blob: 4a57d4cb018108bf519bba113f035111324f7c69 [file] [log] [blame]
Ed Warnickecb9cada2015-12-08 15:45:58 -07001/*
2 *------------------------------------------------------------------
3 * api_format.c
4 *
5 * Copyright (c) 2014 Cisco and/or its affiliates.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at:
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *------------------------------------------------------------------
18 */
19
20#include <vat/vat.h>
21#include <vlibapi/api.h>
22#include <vlibmemory/api.h>
23#include <vlibsocket/api.h>
24#include <vnet/ip/ip.h>
25#include <vnet/sr/sr_packet.h>
26#include <vnet/l2/l2_input.h>
27#include <vnet/l2tp/l2tp.h>
28#include <vnet/vxlan/vxlan.h>
Chris Luke27fe48f2016-04-28 13:44:38 -040029#include <vnet/gre/gre.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070030#include <vnet/nsh-gre/nsh_gre.h>
31#include <vnet/nsh-vxlan-gpe/nsh_vxlan_gpe.h>
32#include <vnet/lisp-gpe/lisp_gpe.h>
33
34#include <api/vpe_msg_enum.h>
35#include <vnet/l2/l2_classify.h>
36#include <vnet/l2/l2_vtr.h>
37#include <vnet/classify/input_acl.h>
Dave Barachbfdedbd2016-01-20 09:11:55 -050038#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -070039#include <vnet/ipsec/ipsec.h>
Matus Fabiane5f42fe2016-04-08 11:18:08 +020040#include <vnet/ipsec/ikev2.h>
Dave Barachbfdedbd2016-01-20 09:11:55 -050041#else
42#include <inttypes.h>
43#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -070044#include <vnet/map/map.h>
Dave Barachc07bf5d2016-02-17 17:52:26 -050045#include <vnet/cop/cop.h>
Shwetha20a64f52016-03-25 10:55:01 +000046#include <vnet/ip/ip6_hop_by_hop.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070047
48#include "vat/json_format.h"
49
50#define vl_typedefs /* define message structures */
51#include <api/vpe_all_api_h.h>
52#undef vl_typedefs
53
54/* declare message handlers for each api */
55
56#define vl_endianfun /* define message structures */
57#include <api/vpe_all_api_h.h>
58#undef vl_endianfun
59
60/* instantiate all the print functions we know about */
61#define vl_print(handle, ...)
62#define vl_printfun
63#include <api/vpe_all_api_h.h>
64#undef vl_printfun
65
66uword unformat_sw_if_index (unformat_input_t * input, va_list * args)
67{
68 vat_main_t * vam = va_arg (*args, vat_main_t *);
69 u32 * result = va_arg (*args, u32 *);
70 u8 * if_name;
71 uword * p;
72
73 if (!unformat (input, "%s", &if_name))
74 return 0;
75
76 p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
77 if (p == 0)
78 return 0;
79 *result = p[0];
80 return 1;
81}
82
83/* Parse an IP4 address %d.%d.%d.%d. */
84uword unformat_ip4_address (unformat_input_t * input, va_list * args)
85{
86 u8 * result = va_arg (*args, u8 *);
87 unsigned a[4];
88
89 if (! unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
90 return 0;
91
92 if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
93 return 0;
94
95 result[0] = a[0];
96 result[1] = a[1];
97 result[2] = a[2];
98 result[3] = a[3];
99
100 return 1;
101}
102
103
104uword
105unformat_ethernet_address (unformat_input_t * input, va_list * args)
106{
107 u8 * result = va_arg (*args, u8 *);
108 u32 i, a[6];
109
110 if (! unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
111 &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
112 return 0;
113
114 /* Check range. */
115 for (i = 0; i < 6; i++)
116 if (a[i] >= (1 << 8))
117 return 0;
118
119 for (i = 0; i < 6; i++)
120 result[i] = a[i];
121
122 return 1;
123}
124
125/* Returns ethernet type as an int in host byte order. */
126uword
127unformat_ethernet_type_host_byte_order (unformat_input_t * input,
128 va_list * args)
129{
130 u16 * result = va_arg (*args, u16 *);
131 int type;
132
133 /* Numeric type. */
134 if (unformat (input, "0x%x", &type)
135 || unformat (input, "%d", &type))
136 {
137 if (type >= (1 << 16))
138 return 0;
139 *result = type;
140 return 1;
141 }
142 return 0;
143}
144
145/* Parse an IP6 address. */
146uword unformat_ip6_address (unformat_input_t * input, va_list * args)
147{
148 ip6_address_t * result = va_arg (*args, ip6_address_t *);
149 u16 hex_quads[8];
150 uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
151 uword c, n_colon, double_colon_index;
152
153 n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
154 double_colon_index = ARRAY_LEN (hex_quads);
155 while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
156 {
157 hex_digit = 16;
158 if (c >= '0' && c <= '9')
159 hex_digit = c - '0';
160 else if (c >= 'a' && c <= 'f')
161 hex_digit = c + 10 - 'a';
162 else if (c >= 'A' && c <= 'F')
163 hex_digit = c + 10 - 'A';
164 else if (c == ':' && n_colon < 2)
165 n_colon++;
166 else
167 {
168 unformat_put_input (input);
169 break;
170 }
171
172 /* Too many hex quads. */
173 if (n_hex_quads >= ARRAY_LEN (hex_quads))
174 return 0;
175
176 if (hex_digit < 16)
177 {
178 hex_quad = (hex_quad << 4) | hex_digit;
179
180 /* Hex quad must fit in 16 bits. */
181 if (n_hex_digits >= 4)
182 return 0;
183
184 n_colon = 0;
185 n_hex_digits++;
186 }
187
188 /* Save position of :: */
189 if (n_colon == 2)
190 {
191 /* More than one :: ? */
192 if (double_colon_index < ARRAY_LEN (hex_quads))
193 return 0;
194 double_colon_index = n_hex_quads;
195 }
196
197 if (n_colon > 0 && n_hex_digits > 0)
198 {
199 hex_quads[n_hex_quads++] = hex_quad;
200 hex_quad = 0;
201 n_hex_digits = 0;
202 }
203 }
204
205 if (n_hex_digits > 0)
206 hex_quads[n_hex_quads++] = hex_quad;
207
208 {
209 word i;
210
211 /* Expand :: to appropriate number of zero hex quads. */
212 if (double_colon_index < ARRAY_LEN (hex_quads))
213 {
214 word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
215
216 for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
217 hex_quads[n_zero + i] = hex_quads[i];
218
219 for (i = 0; i < n_zero; i++)
220 hex_quads[double_colon_index + i] = 0;
221
222 n_hex_quads = ARRAY_LEN (hex_quads);
223 }
224
225 /* Too few hex quads given. */
226 if (n_hex_quads < ARRAY_LEN (hex_quads))
227 return 0;
228
229 for (i = 0; i < ARRAY_LEN (hex_quads); i++)
230 result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
231
232 return 1;
233 }
234}
235
236uword
237unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
238{
Dave Barachbfdedbd2016-01-20 09:11:55 -0500239#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -0700240 u32 * r = va_arg (*args, u32 *);
241
242 if (0) ;
243#define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
244 foreach_ipsec_policy_action
245#undef _
246 else
247 return 0;
248 return 1;
Dave Barachbfdedbd2016-01-20 09:11:55 -0500249#else
250 return 0;
251#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -0700252}
253
254uword
255unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
256{
Dave Barachbfdedbd2016-01-20 09:11:55 -0500257#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -0700258 u32 * r = va_arg (*args, u32 *);
259
260 if (0) ;
261#define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
262 foreach_ipsec_crypto_alg
263#undef _
264 else
265 return 0;
266 return 1;
Dave Barachbfdedbd2016-01-20 09:11:55 -0500267#else
268 return 0;
269#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -0700270}
271
272u8 *
273format_ipsec_crypto_alg (u8 * s, va_list * args)
274{
Dave Barachbfdedbd2016-01-20 09:11:55 -0500275#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -0700276 u32 i = va_arg (*args, u32);
277 u8 * t = 0;
278
279 switch (i)
280 {
281#define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
282 foreach_ipsec_crypto_alg
283#undef _
284 default:
285 return format (s, "unknown");
286 }
287 return format (s, "%s", t);
Dave Barachbfdedbd2016-01-20 09:11:55 -0500288#else
289 return format (s, "Unimplemented");
290#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -0700291}
292
293uword
294unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
295{
Dave Barachbfdedbd2016-01-20 09:11:55 -0500296#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -0700297 u32 * r = va_arg (*args, u32 *);
298
299 if (0) ;
300#define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
301 foreach_ipsec_integ_alg
302#undef _
303 else
304 return 0;
305 return 1;
Dave Barachbfdedbd2016-01-20 09:11:55 -0500306#else
307 return 0;
308#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -0700309}
310
311u8 *
312format_ipsec_integ_alg (u8 * s, va_list * args)
313{
Dave Barachbfdedbd2016-01-20 09:11:55 -0500314#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -0700315 u32 i = va_arg (*args, u32);
316 u8 * t = 0;
317
318 switch (i)
319 {
320#define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
321 foreach_ipsec_integ_alg
322#undef _
323 default:
324 return format (s, "unknown");
325 }
326 return format (s, "%s", t);
Dave Barachbfdedbd2016-01-20 09:11:55 -0500327#else
328 return format (s, "Unsupported");
329#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -0700330}
331
Matus Fabiane5f42fe2016-04-08 11:18:08 +0200332uword
333unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
334{
335#if DPDK > 0
336 u32 * r = va_arg (*args, u32 *);
337
338 if (0) ;
339#define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
340 foreach_ikev2_auth_method
341#undef _
342 else
343 return 0;
344 return 1;
345#else
346 return 0;
347#endif
348}
349
350uword
351unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
352{
353#if DPDK > 0
354 u32 * r = va_arg (*args, u32 *);
355
356 if (0) ;
357#define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
358 foreach_ikev2_id_type
359#undef _
360 else
361 return 0;
362 return 1;
363#else
364 return 0;
365#endif
366}
367
Ed Warnickecb9cada2015-12-08 15:45:58 -0700368u8 * format_ip4_address (u8 * s, va_list * args)
369{
370 u8 * a = va_arg (*args, u8 *);
371 return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
372}
373
374u8 * format_ip6_address (u8 * s, va_list * args)
375{
376 ip6_address_t * a = va_arg (*args, ip6_address_t *);
377 u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
378
379 i_max_n_zero = ARRAY_LEN (a->as_u16);
380 max_n_zeros = 0;
381 i_first_zero = i_max_n_zero;
382 n_zeros = 0;
383 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
384 {
385 u32 is_zero = a->as_u16[i] == 0;
386 if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
387 {
388 i_first_zero = i;
389 n_zeros = 0;
390 }
391 n_zeros += is_zero;
392 if ((! is_zero && n_zeros > max_n_zeros)
393 || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
394 {
395 i_max_n_zero = i_first_zero;
396 max_n_zeros = n_zeros;
397 i_first_zero = ARRAY_LEN (a->as_u16);
398 n_zeros = 0;
399 }
400 }
401
402 last_double_colon = 0;
403 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
404 {
405 if (i == i_max_n_zero && max_n_zeros > 1)
406 {
407 s = format (s, "::");
408 i += max_n_zeros - 1;
409 last_double_colon = 1;
410 }
411 else
412 {
413 s = format (s, "%s%x",
414 (last_double_colon || i == 0) ? "" : ":",
415 clib_net_to_host_u16 (a->as_u16[i]));
416 last_double_colon = 0;
417 }
418 }
419
420 return s;
421}
422
Chris Luke99cb3352016-04-26 10:49:53 -0400423/* Format an IP46 address. */
424u8 * format_ip46_address (u8 * s, va_list * args)
425{
426 ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
427 return ip46_address_is_ip4(ip46)?
428 format(s, "%U", format_ip4_address, &ip46->ip4):
429 format(s, "%U", format_ip6_address, &ip46->ip6);
430}
431
Ed Warnickecb9cada2015-12-08 15:45:58 -0700432u8 * format_ethernet_address (u8 * s, va_list * args)
433{
434 u8 * a = va_arg (*args, u8 *);
435
436 return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
437 a[0], a[1], a[2], a[3], a[4], a[5]);
438}
439
440void increment_v4_address (ip4_address_t * a)
441{
442 u32 v;
443
444 v = ntohl(a->as_u32) + 1;
445 a->as_u32 = ntohl(v);
446}
447
448void increment_v6_address (ip6_address_t * a)
449{
450 u64 v0, v1;
451
452 v0 = clib_net_to_host_u64 (a->as_u64[0]);
453 v1 = clib_net_to_host_u64 (a->as_u64[1]);
454
455 v1 += 1;
456 if (v1 == 0)
457 v0 += 1;
458 a->as_u64[0] = clib_net_to_host_u64 (v0);
459 a->as_u64[1] = clib_net_to_host_u64 (v1);
460}
461
462
463static void vl_api_create_loopback_reply_t_handler
464(vl_api_create_loopback_reply_t * mp)
465{
466 vat_main_t * vam = &vat_main;
467 i32 retval = ntohl(mp->retval);
468
469 vam->retval = retval;
470 vam->result_ready = 1;
471 vam->regenerate_interface_table = 1;
472}
473
474static void vl_api_create_loopback_reply_t_handler_json
475(vl_api_create_loopback_reply_t * mp)
476{
477 vat_main_t * vam = &vat_main;
478 vat_json_node_t node;
479
480 vat_json_init_object(&node);
481 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
482 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
483
484 vat_json_print(vam->ofp, &node);
485 vat_json_free(&node);
486
487 vam->retval = ntohl(mp->retval);
488 vam->result_ready = 1;
489}
490
491static void vl_api_create_vlan_subif_reply_t_handler
492(vl_api_create_vlan_subif_reply_t * mp)
493{
494 vat_main_t * vam = &vat_main;
495 i32 retval = ntohl(mp->retval);
496
497 vam->retval = retval;
498 vam->result_ready = 1;
499 vam->regenerate_interface_table = 1;
500}
501
502static void vl_api_create_vlan_subif_reply_t_handler_json
503(vl_api_create_vlan_subif_reply_t * mp)
504{
505 vat_main_t * vam = &vat_main;
506 vat_json_node_t node;
507
508 vat_json_init_object(&node);
509 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
510 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
511
512 vat_json_print(vam->ofp, &node);
513 vat_json_free(&node);
514
515 vam->retval = ntohl(mp->retval);
516 vam->result_ready = 1;
517}
518
519static void vl_api_create_subif_reply_t_handler
520(vl_api_create_subif_reply_t * mp)
521{
522 vat_main_t * vam = &vat_main;
523 i32 retval = ntohl(mp->retval);
524
525 vam->retval = retval;
526 vam->result_ready = 1;
527 vam->regenerate_interface_table = 1;
528}
529
530static void vl_api_create_subif_reply_t_handler_json
531(vl_api_create_subif_reply_t * mp)
532{
533 vat_main_t * vam = &vat_main;
534 vat_json_node_t node;
535
536 vat_json_init_object(&node);
537 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
538 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
539
540 vat_json_print(vam->ofp, &node);
541 vat_json_free(&node);
542
543 vam->retval = ntohl(mp->retval);
544 vam->result_ready = 1;
545}
546
547static void vl_api_interface_name_renumber_reply_t_handler
548(vl_api_interface_name_renumber_reply_t * mp)
549{
550 vat_main_t * vam = &vat_main;
551 i32 retval = ntohl(mp->retval);
552
553 vam->retval = retval;
554 vam->result_ready = 1;
555 vam->regenerate_interface_table = 1;
556}
557
558static void vl_api_interface_name_renumber_reply_t_handler_json
559(vl_api_interface_name_renumber_reply_t * mp)
560{
561 vat_main_t * vam = &vat_main;
562 vat_json_node_t node;
563
564 vat_json_init_object(&node);
565 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
566
567 vat_json_print(vam->ofp, &node);
568 vat_json_free(&node);
569
570 vam->retval = ntohl(mp->retval);
571 vam->result_ready = 1;
572}
573
574/*
575 * Special-case: build the interface table, maintain
576 * the next loopback sw_if_index vbl.
577 */
578static void vl_api_sw_interface_details_t_handler
579(vl_api_sw_interface_details_t * mp)
580{
581 vat_main_t * vam = &vat_main;
582 u8 * s = format (0, "%s%c", mp->interface_name, 0);
583
584 hash_set_mem (vam->sw_if_index_by_interface_name, s,
585 ntohl(mp->sw_if_index));
586
587 /* In sub interface case, fill the sub interface table entry */
588 if (mp->sw_if_index != mp->sup_sw_if_index) {
589 sw_interface_subif_t * sub = NULL;
590
591 vec_add2(vam->sw_if_subif_table, sub, 1);
592
593 vec_validate(sub->interface_name, strlen((char *)s) + 1);
594 strncpy((char *)sub->interface_name, (char *)s,
595 vec_len(sub->interface_name));
596 sub->sw_if_index = ntohl(mp->sw_if_index);
597 sub->sub_id = ntohl(mp->sub_id);
598
599 sub->sub_dot1ad = mp->sub_dot1ad;
600 sub->sub_number_of_tags = mp->sub_number_of_tags;
601 sub->sub_outer_vlan_id = ntohs(mp->sub_outer_vlan_id);
602 sub->sub_inner_vlan_id = ntohs(mp->sub_inner_vlan_id);
603 sub->sub_exact_match = mp->sub_exact_match;
604 sub->sub_default = mp->sub_default;
605 sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
606 sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
607
608 /* vlan tag rewrite */
609 sub->vtr_op = ntohl(mp->vtr_op);
610 sub->vtr_push_dot1q = ntohl(mp->vtr_push_dot1q);
611 sub->vtr_tag1 = ntohl(mp->vtr_tag1);
612 sub->vtr_tag2 = ntohl(mp->vtr_tag2);
613 }
614}
615
616static void vl_api_sw_interface_details_t_handler_json
617(vl_api_sw_interface_details_t * mp)
618{
619 vat_main_t * vam = &vat_main;
620 vat_json_node_t *node = NULL;
621
622 if (VAT_JSON_ARRAY != vam->json_tree.type) {
623 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
624 vat_json_init_array(&vam->json_tree);
625 }
626 node = vat_json_array_add(&vam->json_tree);
627
628 vat_json_init_object(node);
629 vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
630 vat_json_object_add_uint(node, "sup_sw_if_index", ntohl(mp->sup_sw_if_index));
631 vat_json_object_add_uint(node, "l2_address_length", ntohl(mp->l2_address_length));
632 vat_json_object_add_bytes(node, "l2_address", mp->l2_address, sizeof(mp->l2_address));
633 vat_json_object_add_string_copy(node, "interface_name", mp->interface_name);
634 vat_json_object_add_uint(node, "admin_up_down", mp->admin_up_down);
635 vat_json_object_add_uint(node, "link_up_down", mp->link_up_down);
636 vat_json_object_add_uint(node, "link_duplex", mp->link_duplex);
637 vat_json_object_add_uint(node, "link_speed", mp->link_speed);
Pavel84e4ffe2016-02-17 15:10:04 +0100638 vat_json_object_add_uint(node, "mtu", ntohs(mp->link_mtu));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700639 vat_json_object_add_uint(node, "sub_id", ntohl(mp->sub_id));
640 vat_json_object_add_uint(node, "sub_dot1ad", mp->sub_dot1ad);
641 vat_json_object_add_uint(node, "sub_number_of_tags", mp->sub_number_of_tags);
642 vat_json_object_add_uint(node, "sub_outer_vlan_id", ntohs(mp->sub_outer_vlan_id));
643 vat_json_object_add_uint(node, "sub_inner_vlan_id", ntohs(mp->sub_inner_vlan_id));
644 vat_json_object_add_uint(node, "sub_exact_match", mp->sub_exact_match);
645 vat_json_object_add_uint(node, "sub_default", mp->sub_default);
646 vat_json_object_add_uint(node, "sub_outer_vlan_id_any", mp->sub_outer_vlan_id_any);
647 vat_json_object_add_uint(node, "sub_inner_vlan_id_any", mp->sub_inner_vlan_id_any);
648 vat_json_object_add_uint(node, "vtr_op", ntohl(mp->vtr_op));
649 vat_json_object_add_uint(node, "vtr_push_dot1q", ntohl(mp->vtr_push_dot1q));
650 vat_json_object_add_uint(node, "vtr_tag1", ntohl(mp->vtr_tag1));
651 vat_json_object_add_uint(node, "vtr_tag2", ntohl(mp->vtr_tag2));
652}
653
654static void vl_api_sw_interface_set_flags_t_handler
655(vl_api_sw_interface_set_flags_t * mp)
656{
657 vat_main_t * vam = &vat_main;
658 if (vam->interface_event_display)
659 errmsg ("interface flags: sw_if_index %d %s %s\n",
660 ntohl(mp->sw_if_index),
661 mp->admin_up_down ? "admin-up" : "admin-down",
662 mp->link_up_down ? "link-up" : "link-down");
663}
664
665static void vl_api_sw_interface_set_flags_t_handler_json
666(vl_api_sw_interface_set_flags_t * mp)
667{
668 /* JSON output not supported */
669}
670
Pavel Kotucek00bbf272016-03-03 13:27:11 +0100671static void vl_api_cli_reply_t_handler
Ed Warnickecb9cada2015-12-08 15:45:58 -0700672(vl_api_cli_reply_t * mp)
673{
674 vat_main_t * vam = &vat_main;
675 i32 retval = ntohl(mp->retval);
676
677 vam->retval = retval;
678 vam->shmem_result = (u8 *) mp->reply_in_shmem;
679 vam->result_ready = 1;
680}
681
682static void vl_api_cli_reply_t_handler_json
683(vl_api_cli_reply_t * mp)
684{
685 vat_main_t * vam = &vat_main;
686 vat_json_node_t node;
Dave Barachb44e9bc2016-02-19 09:06:23 -0500687 api_main_t * am = &api_main;
688 void * oldheap;
689 u8 * reply;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700690
691 vat_json_init_object(&node);
692 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
Dave Barachb44e9bc2016-02-19 09:06:23 -0500693 vat_json_object_add_uint(&node, "reply_in_shmem",
694 ntohl(mp->reply_in_shmem));
695 /* Toss the shared-memory original... */
696 pthread_mutex_lock (&am->vlib_rp->mutex);
697 oldheap = svm_push_data_heap (am->vlib_rp);
698
699 reply = (u8 *)(mp->reply_in_shmem);
700 vec_free (reply);
701
702 svm_pop_heap (oldheap);
703 pthread_mutex_unlock (&am->vlib_rp->mutex);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700704
705 vat_json_print(vam->ofp, &node);
706 vat_json_free(&node);
707
708 vam->retval = ntohl(mp->retval);
709 vam->result_ready = 1;
710}
711
712static void vl_api_classify_add_del_table_reply_t_handler
713(vl_api_classify_add_del_table_reply_t * mp)
714{
715 vat_main_t * vam = &vat_main;
716 i32 retval = ntohl(mp->retval);
717 if (vam->async_mode) {
718 vam->async_errors += (retval < 0);
719 } else {
720 vam->retval = retval;
721 vam->result_ready = 1;
722 if (retval == 0 &&
723 ((mp->new_table_index != 0xFFFFFFFF) ||
724 (mp->skip_n_vectors != 0xFFFFFFFF) ||
725 (mp->match_n_vectors != 0xFFFFFFFF)))
726 /*
727 * Note: this is just barely thread-safe, depends on
728 * the main thread spinning waiting for an answer...
729 */
730 errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d\n",
731 ntohl(mp->new_table_index),
732 ntohl(mp->skip_n_vectors), ntohl(mp->match_n_vectors));
733 }
734}
735
736static void vl_api_classify_add_del_table_reply_t_handler_json
737(vl_api_classify_add_del_table_reply_t * mp)
738{
739 vat_main_t * vam = &vat_main;
740 vat_json_node_t node;
741
742 vat_json_init_object(&node);
743 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
744 vat_json_object_add_uint(&node, "new_table_index", ntohl(mp->new_table_index));
745 vat_json_object_add_uint(&node, "skip_n_vectors", ntohl(mp->skip_n_vectors));
746 vat_json_object_add_uint(&node, "match_n_vectors", ntohl(mp->match_n_vectors));
747
748 vat_json_print(vam->ofp, &node);
749 vat_json_free(&node);
750
751 vam->retval = ntohl(mp->retval);
752 vam->result_ready = 1;
753}
754
755static void vl_api_get_node_index_reply_t_handler
756(vl_api_get_node_index_reply_t * mp)
757{
758 vat_main_t * vam = &vat_main;
759 i32 retval = ntohl(mp->retval);
760 if (vam->async_mode) {
761 vam->async_errors += (retval < 0);
762 } else {
763 vam->retval = retval;
764 vam->result_ready = 1;
765 if (retval == 0)
766 errmsg ("node index %d\n", ntohl(mp->node_index));
767 }
768}
769
770static void vl_api_get_node_index_reply_t_handler_json
771(vl_api_get_node_index_reply_t * mp)
772{
773 vat_main_t * vam = &vat_main;
774 vat_json_node_t node;
775
776 vat_json_init_object(&node);
777 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
778 vat_json_object_add_uint(&node, "node_index", ntohl(mp->node_index));
779
780 vat_json_print(vam->ofp, &node);
781 vat_json_free(&node);
782
783 vam->retval = ntohl(mp->retval);
784 vam->result_ready = 1;
785}
786
787static void vl_api_add_node_next_reply_t_handler
788(vl_api_add_node_next_reply_t * mp)
789{
790 vat_main_t * vam = &vat_main;
791 i32 retval = ntohl(mp->retval);
792 if (vam->async_mode) {
793 vam->async_errors += (retval < 0);
794 } else {
795 vam->retval = retval;
796 vam->result_ready = 1;
797 if (retval == 0)
798 errmsg ("next index %d\n", ntohl(mp->next_index));
799 }
800}
801
802static void vl_api_add_node_next_reply_t_handler_json
803(vl_api_add_node_next_reply_t * mp)
804{
805 vat_main_t * vam = &vat_main;
806 vat_json_node_t node;
807
808 vat_json_init_object(&node);
809 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
810 vat_json_object_add_uint(&node, "next_index", ntohl(mp->next_index));
811
812 vat_json_print(vam->ofp, &node);
813 vat_json_free(&node);
814
815 vam->retval = ntohl(mp->retval);
816 vam->result_ready = 1;
817}
818
819static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler
820(vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
821{
822 vat_main_t * vam = &vat_main;
823 i32 retval = ntohl(mp->retval);
824 u32 sw_if_index = ntohl(mp->tunnel_sw_if_index);
825
826 if (retval >= 0 && sw_if_index != (u32)~0) {
827 errmsg ("tunnel_sw_if_index %d\n", sw_if_index);
828 }
829 vam->retval = retval;
830 vam->result_ready = 1;
831}
832
833static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler_json
834(vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
835{
836 vat_main_t * vam = &vat_main;
837 vat_json_node_t node;
838
839 vat_json_init_object(&node);
840 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
841 vat_json_object_add_uint(&node, "tunnel_sw_if_index", ntohl(mp->tunnel_sw_if_index));
842
843 vat_json_print(vam->ofp, &node);
844 vat_json_free(&node);
845
846 vam->retval = ntohl(mp->retval);
847 vam->result_ready = 1;
848}
849
850static void vl_api_nsh_gre_add_del_tunnel_reply_t_handler
851(vl_api_nsh_gre_add_del_tunnel_reply_t * mp)
852{
853 vat_main_t * vam = &vat_main;
854 i32 retval = ntohl(mp->retval);
855 u32 sw_if_index = ntohl(mp->sw_if_index);
856
857 if (retval >= 0 && sw_if_index != (u32)~0) {
858 errmsg ("sw_if_index %d\n", ntohl(mp->sw_if_index));
859 }
860 vam->retval = retval;
861 vam->result_ready = 1;
862}
863
864static void vl_api_nsh_gre_add_del_tunnel_reply_t_handler_json
865(vl_api_nsh_gre_add_del_tunnel_reply_t * mp)
866{
867 vat_main_t * vam = &vat_main;
868 vat_json_node_t node;
869
870 vat_json_init_object(&node);
871 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
872 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
873
874 vat_json_print(vam->ofp, &node);
875 vat_json_free(&node);
876
877 vam->retval = ntohl(mp->retval);
878 vam->result_ready = 1;
879}
880
881static void vl_api_nsh_vxlan_gpe_add_del_tunnel_reply_t_handler
882(vl_api_nsh_vxlan_gpe_add_del_tunnel_reply_t * mp)
883{
884 vat_main_t * vam = &vat_main;
885 i32 retval = ntohl(mp->retval);
886 u32 sw_if_index = ntohl(mp->sw_if_index);
887
888 if (retval >= 0 && sw_if_index != (u32)~0) {
889 errmsg ("sw_if_index %d\n", ntohl(mp->sw_if_index));
890 }
891 vam->retval = retval;
892 vam->result_ready = 1;
893}
894
895static void vl_api_nsh_vxlan_gpe_add_del_tunnel_reply_t_handler_json
896(vl_api_nsh_vxlan_gpe_add_del_tunnel_reply_t * mp)
897{
898 vat_main_t * vam = &vat_main;
899 vat_json_node_t node;
900
901 vat_json_init_object(&node);
902 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
903 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
904
905 vat_json_print(vam->ofp, &node);
906 vat_json_free(&node);
907
908 vam->retval = ntohl(mp->retval);
909 vam->result_ready = 1;
910}
911
912static void vl_api_lisp_gpe_add_del_tunnel_reply_t_handler
913(vl_api_lisp_gpe_add_del_tunnel_reply_t * mp)
914{
915 vat_main_t * vam = &vat_main;
916 i32 retval = ntohl(mp->retval);
917 u32 sw_if_index = ntohl(mp->sw_if_index);
918
919 if (retval >= 0 && sw_if_index != (u32)~0) {
920 errmsg ("sw_if_index %d\n", ntohl(mp->sw_if_index));
921 }
922 vam->retval = retval;
923 vam->result_ready = 1;
924}
925
926static void vl_api_lisp_gpe_add_del_tunnel_reply_t_handler_json
927(vl_api_lisp_gpe_add_del_tunnel_reply_t * mp)
928{
929 vat_main_t * vam = &vat_main;
930 vat_json_node_t node;
931
932 vat_json_init_object(&node);
933 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
934 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
935
936 vat_json_print(vam->ofp, &node);
937 vat_json_free(&node);
938
939 vam->retval = ntohl(mp->retval);
940 vam->result_ready = 1;
941}
942
943static void vl_api_show_version_reply_t_handler
944(vl_api_show_version_reply_t * mp)
945{
946 vat_main_t * vam = &vat_main;
947 i32 retval = ntohl(mp->retval);
948
949 if (retval >= 0) {
950 errmsg (" program: %s\n", mp->program);
Damjan Mariona0d4a1a2015-12-12 14:40:59 +0100951 errmsg (" version: %s\n", mp->version);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700952 errmsg (" build date: %s\n", mp->build_date);
953 errmsg ("build directory: %s\n", mp->build_directory);
954 }
955 vam->retval = retval;
956 vam->result_ready = 1;
957}
958
959static void vl_api_show_version_reply_t_handler_json
960(vl_api_show_version_reply_t * mp)
961{
962 vat_main_t * vam = &vat_main;
963 vat_json_node_t node;
964
965 vat_json_init_object(&node);
966 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
967 vat_json_object_add_string_copy(&node, "program", mp->program);
Damjan Mariona0d4a1a2015-12-12 14:40:59 +0100968 vat_json_object_add_string_copy(&node, "version", mp->version);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700969 vat_json_object_add_string_copy(&node, "build_date", mp->build_date);
970 vat_json_object_add_string_copy(&node, "build_directory", mp->build_directory);
971
972 vat_json_print(vam->ofp, &node);
973 vat_json_free(&node);
974
975 vam->retval = ntohl(mp->retval);
976 vam->result_ready = 1;
977}
978
979static void vl_api_ip4_arp_event_t_handler
980(vl_api_ip4_arp_event_t * mp)
981{
982 vat_main_t * vam = &vat_main;
983 errmsg ("arp event: address %U new mac %U sw_if_index %d\n",
984 format_ip4_address, &mp->address,
985 format_ethernet_address, mp->new_mac, mp->sw_if_index);
986}
987
988static void vl_api_ip4_arp_event_t_handler_json
989(vl_api_ip4_arp_event_t * mp)
990{
991 /* JSON output not supported */
992}
993
994/*
995 * Special-case: build the bridge domain table, maintain
996 * the next bd id vbl.
997 */
998static void vl_api_bridge_domain_details_t_handler
999(vl_api_bridge_domain_details_t * mp)
1000{
1001 vat_main_t * vam = &vat_main;
1002 u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1003
1004 fformat (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s\n",
1005 " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1006
1007 fformat (vam->ofp, "%3d %3d %3d %3d %3d %3d\n",
1008 ntohl (mp->bd_id), mp->learn, mp->forward,
1009 mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1010
1011 if (n_sw_ifs)
1012 fformat (vam->ofp, "\n\n%s %s %s\n", "sw_if_index", "SHG",
1013 "Interface Name");
1014}
1015
1016static void vl_api_bridge_domain_details_t_handler_json
1017(vl_api_bridge_domain_details_t * mp)
1018{
1019 vat_main_t * vam = &vat_main;
1020 vat_json_node_t *node, *array = NULL;
1021
1022 if (VAT_JSON_ARRAY != vam->json_tree.type) {
1023 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
1024 vat_json_init_array(&vam->json_tree);
1025 }
1026 node = vat_json_array_add(&vam->json_tree);
1027
1028 vat_json_init_object(node);
1029 vat_json_object_add_uint(node, "bd_id", ntohl(mp->bd_id));
1030 vat_json_object_add_uint(node, "flood", mp->flood);
1031 vat_json_object_add_uint(node, "forward", mp->forward);
1032 vat_json_object_add_uint(node, "learn", mp->learn);
1033 vat_json_object_add_uint(node, "bvi_sw_if_index", ntohl(mp->bvi_sw_if_index));
1034 vat_json_object_add_uint(node, "n_sw_ifs", ntohl(mp->n_sw_ifs));
1035 array = vat_json_object_add(node, "sw_if");
1036 vat_json_init_array(array);
1037}
1038
1039/*
1040 * Special-case: build the bridge domain sw if table.
1041 */
1042static void vl_api_bridge_domain_sw_if_details_t_handler
1043(vl_api_bridge_domain_sw_if_details_t * mp)
1044{
1045 vat_main_t * vam = &vat_main;
1046 hash_pair_t * p;
1047 u8 * sw_if_name = 0;
1048 u32 sw_if_index;
1049
1050 sw_if_index = ntohl (mp->sw_if_index);
1051 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1052 ({
1053 if ((u32) p->value[0] == sw_if_index) {
1054 sw_if_name = (u8 *)(p->key);
1055 break;
1056 }
1057 }));
1058
1059 fformat (vam->ofp, "%7d %3d %s", sw_if_index,
1060 mp->shg, sw_if_name ? (char *)sw_if_name :
1061 "sw_if_index not found!");
1062}
1063
1064static void vl_api_bridge_domain_sw_if_details_t_handler_json
1065(vl_api_bridge_domain_sw_if_details_t * mp)
1066{
1067 vat_main_t * vam = &vat_main;
1068 vat_json_node_t *node = NULL;
1069 uword last_index = 0;
1070
1071 ASSERT(VAT_JSON_ARRAY == vam->json_tree.type);
1072 ASSERT(vec_len(vam->json_tree.array) >= 1);
1073 last_index = vec_len(vam->json_tree.array) - 1;
1074 node = &vam->json_tree.array[last_index];
1075 node = vat_json_object_get_element(node, "sw_if");
1076 ASSERT(NULL != node);
1077 node = vat_json_array_add(node);
1078
1079 vat_json_init_object(node);
1080 vat_json_object_add_uint(node, "bd_id", ntohl(mp->bd_id));
1081 vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
1082 vat_json_object_add_uint(node, "shg", mp->shg);
1083}
1084
1085static void vl_api_control_ping_reply_t_handler
1086(vl_api_control_ping_reply_t * mp)
1087{
1088 vat_main_t * vam = &vat_main;
1089 i32 retval = ntohl(mp->retval);
1090 if (vam->async_mode) {
1091 vam->async_errors += (retval < 0);
1092 } else {
1093 vam->retval = retval;
1094 vam->result_ready = 1;
1095 }
1096}
1097
1098static void vl_api_control_ping_reply_t_handler_json
1099(vl_api_control_ping_reply_t * mp)
1100{
1101 vat_main_t * vam = &vat_main;
1102 i32 retval = ntohl(mp->retval);
1103
1104 if (VAT_JSON_NONE != vam->json_tree.type) {
1105 vat_json_print(vam->ofp, &vam->json_tree);
1106 vat_json_free(&vam->json_tree);
1107 vam->json_tree.type = VAT_JSON_NONE;
1108 } else {
1109 /* just print [] */
1110 vat_json_init_array(&vam->json_tree);
1111 vat_json_print(vam->ofp, &vam->json_tree);
1112 vam->json_tree.type = VAT_JSON_NONE;
1113 }
1114
1115 vam->retval = retval;
1116 vam->result_ready = 1;
1117}
1118
1119static void vl_api_l2_flags_reply_t_handler
1120(vl_api_l2_flags_reply_t * mp)
1121{
1122 vat_main_t * vam = &vat_main;
1123 i32 retval = ntohl(mp->retval);
1124 if (vam->async_mode) {
1125 vam->async_errors += (retval < 0);
1126 } else {
1127 vam->retval = retval;
1128 vam->result_ready = 1;
1129 }
1130}
1131
1132static void vl_api_l2_flags_reply_t_handler_json
1133(vl_api_l2_flags_reply_t * mp)
1134{
1135 vat_main_t * vam = &vat_main;
1136 vat_json_node_t node;
1137
1138 vat_json_init_object(&node);
1139 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1140 vat_json_object_add_uint(&node, "resulting_feature_bitmap", ntohl(mp->resulting_feature_bitmap));
1141
1142 vat_json_print(vam->ofp, &node);
1143 vat_json_free(&node);
1144
1145 vam->retval = ntohl(mp->retval);
1146 vam->result_ready = 1;
1147}
1148
1149static void vl_api_bridge_flags_reply_t_handler
1150(vl_api_bridge_flags_reply_t * mp)
1151{
1152 vat_main_t * vam = &vat_main;
1153 i32 retval = ntohl(mp->retval);
1154 if (vam->async_mode) {
1155 vam->async_errors += (retval < 0);
1156 } else {
1157 vam->retval = retval;
1158 vam->result_ready = 1;
1159 }
1160}
1161
1162static void vl_api_bridge_flags_reply_t_handler_json
1163(vl_api_bridge_flags_reply_t * mp)
1164{
1165 vat_main_t * vam = &vat_main;
1166 vat_json_node_t node;
1167
1168 vat_json_init_object(&node);
1169 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1170 vat_json_object_add_uint(&node, "resulting_feature_bitmap", ntohl(mp->resulting_feature_bitmap));
1171
1172 vat_json_print(vam->ofp, &node);
1173 vat_json_free(&node);
1174
1175 vam->retval = ntohl(mp->retval);
1176 vam->result_ready = 1;
1177}
1178
1179static void vl_api_tap_connect_reply_t_handler
1180(vl_api_tap_connect_reply_t * mp)
1181{
1182 vat_main_t * vam = &vat_main;
1183 i32 retval = ntohl(mp->retval);
1184 if (vam->async_mode) {
1185 vam->async_errors += (retval < 0);
1186 } else {
1187 vam->retval = retval;
1188 vam->result_ready = 1;
1189 }
1190}
1191
1192static void vl_api_tap_connect_reply_t_handler_json
1193(vl_api_tap_connect_reply_t * mp)
1194{
1195 vat_main_t * vam = &vat_main;
1196 vat_json_node_t node;
1197
1198 vat_json_init_object(&node);
1199 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1200 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
1201
1202 vat_json_print(vam->ofp, &node);
1203 vat_json_free(&node);
1204
1205 vam->retval = ntohl(mp->retval);
1206 vam->result_ready = 1;
1207}
1208
1209static void vl_api_tap_modify_reply_t_handler
1210(vl_api_tap_modify_reply_t * mp)
1211{
1212 vat_main_t * vam = &vat_main;
1213 i32 retval = ntohl(mp->retval);
1214 if (vam->async_mode) {
1215 vam->async_errors += (retval < 0);
1216 } else {
1217 vam->retval = retval;
1218 vam->result_ready = 1;
1219 }
1220}
1221
1222static void vl_api_tap_modify_reply_t_handler_json
1223(vl_api_tap_modify_reply_t * mp)
1224{
1225 vat_main_t * vam = &vat_main;
1226 vat_json_node_t node;
1227
1228 vat_json_init_object(&node);
1229 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1230 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
1231
1232 vat_json_print(vam->ofp, &node);
1233 vat_json_free(&node);
1234
1235 vam->retval = ntohl(mp->retval);
1236 vam->result_ready = 1;
1237}
1238
1239static void vl_api_tap_delete_reply_t_handler
1240(vl_api_tap_delete_reply_t * mp)
1241{
1242 vat_main_t * vam = &vat_main;
1243 i32 retval = ntohl(mp->retval);
1244 if (vam->async_mode) {
1245 vam->async_errors += (retval < 0);
1246 } else {
1247 vam->retval = retval;
1248 vam->result_ready = 1;
1249 }
1250}
1251
1252static void vl_api_tap_delete_reply_t_handler_json
1253(vl_api_tap_delete_reply_t * mp)
1254{
1255 vat_main_t * vam = &vat_main;
1256 vat_json_node_t node;
1257
1258 vat_json_init_object(&node);
1259 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1260
1261 vat_json_print(vam->ofp, &node);
1262 vat_json_free(&node);
1263
1264 vam->retval = ntohl(mp->retval);
1265 vam->result_ready = 1;
1266}
1267
1268static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler
1269(vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1270{
1271 vat_main_t * vam = &vat_main;
1272 i32 retval = ntohl(mp->retval);
1273 if (vam->async_mode) {
1274 vam->async_errors += (retval < 0);
1275 } else {
1276 vam->retval = retval;
1277 vam->result_ready = 1;
1278 }
1279}
1280
1281static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler_json
1282(vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1283{
1284 vat_main_t * vam = &vat_main;
1285 vat_json_node_t node;
1286
1287 vat_json_init_object(&node);
1288 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1289 vat_json_object_add_uint(&node, "tunnel_sw_if_index", ntohl(mp->tunnel_sw_if_index));
1290
1291 vat_json_print(vam->ofp, &node);
1292 vat_json_free(&node);
1293
1294 vam->retval = ntohl(mp->retval);
1295 vam->result_ready = 1;
1296}
1297
1298static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1299(vl_api_l2tpv3_create_tunnel_reply_t * mp)
1300{
1301 vat_main_t * vam = &vat_main;
1302 i32 retval = ntohl(mp->retval);
1303 if (vam->async_mode) {
1304 vam->async_errors += (retval < 0);
1305 } else {
1306 vam->retval = retval;
1307 vam->result_ready = 1;
1308 }
1309}
1310
1311static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1312(vl_api_l2tpv3_create_tunnel_reply_t * mp)
1313{
1314 vat_main_t * vam = &vat_main;
1315 vat_json_node_t node;
1316
1317 vat_json_init_object(&node);
1318 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1319 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
1320
1321 vat_json_print(vam->ofp, &node);
1322 vat_json_free(&node);
1323
1324 vam->retval = ntohl(mp->retval);
1325 vam->result_ready = 1;
1326}
1327
1328static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1329(vl_api_vxlan_add_del_tunnel_reply_t * mp)
1330{
1331 vat_main_t * vam = &vat_main;
1332 i32 retval = ntohl(mp->retval);
1333 if (vam->async_mode) {
1334 vam->async_errors += (retval < 0);
1335 } else {
1336 vam->retval = retval;
1337 vam->result_ready = 1;
1338 }
1339}
1340
1341static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1342(vl_api_vxlan_add_del_tunnel_reply_t * mp)
1343{
1344 vat_main_t * vam = &vat_main;
1345 vat_json_node_t node;
1346
1347 vat_json_init_object(&node);
1348 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1349 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
1350
1351 vat_json_print(vam->ofp, &node);
1352 vat_json_free(&node);
1353
1354 vam->retval = ntohl(mp->retval);
1355 vam->result_ready = 1;
1356}
1357
Chris Luke27fe48f2016-04-28 13:44:38 -04001358static void vl_api_gre_add_del_tunnel_reply_t_handler
1359(vl_api_gre_add_del_tunnel_reply_t * mp)
1360{
1361 vat_main_t * vam = &vat_main;
1362 i32 retval = ntohl(mp->retval);
1363 if (vam->async_mode) {
1364 vam->async_errors += (retval < 0);
1365 } else {
1366 vam->retval = retval;
1367 vam->result_ready = 1;
1368 }
1369}
1370
1371static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1372(vl_api_gre_add_del_tunnel_reply_t * mp)
1373{
1374 vat_main_t * vam = &vat_main;
1375 vat_json_node_t node;
1376
1377 vat_json_init_object(&node);
1378 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1379 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
1380
1381 vat_json_print(vam->ofp, &node);
1382 vat_json_free(&node);
1383
1384 vam->retval = ntohl(mp->retval);
1385 vam->result_ready = 1;
1386}
1387
Ed Warnickecb9cada2015-12-08 15:45:58 -07001388static void vl_api_create_vhost_user_if_reply_t_handler
1389(vl_api_create_vhost_user_if_reply_t * mp)
1390{
1391 vat_main_t * vam = &vat_main;
1392 i32 retval = ntohl(mp->retval);
1393 if (vam->async_mode) {
1394 vam->async_errors += (retval < 0);
1395 } else {
1396 vam->retval = retval;
1397 vam->result_ready = 1;
1398 }
1399}
1400
1401static void vl_api_create_vhost_user_if_reply_t_handler_json
1402(vl_api_create_vhost_user_if_reply_t * mp)
1403{
1404 vat_main_t * vam = &vat_main;
1405 vat_json_node_t node;
1406
1407 vat_json_init_object(&node);
1408 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1409 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
1410
1411 vat_json_print(vam->ofp, &node);
1412 vat_json_free(&node);
1413
1414 vam->retval = ntohl(mp->retval);
1415 vam->result_ready = 1;
1416}
1417
1418static void vl_api_ip_address_details_t_handler
1419(vl_api_ip_address_details_t * mp)
1420{
1421 vat_main_t * vam = &vat_main;
1422 static ip_address_details_t empty_ip_address_details = {{0}};
1423 ip_address_details_t * address = NULL;
1424 ip_details_t * current_ip_details = NULL;
1425 ip_details_t * details = NULL;
1426
1427 details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1428
1429 if (!details || vam->current_sw_if_index >= vec_len(details)
1430 || !details[vam->current_sw_if_index].present) {
1431 errmsg ("ip address details arrived but not stored\n");
1432 errmsg ("ip_dump should be called first\n");
1433 return;
1434 }
1435
1436 current_ip_details = vec_elt_at_index(details,
1437 vam->current_sw_if_index);
1438
1439#define addresses (current_ip_details->addr)
1440
1441 vec_validate_init_empty(addresses, vec_len(addresses),
1442 empty_ip_address_details);
1443
1444 address = vec_elt_at_index(addresses, vec_len(addresses) - 1);
1445
Damjan Marionf1213b82016-03-13 02:22:06 +01001446 clib_memcpy(&address->ip, &mp->ip, sizeof(address->ip));
Ed Warnickecb9cada2015-12-08 15:45:58 -07001447 address->prefix_length = mp->prefix_length;
1448#undef addresses
1449}
1450
1451static void vl_api_ip_address_details_t_handler_json
1452(vl_api_ip_address_details_t * mp)
1453{
1454 vat_main_t * vam = &vat_main;
1455 vat_json_node_t *node = NULL;
1456 struct in6_addr ip6;
1457 struct in_addr ip4;
1458
1459 if (VAT_JSON_ARRAY != vam->json_tree.type) {
1460 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
1461 vat_json_init_array(&vam->json_tree);
1462 }
1463 node = vat_json_array_add(&vam->json_tree);
1464
1465 vat_json_init_object(node);
1466 if (vam->is_ipv6) {
Damjan Marionf1213b82016-03-13 02:22:06 +01001467 clib_memcpy(&ip6, mp->ip, sizeof(ip6));
Ed Warnickecb9cada2015-12-08 15:45:58 -07001468 vat_json_object_add_ip6(node, "ip", ip6);
1469 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01001470 clib_memcpy(&ip4, mp->ip, sizeof(ip4));
Ed Warnickecb9cada2015-12-08 15:45:58 -07001471 vat_json_object_add_ip4(node, "ip", ip4);
1472 }
1473 vat_json_object_add_uint(node, "prefix_length", mp->prefix_length);
1474}
1475
1476static void vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1477{
1478 vat_main_t * vam = &vat_main;
1479 static ip_details_t empty_ip_details = {0};
1480 ip_details_t * ip = NULL;
1481 u32 sw_if_index = ~0;
1482
1483 sw_if_index = ntohl(mp->sw_if_index);
1484
1485 vec_validate_init_empty(vam->ip_details_by_sw_if_index[vam->is_ipv6],
1486 sw_if_index, empty_ip_details);
1487
1488 ip = vec_elt_at_index(vam->ip_details_by_sw_if_index[vam->is_ipv6],
1489 sw_if_index);
1490
1491 ip->present = 1;
1492}
1493
1494static void vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1495{
1496 vat_main_t * vam = &vat_main;
1497
1498 if (VAT_JSON_ARRAY != vam->json_tree.type) {
1499 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
1500 vat_json_init_array(&vam->json_tree);
1501 }
1502 vat_json_array_add_uint(&vam->json_tree, clib_net_to_host_u32(mp->sw_if_index));
1503}
1504
1505static void vl_api_map_domain_details_t_handler_json
1506(vl_api_map_domain_details_t * mp)
1507{
1508 vat_json_node_t * node = NULL;
1509 vat_main_t * vam = &vat_main;
1510 struct in6_addr ip6;
1511 struct in_addr ip4;
1512
1513 if (VAT_JSON_ARRAY != vam->json_tree.type) {
1514 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
1515 vat_json_init_array(&vam->json_tree);
1516 }
1517
1518 node = vat_json_array_add(&vam->json_tree);
1519 vat_json_init_object(node);
1520
1521 vat_json_object_add_uint(node, "domain_index", clib_net_to_host_u32(mp->domain_index));
Damjan Marionf1213b82016-03-13 02:22:06 +01001522 clib_memcpy(&ip6, mp->ip6_prefix, sizeof(ip6));
Ed Warnickecb9cada2015-12-08 15:45:58 -07001523 vat_json_object_add_ip6(node, "ip6_prefix", ip6);
Damjan Marionf1213b82016-03-13 02:22:06 +01001524 clib_memcpy(&ip4, mp->ip4_prefix, sizeof(ip4));
Ed Warnickecb9cada2015-12-08 15:45:58 -07001525 vat_json_object_add_ip4(node, "ip4_prefix", ip4);
Damjan Marionf1213b82016-03-13 02:22:06 +01001526 clib_memcpy(&ip6, mp->ip6_src, sizeof(ip6));
Ed Warnickecb9cada2015-12-08 15:45:58 -07001527 vat_json_object_add_ip6(node, "ip6_src", ip6);
1528 vat_json_object_add_int(node, "ip6_prefix_len", mp->ip6_prefix_len);
1529 vat_json_object_add_int(node, "ip4_prefix_len", mp->ip4_prefix_len);
1530 vat_json_object_add_int(node, "ip6_src_len", mp->ip6_src_len);
1531 vat_json_object_add_int(node, "ea_bits_len", mp->ea_bits_len);
1532 vat_json_object_add_int(node, "psid_offset", mp->psid_offset);
1533 vat_json_object_add_int(node, "psid_length", mp->psid_length);
1534 vat_json_object_add_uint(node, "flags", mp->flags);
1535 vat_json_object_add_uint(node, "mtu", clib_net_to_host_u16(mp->mtu));
1536 vat_json_object_add_int(node, "is_translation", mp->is_translation);
1537}
1538
1539static void vl_api_map_domain_details_t_handler
1540(vl_api_map_domain_details_t * mp)
1541{
1542 vat_main_t * vam = &vat_main;
1543
1544 if (mp->is_translation) {
1545 fformat(vam->ofp, "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u\n",
1546 format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1547 format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1548 format_ip6_address, mp->ip6_src, mp->ip6_src_len, clib_net_to_host_u32(mp->domain_index));
1549 } else {
1550 fformat(vam->ofp, "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u\n",
1551 format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1552 format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1553 format_ip6_address, mp->ip6_src, clib_net_to_host_u32(mp->domain_index));
1554 }
1555 fformat(vam->ofp, " ea-len %d psid-offset %d psid-len %d mtu %d %s\n",
1556 mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu, mp->is_translation? "map-t":"");
1557}
1558
1559static void vl_api_map_rule_details_t_handler_json
1560(vl_api_map_rule_details_t * mp)
1561{
1562 struct in6_addr ip6;
1563 vat_json_node_t * node = NULL;
1564 vat_main_t * vam = &vat_main;
1565
1566 if (VAT_JSON_ARRAY != vam->json_tree.type) {
1567 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
1568 vat_json_init_array(&vam->json_tree);
1569 }
1570
1571 node = vat_json_array_add(&vam->json_tree);
1572 vat_json_init_object(node);
1573
1574 vat_json_object_add_uint(node, "psid", clib_net_to_host_u16(mp->psid));
Damjan Marionf1213b82016-03-13 02:22:06 +01001575 clib_memcpy(&ip6, mp->ip6_dst, sizeof(ip6));
Ed Warnickecb9cada2015-12-08 15:45:58 -07001576 vat_json_object_add_ip6(node, "ip6_dst", ip6);
1577}
1578
1579static void vl_api_map_rule_details_t_handler
1580(vl_api_map_rule_details_t * mp)
1581{
1582 vat_main_t * vam = &vat_main;
1583 fformat(vam->ofp, " %d (psid) %U (ip6-dst)\n", clib_net_to_host_u16(mp->psid),
1584 format_ip6_address, mp->ip6_dst);
1585}
1586
1587static void vl_api_dhcp_compl_event_t_handler
1588(vl_api_dhcp_compl_event_t * mp)
1589{
1590 vat_main_t * vam = &vat_main;
1591 errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1592 "router_addr %U host_mac %U\n",
1593 mp->pid, mp->is_ipv6 ? "ipv6":"ipv4", mp->hostname,
1594 format_ip4_address, &mp->host_address,
1595 format_ip4_address, &mp->router_address,
1596 format_ethernet_address, mp->host_mac);
1597}
1598
1599static void vl_api_dhcp_compl_event_t_handler_json
1600(vl_api_dhcp_compl_event_t * mp)
1601{
1602 /* JSON output not supported */
1603}
1604
1605static void set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1606 u32 counter)
1607{
1608 vat_main_t * vam = &vat_main;
1609 static u64 default_counter = 0;
1610
1611 vec_validate_init_empty(vam->simple_interface_counters, vnet_counter_type, NULL);
1612 vec_validate_init_empty(vam->simple_interface_counters[vnet_counter_type],
1613 sw_if_index, default_counter);
1614 vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1615}
1616
1617static void set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1618 interface_counter_t counter)
1619{
1620 vat_main_t * vam = &vat_main;
1621 static interface_counter_t default_counter = {0, };
1622
1623 vec_validate_init_empty(vam->combined_interface_counters, vnet_counter_type, NULL);
1624 vec_validate_init_empty(vam->combined_interface_counters[vnet_counter_type],
1625 sw_if_index, default_counter);
1626 vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1627}
1628
1629static void vl_api_vnet_interface_counters_t_handler
1630(vl_api_vnet_interface_counters_t *mp)
1631{
1632 /* not supported */
1633}
1634
1635static void vl_api_vnet_interface_counters_t_handler_json
1636(vl_api_vnet_interface_counters_t *mp)
1637{
1638 interface_counter_t counter;
1639 vlib_counter_t *v;
1640 u64 *v_packets;
1641 u64 packets;
1642 u32 count;
1643 u32 first_sw_if_index;
1644 int i;
1645
1646 count = ntohl(mp->count);
1647 first_sw_if_index = ntohl(mp->first_sw_if_index);
1648
1649 if (!mp->is_combined) {
1650 v_packets = (u64*)&mp->data;
1651 for (i = 0; i < count; i++) {
1652 packets = clib_net_to_host_u64(clib_mem_unaligned(v_packets, u64));
1653 set_simple_interface_counter(mp->vnet_counter_type,
1654 first_sw_if_index + i, packets);
1655 v_packets++;
1656 }
1657 } else {
1658 v = (vlib_counter_t*)&mp->data;
1659 for (i = 0; i < count; i++) {
1660 counter.packets = clib_net_to_host_u64(
1661 clib_mem_unaligned(&v->packets, u64));
1662 counter.bytes = clib_net_to_host_u64(
1663 clib_mem_unaligned(&v->bytes, u64));
1664 set_combined_interface_counter(mp->vnet_counter_type,
1665 first_sw_if_index + i, counter);
1666 v++;
1667 }
1668 }
1669}
1670
1671static u32 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1672{
1673 vat_main_t * vam = &vat_main;
1674 u32 i;
1675
1676 for (i = 0; i < vec_len(vam->ip4_fib_counters_vrf_id_by_index); i++) {
1677 if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id) {
1678 return i;
1679 }
1680 }
1681 return ~0;
1682}
1683
1684static u32 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1685{
1686 vat_main_t * vam = &vat_main;
1687 u32 i;
1688
1689 for (i = 0; i < vec_len(vam->ip6_fib_counters_vrf_id_by_index); i++) {
1690 if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id) {
1691 return i;
1692 }
1693 }
1694 return ~0;
1695}
1696
1697static void vl_api_vnet_ip4_fib_counters_t_handler
1698(vl_api_vnet_ip4_fib_counters_t *mp)
1699{
1700 /* not supported */
1701}
1702
1703static void vl_api_vnet_ip4_fib_counters_t_handler_json
1704(vl_api_vnet_ip4_fib_counters_t *mp)
1705{
1706 vat_main_t * vam = &vat_main;
1707 vl_api_ip4_fib_counter_t *v;
1708 ip4_fib_counter_t *counter;
1709 struct in_addr ip4;
1710 u32 vrf_id;
1711 u32 vrf_index;
1712 u32 count;
1713 int i;
1714
1715 vrf_id = ntohl(mp->vrf_id);
1716 vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id(vrf_id);
1717 if (~0 == vrf_index) {
1718 vrf_index = vec_len(vam->ip4_fib_counters_vrf_id_by_index);
1719 vec_validate(vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
1720 vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
1721 vec_validate(vam->ip4_fib_counters, vrf_index);
1722 vam->ip4_fib_counters[vrf_index] = NULL;
1723 }
1724
1725 vec_free(vam->ip4_fib_counters[vrf_index]);
1726 v = (vl_api_ip4_fib_counter_t*)&mp->c;
1727 count = ntohl(mp->count);
1728 for (i = 0; i < count; i++) {
1729 vec_validate(vam->ip4_fib_counters[vrf_index], i);
1730 counter = &vam->ip4_fib_counters[vrf_index][i];
Damjan Marionf1213b82016-03-13 02:22:06 +01001731 clib_memcpy(&ip4, &v->address, sizeof(ip4));
Ed Warnickecb9cada2015-12-08 15:45:58 -07001732 counter->address = ip4;
1733 counter->address_length = v->address_length;
1734 counter->packets = clib_net_to_host_u64(v->packets);
1735 counter->bytes = clib_net_to_host_u64(v->bytes);
1736 v++;
1737 }
1738}
1739
1740static void vl_api_vnet_ip6_fib_counters_t_handler
1741(vl_api_vnet_ip6_fib_counters_t *mp)
1742{
1743 /* not supported */
1744}
1745
1746static void vl_api_vnet_ip6_fib_counters_t_handler_json
1747(vl_api_vnet_ip6_fib_counters_t *mp)
1748{
1749 vat_main_t * vam = &vat_main;
1750 vl_api_ip6_fib_counter_t *v;
1751 ip6_fib_counter_t *counter;
1752 struct in6_addr ip6;
1753 u32 vrf_id;
1754 u32 vrf_index;
1755 u32 count;
1756 int i;
1757
1758 vrf_id = ntohl(mp->vrf_id);
1759 vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id(vrf_id);
1760 if (~0 == vrf_index) {
1761 vrf_index = vec_len(vam->ip6_fib_counters_vrf_id_by_index);
1762 vec_validate(vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
1763 vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
1764 vec_validate(vam->ip6_fib_counters, vrf_index);
1765 vam->ip6_fib_counters[vrf_index] = NULL;
1766 }
1767
1768 vec_free(vam->ip6_fib_counters[vrf_index]);
1769 v = (vl_api_ip6_fib_counter_t*)&mp->c;
1770 count = ntohl(mp->count);
1771 for (i = 0; i < count; i++) {
1772 vec_validate(vam->ip6_fib_counters[vrf_index], i);
1773 counter = &vam->ip6_fib_counters[vrf_index][i];
Damjan Marionf1213b82016-03-13 02:22:06 +01001774 clib_memcpy(&ip6, &v->address, sizeof(ip6));
Ed Warnickecb9cada2015-12-08 15:45:58 -07001775 counter->address = ip6;
1776 counter->address_length = v->address_length;
1777 counter->packets = clib_net_to_host_u64(v->packets);
1778 counter->bytes = clib_net_to_host_u64(v->bytes);
1779 v++;
1780 }
1781}
1782
1783static void vl_api_get_first_msg_id_reply_t_handler
1784(vl_api_get_first_msg_id_reply_t * mp)
1785{
1786 vat_main_t * vam = &vat_main;
1787 i32 retval = ntohl(mp->retval);
1788
1789 if (vam->async_mode) {
1790 vam->async_errors += (retval < 0);
1791 } else {
1792 vam->retval = retval;
1793 vam->result_ready = 1;
1794 }
1795 if (retval >= 0) {
1796 errmsg ("first message id %d\n", ntohs(mp->first_msg_id));
1797 }
1798}
1799
1800static void vl_api_get_first_msg_id_reply_t_handler_json
1801(vl_api_get_first_msg_id_reply_t * mp)
1802{
1803 vat_main_t * vam = &vat_main;
1804 vat_json_node_t node;
1805
1806 vat_json_init_object(&node);
1807 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1808 vat_json_object_add_uint(&node, "first_msg_id",
1809 (uint) ntohs(mp->first_msg_id));
1810
1811 vat_json_print(vam->ofp, &node);
1812 vat_json_free(&node);
1813
1814 vam->retval = ntohl(mp->retval);
1815 vam->result_ready = 1;
1816}
1817
Dave Barachb44e9bc2016-02-19 09:06:23 -05001818static void vl_api_get_node_graph_reply_t_handler
1819(vl_api_get_node_graph_reply_t * mp)
1820{
1821 vat_main_t * vam = &vat_main;
1822 api_main_t * am = &api_main;
1823 i32 retval = ntohl(mp->retval);
1824 u8 * pvt_copy, * reply;
1825 void * oldheap;
1826 vlib_node_t * node;
1827 int i;
1828
1829 if (vam->async_mode) {
1830 vam->async_errors += (retval < 0);
1831 } else {
1832 vam->retval = retval;
1833 vam->result_ready = 1;
1834 }
1835
1836 /* "Should never happen..." */
1837 if (retval != 0)
1838 return;
1839
1840 reply = (u8 *)(mp->reply_in_shmem);
1841 pvt_copy = vec_dup (reply);
1842
1843 /* Toss the shared-memory original... */
1844 pthread_mutex_lock (&am->vlib_rp->mutex);
1845 oldheap = svm_push_data_heap (am->vlib_rp);
1846
1847 vec_free (reply);
1848
1849 svm_pop_heap (oldheap);
1850 pthread_mutex_unlock (&am->vlib_rp->mutex);
1851
1852 if (vam->graph_nodes) {
1853 hash_free (vam->graph_node_index_by_name);
1854
1855 for (i = 0; i < vec_len (vam->graph_nodes); i++) {
1856 node = vam->graph_nodes[i];
1857 vec_free (node->name);
1858 vec_free (node->next_nodes);
1859 vec_free (node);
1860 }
1861 vec_free(vam->graph_nodes);
1862 }
1863
1864 vam->graph_node_index_by_name = hash_create_string (0, sizeof(uword));
1865 vam->graph_nodes = vlib_node_unserialize (pvt_copy);
1866 vec_free (pvt_copy);
1867
1868 for (i = 0; i < vec_len (vam->graph_nodes); i++) {
1869 node = vam->graph_nodes[i];
1870 hash_set_mem (vam->graph_node_index_by_name, node->name, i);
1871 }
1872}
1873
1874static void vl_api_get_node_graph_reply_t_handler_json
1875(vl_api_get_node_graph_reply_t * mp)
1876{
1877 vat_main_t * vam = &vat_main;
1878 api_main_t * am = &api_main;
1879 void * oldheap;
1880 vat_json_node_t node;
1881 u8 * reply;
1882
1883 /* $$$$ make this real? */
1884 vat_json_init_object(&node);
1885 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1886 vat_json_object_add_uint(&node, "reply_in_shmem", mp->reply_in_shmem);
1887
1888 reply = (u8 *)(mp->reply_in_shmem);
1889
1890 /* Toss the shared-memory original... */
1891 pthread_mutex_lock (&am->vlib_rp->mutex);
1892 oldheap = svm_push_data_heap (am->vlib_rp);
1893
1894 vec_free (reply);
1895
1896 svm_pop_heap (oldheap);
1897 pthread_mutex_unlock (&am->vlib_rp->mutex);
1898
1899 vat_json_print(vam->ofp, &node);
1900 vat_json_free(&node);
1901
1902 vam->retval = ntohl(mp->retval);
1903 vam->result_ready = 1;
1904}
1905
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02001906static void
1907vl_api_lisp_locator_set_details_t_handler (
1908 vl_api_lisp_locator_set_details_t *mp)
1909{
1910 vat_main_t *vam = &vat_main;
1911
1912 fformat(vam->ofp, "%=20s%=16d%=16d%=16d\n",
1913 mp->locator_set_name,
1914 ntohl(mp->sw_if_index),
1915 mp->priority,
1916 mp->weight);
1917}
1918
1919static void
1920vl_api_lisp_locator_set_details_t_handler_json (
1921 vl_api_lisp_locator_set_details_t *mp)
1922{
1923 vat_main_t *vam = &vat_main;
1924 vat_json_node_t *node = NULL;
1925
1926 if (VAT_JSON_ARRAY != vam->json_tree.type) {
1927 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
1928 vat_json_init_array(&vam->json_tree);
1929 }
1930 node = vat_json_array_add(&vam->json_tree);
1931
1932 vat_json_init_object(node);
1933 vat_json_object_add_string_copy(node, "locator-set", mp->locator_set_name);
1934 vat_json_object_add_uint(node, "locator", ntohl(mp->sw_if_index));
1935 vat_json_object_add_uint(node, "priority", mp->priority);
1936 vat_json_object_add_uint(node, "weight", mp->weight);
1937}
1938
1939static void
1940vl_api_lisp_local_eid_table_details_t_handler (
1941 vl_api_lisp_local_eid_table_details_t *mp)
1942{
1943 vat_main_t *vam = &vat_main;
1944 u8 *prefix;
1945
1946 prefix = format(0, "%U/%d",
1947 mp->eid_is_ipv6 ? format_ip6_address : format_ip4_address,
1948 mp->eid_ip_address,
1949 mp->eid_prefix_len);
1950
1951 fformat(vam->ofp, "%=20s%=30s\n",
1952 mp->locator_set_name, prefix);
1953
1954 vec_free(prefix);
1955}
1956
1957static void
1958vl_api_lisp_local_eid_table_details_t_handler_json (
1959 vl_api_lisp_local_eid_table_details_t *mp)
1960{
1961 vat_main_t *vam = &vat_main;
1962 vat_json_node_t *node = NULL;
1963 struct in6_addr ip6;
1964 struct in_addr ip4;
1965
1966 if (VAT_JSON_ARRAY != vam->json_tree.type) {
1967 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
1968 vat_json_init_array(&vam->json_tree);
1969 }
1970 node = vat_json_array_add(&vam->json_tree);
1971
1972 vat_json_init_object(node);
1973 vat_json_object_add_string_copy(node, "locator-set", mp->locator_set_name);
1974 if (mp->eid_is_ipv6) {
Damjan Marionf1213b82016-03-13 02:22:06 +01001975 clib_memcpy(&ip6, mp->eid_ip_address, sizeof(ip6));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02001976 vat_json_object_add_ip6(node, "eid address", ip6);
1977 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01001978 clib_memcpy(&ip4, mp->eid_ip_address, sizeof(ip4));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02001979 vat_json_object_add_ip4(node, "eid address", ip4);
1980 }
1981 vat_json_object_add_uint(node, "eid prefix len", mp->eid_prefix_len);
1982}
1983
1984static u8 *
1985format_decap_next (u8 * s, va_list * args)
1986{
1987 u32 next_index = va_arg (*args, u32);
1988
1989 switch (next_index)
1990 {
1991 case LISP_GPE_INPUT_NEXT_DROP:
1992 return format (s, "drop");
1993 case LISP_GPE_INPUT_NEXT_IP4_INPUT:
1994 return format (s, "ip4");
1995 case LISP_GPE_INPUT_NEXT_IP6_INPUT:
1996 return format (s, "ip6");
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02001997 default:
1998 return format (s, "unknown %d", next_index);
1999 }
2000 return s;
2001}
2002
2003static void
2004vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *mp)
2005{
2006 vat_main_t *vam = &vat_main;
2007 u8 *iid_str;
2008 u8 *flag_str = NULL;
2009
2010 iid_str = format(0, "%d (0x%x)", ntohl(mp->iid), ntohl(mp->iid));
2011
2012#define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n);
2013 foreach_lisp_gpe_flag_bit;
2014#undef _
2015
2016 fformat(vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U"
2017 "%=16d%=16d%=16sd=16d%=16s%=16s\n",
2018 mp->tunnels,
2019 mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2020 mp->source_ip,
2021 mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2022 mp->destination_ip,
2023 ntohl(mp->encap_fib_id),
2024 ntohl(mp->decap_fib_id),
2025 format_decap_next, ntohl(mp->dcap_next),
2026 mp->ver_res >> 6,
2027 flag_str,
2028 mp->next_protocol,
2029 mp->ver_res,
2030 mp->res,
2031 iid_str);
2032
2033 vec_free(iid_str);
2034}
2035
2036static void
2037vl_api_lisp_gpe_tunnel_details_t_handler_json (
2038 vl_api_lisp_gpe_tunnel_details_t *mp)
2039{
2040 vat_main_t *vam = &vat_main;
2041 vat_json_node_t *node = NULL;
2042 struct in6_addr ip6;
2043 struct in_addr ip4;
2044 u8 *next_decap_str;
2045
2046 next_decap_str = format(0, "%U", format_decap_next, htonl(mp->dcap_next));
2047
2048 if (VAT_JSON_ARRAY != vam->json_tree.type) {
2049 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
2050 vat_json_init_array(&vam->json_tree);
2051 }
2052 node = vat_json_array_add(&vam->json_tree);
2053
2054 vat_json_init_object(node);
2055 vat_json_object_add_uint(node, "tunel", mp->tunnels);
2056 if (mp->is_ipv6) {
Damjan Marionf1213b82016-03-13 02:22:06 +01002057 clib_memcpy(&ip6, mp->source_ip, sizeof(ip6));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002058 vat_json_object_add_ip6(node, "source address", ip6);
Damjan Marionf1213b82016-03-13 02:22:06 +01002059 clib_memcpy(&ip6, mp->destination_ip, sizeof(ip6));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002060 vat_json_object_add_ip6(node, "destination address", ip6);
2061 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01002062 clib_memcpy(&ip4, mp->source_ip, sizeof(ip4));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002063 vat_json_object_add_ip4(node, "source address", ip4);
Damjan Marionf1213b82016-03-13 02:22:06 +01002064 clib_memcpy(&ip4, mp->destination_ip, sizeof(ip4));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002065 vat_json_object_add_ip4(node, "destination address", ip4);
2066 }
2067 vat_json_object_add_uint(node, "fib encap", ntohl(mp->encap_fib_id));
2068 vat_json_object_add_uint(node, "fib decap", ntohl(mp->decap_fib_id));
2069 vat_json_object_add_string_copy(node, "decap next", next_decap_str);
2070 vat_json_object_add_uint(node, "lisp version", mp->ver_res >> 6);
2071 vat_json_object_add_uint(node, "flags", mp->flags);
2072 vat_json_object_add_uint(node, "next protocol", mp->next_protocol);
2073 vat_json_object_add_uint(node, "ver_res", mp->ver_res);
2074 vat_json_object_add_uint(node, "res", mp->res);
2075 vat_json_object_add_uint(node, "iid", ntohl(mp->iid));
2076
2077 vec_free(next_decap_str);
2078}
2079
2080static void
2081vl_api_lisp_map_resolver_details_t_handler (
2082 vl_api_lisp_map_resolver_details_t *mp)
2083{
2084 vat_main_t *vam = &vat_main;
2085
2086 fformat(vam->ofp, "%=20U\n",
2087 mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2088 mp->ip_address);
2089}
2090
2091static void
2092vl_api_lisp_map_resolver_details_t_handler_json (
2093 vl_api_lisp_map_resolver_details_t *mp)
2094{
2095 vat_main_t *vam = &vat_main;
2096 vat_json_node_t *node = NULL;
2097 struct in6_addr ip6;
2098 struct in_addr ip4;
2099
2100 if (VAT_JSON_ARRAY != vam->json_tree.type) {
2101 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
2102 vat_json_init_array(&vam->json_tree);
2103 }
2104 node = vat_json_array_add(&vam->json_tree);
2105
2106 vat_json_init_object(node);
2107 if (mp->is_ipv6) {
Damjan Marionf1213b82016-03-13 02:22:06 +01002108 clib_memcpy(&ip6, mp->ip_address, sizeof(ip6));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002109 vat_json_object_add_ip6(node, "map resolver", ip6);
2110 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01002111 clib_memcpy(&ip4, mp->ip_address, sizeof(ip4));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002112 vat_json_object_add_ip4(node, "map resolver", ip4);
2113 }
2114}
2115
Ed Warnickecb9cada2015-12-08 15:45:58 -07002116#define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
2117#define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
2118#define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
2119#define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
2120
2121/*
2122 * Generate boilerplate reply handlers, which
2123 * dig the return value out of the xxx_reply_t API message,
2124 * stick it into vam->retval, and set vam->result_ready
2125 *
2126 * Could also do this by pointing N message decode slots at
2127 * a single function, but that could break in subtle ways.
2128 */
2129
2130#define foreach_standard_reply_retval_handler \
2131_(sw_interface_set_flags_reply) \
2132_(sw_interface_add_del_address_reply) \
2133_(sw_interface_set_table_reply) \
2134_(sw_interface_set_vpath_reply) \
2135_(sw_interface_set_l2_bridge_reply) \
2136_(bridge_domain_add_del_reply) \
2137_(sw_interface_set_l2_xconnect_reply) \
2138_(l2fib_add_del_reply) \
2139_(ip_add_del_route_reply) \
2140_(proxy_arp_add_del_reply) \
2141_(proxy_arp_intfc_enable_disable_reply) \
2142_(mpls_add_del_encap_reply) \
2143_(mpls_add_del_decap_reply) \
2144_(mpls_ethernet_add_del_tunnel_2_reply) \
2145_(sw_interface_set_unnumbered_reply) \
2146_(ip_neighbor_add_del_reply) \
2147_(reset_vrf_reply) \
2148_(oam_add_del_reply) \
2149_(reset_fib_reply) \
2150_(dhcp_proxy_config_reply) \
2151_(dhcp_proxy_config_2_reply) \
2152_(dhcp_proxy_set_vss_reply) \
2153_(dhcp_client_config_reply) \
2154_(set_ip_flow_hash_reply) \
2155_(sw_interface_ip6_enable_disable_reply) \
2156_(sw_interface_ip6_set_link_local_address_reply) \
2157_(sw_interface_ip6nd_ra_prefix_reply) \
2158_(sw_interface_ip6nd_ra_config_reply) \
2159_(set_arp_neighbor_limit_reply) \
2160_(l2_patch_add_del_reply) \
2161_(sr_tunnel_add_del_reply) \
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07002162_(sr_policy_add_del_reply) \
2163_(sr_multicast_map_add_del_reply) \
Ed Warnickecb9cada2015-12-08 15:45:58 -07002164_(classify_add_del_session_reply) \
2165_(classify_set_interface_ip_table_reply) \
2166_(classify_set_interface_l2_tables_reply) \
2167_(l2tpv3_set_tunnel_cookies_reply) \
2168_(l2tpv3_interface_enable_disable_reply) \
2169_(l2tpv3_set_lookup_key_reply) \
2170_(l2_fib_clear_table_reply) \
2171_(l2_interface_efp_filter_reply) \
2172_(l2_interface_vlan_tag_rewrite_reply) \
2173_(modify_vhost_user_if_reply) \
2174_(delete_vhost_user_if_reply) \
2175_(want_ip4_arp_events_reply) \
2176_(input_acl_set_interface_reply) \
2177_(ipsec_spd_add_del_reply) \
2178_(ipsec_interface_add_del_spd_reply) \
2179_(ipsec_spd_add_del_entry_reply) \
2180_(ipsec_sad_add_del_entry_reply) \
2181_(ipsec_sa_set_key_reply) \
Matus Fabiane5f42fe2016-04-08 11:18:08 +02002182_(ikev2_profile_add_del_reply) \
2183_(ikev2_profile_set_auth_reply) \
2184_(ikev2_profile_set_id_reply) \
2185_(ikev2_profile_set_ts_reply) \
2186_(ikev2_set_local_key_reply) \
Ed Warnickecb9cada2015-12-08 15:45:58 -07002187_(delete_loopback_reply) \
2188_(bd_ip_mac_add_del_reply) \
2189_(map_del_domain_reply) \
2190_(map_add_del_rule_reply) \
2191_(want_interface_events_reply) \
Dave Barachc07bf5d2016-02-17 17:52:26 -05002192_(want_stats_reply) \
2193_(cop_interface_enable_disable_reply) \
Pavel Kotucek00bbf272016-03-03 13:27:11 +01002194_(cop_whitelist_enable_disable_reply) \
Shwetha20a64f52016-03-25 10:55:01 +00002195_(sw_interface_clear_stats_reply) \
2196_(trace_profile_add_reply) \
2197_(trace_profile_apply_reply) \
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002198_(trace_profile_del_reply) \
2199_(lisp_add_del_locator_set_reply) \
2200_(lisp_add_del_locator_reply) \
2201_(lisp_add_del_local_eid_reply) \
2202_(lisp_gpe_add_del_fwd_entry_reply) \
2203_(lisp_add_del_map_resolver_reply) \
Florin Coras577c3552016-04-21 00:45:40 +02002204_(lisp_gpe_enable_disable_reply) \
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002205_(lisp_gpe_add_del_iface_reply)
Ed Warnickecb9cada2015-12-08 15:45:58 -07002206
2207#define _(n) \
2208 static void vl_api_##n##_t_handler \
2209 (vl_api_##n##_t * mp) \
2210 { \
2211 vat_main_t * vam = &vat_main; \
2212 i32 retval = ntohl(mp->retval); \
2213 if (vam->async_mode) { \
2214 vam->async_errors += (retval < 0); \
2215 } else { \
2216 vam->retval = retval; \
2217 vam->result_ready = 1; \
2218 } \
2219 }
2220foreach_standard_reply_retval_handler;
2221#undef _
2222
2223#define _(n) \
2224 static void vl_api_##n##_t_handler_json \
2225 (vl_api_##n##_t * mp) \
2226 { \
2227 vat_main_t * vam = &vat_main; \
2228 vat_json_node_t node; \
2229 vat_json_init_object(&node); \
2230 vat_json_object_add_int(&node, "retval", ntohl(mp->retval)); \
2231 vat_json_print(vam->ofp, &node); \
2232 vam->retval = ntohl(mp->retval); \
2233 vam->result_ready = 1; \
2234 }
2235foreach_standard_reply_retval_handler;
2236#undef _
2237
2238/*
2239 * Table of message reply handlers, must include boilerplate handlers
2240 * we just generated
2241 */
2242
2243#define foreach_vpe_api_reply_msg \
2244_(CREATE_LOOPBACK_REPLY, create_loopback_reply) \
2245_(SW_INTERFACE_DETAILS, sw_interface_details) \
2246_(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags) \
2247_(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply) \
2248_(CONTROL_PING_REPLY, control_ping_reply) \
2249_(CLI_REPLY, cli_reply) \
2250_(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY, \
2251 sw_interface_add_del_address_reply) \
2252_(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply) \
2253_(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply) \
2254_(SW_INTERFACE_SET_L2_XCONNECT_REPLY, \
2255 sw_interface_set_l2_xconnect_reply) \
2256_(SW_INTERFACE_SET_L2_BRIDGE_REPLY, \
2257 sw_interface_set_l2_bridge_reply) \
2258_(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply) \
2259_(BRIDGE_DOMAIN_DETAILS, bridge_domain_details) \
2260_(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details) \
2261_(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply) \
2262_(L2_FLAGS_REPLY, l2_flags_reply) \
2263_(BRIDGE_FLAGS_REPLY, bridge_flags_reply) \
2264_(TAP_CONNECT_REPLY, tap_connect_reply) \
2265_(TAP_MODIFY_REPLY, tap_modify_reply) \
2266_(TAP_DELETE_REPLY, tap_delete_reply) \
2267_(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details) \
2268_(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply) \
2269_(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply) \
2270_(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY, \
2271 proxy_arp_intfc_enable_disable_reply) \
2272_(MPLS_ADD_DEL_ENCAP_REPLY, mpls_add_del_encap_reply) \
2273_(MPLS_ADD_DEL_DECAP_REPLY, mpls_add_del_decap_reply) \
2274_(MPLS_GRE_ADD_DEL_TUNNEL_REPLY, mpls_gre_add_del_tunnel_reply) \
2275_(MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY, \
2276 mpls_ethernet_add_del_tunnel_reply) \
2277_(MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY, \
2278 mpls_ethernet_add_del_tunnel_2_reply) \
2279_(SW_INTERFACE_SET_UNNUMBERED_REPLY, \
2280 sw_interface_set_unnumbered_reply) \
2281_(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply) \
2282_(RESET_VRF_REPLY, reset_vrf_reply) \
2283_(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply) \
2284_(CREATE_SUBIF_REPLY, create_subif_reply) \
2285_(OAM_ADD_DEL_REPLY, oam_add_del_reply) \
2286_(RESET_FIB_REPLY, reset_fib_reply) \
2287_(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply) \
2288_(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply) \
2289_(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply) \
2290_(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply) \
2291_(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply) \
2292_(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY, \
2293 sw_interface_ip6_enable_disable_reply) \
2294_(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY, \
2295 sw_interface_ip6_set_link_local_address_reply) \
2296_(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY, \
2297 sw_interface_ip6nd_ra_prefix_reply) \
2298_(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY, \
2299 sw_interface_ip6nd_ra_config_reply) \
2300_(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply) \
2301_(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply) \
2302_(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply) \
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07002303_(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply) \
2304_(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply) \
Ed Warnickecb9cada2015-12-08 15:45:58 -07002305_(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply) \
2306_(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply) \
2307_(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY, \
2308classify_set_interface_ip_table_reply) \
2309_(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY, \
2310 classify_set_interface_l2_tables_reply) \
2311_(GET_NODE_INDEX_REPLY, get_node_index_reply) \
2312_(ADD_NODE_NEXT_REPLY, add_node_next_reply) \
2313_(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply) \
2314_(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply) \
2315_(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY, \
2316 l2tpv3_interface_enable_disable_reply) \
2317_(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply) \
2318_(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details) \
2319_(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply) \
Dave Wallace60231f32015-12-17 21:04:30 -05002320_(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details) \
Chris Luke27fe48f2016-04-28 13:44:38 -04002321_(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply) \
2322_(GRE_TUNNEL_DETAILS, gre_tunnel_details) \
Ed Warnickecb9cada2015-12-08 15:45:58 -07002323_(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply) \
2324_(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply) \
2325_(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
2326_(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details) \
2327_(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply) \
2328_(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply) \
2329_(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply) \
2330_(SHOW_VERSION_REPLY, show_version_reply) \
2331_(NSH_GRE_ADD_DEL_TUNNEL_REPLY, nsh_gre_add_del_tunnel_reply) \
2332_(L2_FIB_TABLE_ENTRY, l2_fib_table_entry) \
2333_(NSH_VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, nsh_vxlan_gpe_add_del_tunnel_reply) \
2334_(LISP_GPE_ADD_DEL_TUNNEL_REPLY, lisp_gpe_add_del_tunnel_reply) \
2335_(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply) \
2336_(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply) \
2337_(IP4_ARP_EVENT, ip4_arp_event) \
2338_(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply) \
2339_(IP_ADDRESS_DETAILS, ip_address_details) \
2340_(IP_DETAILS, ip_details) \
2341_(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply) \
2342_(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
2343_(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply) \
2344_(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply) \
2345_(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply) \
Matus Fabiane5f42fe2016-04-08 11:18:08 +02002346_(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply) \
2347_(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply) \
2348_(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply) \
2349_(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply) \
2350_(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply) \
Ed Warnickecb9cada2015-12-08 15:45:58 -07002351_(DELETE_LOOPBACK_REPLY, delete_loopback_reply) \
2352_(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply) \
2353_(DHCP_COMPL_EVENT, dhcp_compl_event) \
2354_(VNET_INTERFACE_COUNTERS, vnet_interface_counters) \
2355_(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters) \
2356_(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters) \
2357_(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply) \
2358_(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply) \
Dave Barachc07bf5d2016-02-17 17:52:26 -05002359_(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply) \
Ed Warnickecb9cada2015-12-08 15:45:58 -07002360_(MAP_DOMAIN_DETAILS, map_domain_details) \
2361_(MAP_RULE_DETAILS, map_rule_details) \
2362_(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply) \
2363_(WANT_STATS_REPLY, want_stats_reply) \
Dave Barachc07bf5d2016-02-17 17:52:26 -05002364_(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply) \
2365_(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
Dave Barachb44e9bc2016-02-19 09:06:23 -05002366_(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
Pavel Kotucek00bbf272016-03-03 13:27:11 +01002367_(GET_NODE_GRAPH_REPLY, get_node_graph_reply) \
Shwetha20a64f52016-03-25 10:55:01 +00002368_(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply) \
2369_(TRACE_PROFILE_ADD_REPLY, trace_profile_add_reply) \
2370_(TRACE_PROFILE_APPLY_REPLY, trace_profile_apply_reply) \
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002371_(TRACE_PROFILE_DEL_REPLY, trace_profile_del_reply) \
2372_(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply) \
2373_(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply) \
2374_(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply) \
2375_(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply) \
2376_(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply) \
Florin Coras577c3552016-04-21 00:45:40 +02002377_(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply) \
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002378_(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply) \
2379_(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details) \
2380_(LISP_LOCAL_EID_TABLE_DETAILS, lisp_local_eid_table_details) \
2381_(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details) \
2382_(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)
Ed Warnickecb9cada2015-12-08 15:45:58 -07002383
2384/* M: construct, but don't yet send a message */
2385
2386#define M(T,t) \
2387do { \
2388 vam->result_ready = 0; \
2389 mp = vl_msg_api_alloc(sizeof(*mp)); \
2390 memset (mp, 0, sizeof (*mp)); \
2391 mp->_vl_msg_id = ntohs (VL_API_##T); \
2392 mp->client_index = vam->my_client_index; \
2393} while(0);
2394
2395#define M2(T,t,n) \
2396do { \
2397 vam->result_ready = 0; \
2398 mp = vl_msg_api_alloc(sizeof(*mp)+(n)); \
2399 memset (mp, 0, sizeof (*mp)); \
2400 mp->_vl_msg_id = ntohs (VL_API_##T); \
2401 mp->client_index = vam->my_client_index; \
2402} while(0);
2403
2404
2405/* S: send a message */
2406#define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
2407
2408/* W: wait for results, with timeout */
2409#define W \
2410do { \
2411 timeout = vat_time_now (vam) + 1.0; \
2412 \
2413 while (vat_time_now (vam) < timeout) { \
2414 if (vam->result_ready == 1) { \
2415 return (vam->retval); \
2416 } \
2417 } \
2418 return -99; \
2419} while(0);
2420
2421typedef struct {
2422 u8 * name;
2423 u32 value;
2424} name_sort_t;
2425
2426
2427#define STR_VTR_OP_CASE(op) \
2428 case L2_VTR_ ## op: \
2429 return "" # op;
2430
2431static const char *str_vtr_op(u32 vtr_op)
2432{
2433 switch(vtr_op) {
2434 STR_VTR_OP_CASE(DISABLED);
2435 STR_VTR_OP_CASE(PUSH_1);
2436 STR_VTR_OP_CASE(PUSH_2);
2437 STR_VTR_OP_CASE(POP_1);
2438 STR_VTR_OP_CASE(POP_2);
2439 STR_VTR_OP_CASE(TRANSLATE_1_1);
2440 STR_VTR_OP_CASE(TRANSLATE_1_2);
2441 STR_VTR_OP_CASE(TRANSLATE_2_1);
2442 STR_VTR_OP_CASE(TRANSLATE_2_2);
2443 }
2444
2445 return "UNKNOWN";
2446}
2447
2448static int dump_sub_interface_table (vat_main_t * vam)
2449{
2450 const sw_interface_subif_t * sub = NULL;
2451
2452 if (vam->json_output) {
2453 clib_warning ("JSON output supported only for VPE API calls and dump_stats_table");
2454 return -99;
2455 }
2456
2457 fformat (vam->ofp,
2458 "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
2459 "Interface", "sw_if_index",
2460 "sub id", "dot1ad", "tags", "outer id",
2461 "inner id", "exact", "default",
2462 "outer any", "inner any");
2463
2464 vec_foreach (sub, vam->sw_if_subif_table) {
2465 fformat (vam->ofp,
2466 "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
2467 sub->interface_name,
2468 sub->sw_if_index,
2469 sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
2470 sub->sub_number_of_tags, sub->sub_outer_vlan_id,
2471 sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
2472 sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
2473 if (sub->vtr_op != L2_VTR_DISABLED) {
2474 fformat (vam->ofp,
2475 " vlan-tag-rewrite - op: %-14s [ dot1q: %d "
2476 "tag1: %d tag2: %d ]\n",
2477 str_vtr_op(sub->vtr_op), sub->vtr_push_dot1q,
2478 sub->vtr_tag1, sub->vtr_tag2);
2479 }
2480 }
2481
2482 return 0;
2483}
2484
Matus Fabiand2dc3df2015-12-14 10:31:33 -05002485static int name_sort_cmp (void * a1, void * a2)
2486{
2487 name_sort_t * n1 = a1;
2488 name_sort_t * n2 = a2;
2489
2490 return strcmp ((char *)n1->name, (char *)n2->name);
2491}
2492
Ed Warnickecb9cada2015-12-08 15:45:58 -07002493static int dump_interface_table (vat_main_t * vam)
2494{
2495 hash_pair_t * p;
2496 name_sort_t * nses = 0, * ns;
2497
2498 if (vam->json_output) {
2499 clib_warning ("JSON output supported only for VPE API calls and dump_stats_table");
2500 return -99;
2501 }
2502
2503 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
2504 ({
2505 vec_add2 (nses, ns, 1);
2506 ns->name = (u8 *)(p->key);
2507 ns->value = (u32) p->value[0];
2508 }));
2509
Matus Fabiand2dc3df2015-12-14 10:31:33 -05002510 vec_sort_with_function (nses, name_sort_cmp);
Ed Warnickecb9cada2015-12-08 15:45:58 -07002511
2512 fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
2513 vec_foreach (ns, nses) {
2514 fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
2515 }
2516 vec_free (nses);
2517 return 0;
2518}
2519
2520static int dump_ip_table (vat_main_t * vam, int is_ipv6)
2521{
2522 const ip_details_t * det = NULL;
2523 const ip_address_details_t * address = NULL;
2524 u32 i = ~0;
2525
2526 fformat (vam->ofp,
2527 "%-12s\n",
2528 "sw_if_index");
2529
Damjan Marionfa693552016-04-26 19:30:36 +02002530 if (0 == vam) {
Ed Warnickecb9cada2015-12-08 15:45:58 -07002531 return 0;
2532 }
2533
2534 vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6]) {
2535 i++;
2536 if (!det->present) {
2537 continue;
2538 }
2539 fformat (vam->ofp,
2540 "%-12d\n",
2541 i);
2542 fformat (vam->ofp,
2543 " %-30s%-13s\n",
2544 "Address", "Prefix length");
2545 if (!det->addr) {
2546 continue;
2547 }
2548 vec_foreach (address, det->addr) {
2549 fformat (vam->ofp,
2550 " %-30U%-13d\n",
2551 is_ipv6 ? format_ip6_address : format_ip4_address,
2552 address->ip,
2553 address->prefix_length);
2554 }
2555 }
2556
2557 return 0;
2558}
2559
2560static int dump_ipv4_table (vat_main_t * vam)
2561{
2562 if (vam->json_output) {
2563 clib_warning ("JSON output supported only for VPE API calls and dump_stats_table");
2564 return -99;
2565 }
2566
2567 return dump_ip_table (vam, 0);
2568}
2569
2570static int dump_ipv6_table (vat_main_t * vam)
2571{
2572 if (vam->json_output) {
2573 clib_warning ("JSON output supported only for VPE API calls and dump_stats_table");
2574 return -99;
2575 }
2576
2577 return dump_ip_table (vam, 1);
2578}
2579
2580static char* counter_type_to_str (u8 counter_type, u8 is_combined)
2581{
2582 if (!is_combined) {
2583 switch(counter_type) {
2584 case VNET_INTERFACE_COUNTER_DROP:
2585 return "drop";
2586 case VNET_INTERFACE_COUNTER_PUNT:
2587 return "punt";
2588 case VNET_INTERFACE_COUNTER_IP4:
2589 return "ip4";
2590 case VNET_INTERFACE_COUNTER_IP6:
2591 return "ip6";
2592 case VNET_INTERFACE_COUNTER_RX_NO_BUF:
2593 return "rx-no-buf";
2594 case VNET_INTERFACE_COUNTER_RX_MISS:
2595 return "rx-miss";
2596 case VNET_INTERFACE_COUNTER_RX_ERROR:
2597 return "rx-error";
2598 case VNET_INTERFACE_COUNTER_TX_ERROR:
2599 return "tx-error";
2600 default:
2601 return "INVALID-COUNTER-TYPE";
2602 }
2603 } else {
2604 switch(counter_type) {
2605 case VNET_INTERFACE_COUNTER_RX:
2606 return "rx";
2607 case VNET_INTERFACE_COUNTER_TX:
2608 return "tx";
2609 default:
2610 return "INVALID-COUNTER-TYPE";
2611 }
2612 }
2613}
2614
2615static int dump_stats_table (vat_main_t * vam)
2616{
2617 vat_json_node_t node;
2618 vat_json_node_t *msg_array;
2619 vat_json_node_t *msg;
2620 vat_json_node_t *counter_array;
2621 vat_json_node_t *counter;
2622 interface_counter_t c;
2623 u64 packets;
2624 ip4_fib_counter_t *c4;
2625 ip6_fib_counter_t *c6;
2626 int i, j;
2627
2628 if (!vam->json_output) {
2629 clib_warning ("dump_stats_table supported only in JSON format");
2630 return -99;
2631 }
2632
2633 vat_json_init_object(&node);
2634
2635 /* interface counters */
2636 msg_array = vat_json_object_add(&node, "interface_counters");
2637 vat_json_init_array(msg_array);
2638 for (i = 0; i < vec_len(vam->simple_interface_counters); i++) {
2639 msg = vat_json_array_add(msg_array);
2640 vat_json_init_object(msg);
2641 vat_json_object_add_string_copy(msg, "vnet_counter_type",
2642 (u8*)counter_type_to_str(i, 0));
2643 vat_json_object_add_int(msg, "is_combined", 0);
2644 counter_array = vat_json_object_add(msg, "data");
2645 vat_json_init_array(counter_array);
2646 for (j = 0; j < vec_len(vam->simple_interface_counters[i]); j++) {
2647 packets = vam->simple_interface_counters[i][j];
2648 vat_json_array_add_uint(counter_array, packets);
2649 }
2650 }
2651 for (i = 0; i < vec_len(vam->combined_interface_counters); i++) {
2652 msg = vat_json_array_add(msg_array);
2653 vat_json_init_object(msg);
2654 vat_json_object_add_string_copy(msg, "vnet_counter_type",
2655 (u8*)counter_type_to_str(i, 1));
2656 vat_json_object_add_int(msg, "is_combined", 1);
2657 counter_array = vat_json_object_add(msg, "data");
2658 vat_json_init_array(counter_array);
2659 for (j = 0; j < vec_len(vam->combined_interface_counters[i]); j++) {
2660 c = vam->combined_interface_counters[i][j];
2661 counter = vat_json_array_add(counter_array);
2662 vat_json_init_object(counter);
2663 vat_json_object_add_uint(counter, "packets", c.packets);
2664 vat_json_object_add_uint(counter, "bytes", c.bytes);
2665 }
2666 }
2667
2668 /* ip4 fib counters */
2669 msg_array = vat_json_object_add(&node, "ip4_fib_counters");
2670 vat_json_init_array(msg_array);
2671 for (i = 0; i < vec_len(vam->ip4_fib_counters); i++) {
2672 msg = vat_json_array_add(msg_array);
2673 vat_json_init_object(msg);
2674 vat_json_object_add_uint(msg, "vrf_id", vam->ip4_fib_counters_vrf_id_by_index[i]);
2675 counter_array = vat_json_object_add(msg, "c");
2676 vat_json_init_array(counter_array);
2677 for (j = 0; j < vec_len(vam->ip4_fib_counters[i]); j++) {
2678 counter = vat_json_array_add(counter_array);
2679 vat_json_init_object(counter);
2680 c4 = &vam->ip4_fib_counters[i][j];
2681 vat_json_object_add_ip4(counter, "address", c4->address);
2682 vat_json_object_add_uint(counter, "address_length", c4->address_length);
2683 vat_json_object_add_uint(counter, "packets", c4->packets);
2684 vat_json_object_add_uint(counter, "bytes", c4->bytes);
2685 }
2686 }
2687
2688 /* ip6 fib counters */
2689 msg_array = vat_json_object_add(&node, "ip6_fib_counters");
2690 vat_json_init_array(msg_array);
2691 for (i = 0; i < vec_len(vam->ip6_fib_counters); i++) {
2692 msg = vat_json_array_add(msg_array);
2693 vat_json_init_object(msg);
2694 vat_json_object_add_uint(msg, "vrf_id", vam->ip6_fib_counters_vrf_id_by_index[i]);
2695 counter_array = vat_json_object_add(msg, "c");
2696 vat_json_init_array(counter_array);
2697 for (j = 0; j < vec_len(vam->ip6_fib_counters[i]); j++) {
2698 counter = vat_json_array_add(counter_array);
2699 vat_json_init_object(counter);
2700 c6 = &vam->ip6_fib_counters[i][j];
2701 vat_json_object_add_ip6(counter, "address", c6->address);
2702 vat_json_object_add_uint(counter, "address_length", c6->address_length);
2703 vat_json_object_add_uint(counter, "packets", c6->packets);
2704 vat_json_object_add_uint(counter, "bytes", c6->bytes);
2705 }
2706 }
2707
2708 vat_json_print(vam->ofp, &node);
2709 vat_json_free(&node);
2710
2711 return 0;
2712}
2713
2714int exec (vat_main_t * vam)
2715{
2716 api_main_t * am = &api_main;
2717 vl_api_cli_request_t *mp;
2718 f64 timeout;
2719 void * oldheap;
2720 u8 * cmd = 0;
2721 unformat_input_t * i = vam->input;
2722
2723 if (vec_len(i->buffer) == 0)
2724 return -1;
2725
2726 if (vam->exec_mode == 0 && unformat (i, "mode")) {
2727 vam->exec_mode = 1;
2728 return 0;
2729 }
2730 if (vam->exec_mode == 1 &&
2731 (unformat (i, "exit") || unformat (i, "quit"))) {
2732 vam->exec_mode = 0;
2733 return 0;
2734 }
2735
2736
2737 M(CLI_REQUEST, cli_request);
2738
2739 /*
2740 * Copy cmd into shared memory.
2741 * In order for the CLI command to work, it
2742 * must be a vector ending in \n, not a C-string ending
2743 * in \n\0.
2744 */
2745 pthread_mutex_lock (&am->vlib_rp->mutex);
2746 oldheap = svm_push_data_heap (am->vlib_rp);
2747
2748 vec_validate (cmd, vec_len(vam->input->buffer)-1);
Damjan Marionf1213b82016-03-13 02:22:06 +01002749 clib_memcpy (cmd, vam->input->buffer, vec_len(vam->input->buffer));
Ed Warnickecb9cada2015-12-08 15:45:58 -07002750
2751 svm_pop_heap (oldheap);
2752 pthread_mutex_unlock (&am->vlib_rp->mutex);
2753
2754 mp->cmd_in_shmem = (u64) cmd;
2755 S;
2756 timeout = vat_time_now (vam) + 10.0;
2757
2758 while (vat_time_now (vam) < timeout) {
2759 if (vam->result_ready == 1) {
2760 u8 * free_me;
Pavel Kotucek060c6fc2016-02-24 15:52:42 +01002761 if (vam->shmem_result != NULL)
2762 fformat (vam->ofp, "%s", vam->shmem_result);
Ed Warnickecb9cada2015-12-08 15:45:58 -07002763 pthread_mutex_lock (&am->vlib_rp->mutex);
2764 oldheap = svm_push_data_heap (am->vlib_rp);
2765
2766 free_me = (u8 *)vam->shmem_result;
2767 vec_free (free_me);
2768
2769 svm_pop_heap (oldheap);
2770 pthread_mutex_unlock (&am->vlib_rp->mutex);
2771 return 0;
2772 }
2773 }
2774 return -99;
2775}
2776
2777static int api_create_loopback (vat_main_t * vam)
2778{
2779 unformat_input_t * i = vam->input;
2780 vl_api_create_loopback_t *mp;
2781 f64 timeout;
2782 u8 mac_address[6];
2783 u8 mac_set = 0;
2784
2785 memset (mac_address, 0, sizeof (mac_address));
2786
2787 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2788 {
2789 if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
2790 mac_set = 1;
2791 else
2792 break;
2793 }
2794
2795 /* Construct the API message */
2796 M(CREATE_LOOPBACK, create_loopback);
2797 if (mac_set)
Damjan Marionf1213b82016-03-13 02:22:06 +01002798 clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07002799
2800 S; W;
2801}
2802
2803static int api_delete_loopback (vat_main_t * vam)
2804{
2805 unformat_input_t * i = vam->input;
2806 vl_api_delete_loopback_t *mp;
2807 f64 timeout;
2808 u32 sw_if_index = ~0;
2809
2810 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2811 {
2812 if (unformat (i, "sw_if_index %d", &sw_if_index))
2813 ;
2814 else
2815 break;
2816 }
2817
2818 if (sw_if_index == ~0)
2819 {
2820 errmsg ("missing sw_if_index\n");
2821 return -99;
2822 }
2823
2824 /* Construct the API message */
2825 M(DELETE_LOOPBACK, delete_loopback);
2826 mp->sw_if_index = ntohl (sw_if_index);
2827
2828 S; W;
2829}
2830
2831static int api_want_stats (vat_main_t * vam)
2832{
2833 unformat_input_t * i = vam->input;
2834 vl_api_want_stats_t * mp;
2835 f64 timeout;
2836 int enable = -1;
2837
2838 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2839 {
2840 if (unformat (i, "enable"))
2841 enable = 1;
2842 else if (unformat (i, "disable"))
2843 enable = 0;
2844 else
2845 break;
2846 }
2847
2848 if (enable == -1)
2849 {
2850 errmsg ("missing enable|disable\n");
2851 return -99;
2852 }
2853
2854 M(WANT_STATS, want_stats);
2855 mp->enable_disable = enable;
2856
2857 S; W;
2858}
2859
2860static int api_want_interface_events (vat_main_t * vam)
2861{
2862 unformat_input_t * i = vam->input;
2863 vl_api_want_interface_events_t * mp;
2864 f64 timeout;
2865 int enable = -1;
2866
2867 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2868 {
2869 if (unformat (i, "enable"))
2870 enable = 1;
2871 else if (unformat (i, "disable"))
2872 enable = 0;
2873 else
2874 break;
2875 }
2876
2877 if (enable == -1)
2878 {
2879 errmsg ("missing enable|disable\n");
2880 return -99;
2881 }
2882
2883 M(WANT_INTERFACE_EVENTS, want_interface_events);
2884 mp->enable_disable = enable;
2885
2886 vam->interface_event_display = enable;
2887
2888 S; W;
2889}
2890
2891
2892/* Note: non-static, called once to set up the initial intfc table */
2893int api_sw_interface_dump (vat_main_t * vam)
2894{
2895 vl_api_sw_interface_dump_t *mp;
2896 f64 timeout;
2897 hash_pair_t * p;
2898 name_sort_t * nses = 0, * ns;
2899 sw_interface_subif_t * sub = NULL;
2900
2901 /* Toss the old name table */
2902 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
2903 ({
2904 vec_add2 (nses, ns, 1);
2905 ns->name = (u8 *)(p->key);
2906 ns->value = (u32) p->value[0];
2907 }));
2908
2909 hash_free (vam->sw_if_index_by_interface_name);
2910
2911 vec_foreach (ns, nses)
2912 vec_free (ns->name);
2913
2914 vec_free (nses);
2915
2916 vec_foreach (sub, vam->sw_if_subif_table) {
2917 vec_free (sub->interface_name);
2918 }
2919 vec_free (vam->sw_if_subif_table);
2920
2921 /* recreate the interface name hash table */
2922 vam->sw_if_index_by_interface_name
2923 = hash_create_string (0, sizeof(uword));
2924
2925 /* Get list of ethernets */
2926 M(SW_INTERFACE_DUMP, sw_interface_dump);
2927 mp->name_filter_valid = 1;
Damjan Marionfa693552016-04-26 19:30:36 +02002928 strncpy ((char *) mp->name_filter, "Ether", sizeof(mp->name_filter)-1);
Ed Warnickecb9cada2015-12-08 15:45:58 -07002929 S;
2930
2931 /* and local / loopback interfaces */
2932 M(SW_INTERFACE_DUMP, sw_interface_dump);
2933 mp->name_filter_valid = 1;
Damjan Marionfa693552016-04-26 19:30:36 +02002934 strncpy ((char *) mp->name_filter, "lo", sizeof(mp->name_filter)-1);
Ed Warnickecb9cada2015-12-08 15:45:58 -07002935 S;
2936
2937 /* and vxlan tunnel interfaces */
2938 M(SW_INTERFACE_DUMP, sw_interface_dump);
2939 mp->name_filter_valid = 1;
Damjan Marionfa693552016-04-26 19:30:36 +02002940 strncpy ((char *) mp->name_filter, "vxlan", sizeof(mp->name_filter)-1);
Ed Warnickecb9cada2015-12-08 15:45:58 -07002941 S;
2942
Damjan Marionb02e49c2016-03-31 17:44:25 +02002943 /* and host (af_packet) interfaces */
2944 M(SW_INTERFACE_DUMP, sw_interface_dump);
2945 mp->name_filter_valid = 1;
Damjan Marionfa693552016-04-26 19:30:36 +02002946 strncpy ((char *) mp->name_filter, "host", sizeof(mp->name_filter)-1);
Damjan Marionb02e49c2016-03-31 17:44:25 +02002947 S;
2948
Ed Warnickecb9cada2015-12-08 15:45:58 -07002949 /* and l2tpv3 tunnel interfaces */
2950 M(SW_INTERFACE_DUMP, sw_interface_dump);
2951 mp->name_filter_valid = 1;
Damjan Marionfa693552016-04-26 19:30:36 +02002952 strncpy ((char *) mp->name_filter, "l2tpv3_tunnel", sizeof(mp->name_filter)-1);
Ed Warnickecb9cada2015-12-08 15:45:58 -07002953 S;
2954
2955 /* Use a control ping for synchronization */
2956 {
2957 vl_api_control_ping_t * mp;
2958 M(CONTROL_PING, control_ping);
2959 S;
2960 }
2961 W;
2962}
2963
2964static int api_sw_interface_set_flags (vat_main_t * vam)
2965{
2966 unformat_input_t * i = vam->input;
2967 vl_api_sw_interface_set_flags_t *mp;
2968 f64 timeout;
2969 u32 sw_if_index;
2970 u8 sw_if_index_set = 0;
2971 u8 admin_up = 0, link_up = 0;
2972
2973 /* Parse args required to build the message */
2974 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
2975 if (unformat (i, "admin-up"))
2976 admin_up = 1;
2977 else if (unformat (i, "admin-down"))
2978 admin_up = 0;
2979 else if (unformat (i, "link-up"))
2980 link_up = 1;
2981 else if (unformat (i, "link-down"))
2982 link_up = 0;
2983 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
2984 sw_if_index_set = 1;
2985 else if (unformat (i, "sw_if_index %d", &sw_if_index))
2986 sw_if_index_set = 1;
2987 else
2988 break;
2989 }
2990
2991 if (sw_if_index_set == 0) {
2992 errmsg ("missing interface name or sw_if_index\n");
2993 return -99;
2994 }
2995
2996 /* Construct the API message */
2997 M(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
2998 mp->sw_if_index = ntohl (sw_if_index);
2999 mp->admin_up_down = admin_up;
3000 mp->link_up_down = link_up;
3001
3002 /* send it... */
3003 S;
3004
3005 /* Wait for a reply, return the good/bad news... */
3006 W;
3007}
3008
Pavel Kotucek00bbf272016-03-03 13:27:11 +01003009static int api_sw_interface_clear_stats (vat_main_t * vam)
3010{
3011 unformat_input_t * i = vam->input;
3012 vl_api_sw_interface_clear_stats_t *mp;
3013 f64 timeout;
3014 u32 sw_if_index;
3015 u8 sw_if_index_set = 0;
3016
3017 /* Parse args required to build the message */
3018 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3019 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3020 sw_if_index_set = 1;
3021 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3022 sw_if_index_set = 1;
3023 else
3024 break;
3025 }
3026
3027 /* Construct the API message */
3028 M(SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
3029
3030 if (sw_if_index_set == 1)
3031 mp->sw_if_index = ntohl (sw_if_index);
3032 else
3033 mp->sw_if_index = ~0;
3034
3035 /* send it... */
3036 S;
3037
3038 /* Wait for a reply, return the good/bad news... */
3039 W;
3040}
3041
Ed Warnickecb9cada2015-12-08 15:45:58 -07003042static int api_sw_interface_add_del_address (vat_main_t * vam)
3043{
3044 unformat_input_t * i = vam->input;
3045 vl_api_sw_interface_add_del_address_t *mp;
3046 f64 timeout;
3047 u32 sw_if_index;
3048 u8 sw_if_index_set = 0;
3049 u8 is_add = 1, del_all = 0;
3050 u32 address_length = 0;
3051 u8 v4_address_set = 0;
3052 u8 v6_address_set = 0;
3053 ip4_address_t v4address;
3054 ip6_address_t v6address;
3055
3056 /* Parse args required to build the message */
3057 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3058 if (unformat (i, "del-all"))
3059 del_all = 1;
3060 else if (unformat (i, "del"))
3061 is_add = 0;
3062 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3063 sw_if_index_set = 1;
3064 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3065 sw_if_index_set = 1;
3066 else if (unformat (i, "%U/%d",
3067 unformat_ip4_address, &v4address,
3068 &address_length))
3069 v4_address_set = 1;
3070 else if (unformat (i, "%U/%d",
3071 unformat_ip6_address, &v6address,
3072 &address_length))
3073 v6_address_set = 1;
3074 else
3075 break;
3076 }
3077
3078 if (sw_if_index_set == 0) {
3079 errmsg ("missing interface name or sw_if_index\n");
3080 return -99;
3081 }
3082 if (v4_address_set && v6_address_set) {
3083 errmsg ("both v4 and v6 addresses set\n");
3084 return -99;
3085 }
3086 if (!v4_address_set && !v6_address_set && !del_all) {
3087 errmsg ("no addresses set\n");
3088 return -99;
3089 }
3090
3091 /* Construct the API message */
3092 M(SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
3093
3094 mp->sw_if_index = ntohl (sw_if_index);
3095 mp->is_add = is_add;
3096 mp->del_all = del_all;
3097 if (v6_address_set) {
3098 mp->is_ipv6 = 1;
Damjan Marionf1213b82016-03-13 02:22:06 +01003099 clib_memcpy (mp->address, &v6address, sizeof (v6address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07003100 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01003101 clib_memcpy (mp->address, &v4address, sizeof (v4address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07003102 }
3103 mp->address_length = address_length;
3104
3105 /* send it... */
3106 S;
3107
3108 /* Wait for a reply, return good/bad news */
3109 W;
3110}
3111
3112static int api_sw_interface_set_table (vat_main_t * vam)
3113{
3114 unformat_input_t * i = vam->input;
3115 vl_api_sw_interface_set_table_t *mp;
3116 f64 timeout;
3117 u32 sw_if_index, vrf_id = 0;
3118 u8 sw_if_index_set = 0;
3119 u8 is_ipv6 = 0;
3120
3121 /* Parse args required to build the message */
3122 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3123 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3124 sw_if_index_set = 1;
3125 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3126 sw_if_index_set = 1;
3127 else if (unformat (i, "vrf %d", &vrf_id))
3128 ;
3129 else if (unformat (i, "ipv6"))
3130 is_ipv6 = 1;
3131 else
3132 break;
3133 }
3134
3135 if (sw_if_index_set == 0) {
3136 errmsg ("missing interface name or sw_if_index\n");
3137 return -99;
3138 }
3139
3140 /* Construct the API message */
3141 M(SW_INTERFACE_SET_TABLE, sw_interface_set_table);
3142
3143 mp->sw_if_index = ntohl (sw_if_index);
3144 mp->is_ipv6 = is_ipv6;
3145 mp->vrf_id = ntohl (vrf_id);
3146
3147 /* send it... */
3148 S;
3149
3150 /* Wait for a reply... */
3151 W;
3152}
3153
3154static int api_sw_interface_set_vpath (vat_main_t * vam)
3155{
3156 unformat_input_t * i = vam->input;
3157 vl_api_sw_interface_set_vpath_t *mp;
3158 f64 timeout;
3159 u32 sw_if_index = 0;
3160 u8 sw_if_index_set = 0;
3161 u8 is_enable = 0;
3162
3163 /* Parse args required to build the message */
3164 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3165 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3166 sw_if_index_set = 1;
3167 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3168 sw_if_index_set = 1;
3169 else if (unformat (i, "enable"))
3170 is_enable = 1;
3171 else if (unformat (i, "disable"))
3172 is_enable = 0;
3173 else
3174 break;
3175 }
3176
3177 if (sw_if_index_set == 0) {
3178 errmsg ("missing interface name or sw_if_index\n");
3179 return -99;
3180 }
3181
3182 /* Construct the API message */
3183 M(SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
3184
3185 mp->sw_if_index = ntohl (sw_if_index);
3186 mp->enable = is_enable;
3187
3188 /* send it... */
3189 S;
3190
3191 /* Wait for a reply... */
3192 W;
3193}
3194
3195static int api_sw_interface_set_l2_xconnect (vat_main_t * vam)
3196{
3197 unformat_input_t * i = vam->input;
3198 vl_api_sw_interface_set_l2_xconnect_t *mp;
3199 f64 timeout;
3200 u32 rx_sw_if_index;
3201 u8 rx_sw_if_index_set = 0;
3202 u32 tx_sw_if_index;
3203 u8 tx_sw_if_index_set = 0;
3204 u8 enable = 1;
3205
3206 /* Parse args required to build the message */
3207 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3208 if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
3209 rx_sw_if_index_set = 1;
3210 else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
3211 tx_sw_if_index_set = 1;
3212 else if (unformat (i, "rx")) {
3213 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3214 if (unformat (i, "%U", unformat_sw_if_index, vam,
3215 &rx_sw_if_index))
3216 rx_sw_if_index_set = 1;
3217 } else
3218 break;
3219 } else if (unformat (i, "tx")) {
3220 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3221 if (unformat (i, "%U", unformat_sw_if_index, vam,
3222 &tx_sw_if_index))
3223 tx_sw_if_index_set = 1;
3224 } else
3225 break;
3226 } else if (unformat (i, "enable"))
3227 enable = 1;
3228 else if (unformat (i, "disable"))
3229 enable = 0;
3230 else
3231 break;
3232 }
3233
3234 if (rx_sw_if_index_set == 0) {
3235 errmsg ("missing rx interface name or rx_sw_if_index\n");
3236 return -99;
3237 }
3238
3239 if (enable && (tx_sw_if_index_set == 0)) {
3240 errmsg ("missing tx interface name or tx_sw_if_index\n");
3241 return -99;
3242 }
3243
3244 M(SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
3245
3246 mp->rx_sw_if_index = ntohl(rx_sw_if_index);
3247 mp->tx_sw_if_index = ntohl(tx_sw_if_index);
3248 mp->enable = enable;
3249
3250 S; W;
3251 /* NOTREACHED */
3252 return 0;
3253}
3254
3255static int api_sw_interface_set_l2_bridge (vat_main_t * vam)
3256{
3257 unformat_input_t * i = vam->input;
3258 vl_api_sw_interface_set_l2_bridge_t *mp;
3259 f64 timeout;
3260 u32 rx_sw_if_index;
3261 u8 rx_sw_if_index_set = 0;
3262 u32 bd_id;
3263 u8 bd_id_set = 0;
3264 u8 bvi = 0;
3265 u32 shg = 0;
3266 u8 enable = 1;
3267
3268 /* Parse args required to build the message */
3269 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3270 if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
3271 rx_sw_if_index_set = 1;
3272 else if (unformat (i, "bd_id %d", &bd_id))
3273 bd_id_set = 1;
3274 else if (unformat (i, "%U", unformat_sw_if_index, vam,
3275 &rx_sw_if_index))
3276 rx_sw_if_index_set = 1;
3277 else if (unformat (i, "shg %d", &shg))
3278 ;
3279 else if (unformat (i, "bvi"))
3280 bvi = 1;
3281 else if (unformat (i, "enable"))
3282 enable = 1;
3283 else if (unformat (i, "disable"))
3284 enable = 0;
3285 else
3286 break;
3287 }
3288
3289 if (rx_sw_if_index_set == 0) {
3290 errmsg ("missing rx interface name or sw_if_index\n");
3291 return -99;
3292 }
3293
3294 if (enable && (bd_id_set == 0)) {
3295 errmsg ("missing bridge domain\n");
3296 return -99;
3297 }
3298
3299 M(SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
3300
3301 mp->rx_sw_if_index = ntohl(rx_sw_if_index);
3302 mp->bd_id = ntohl(bd_id);
3303 mp->shg = (u8)shg;
3304 mp->bvi = bvi;
3305 mp->enable = enable;
3306
3307 S; W;
3308 /* NOTREACHED */
3309 return 0;
3310}
3311
3312static int api_bridge_domain_dump (vat_main_t * vam)
3313{
3314 unformat_input_t * i = vam->input;
3315 vl_api_bridge_domain_dump_t *mp;
3316 f64 timeout;
3317 u32 bd_id = ~0;
3318
3319 /* Parse args required to build the message */
3320 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3321 if (unformat (i, "bd_id %d", &bd_id))
3322 ;
3323 else
3324 break;
3325 }
3326
3327 M(BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
3328 mp->bd_id = ntohl(bd_id);
3329 S;
3330
3331 /* Use a control ping for synchronization */
3332 {
3333 vl_api_control_ping_t * mp;
3334 M(CONTROL_PING, control_ping);
3335 S;
3336 }
3337
3338 W;
3339 /* NOTREACHED */
3340 return 0;
3341}
3342
3343static int api_bridge_domain_add_del (vat_main_t * vam)
3344{
3345 unformat_input_t * i = vam->input;
3346 vl_api_bridge_domain_add_del_t *mp;
3347 f64 timeout;
3348 u32 bd_id = ~0;
3349 u8 is_add = 1;
3350 u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
3351
3352 /* Parse args required to build the message */
3353 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3354 if (unformat (i, "bd_id %d", &bd_id))
3355 ;
3356 else if (unformat (i, "flood %d", &flood))
3357 ;
3358 else if (unformat (i, "uu-flood %d", &uu_flood))
3359 ;
3360 else if (unformat (i, "forward %d", &forward))
3361 ;
3362 else if (unformat (i, "learn %d", &learn))
3363 ;
3364 else if (unformat (i, "arp-term %d", &arp_term))
3365 ;
3366 else if (unformat (i, "del")) {
3367 is_add = 0;
3368 flood = uu_flood = forward = learn = 0;
3369 }
3370 else
3371 break;
3372 }
3373
3374 if (bd_id == ~0) {
3375 errmsg ("missing bridge domain\n");
3376 return -99;
3377 }
3378
3379 M(BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
3380
3381 mp->bd_id = ntohl(bd_id);
3382 mp->flood = flood;
3383 mp->uu_flood = uu_flood;
3384 mp->forward = forward;
3385 mp->learn = learn;
3386 mp->arp_term = arp_term;
3387 mp->is_add = is_add;
3388
3389 S; W;
3390 /* NOTREACHED */
3391 return 0;
3392}
3393
3394static int api_l2fib_add_del (vat_main_t * vam)
3395{
3396 unformat_input_t * i = vam->input;
3397 vl_api_l2fib_add_del_t *mp;
3398 f64 timeout;
3399 u64 mac = 0;
3400 u8 mac_set = 0;
3401 u32 bd_id;
3402 u8 bd_id_set = 0;
3403 u32 sw_if_index;
3404 u8 sw_if_index_set = 0;
3405 u8 is_add = 1;
3406 u8 static_mac = 0;
3407 u8 filter_mac = 0;
3408
3409 /* Parse args required to build the message */
3410 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3411 if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
3412 mac_set = 1;
3413 else if (unformat (i, "bd_id %d", &bd_id))
3414 bd_id_set = 1;
3415 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3416 sw_if_index_set = 1;
3417 else if (unformat (i, "sw_if")) {
3418 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3419 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3420 sw_if_index_set = 1;
3421 } else
3422 break;
3423 } else if (unformat (i, "static"))
3424 static_mac = 1;
3425 else if (unformat (i, "filter")) {
3426 filter_mac = 1;
3427 static_mac = 1;
3428 } else if (unformat (i, "del"))
3429 is_add = 0;
3430 else
3431 break;
3432 }
3433
3434 if (mac_set == 0) {
3435 errmsg ("missing mac address\n");
3436 return -99;
3437 }
3438
3439 if (bd_id_set == 0) {
3440 errmsg ("missing bridge domain\n");
3441 return -99;
3442 }
3443
3444 if (is_add && (sw_if_index_set == 0)) {
3445 errmsg ("missing interface name or sw_if_index\n");
3446 return -99;
3447 }
3448
3449 M(L2FIB_ADD_DEL, l2fib_add_del);
3450
3451 mp->mac = mac;
3452 mp->bd_id = ntohl(bd_id);
3453 mp->is_add = is_add;
3454
3455 if (is_add) {
3456 mp->sw_if_index = ntohl(sw_if_index);
3457 mp->static_mac = static_mac;
3458 mp->filter_mac = filter_mac;
3459 }
3460
3461 S; W;
3462 /* NOTREACHED */
3463 return 0;
3464}
3465
3466static int api_l2_flags (vat_main_t * vam)
3467{
3468 unformat_input_t * i = vam->input;
3469 vl_api_l2_flags_t *mp;
3470 f64 timeout;
3471 u32 sw_if_index;
3472 u32 feature_bitmap = 0;
3473 u8 sw_if_index_set = 0;
3474
3475 /* Parse args required to build the message */
3476 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3477 if (unformat (i, "sw_if_index %d", &sw_if_index))
3478 sw_if_index_set = 1;
3479 else if (unformat (i, "sw_if")) {
3480 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3481 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3482 sw_if_index_set = 1;
3483 } else
3484 break;
3485 } else if (unformat (i, "learn"))
3486 feature_bitmap |= L2INPUT_FEAT_LEARN;
3487 else if (unformat (i, "forward"))
3488 feature_bitmap |= L2INPUT_FEAT_FWD;
3489 else if (unformat (i, "flood"))
3490 feature_bitmap |= L2INPUT_FEAT_FLOOD;
3491 else if (unformat (i, "uu-flood"))
3492 feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
3493 else
3494 break;
3495 }
3496
3497 if (sw_if_index_set == 0) {
3498 errmsg ("missing interface name or sw_if_index\n");
3499 return -99;
3500 }
3501
3502 M(L2_FLAGS, l2_flags);
3503
3504 mp->sw_if_index = ntohl(sw_if_index);
3505 mp->feature_bitmap = ntohl(feature_bitmap);
3506
3507 S; W;
3508 /* NOTREACHED */
3509 return 0;
3510}
3511
3512static int api_bridge_flags (vat_main_t * vam)
3513{
3514 unformat_input_t * i = vam->input;
3515 vl_api_bridge_flags_t *mp;
3516 f64 timeout;
3517 u32 bd_id;
3518 u8 bd_id_set = 0;
3519 u8 is_set = 1;
3520 u32 flags = 0;
3521
3522 /* Parse args required to build the message */
3523 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3524 if (unformat (i, "bd_id %d", &bd_id))
3525 bd_id_set = 1;
3526 else if (unformat (i, "learn"))
3527 flags |= L2_LEARN;
3528 else if (unformat (i, "forward"))
3529 flags |= L2_FWD;
3530 else if (unformat (i, "flood"))
3531 flags |= L2_FLOOD;
3532 else if (unformat (i, "uu-flood"))
3533 flags |= L2_UU_FLOOD;
3534 else if (unformat (i, "arp-term"))
3535 flags |= L2_ARP_TERM;
3536 else if (unformat (i, "off"))
3537 is_set = 0;
3538 else if (unformat (i, "disable"))
3539 is_set = 0;
3540 else
3541 break;
3542 }
3543
3544 if (bd_id_set == 0) {
3545 errmsg ("missing bridge domain\n");
3546 return -99;
3547 }
3548
3549 M(BRIDGE_FLAGS, bridge_flags);
3550
3551 mp->bd_id = ntohl(bd_id);
3552 mp->feature_bitmap = ntohl(flags);
3553 mp->is_set = is_set;
3554
3555 S; W;
3556 /* NOTREACHED */
3557 return 0;
3558}
3559
3560static int api_bd_ip_mac_add_del (vat_main_t * vam)
3561{
3562 unformat_input_t * i = vam->input;
3563 vl_api_bd_ip_mac_add_del_t *mp;
3564 f64 timeout;
3565 u32 bd_id;
3566 u8 is_ipv6 = 0;
3567 u8 is_add = 1;
3568 u8 bd_id_set = 0;
3569 u8 ip_set = 0;
3570 u8 mac_set = 0;
3571 ip4_address_t v4addr;
3572 ip6_address_t v6addr;
3573 u8 macaddr[6];
3574
3575
3576 /* Parse args required to build the message */
3577 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3578 if (unformat (i, "bd_id %d", &bd_id)) {
3579 bd_id_set++;
3580 } else if (unformat (i, "%U", unformat_ip4_address, &v4addr)) {
3581 ip_set++;
3582 } else if (unformat (i, "%U", unformat_ip6_address, &v6addr)) {
3583 ip_set++;
3584 is_ipv6++;
3585 } else if (unformat (i, "%U", unformat_ethernet_address, macaddr)) {
3586 mac_set++;
3587 } else if (unformat (i, "del"))
3588 is_add = 0;
3589 else
3590 break;
3591 }
3592
3593 if (bd_id_set == 0) {
3594 errmsg ("missing bridge domain\n");
3595 return -99;
3596 } else if (ip_set == 0) {
3597 errmsg ("missing IP address\n");
3598 return -99;
3599 } else if (mac_set == 0) {
3600 errmsg ("missing MAC address\n");
3601 return -99;
3602 }
3603
3604 M(BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
3605
3606 mp->bd_id = ntohl(bd_id);
3607 mp->is_ipv6 = is_ipv6;
3608 mp->is_add = is_add;
3609 if (is_ipv6)
Damjan Marionf1213b82016-03-13 02:22:06 +01003610 clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
3611 else clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
3612 clib_memcpy (mp->mac_address, macaddr, 6);
Ed Warnickecb9cada2015-12-08 15:45:58 -07003613 S; W;
3614 /* NOTREACHED */
3615 return 0;
3616}
3617
3618static int api_tap_connect (vat_main_t * vam)
3619{
3620 unformat_input_t * i = vam->input;
3621 vl_api_tap_connect_t *mp;
3622 f64 timeout;
3623 u8 mac_address[6];
3624 u8 random_mac = 1;
3625 u8 name_set = 0;
3626 u8 * tap_name;
3627
3628 memset (mac_address, 0, sizeof (mac_address));
3629
3630 /* Parse args required to build the message */
3631 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3632 if (unformat (i, "mac %U", unformat_ethernet_address, mac_address)) {
3633 random_mac = 0;
3634 }
3635 else if (unformat (i, "random-mac"))
3636 random_mac = 1;
3637 else if (unformat (i, "tapname %s", &tap_name))
3638 name_set = 1;
3639 else
3640 break;
3641 }
3642
3643 if (name_set == 0) {
3644 errmsg ("missing tap name\n");
3645 return -99;
3646 }
3647 if (vec_len (tap_name) > 63) {
3648 errmsg ("tap name too long\n");
3649 }
3650 vec_add1 (tap_name, 0);
3651
3652 /* Construct the API message */
3653 M(TAP_CONNECT, tap_connect);
3654
3655 mp->use_random_mac = random_mac;
Damjan Marionf1213b82016-03-13 02:22:06 +01003656 clib_memcpy (mp->mac_address, mac_address, 6);
3657 clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
Ed Warnickecb9cada2015-12-08 15:45:58 -07003658 vec_free (tap_name);
3659
3660 /* send it... */
3661 S;
3662
3663 /* Wait for a reply... */
3664 W;
3665}
3666
3667static int api_tap_modify (vat_main_t * vam)
3668{
3669 unformat_input_t * i = vam->input;
3670 vl_api_tap_modify_t *mp;
3671 f64 timeout;
3672 u8 mac_address[6];
3673 u8 random_mac = 1;
3674 u8 name_set = 0;
3675 u8 * tap_name;
3676 u32 sw_if_index = ~0;
3677 u8 sw_if_index_set = 0;
3678
3679 memset (mac_address, 0, sizeof (mac_address));
3680
3681 /* Parse args required to build the message */
3682 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3683 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3684 sw_if_index_set = 1;
3685 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3686 sw_if_index_set = 1;
3687 else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address)) {
3688 random_mac = 0;
3689 }
3690 else if (unformat (i, "random-mac"))
3691 random_mac = 1;
3692 else if (unformat (i, "tapname %s", &tap_name))
3693 name_set = 1;
3694 else
3695 break;
3696 }
3697
3698 if (sw_if_index_set == 0) {
3699 errmsg ("missing vpp interface name");
3700 return -99;
3701 }
3702 if (name_set == 0) {
3703 errmsg ("missing tap name\n");
3704 return -99;
3705 }
3706 if (vec_len (tap_name) > 63) {
3707 errmsg ("tap name too long\n");
3708 }
3709 vec_add1 (tap_name, 0);
3710
3711 /* Construct the API message */
3712 M(TAP_MODIFY, tap_modify);
3713
3714 mp->use_random_mac = random_mac;
3715 mp->sw_if_index = ntohl(sw_if_index);
Damjan Marionf1213b82016-03-13 02:22:06 +01003716 clib_memcpy (mp->mac_address, mac_address, 6);
3717 clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
Ed Warnickecb9cada2015-12-08 15:45:58 -07003718 vec_free (tap_name);
3719
3720 /* send it... */
3721 S;
3722
3723 /* Wait for a reply... */
3724 W;
3725}
3726
3727static int api_tap_delete (vat_main_t * vam)
3728{
3729 unformat_input_t * i = vam->input;
3730 vl_api_tap_delete_t *mp;
3731 f64 timeout;
3732 u32 sw_if_index = ~0;
3733 u8 sw_if_index_set = 0;
3734
3735 /* Parse args required to build the message */
3736 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3737 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3738 sw_if_index_set = 1;
3739 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3740 sw_if_index_set = 1;
3741 else
3742 break;
3743 }
3744
3745 if (sw_if_index_set == 0) {
3746 errmsg ("missing vpp interface name");
3747 return -99;
3748 }
3749
3750 /* Construct the API message */
3751 M(TAP_DELETE, tap_delete);
3752
3753 mp->sw_if_index = ntohl(sw_if_index);
3754
3755 /* send it... */
3756 S;
3757
3758 /* Wait for a reply... */
3759 W;
3760}
3761
3762static int api_ip_add_del_route (vat_main_t * vam)
3763{
3764 unformat_input_t * i = vam->input;
3765 vl_api_ip_add_del_route_t *mp;
3766 f64 timeout;
3767 u32 sw_if_index = 0, vrf_id = 0;
3768 u8 sw_if_index_set = 0;
3769 u8 is_ipv6 = 0;
3770 u8 is_local = 0, is_drop = 0;
3771 u8 create_vrf_if_needed = 0;
3772 u8 is_add = 1;
3773 u8 next_hop_weight = 1;
3774 u8 not_last = 0;
3775 u8 is_multipath = 0;
3776 u8 address_set = 0;
3777 u8 address_length_set = 0;
3778 u32 lookup_in_vrf = 0;
3779 u32 resolve_attempts = 0;
3780 u32 dst_address_length = 0;
3781 u8 next_hop_set = 0;
3782 ip4_address_t v4_dst_address, v4_next_hop_address;
3783 ip6_address_t v6_dst_address, v6_next_hop_address;
3784 int count = 1;
3785 int j;
3786 f64 before = 0;
3787 u32 random_add_del = 0;
3788 u32 * random_vector = 0;
3789 uword * random_hash;
3790 u32 random_seed = 0xdeaddabe;
3791 u32 classify_table_index = ~0;
3792 u8 is_classify = 0;
3793
3794 /* Parse args required to build the message */
3795 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3796 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3797 sw_if_index_set = 1;
3798 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3799 sw_if_index_set = 1;
3800 else if (unformat (i, "%U", unformat_ip4_address,
3801 &v4_dst_address)) {
3802 address_set = 1;
3803 is_ipv6 = 0;
3804 }
3805 else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address)) {
3806 address_set = 1;
3807 is_ipv6 = 1;
3808 }
3809 else if (unformat (i, "/%d", &dst_address_length)) {
3810 address_length_set = 1;
3811 }
3812
3813 else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
3814 &v4_next_hop_address)) {
3815 next_hop_set = 1;
3816 }
3817 else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
3818 &v6_next_hop_address)) {
3819 next_hop_set = 1;
3820 }
3821 else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
3822 ;
3823 else if (unformat (i, "weight %d", &next_hop_weight))
3824 ;
3825 else if (unformat (i, "drop")) {
3826 is_drop = 1;
3827 } else if (unformat (i, "local")) {
3828 is_local = 1;
3829 } else if (unformat (i, "classify %d", &classify_table_index)) {
3830 is_classify = 1;
3831 } else if (unformat (i, "del"))
3832 is_add = 0;
3833 else if (unformat (i, "add"))
3834 is_add = 1;
3835 else if (unformat (i, "not-last"))
3836 not_last = 1;
3837 else if (unformat (i, "multipath"))
3838 is_multipath = 1;
3839 else if (unformat (i, "vrf %d", &vrf_id))
3840 ;
3841 else if (unformat (i, "create-vrf"))
3842 create_vrf_if_needed = 1;
3843 else if (unformat (i, "count %d", &count))
3844 ;
3845 else if (unformat (i, "lookup-in-vrf %d", &lookup_in_vrf))
3846 ;
3847 else if (unformat (i, "random"))
3848 random_add_del = 1;
3849 else if (unformat (i, "seed %d", &random_seed))
3850 ;
3851 else {
3852 clib_warning ("parse error '%U'", format_unformat_error, i);
3853 return -99;
3854 }
3855 }
3856
3857 if (resolve_attempts > 0 && sw_if_index_set == 0) {
3858 errmsg ("ARP resolution needs explicit interface or sw_if_index\n");
3859 return -99;
3860 }
3861
3862 if (!next_hop_set && !is_drop && !is_local && !is_classify) {
3863 errmsg ("next hop / local / drop / classify not set\n");
3864 return -99;
3865 }
3866
3867 if (address_set == 0) {
3868 errmsg ("missing addresses\n");
3869 return -99;
3870 }
3871
3872 if (address_length_set == 0) {
3873 errmsg ("missing address length\n");
3874 return -99;
3875 }
3876
3877 /* Generate a pile of unique, random routes */
3878 if (random_add_del) {
3879 u32 this_random_address;
3880 random_hash = hash_create (count, sizeof(uword));
3881
3882 hash_set (random_hash, v4_next_hop_address.as_u32, 1);
3883 for (j = 0; j <= count; j++) {
3884 do {
3885 this_random_address = random_u32 (&random_seed);
3886 this_random_address =
3887 clib_host_to_net_u32 (this_random_address);
3888 } while (hash_get (random_hash, this_random_address));
3889 vec_add1 (random_vector, this_random_address);
3890 hash_set (random_hash, this_random_address, 1);
3891 }
3892 hash_free (random_hash);
3893 v4_dst_address.as_u32 = random_vector[0];
3894 }
3895
3896 if (count > 1) {
3897 /* Turn on async mode */
3898 vam->async_mode = 1;
3899 vam->async_errors = 0;
3900 before = vat_time_now(vam);
3901 }
3902
3903 for (j = 0; j < count; j++) {
3904 /* Construct the API message */
3905 M(IP_ADD_DEL_ROUTE, ip_add_del_route);
3906
3907 mp->next_hop_sw_if_index = ntohl (sw_if_index);
3908 mp->vrf_id = ntohl (vrf_id);
3909 if (resolve_attempts > 0) {
3910 mp->resolve_attempts = ntohl (resolve_attempts);
3911 mp->resolve_if_needed = 1;
3912 }
3913 mp->create_vrf_if_needed = create_vrf_if_needed;
3914
3915 mp->is_add = is_add;
3916 mp->is_drop = is_drop;
3917 mp->is_ipv6 = is_ipv6;
3918 mp->is_local = is_local;
3919 mp->is_classify = is_classify;
3920 mp->is_multipath = is_multipath;
3921 mp->not_last = not_last;
3922 mp->next_hop_weight = next_hop_weight;
3923 mp->dst_address_length = dst_address_length;
3924 mp->lookup_in_vrf = ntohl(lookup_in_vrf);
3925 mp->classify_table_index = ntohl(classify_table_index);
3926
3927 if (is_ipv6){
Damjan Marionf1213b82016-03-13 02:22:06 +01003928 clib_memcpy (mp->dst_address, &v6_dst_address, sizeof (v6_dst_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07003929 if (next_hop_set)
Damjan Marionf1213b82016-03-13 02:22:06 +01003930 clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
Ed Warnickecb9cada2015-12-08 15:45:58 -07003931 sizeof (v6_next_hop_address));
3932 increment_v6_address (&v6_dst_address);
3933 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01003934 clib_memcpy (mp->dst_address, &v4_dst_address, sizeof (v4_dst_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07003935 if (next_hop_set)
Damjan Marionf1213b82016-03-13 02:22:06 +01003936 clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
Ed Warnickecb9cada2015-12-08 15:45:58 -07003937 sizeof (v4_next_hop_address));
3938 if (random_add_del)
3939 v4_dst_address.as_u32 = random_vector[j+1];
3940 else
3941 increment_v4_address (&v4_dst_address);
3942 }
3943 /* send it... */
3944 S;
3945 }
3946
3947 /* When testing multiple add/del ops, use a control-ping to sync */
3948 if (count > 1) {
3949 vl_api_control_ping_t * mp;
3950 f64 after;
3951
3952 /* Shut off async mode */
3953 vam->async_mode = 0;
3954
3955 M(CONTROL_PING, control_ping);
3956 S;
3957
3958 timeout = vat_time_now(vam) + 1.0;
3959 while (vat_time_now (vam) < timeout)
3960 if (vam->result_ready == 1)
3961 goto out;
3962 vam->retval = -99;
3963
3964 out:
3965 if (vam->retval == -99)
3966 errmsg ("timeout\n");
3967
3968 if (vam->async_errors > 0) {
3969 errmsg ("%d asynchronous errors\n", vam->async_errors);
3970 vam->retval = -98;
3971 }
3972 vam->async_errors = 0;
3973 after = vat_time_now(vam);
3974
3975 fformat(vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
3976 count, after - before, count / (after - before));
3977 } else {
3978 /* Wait for a reply... */
3979 W;
3980 }
3981
3982 /* Return the good/bad news */
3983 return (vam->retval);
3984}
3985
3986static int api_proxy_arp_add_del (vat_main_t * vam)
3987{
3988 unformat_input_t * i = vam->input;
3989 vl_api_proxy_arp_add_del_t *mp;
3990 f64 timeout;
3991 u32 vrf_id = 0;
3992 u8 is_add = 1;
3993 ip4_address_t lo, hi;
3994 u8 range_set = 0;
3995
3996 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3997 if (unformat (i, "vrf %d", &vrf_id))
3998 ;
3999 else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
4000 unformat_ip4_address, &hi))
4001 range_set = 1;
4002 else if (unformat (i, "del"))
4003 is_add = 0;
4004 else {
4005 clib_warning ("parse error '%U'", format_unformat_error, i);
4006 return -99;
4007 }
4008 }
4009
4010 if (range_set == 0) {
4011 errmsg ("address range not set\n");
4012 return -99;
4013 }
4014
4015 M(PROXY_ARP_ADD_DEL, proxy_arp_add_del);
4016
4017 mp->vrf_id = ntohl(vrf_id);
4018 mp->is_add = is_add;
Damjan Marionf1213b82016-03-13 02:22:06 +01004019 clib_memcpy(mp->low_address, &lo, sizeof (mp->low_address));
4020 clib_memcpy(mp->hi_address, &hi, sizeof (mp->hi_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004021
4022 S; W;
4023 /* NOTREACHED */
4024 return 0;
4025}
4026
4027static int api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
4028{
4029 unformat_input_t * i = vam->input;
4030 vl_api_proxy_arp_intfc_enable_disable_t *mp;
4031 f64 timeout;
4032 u32 sw_if_index;
4033 u8 enable = 1;
4034 u8 sw_if_index_set = 0;
4035
4036 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4037 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4038 sw_if_index_set = 1;
4039 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4040 sw_if_index_set = 1;
4041 else if (unformat (i, "enable"))
4042 enable = 1;
4043 else if (unformat (i, "disable"))
4044 enable = 0;
4045 else {
4046 clib_warning ("parse error '%U'", format_unformat_error, i);
4047 return -99;
4048 }
4049 }
4050
4051 if (sw_if_index_set == 0) {
4052 errmsg ("missing interface name or sw_if_index\n");
4053 return -99;
4054 }
4055
4056 M(PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
4057
4058 mp->sw_if_index = ntohl(sw_if_index);
4059 mp->enable_disable = enable;
4060
4061 S; W;
4062 /* NOTREACHED */
4063 return 0;
4064}
4065
4066static int api_mpls_add_del_decap (vat_main_t * vam)
4067{
4068 unformat_input_t * i = vam->input;
4069 vl_api_mpls_add_del_decap_t *mp;
4070 f64 timeout;
4071 u32 rx_vrf_id = 0;
4072 u32 tx_vrf_id = 0;
4073 u32 label = 0;
4074 u8 is_add = 1;
4075 u8 s_bit = 1;
4076 u32 next_index = 1;
4077
4078 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4079 if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
4080 ;
4081 else if (unformat (i, "tx_vrf_id %d", &tx_vrf_id))
4082 ;
4083 else if (unformat (i, "label %d", &label))
4084 ;
4085 else if (unformat (i, "next-index %d", &next_index))
4086 ;
4087 else if (unformat (i, "del"))
4088 is_add = 0;
4089 else if (unformat (i, "s-bit-clear"))
4090 s_bit = 0;
4091 else {
4092 clib_warning ("parse error '%U'", format_unformat_error, i);
4093 return -99;
4094 }
4095 }
4096
4097 M(MPLS_ADD_DEL_DECAP, mpls_add_del_decap);
4098
4099 mp->rx_vrf_id = ntohl(rx_vrf_id);
4100 mp->tx_vrf_id = ntohl(tx_vrf_id);
4101 mp->label = ntohl(label);
4102 mp->next_index = ntohl(next_index);
4103 mp->s_bit = s_bit;
4104 mp->is_add = is_add;
4105
4106 S; W;
4107 /* NOTREACHED */
4108 return 0;
4109}
4110
4111static int api_mpls_add_del_encap (vat_main_t * vam)
4112{
4113 unformat_input_t * i = vam->input;
4114 vl_api_mpls_add_del_encap_t *mp;
4115 f64 timeout;
4116 u32 vrf_id = 0;
4117 u32 *labels = 0;
4118 u32 label;
4119 ip4_address_t dst_address;
4120 u8 is_add = 1;
4121
4122 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4123 if (unformat (i, "vrf %d", &vrf_id))
4124 ;
4125 else if (unformat (i, "label %d", &label))
4126 vec_add1 (labels, ntohl(label));
4127 else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
4128 ;
4129 else if (unformat (i, "del"))
4130 is_add = 0;
4131 else {
4132 clib_warning ("parse error '%U'", format_unformat_error, i);
4133 return -99;
4134 }
4135 }
4136
4137 if (vec_len (labels) == 0) {
4138 errmsg ("missing encap label stack\n");
4139 return -99;
4140 }
4141
4142 M2(MPLS_ADD_DEL_ENCAP, mpls_add_del_encap,
4143 sizeof (u32) * vec_len (labels));
4144
4145 mp->vrf_id = ntohl(vrf_id);
Damjan Marionf1213b82016-03-13 02:22:06 +01004146 clib_memcpy(mp->dst_address, &dst_address, sizeof (dst_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004147 mp->is_add = is_add;
4148 mp->nlabels = vec_len (labels);
Damjan Marionf1213b82016-03-13 02:22:06 +01004149 clib_memcpy(mp->labels, labels, sizeof(u32)*mp->nlabels);
Ed Warnickecb9cada2015-12-08 15:45:58 -07004150
4151 vec_free(labels);
4152
4153 S; W;
4154 /* NOTREACHED */
4155 return 0;
4156}
4157
4158static int api_mpls_gre_add_del_tunnel (vat_main_t * vam)
4159{
4160 unformat_input_t * i = vam->input;
4161 vl_api_mpls_gre_add_del_tunnel_t *mp;
4162 f64 timeout;
4163 u32 inner_vrf_id = 0;
4164 u32 outer_vrf_id = 0;
4165 ip4_address_t src_address;
4166 ip4_address_t dst_address;
4167 ip4_address_t intfc_address;
4168 u32 tmp;
4169 u8 intfc_address_length = 0;
4170 u8 is_add = 1;
4171 u8 l2_only = 0;
4172
4173 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4174 if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
4175 ;
4176 else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
4177 ;
4178 else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
4179 ;
4180 else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
4181 ;
4182 else if (unformat (i, "adj %U/%d", unformat_ip4_address,
4183 &intfc_address, &tmp))
4184 intfc_address_length = tmp;
4185 else if (unformat (i, "l2-only"))
4186 l2_only = 1;
4187 else if (unformat (i, "del"))
4188 is_add = 0;
4189 else {
4190 clib_warning ("parse error '%U'", format_unformat_error, i);
4191 return -99;
4192 }
4193 }
4194
4195 M(MPLS_GRE_ADD_DEL_TUNNEL, mpls_gre_add_del_tunnel);
4196
4197 mp->inner_vrf_id = ntohl(inner_vrf_id);
4198 mp->outer_vrf_id = ntohl(outer_vrf_id);
Damjan Marionf1213b82016-03-13 02:22:06 +01004199 clib_memcpy(mp->src_address, &src_address, sizeof (src_address));
4200 clib_memcpy(mp->dst_address, &dst_address, sizeof (dst_address));
4201 clib_memcpy(mp->intfc_address, &intfc_address, sizeof (intfc_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004202 mp->intfc_address_length = intfc_address_length;
4203 mp->l2_only = l2_only;
4204 mp->is_add = is_add;
4205
4206 S; W;
4207 /* NOTREACHED */
4208 return 0;
4209}
4210
4211static int api_mpls_ethernet_add_del_tunnel (vat_main_t * vam)
4212{
4213 unformat_input_t * i = vam->input;
4214 vl_api_mpls_ethernet_add_del_tunnel_t *mp;
4215 f64 timeout;
4216 u32 inner_vrf_id = 0;
4217 ip4_address_t intfc_address;
4218 u8 dst_mac_address[6];
4219 int dst_set = 1;
4220 u32 tmp;
4221 u8 intfc_address_length = 0;
4222 u8 is_add = 1;
4223 u8 l2_only = 0;
4224 u32 tx_sw_if_index;
4225 int tx_sw_if_index_set = 0;
4226
4227 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4228 if (unformat (i, "vrf %d", &inner_vrf_id))
4229 ;
4230 else if (unformat (i, "adj %U/%d", unformat_ip4_address,
4231 &intfc_address, &tmp))
4232 intfc_address_length = tmp;
4233 else if (unformat (i, "%U",
4234 unformat_sw_if_index, vam, &tx_sw_if_index))
4235 tx_sw_if_index_set = 1;
4236 else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
4237 tx_sw_if_index_set = 1;
4238 else if (unformat (i, "dst %U", unformat_ethernet_address,
4239 dst_mac_address))
4240 dst_set = 1;
4241 else if (unformat (i, "l2-only"))
4242 l2_only = 1;
4243 else if (unformat (i, "del"))
4244 is_add = 0;
4245 else {
4246 clib_warning ("parse error '%U'", format_unformat_error, i);
4247 return -99;
4248 }
4249 }
4250
4251 if (!dst_set) {
4252 errmsg ("dst (mac address) not set\n");
4253 return -99;
4254 }
4255 if (!tx_sw_if_index_set) {
4256 errmsg ("tx-intfc not set\n");
4257 return -99;
4258 }
4259
4260 M(MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel);
4261
4262 mp->vrf_id = ntohl(inner_vrf_id);
Damjan Marionf1213b82016-03-13 02:22:06 +01004263 clib_memcpy (mp->adj_address, &intfc_address, sizeof (intfc_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004264 mp->adj_address_length = intfc_address_length;
Damjan Marionf1213b82016-03-13 02:22:06 +01004265 clib_memcpy (mp->dst_mac_address, dst_mac_address, sizeof (dst_mac_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004266 mp->tx_sw_if_index = ntohl(tx_sw_if_index);
4267 mp->l2_only = l2_only;
4268 mp->is_add = is_add;
4269
4270 S; W;
4271 /* NOTREACHED */
4272 return 0;
4273}
4274
4275static int api_mpls_ethernet_add_del_tunnel_2 (vat_main_t * vam)
4276{
4277 unformat_input_t * i = vam->input;
4278 vl_api_mpls_ethernet_add_del_tunnel_2_t *mp;
4279 f64 timeout;
4280 u32 inner_vrf_id = 0;
4281 u32 outer_vrf_id = 0;
4282 ip4_address_t adj_address;
4283 int adj_address_set = 0;
4284 ip4_address_t next_hop_address;
4285 int next_hop_address_set = 0;
4286 u32 tmp;
4287 u8 adj_address_length = 0;
4288 u8 l2_only = 0;
4289 u8 is_add = 1;
4290 u32 resolve_attempts = 5;
4291 u8 resolve_if_needed = 1;
4292
4293 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4294 if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
4295 ;
4296 else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
4297 ;
4298 else if (unformat (i, "adj %U/%d", unformat_ip4_address,
4299 &adj_address, &tmp)) {
4300 adj_address_length = tmp;
4301 adj_address_set = 1;
4302 }
4303 else if (unformat (i, "next-hop %U", unformat_ip4_address,
4304 &next_hop_address))
4305 next_hop_address_set = 1;
4306 else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
4307 ;
4308 else if (unformat (i, "resolve-if-needed %d", &tmp))
4309 resolve_if_needed = tmp;
4310 else if (unformat (i, "l2-only"))
4311 l2_only = 1;
4312 else if (unformat (i, "del"))
4313 is_add = 0;
4314 else {
4315 clib_warning ("parse error '%U'", format_unformat_error, i);
4316 return -99;
4317 }
4318 }
4319
4320 if (!adj_address_set) {
4321 errmsg ("adjacency address/mask not set\n");
4322 return -99;
4323 }
4324 if (!next_hop_address_set) {
4325 errmsg ("ip4 next hop address (in outer fib) not set\n");
4326 return -99;
4327 }
4328
4329 M(MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2);
4330
4331 mp->inner_vrf_id = ntohl(inner_vrf_id);
4332 mp->outer_vrf_id = ntohl(outer_vrf_id);
4333 mp->resolve_attempts = ntohl(resolve_attempts);
4334 mp->resolve_if_needed = resolve_if_needed;
4335 mp->is_add = is_add;
4336 mp->l2_only = l2_only;
Damjan Marionf1213b82016-03-13 02:22:06 +01004337 clib_memcpy (mp->adj_address, &adj_address, sizeof (adj_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004338 mp->adj_address_length = adj_address_length;
Damjan Marionf1213b82016-03-13 02:22:06 +01004339 clib_memcpy (mp->next_hop_ip4_address_in_outer_vrf, &next_hop_address,
Ed Warnickecb9cada2015-12-08 15:45:58 -07004340 sizeof (next_hop_address));
4341
4342 S; W;
4343 /* NOTREACHED */
4344 return 0;
4345}
4346
4347static int api_sw_interface_set_unnumbered (vat_main_t * vam)
4348{
4349 unformat_input_t * i = vam->input;
4350 vl_api_sw_interface_set_unnumbered_t *mp;
4351 f64 timeout;
4352 u32 sw_if_index;
4353 u32 unnum_sw_index;
4354 u8 is_add = 1;
4355 u8 sw_if_index_set = 0;
4356
4357 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4358 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4359 sw_if_index_set = 1;
4360 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4361 sw_if_index_set = 1;
4362 else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
4363 ;
4364 else if (unformat (i, "del"))
4365 is_add = 0;
4366 else {
4367 clib_warning ("parse error '%U'", format_unformat_error, i);
4368 return -99;
4369 }
4370 }
4371
4372 if (sw_if_index_set == 0) {
4373 errmsg ("missing interface name or sw_if_index\n");
4374 return -99;
4375 }
4376
4377 M(SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
4378
4379 mp->sw_if_index = ntohl(sw_if_index);
4380 mp->unnumbered_sw_if_index = ntohl(unnum_sw_index);
4381 mp->is_add = is_add;
4382
4383 S; W;
4384 /* NOTREACHED */
4385 return 0;
4386}
4387
4388static int api_ip_neighbor_add_del (vat_main_t * vam)
4389{
4390 unformat_input_t * i = vam->input;
4391 vl_api_ip_neighbor_add_del_t *mp;
4392 f64 timeout;
4393 u32 sw_if_index;
4394 u8 sw_if_index_set = 0;
4395 u32 vrf_id = 0;
4396 u8 is_add = 1;
4397 u8 is_static = 0;
4398 u8 mac_address[6];
4399 u8 mac_set = 0;
4400 u8 v4_address_set = 0;
4401 u8 v6_address_set = 0;
4402 ip4_address_t v4address;
4403 ip6_address_t v6address;
4404
4405 memset (mac_address, 0, sizeof (mac_address));
4406
4407 /* Parse args required to build the message */
4408 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4409 if (unformat (i, "mac %U", unformat_ethernet_address, mac_address)) {
4410 mac_set = 1;
4411 }
4412 else if (unformat (i, "del"))
4413 is_add = 0;
4414 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4415 sw_if_index_set = 1;
4416 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4417 sw_if_index_set = 1;
4418 else if (unformat (i, "is_static"))
4419 is_static = 1;
4420 else if (unformat (i, "vrf %d", &vrf_id))
4421 ;
4422 else if (unformat (i, "dst %U",
4423 unformat_ip4_address, &v4address))
4424 v4_address_set = 1;
4425 else if (unformat (i, "dst %U",
4426 unformat_ip6_address, &v6address))
4427 v6_address_set = 1;
4428 else {
4429 clib_warning ("parse error '%U'", format_unformat_error, i);
4430 return -99;
4431 }
4432 }
4433
4434 if (sw_if_index_set == 0) {
4435 errmsg ("missing interface name or sw_if_index\n");
4436 return -99;
4437 }
4438 if (v4_address_set && v6_address_set) {
4439 errmsg ("both v4 and v6 addresses set\n");
4440 return -99;
4441 }
4442 if (!v4_address_set && !v6_address_set) {
4443 errmsg ("no addresses set\n");
4444 return -99;
4445 }
4446
4447 /* Construct the API message */
4448 M(IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
4449
4450 mp->sw_if_index = ntohl (sw_if_index);
4451 mp->is_add = is_add;
4452 mp->vrf_id = ntohl (vrf_id);
4453 mp->is_static = is_static;
4454 if (mac_set)
Damjan Marionf1213b82016-03-13 02:22:06 +01004455 clib_memcpy (mp->mac_address, mac_address, 6);
Ed Warnickecb9cada2015-12-08 15:45:58 -07004456 if (v6_address_set) {
4457 mp->is_ipv6 = 1;
Damjan Marionf1213b82016-03-13 02:22:06 +01004458 clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004459 } else {
4460 /* mp->is_ipv6 = 0; via memset in M macro above */
Damjan Marionf1213b82016-03-13 02:22:06 +01004461 clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004462 }
4463
4464 /* send it... */
4465 S;
4466
4467 /* Wait for a reply, return good/bad news */
4468 W;
4469
4470 /* NOTREACHED */
4471 return 0;
4472}
4473
4474static int api_reset_vrf (vat_main_t * vam)
4475{
4476 unformat_input_t * i = vam->input;
4477 vl_api_reset_vrf_t *mp;
4478 f64 timeout;
4479 u32 vrf_id = 0;
4480 u8 is_ipv6 = 0;
4481 u8 vrf_id_set = 0;
4482
4483 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4484 if (unformat (i, "vrf %d", &vrf_id))
4485 vrf_id_set = 1;
4486 else if (unformat (i, "ipv6"))
4487 is_ipv6 = 1;
4488 else {
4489 clib_warning ("parse error '%U'", format_unformat_error, i);
4490 return -99;
4491 }
4492 }
4493
4494 if (vrf_id_set == 0) {
4495 errmsg ("missing vrf id\n");
4496 return -99;
4497 }
4498
4499 M(RESET_VRF, reset_vrf);
4500
4501 mp->vrf_id = ntohl(vrf_id);
4502 mp->is_ipv6 = is_ipv6;
4503
4504 S; W;
4505 /* NOTREACHED */
4506 return 0;
4507}
4508
4509static int api_create_vlan_subif (vat_main_t * vam)
4510{
4511 unformat_input_t * i = vam->input;
4512 vl_api_create_vlan_subif_t *mp;
4513 f64 timeout;
4514 u32 sw_if_index;
4515 u8 sw_if_index_set = 0;
4516 u32 vlan_id;
4517 u8 vlan_id_set = 0;
4518
4519 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4520 if (unformat (i, "sw_if_index %d", &sw_if_index))
4521 sw_if_index_set = 1;
4522 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4523 sw_if_index_set = 1;
4524 else if (unformat (i, "vlan %d", &vlan_id))
4525 vlan_id_set = 1;
4526 else {
4527 clib_warning ("parse error '%U'", format_unformat_error, i);
4528 return -99;
4529 }
4530 }
4531
4532 if (sw_if_index_set == 0) {
4533 errmsg ("missing interface name or sw_if_index\n");
4534 return -99;
4535 }
4536
4537 if (vlan_id_set == 0) {
4538 errmsg ("missing vlan_id\n");
4539 return -99;
4540 }
4541 M(CREATE_VLAN_SUBIF, create_vlan_subif);
4542
4543 mp->sw_if_index = ntohl(sw_if_index);
4544 mp->vlan_id = ntohl(vlan_id);
4545
4546 S; W;
4547 /* NOTREACHED */
4548 return 0;
4549}
4550
4551#define foreach_create_subif_bit \
4552_(no_tags) \
4553_(one_tag) \
4554_(two_tags) \
4555_(dot1ad) \
4556_(exact_match) \
4557_(default_sub) \
4558_(outer_vlan_id_any) \
4559_(inner_vlan_id_any)
4560
4561static int api_create_subif (vat_main_t * vam)
4562{
4563 unformat_input_t * i = vam->input;
4564 vl_api_create_subif_t *mp;
4565 f64 timeout;
4566 u32 sw_if_index;
4567 u8 sw_if_index_set = 0;
4568 u32 sub_id;
4569 u8 sub_id_set = 0;
4570 u32 no_tags = 0;
4571 u32 one_tag = 0;
4572 u32 two_tags = 0;
4573 u32 dot1ad = 0;
4574 u32 exact_match = 0;
4575 u32 default_sub = 0;
4576 u32 outer_vlan_id_any = 0;
4577 u32 inner_vlan_id_any = 0;
4578 u32 tmp;
4579 u16 outer_vlan_id = 0;
4580 u16 inner_vlan_id = 0;
4581
4582 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4583 if (unformat (i, "sw_if_index %d", &sw_if_index))
4584 sw_if_index_set = 1;
4585 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4586 sw_if_index_set = 1;
4587 else if (unformat (i, "sub_id %d", &sub_id))
4588 sub_id_set = 1;
4589 else if (unformat (i, "outer_vlan_id %d", &tmp))
4590 outer_vlan_id = tmp;
4591 else if (unformat (i, "inner_vlan_id %d", &tmp))
4592 inner_vlan_id = tmp;
4593
4594#define _(a) else if (unformat (i, #a)) a = 1 ;
4595 foreach_create_subif_bit
4596#undef _
4597
4598 else {
4599 clib_warning ("parse error '%U'", format_unformat_error, i);
4600 return -99;
4601 }
4602 }
4603
4604 if (sw_if_index_set == 0) {
4605 errmsg ("missing interface name or sw_if_index\n");
4606 return -99;
4607 }
4608
4609 if (sub_id_set == 0) {
4610 errmsg ("missing sub_id\n");
4611 return -99;
4612 }
4613 M(CREATE_SUBIF, create_subif);
4614
4615 mp->sw_if_index = ntohl(sw_if_index);
4616 mp->sub_id = ntohl(sub_id);
4617
4618#define _(a) mp->a = a;
4619 foreach_create_subif_bit;
4620#undef _
4621
4622 mp->outer_vlan_id = ntohs (outer_vlan_id);
4623 mp->inner_vlan_id = ntohs (inner_vlan_id);
4624
4625 S; W;
4626 /* NOTREACHED */
4627 return 0;
4628}
4629
4630static int api_oam_add_del (vat_main_t * vam)
4631{
4632 unformat_input_t * i = vam->input;
4633 vl_api_oam_add_del_t *mp;
4634 f64 timeout;
4635 u32 vrf_id = 0;
4636 u8 is_add = 1;
4637 ip4_address_t src, dst;
4638 u8 src_set = 0;
4639 u8 dst_set = 0;
4640
4641 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4642 if (unformat (i, "vrf %d", &vrf_id))
4643 ;
4644 else if (unformat (i, "src %U", unformat_ip4_address, &src))
4645 src_set = 1;
4646 else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
4647 dst_set = 1;
4648 else if (unformat (i, "del"))
4649 is_add = 0;
4650 else {
4651 clib_warning ("parse error '%U'", format_unformat_error, i);
4652 return -99;
4653 }
4654 }
4655
4656 if (src_set == 0) {
4657 errmsg ("missing src addr\n");
4658 return -99;
4659 }
4660
4661 if (dst_set == 0) {
4662 errmsg ("missing dst addr\n");
4663 return -99;
4664 }
4665
4666 M(OAM_ADD_DEL, oam_add_del);
4667
4668 mp->vrf_id = ntohl(vrf_id);
4669 mp->is_add = is_add;
Damjan Marionf1213b82016-03-13 02:22:06 +01004670 clib_memcpy(mp->src_address, &src, sizeof (mp->src_address));
4671 clib_memcpy(mp->dst_address, &dst, sizeof (mp->dst_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004672
4673 S; W;
4674 /* NOTREACHED */
4675 return 0;
4676}
4677
4678static int api_reset_fib (vat_main_t * vam)
4679{
4680 unformat_input_t * i = vam->input;
4681 vl_api_reset_fib_t *mp;
4682 f64 timeout;
4683 u32 vrf_id = 0;
4684 u8 is_ipv6 = 0;
4685 u8 vrf_id_set = 0;
4686
4687 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4688 if (unformat (i, "vrf %d", &vrf_id))
4689 vrf_id_set = 1;
4690 else if (unformat (i, "ipv6"))
4691 is_ipv6 = 1;
4692 else {
4693 clib_warning ("parse error '%U'", format_unformat_error, i);
4694 return -99;
4695 }
4696 }
4697
4698 if (vrf_id_set == 0) {
4699 errmsg ("missing vrf id\n");
4700 return -99;
4701 }
4702
4703 M(RESET_FIB, reset_fib);
4704
4705 mp->vrf_id = ntohl(vrf_id);
4706 mp->is_ipv6 = is_ipv6;
4707
4708 S; W;
4709 /* NOTREACHED */
4710 return 0;
4711}
4712
4713static int api_dhcp_proxy_config (vat_main_t * vam)
4714{
4715 unformat_input_t * i = vam->input;
4716 vl_api_dhcp_proxy_config_t *mp;
4717 f64 timeout;
4718 u32 vrf_id = 0;
4719 u8 is_add = 1;
4720 u8 insert_cid = 1;
4721 u8 v4_address_set = 0;
4722 u8 v6_address_set = 0;
4723 ip4_address_t v4address;
4724 ip6_address_t v6address;
4725 u8 v4_src_address_set = 0;
4726 u8 v6_src_address_set = 0;
4727 ip4_address_t v4srcaddress;
4728 ip6_address_t v6srcaddress;
4729
4730 /* Parse args required to build the message */
4731 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4732 if (unformat (i, "del"))
4733 is_add = 0;
4734 else if (unformat (i, "vrf %d", &vrf_id))
4735 ;
4736 else if (unformat (i, "insert-cid %d", &insert_cid))
4737 ;
4738 else if (unformat (i, "svr %U",
4739 unformat_ip4_address, &v4address))
4740 v4_address_set = 1;
4741 else if (unformat (i, "svr %U",
4742 unformat_ip6_address, &v6address))
4743 v6_address_set = 1;
4744 else if (unformat (i, "src %U",
4745 unformat_ip4_address, &v4srcaddress))
4746 v4_src_address_set = 1;
4747 else if (unformat (i, "src %U",
4748 unformat_ip6_address, &v6srcaddress))
4749 v6_src_address_set = 1;
4750 else
4751 break;
4752 }
4753
4754 if (v4_address_set && v6_address_set) {
4755 errmsg ("both v4 and v6 server addresses set\n");
4756 return -99;
4757 }
4758 if (!v4_address_set && !v6_address_set) {
4759 errmsg ("no server addresses set\n");
4760 return -99;
4761 }
4762
4763 if (v4_src_address_set && v6_src_address_set) {
4764 errmsg ("both v4 and v6 src addresses set\n");
4765 return -99;
4766 }
4767 if (!v4_src_address_set && !v6_src_address_set) {
4768 errmsg ("no src addresses set\n");
4769 return -99;
4770 }
4771
4772 if (!(v4_src_address_set && v4_address_set) &&
4773 !(v6_src_address_set && v6_address_set)) {
4774 errmsg ("no matching server and src addresses set\n");
4775 return -99;
4776 }
4777
4778 /* Construct the API message */
4779 M(DHCP_PROXY_CONFIG, dhcp_proxy_config);
4780
4781 mp->insert_circuit_id = insert_cid;
4782 mp->is_add = is_add;
4783 mp->vrf_id = ntohl (vrf_id);
4784 if (v6_address_set) {
4785 mp->is_ipv6 = 1;
Damjan Marionf1213b82016-03-13 02:22:06 +01004786 clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
4787 clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004788 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01004789 clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
4790 clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004791 }
4792
4793 /* send it... */
4794 S;
4795
4796 /* Wait for a reply, return good/bad news */
4797 W;
4798 /* NOTREACHED */
4799 return 0;
4800}
4801
4802static int api_dhcp_proxy_config_2 (vat_main_t * vam)
4803{
4804 unformat_input_t * i = vam->input;
4805 vl_api_dhcp_proxy_config_2_t *mp;
4806 f64 timeout;
4807 u32 rx_vrf_id = 0;
4808 u32 server_vrf_id = 0;
4809 u8 is_add = 1;
4810 u8 insert_cid = 1;
4811 u8 v4_address_set = 0;
4812 u8 v6_address_set = 0;
4813 ip4_address_t v4address;
4814 ip6_address_t v6address;
4815 u8 v4_src_address_set = 0;
4816 u8 v6_src_address_set = 0;
4817 ip4_address_t v4srcaddress;
4818 ip6_address_t v6srcaddress;
4819
4820 /* Parse args required to build the message */
4821 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4822 if (unformat (i, "del"))
4823 is_add = 0;
4824 else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
4825 ;
4826 else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
4827 ;
4828 else if (unformat (i, "insert-cid %d", &insert_cid))
4829 ;
4830 else if (unformat (i, "svr %U",
4831 unformat_ip4_address, &v4address))
4832 v4_address_set = 1;
4833 else if (unformat (i, "svr %U",
4834 unformat_ip6_address, &v6address))
4835 v6_address_set = 1;
4836 else if (unformat (i, "src %U",
4837 unformat_ip4_address, &v4srcaddress))
4838 v4_src_address_set = 1;
4839 else if (unformat (i, "src %U",
4840 unformat_ip6_address, &v6srcaddress))
4841 v6_src_address_set = 1;
4842 else
4843 break;
4844 }
4845
4846 if (v4_address_set && v6_address_set) {
4847 errmsg ("both v4 and v6 server addresses set\n");
4848 return -99;
4849 }
4850 if (!v4_address_set && !v6_address_set) {
4851 errmsg ("no server addresses set\n");
4852 return -99;
4853 }
4854
4855 if (v4_src_address_set && v6_src_address_set) {
4856 errmsg ("both v4 and v6 src addresses set\n");
4857 return -99;
4858 }
4859 if (!v4_src_address_set && !v6_src_address_set) {
4860 errmsg ("no src addresses set\n");
4861 return -99;
4862 }
4863
4864 if (!(v4_src_address_set && v4_address_set) &&
4865 !(v6_src_address_set && v6_address_set)) {
4866 errmsg ("no matching server and src addresses set\n");
4867 return -99;
4868 }
4869
4870 /* Construct the API message */
4871 M(DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
4872
4873 mp->insert_circuit_id = insert_cid;
4874 mp->is_add = is_add;
4875 mp->rx_vrf_id = ntohl (rx_vrf_id);
4876 mp->server_vrf_id = ntohl (server_vrf_id);
4877 if (v6_address_set) {
4878 mp->is_ipv6 = 1;
Damjan Marionf1213b82016-03-13 02:22:06 +01004879 clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
4880 clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004881 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01004882 clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
4883 clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004884 }
4885
4886 /* send it... */
4887 S;
4888
4889 /* Wait for a reply, return good/bad news */
4890 W;
4891 /* NOTREACHED */
4892 return 0;
4893}
4894
4895static int api_dhcp_proxy_set_vss (vat_main_t * vam)
4896{
4897 unformat_input_t * i = vam->input;
4898 vl_api_dhcp_proxy_set_vss_t *mp;
4899 f64 timeout;
4900 u8 is_ipv6 = 0;
4901 u8 is_add = 1;
4902 u32 tbl_id;
4903 u8 tbl_id_set = 0;
4904 u32 oui;
4905 u8 oui_set = 0;
4906 u32 fib_id;
4907 u8 fib_id_set = 0;
4908
4909 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4910 if (unformat (i, "tbl_id %d", &tbl_id))
4911 tbl_id_set = 1;
4912 if (unformat (i, "fib_id %d", &fib_id))
4913 fib_id_set = 1;
4914 if (unformat (i, "oui %d", &oui))
4915 oui_set = 1;
4916 else if (unformat (i, "ipv6"))
4917 is_ipv6 = 1;
4918 else if (unformat (i, "del"))
4919 is_add = 0;
4920 else {
4921 clib_warning ("parse error '%U'", format_unformat_error, i);
4922 return -99;
4923 }
4924 }
4925
4926 if (tbl_id_set == 0) {
4927 errmsg ("missing tbl id\n");
4928 return -99;
4929 }
4930
4931 if (fib_id_set == 0) {
4932 errmsg ("missing fib id\n");
4933 return -99;
4934 }
4935 if (oui_set == 0) {
4936 errmsg ("missing oui\n");
4937 return -99;
4938 }
4939
4940 M(DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
4941 mp->tbl_id = ntohl(tbl_id);
4942 mp->fib_id = ntohl(fib_id);
4943 mp->oui = ntohl(oui);
4944 mp->is_ipv6 = is_ipv6;
4945 mp->is_add = is_add;
4946
4947 S; W;
4948 /* NOTREACHED */
4949 return 0;
4950}
4951
4952static int api_dhcp_client_config (vat_main_t * vam)
4953{
4954 unformat_input_t * i = vam->input;
4955 vl_api_dhcp_client_config_t *mp;
4956 f64 timeout;
4957 u32 sw_if_index;
4958 u8 sw_if_index_set = 0;
4959 u8 is_add = 1;
4960 u8 * hostname = 0;
4961 u8 disable_event = 0;
4962
4963 /* Parse args required to build the message */
4964 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4965 if (unformat (i, "del"))
4966 is_add = 0;
4967 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4968 sw_if_index_set = 1;
4969 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4970 sw_if_index_set = 1;
4971 else if (unformat (i, "hostname %s", &hostname))
4972 ;
4973 else if (unformat (i, "disable_event"))
4974 disable_event = 1;
4975 else
4976 break;
4977 }
4978
4979 if (sw_if_index_set == 0) {
4980 errmsg ("missing interface name or sw_if_index\n");
4981 return -99;
4982 }
4983
4984 if (vec_len (hostname) > 63) {
4985 errmsg ("hostname too long\n");
4986 }
4987 vec_add1 (hostname, 0);
4988
4989 /* Construct the API message */
4990 M(DHCP_CLIENT_CONFIG, dhcp_client_config);
4991
4992 mp->sw_if_index = ntohl (sw_if_index);
Damjan Marionf1213b82016-03-13 02:22:06 +01004993 clib_memcpy (mp->hostname, hostname, vec_len (hostname));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004994 vec_free (hostname);
4995 mp->is_add = is_add;
4996 mp->want_dhcp_event = disable_event ? 0 : 1;
4997 mp->pid = getpid();
4998
4999 /* send it... */
5000 S;
5001
5002 /* Wait for a reply, return good/bad news */
5003 W;
5004 /* NOTREACHED */
5005 return 0;
5006}
5007
5008static int api_set_ip_flow_hash (vat_main_t * vam)
5009{
5010 unformat_input_t * i = vam->input;
5011 vl_api_set_ip_flow_hash_t *mp;
5012 f64 timeout;
5013 u32 vrf_id = 0;
5014 u8 is_ipv6 = 0;
5015 u8 vrf_id_set = 0;
5016 u8 src = 0;
5017 u8 dst = 0;
5018 u8 sport = 0;
5019 u8 dport = 0;
5020 u8 proto = 0;
5021 u8 reverse = 0;
5022
5023 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5024 if (unformat (i, "vrf %d", &vrf_id))
5025 vrf_id_set = 1;
5026 else if (unformat (i, "ipv6"))
5027 is_ipv6 = 1;
5028 else if (unformat (i, "src"))
5029 src = 1;
5030 else if (unformat (i, "dst"))
5031 dst = 1;
5032 else if (unformat (i, "sport"))
5033 sport = 1;
5034 else if (unformat (i, "dport"))
5035 dport = 1;
5036 else if (unformat (i, "proto"))
5037 proto = 1;
5038 else if (unformat (i, "reverse"))
5039 reverse = 1;
5040
5041 else {
5042 clib_warning ("parse error '%U'", format_unformat_error, i);
5043 return -99;
5044 }
5045 }
5046
5047 if (vrf_id_set == 0) {
5048 errmsg ("missing vrf id\n");
5049 return -99;
5050 }
5051
5052 M(SET_IP_FLOW_HASH, set_ip_flow_hash);
5053 mp->src = src;
5054 mp->dst = dst;
5055 mp->sport = sport;
5056 mp->dport = dport;
5057 mp->proto = proto;
5058 mp->reverse = reverse;
5059 mp->vrf_id = ntohl(vrf_id);
5060 mp->is_ipv6 = is_ipv6;
5061
5062 S; W;
5063 /* NOTREACHED */
5064 return 0;
5065}
5066
5067static int api_sw_interface_ip6_enable_disable (vat_main_t * vam)
5068{
5069 unformat_input_t * i = vam->input;
5070 vl_api_sw_interface_ip6_enable_disable_t *mp;
5071 f64 timeout;
5072 u32 sw_if_index;
5073 u8 sw_if_index_set = 0;
5074 u8 enable = 0;
5075
5076 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5077 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5078 sw_if_index_set = 1;
5079 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5080 sw_if_index_set = 1;
5081 else if (unformat (i, "enable"))
5082 enable = 1;
5083 else if (unformat (i, "disable"))
5084 enable = 0;
5085 else {
5086 clib_warning ("parse error '%U'", format_unformat_error, i);
5087 return -99;
5088 }
5089 }
5090
5091 if (sw_if_index_set == 0) {
5092 errmsg ("missing interface name or sw_if_index\n");
5093 return -99;
5094 }
5095
5096 M(SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
5097
5098 mp->sw_if_index = ntohl(sw_if_index);
5099 mp->enable = enable;
5100
5101 S; W;
5102 /* NOTREACHED */
5103 return 0;
5104}
5105
5106static int api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
5107{
5108 unformat_input_t * i = vam->input;
5109 vl_api_sw_interface_ip6_set_link_local_address_t *mp;
5110 f64 timeout;
5111 u32 sw_if_index;
5112 u8 sw_if_index_set = 0;
5113 u32 address_length = 0;
5114 u8 v6_address_set = 0;
5115 ip6_address_t v6address;
5116
5117 /* Parse args required to build the message */
5118 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5119 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5120 sw_if_index_set = 1;
5121 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5122 sw_if_index_set = 1;
5123 else if (unformat (i, "%U/%d",
5124 unformat_ip6_address, &v6address,
5125 &address_length))
5126 v6_address_set = 1;
5127 else
5128 break;
5129 }
5130
5131 if (sw_if_index_set == 0) {
5132 errmsg ("missing interface name or sw_if_index\n");
5133 return -99;
5134 }
5135 if (!v6_address_set) {
5136 errmsg ("no address set\n");
5137 return -99;
5138 }
5139
5140 /* Construct the API message */
5141 M(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, \
5142 sw_interface_ip6_set_link_local_address);
5143
5144 mp->sw_if_index = ntohl (sw_if_index);
Damjan Marionf1213b82016-03-13 02:22:06 +01005145 clib_memcpy (mp->address, &v6address, sizeof (v6address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005146 mp->address_length = address_length;
5147
5148 /* send it... */
5149 S;
5150
5151 /* Wait for a reply, return good/bad news */
5152 W;
5153
5154 /* NOTREACHED */
5155 return 0;
5156}
5157
5158
5159static int api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
5160{
5161 unformat_input_t * i = vam->input;
5162 vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
5163 f64 timeout;
5164 u32 sw_if_index;
5165 u8 sw_if_index_set = 0;
5166 u32 address_length = 0;
5167 u8 v6_address_set = 0;
5168 ip6_address_t v6address;
5169 u8 use_default = 0;
5170 u8 no_advertise = 0;
5171 u8 off_link = 0;
5172 u8 no_autoconfig = 0;
5173 u8 no_onlink = 0;
5174 u8 is_no = 0;
5175 u32 val_lifetime = 0;
5176 u32 pref_lifetime = 0;
5177
5178 /* Parse args required to build the message */
5179 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5180 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5181 sw_if_index_set = 1;
5182 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5183 sw_if_index_set = 1;
5184 else if (unformat (i, "%U/%d",
5185 unformat_ip6_address, &v6address,
5186 &address_length))
5187 v6_address_set = 1;
5188 else if (unformat (i, "val_life %d", &val_lifetime))
5189 ;
5190 else if (unformat (i, "pref_life %d", &pref_lifetime))
5191 ;
5192 else if (unformat (i, "def"))
5193 use_default = 1;
5194 else if (unformat (i, "noadv"))
5195 no_advertise = 1;
5196 else if (unformat (i, "offl"))
5197 off_link = 1;
5198 else if (unformat (i, "noauto"))
5199 no_autoconfig = 1;
5200 else if (unformat (i, "nolink"))
5201 no_onlink = 1;
5202 else if (unformat (i, "isno"))
5203 is_no = 1;
5204 else {
5205 clib_warning ("parse error '%U'", format_unformat_error, i);
5206 return -99;
5207 }
5208 }
5209
5210 if (sw_if_index_set == 0) {
5211 errmsg ("missing interface name or sw_if_index\n");
5212 return -99;
5213 }
5214 if (!v6_address_set) {
5215 errmsg ("no address set\n");
5216 return -99;
5217 }
5218
5219 /* Construct the API message */
5220 M(SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
5221
5222 mp->sw_if_index = ntohl (sw_if_index);
Damjan Marionf1213b82016-03-13 02:22:06 +01005223 clib_memcpy (mp->address, &v6address, sizeof (v6address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005224 mp->address_length = address_length;
5225 mp->use_default = use_default;
5226 mp->no_advertise = no_advertise;
5227 mp->off_link = off_link;
5228 mp->no_autoconfig = no_autoconfig;
5229 mp->no_onlink = no_onlink;
5230 mp->is_no = is_no;
5231 mp->val_lifetime = ntohl(val_lifetime);
5232 mp->pref_lifetime = ntohl(pref_lifetime);
5233
5234 /* send it... */
5235 S;
5236
5237 /* Wait for a reply, return good/bad news */
5238 W;
5239
5240 /* NOTREACHED */
5241 return 0;
5242}
5243
5244static int api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
5245{
5246 unformat_input_t * i = vam->input;
5247 vl_api_sw_interface_ip6nd_ra_config_t *mp;
5248 f64 timeout;
5249 u32 sw_if_index;
5250 u8 sw_if_index_set = 0;
5251 u8 surpress = 0;
5252 u8 managed = 0;
5253 u8 other = 0;
5254 u8 ll_option = 0;
5255 u8 send_unicast = 0;
5256 u8 cease = 0;
5257 u8 is_no = 0;
5258 u8 default_router = 0;
5259 u32 max_interval = 0;
5260 u32 min_interval = 0;
5261 u32 lifetime = 0;
5262 u32 initial_count = 0;
5263 u32 initial_interval = 0;
5264
5265
5266 /* Parse args required to build the message */
5267 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5268 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5269 sw_if_index_set = 1;
5270 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5271 sw_if_index_set = 1;
5272 else if (unformat (i, "maxint %d", &max_interval))
5273 ;
5274 else if (unformat (i, "minint %d", &min_interval))
5275 ;
5276 else if (unformat (i, "life %d", &lifetime))
5277 ;
5278 else if (unformat (i, "count %d", &initial_count))
5279 ;
5280 else if (unformat (i, "interval %d", &initial_interval))
5281 ;
5282 else if (unformat (i, "surpress"))
5283 surpress = 1;
5284 else if (unformat (i, "managed"))
5285 managed = 1;
5286 else if (unformat (i, "other"))
5287 other = 1;
5288 else if (unformat (i, "ll"))
5289 ll_option = 1;
5290 else if (unformat (i, "send"))
5291 send_unicast = 1;
5292 else if (unformat (i, "cease"))
5293 cease = 1;
5294 else if (unformat (i, "isno"))
5295 is_no = 1;
5296 else if (unformat (i, "def"))
5297 default_router = 1;
5298 else {
5299 clib_warning ("parse error '%U'", format_unformat_error, i);
5300 return -99;
5301 }
5302 }
5303
5304 if (sw_if_index_set == 0) {
5305 errmsg ("missing interface name or sw_if_index\n");
5306 return -99;
5307 }
5308
5309 /* Construct the API message */
5310 M(SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
5311
5312 mp->sw_if_index = ntohl (sw_if_index);
5313 mp->max_interval = ntohl(max_interval);
5314 mp->min_interval = ntohl(min_interval);
5315 mp->lifetime = ntohl(lifetime);
5316 mp->initial_count = ntohl(initial_count);
5317 mp->initial_interval = ntohl(initial_interval);
5318 mp->surpress = surpress;
5319 mp->managed = managed;
5320 mp->other = other;
5321 mp->ll_option = ll_option;
5322 mp->send_unicast = send_unicast;
5323 mp->cease = cease;
5324 mp->is_no = is_no;
5325 mp->default_router = default_router;
5326
5327 /* send it... */
5328 S;
5329
5330 /* Wait for a reply, return good/bad news */
5331 W;
5332
5333 /* NOTREACHED */
5334 return 0;
5335}
5336
5337static int api_set_arp_neighbor_limit (vat_main_t * vam)
5338{
5339 unformat_input_t * i = vam->input;
5340 vl_api_set_arp_neighbor_limit_t *mp;
5341 f64 timeout;
5342 u32 arp_nbr_limit;
5343 u8 limit_set = 0;
5344 u8 is_ipv6 = 0;
5345
5346 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5347 if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
5348 limit_set = 1;
5349 else if (unformat (i, "ipv6"))
5350 is_ipv6 = 1;
5351 else {
5352 clib_warning ("parse error '%U'", format_unformat_error, i);
5353 return -99;
5354 }
5355 }
5356
5357 if (limit_set == 0) {
5358 errmsg ("missing limit value\n");
5359 return -99;
5360 }
5361
5362 M(SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
5363
5364 mp->arp_neighbor_limit = ntohl(arp_nbr_limit);
5365 mp->is_ipv6 = is_ipv6;
5366
5367 S; W;
5368 /* NOTREACHED */
5369 return 0;
5370}
5371
5372static int api_l2_patch_add_del (vat_main_t * vam)
5373{
5374 unformat_input_t * i = vam->input;
5375 vl_api_l2_patch_add_del_t *mp;
5376 f64 timeout;
5377 u32 rx_sw_if_index;
5378 u8 rx_sw_if_index_set = 0;
5379 u32 tx_sw_if_index;
5380 u8 tx_sw_if_index_set = 0;
5381 u8 is_add = 1;
5382
5383 /* Parse args required to build the message */
5384 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5385 if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5386 rx_sw_if_index_set = 1;
5387 else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5388 tx_sw_if_index_set = 1;
5389 else if (unformat (i, "rx")) {
5390 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5391 if (unformat (i, "%U", unformat_sw_if_index, vam,
5392 &rx_sw_if_index))
5393 rx_sw_if_index_set = 1;
5394 } else
5395 break;
5396 } else if (unformat (i, "tx")) {
5397 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5398 if (unformat (i, "%U", unformat_sw_if_index, vam,
5399 &tx_sw_if_index))
5400 tx_sw_if_index_set = 1;
5401 } else
5402 break;
5403 } else if (unformat (i, "del"))
5404 is_add = 0;
5405 else
5406 break;
5407 }
5408
5409 if (rx_sw_if_index_set == 0) {
5410 errmsg ("missing rx interface name or rx_sw_if_index\n");
5411 return -99;
5412 }
5413
5414 if (tx_sw_if_index_set == 0) {
5415 errmsg ("missing tx interface name or tx_sw_if_index\n");
5416 return -99;
5417 }
5418
5419 M(L2_PATCH_ADD_DEL, l2_patch_add_del);
5420
5421 mp->rx_sw_if_index = ntohl(rx_sw_if_index);
5422 mp->tx_sw_if_index = ntohl(tx_sw_if_index);
5423 mp->is_add = is_add;
5424
5425 S; W;
5426 /* NOTREACHED */
5427 return 0;
5428}
Shwetha20a64f52016-03-25 10:55:01 +00005429static int api_trace_profile_add (vat_main_t *vam)
5430{
5431 unformat_input_t * input = vam->input;
5432 vl_api_trace_profile_add_t *mp;
5433 f64 timeout;
5434 u32 id = 0;
5435 u32 trace_option_elts = 0;
5436 u32 trace_type = 0, node_id = 0, app_data = 0, trace_tsp = 2;
5437 int has_pow_option = 0;
5438 int has_ppc_option = 0;
5439
5440 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5441 {
5442 if (unformat (input, "id %d trace-type 0x%x trace-elts %d "
5443 "trace-tsp %d node-id 0x%x app-data 0x%x",
5444 &id, &trace_type, &trace_option_elts, &trace_tsp,
5445 &node_id, &app_data))
5446 ;
5447 else if (unformat (input, "pow"))
5448 has_pow_option = 1;
5449 else if (unformat (input, "ppc encap"))
5450 has_ppc_option = PPC_ENCAP;
5451 else if (unformat (input, "ppc decap"))
5452 has_ppc_option = PPC_DECAP;
5453 else if (unformat (input, "ppc none"))
5454 has_ppc_option = PPC_NONE;
5455 else
5456 break;
5457 }
5458 M(TRACE_PROFILE_ADD, trace_profile_add);
5459 mp->id = htons(id);
5460 mp->trace_type = trace_type;
5461 mp->trace_num_elt = trace_option_elts;
5462 mp->trace_ppc = has_ppc_option;
5463 mp->trace_app_data = htonl(app_data);
5464 mp->pow_enable = has_pow_option;
5465 mp->trace_tsp = trace_tsp;
5466 mp->node_id = htonl(node_id);
5467
5468 S; W;
5469
5470 return(0);
5471
5472}
5473static int api_trace_profile_apply (vat_main_t *vam)
5474{
5475 unformat_input_t * input = vam->input;
5476 vl_api_trace_profile_apply_t *mp;
5477 f64 timeout;
5478 ip6_address_t addr;
5479 u32 mask_width = ~0;
5480 int is_add = 0;
5481 int is_pop = 0;
5482 int is_none = 0;
5483 u32 vrf_id = 0;
5484 u32 id = 0;
5485
5486 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5487 {
5488 if (unformat (input, "%U/%d",
5489 unformat_ip6_address, &addr, &mask_width))
5490 ;
5491 else if (unformat (input, "id %d", &id))
5492 ;
5493 else if (unformat (input, "vrf-id %d", &vrf_id))
5494 ;
5495 else if (unformat (input, "add"))
5496 is_add = 1;
5497 else if (unformat (input, "pop"))
5498 is_pop = 1;
5499 else if (unformat (input, "none"))
5500 is_none = 1;
5501 else
5502 break;
5503 }
Ed Warnickecb9cada2015-12-08 15:45:58 -07005504
Shwetha20a64f52016-03-25 10:55:01 +00005505 if ((is_add + is_pop + is_none) != 1) {
5506 errmsg("One of (add, pop, none) required");
5507 return -99;
5508 }
5509 if (mask_width == ~0) {
5510 errmsg("<address>/<mask-width> required");
5511 return -99;
5512 }
5513 M(TRACE_PROFILE_APPLY, trace_profile_apply);
Damjan Marionf1213b82016-03-13 02:22:06 +01005514 clib_memcpy(mp->dest_ipv6, &addr, sizeof(mp->dest_ipv6));
Shwetha20a64f52016-03-25 10:55:01 +00005515 mp->id = htons(id);
5516 mp->prefix_length = htonl(mask_width);
5517 mp->vrf_id = htonl(vrf_id);
5518 if (is_add)
5519 mp->trace_op = IOAM_HBYH_ADD;
5520 else if (is_pop)
5521 mp->trace_op = IOAM_HBYH_POP;
5522 else
5523 mp->trace_op = IOAM_HBYH_MOD;
5524
5525 if(is_none)
5526 mp->enable = 0;
5527 else
5528 mp->enable = 1;
5529
5530 S; W;
5531
5532 return 0;
5533}
5534
5535static int api_trace_profile_del (vat_main_t *vam)
5536{
5537 vl_api_trace_profile_del_t *mp;
5538 f64 timeout;
5539
5540 M(TRACE_PROFILE_DEL, trace_profile_del);
5541 S; W;
5542 return 0;
5543}
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07005544
Ed Warnickecb9cada2015-12-08 15:45:58 -07005545static int api_sr_tunnel_add_del (vat_main_t * vam)
5546{
5547 unformat_input_t * i = vam->input;
5548 vl_api_sr_tunnel_add_del_t *mp;
5549 f64 timeout;
5550 int is_del = 0;
5551 int pl_index;
5552 ip6_address_t src_address;
5553 int src_address_set = 0;
5554 ip6_address_t dst_address;
5555 u32 dst_mask_width;
5556 int dst_address_set = 0;
5557 u16 flags = 0;
5558 u32 rx_table_id = 0;
5559 u32 tx_table_id = 0;
5560 ip6_address_t * segments = 0;
5561 ip6_address_t * this_seg;
5562 ip6_address_t * tags = 0;
5563 ip6_address_t * this_tag;
5564 ip6_address_t next_address, tag;
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07005565 u8 * name = 0;
5566 u8 * policy_name = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -07005567
5568 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5569 {
5570 if (unformat (i, "del"))
5571 is_del = 1;
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07005572 else if (unformat (i, "name %s", &name))
5573 ;
5574 else if (unformat (i, "policy %s", &policy_name))
5575 ;
Ed Warnickecb9cada2015-12-08 15:45:58 -07005576 else if (unformat (i, "rx_fib_id %d", &rx_table_id))
5577 ;
5578 else if (unformat (i, "tx_fib_id %d", &tx_table_id))
5579 ;
5580 else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
5581 src_address_set = 1;
5582 else if (unformat (i, "dst %U/%d",
5583 unformat_ip6_address, &dst_address,
5584 &dst_mask_width))
5585 dst_address_set = 1;
5586 else if (unformat (i, "next %U", unformat_ip6_address,
5587 &next_address))
5588 {
5589 vec_add2 (segments, this_seg, 1);
Damjan Marionf1213b82016-03-13 02:22:06 +01005590 clib_memcpy (this_seg->as_u8, next_address.as_u8, sizeof (*this_seg));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005591 }
5592 else if (unformat (i, "tag %U", unformat_ip6_address,
5593 &tag))
5594 {
5595 vec_add2 (tags, this_tag, 1);
Damjan Marionf1213b82016-03-13 02:22:06 +01005596 clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005597 }
5598 else if (unformat (i, "clean"))
5599 flags |= IP6_SR_HEADER_FLAG_CLEANUP;
5600 else if (unformat (i, "protected"))
5601 flags |= IP6_SR_HEADER_FLAG_PROTECTED;
5602 else if (unformat (i, "InPE %d", &pl_index))
5603 {
5604 if (pl_index <= 0 || pl_index > 4)
5605 {
5606 pl_index_range_error:
5607 errmsg ("pl index %d out of range\n", pl_index);
5608 return -99;
5609 }
5610 flags |= IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3*(pl_index - 1));
5611 }
5612 else if (unformat (i, "EgPE %d", &pl_index))
5613 {
5614 if (pl_index <= 0 || pl_index > 4)
5615 goto pl_index_range_error;
5616 flags |= IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3*(pl_index - 1));
5617 }
5618 else if (unformat (i, "OrgSrc %d", &pl_index))
5619 {
5620 if (pl_index <= 0 || pl_index > 4)
5621 goto pl_index_range_error;
5622 flags |= IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3*(pl_index - 1));
5623 }
5624 else
5625 break;
5626 }
5627
5628 if (!src_address_set)
5629 {
5630 errmsg ("src address required\n");
5631 return -99;
5632 }
5633
5634 if (!dst_address_set)
5635 {
5636 errmsg ("dst address required\n");
5637 return -99;
5638 }
5639
5640 if (!segments)
5641 {
5642 errmsg ("at least one sr segment required\n");
5643 return -99;
5644 }
5645
5646 M2(SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
5647 vec_len(segments) * sizeof (ip6_address_t)
5648 + vec_len(tags) * sizeof (ip6_address_t));
5649
Damjan Marionf1213b82016-03-13 02:22:06 +01005650 clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
5651 clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005652 mp->dst_mask_width = dst_mask_width;
5653 mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
5654 mp->n_segments = vec_len (segments);
5655 mp->n_tags = vec_len (tags);
5656 mp->is_add = is_del == 0;
Damjan Marionf1213b82016-03-13 02:22:06 +01005657 clib_memcpy (mp->segs_and_tags, segments,
Ed Warnickecb9cada2015-12-08 15:45:58 -07005658 vec_len(segments)* sizeof (ip6_address_t));
Damjan Marionf1213b82016-03-13 02:22:06 +01005659 clib_memcpy (mp->segs_and_tags + vec_len(segments)*sizeof (ip6_address_t),
Ed Warnickecb9cada2015-12-08 15:45:58 -07005660 tags, vec_len(tags)* sizeof (ip6_address_t));
5661
5662 mp->outer_vrf_id = ntohl (rx_table_id);
5663 mp->inner_vrf_id = ntohl (tx_table_id);
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07005664 memcpy (mp->name, name, vec_len(name));
5665 memcpy (mp->policy_name, policy_name, vec_len(policy_name));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005666
5667 vec_free (segments);
5668 vec_free (tags);
5669
5670 S; W;
5671 /* NOTREACHED */
5672}
5673
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07005674static int api_sr_policy_add_del (vat_main_t * vam)
5675{
5676 unformat_input_t * input = vam->input;
5677 vl_api_sr_policy_add_del_t *mp;
5678 f64 timeout;
5679 int is_del = 0;
5680 u8 * name = 0;
5681 u8 * tunnel_name = 0;
5682 u8 ** tunnel_names = 0;
5683
5684 int name_set = 0 ;
5685 int tunnel_set = 0;
5686 int j = 0;
5687 int tunnel_names_length = 1; // Init to 1 to offset the #tunnel_names counter byte
5688 int tun_name_len = 0; // Different naming convention used as confusing these would be "bad" (TM)
5689
5690 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5691 {
5692 if (unformat (input, "del"))
5693 is_del = 1;
5694 else if (unformat (input, "name %s", &name))
5695 name_set = 1;
5696 else if (unformat (input, "tunnel %s", &tunnel_name))
5697 {
5698 if (tunnel_name)
5699 {
5700 vec_add1 (tunnel_names, tunnel_name);
5701 /* For serializer:
5702 - length = #bytes to store in serial vector
5703 - +1 = byte to store that length
5704 */
5705 tunnel_names_length += (vec_len (tunnel_name) + 1);
5706 tunnel_set = 1;
5707 tunnel_name = 0;
5708 }
5709 }
5710 else
5711 break;
5712 }
5713
5714 if (!name_set)
5715 {
5716 errmsg ("policy name required\n");
5717 return -99;
5718 }
5719
5720 if ((!tunnel_set) && (!is_del))
5721 {
5722 errmsg ("tunnel name required\n");
5723 return -99;
5724 }
5725
5726 M2(SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
5727
5728
5729
5730 mp->is_add = !is_del;
5731
5732 memcpy (mp->name, name, vec_len(name));
5733 // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
5734 u8 * serial_orig = 0;
5735 vec_validate (serial_orig, tunnel_names_length);
5736 *serial_orig = vec_len(tunnel_names); // Store the number of tunnels as length in first byte of serialized vector
5737 serial_orig += 1; // Move along one byte to store the length of first tunnel_name
5738
5739 for (j=0; j < vec_len(tunnel_names); j++)
5740 {
5741 tun_name_len = vec_len (tunnel_names[j]);
5742 *serial_orig = tun_name_len; // Store length of tunnel name in first byte of Length/Value pair
5743 serial_orig += 1; // Move along one byte to store the actual tunnel name
5744 memcpy (serial_orig, tunnel_names[j], tun_name_len);
5745 serial_orig += tun_name_len; // Advance past the copy
5746 }
5747 memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length); // Regress serial_orig to head then copy fwd
5748
5749 vec_free (tunnel_names);
5750 vec_free (tunnel_name);
5751
5752 S; W;
5753 /* NOTREACHED */
5754}
5755
5756static int api_sr_multicast_map_add_del (vat_main_t * vam)
5757{
5758 unformat_input_t * input = vam->input;
5759 vl_api_sr_multicast_map_add_del_t *mp;
5760 f64 timeout;
5761 int is_del = 0;
5762 ip6_address_t multicast_address;
5763 u8 * policy_name = 0;
5764 int multicast_address_set = 0;
5765
5766 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5767 {
5768 if (unformat (input, "del"))
5769 is_del = 1;
5770 else if (unformat (input, "address %U", unformat_ip6_address, &multicast_address))
5771 multicast_address_set = 1;
5772 else if (unformat (input, "sr-policy %s", &policy_name))
5773 ;
5774 else
5775 break;
5776 }
5777
5778 if (!is_del && !policy_name)
5779 {
5780 errmsg ("sr-policy name required\n");
5781 return -99;
5782 }
5783
5784
5785 if (!multicast_address_set)
5786 {
5787 errmsg ("address required\n");
5788 return -99;
5789 }
5790
5791 M(SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
5792
5793 mp->is_add = !is_del;
5794 memcpy (mp->policy_name, policy_name, vec_len(policy_name));
5795 clib_memcpy (mp->multicast_address, &multicast_address, sizeof (mp->multicast_address));
5796
5797
5798 vec_free (policy_name);
5799
5800 S; W;
5801 /* NOTREACHED */
5802}
5803
Ed Warnickecb9cada2015-12-08 15:45:58 -07005804
5805#define foreach_ip4_proto_field \
5806_(src_address) \
5807_(dst_address) \
5808_(tos) \
5809_(length) \
5810_(fragment_id) \
5811_(ttl) \
5812_(protocol) \
5813_(checksum)
5814
5815uword unformat_ip4_mask (unformat_input_t * input, va_list * args)
5816{
5817 u8 ** maskp = va_arg (*args, u8 **);
5818 u8 * mask = 0;
5819 u8 found_something = 0;
5820 ip4_header_t * ip;
5821
5822#define _(a) u8 a=0;
5823 foreach_ip4_proto_field;
5824#undef _
5825 u8 version = 0;
5826 u8 hdr_length = 0;
5827
5828
5829 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5830 {
5831 if (unformat (input, "version"))
5832 version = 1;
5833 else if (unformat (input, "hdr_length"))
5834 hdr_length = 1;
5835 else if (unformat (input, "src"))
5836 src_address = 1;
5837 else if (unformat (input, "dst"))
5838 dst_address = 1;
5839 else if (unformat (input, "proto"))
5840 protocol = 1;
5841
5842#define _(a) else if (unformat (input, #a)) a=1;
5843 foreach_ip4_proto_field
5844#undef _
5845 else
5846 break;
5847 }
5848
5849#define _(a) found_something += a;
5850 foreach_ip4_proto_field;
5851#undef _
5852
5853 if (found_something == 0)
5854 return 0;
5855
5856 vec_validate (mask, sizeof (*ip) - 1);
5857
5858 ip = (ip4_header_t *) mask;
5859
5860#define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
5861 foreach_ip4_proto_field;
5862#undef _
5863
5864 ip->ip_version_and_header_length = 0;
5865
5866 if (version)
5867 ip->ip_version_and_header_length |= 0xF0;
5868
5869 if (hdr_length)
5870 ip->ip_version_and_header_length |= 0x0F;
5871
5872 *maskp = mask;
5873 return 1;
5874}
5875
5876#define foreach_ip6_proto_field \
5877_(src_address) \
5878_(dst_address) \
5879_(payload_length) \
5880_(hop_limit) \
5881_(protocol)
5882
5883uword unformat_ip6_mask (unformat_input_t * input, va_list * args)
5884{
5885 u8 ** maskp = va_arg (*args, u8 **);
5886 u8 * mask = 0;
5887 u8 found_something = 0;
5888 ip6_header_t * ip;
5889 u32 ip_version_traffic_class_and_flow_label;
5890
5891#define _(a) u8 a=0;
5892 foreach_ip6_proto_field;
5893#undef _
5894 u8 version = 0;
5895 u8 traffic_class = 0;
5896 u8 flow_label = 0;
5897
5898 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5899 {
5900 if (unformat (input, "version"))
5901 version = 1;
5902 else if (unformat (input, "traffic-class"))
5903 traffic_class = 1;
5904 else if (unformat (input, "flow-label"))
5905 flow_label = 1;
5906 else if (unformat (input, "src"))
5907 src_address = 1;
5908 else if (unformat (input, "dst"))
5909 dst_address = 1;
5910 else if (unformat (input, "proto"))
5911 protocol = 1;
5912
5913#define _(a) else if (unformat (input, #a)) a=1;
5914 foreach_ip6_proto_field
5915#undef _
5916 else
5917 break;
5918 }
5919
5920#define _(a) found_something += a;
5921 foreach_ip6_proto_field;
5922#undef _
5923
5924 if (found_something == 0)
5925 return 0;
5926
5927 vec_validate (mask, sizeof (*ip) - 1);
5928
5929 ip = (ip6_header_t *) mask;
5930
5931#define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
5932 foreach_ip6_proto_field;
5933#undef _
5934
5935 ip_version_traffic_class_and_flow_label = 0;
5936
5937 if (version)
5938 ip_version_traffic_class_and_flow_label |= 0xF0000000;
5939
5940 if (traffic_class)
5941 ip_version_traffic_class_and_flow_label |= 0x0FF00000;
5942
5943 if (flow_label)
5944 ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
5945
5946 ip->ip_version_traffic_class_and_flow_label =
5947 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
5948
5949 *maskp = mask;
5950 return 1;
5951}
5952
5953uword unformat_l3_mask (unformat_input_t * input, va_list * args)
5954{
5955 u8 ** maskp = va_arg (*args, u8 **);
5956
5957 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
5958 if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
5959 return 1;
5960 else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
5961 return 1;
5962 else
5963 break;
5964 }
5965 return 0;
5966}
5967
5968uword unformat_l2_mask (unformat_input_t * input, va_list * args)
5969{
5970 u8 ** maskp = va_arg (*args, u8 **);
5971 u8 * mask = 0;
5972 u8 src = 0;
5973 u8 dst = 0;
5974 u8 proto = 0;
5975 u8 tag1 = 0;
5976 u8 tag2 = 0;
5977 u8 ignore_tag1 = 0;
5978 u8 ignore_tag2 = 0;
5979 u8 cos1 = 0;
5980 u8 cos2 = 0;
5981 u8 dot1q = 0;
5982 u8 dot1ad = 0;
5983 int len = 14;
5984
5985 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
5986 if (unformat (input, "src"))
5987 src = 1;
5988 else if (unformat (input, "dst"))
5989 dst = 1;
5990 else if (unformat (input, "proto"))
5991 proto = 1;
5992 else if (unformat (input, "tag1"))
5993 tag1 = 1;
5994 else if (unformat (input, "tag2"))
5995 tag2 = 1;
5996 else if (unformat (input, "ignore-tag1"))
5997 ignore_tag1 = 1;
5998 else if (unformat (input, "ignore-tag2"))
5999 ignore_tag2 = 1;
6000 else if (unformat (input, "cos1"))
6001 cos1 = 1;
6002 else if (unformat (input, "cos2"))
6003 cos2 = 1;
6004 else if (unformat (input, "dot1q"))
6005 dot1q = 1;
6006 else if (unformat (input, "dot1ad"))
6007 dot1ad = 1;
6008 else
6009 break;
6010 }
6011 if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
6012 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
6013 return 0;
6014
6015 if (tag1 || ignore_tag1 || cos1 || dot1q)
6016 len = 18;
6017 if (tag2 || ignore_tag2 || cos2 || dot1ad)
6018 len = 22;
6019
6020 vec_validate (mask, len-1);
6021
6022 if (dst)
6023 memset (mask, 0xff, 6);
6024
6025 if (src)
6026 memset (mask + 6, 0xff, 6);
6027
6028 if (tag2 || dot1ad)
6029 {
6030 /* inner vlan tag */
6031 if (tag2)
6032 {
6033 mask[19] = 0xff;
6034 mask[18] = 0x0f;
6035 }
6036 if (cos2)
6037 mask[18] |= 0xe0;
6038 if (proto)
6039 mask[21] = mask [20] = 0xff;
6040 if (tag1)
6041 {
6042 mask [15] = 0xff;
6043 mask [14] = 0x0f;
6044 }
6045 if (cos1)
6046 mask[14] |= 0xe0;
6047 *maskp = mask;
6048 return 1;
6049 }
6050 if (tag1 | dot1q)
6051 {
6052 if (tag1)
6053 {
6054 mask [15] = 0xff;
6055 mask [14] = 0x0f;
6056 }
6057 if (cos1)
6058 mask[14] |= 0xe0;
6059 if (proto)
6060 mask[16] = mask [17] = 0xff;
6061
6062 *maskp = mask;
6063 return 1;
6064 }
6065 if (cos2)
6066 mask[18] |= 0xe0;
6067 if (cos1)
6068 mask[14] |= 0xe0;
6069 if (proto)
6070 mask[12] = mask [13] = 0xff;
6071
6072 *maskp = mask;
6073 return 1;
6074}
6075
6076uword unformat_classify_mask (unformat_input_t * input, va_list * args)
6077{
6078 u8 ** maskp = va_arg (*args, u8 **);
6079 u32 * skipp = va_arg (*args, u32 *);
6080 u32 * matchp = va_arg (*args, u32 *);
6081 u32 match;
6082 u8 * mask = 0;
6083 u8 * l2 = 0;
6084 u8 * l3 = 0;
6085 int i;
6086
6087 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
6088 if (unformat (input, "hex %U", unformat_hex_string, &mask))
6089 ;
6090 else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
6091 ;
6092 else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
6093 ;
6094 else
6095 break;
6096 }
6097
6098 if (mask || l2 || l3)
6099 {
6100 if (l2 || l3)
6101 {
6102 /* "With a free Ethernet header in every package" */
6103 if (l2 == 0)
6104 vec_validate (l2, 13);
6105 mask = l2;
6106 vec_append (mask, l3);
6107 vec_free (l3);
6108 }
6109
6110 /* Scan forward looking for the first significant mask octet */
6111 for (i = 0; i < vec_len (mask); i++)
6112 if (mask[i])
6113 break;
6114
6115 /* compute (skip, match) params */
6116 *skipp = i / sizeof(u32x4);
6117 vec_delete (mask, *skipp * sizeof(u32x4), 0);
6118
6119 /* Pad mask to an even multiple of the vector size */
6120 while (vec_len (mask) % sizeof (u32x4))
6121 vec_add1 (mask, 0);
6122
6123 match = vec_len (mask) / sizeof (u32x4);
6124
6125 for (i = match*sizeof(u32x4); i > 0; i-= sizeof(u32x4))
6126 {
6127 u64 *tmp = (u64 *)(mask + (i-sizeof(u32x4)));
6128 if (*tmp || *(tmp+1))
6129 break;
6130 match--;
6131 }
6132 if (match == 0)
6133 clib_warning ("BUG: match 0");
6134
6135 _vec_len (mask) = match * sizeof(u32x4);
6136
6137 *matchp = match;
6138 *maskp = mask;
6139
6140 return 1;
6141 }
6142
6143 return 0;
6144}
6145
6146#define foreach_l2_next \
6147_(drop, DROP) \
6148_(ethernet, ETHERNET_INPUT) \
6149_(ip4, IP4_INPUT) \
6150_(ip6, IP6_INPUT)
6151
6152uword unformat_l2_next_index (unformat_input_t * input, va_list * args)
6153{
6154 u32 * miss_next_indexp = va_arg (*args, u32 *);
6155 u32 next_index = 0;
6156 u32 tmp;
6157
6158#define _(n,N) \
6159 if (unformat (input, #n)) { next_index = L2_CLASSIFY_NEXT_##N; goto out;}
6160 foreach_l2_next;
6161#undef _
6162
6163 if (unformat (input, "%d", &tmp))
6164 {
6165 next_index = tmp;
6166 goto out;
6167 }
6168
6169 return 0;
6170
6171 out:
6172 *miss_next_indexp = next_index;
6173 return 1;
6174}
6175
6176#define foreach_ip_next \
6177_(miss, MISS) \
6178_(drop, DROP) \
6179_(local, LOCAL) \
6180_(rewrite, REWRITE)
6181
6182uword unformat_ip_next_index (unformat_input_t * input, va_list * args)
6183{
6184 u32 * miss_next_indexp = va_arg (*args, u32 *);
6185 u32 next_index = 0;
6186 u32 tmp;
6187
6188#define _(n,N) \
6189 if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
6190 foreach_ip_next;
6191#undef _
6192
6193 if (unformat (input, "%d", &tmp))
6194 {
6195 next_index = tmp;
6196 goto out;
6197 }
6198
6199 return 0;
6200
6201 out:
6202 *miss_next_indexp = next_index;
6203 return 1;
6204}
6205
6206#define foreach_acl_next \
6207_(deny, DENY)
6208
6209uword unformat_acl_next_index (unformat_input_t * input, va_list * args)
6210{
6211 u32 * miss_next_indexp = va_arg (*args, u32 *);
6212 u32 next_index = 0;
6213 u32 tmp;
6214
6215#define _(n,N) \
6216 if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
6217 foreach_acl_next;
6218#undef _
6219
6220 if (unformat (input, "permit"))
6221 {
6222 next_index = ~0;
6223 goto out;
6224 }
6225 else if (unformat (input, "%d", &tmp))
6226 {
6227 next_index = tmp;
6228 goto out;
6229 }
6230
6231 return 0;
6232
6233 out:
6234 *miss_next_indexp = next_index;
6235 return 1;
6236}
6237
6238static int api_classify_add_del_table (vat_main_t * vam)
6239{
6240 unformat_input_t * i = vam->input;
6241 vl_api_classify_add_del_table_t *mp;
6242
6243 u32 nbuckets = 2;
6244 u32 skip = ~0;
6245 u32 match = ~0;
6246 int is_add = 1;
6247 u32 table_index = ~0;
6248 u32 next_table_index = ~0;
6249 u32 miss_next_index = ~0;
6250 u32 memory_size = 32<<20;
6251 u8 * mask = 0;
6252 f64 timeout;
6253
6254 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6255 if (unformat (i, "del"))
6256 is_add = 0;
6257 else if (unformat (i, "buckets %d", &nbuckets))
6258 ;
6259 else if (unformat (i, "memory_size %d", &memory_size))
6260 ;
6261 else if (unformat (i, "skip %d", &skip))
6262 ;
6263 else if (unformat (i, "match %d", &match))
6264 ;
6265 else if (unformat (i, "table %d", &table_index))
6266 ;
6267 else if (unformat (i, "mask %U", unformat_classify_mask,
6268 &mask, &skip, &match))
6269 ;
6270 else if (unformat (i, "next-table %d", &next_table_index))
6271 ;
6272 else if (unformat (i, "miss-next %U", unformat_ip_next_index,
6273 &miss_next_index))
6274 ;
6275 else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
6276 &miss_next_index))
6277 ;
6278 else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
6279 &miss_next_index))
6280 ;
6281 else
6282 break;
6283 }
6284
6285 if (is_add && mask == 0) {
6286 errmsg ("Mask required\n");
6287 return -99;
6288 }
6289
6290 if (is_add && skip == ~0) {
6291 errmsg ("skip count required\n");
6292 return -99;
6293 }
6294
6295 if (is_add && match == ~0) {
6296 errmsg ("match count required\n");
6297 return -99;
6298 }
6299
6300 if (!is_add && table_index == ~0) {
6301 errmsg ("table index required for delete\n");
6302 return -99;
6303 }
6304
6305 M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table,
6306 vec_len(mask));
6307
6308 mp->is_add = is_add;
6309 mp->table_index = ntohl(table_index);
6310 mp->nbuckets = ntohl(nbuckets);
6311 mp->memory_size = ntohl(memory_size);
6312 mp->skip_n_vectors = ntohl(skip);
6313 mp->match_n_vectors = ntohl(match);
6314 mp->next_table_index = ntohl(next_table_index);
6315 mp->miss_next_index = ntohl(miss_next_index);
Damjan Marionf1213b82016-03-13 02:22:06 +01006316 clib_memcpy (mp->mask, mask, vec_len(mask));
Ed Warnickecb9cada2015-12-08 15:45:58 -07006317
6318 vec_free(mask);
6319
6320 S; W;
6321 /* NOTREACHED */
6322}
6323
6324uword unformat_ip4_match (unformat_input_t * input, va_list * args)
6325{
6326 u8 ** matchp = va_arg (*args, u8 **);
6327 u8 * match = 0;
6328 ip4_header_t * ip;
6329 int version = 0;
6330 u32 version_val;
6331 int hdr_length = 0;
6332 u32 hdr_length_val;
6333 int src = 0, dst = 0;
6334 ip4_address_t src_val, dst_val;
6335 int proto = 0;
6336 u32 proto_val;
6337 int tos = 0;
6338 u32 tos_val;
6339 int length = 0;
6340 u32 length_val;
6341 int fragment_id = 0;
6342 u32 fragment_id_val;
6343 int ttl = 0;
6344 int ttl_val;
6345 int checksum = 0;
6346 u32 checksum_val;
6347
6348 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
6349 {
6350 if (unformat (input, "version %d", &version_val))
6351 version = 1;
6352 else if (unformat (input, "hdr_length %d", &hdr_length_val))
6353 hdr_length = 1;
6354 else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
6355 src = 1;
6356 else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
6357 dst = 1;
6358 else if (unformat (input, "proto %d", &proto_val))
6359 proto = 1;
6360 else if (unformat (input, "tos %d", &tos_val))
6361 tos = 1;
6362 else if (unformat (input, "length %d", &length_val))
6363 length = 1;
6364 else if (unformat (input, "fragment_id %d", &fragment_id_val))
6365 fragment_id = 1;
6366 else if (unformat (input, "ttl %d", &ttl_val))
6367 ttl = 1;
6368 else if (unformat (input, "checksum %d", &checksum_val))
6369 checksum = 1;
6370 else
6371 break;
6372 }
6373
6374 if (version + hdr_length + src + dst + proto + tos + length + fragment_id
6375 + ttl + checksum == 0)
6376 return 0;
6377
6378 /*
6379 * Aligned because we use the real comparison functions
6380 */
6381 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof(u32x4));
6382
6383 ip = (ip4_header_t *) match;
6384
6385 /* These are realistically matched in practice */
6386 if (src)
6387 ip->src_address.as_u32 = src_val.as_u32;
6388
6389 if (dst)
6390 ip->dst_address.as_u32 = dst_val.as_u32;
6391
6392 if (proto)
6393 ip->protocol = proto_val;
6394
6395
6396 /* These are not, but they're included for completeness */
6397 if (version)
6398 ip->ip_version_and_header_length |= (version_val & 0xF)<<4;
6399
6400 if (hdr_length)
6401 ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
6402
6403 if (tos)
6404 ip->tos = tos_val;
6405
6406 if (length)
6407 ip->length = length_val;
6408
6409 if (ttl)
6410 ip->ttl = ttl_val;
6411
6412 if (checksum)
6413 ip->checksum = checksum_val;
6414
6415 *matchp = match;
6416 return 1;
6417}
6418
6419uword unformat_ip6_match (unformat_input_t * input, va_list * args)
6420{
6421 u8 ** matchp = va_arg (*args, u8 **);
6422 u8 * match = 0;
6423 ip6_header_t * ip;
6424 int version = 0;
6425 u32 version_val;
6426 u8 traffic_class;
6427 u32 traffic_class_val;
6428 u8 flow_label;
6429 u8 flow_label_val;
6430 int src = 0, dst = 0;
6431 ip6_address_t src_val, dst_val;
6432 int proto = 0;
6433 u32 proto_val;
6434 int payload_length = 0;
6435 u32 payload_length_val;
6436 int hop_limit = 0;
6437 int hop_limit_val;
6438 u32 ip_version_traffic_class_and_flow_label;
6439
6440 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
6441 {
6442 if (unformat (input, "version %d", &version_val))
6443 version = 1;
6444 else if (unformat (input, "traffic_class %d", &traffic_class_val))
6445 traffic_class = 1;
6446 else if (unformat (input, "flow_label %d", &flow_label_val))
6447 flow_label = 1;
6448 else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
6449 src = 1;
6450 else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
6451 dst = 1;
6452 else if (unformat (input, "proto %d", &proto_val))
6453 proto = 1;
6454 else if (unformat (input, "payload_length %d", &payload_length_val))
6455 payload_length = 1;
6456 else if (unformat (input, "hop_limit %d", &hop_limit_val))
6457 hop_limit = 1;
6458 else
6459 break;
6460 }
6461
6462 if (version + traffic_class + flow_label + src + dst + proto +
6463 payload_length + hop_limit == 0)
6464 return 0;
6465
6466 /*
6467 * Aligned because we use the real comparison functions
6468 */
6469 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof(u32x4));
6470
6471 ip = (ip6_header_t *) match;
6472
6473 if (src)
Damjan Marionf1213b82016-03-13 02:22:06 +01006474 clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07006475
6476 if (dst)
Damjan Marionf1213b82016-03-13 02:22:06 +01006477 clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07006478
6479 if (proto)
6480 ip->protocol = proto_val;
6481
6482 ip_version_traffic_class_and_flow_label = 0;
6483
6484 if (version)
6485 ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
6486
6487 if (traffic_class)
6488 ip_version_traffic_class_and_flow_label |= (traffic_class_val & 0xFF) << 20;
6489
6490 if (flow_label)
6491 ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
6492
6493 ip->ip_version_traffic_class_and_flow_label =
6494 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
6495
6496 if (payload_length)
6497 ip->payload_length = clib_host_to_net_u16 (payload_length_val);
6498
6499 if (hop_limit)
6500 ip->hop_limit = hop_limit_val;
6501
6502 *matchp = match;
6503 return 1;
6504}
6505
6506uword unformat_l3_match (unformat_input_t * input, va_list * args)
6507{
6508 u8 ** matchp = va_arg (*args, u8 **);
6509
6510 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
6511 if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
6512 return 1;
6513 else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
6514 return 1;
6515 else
6516 break;
6517 }
6518 return 0;
6519}
6520
6521uword unformat_vlan_tag (unformat_input_t * input, va_list * args)
6522{
6523 u8 * tagp = va_arg (*args, u8 *);
6524 u32 tag;
6525
6526 if (unformat(input, "%d", &tag))
6527 {
6528 tagp[0] = (tag>>8) & 0x0F;
6529 tagp[1] = tag & 0xFF;
6530 return 1;
6531 }
6532
6533 return 0;
6534}
6535
6536uword unformat_l2_match (unformat_input_t * input, va_list * args)
6537{
6538 u8 ** matchp = va_arg (*args, u8 **);
6539 u8 * match = 0;
6540 u8 src = 0;
6541 u8 src_val[6];
6542 u8 dst = 0;
6543 u8 dst_val[6];
6544 u8 proto = 0;
6545 u16 proto_val;
6546 u8 tag1 = 0;
6547 u8 tag1_val [2];
6548 u8 tag2 = 0;
6549 u8 tag2_val [2];
6550 int len = 14;
6551 u8 ignore_tag1 = 0;
6552 u8 ignore_tag2 = 0;
6553 u8 cos1 = 0;
6554 u8 cos2 = 0;
6555 u32 cos1_val = 0;
6556 u32 cos2_val = 0;
6557
6558 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
6559 if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
6560 src = 1;
6561 else if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
6562 dst = 1;
6563 else if (unformat (input, "proto %U",
6564 unformat_ethernet_type_host_byte_order, &proto_val))
6565 proto = 1;
6566 else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
6567 tag1 = 1;
6568 else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
6569 tag2 = 1;
6570 else if (unformat (input, "ignore-tag1"))
6571 ignore_tag1 = 1;
6572 else if (unformat (input, "ignore-tag2"))
6573 ignore_tag2 = 1;
6574 else if (unformat (input, "cos1 %d", &cos1_val))
6575 cos1 = 1;
6576 else if (unformat (input, "cos2 %d", &cos2_val))
6577 cos2 = 1;
6578 else
6579 break;
6580 }
6581 if ((src + dst + proto + tag1 + tag2 +
6582 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
6583 return 0;
6584
6585 if (tag1 || ignore_tag1 || cos1)
6586 len = 18;
6587 if (tag2 || ignore_tag2 || cos2)
6588 len = 22;
6589
6590 vec_validate_aligned (match, len-1, sizeof(u32x4));
6591
6592 if (dst)
Damjan Marionf1213b82016-03-13 02:22:06 +01006593 clib_memcpy (match, dst_val, 6);
Ed Warnickecb9cada2015-12-08 15:45:58 -07006594
6595 if (src)
Damjan Marionf1213b82016-03-13 02:22:06 +01006596 clib_memcpy (match + 6, src_val, 6);
Ed Warnickecb9cada2015-12-08 15:45:58 -07006597
6598 if (tag2)
6599 {
6600 /* inner vlan tag */
6601 match[19] = tag2_val[1];
6602 match[18] = tag2_val[0];
6603 if (cos2)
6604 match [18] |= (cos2_val & 0x7) << 5;
6605 if (proto)
6606 {
6607 match[21] = proto_val & 0xff;
6608 match[20] = proto_val >> 8;
6609 }
6610 if (tag1)
6611 {
6612 match [15] = tag1_val[1];
6613 match [14] = tag1_val[0];
6614 }
6615 if (cos1)
6616 match [14] |= (cos1_val & 0x7) << 5;
6617 *matchp = match;
6618 return 1;
6619 }
6620 if (tag1)
6621 {
6622 match [15] = tag1_val[1];
6623 match [14] = tag1_val[0];
6624 if (proto)
6625 {
6626 match[17] = proto_val & 0xff;
6627 match[16] = proto_val >> 8;
6628 }
6629 if (cos1)
6630 match [14] |= (cos1_val & 0x7) << 5;
6631
6632 *matchp = match;
6633 return 1;
6634 }
6635 if (cos2)
6636 match [18] |= (cos2_val & 0x7) << 5;
6637 if (cos1)
6638 match [14] |= (cos1_val & 0x7) << 5;
6639 if (proto)
6640 {
6641 match[13] = proto_val & 0xff;
6642 match[12] = proto_val >> 8;
6643 }
6644
6645 *matchp = match;
6646 return 1;
6647}
6648
6649
6650uword unformat_classify_match (unformat_input_t * input, va_list * args)
6651{
6652 u8 ** matchp = va_arg (*args, u8 **);
6653 u32 skip_n_vectors = va_arg (*args, u32);
6654 u32 match_n_vectors = va_arg (*args, u32);
6655
6656 u8 * match = 0;
6657 u8 * l2 = 0;
6658 u8 * l3 = 0;
6659
6660 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
6661 if (unformat (input, "hex %U", unformat_hex_string, &match))
6662 ;
6663 else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
6664 ;
6665 else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
6666 ;
6667 else
6668 break;
6669 }
6670
6671 if (match || l2 || l3)
6672 {
6673 if (l2 || l3)
6674 {
6675 /* "Win a free Ethernet header in every packet" */
6676 if (l2 == 0)
6677 vec_validate_aligned (l2, 13, sizeof(u32x4));
6678 match = l2;
6679 vec_append_aligned (match, l3, sizeof(u32x4));
6680 vec_free (l3);
6681 }
6682
6683 /* Make sure the vector is big enough even if key is all 0's */
6684 vec_validate_aligned
6685 (match, ((match_n_vectors + skip_n_vectors) * sizeof(u32x4)) - 1,
6686 sizeof(u32x4));
6687
6688 /* Set size, include skipped vectors*/
6689 _vec_len (match) = (match_n_vectors+skip_n_vectors) * sizeof(u32x4);
6690
6691 *matchp = match;
6692
6693 return 1;
6694 }
6695
6696 return 0;
6697}
6698
6699static int api_classify_add_del_session (vat_main_t * vam)
6700{
6701 unformat_input_t * i = vam->input;
6702 vl_api_classify_add_del_session_t *mp;
6703 int is_add = 1;
6704 u32 table_index = ~0;
6705 u32 hit_next_index = ~0;
6706 u32 opaque_index = ~0;
6707 u8 * match = 0;
6708 i32 advance = 0;
6709 f64 timeout;
6710 u32 skip_n_vectors = 0;
6711 u32 match_n_vectors = 0;
6712
6713 /*
6714 * Warning: you have to supply skip_n and match_n
6715 * because the API client cant simply look at the classify
6716 * table object.
6717 */
6718
6719 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6720 if (unformat (i, "del"))
6721 is_add = 0;
6722 else if (unformat (i, "hit-next %U", unformat_ip_next_index,
6723 &hit_next_index))
6724 ;
6725 else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
6726 &hit_next_index))
6727 ;
6728 else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
6729 &hit_next_index))
6730 ;
6731 else if (unformat (i, "opaque-index %d", &opaque_index))
6732 ;
6733 else if (unformat (i, "skip_n %d", &skip_n_vectors))
6734 ;
6735 else if (unformat (i, "match_n %d", &match_n_vectors))
6736 ;
6737 else if (unformat (i, "match %U", unformat_classify_match,
6738 &match, skip_n_vectors, match_n_vectors))
6739 ;
6740 else if (unformat (i, "advance %d", &advance))
6741 ;
6742 else if (unformat (i, "table-index %d", &table_index))
6743 ;
6744 else
6745 break;
6746 }
6747
6748 if (table_index == ~0) {
6749 errmsg ("Table index required\n");
6750 return -99;
6751 }
6752
6753 if (is_add && match == 0) {
6754 errmsg ("Match value required\n");
6755 return -99;
6756 }
6757
6758 M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session,
6759 vec_len(match));
6760
6761 mp->is_add = is_add;
6762 mp->table_index = ntohl(table_index);
6763 mp->hit_next_index = ntohl(hit_next_index);
6764 mp->opaque_index = ntohl(opaque_index);
6765 mp->advance = ntohl(advance);
Damjan Marionf1213b82016-03-13 02:22:06 +01006766 clib_memcpy (mp->match, match, vec_len(match));
Ed Warnickecb9cada2015-12-08 15:45:58 -07006767 vec_free(match);
6768
6769 S; W;
6770 /* NOTREACHED */
6771}
6772
6773static int api_classify_set_interface_ip_table (vat_main_t * vam)
6774{
6775 unformat_input_t * i = vam->input;
6776 vl_api_classify_set_interface_ip_table_t *mp;
6777 f64 timeout;
6778 u32 sw_if_index;
6779 int sw_if_index_set;
6780 u32 table_index = ~0;
6781 u8 is_ipv6 = 0;
6782
6783 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6784 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6785 sw_if_index_set = 1;
6786 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6787 sw_if_index_set = 1;
6788 else if (unformat (i, "table %d", &table_index))
6789 ;
6790 else {
6791 clib_warning ("parse error '%U'", format_unformat_error, i);
6792 return -99;
6793 }
6794 }
6795
6796 if (sw_if_index_set == 0) {
6797 errmsg ("missing interface name or sw_if_index\n");
6798 return -99;
6799 }
6800
6801
6802 M(CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
6803
6804 mp->sw_if_index = ntohl(sw_if_index);
6805 mp->table_index = ntohl(table_index);
6806 mp->is_ipv6 = is_ipv6;
6807
6808 S; W;
6809 /* NOTREACHED */
6810 return 0;
6811}
6812
6813static int api_classify_set_interface_l2_tables (vat_main_t * vam)
6814{
6815 unformat_input_t * i = vam->input;
6816 vl_api_classify_set_interface_l2_tables_t *mp;
6817 f64 timeout;
6818 u32 sw_if_index;
6819 int sw_if_index_set;
6820 u32 ip4_table_index = ~0;
6821 u32 ip6_table_index = ~0;
6822 u32 other_table_index = ~0;
6823
6824 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6825 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6826 sw_if_index_set = 1;
6827 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6828 sw_if_index_set = 1;
6829 else if (unformat (i, "ip4-table %d", &ip4_table_index))
6830 ;
6831 else if (unformat (i, "ip6-table %d", &ip6_table_index))
6832 ;
6833 else if (unformat (i, "other-table %d", &other_table_index))
6834 ;
6835 else {
6836 clib_warning ("parse error '%U'", format_unformat_error, i);
6837 return -99;
6838 }
6839 }
6840
6841 if (sw_if_index_set == 0) {
6842 errmsg ("missing interface name or sw_if_index\n");
6843 return -99;
6844 }
6845
6846
6847 M(CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
6848
6849 mp->sw_if_index = ntohl(sw_if_index);
6850 mp->ip4_table_index = ntohl(ip4_table_index);
6851 mp->ip6_table_index = ntohl(ip6_table_index);
6852 mp->other_table_index = ntohl(other_table_index);
6853
6854
6855 S; W;
6856 /* NOTREACHED */
6857 return 0;
6858}
6859
6860static int api_get_node_index (vat_main_t * vam)
6861{
6862 unformat_input_t * i = vam->input;
6863 vl_api_get_node_index_t * mp;
6864 f64 timeout;
6865 u8 * name = 0;
6866
6867 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6868 if (unformat (i, "node %s", &name))
6869 ;
6870 else
6871 break;
6872 }
6873 if (name == 0) {
6874 errmsg ("node name required\n");
6875 return -99;
6876 }
6877 if (vec_len (name) >= ARRAY_LEN(mp->node_name)) {
6878 errmsg ("node name too long, max %d\n", ARRAY_LEN(mp->node_name));
6879 return -99;
6880 }
6881
6882 M(GET_NODE_INDEX, get_node_index);
Damjan Marionf1213b82016-03-13 02:22:06 +01006883 clib_memcpy (mp->node_name, name, vec_len(name));
Ed Warnickecb9cada2015-12-08 15:45:58 -07006884 vec_free(name);
6885
6886 S; W;
6887 /* NOTREACHED */
6888 return 0;
6889}
6890
6891static int api_add_node_next (vat_main_t * vam)
6892{
6893 unformat_input_t * i = vam->input;
6894 vl_api_add_node_next_t * mp;
6895 f64 timeout;
6896 u8 * name = 0;
6897 u8 * next = 0;
6898
6899 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6900 if (unformat (i, "node %s", &name))
6901 ;
6902 else if (unformat (i, "next %s", &next))
6903 ;
6904 else
6905 break;
6906 }
6907 if (name == 0) {
6908 errmsg ("node name required\n");
6909 return -99;
6910 }
6911 if (vec_len (name) >= ARRAY_LEN(mp->node_name)) {
6912 errmsg ("node name too long, max %d\n", ARRAY_LEN(mp->node_name));
6913 return -99;
6914 }
6915 if (next == 0) {
6916 errmsg ("next node required\n");
6917 return -99;
6918 }
6919 if (vec_len (next) >= ARRAY_LEN(mp->next_name)) {
6920 errmsg ("next name too long, max %d\n", ARRAY_LEN(mp->next_name));
6921 return -99;
6922 }
6923
6924 M(ADD_NODE_NEXT, add_node_next);
Damjan Marionf1213b82016-03-13 02:22:06 +01006925 clib_memcpy (mp->node_name, name, vec_len(name));
6926 clib_memcpy (mp->next_name, next, vec_len(next));
Ed Warnickecb9cada2015-12-08 15:45:58 -07006927 vec_free(name);
6928 vec_free(next);
6929
6930 S; W;
6931 /* NOTREACHED */
6932 return 0;
6933}
6934
6935static int api_l2tpv3_create_tunnel (vat_main_t * vam)
6936{
6937 unformat_input_t * i = vam->input;
6938 ip6_address_t client_address, our_address;
6939 int client_address_set = 0;
6940 int our_address_set = 0;
6941 u32 local_session_id = 0;
6942 u32 remote_session_id = 0;
6943 u64 local_cookie = 0;
6944 u64 remote_cookie = 0;
6945 u8 l2_sublayer_present = 0;
6946 vl_api_l2tpv3_create_tunnel_t * mp;
6947 f64 timeout;
6948
6949 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6950 if (unformat (i, "client_address %U", unformat_ip6_address,
6951 &client_address))
6952 client_address_set = 1;
6953 else if (unformat (i, "our_address %U", unformat_ip6_address,
6954 &our_address))
6955 our_address_set = 1;
6956 else if (unformat (i, "local_session_id %d", &local_session_id))
6957 ;
6958 else if (unformat (i, "remote_session_id %d", &remote_session_id))
6959 ;
6960 else if (unformat (i, "local_cookie %lld", &local_cookie))
6961 ;
6962 else if (unformat (i, "remote_cookie %lld", &remote_cookie))
6963 ;
6964 else if (unformat (i, "l2-sublayer-present"))
6965 l2_sublayer_present = 1;
6966 else
6967 break;
6968 }
6969
6970 if (client_address_set == 0) {
6971 errmsg ("client_address required\n");
6972 return -99;
6973 }
6974
6975 if (our_address_set == 0) {
6976 errmsg ("our_address required\n");
6977 return -99;
6978 }
6979
6980 M(L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
6981
Damjan Marionf1213b82016-03-13 02:22:06 +01006982 clib_memcpy (mp->client_address, client_address.as_u8,
Ed Warnickecb9cada2015-12-08 15:45:58 -07006983 sizeof (mp->client_address));
6984
Damjan Marionf1213b82016-03-13 02:22:06 +01006985 clib_memcpy (mp->our_address, our_address.as_u8,
Ed Warnickecb9cada2015-12-08 15:45:58 -07006986 sizeof (mp->our_address));
6987
6988 mp->local_session_id = ntohl (local_session_id);
6989 mp->remote_session_id = ntohl (remote_session_id);
6990 mp->local_cookie = clib_host_to_net_u64 (local_cookie);
6991 mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
6992 mp->l2_sublayer_present = l2_sublayer_present;
6993 mp->is_ipv6 = 1;
6994
6995 S; W;
6996 /* NOTREACHED */
6997 return 0;
6998}
6999
7000static int api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
7001{
7002 unformat_input_t * i = vam->input;
7003 u32 sw_if_index;
7004 u8 sw_if_index_set = 0;
7005 u64 new_local_cookie = 0;
7006 u64 new_remote_cookie = 0;
7007 vl_api_l2tpv3_set_tunnel_cookies_t *mp;
7008 f64 timeout;
7009
7010 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7011 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7012 sw_if_index_set = 1;
7013 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7014 sw_if_index_set = 1;
7015 else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
7016 ;
7017 else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
7018 ;
7019 else
7020 break;
7021 }
7022
7023 if (sw_if_index_set == 0) {
7024 errmsg ("missing interface name or sw_if_index\n");
7025 return -99;
7026 }
7027
7028 M(L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
7029
7030 mp->sw_if_index = ntohl(sw_if_index);
7031 mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
7032 mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
7033
7034 S; W;
7035 /* NOTREACHED */
7036 return 0;
7037}
7038
7039static int api_l2tpv3_interface_enable_disable (vat_main_t * vam)
7040{
7041 unformat_input_t * i = vam->input;
7042 vl_api_l2tpv3_interface_enable_disable_t *mp;
7043 f64 timeout;
7044 u32 sw_if_index;
7045 u8 sw_if_index_set = 0;
7046 u8 enable_disable = 1;
7047
7048 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7049 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7050 sw_if_index_set = 1;
7051 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7052 sw_if_index_set = 1;
7053 else if (unformat (i, "enable"))
7054 enable_disable = 1;
7055 else if (unformat (i, "disable"))
7056 enable_disable = 0;
7057 else
7058 break;
7059 }
7060
7061 if (sw_if_index_set == 0) {
7062 errmsg ("missing interface name or sw_if_index\n");
7063 return -99;
7064 }
7065
7066 M(L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
7067
7068 mp->sw_if_index = ntohl(sw_if_index);
7069 mp->enable_disable = enable_disable;
7070
7071 S; W;
7072 /* NOTREACHED */
7073 return 0;
7074}
7075
7076static int api_l2tpv3_set_lookup_key (vat_main_t * vam)
7077{
7078 unformat_input_t * i = vam->input;
7079 vl_api_l2tpv3_set_lookup_key_t * mp;
7080 f64 timeout;
7081 u8 key = ~0;
7082
7083 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7084 if (unformat (i, "lookup_v6_src"))
7085 key = L2T_LOOKUP_SRC_ADDRESS;
7086 else if (unformat (i, "lookup_v6_dst"))
7087 key = L2T_LOOKUP_DST_ADDRESS;
7088 else if (unformat (i, "lookup_session_id"))
7089 key = L2T_LOOKUP_SESSION_ID;
7090 else
7091 break;
7092 }
7093
Damjan Marionfa693552016-04-26 19:30:36 +02007094 if (key == (u8) ~0) {
Ed Warnickecb9cada2015-12-08 15:45:58 -07007095 errmsg ("l2tp session lookup key unset\n");
7096 return -99;
7097 }
7098
7099 M(L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
7100
7101 mp->key = key;
7102
7103 S; W;
7104 /* NOTREACHED */
7105 return 0;
7106}
7107
7108static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
7109(vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
7110{
7111 vat_main_t * vam = &vat_main;
7112
7113 fformat(vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
7114 format_ip6_address, mp->our_address,
7115 format_ip6_address, mp->client_address,
7116 clib_net_to_host_u32(mp->sw_if_index));
7117
7118 fformat (vam->ofp, " local cookies %016llx %016llx remote cookie %016llx\n",
7119 clib_net_to_host_u64 (mp->local_cookie[0]),
7120 clib_net_to_host_u64 (mp->local_cookie[1]),
7121 clib_net_to_host_u64 (mp->remote_cookie));
7122
7123 fformat (vam->ofp, " local session-id %d remote session-id %d\n",
7124 clib_net_to_host_u32 (mp->local_session_id),
7125 clib_net_to_host_u32 (mp->remote_session_id));
7126
7127 fformat (vam->ofp, " l2 specific sublayer %s\n\n",
7128 mp->l2_sublayer_present ? "preset" : "absent");
7129
7130}
7131
7132static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
7133(vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
7134{
7135 vat_main_t * vam = &vat_main;
7136 vat_json_node_t *node = NULL;
7137 struct in6_addr addr;
7138
7139 if (VAT_JSON_ARRAY != vam->json_tree.type) {
7140 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
7141 vat_json_init_array(&vam->json_tree);
7142 }
7143 node = vat_json_array_add(&vam->json_tree);
7144
7145 vat_json_init_object(node);
7146
Damjan Marionf1213b82016-03-13 02:22:06 +01007147 clib_memcpy(&addr, mp->our_address, sizeof(addr));
Ed Warnickecb9cada2015-12-08 15:45:58 -07007148 vat_json_object_add_ip6(node, "our_address", addr);
Damjan Marionf1213b82016-03-13 02:22:06 +01007149 clib_memcpy(&addr, mp->client_address, sizeof(addr));
Ed Warnickecb9cada2015-12-08 15:45:58 -07007150 vat_json_object_add_ip6(node, "client_address", addr);
7151
7152 vat_json_node_t * lc = vat_json_object_add(node, "local_cookie");
7153 vat_json_init_array(lc);
7154 vat_json_array_add_uint(lc, clib_net_to_host_u64(mp->local_cookie[0]));
7155 vat_json_array_add_uint(lc, clib_net_to_host_u64(mp->local_cookie[1]));
7156 vat_json_object_add_uint(node, "remote_cookie", clib_net_to_host_u64(mp->remote_cookie));
7157
7158 printf("local id: %u", clib_net_to_host_u32(mp->local_session_id));
7159 vat_json_object_add_uint(node, "local_session_id", clib_net_to_host_u32(mp->local_session_id));
7160 vat_json_object_add_uint(node, "remote_session_id", clib_net_to_host_u32(mp->remote_session_id));
7161 vat_json_object_add_string_copy(node, "l2_sublayer", mp->l2_sublayer_present ?
7162 (u8*)"present" : (u8*)"absent");
7163}
7164
7165static int api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
7166{
7167 vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
7168 f64 timeout;
7169
7170 /* Get list of l2tpv3-tunnel interfaces */
7171 M(SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
7172 S;
7173
7174 /* Use a control ping for synchronization */
7175 {
7176 vl_api_control_ping_t * mp;
7177 M(CONTROL_PING, control_ping);
7178 S;
7179 }
7180 W;
7181}
7182
7183
7184static void vl_api_sw_interface_tap_details_t_handler
7185(vl_api_sw_interface_tap_details_t * mp)
7186{
7187 vat_main_t * vam = &vat_main;
7188
7189 fformat(vam->ofp, "%-16s %d\n",
7190 mp->dev_name,
7191 clib_net_to_host_u32(mp->sw_if_index));
7192}
7193
7194static void vl_api_sw_interface_tap_details_t_handler_json
7195(vl_api_sw_interface_tap_details_t * mp)
7196{
7197 vat_main_t * vam = &vat_main;
7198 vat_json_node_t *node = NULL;
7199
7200 if (VAT_JSON_ARRAY != vam->json_tree.type) {
7201 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
7202 vat_json_init_array(&vam->json_tree);
7203 }
7204 node = vat_json_array_add(&vam->json_tree);
7205
7206 vat_json_init_object(node);
7207 vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
7208 vat_json_object_add_string_copy(node, "dev_name", mp->dev_name);
7209}
7210
7211static int api_sw_interface_tap_dump (vat_main_t * vam)
7212{
7213 vl_api_sw_interface_tap_dump_t *mp;
7214 f64 timeout;
7215
7216 fformat(vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
7217 /* Get list of tap interfaces */
7218 M(SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
7219 S;
7220
7221 /* Use a control ping for synchronization */
7222 {
7223 vl_api_control_ping_t * mp;
7224 M(CONTROL_PING, control_ping);
7225 S;
7226 }
7227 W;
7228}
7229
7230static uword unformat_vxlan_decap_next
7231(unformat_input_t * input, va_list * args)
7232{
7233 u32 * result = va_arg (*args, u32 *);
7234 u32 tmp;
7235
7236 if (unformat (input, "drop"))
7237 *result = VXLAN_INPUT_NEXT_DROP;
7238 else if (unformat (input, "ip4"))
7239 *result = VXLAN_INPUT_NEXT_IP4_INPUT;
7240 else if (unformat (input, "ip6"))
7241 *result = VXLAN_INPUT_NEXT_IP6_INPUT;
7242 else if (unformat (input, "l2"))
7243 *result = VXLAN_INPUT_NEXT_L2_INPUT;
7244 else if (unformat (input, "%d", &tmp))
7245 *result = tmp;
7246 else
7247 return 0;
7248 return 1;
7249}
7250
7251static int api_vxlan_add_del_tunnel (vat_main_t * vam)
7252{
7253 unformat_input_t * line_input = vam->input;
7254 vl_api_vxlan_add_del_tunnel_t *mp;
7255 f64 timeout;
Chris Luke99cb3352016-04-26 10:49:53 -04007256 ip4_address_t src4, dst4;
7257 ip6_address_t src6, dst6;
Ed Warnickecb9cada2015-12-08 15:45:58 -07007258 u8 is_add = 1;
Chris Luke99cb3352016-04-26 10:49:53 -04007259 u8 ipv4_set = 0, ipv6_set = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -07007260 u8 src_set = 0;
7261 u8 dst_set = 0;
7262 u32 encap_vrf_id = 0;
7263 u32 decap_next_index = ~0;
7264 u32 vni = 0;
7265
7266 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
7267 if (unformat (line_input, "del"))
7268 is_add = 0;
7269 else if (unformat (line_input, "src %U",
Chris Luke99cb3352016-04-26 10:49:53 -04007270 unformat_ip4_address, &src4))
7271 {
7272 ipv4_set = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -07007273 src_set = 1;
Chris Luke99cb3352016-04-26 10:49:53 -04007274 }
Ed Warnickecb9cada2015-12-08 15:45:58 -07007275 else if (unformat (line_input, "dst %U",
Chris Luke99cb3352016-04-26 10:49:53 -04007276 unformat_ip4_address, &dst4))
7277 {
7278 ipv4_set = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -07007279 dst_set = 1;
Chris Luke99cb3352016-04-26 10:49:53 -04007280 }
7281 else if (unformat (line_input, "src %U",
7282 unformat_ip6_address, &src6))
7283 {
7284 ipv6_set = 1;
7285 src_set = 1;
7286 }
7287 else if (unformat (line_input, "dst %U",
7288 unformat_ip6_address, &dst6))
7289 {
7290 ipv6_set = 1;
7291 dst_set = 1;
7292 }
Ed Warnickecb9cada2015-12-08 15:45:58 -07007293 else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
7294 ;
7295 else if (unformat (line_input, "decap-next %U",
7296 unformat_vxlan_decap_next, &decap_next_index))
7297 ;
7298 else if (unformat (line_input, "vni %d", &vni))
7299 ;
7300 else {
7301 errmsg ("parse error '%U'\n", format_unformat_error, line_input);
7302 return -99;
7303 }
7304 }
7305
7306 if (src_set == 0) {
7307 errmsg ("tunnel src address not specified\n");
7308 return -99;
7309 }
7310 if (dst_set == 0) {
7311 errmsg ("tunnel dst address not specified\n");
7312 return -99;
7313 }
7314
Chris Luke99cb3352016-04-26 10:49:53 -04007315 if (ipv4_set && ipv6_set) {
7316 errmsg ("both IPv4 and IPv6 addresses specified");
7317 return -99;
7318 }
7319
Ed Warnickecb9cada2015-12-08 15:45:58 -07007320 if ((vni == 0) || (vni>>24)) {
7321 errmsg ("vni not specified or out of range\n");
7322 return -99;
7323 }
7324
7325 M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
Chris Luke99cb3352016-04-26 10:49:53 -04007326
7327 if (ipv6_set) {
7328 clib_memcpy(&mp->dst_address, &src6, sizeof(src6));
7329 clib_memcpy(&mp->dst_address, &src6, sizeof(dst6));
7330 } else {
7331 clib_memcpy(&mp->src_address, &src4, sizeof(src4));
7332 clib_memcpy(&mp->dst_address, &dst4, sizeof(dst4));
7333 }
Ed Warnickecb9cada2015-12-08 15:45:58 -07007334 mp->encap_vrf_id = ntohl(encap_vrf_id);
7335 mp->decap_next_index = ntohl(decap_next_index);
7336 mp->vni = ntohl(vni);
7337 mp->is_add = is_add;
Chris Luke99cb3352016-04-26 10:49:53 -04007338 mp->is_ipv6 = ipv6_set;
Ed Warnickecb9cada2015-12-08 15:45:58 -07007339
7340 S; W;
7341 /* NOTREACHED */
7342 return 0;
7343}
7344
Dave Wallace60231f32015-12-17 21:04:30 -05007345static void vl_api_vxlan_tunnel_details_t_handler
7346(vl_api_vxlan_tunnel_details_t * mp)
7347{
7348 vat_main_t * vam = &vat_main;
7349
Chris Luke99cb3352016-04-26 10:49:53 -04007350 fformat(vam->ofp, "%11d%24U%24U%14d%18d%13d\n",
Dave Wallace60231f32015-12-17 21:04:30 -05007351 ntohl(mp->sw_if_index),
Chris Luke99cb3352016-04-26 10:49:53 -04007352 format_ip46_address, &(mp->src_address[0]),
7353 format_ip46_address, &(mp->dst_address[0]),
Dave Wallace60231f32015-12-17 21:04:30 -05007354 ntohl(mp->encap_vrf_id),
7355 ntohl(mp->decap_next_index),
7356 ntohl(mp->vni));
7357}
7358
7359static void vl_api_vxlan_tunnel_details_t_handler_json
7360(vl_api_vxlan_tunnel_details_t * mp)
7361{
7362 vat_main_t * vam = &vat_main;
7363 vat_json_node_t *node = NULL;
7364 struct in_addr ip4;
Chris Luke99cb3352016-04-26 10:49:53 -04007365 struct in6_addr ip6;
Dave Wallace60231f32015-12-17 21:04:30 -05007366
7367 if (VAT_JSON_ARRAY != vam->json_tree.type) {
7368 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
7369 vat_json_init_array(&vam->json_tree);
7370 }
7371 node = vat_json_array_add(&vam->json_tree);
7372
7373 vat_json_init_object(node);
7374 vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
Chris Luke99cb3352016-04-26 10:49:53 -04007375 if (mp->is_ipv6) {
7376 clib_memcpy(&ip6, &(mp->src_address[0]), sizeof(ip6));
7377 vat_json_object_add_ip6(node, "src_address", ip6);
7378 clib_memcpy(&ip6, &(mp->dst_address[0]), sizeof(ip6));
7379 vat_json_object_add_ip6(node, "dst_address", ip6);
7380 } else {
7381 clib_memcpy(&ip4, &(mp->src_address[0]), sizeof(ip4));
7382 vat_json_object_add_ip4(node, "src_address", ip4);
7383 clib_memcpy(&ip4, &(mp->dst_address[0]), sizeof(ip4));
7384 vat_json_object_add_ip4(node, "dst_address", ip4);
7385 }
Dave Wallace60231f32015-12-17 21:04:30 -05007386 vat_json_object_add_uint(node, "encap_vrf_id", ntohl(mp->encap_vrf_id));
7387 vat_json_object_add_uint(node, "decap_next_index", ntohl(mp->decap_next_index));
7388 vat_json_object_add_uint(node, "vni", ntohl(mp->vni));
Chris Luke99cb3352016-04-26 10:49:53 -04007389 vat_json_object_add_uint(node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
Dave Wallace60231f32015-12-17 21:04:30 -05007390}
7391
7392static int api_vxlan_tunnel_dump (vat_main_t * vam)
7393{
7394 unformat_input_t * i = vam->input;
7395 vl_api_vxlan_tunnel_dump_t *mp;
7396 f64 timeout;
7397 u32 sw_if_index;
7398 u8 sw_if_index_set = 0;
7399
7400 /* Parse args required to build the message */
7401 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7402 if (unformat (i, "sw_if_index %d", &sw_if_index))
7403 sw_if_index_set = 1;
7404 else
7405 break;
7406 }
7407
7408 if (sw_if_index_set == 0) {
7409 sw_if_index = ~0;
7410 }
7411
7412 if (!vam->json_output) {
Chris Luke99cb3352016-04-26 10:49:53 -04007413 fformat(vam->ofp, "%11s%24s%24s%14s%18s%13s\n",
Dave Wallace60231f32015-12-17 21:04:30 -05007414 "sw_if_index", "src_address", "dst_address",
7415 "encap_vrf_id", "decap_next_index", "vni");
7416 }
7417
Chris Luke99cb3352016-04-26 10:49:53 -04007418 /* Get list of vxlan-tunnel interfaces */
Dave Wallace60231f32015-12-17 21:04:30 -05007419 M(VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
7420
7421 mp->sw_if_index = htonl(sw_if_index);
7422
7423 S;
7424
7425 /* Use a control ping for synchronization */
7426 {
7427 vl_api_control_ping_t * mp;
7428 M(CONTROL_PING, control_ping);
7429 S;
7430 }
7431 W;
7432}
7433
Chris Luke27fe48f2016-04-28 13:44:38 -04007434static int api_gre_add_del_tunnel (vat_main_t * vam)
7435{
7436 unformat_input_t * line_input = vam->input;
7437 vl_api_gre_add_del_tunnel_t *mp;
7438 f64 timeout;
7439 ip4_address_t src4, dst4;
7440 u8 is_add = 1;
7441 u8 src_set = 0;
7442 u8 dst_set = 0;
7443 u32 outer_fib_id = 0;
7444
7445 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
7446 if (unformat (line_input, "del"))
7447 is_add = 0;
7448 else if (unformat (line_input, "src %U",
7449 unformat_ip4_address, &src4))
7450 src_set = 1;
7451 else if (unformat (line_input, "dst %U",
7452 unformat_ip4_address, &dst4))
7453 dst_set = 1;
7454 else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
7455 ;
7456 else {
7457 errmsg ("parse error '%U'\n", format_unformat_error, line_input);
7458 return -99;
7459 }
7460 }
7461
7462 if (src_set == 0) {
7463 errmsg ("tunnel src address not specified\n");
7464 return -99;
7465 }
7466 if (dst_set == 0) {
7467 errmsg ("tunnel dst address not specified\n");
7468 return -99;
7469 }
7470
7471
7472 M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
7473
7474 clib_memcpy(&mp->src_address, &src4, sizeof(src4));
7475 clib_memcpy(&mp->dst_address, &dst4, sizeof(dst4));
7476 mp->outer_table_id = ntohl(outer_fib_id);
7477 mp->is_add = is_add;
7478
7479 S; W;
7480 /* NOTREACHED */
7481 return 0;
7482}
7483
7484static void vl_api_gre_tunnel_details_t_handler
7485(vl_api_gre_tunnel_details_t * mp)
7486{
7487 vat_main_t * vam = &vat_main;
7488
7489 fformat(vam->ofp, "%11d%15U%15U%14d\n",
7490 ntohl(mp->sw_if_index),
7491 format_ip4_address, &mp->src_address,
7492 format_ip4_address, &mp->dst_address,
7493 ntohl(mp->outer_table_id));
7494}
7495
7496static void vl_api_gre_tunnel_details_t_handler_json
7497(vl_api_gre_tunnel_details_t * mp)
7498{
7499 vat_main_t * vam = &vat_main;
7500 vat_json_node_t *node = NULL;
7501 struct in_addr ip4;
7502
7503 if (VAT_JSON_ARRAY != vam->json_tree.type) {
7504 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
7505 vat_json_init_array(&vam->json_tree);
7506 }
7507 node = vat_json_array_add(&vam->json_tree);
7508
7509 vat_json_init_object(node);
7510 vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
7511 clib_memcpy(&ip4, &mp->src_address, sizeof(ip4));
7512 vat_json_object_add_ip4(node, "src_address", ip4);
7513 clib_memcpy(&ip4, &mp->dst_address, sizeof(ip4));
7514 vat_json_object_add_ip4(node, "dst_address", ip4);
7515 vat_json_object_add_uint(node, "outer_fib_id", ntohl(mp->outer_table_id));
7516}
7517
7518static int api_gre_tunnel_dump (vat_main_t * vam)
7519{
7520 unformat_input_t * i = vam->input;
7521 vl_api_gre_tunnel_dump_t *mp;
7522 f64 timeout;
7523 u32 sw_if_index;
7524 u8 sw_if_index_set = 0;
7525
7526 /* Parse args required to build the message */
7527 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7528 if (unformat (i, "sw_if_index %d", &sw_if_index))
7529 sw_if_index_set = 1;
7530 else
7531 break;
7532 }
7533
7534 if (sw_if_index_set == 0) {
7535 sw_if_index = ~0;
7536 }
7537
7538 if (!vam->json_output) {
7539 fformat(vam->ofp, "%11s%15s%15s%14s\n",
7540 "sw_if_index", "src_address", "dst_address",
7541 "outer_fib_id");
7542 }
7543
7544 /* Get list of gre-tunnel interfaces */
7545 M(GRE_TUNNEL_DUMP, gre_tunnel_dump);
7546
7547 mp->sw_if_index = htonl(sw_if_index);
7548
7549 S;
7550
7551 /* Use a control ping for synchronization */
7552 {
7553 vl_api_control_ping_t * mp;
7554 M(CONTROL_PING, control_ping);
7555 S;
7556 }
7557 W;
7558}
7559
Ed Warnickecb9cada2015-12-08 15:45:58 -07007560static int api_l2_fib_clear_table (vat_main_t * vam)
7561{
7562// unformat_input_t * i = vam->input;
7563 vl_api_l2_fib_clear_table_t *mp;
7564 f64 timeout;
7565
7566 M(L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
7567
7568 S; W;
7569 /* NOTREACHED */
7570 return 0;
7571}
7572
7573static int api_l2_interface_efp_filter (vat_main_t * vam)
7574{
7575 unformat_input_t * i = vam->input;
7576 vl_api_l2_interface_efp_filter_t *mp;
7577 f64 timeout;
7578 u32 sw_if_index;
7579 u8 enable = 1;
7580 u8 sw_if_index_set = 0;
7581
7582 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7583 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7584 sw_if_index_set = 1;
7585 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7586 sw_if_index_set = 1;
7587 else if (unformat (i, "enable"))
7588 enable = 1;
7589 else if (unformat (i, "disable"))
7590 enable = 0;
7591 else {
7592 clib_warning ("parse error '%U'", format_unformat_error, i);
7593 return -99;
7594 }
7595 }
7596
7597 if (sw_if_index_set == 0) {
7598 errmsg ("missing sw_if_index\n");
7599 return -99;
7600 }
7601
7602 M(L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
7603
7604 mp->sw_if_index = ntohl(sw_if_index);
7605 mp->enable_disable = enable;
7606
7607 S; W;
7608 /* NOTREACHED */
7609 return 0;
7610}
7611
7612#define foreach_vtr_op \
7613_("disable", L2_VTR_DISABLED) \
7614_("push-1", L2_VTR_PUSH_1) \
7615_("push-2", L2_VTR_PUSH_2) \
7616_("pop-1", L2_VTR_POP_1) \
7617_("pop-2", L2_VTR_POP_2) \
7618_("translate-1-1", L2_VTR_TRANSLATE_1_1) \
7619_("translate-1-2", L2_VTR_TRANSLATE_1_2) \
7620_("translate-2-1", L2_VTR_TRANSLATE_2_1) \
7621_("translate-2-2", L2_VTR_TRANSLATE_2_2)
7622
7623static int api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
7624{
7625 unformat_input_t * i = vam->input;
7626 vl_api_l2_interface_vlan_tag_rewrite_t *mp;
7627 f64 timeout;
7628 u32 sw_if_index;
7629 u8 sw_if_index_set = 0;
7630 u8 vtr_op_set = 0;
7631 u32 vtr_op = 0;
7632 u32 push_dot1q = 1;
7633 u32 tag1 = ~0;
7634 u32 tag2 = ~0;
7635
7636 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7637 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7638 sw_if_index_set = 1;
7639 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7640 sw_if_index_set = 1;
7641 else if (unformat (i, "vtr_op %d", &vtr_op))
7642 vtr_op_set = 1;
7643#define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
7644 foreach_vtr_op
7645#undef _
7646
7647 else if (unformat (i, "push_dot1q %d", &push_dot1q))
7648 ;
7649 else if (unformat (i, "tag1 %d", &tag1))
7650 ;
7651 else if (unformat (i, "tag2 %d", &tag2))
7652 ;
7653 else {
7654 clib_warning ("parse error '%U'", format_unformat_error, i);
7655 return -99;
7656 }
7657 }
7658
7659 if ((sw_if_index_set == 0)||(vtr_op_set == 0)) {
7660 errmsg ("missing vtr operation or sw_if_index\n");
7661 return -99;
7662 }
7663
7664 M(L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
7665
7666 mp->sw_if_index = ntohl(sw_if_index);
7667 mp->vtr_op = ntohl(vtr_op);
7668 mp->push_dot1q = ntohl(push_dot1q);
7669 mp->tag1 = ntohl(tag1);
7670 mp->tag2 = ntohl(tag2);
7671
7672 S; W;
7673 /* NOTREACHED */
7674 return 0;
7675}
7676
7677static int api_create_vhost_user_if (vat_main_t * vam)
7678{
7679 unformat_input_t * i = vam->input;
7680 vl_api_create_vhost_user_if_t *mp;
7681 f64 timeout;
7682 u8 * file_name;
7683 u8 is_server = 0;
7684 u8 file_name_set = 0;
7685 u32 custom_dev_instance = ~0;
Pierre Pfisteref65cb02016-02-19 13:52:44 +00007686 u8 hwaddr[6];
7687 u8 use_custom_mac = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -07007688
7689 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7690 if (unformat (i, "socket %s", &file_name)) {
7691 file_name_set = 1;
7692 }
7693 else if (unformat (i, "renumber %"PRIu32, &custom_dev_instance))
7694 ;
Pierre Pfisteref65cb02016-02-19 13:52:44 +00007695 else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
7696 use_custom_mac = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -07007697 else if (unformat (i, "server"))
7698 is_server = 1;
7699 else
7700 break;
7701 }
7702
7703 if (file_name_set == 0) {
7704 errmsg ("missing socket file name\n");
7705 return -99;
7706 }
7707
7708 if (vec_len (file_name) > 255) {
7709 errmsg ("socket file name too long\n");
7710 return -99;
7711 }
7712 vec_add1 (file_name, 0);
7713
7714 M(CREATE_VHOST_USER_IF, create_vhost_user_if);
7715
7716 mp->is_server = is_server;
Damjan Marionf1213b82016-03-13 02:22:06 +01007717 clib_memcpy(mp->sock_filename, file_name, vec_len(file_name));
Ed Warnickecb9cada2015-12-08 15:45:58 -07007718 vec_free(file_name);
7719 if (custom_dev_instance != ~0) {
7720 mp->renumber = 1;
7721 mp->custom_dev_instance = ntohl(custom_dev_instance);
7722 }
Pierre Pfisteref65cb02016-02-19 13:52:44 +00007723 mp->use_custom_mac = use_custom_mac;
Damjan Marionf1213b82016-03-13 02:22:06 +01007724 clib_memcpy(mp->mac_address, hwaddr, 6);
Ed Warnickecb9cada2015-12-08 15:45:58 -07007725
7726 S; W;
7727 /* NOTREACHED */
7728 return 0;
7729}
7730
7731static int api_modify_vhost_user_if (vat_main_t * vam)
7732{
7733 unformat_input_t * i = vam->input;
7734 vl_api_modify_vhost_user_if_t *mp;
7735 f64 timeout;
7736 u8 * file_name;
7737 u8 is_server = 0;
7738 u8 file_name_set = 0;
7739 u32 custom_dev_instance = ~0;
7740 u8 sw_if_index_set = 0;
7741 u32 sw_if_index = (u32)~0;
7742
7743 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7744 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7745 sw_if_index_set = 1;
7746 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7747 sw_if_index_set = 1;
7748 else if (unformat (i, "socket %s", &file_name)) {
7749 file_name_set = 1;
7750 }
7751 else if (unformat (i, "renumber %"PRIu32, &custom_dev_instance))
7752 ;
7753 else if (unformat (i, "server"))
7754 is_server = 1;
7755 else
7756 break;
7757 }
7758
7759 if (sw_if_index_set == 0) {
7760 errmsg ("missing sw_if_index or interface name\n");
7761 return -99;
7762 }
7763
7764 if (file_name_set == 0) {
7765 errmsg ("missing socket file name\n");
7766 return -99;
7767 }
7768
7769 if (vec_len (file_name) > 255) {
7770 errmsg ("socket file name too long\n");
7771 return -99;
7772 }
7773 vec_add1 (file_name, 0);
7774
7775 M(MODIFY_VHOST_USER_IF, modify_vhost_user_if);
7776
7777 mp->sw_if_index = ntohl(sw_if_index);
7778 mp->is_server = is_server;
Damjan Marionf1213b82016-03-13 02:22:06 +01007779 clib_memcpy(mp->sock_filename, file_name, vec_len(file_name));
Ed Warnickecb9cada2015-12-08 15:45:58 -07007780 vec_free(file_name);
7781 if (custom_dev_instance != ~0) {
7782 mp->renumber = 1;
7783 mp->custom_dev_instance = ntohl(custom_dev_instance);
7784 }
7785
7786 S; W;
7787 /* NOTREACHED */
7788 return 0;
7789}
7790
7791static int api_delete_vhost_user_if (vat_main_t * vam)
7792{
7793 unformat_input_t * i = vam->input;
7794 vl_api_delete_vhost_user_if_t *mp;
7795 f64 timeout;
7796 u32 sw_if_index = ~0;
7797 u8 sw_if_index_set = 0;
7798
7799 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7800 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7801 sw_if_index_set = 1;
7802 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7803 sw_if_index_set = 1;
7804 else
7805 break;
7806 }
7807
7808 if (sw_if_index_set == 0) {
7809 errmsg ("missing sw_if_index or interface name\n");
7810 return -99;
7811 }
7812
7813
7814 M(DELETE_VHOST_USER_IF, delete_vhost_user_if);
7815
7816 mp->sw_if_index = ntohl(sw_if_index);
7817
7818 S; W;
7819 /* NOTREACHED */
7820 return 0;
7821}
7822
7823static void vl_api_sw_interface_vhost_user_details_t_handler
7824(vl_api_sw_interface_vhost_user_details_t * mp)
7825{
7826 vat_main_t * vam = &vat_main;
7827
7828 fformat(vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
7829 (char *)mp->interface_name,
7830 ntohl(mp->sw_if_index), ntohl(mp->virtio_net_hdr_sz),
7831 clib_net_to_host_u64(mp->features), mp->is_server,
7832 ntohl(mp->num_regions), (char *)mp->sock_filename);
7833 fformat(vam->ofp, " Status: '%s'\n", strerror(ntohl(mp->sock_errno)));
7834}
7835
7836static void vl_api_sw_interface_vhost_user_details_t_handler_json
7837(vl_api_sw_interface_vhost_user_details_t * mp)
7838{
7839 vat_main_t * vam = &vat_main;
7840 vat_json_node_t *node = NULL;
7841
7842 if (VAT_JSON_ARRAY != vam->json_tree.type) {
7843 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
7844 vat_json_init_array(&vam->json_tree);
7845 }
7846 node = vat_json_array_add(&vam->json_tree);
7847
7848 vat_json_init_object(node);
7849 vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
7850 vat_json_object_add_string_copy(node, "interface_name", mp->interface_name);
7851 vat_json_object_add_uint(node, "virtio_net_hdr_sz", ntohl(mp->virtio_net_hdr_sz));
7852 vat_json_object_add_uint(node, "features", clib_net_to_host_u64(mp->features));
7853 vat_json_object_add_uint(node, "is_server", mp->is_server);
7854 vat_json_object_add_string_copy(node, "sock_filename", mp->sock_filename);
7855 vat_json_object_add_uint(node, "num_regions", ntohl(mp->num_regions));
7856 vat_json_object_add_uint(node, "sock_errno", ntohl(mp->sock_errno));
7857}
7858
7859static int api_sw_interface_vhost_user_dump (vat_main_t * vam)
7860{
7861 vl_api_sw_interface_vhost_user_dump_t *mp;
7862 f64 timeout;
7863 fformat(vam->ofp, "Interface name idx hdr_sz features server regions filename\n");
7864
7865 /* Get list of vhost-user interfaces */
7866 M(SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
7867 S;
7868
7869 /* Use a control ping for synchronization */
7870 {
7871 vl_api_control_ping_t * mp;
7872 M(CONTROL_PING, control_ping);
7873 S;
7874 }
7875 W;
7876}
7877
7878static int api_show_version (vat_main_t * vam)
7879{
7880 vl_api_show_version_t *mp;
7881 f64 timeout;
7882
7883 M(SHOW_VERSION, show_version);
7884
7885 S; W;
7886 /* NOTREACHED */
7887 return 0;
7888}
7889
7890static uword unformat_nsh_gre_decap_next
7891(unformat_input_t * input, va_list * args)
7892{
7893 u32 * result = va_arg (*args, u32 *);
7894 u32 tmp;
7895
7896 if (unformat (input, "drop"))
7897 *result = NSH_INPUT_NEXT_DROP;
7898 else if (unformat (input, "ip4"))
7899 *result = NSH_INPUT_NEXT_IP4_INPUT;
7900 else if (unformat (input, "ip6"))
7901 *result = NSH_INPUT_NEXT_IP6_INPUT;
7902 else if (unformat (input, "ethernet"))
7903 *result = NSH_INPUT_NEXT_ETHERNET_INPUT;
7904 else if (unformat (input, "%d", &tmp))
7905 *result = tmp;
7906 else
7907 return 0;
7908 return 1;
7909}
7910
7911static int api_nsh_gre_add_del_tunnel (vat_main_t * vam)
7912{
7913 unformat_input_t * line_input = vam->input;
7914 vl_api_nsh_gre_add_del_tunnel_t *mp;
7915 f64 timeout;
7916 ip4_address_t src, dst;
7917 u8 is_add = 1;
7918 u8 src_set = 0;
7919 u8 dst_set = 0;
7920 u32 encap_vrf_id = 0;
7921 u32 decap_vrf_id = 0;
7922 u8 ver_o_c = 0;
7923 u8 md_type = 0;
7924 u8 next_protocol = 1; /* ip4 */
7925 u32 spi;
7926 u8 spi_set = 0;
7927 u32 si;
7928 u8 si_set = 0;
7929 u32 spi_si;
7930 u32 c1 = 0;
7931 u32 c2 = 0;
7932 u32 c3 = 0;
7933 u32 c4 = 0;
7934 u32 *tlvs = 0;
7935 u32 decap_next_index = NSH_INPUT_NEXT_IP4_INPUT;
7936 u32 tmp;
7937 int i;
7938
7939 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
7940 if (unformat (line_input, "del"))
7941 is_add = 0;
7942 else if (unformat (line_input, "src %U",
7943 unformat_ip4_address, &src))
7944 src_set = 1;
7945 else if (unformat (line_input, "dst %U",
7946 unformat_ip4_address, &dst))
7947 dst_set = 1;
7948 else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
7949 ;
7950 else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
7951 ;
7952 else if (unformat (line_input, "decap-next %U",
7953 unformat_nsh_gre_decap_next, &decap_next_index))
7954 ;
7955 else if (unformat (line_input, "version %d", &tmp))
7956 ver_o_c |= (tmp & 3) << 6;
7957 else if (unformat (line_input, "o-bit %d", &tmp))
7958 ver_o_c |= (tmp & 1) << 5;
7959 else if (unformat (line_input, "c-bit %d", &tmp))
7960 ver_o_c |= (tmp & 1) << 4;
7961 else if (unformat (line_input, "md-type %d", &tmp))
7962 md_type = tmp;
7963 else if (unformat(line_input, "next-ip4"))
7964 next_protocol = 1;
7965 else if (unformat(line_input, "next-ip6"))
7966 next_protocol = 2;
7967 else if (unformat(line_input, "next-ethernet"))
7968 next_protocol = 3;
7969 else if (unformat (line_input, "c1 %d", &c1))
7970 ;
7971 else if (unformat (line_input, "c2 %d", &c2))
7972 ;
7973 else if (unformat (line_input, "c3 %d", &c3))
7974 ;
7975 else if (unformat (line_input, "c4 %d", &c4))
7976 ;
7977 else if (unformat (line_input, "spi %d", &spi))
7978 spi_set = 1;
7979 else if (unformat (line_input, "si %d", &si))
7980 si_set = 1;
7981 else if (unformat (line_input, "tlv %x"))
7982 vec_add1 (tlvs, tmp);
7983 else {
7984 errmsg ("parse error '%U'\n", format_unformat_error, line_input);
7985 return -99;
7986 }
7987 }
7988
7989 if (src_set == 0) {
7990 errmsg ("tunnel src address not specified\n");
7991 return -99;
7992 }
7993 if (dst_set == 0) {
7994 errmsg ("tunnel dst address not specified\n");
7995 return -99;
7996 }
7997
7998 if (spi_set == 0) {
7999 errmsg ("spi not specified\n");
8000 return -99;
8001 }
8002
8003 if (si_set == 0) {
8004 errmsg ("si not specified\n");
8005 return -99;
8006 }
8007
8008 M2 (NSH_GRE_ADD_DEL_TUNNEL, nsh_gre_add_del_tunnel,
8009 sizeof(u32) * vec_len (tlvs));
8010
8011 spi_si = (spi<<8) | si;
8012
8013 mp->src = src.as_u32;
8014 mp->dst = dst.as_u32;
8015 mp->encap_vrf_id = ntohl(encap_vrf_id);
8016 mp->decap_vrf_id = ntohl(decap_vrf_id);
8017 mp->decap_next_index = ntohl(decap_next_index);
8018 mp->tlv_len_in_words = vec_len (tlvs);
8019 mp->is_add = is_add;
8020 mp->ver_o_c = ver_o_c;
8021 mp->length = 6 + vec_len(tlvs);
8022 mp->md_type = md_type;
8023 mp->next_protocol = next_protocol;
8024 mp->spi_si = ntohl(spi_si);
8025 mp->c1 = ntohl(c1);
8026 mp->c2 = ntohl(c2);
8027 mp->c3 = ntohl(c3);
8028 mp->c4 = ntohl(c4);
8029
8030 for (i = 0; i < vec_len(tlvs); i++)
8031 mp->tlvs[i] = ntohl(tlvs[i]);
8032
8033 vec_free (tlvs);
8034
8035 S; W;
8036 /* NOTREACHED */
8037 return 0;
8038}
8039
8040static uword unformat_nsh_vxlan_gpe_decap_next
8041(unformat_input_t * input, va_list * args)
8042{
8043 u32 * result = va_arg (*args, u32 *);
8044 u32 tmp;
8045
8046 if (unformat (input, "drop"))
8047 *result = NSH_VXLAN_GPE_INPUT_NEXT_DROP;
8048 else if (unformat (input, "ip4"))
8049 *result = NSH_VXLAN_GPE_INPUT_NEXT_IP4_INPUT;
8050 else if (unformat (input, "ip6"))
8051 *result = NSH_VXLAN_GPE_INPUT_NEXT_IP6_INPUT;
8052 else if (unformat (input, "ethernet"))
8053 *result = NSH_VXLAN_GPE_INPUT_NEXT_ETHERNET_INPUT;
8054 else if (unformat (input, "nsh-vxlan-gpe"))
8055 *result = NSH_VXLAN_GPE_INPUT_NEXT_ETHERNET_INPUT;
8056 else if (unformat (input, "%d", &tmp))
8057 *result = tmp;
8058 else
8059 return 0;
8060 return 1;
8061}
8062
8063static int api_nsh_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
8064{
8065 unformat_input_t * line_input = vam->input;
8066 vl_api_nsh_vxlan_gpe_add_del_tunnel_t *mp;
8067 f64 timeout;
8068 ip4_address_t src, dst;
8069 u8 is_add = 1;
8070 u8 src_set = 0;
8071 u8 dst_set = 0;
8072 u32 encap_vrf_id = 0;
8073 u32 decap_vrf_id = 0;
8074 u8 ver_o_c = 0;
8075 u8 md_type = 0;
8076 u8 next_protocol = 1; /* ip4 */
8077 u32 spi;
8078 u8 spi_set = 0;
8079 u32 si;
8080 u8 si_set = 0;
8081 u32 spi_si;
8082 u32 c1 = 0;
8083 u32 c2 = 0;
8084 u32 c3 = 0;
8085 u32 c4 = 0;
8086 u32 *tlvs = 0;
8087 u32 decap_next_index = NSH_INPUT_NEXT_IP4_INPUT;
8088 u32 vni;
8089 u8 vni_set = 0;
8090 u32 tmp;
8091 int i;
8092
8093 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
8094 if (unformat (line_input, "del"))
8095 is_add = 0;
8096 else if (unformat (line_input, "src %U",
8097 unformat_ip4_address, &src))
8098 src_set = 1;
8099 else if (unformat (line_input, "dst %U",
8100 unformat_ip4_address, &dst))
8101 dst_set = 1;
8102 else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
8103 ;
8104 else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
8105 ;
8106 else if (unformat (line_input, "decap-next %U",
8107 unformat_nsh_vxlan_gpe_decap_next,
8108 &decap_next_index))
8109 ;
8110 else if (unformat (line_input, "vni %d", &vni))
8111 vni_set = 1;
8112 else if (unformat (line_input, "version %d", &tmp))
8113 ver_o_c |= (tmp & 3) << 6;
8114 else if (unformat (line_input, "o-bit %d", &tmp))
8115 ver_o_c |= (tmp & 1) << 5;
8116 else if (unformat (line_input, "c-bit %d", &tmp))
8117 ver_o_c |= (tmp & 1) << 4;
8118 else if (unformat (line_input, "md-type %d", &tmp))
8119 md_type = tmp;
8120 else if (unformat(line_input, "next-ip4"))
8121 next_protocol = 1;
8122 else if (unformat(line_input, "next-ip6"))
8123 next_protocol = 2;
8124 else if (unformat(line_input, "next-ethernet"))
8125 next_protocol = 3;
8126 else if (unformat (line_input, "c1 %d", &c1))
8127 ;
8128 else if (unformat (line_input, "c2 %d", &c2))
8129 ;
8130 else if (unformat (line_input, "c3 %d", &c3))
8131 ;
8132 else if (unformat (line_input, "c4 %d", &c4))
8133 ;
8134 else if (unformat (line_input, "spi %d", &spi))
8135 spi_set = 1;
8136 else if (unformat (line_input, "si %d", &si))
8137 si_set = 1;
8138 else if (unformat (line_input, "tlv %x"))
8139 vec_add1 (tlvs, tmp);
8140 else {
8141 errmsg ("parse error '%U'\n", format_unformat_error, line_input);
8142 return -99;
8143 }
8144 }
8145
8146 if (src_set == 0) {
8147 errmsg ("tunnel src address not specified\n");
8148 return -99;
8149 }
8150 if (dst_set == 0) {
8151 errmsg ("tunnel dst address not specified\n");
8152 return -99;
8153 }
8154
8155 if (spi_set == 0) {
8156 errmsg ("spi not specified\n");
8157 return -99;
8158 }
8159
8160 if (si_set == 0) {
8161 errmsg ("si not specified\n");
8162 return -99;
8163 }
8164 if (vni_set == 0) {
8165 errmsg ("vni not specified\n");
8166 return -99;
8167 }
8168
8169 M2 (NSH_VXLAN_GPE_ADD_DEL_TUNNEL, nsh_vxlan_gpe_add_del_tunnel,
8170 sizeof(u32) * vec_len (tlvs));
8171
8172 spi_si = (spi<<8) | si;
8173
8174 mp->src = src.as_u32;
8175 mp->dst = dst.as_u32;
8176 mp->encap_vrf_id = ntohl(encap_vrf_id);
8177 mp->decap_vrf_id = ntohl(decap_vrf_id);
8178 mp->decap_next_index = ntohl(decap_next_index);
8179 mp->tlv_len_in_words = vec_len (tlvs);
8180 mp->vni = ntohl(vni);
8181 mp->is_add = is_add;
8182 mp->ver_o_c = ver_o_c;
8183 mp->length = 6 + vec_len(tlvs);
8184 mp->md_type = md_type;
8185 mp->next_protocol = next_protocol;
8186 mp->spi_si = ntohl(spi_si);
8187 mp->c1 = ntohl(c1);
8188 mp->c2 = ntohl(c2);
8189 mp->c3 = ntohl(c3);
8190 mp->c4 = ntohl(c4);
8191
8192 for (i = 0; i < vec_len(tlvs); i++)
8193 mp->tlvs[i] = ntohl(tlvs[i]);
8194
8195 vec_free (tlvs);
8196
8197 S; W;
8198 /* NOTREACHED */
8199 return 0;
8200}
8201
8202static uword unformat_lisp_gpe_decap_next (unformat_input_t * input,
8203 va_list * args)
8204{
8205 u32 * result = va_arg (*args, u32 *);
8206 u32 tmp;
8207
8208 if (unformat (input, "drop"))
8209 *result = LISP_GPE_INPUT_NEXT_DROP;
8210 else if (unformat (input, "ip4"))
8211 *result = LISP_GPE_INPUT_NEXT_IP4_INPUT;
8212 else if (unformat (input, "ip6"))
8213 *result = LISP_GPE_INPUT_NEXT_IP6_INPUT;
8214 else if (unformat (input, "ethernet"))
8215 *result = LISP_GPE_INPUT_NEXT_IP6_INPUT;
Ed Warnickecb9cada2015-12-08 15:45:58 -07008216 else if (unformat (input, "%d", &tmp))
8217 *result = tmp;
8218 else
8219 return 0;
8220 return 1;
8221}
8222
8223static int
8224api_lisp_gpe_add_del_tunnel (vat_main_t * vam)
8225{
8226 unformat_input_t * line_input = vam->input;
8227 vl_api_lisp_gpe_add_del_tunnel_t *mp;
8228 f64 timeout;
8229 ip4_address_t src, dst;
8230 u8 is_add = 1;
8231 u8 src_set = 0;
8232 u8 dst_set = 0;
8233 u32 encap_vrf_id = 0;
8234 u32 decap_vrf_id = 0;
8235 u8 next_protocol = LISP_GPE_NEXT_PROTOCOL_IP4;
8236 u32 decap_next_index = LISP_GPE_INPUT_NEXT_IP4_INPUT;
8237 u8 flags = LISP_GPE_FLAGS_P;
8238 u8 ver_res = 0;
8239 u8 res = 0;
8240 u32 iid = 0;
8241 u8 iid_set = 0;
8242 u32 tmp;
8243
8244 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
8245 if (unformat (line_input, "del"))
8246 is_add = 0;
8247 else if (unformat (line_input, "src %U",
8248 unformat_ip4_address, &src))
8249 src_set = 1;
8250 else if (unformat (line_input, "dst %U",
8251 unformat_ip4_address, &dst))
8252 dst_set = 1;
8253 else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
8254 ;
8255 else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
8256 ;
8257 else if (unformat (line_input, "decap-next %U",
8258 unformat_lisp_gpe_decap_next,
8259 &decap_next_index))
8260 ;
8261 else if (unformat(line_input, "next-ip4"))
8262 next_protocol = 1;
8263 else if (unformat(line_input, "next-ip6"))
8264 next_protocol = 2;
8265 else if (unformat(line_input, "next-ethernet"))
8266 next_protocol = 3;
8267 else if (unformat(line_input, "next-nsh"))
8268 next_protocol = 4;
8269 /* Allow the user to specify anything they want in the LISP hdr */
8270 else if (unformat (line_input, "ver_res %x", &tmp))
8271 ver_res = tmp;
8272 else if (unformat (line_input, "res %x", &tmp))
8273 res = tmp;
8274 else if (unformat (line_input, "flags %x", &tmp))
8275 flags = tmp;
8276 else if (unformat (line_input, "n-bit"))
8277 flags |= LISP_GPE_FLAGS_N;
8278 else if (unformat (line_input, "l-bit"))
8279 flags |= LISP_GPE_FLAGS_L;
8280 else if (unformat (line_input, "e-bit"))
8281 flags |= LISP_GPE_FLAGS_E;
8282 else if (unformat (line_input, "v-bit"))
8283 flags |= LISP_GPE_FLAGS_V;
8284 else if (unformat (line_input, "i-bit"))
8285 flags |= LISP_GPE_FLAGS_V;
8286 else if (unformat (line_input, "not-p-bit"))
8287 flags &= !LISP_GPE_FLAGS_P;
8288 else if (unformat (line_input, "p-bit"))
8289 flags |= LISP_GPE_FLAGS_P;
8290 else if (unformat (line_input, "o-bit"))
8291 flags |= LISP_GPE_FLAGS_O;
8292 else if (unformat (line_input, "iidx %x", &iid))
8293 iid_set = 1;
8294 else if (unformat (line_input, "iid %d", &iid))
8295 iid_set = 1;
8296 else {
8297 errmsg ("parse error '%U'\n", format_unformat_error, line_input);
8298 return -99;
8299 }
8300 }
8301
8302 if (src_set == 0) {
8303 errmsg ("tunnel src address not specified\n");
8304 return -99;
8305 }
8306 if (dst_set == 0) {
8307 errmsg ("tunnel dst address not specified\n");
8308 return -99;
8309 }
8310 if (iid_set == 0) {
8311 errmsg ("iid not specified\n");
8312 return -99;
8313 }
8314
8315 M(LISP_GPE_ADD_DEL_TUNNEL, lisp_gpe_add_del_tunnel);
8316
8317 mp->src = src.as_u32;
8318 mp->dst = dst.as_u32;
8319 mp->encap_vrf_id = ntohl(encap_vrf_id);
8320 mp->decap_vrf_id = ntohl(decap_vrf_id);
8321 mp->decap_next_index = ntohl(decap_next_index);
8322 mp->is_add = is_add;
8323 mp->flags = flags;
8324 mp->ver_res = ver_res;
8325 mp->res = res;
8326 mp->next_protocol = next_protocol;
8327 mp->iid = ntohl(iid);
8328
8329 S; W;
8330
8331 /* NOTREACHED */
8332 return 0;
8333}
8334
8335
8336u8 * format_l2_fib_mac_address (u8 * s, va_list * args)
8337{
8338 u8 * a = va_arg (*args, u8 *);
8339
8340 return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
8341 a[2], a[3], a[4], a[5], a[6], a[7]);
8342}
8343
8344static void vl_api_l2_fib_table_entry_t_handler
8345(vl_api_l2_fib_table_entry_t * mp)
8346{
8347 vat_main_t * vam = &vat_main;
8348
8349 fformat(vam->ofp, "%3" PRIu32 " %U %3" PRIu32
8350 " %d %d %d\n",
8351 ntohl(mp->bd_id), format_l2_fib_mac_address, &mp->mac,
8352 ntohl(mp->sw_if_index), mp->static_mac, mp->filter_mac,
8353 mp->bvi_mac);
8354}
8355
8356static void vl_api_l2_fib_table_entry_t_handler_json
8357(vl_api_l2_fib_table_entry_t * mp)
8358{
8359 vat_main_t * vam = &vat_main;
8360 vat_json_node_t *node = NULL;
8361
8362 if (VAT_JSON_ARRAY != vam->json_tree.type) {
8363 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
8364 vat_json_init_array(&vam->json_tree);
8365 }
8366 node = vat_json_array_add(&vam->json_tree);
8367
8368 vat_json_init_object(node);
8369 vat_json_object_add_uint(node, "bd_id", ntohl(mp->bd_id));
8370 vat_json_object_add_uint(node, "mac", clib_net_to_host_u64(mp->mac));
8371 vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
8372 vat_json_object_add_uint(node, "static_mac", mp->static_mac);
8373 vat_json_object_add_uint(node, "filter_mac", mp->filter_mac);
8374 vat_json_object_add_uint(node, "bvi_mac", mp->bvi_mac);
8375}
8376
8377static int api_l2_fib_table_dump (vat_main_t * vam)
8378{
8379 unformat_input_t * i = vam->input;
8380 vl_api_l2_fib_table_dump_t *mp;
8381 f64 timeout;
8382 u32 bd_id;
8383 u8 bd_id_set = 0;
8384
8385 /* Parse args required to build the message */
8386 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8387 if (unformat (i, "bd_id %d", &bd_id))
8388 bd_id_set = 1;
8389 else
8390 break;
8391 }
8392
8393 if (bd_id_set == 0) {
8394 errmsg ("missing bridge domain\n");
8395 return -99;
8396 }
8397
8398 fformat(vam->ofp, "BD-ID Mac Address sw-ndx Static Filter BVI\n");
8399
8400 /* Get list of l2 fib entries */
8401 M(L2_FIB_TABLE_DUMP, l2_fib_table_dump);
8402
8403 mp->bd_id = ntohl(bd_id);
8404 S;
8405
8406 /* Use a control ping for synchronization */
8407 {
8408 vl_api_control_ping_t * mp;
8409 M(CONTROL_PING, control_ping);
8410 S;
8411 }
8412 W;
8413}
8414
8415
8416static int
8417api_interface_name_renumber (vat_main_t * vam)
8418{
8419 unformat_input_t * line_input = vam->input;
8420 vl_api_interface_name_renumber_t *mp;
8421 u32 sw_if_index = ~0;
8422 f64 timeout;
8423 u32 new_show_dev_instance = ~0;
8424
8425 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
8426 if (unformat (line_input, "%U", unformat_sw_if_index, vam,
8427 &sw_if_index))
8428 ;
8429 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
8430 ;
8431 else if (unformat (line_input, "new_show_dev_instance %d",
8432 &new_show_dev_instance))
8433 ;
8434 else
8435 break;
8436 }
8437
8438 if (sw_if_index == ~0) {
8439 errmsg ("missing interface name or sw_if_index\n");
8440 return -99;
8441 }
8442
8443 if (new_show_dev_instance == ~0) {
8444 errmsg ("missing new_show_dev_instance\n");
8445 return -99;
8446 }
8447
8448 M(INTERFACE_NAME_RENUMBER, interface_name_renumber);
8449
8450 mp->sw_if_index = ntohl (sw_if_index);
8451 mp->new_show_dev_instance = ntohl (new_show_dev_instance);
8452
8453 S; W;
8454}
8455
8456static int
8457api_want_ip4_arp_events (vat_main_t * vam)
8458{
8459 unformat_input_t * line_input = vam->input;
8460 vl_api_want_ip4_arp_events_t * mp;
8461 f64 timeout;
8462 ip4_address_t address;
8463 int address_set = 0;
8464 u32 enable_disable = 1;
8465
8466 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
8467 if (unformat (line_input, "address %U",
8468 unformat_ip4_address, &address))
8469 address_set = 1;
8470 else if (unformat (line_input, "del"))
8471 enable_disable = 0;
8472 else
8473 break;
8474 }
8475
8476 if (address_set == 0) {
8477 errmsg ("missing addresses\n");
8478 return -99;
8479 }
8480
8481 M(WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
8482 mp->enable_disable = enable_disable;
8483 mp->pid = getpid();
8484 mp->address = address.as_u32;
8485
8486 S; W;
8487}
8488
8489static int api_input_acl_set_interface (vat_main_t * vam)
8490{
8491 unformat_input_t * i = vam->input;
8492 vl_api_input_acl_set_interface_t *mp;
8493 f64 timeout;
8494 u32 sw_if_index;
8495 int sw_if_index_set;
8496 u32 ip4_table_index = ~0;
8497 u32 ip6_table_index = ~0;
8498 u32 l2_table_index = ~0;
8499 u8 is_add = 1;
8500
8501 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8502 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8503 sw_if_index_set = 1;
8504 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8505 sw_if_index_set = 1;
8506 else if (unformat (i, "del"))
8507 is_add = 0;
8508 else if (unformat (i, "ip4-table %d", &ip4_table_index))
8509 ;
8510 else if (unformat (i, "ip6-table %d", &ip6_table_index))
8511 ;
8512 else if (unformat (i, "l2-table %d", &l2_table_index))
8513 ;
8514 else {
8515 clib_warning ("parse error '%U'", format_unformat_error, i);
8516 return -99;
8517 }
8518 }
8519
8520 if (sw_if_index_set == 0) {
8521 errmsg ("missing interface name or sw_if_index\n");
8522 return -99;
8523 }
8524
8525 M(INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
8526
8527 mp->sw_if_index = ntohl(sw_if_index);
8528 mp->ip4_table_index = ntohl(ip4_table_index);
8529 mp->ip6_table_index = ntohl(ip6_table_index);
8530 mp->l2_table_index = ntohl(l2_table_index);
8531 mp->is_add = is_add;
8532
8533 S; W;
8534 /* NOTREACHED */
8535 return 0;
8536}
8537
8538static int
8539api_ip_address_dump (vat_main_t * vam)
8540{
8541 unformat_input_t * i = vam->input;
8542 vl_api_ip_address_dump_t * mp;
8543 u32 sw_if_index = ~0;
8544 u8 sw_if_index_set = 0;
8545 u8 ipv4_set = 0;
8546 u8 ipv6_set = 0;
8547 f64 timeout;
8548
8549 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8550 if (unformat (i, "sw_if_index %d", &sw_if_index))
8551 sw_if_index_set = 1;
8552 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8553 sw_if_index_set = 1;
8554 else if (unformat (i, "ipv4"))
8555 ipv4_set = 1;
8556 else if (unformat (i, "ipv6"))
8557 ipv6_set = 1;
8558 else
8559 break;
8560 }
8561
8562 if (ipv4_set && ipv6_set) {
8563 errmsg ("ipv4 and ipv6 flags cannot be both set\n");
8564 return -99;
8565 }
8566
8567 if ((!ipv4_set) && (!ipv6_set)) {
8568 errmsg ("no ipv4 nor ipv6 flag set\n");
8569 return -99;
8570 }
8571
8572 if (sw_if_index_set == 0) {
8573 errmsg ("missing interface name or sw_if_index\n");
8574 return -99;
8575 }
8576
8577 vam->current_sw_if_index = sw_if_index;
8578 vam->is_ipv6 = ipv6_set;
8579
8580 M(IP_ADDRESS_DUMP, ip_address_dump);
8581 mp->sw_if_index = ntohl(sw_if_index);
8582 mp->is_ipv6 = ipv6_set;
8583 S;
8584
8585 /* Use a control ping for synchronization */
8586 {
8587 vl_api_control_ping_t * mp;
8588 M(CONTROL_PING, control_ping);
8589 S;
8590 }
8591 W;
8592}
8593
8594static int
8595api_ip_dump (vat_main_t * vam)
8596{
8597 vl_api_ip_dump_t * mp;
8598 unformat_input_t * in = vam->input;
8599 int ipv4_set = 0;
8600 int ipv6_set = 0;
8601 int is_ipv6;
8602 f64 timeout;
8603 int i;
8604
8605 while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT) {
8606 if (unformat (in, "ipv4"))
8607 ipv4_set = 1;
8608 else if (unformat (in, "ipv6"))
8609 ipv6_set = 1;
8610 else
8611 break;
8612 }
8613
8614 if (ipv4_set && ipv6_set) {
8615 errmsg ("ipv4 and ipv6 flags cannot be both set\n");
8616 return -99;
8617 }
8618
8619 if ((!ipv4_set) && (!ipv6_set)) {
8620 errmsg ("no ipv4 nor ipv6 flag set\n");
8621 return -99;
8622 }
8623
8624 is_ipv6 = ipv6_set;
8625 vam->is_ipv6 = is_ipv6;
8626
8627 /* free old data */
8628 for (i = 0; i < vec_len(vam->ip_details_by_sw_if_index[is_ipv6]); i++) {
8629 vec_free(vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
8630 }
8631 vec_free(vam->ip_details_by_sw_if_index[is_ipv6]);
8632
8633 M(IP_DUMP, ip_dump);
8634 mp->is_ipv6 = ipv6_set;
8635 S;
8636
8637 /* Use a control ping for synchronization */
8638 {
8639 vl_api_control_ping_t * mp;
8640 M(CONTROL_PING, control_ping);
8641 S;
8642 }
8643 W;
8644}
8645
8646static int
8647api_ipsec_spd_add_del (vat_main_t * vam)
8648{
Dave Barachbfdedbd2016-01-20 09:11:55 -05008649#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -07008650 unformat_input_t * i = vam->input;
8651 vl_api_ipsec_spd_add_del_t *mp;
8652 f64 timeout;
8653 u32 spd_id = ~0;
8654 u8 is_add = 1;
8655
8656 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8657 if (unformat (i, "spd_id %d", &spd_id))
8658 ;
8659 else if (unformat (i, "del"))
8660 is_add = 0;
8661 else {
8662 clib_warning ("parse error '%U'", format_unformat_error, i);
8663 return -99;
8664 }
8665 }
8666 if (spd_id == ~0) {
8667 errmsg ("spd_id must be set\n");
8668 return -99;
8669 }
8670
8671 M(IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
8672
8673 mp->spd_id = ntohl(spd_id);
8674 mp->is_add = is_add;
8675
8676 S; W;
8677 /* NOTREACHED */
8678 return 0;
Dave Barachbfdedbd2016-01-20 09:11:55 -05008679#else
8680 clib_warning ("unsupported (no dpdk)");
8681 return -99;
8682#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -07008683}
8684
8685static int
8686api_ipsec_interface_add_del_spd (vat_main_t * vam)
8687{
Dave Barachbfdedbd2016-01-20 09:11:55 -05008688#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -07008689 unformat_input_t * i = vam->input;
8690 vl_api_ipsec_interface_add_del_spd_t *mp;
8691 f64 timeout;
8692 u32 sw_if_index;
8693 u8 sw_if_index_set = 0;
8694 u32 spd_id = (u32) ~0;
8695 u8 is_add = 1;
8696
8697 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8698 if (unformat (i, "del"))
8699 is_add = 0;
8700 else if (unformat (i, "spd_id %d", &spd_id))
8701 ;
8702 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8703 sw_if_index_set = 1;
8704 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8705 sw_if_index_set = 1;
8706 else {
8707 clib_warning ("parse error '%U'", format_unformat_error, i);
8708 return -99;
8709 }
8710
8711 }
8712
8713 if (spd_id == (u32) ~0) {
8714 errmsg ("spd_id must be set\n");
8715 return -99;
8716 }
8717
8718 if (sw_if_index_set == 0) {
8719 errmsg ("missing interface name or sw_if_index\n");
8720 return -99;
8721 }
8722
8723 M(IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
8724
8725 mp->spd_id = ntohl(spd_id);
8726 mp->sw_if_index = ntohl (sw_if_index);
8727 mp->is_add = is_add;
8728
8729 S; W;
8730 /* NOTREACHED */
8731 return 0;
Dave Barachbfdedbd2016-01-20 09:11:55 -05008732#else
8733 clib_warning ("unsupported (no dpdk)");
8734 return -99;
8735#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -07008736}
8737
8738static int
8739api_ipsec_spd_add_del_entry (vat_main_t * vam)
8740{
Dave Barachbfdedbd2016-01-20 09:11:55 -05008741#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -07008742 unformat_input_t * i = vam->input;
8743 vl_api_ipsec_spd_add_del_entry_t *mp;
8744 f64 timeout;
8745 u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
8746 u32 spd_id, sa_id, protocol = 0, policy = 0;
8747 i32 priority;
8748 u32 rport_start = 0, rport_stop = (u32) ~0;
8749 u32 lport_start = 0, lport_stop = (u32) ~0;
8750 ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
8751 ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
8752
8753 laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
8754 laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~0;
8755 laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
8756 laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
8757 laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~0;
8758 laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~0;
8759
8760 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8761 if (unformat (i, "del"))
8762 is_add = 0;
8763 if (unformat (i, "outbound"))
8764 is_outbound = 1;
8765 if (unformat (i, "inbound"))
8766 is_outbound = 0;
8767 else if (unformat (i, "spd_id %d", &spd_id))
8768 ;
8769 else if (unformat (i, "sa_id %d", &sa_id))
8770 ;
8771 else if (unformat (i, "priority %d", &priority))
8772 ;
8773 else if (unformat (i, "protocol %d", &protocol))
8774 ;
8775 else if (unformat (i, "lport_start %d", &lport_start))
8776 ;
8777 else if (unformat (i, "lport_stop %d", &lport_stop))
8778 ;
8779 else if (unformat (i, "rport_start %d", &rport_start))
8780 ;
8781 else if (unformat (i, "rport_stop %d", &rport_stop))
8782 ;
8783 else if (unformat (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
8784 {
8785 is_ipv6 = 0;
8786 is_ip_any =0;
8787 }
8788 else if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
8789 {
8790 is_ipv6 = 0;
8791 is_ip_any = 0;
8792 }
8793 else if (unformat (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
8794 {
8795 is_ipv6 = 0;
8796 is_ip_any = 0;
8797 }
8798 else if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
8799 {
8800 is_ipv6 = 0;
8801 is_ip_any = 0;
8802 }
8803 else if (unformat (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
8804 {
8805 is_ipv6 = 1;
8806 is_ip_any = 0;
8807 }
8808 else if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
8809 {
8810 is_ipv6 = 1;
8811 is_ip_any = 0;
8812 }
8813 else if (unformat (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
8814 {
8815 is_ipv6 = 1;
8816 is_ip_any = 0;
8817 }
8818 else if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
8819 {
8820 is_ipv6 = 1;
8821 is_ip_any = 0;
8822 }
8823 else if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
8824 {
8825 if (policy == IPSEC_POLICY_ACTION_RESOLVE) {
8826 clib_warning ("unsupported action: 'resolve'");
8827 return -99;
8828 }
8829 }
8830 else {
8831 clib_warning ("parse error '%U'", format_unformat_error, i);
8832 return -99;
8833 }
8834
8835 }
8836
8837 M(IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
8838
8839 mp->spd_id = ntohl(spd_id);
8840 mp->priority = ntohl(priority);
8841 mp->is_outbound = is_outbound;
8842
8843 mp->is_ipv6 = is_ipv6;
8844 if (is_ipv6 || is_ip_any) {
Damjan Marionf1213b82016-03-13 02:22:06 +01008845 clib_memcpy (mp->remote_address_start, &raddr6_start, sizeof(ip6_address_t));
8846 clib_memcpy (mp->remote_address_stop, &raddr6_stop, sizeof(ip6_address_t));
8847 clib_memcpy (mp->local_address_start, &laddr6_start, sizeof(ip6_address_t));
8848 clib_memcpy (mp->local_address_stop, &laddr6_stop, sizeof(ip6_address_t));
Ed Warnickecb9cada2015-12-08 15:45:58 -07008849 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01008850 clib_memcpy (mp->remote_address_start, &raddr4_start, sizeof(ip4_address_t));
8851 clib_memcpy (mp->remote_address_stop, &raddr4_stop, sizeof(ip4_address_t));
8852 clib_memcpy (mp->local_address_start, &laddr4_start, sizeof(ip4_address_t));
8853 clib_memcpy (mp->local_address_stop, &laddr4_stop, sizeof(ip4_address_t));
Ed Warnickecb9cada2015-12-08 15:45:58 -07008854 }
8855 mp->protocol = (u8) protocol;
8856 mp->local_port_start = ntohs((u16) lport_start);
8857 mp->local_port_stop = ntohs((u16) lport_stop);
8858 mp->remote_port_start = ntohs((u16) rport_start);
8859 mp->remote_port_stop = ntohs((u16) rport_stop);
8860 mp->policy = (u8) policy;
8861 mp->sa_id = ntohl(sa_id);
8862 mp->is_add = is_add;
8863 mp->is_ip_any = is_ip_any;
8864 S; W;
8865 /* NOTREACHED */
8866 return 0;
Dave Barachbfdedbd2016-01-20 09:11:55 -05008867#else
8868 clib_warning ("unsupported (no dpdk)");
8869 return -99;
8870#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -07008871}
8872
8873static int
8874api_ipsec_sad_add_del_entry (vat_main_t * vam)
8875{
Dave Barachbfdedbd2016-01-20 09:11:55 -05008876#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -07008877 unformat_input_t * i = vam->input;
8878 vl_api_ipsec_sad_add_del_entry_t *mp;
8879 f64 timeout;
8880 u32 sad_id, spi;
8881 u8 * ck, * ik;
8882 u8 is_add = 1;
8883
8884 u8 protocol = IPSEC_PROTOCOL_AH;
8885 u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
8886 u32 crypto_alg = 0, integ_alg = 0;
8887 ip4_address_t tun_src4;
8888 ip4_address_t tun_dst4;
8889 ip6_address_t tun_src6;
8890 ip6_address_t tun_dst6;
8891
8892 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8893 if (unformat (i, "del"))
8894 is_add = 0;
8895 else if (unformat (i, "sad_id %d", &sad_id))
8896 ;
8897 else if (unformat (i, "spi %d", &spi))
8898 ;
8899 else if (unformat (i, "esp"))
8900 protocol = IPSEC_PROTOCOL_ESP;
8901 else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4)) {
8902 is_tunnel = 1;
8903 is_tunnel_ipv6 = 0;
8904 }
8905 else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4)) {
8906 is_tunnel = 1;
8907 is_tunnel_ipv6 = 0;
8908 }
8909 else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6)) {
8910 is_tunnel = 1;
8911 is_tunnel_ipv6 = 1;
8912 }
8913 else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6)) {
8914 is_tunnel = 1;
8915 is_tunnel_ipv6 = 1;
8916 }
8917 else if (unformat (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg)) {
8918 if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
8919 crypto_alg > IPSEC_INTEG_ALG_SHA_512_256) {
8920 clib_warning ("unsupported crypto-alg: '%U'",
8921 format_ipsec_crypto_alg, crypto_alg);
8922 return -99;
8923 }
8924 }
8925 else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
8926 ;
8927 else if (unformat (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg)) {
8928 if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
8929 integ_alg > IPSEC_INTEG_ALG_SHA_512_256) {
8930 clib_warning ("unsupported integ-alg: '%U'",
8931 format_ipsec_integ_alg, integ_alg);
8932 return -99;
8933 }
8934 }
8935 else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
8936 ;
8937 else {
8938 clib_warning ("parse error '%U'", format_unformat_error, i);
8939 return -99;
8940 }
8941
8942 }
8943
8944 M(IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
8945
8946 mp->sad_id = ntohl(sad_id);
8947 mp->is_add = is_add;
8948 mp->protocol = protocol;
8949 mp->spi = ntohl(spi);
8950 mp->is_tunnel = is_tunnel;
8951 mp->is_tunnel_ipv6 = is_tunnel_ipv6;
8952 mp->crypto_algorithm = crypto_alg;
8953 mp->integrity_algorithm = integ_alg;
8954 mp->crypto_key_length = vec_len(ck);
8955 mp->integrity_key_length = vec_len(ik);
8956
8957 if (mp->crypto_key_length > sizeof(mp->crypto_key))
8958 mp->crypto_key_length = sizeof(mp->crypto_key);
8959
8960 if (mp->integrity_key_length > sizeof(mp->integrity_key))
8961 mp->integrity_key_length = sizeof(mp->integrity_key);
8962
Damjan Marionf1213b82016-03-13 02:22:06 +01008963 clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
8964 clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
Ed Warnickecb9cada2015-12-08 15:45:58 -07008965
8966 if (is_tunnel) {
8967 if (is_tunnel_ipv6) {
Damjan Marionf1213b82016-03-13 02:22:06 +01008968 clib_memcpy (mp->tunnel_src_address, &tun_src6, sizeof(ip6_address_t));
8969 clib_memcpy (mp->tunnel_dst_address, &tun_dst6, sizeof(ip6_address_t));
Ed Warnickecb9cada2015-12-08 15:45:58 -07008970 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01008971 clib_memcpy (mp->tunnel_src_address, &tun_src4, sizeof(ip4_address_t));
8972 clib_memcpy (mp->tunnel_dst_address, &tun_dst4, sizeof(ip4_address_t));
Ed Warnickecb9cada2015-12-08 15:45:58 -07008973 }
8974 }
8975
8976 S; W;
8977 /* NOTREACHED */
8978 return 0;
Dave Barachbfdedbd2016-01-20 09:11:55 -05008979#else
8980 clib_warning ("unsupported (no dpdk)");
8981 return -99;
8982#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -07008983}
8984
8985static int
8986api_ipsec_sa_set_key (vat_main_t * vam)
8987{
Dave Barachbfdedbd2016-01-20 09:11:55 -05008988#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -07008989 unformat_input_t * i = vam->input;
8990 vl_api_ipsec_sa_set_key_t *mp;
8991 f64 timeout;
8992 u32 sa_id;
8993 u8 * ck, * ik;
8994
8995 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8996 if (unformat (i, "sa_id %d", &sa_id))
8997 ;
8998 else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
8999 ;
9000 else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
9001 ;
9002 else {
9003 clib_warning ("parse error '%U'", format_unformat_error, i);
9004 return -99;
9005 }
9006 }
9007
9008 M(IPSEC_SA_SET_KEY, ipsec_set_sa_key);
9009
9010 mp->sa_id = ntohl(sa_id);
9011 mp->crypto_key_length = vec_len(ck);
9012 mp->integrity_key_length = vec_len(ik);
9013
9014 if (mp->crypto_key_length > sizeof(mp->crypto_key))
9015 mp->crypto_key_length = sizeof(mp->crypto_key);
9016
9017 if (mp->integrity_key_length > sizeof(mp->integrity_key))
9018 mp->integrity_key_length = sizeof(mp->integrity_key);
9019
Damjan Marionf1213b82016-03-13 02:22:06 +01009020 clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
9021 clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
Ed Warnickecb9cada2015-12-08 15:45:58 -07009022
9023 S; W;
9024 /* NOTREACHED */
9025 return 0;
Dave Barachbfdedbd2016-01-20 09:11:55 -05009026#else
9027 clib_warning ("unsupported (no dpdk)");
9028 return -99;
9029#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -07009030}
9031
Matus Fabiane5f42fe2016-04-08 11:18:08 +02009032static int
9033api_ikev2_profile_add_del (vat_main_t * vam)
9034{
9035#if DPDK > 0
9036 unformat_input_t * i = vam->input;
9037 vl_api_ikev2_profile_add_del_t * mp;
9038 f64 timeout;
9039 u8 is_add = 1;
9040 u8 * name = 0;
9041
9042 const char * valid_chars = "a-zA-Z0-9_";
9043
9044 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9045 if (unformat (i, "del"))
9046 is_add = 0;
9047 else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
9048 vec_add1 (name, 0);
9049 else {
9050 errmsg ("parse error '%U'", format_unformat_error, i);
9051 return -99;
9052 }
9053 }
9054
9055 if (!vec_len (name)) {
9056 errmsg ("profile name must be specified");
9057 return -99;
9058 }
9059
9060 if (vec_len (name) > 64) {
9061 errmsg ("profile name too long");
9062 return -99;
9063 }
9064
9065 M(IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
9066
Damjan Marionf1213b82016-03-13 02:22:06 +01009067 clib_memcpy(mp->name, name, vec_len (name));
Matus Fabiane5f42fe2016-04-08 11:18:08 +02009068 mp->is_add = is_add;
9069 vec_free (name);
9070
9071 S; W;
9072 /* NOTREACHED */
9073 return 0;
9074#else
9075 clib_warning ("unsupported (no dpdk)");
9076 return -99;
9077#endif
9078}
9079
9080static int
9081api_ikev2_profile_set_auth (vat_main_t * vam)
9082{
9083#if DPDK > 0
9084 unformat_input_t * i = vam->input;
9085 vl_api_ikev2_profile_set_auth_t * mp;
9086 f64 timeout;
9087 u8 * name = 0;
9088 u8 * data = 0;
9089 u32 auth_method = 0;
9090 u8 is_hex = 0;
9091
9092 const char * valid_chars = "a-zA-Z0-9_";
9093
9094 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9095 if (unformat (i, "name %U", unformat_token, valid_chars, &name))
9096 vec_add1 (name, 0);
9097 else if (unformat (i, "auth_method %U",
9098 unformat_ikev2_auth_method, &auth_method))
9099 ;
9100 else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
9101 is_hex = 1;
9102 else if (unformat (i, "auth_data %v", &data))
9103 ;
9104 else {
9105 errmsg ("parse error '%U'", format_unformat_error, i);
9106 return -99;
9107 }
9108 }
9109
9110 if (!vec_len (name)) {
9111 errmsg ("profile name must be specified");
9112 return -99;
9113 }
9114
9115 if (vec_len (name) > 64) {
9116 errmsg ("profile name too long");
9117 return -99;
9118 }
9119
9120 if (!vec_len(data)) {
9121 errmsg ("auth_data must be specified");
9122 return -99;
9123 }
9124
9125 if (!auth_method) {
9126 errmsg ("auth_method must be specified");
9127 return -99;
9128 }
9129
9130 M(IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
9131
9132 mp->is_hex = is_hex;
9133 mp->auth_method = (u8) auth_method;
9134 mp->data_len = vec_len (data);
Damjan Marionf1213b82016-03-13 02:22:06 +01009135 clib_memcpy (mp->name, name, vec_len (name));
9136 clib_memcpy (mp->data, data, vec_len (data));
Matus Fabiane5f42fe2016-04-08 11:18:08 +02009137 vec_free (name);
9138 vec_free (data);
9139
9140 S; W;
9141 /* NOTREACHED */
9142 return 0;
9143#else
9144 clib_warning ("unsupported (no dpdk)");
9145 return -99;
9146#endif
9147}
9148
9149static int
9150api_ikev2_profile_set_id (vat_main_t * vam)
9151{
9152#if DPDK > 0
9153 unformat_input_t * i = vam->input;
9154 vl_api_ikev2_profile_set_id_t * mp;
9155 f64 timeout;
9156 u8 * name = 0;
9157 u8 * data = 0;
9158 u8 is_local = 0;
9159 u32 id_type = 0;
9160 ip4_address_t ip4;
9161
9162 const char * valid_chars = "a-zA-Z0-9_";
9163
9164 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9165 if (unformat (i, "name %U", unformat_token, valid_chars, &name))
9166 vec_add1 (name, 0);
9167 else if (unformat (i, "id_type %U",
9168 unformat_ikev2_id_type, &id_type))
9169 ;
9170 else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
9171 {
9172 data = vec_new(u8, 4);
Damjan Marionf1213b82016-03-13 02:22:06 +01009173 clib_memcpy(data, ip4.as_u8, 4);
Matus Fabiane5f42fe2016-04-08 11:18:08 +02009174 }
9175 else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
9176 ;
9177 else if (unformat (i, "id_data %v", &data))
9178 ;
9179 else if (unformat (i, "local"))
9180 is_local = 1;
9181 else if (unformat (i, "remote"))
9182 is_local = 0;
9183 else {
9184 errmsg ("parse error '%U'", format_unformat_error, i);
9185 return -99;
9186 }
9187 }
9188
9189 if (!vec_len (name)) {
9190 errmsg ("profile name must be specified");
9191 return -99;
9192 }
9193
9194 if (vec_len (name) > 64) {
9195 errmsg ("profile name too long");
9196 return -99;
9197 }
9198
9199 if (!vec_len(data)) {
9200 errmsg ("id_data must be specified");
9201 return -99;
9202 }
9203
9204 if (!id_type) {
9205 errmsg ("id_type must be specified");
9206 return -99;
9207 }
9208
9209 M(IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
9210
9211 mp->is_local = is_local;
9212 mp->id_type = (u8) id_type;
9213 mp->data_len = vec_len (data);
Damjan Marionf1213b82016-03-13 02:22:06 +01009214 clib_memcpy (mp->name, name, vec_len (name));
9215 clib_memcpy (mp->data, data, vec_len (data));
Matus Fabiane5f42fe2016-04-08 11:18:08 +02009216 vec_free (name);
9217 vec_free (data);
9218
9219 S; W;
9220 /* NOTREACHED */
9221 return 0;
9222#else
9223 clib_warning ("unsupported (no dpdk)");
9224 return -99;
9225#endif
9226}
9227
9228static int
9229api_ikev2_profile_set_ts (vat_main_t * vam)
9230{
9231#if DPDK > 0
9232 unformat_input_t * i = vam->input;
9233 vl_api_ikev2_profile_set_ts_t * mp;
9234 f64 timeout;
9235 u8 * name = 0;
9236 u8 is_local = 0;
9237 u32 proto = 0, start_port = 0, end_port = (u32) ~0;
9238 ip4_address_t start_addr, end_addr;
9239
9240 const char * valid_chars = "a-zA-Z0-9_";
9241
9242 start_addr.as_u32 = 0;
9243 end_addr.as_u32 = (u32) ~0;
9244
9245 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9246 if (unformat (i, "name %U", unformat_token, valid_chars, &name))
9247 vec_add1 (name, 0);
9248 else if (unformat (i, "protocol %d", &proto))
9249 ;
9250 else if (unformat (i, "start_port %d", &start_port))
9251 ;
9252 else if (unformat (i, "end_port %d", &end_port))
9253 ;
9254 else if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
9255 ;
9256 else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
9257 ;
9258 else if (unformat (i, "local"))
9259 is_local = 1;
9260 else if (unformat (i, "remote"))
9261 is_local = 0;
9262 else {
9263 errmsg ("parse error '%U'", format_unformat_error, i);
9264 return -99;
9265 }
9266 }
9267
9268 if (!vec_len (name)) {
9269 errmsg ("profile name must be specified");
9270 return -99;
9271 }
9272
9273 if (vec_len (name) > 64) {
9274 errmsg ("profile name too long");
9275 return -99;
9276 }
9277
9278 M(IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
9279
9280 mp->is_local = is_local;
9281 mp->proto = (u8) proto;
9282 mp->start_port = (u16) start_port;
9283 mp->end_port = (u16) end_port;
9284 mp->start_addr = start_addr.as_u32;
9285 mp->end_addr = end_addr.as_u32;
Damjan Marionf1213b82016-03-13 02:22:06 +01009286 clib_memcpy (mp->name, name, vec_len (name));
Matus Fabiane5f42fe2016-04-08 11:18:08 +02009287 vec_free (name);
9288
9289 S; W;
9290 /* NOTREACHED */
9291 return 0;
9292#else
9293 clib_warning ("unsupported (no dpdk)");
9294 return -99;
9295#endif
9296}
9297
9298static int
9299api_ikev2_set_local_key (vat_main_t * vam)
9300{
9301#if DPDK > 0
9302 unformat_input_t * i = vam->input;
9303 vl_api_ikev2_set_local_key_t * mp;
9304 f64 timeout;
9305 u8 * file = 0;
9306
9307 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9308 if (unformat (i, "file %v", &file))
9309 vec_add1 (file, 0);
9310 else {
9311 errmsg ("parse error '%U'", format_unformat_error, i);
9312 return -99;
9313 }
9314 }
9315
9316 if (!vec_len (file)) {
9317 errmsg ("RSA key file must be specified");
9318 return -99;
9319 }
9320
9321 if (vec_len (file) > 256) {
9322 errmsg ("file name too long");
9323 return -99;
9324 }
9325
9326 M(IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
9327
Damjan Marionf1213b82016-03-13 02:22:06 +01009328 clib_memcpy (mp->key_file, file, vec_len (file));
Matus Fabiane5f42fe2016-04-08 11:18:08 +02009329 vec_free (file);
9330
9331 S; W;
9332 /* NOTREACHED */
9333 return 0;
9334#else
9335 clib_warning ("unsupported (no dpdk)");
9336 return -99;
9337#endif
9338}
9339
Ed Warnickecb9cada2015-12-08 15:45:58 -07009340/*
9341 * MAP
9342 */
9343static int api_map_add_domain (vat_main_t * vam)
9344{
9345 unformat_input_t *i = vam->input;
9346 vl_api_map_add_domain_t *mp;
9347 f64 timeout;
9348
9349 ip4_address_t ip4_prefix;
9350 ip6_address_t ip6_prefix;
9351 ip6_address_t ip6_src;
9352 u32 num_m_args = 0;
9353 u32 ip6_prefix_len, ip4_prefix_len, ea_bits_len, psid_offset,
9354 psid_length;
9355 u8 is_translation = 0;
9356 u32 mtu = 0;
9357 u8 ip6_src_len = 128;
9358
9359 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9360 if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
9361 &ip4_prefix, &ip4_prefix_len))
9362 num_m_args++;
9363 else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
9364 &ip6_prefix, &ip6_prefix_len))
9365 num_m_args++;
9366 else if (unformat (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src, &ip6_src_len))
9367 num_m_args++;
9368 else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
9369 num_m_args++;
9370 else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
9371 num_m_args++;
9372 else if (unformat (i, "psid-offset %d", &psid_offset))
9373 num_m_args++;
9374 else if (unformat (i, "psid-len %d", &psid_length))
9375 num_m_args++;
9376 else if (unformat (i, "mtu %d", &mtu))
9377 num_m_args++;
9378 else if (unformat (i, "map-t"))
9379 is_translation = 1;
9380 else {
9381 clib_warning ("parse error '%U'", format_unformat_error, i);
9382 return -99;
9383 }
9384 }
9385
9386 if (num_m_args != 6) {
9387 errmsg("mandatory argument(s) missing\n");
9388 return -99;
9389 }
9390
9391 /* Construct the API message */
9392 M(MAP_ADD_DOMAIN, map_add_domain);
9393
Damjan Marionf1213b82016-03-13 02:22:06 +01009394 clib_memcpy(mp->ip4_prefix, &ip4_prefix, sizeof(ip4_prefix));
Ed Warnickecb9cada2015-12-08 15:45:58 -07009395 mp->ip4_prefix_len = ip4_prefix_len;
9396
Damjan Marionf1213b82016-03-13 02:22:06 +01009397 clib_memcpy(mp->ip6_prefix, &ip6_prefix, sizeof(ip6_prefix));
Ed Warnickecb9cada2015-12-08 15:45:58 -07009398 mp->ip6_prefix_len = ip6_prefix_len;
9399
Damjan Marionf1213b82016-03-13 02:22:06 +01009400 clib_memcpy(mp->ip6_src, &ip6_src, sizeof(ip6_src));
Ed Warnickecb9cada2015-12-08 15:45:58 -07009401 mp->ip6_src_prefix_len = ip6_src_len;
9402
9403 mp->ea_bits_len = ea_bits_len;
9404 mp->psid_offset = psid_offset;
9405 mp->psid_length = psid_length;
9406 mp->is_translation = is_translation;
9407 mp->mtu = htons(mtu);
9408
9409 /* send it... */
9410 S;
9411
9412 /* Wait for a reply, return good/bad news */
9413 W;
9414}
9415
9416static int api_map_del_domain (vat_main_t * vam)
9417{
9418 unformat_input_t *i = vam->input;
9419 vl_api_map_del_domain_t *mp;
9420 f64 timeout;
9421
9422 u32 num_m_args = 0;
9423 u32 index;
9424
9425 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9426 if (unformat (i, "index %d", &index))
9427 num_m_args++;
9428 else {
9429 clib_warning ("parse error '%U'", format_unformat_error, i);
9430 return -99;
9431 }
9432 }
9433
9434 if (num_m_args != 1) {
9435 errmsg("mandatory argument(s) missing\n");
9436 return -99;
9437 }
9438
9439 /* Construct the API message */
9440 M(MAP_DEL_DOMAIN, map_del_domain);
9441
9442 mp->index = ntohl(index);
9443
9444 /* send it... */
9445 S;
9446
9447 /* Wait for a reply, return good/bad news */
9448 W;
9449}
9450
9451static int api_map_add_del_rule (vat_main_t * vam)
9452{
9453 unformat_input_t *i = vam->input;
9454 vl_api_map_add_del_rule_t *mp;
9455 f64 timeout;
9456 u8 is_add = 1;
9457 ip6_address_t ip6_dst;
9458 u32 num_m_args = 0, index, psid;
9459
9460 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9461 if (unformat (i, "index %d", &index))
9462 num_m_args++;
9463 else if (unformat (i, "psid %d", &psid))
9464 num_m_args++;
9465 else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
9466 num_m_args++;
9467 else if (unformat (i, "del")) {
9468 is_add = 0;
9469 } else {
9470 clib_warning ("parse error '%U'", format_unformat_error, i);
9471 return -99;
9472 }
9473 }
9474
9475 /* Construct the API message */
9476 M(MAP_ADD_DEL_RULE, map_add_del_rule);
9477
9478 mp->index = ntohl(index);
9479 mp->is_add = is_add;
Damjan Marionf1213b82016-03-13 02:22:06 +01009480 clib_memcpy(mp->ip6_dst, &ip6_dst, sizeof(ip6_dst));
Ed Warnickecb9cada2015-12-08 15:45:58 -07009481 mp->psid = ntohs(psid);
9482
9483 /* send it... */
9484 S;
9485
9486 /* Wait for a reply, return good/bad news */
9487 W;
9488}
9489
9490static int api_map_domain_dump (vat_main_t * vam)
9491{
9492 vl_api_map_domain_dump_t *mp;
9493 f64 timeout;
9494
9495 /* Construct the API message */
9496 M(MAP_DOMAIN_DUMP, map_domain_dump);
9497
9498 /* send it... */
9499 S;
9500
9501 /* Use a control ping for synchronization */
9502 {
9503 vl_api_control_ping_t * mp;
9504 M(CONTROL_PING, control_ping);
9505 S;
9506 }
9507 W;
9508}
9509
9510static int api_map_rule_dump (vat_main_t * vam)
9511{
9512 unformat_input_t *i = vam->input;
9513 vl_api_map_rule_dump_t *mp;
9514 f64 timeout;
9515 u32 domain_index = ~0;
9516
9517 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9518 if (unformat (i, "index %u", &domain_index))
9519 ;
9520 else
9521 break;
9522 }
9523
9524 if (domain_index == ~0) {
9525 clib_warning("parse error: domain index expected");
9526 return -99;
9527 }
9528
9529 /* Construct the API message */
9530 M(MAP_RULE_DUMP, map_rule_dump);
9531
9532 mp->domain_index = htonl(domain_index);
9533
9534 /* send it... */
9535 S;
9536
9537 /* Use a control ping for synchronization */
9538 {
9539 vl_api_control_ping_t * mp;
9540 M(CONTROL_PING, control_ping);
9541 S;
9542 }
9543 W;
9544}
9545
9546static void vl_api_map_add_domain_reply_t_handler
9547(vl_api_map_add_domain_reply_t * mp)
9548{
9549 vat_main_t * vam = &vat_main;
9550 i32 retval = ntohl(mp->retval);
9551
9552 if (vam->async_mode) {
9553 vam->async_errors += (retval < 0);
9554 } else {
9555 vam->retval = retval;
9556 vam->result_ready = 1;
9557 }
9558}
9559
9560static void vl_api_map_add_domain_reply_t_handler_json
9561(vl_api_map_add_domain_reply_t * mp)
9562{
9563 vat_main_t * vam = &vat_main;
9564 vat_json_node_t node;
9565
9566 vat_json_init_object(&node);
9567 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
9568 vat_json_object_add_uint(&node, "index", ntohl(mp->index));
9569
9570 vat_json_print(vam->ofp, &node);
9571 vat_json_free(&node);
9572
9573 vam->retval = ntohl(mp->retval);
9574 vam->result_ready = 1;
9575}
9576
9577static int
9578api_get_first_msg_id (vat_main_t * vam)
9579{
9580 vl_api_get_first_msg_id_t * mp;
9581 f64 timeout;
9582 unformat_input_t * i = vam->input;
9583 u8 * name;
9584 u8 name_set = 0;
9585
9586 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9587 if (unformat (i, "client %s", &name))
9588 name_set = 1;
9589 else
9590 break;
9591 }
9592
9593 if (name_set == 0) {
9594 errmsg ("missing client name\n");
9595 return -99;
9596 }
9597 vec_add1 (name, 0);
9598
9599 if (vec_len (name) > 63) {
9600 errmsg ("client name too long\n");
9601 return -99;
9602 }
9603
9604 M(GET_FIRST_MSG_ID, get_first_msg_id);
Damjan Marionf1213b82016-03-13 02:22:06 +01009605 clib_memcpy (mp->name, name, vec_len(name));
Ed Warnickecb9cada2015-12-08 15:45:58 -07009606 S; W;
9607 /* NOTREACHED */
9608 return 0;
9609}
9610
Dave Barachc07bf5d2016-02-17 17:52:26 -05009611static int api_cop_interface_enable_disable (vat_main_t * vam)
9612{
9613 unformat_input_t * line_input = vam->input;
9614 vl_api_cop_interface_enable_disable_t * mp;
9615 f64 timeout;
9616 u32 sw_if_index = ~0;
9617 u8 enable_disable = 1;
9618
9619 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
9620 if (unformat (line_input, "disable"))
9621 enable_disable = 0;
9622 if (unformat (line_input, "enable"))
9623 enable_disable = 1;
9624 else if (unformat (line_input, "%U", unformat_sw_if_index,
9625 vam, &sw_if_index))
9626 ;
9627 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
9628 ;
9629 else
9630 break;
9631 }
9632
9633 if (sw_if_index == ~0) {
9634 errmsg ("missing interface name or sw_if_index\n");
9635 return -99;
9636 }
9637
9638 /* Construct the API message */
9639 M(COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
9640 mp->sw_if_index = ntohl(sw_if_index);
9641 mp->enable_disable = enable_disable;
9642
9643 /* send it... */
9644 S;
9645 /* Wait for the reply */
9646 W;
9647}
9648
9649static int api_cop_whitelist_enable_disable (vat_main_t * vam)
9650{
9651 unformat_input_t * line_input = vam->input;
9652 vl_api_cop_whitelist_enable_disable_t * mp;
9653 f64 timeout;
9654 u32 sw_if_index = ~0;
9655 u8 ip4=0, ip6=0, default_cop=0;
9656 u32 fib_id;
9657
9658 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
9659 if (unformat (line_input, "ip4"))
9660 ip4 = 1;
9661 else if (unformat (line_input, "ip6"))
9662 ip6 = 1;
9663 else if (unformat (line_input, "default"))
9664 default_cop = 1;
9665 else if (unformat (line_input, "%U", unformat_sw_if_index,
9666 vam, &sw_if_index))
9667 ;
9668 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
9669 ;
9670 else if (unformat (line_input, "fib-id %d", &fib_id))
9671 ;
9672 else
9673 break;
9674 }
9675
9676 if (sw_if_index == ~0) {
9677 errmsg ("missing interface name or sw_if_index\n");
9678 return -99;
9679 }
9680
9681 /* Construct the API message */
9682 M(COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
9683 mp->sw_if_index = ntohl(sw_if_index);
9684 mp->fib_id = ntohl(fib_id);
9685 mp->ip4 = ip4;
9686 mp->ip6 = ip6;
9687 mp->default_cop = default_cop;
9688
9689 /* send it... */
9690 S;
9691 /* Wait for the reply */
9692 W;
9693}
9694
Dave Barachb44e9bc2016-02-19 09:06:23 -05009695static int api_get_node_graph (vat_main_t * vam)
9696{
9697 vl_api_get_node_graph_t * mp;
9698 f64 timeout;
9699
9700 M(GET_NODE_GRAPH, get_node_graph);
9701
9702 /* send it... */
9703 S;
9704 /* Wait for the reply */
9705 W;
9706}
9707
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02009708static int
9709api_lisp_add_del_locator_set(vat_main_t * vam)
9710{
9711 unformat_input_t * input = vam->input;
9712 vl_api_lisp_add_del_locator_set_t *mp;
9713 f64 timeout = ~0;
9714 u8 is_add = 1;
9715 u8 *locator_set_name = NULL;
9716 u8 locator_set_name_set = 0;
9717
9718 /* Parse args required to build the message */
9719 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
9720 if (unformat(input, "del")) {
9721 is_add = 0;
9722 } else if (unformat(input, "locator-set %s", &locator_set_name)) {
9723 locator_set_name_set = 1;
9724 } else
9725 break;
9726 }
9727
9728 if (locator_set_name_set == 0) {
9729 errmsg ("missing locator-set name");
9730 return -99;
9731 }
9732
9733 if (vec_len(locator_set_name) > 64) {
9734 errmsg ("locator-set name too long\n");
9735 vec_free(locator_set_name);
9736 return -99;
9737 }
9738 vec_add1(locator_set_name, 0);
9739
9740 /* Construct the API message */
9741 M(LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set);
9742
9743 mp->is_add = is_add;
Damjan Marionf1213b82016-03-13 02:22:06 +01009744 clib_memcpy(mp->locator_set_name, locator_set_name,
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02009745 vec_len(locator_set_name));
9746 vec_free(locator_set_name);
9747
9748 /* send it... */
9749 S;
9750
9751 /* Wait for a reply... */
9752 W;
9753
9754 /* NOTREACHED */
9755 return 0;
9756}
9757
9758static int
9759api_lisp_add_del_locator(vat_main_t * vam)
9760{
9761 unformat_input_t * input = vam->input;
9762 vl_api_lisp_add_del_locator_t *mp;
9763 f64 timeout = ~0;
9764 u32 tmp_if_index = ~0;
9765 u32 sw_if_index = ~0;
9766 u8 sw_if_index_set = 0;
9767 u8 sw_if_index_if_name_set = 0;
9768 u8 priority = ~0;
9769 u8 priority_set = 0;
9770 u8 weight = ~0;
9771 u8 weight_set = 0;
9772 u8 is_add = 1;
9773 u8 *locator_set_name = NULL;
9774 u8 locator_set_name_set = 0;
9775
9776 /* Parse args required to build the message */
9777 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
9778 if (unformat(input, "del")) {
9779 is_add = 0;
9780 } else if (unformat(input, "locator-set %s", &locator_set_name)) {
9781 locator_set_name_set = 1;
9782 } else if (unformat(input, "iface %U", unformat_sw_if_index, vam,
9783 &tmp_if_index)) {
9784 sw_if_index_if_name_set = 1;
9785 sw_if_index = tmp_if_index;
9786 } else if (unformat(input,"sw_if_index %d", &tmp_if_index)) {
9787 sw_if_index_set = 1;
9788 sw_if_index = tmp_if_index;
9789 } else if (unformat(input, "p %d", &priority)) {
9790 priority_set = 1;
9791 } else if (unformat(input, "w %d", &weight)) {
9792 weight_set = 1;
9793 } else
9794 break;
9795 }
9796
9797 if (locator_set_name_set == 0) {
9798 errmsg ("missing locator-set name");
9799 return -99;
9800 }
9801
9802 if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0) {
9803 errmsg ("missing sw_if_index");
9804 vec_free(locator_set_name);
9805 return -99;
9806 }
9807
9808 if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0) {
9809 errmsg ("cannot use both params interface name and sw_if_index");
9810 vec_free(locator_set_name);
9811 return -99;
9812 }
9813
9814 if (priority_set == 0) {
9815 errmsg ("missing locator-set priority\n");
9816 vec_free(locator_set_name);
9817 return -99;
9818 }
9819
9820 if (weight_set == 0) {
9821 errmsg ("missing locator-set weight\n");
9822 vec_free(locator_set_name);
9823 return -99;
9824 }
9825
9826 if (vec_len(locator_set_name) > 64) {
9827 errmsg ("locator-set name too long\n");
9828 vec_free(locator_set_name);
9829 return -99;
9830 }
9831 vec_add1(locator_set_name, 0);
9832
9833 /* Construct the API message */
9834 M(LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
9835
9836 mp->is_add = is_add;
9837 mp->sw_if_index = ntohl(sw_if_index);
9838 mp->priority = priority;
9839 mp->weight = weight;
Damjan Marionf1213b82016-03-13 02:22:06 +01009840 clib_memcpy(mp->locator_set_name, locator_set_name,
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02009841 vec_len(locator_set_name));
9842 vec_free(locator_set_name);
9843
9844 /* send it... */
9845 S;
9846
9847 /* Wait for a reply... */
9848 W;
9849
9850 /* NOTREACHED */
9851 return 0;
9852}
9853
9854static int
9855api_lisp_add_del_local_eid(vat_main_t * vam)
9856{
9857 unformat_input_t * input = vam->input;
9858 vl_api_lisp_add_del_local_eid_t *mp;
9859 f64 timeout = ~0;
9860 u8 is_add = 1;
9861 u8 eidv4_set = 0;
9862 u8 eidv6_set = 0;
9863 ip4_address_t eidv4;
9864 ip6_address_t eidv6;
9865 u8 tmp_eid_lenght = ~0;
9866 u8 eid_lenght = ~0;
9867 u8 *locator_set_name = NULL;
9868 u8 locator_set_name_set = 0;
9869
9870 /* Parse args required to build the message */
9871 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
9872 if (unformat(input, "del")) {
9873 is_add = 0;
9874 } else if (unformat(input, "eid %U/%d", unformat_ip4_address,
9875 &eidv4, &tmp_eid_lenght)) {
9876 eid_lenght = tmp_eid_lenght;
9877 eidv4_set = 1;
9878 } else if (unformat(input, "eid %U/%d", unformat_ip6_address,
9879 &eidv6, &tmp_eid_lenght)) {
9880 eid_lenght = tmp_eid_lenght;
9881 eidv6_set = 1;
9882 } else if (unformat(input, "locator-set %s", &locator_set_name)) {
9883 locator_set_name_set = 1;
9884 } else
9885 break;
9886 }
9887
9888 if (locator_set_name_set == 0) {
9889 errmsg ("missing locator-set name\n");
9890 return -99;
9891 }
9892
9893 if (vec_len(locator_set_name) > 64) {
9894 errmsg ("locator-set name too long\n");
9895 vec_free(locator_set_name);
9896 return -99;
9897 }
9898 vec_add1(locator_set_name, 0);
9899
9900 if (eidv4_set && eidv6_set) {
9901 errmsg ("both eid v4 and v6 addresses set\n");
9902 vec_free(locator_set_name);
9903 return -99;
9904 }
9905
9906 if (!eidv4_set && !eidv6_set) {
9907 errmsg ("eid addresses not set\n");
9908 vec_free(locator_set_name);
9909 return -99;
9910 }
9911
9912 /* Construct the API message */
9913 M(LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
9914
9915 mp->is_add = is_add;
9916 if (eidv6_set) {
9917 mp->is_ipv6 = 1;
Damjan Marionf1213b82016-03-13 02:22:06 +01009918 clib_memcpy(mp->ip_address, &eidv6, sizeof(eidv6));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02009919 } else {
9920 mp->is_ipv6 = 0;
Damjan Marionf1213b82016-03-13 02:22:06 +01009921 clib_memcpy(mp->ip_address, &eidv4, sizeof(eidv4));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02009922 }
9923 mp->prefix_len = eid_lenght;
Damjan Marionf1213b82016-03-13 02:22:06 +01009924 clib_memcpy(mp->locator_set_name, locator_set_name,
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02009925 vec_len(locator_set_name));
9926 vec_free(locator_set_name);
9927
9928 /* send it... */
9929 S;
9930
9931 /* Wait for a reply... */
9932 W;
9933
9934 /* NOTREACHED */
9935 return 0;
9936}
9937
9938static int
9939api_lisp_gpe_add_del_fwd_entry(vat_main_t * vam)
9940{
9941 unformat_input_t * input = vam->input;
9942 vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
9943 f64 timeout = ~0;
9944 u8 is_add = 1;
9945 u8 eidv4_set = 0, slocv4_set = 0, dlocv4_set = 0;
9946 u8 eidv6_set = 0, slocv6_set = 0, dlocv6_set = 0;
9947 ip4_address_t eidv4, slocv4, dlocv4;
9948 ip6_address_t eidv6, slocv6, dlocv6;
9949 u8 tmp_eid_lenght = ~0;
9950 u8 eid_lenght = ~0;
9951
9952 /* Parse args required to build the message */
9953 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
9954 if (unformat(input, "del")) {
9955 is_add = 0;
9956 } else if (unformat(input, "eid %U/%d", unformat_ip4_address,
9957 &eidv4, &tmp_eid_lenght)) {
9958 eid_lenght = tmp_eid_lenght;
9959 eidv4_set = 1;
9960 } else if (unformat(input, "eid %U/%d", unformat_ip6_address,
9961 &eidv6, &tmp_eid_lenght)) {
9962 eid_lenght = tmp_eid_lenght;
9963 eidv6_set = 1;
9964 } else if (unformat(input, "sloc %U", unformat_ip4_address, &slocv4)) {
9965 slocv4_set = 1;
9966 } else if (unformat(input, "sloc %U", unformat_ip6_address, &slocv6)) {
9967 slocv6_set = 1;
9968 } else if (unformat(input, "dloc %U", unformat_ip4_address, &dlocv4)) {
9969 dlocv4_set = 1;
9970 } else if (unformat(input, "dloc %U", unformat_ip6_address, &dlocv6)) {
9971 dlocv6_set = 1;
9972 } else
9973 break;
9974 }
9975
9976 if (eidv4_set && eidv6_set) {
9977 errmsg ("both eid v4 and v6 addresses set\n");
9978 return -99;
9979 }
9980
9981 if (!eidv4_set && !eidv6_set) {
9982 errmsg ("eid addresses not set\n");
9983 return -99;
9984 }
9985
9986 if (slocv4_set && slocv6_set) {
9987 errmsg ("both source v4 and v6 addresses set\n");
9988 return -99;
9989 }
9990
9991 if (!slocv4_set && !slocv6_set) {
9992 errmsg ("source addresses not set\n");
9993 return -99;
9994 }
9995
9996 if (dlocv4_set && dlocv6_set) {
9997 errmsg ("both destination v4 and v6 addresses set\n");
9998 return -99;
9999 }
10000
10001 if (dlocv4_set && dlocv6_set) {
10002 errmsg ("destination addresses not set\n");
10003 return -99;
10004 }
10005
10006 if (!(slocv4_set == dlocv4_set && slocv6_set == dlocv6_set)) {
10007 errmsg ("mixing type of source and destination address\n");
10008 return -99;
10009 }
10010
10011 /* Construct the API message */
10012 M(LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
10013
10014 mp->is_add = is_add;
10015 if (eidv6_set) {
10016 mp->eid_is_ipv6 = 1;
Damjan Marionf1213b82016-03-13 02:22:06 +010010017 clib_memcpy(mp->eid_ip_address, &eidv6, sizeof(eidv6));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010018 } else {
10019 mp->eid_is_ipv6 = 0;
Damjan Marionf1213b82016-03-13 02:22:06 +010010020 clib_memcpy(mp->eid_ip_address, &eidv4, sizeof(eidv4));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010021 }
10022 mp->eid_prefix_len = eid_lenght;
10023 if (slocv6_set) {
10024 mp->address_is_ipv6 = 1;
Damjan Marionf1213b82016-03-13 02:22:06 +010010025 clib_memcpy(mp->source_ip_address, &slocv6, sizeof(slocv6));
10026 clib_memcpy(mp->destination_ip_address, &dlocv6, sizeof(dlocv6));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010027 } else {
10028 mp->address_is_ipv6 = 0;
Damjan Marionf1213b82016-03-13 02:22:06 +010010029 clib_memcpy(mp->source_ip_address, &slocv4, sizeof(slocv4));
10030 clib_memcpy(mp->destination_ip_address, &dlocv4, sizeof(dlocv4));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010031 }
10032
10033 /* send it... */
10034 S;
10035
10036 /* Wait for a reply... */
10037 W;
10038
10039 /* NOTREACHED */
10040 return 0;
10041}
10042
10043static int
10044api_lisp_add_del_map_resolver(vat_main_t * vam)
10045{
10046 unformat_input_t * input = vam->input;
10047 vl_api_lisp_add_del_map_resolver_t *mp;
10048 f64 timeout = ~0;
10049 u8 is_add = 1;
10050 u8 ipv4_set = 0;
10051 u8 ipv6_set = 0;
10052 ip4_address_t ipv4;
10053 ip6_address_t ipv6;
10054
10055 /* Parse args required to build the message */
10056 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
10057 if (unformat(input, "del")) {
10058 is_add = 0;
10059 } else if (unformat(input, "%U", unformat_ip4_address, &ipv4)) {
10060 ipv4_set = 1;
10061 } else if (unformat(input, "%U", unformat_ip6_address, &ipv6)) {
10062 ipv6_set = 1;
10063 } else
10064 break;
10065 }
10066
10067 if (ipv4_set && ipv6_set) {
10068 errmsg ("both eid v4 and v6 addresses set\n");
10069 return -99;
10070 }
10071
10072 if (!ipv4_set && !ipv6_set) {
10073 errmsg ("eid addresses not set\n");
10074 return -99;
10075 }
10076
10077 /* Construct the API message */
10078 M(LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
10079
10080 mp->is_add = is_add;
10081 if (ipv6_set) {
10082 mp->is_ipv6 = 1;
Damjan Marionf1213b82016-03-13 02:22:06 +010010083 clib_memcpy(mp->ip_address, &ipv6, sizeof(ipv6));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010084 } else {
10085 mp->is_ipv6 = 0;
Damjan Marionf1213b82016-03-13 02:22:06 +010010086 clib_memcpy(mp->ip_address, &ipv4, sizeof(ipv4));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010087 }
10088
10089 /* send it... */
10090 S;
10091
10092 /* Wait for a reply... */
10093 W;
10094
10095 /* NOTREACHED */
10096 return 0;
10097}
10098
10099static int
Florin Coras577c3552016-04-21 00:45:40 +020010100api_lisp_gpe_enable_disable (vat_main_t * vam)
10101{
10102 unformat_input_t * input = vam->input;
10103 vl_api_lisp_gpe_enable_disable_t *mp;
10104 f64 timeout = ~0;
10105 u8 is_set = 0;
10106 u8 is_en = 1;
10107
10108 /* Parse args required to build the message */
10109 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
10110 if (unformat(input, "enable")) {
10111 is_set = 1;
10112 is_en = 1;
10113 } else if (unformat(input, "disable")) {
10114 is_set = 1;
10115 is_en = 0;
10116 } else
10117 break;
10118 }
10119
10120 if (is_set == 0) {
10121 errmsg("Value not set\n");
10122 return -99;
10123 }
10124
10125 /* Construct the API message */
10126 M(LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
10127
10128 mp->is_en = is_en;
10129
10130 /* send it... */
10131 S;
10132
10133 /* Wait for a reply... */
10134 W;
10135
10136 /* NOTREACHED */
10137 return 0;
10138}
10139
10140static int
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010141api_lisp_gpe_add_del_iface(vat_main_t * vam)
10142{
10143 unformat_input_t * input = vam->input;
10144 vl_api_lisp_gpe_add_del_iface_t *mp;
10145 f64 timeout = ~0;
10146 u8 is_set = 0;
Florin Coras577c3552016-04-21 00:45:40 +020010147 u8 is_add = 1;
10148 u32 table_id, vni;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010149
10150 /* Parse args required to build the message */
10151 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
10152 if (unformat(input, "up")) {
10153 is_set = 1;
10154 is_add = 1;
10155 } else if (unformat(input, "down")) {
10156 is_set = 1;
10157 is_add = 0;
Florin Coras577c3552016-04-21 00:45:40 +020010158 } else if (unformat(input, "table_id %d", &table_id)) {
10159 ;
10160 } else if (unformat(input, "vni %d", &vni)) {
10161 ;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010162 } else
10163 break;
10164 }
10165
10166 if (is_set == 0) {
10167 errmsg("Value not set\n");
10168 return -99;
10169 }
10170
10171 /* Construct the API message */
10172 M(LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
10173
10174 mp->is_add = is_add;
Florin Coras577c3552016-04-21 00:45:40 +020010175 mp->table_id = table_id;
10176 mp->vni = vni;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010177
10178 /* send it... */
10179 S;
10180
10181 /* Wait for a reply... */
10182 W;
10183
10184 /* NOTREACHED */
10185 return 0;
10186}
10187
10188static int
10189api_lisp_locator_set_dump(vat_main_t *vam)
10190{
10191 vl_api_lisp_locator_set_dump_t *mp;
10192 f64 timeout = ~0;
10193
10194 if (!vam->json_output) {
10195 fformat(vam->ofp, "%=20s%=16s%=16s%=16s\n",
10196 "Locator-set", "Locator", "Priority", "Weight");
10197 }
10198
10199 M(LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
10200 /* send it... */
10201 S;
10202
10203 /* Use a control ping for synchronization */
10204 {
10205 vl_api_control_ping_t * mp;
10206 M(CONTROL_PING, control_ping);
10207 S;
10208 }
10209 /* Wait for a reply... */
10210 W;
10211
10212 /* NOTREACHED */
10213 return 0;
10214}
10215
10216static int
10217api_lisp_local_eid_table_dump(vat_main_t *vam)
10218{
10219 vl_api_lisp_local_eid_table_dump_t *mp;
10220 f64 timeout = ~0;
10221
10222 if (!vam->json_output) {
10223 fformat(vam->ofp, "%=20s%=30s\n",
10224 "Locator-set", "Eid");
10225 }
10226
10227 M(LISP_LOCAL_EID_TABLE_DUMP, lisp_local_eid_table_dump);
10228 /* send it... */
10229 S;
10230
10231 /* Use a control ping for synchronization */
10232 {
10233 vl_api_control_ping_t * mp;
10234 M(CONTROL_PING, control_ping);
10235 S;
10236 }
10237 /* Wait for a reply... */
10238 W;
10239
10240 /* NOTREACHED */
10241 return 0;
10242}
10243
10244static int
10245api_lisp_gpe_tunnel_dump(vat_main_t *vam)
10246{
10247 vl_api_lisp_gpe_tunnel_dump_t *mp;
10248 f64 timeout = ~0;
10249
10250 if (!vam->json_output) {
10251 fformat(vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
10252 "%=16s%=16s%=16s%=16s%=16s\n",
10253 "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
10254 "Decap next", "Lisp version", "Flags", "Next protocol",
10255 "ver_res", "res", "iid");
10256 }
10257
10258 M(LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
10259 /* send it... */
10260 S;
10261
10262 /* Use a control ping for synchronization */
10263 {
10264 vl_api_control_ping_t * mp;
10265 M(CONTROL_PING, control_ping);
10266 S;
10267 }
10268 /* Wait for a reply... */
10269 W;
10270
10271 /* NOTREACHED */
10272 return 0;
10273}
10274
10275static int
10276api_lisp_map_resolver_dump(vat_main_t *vam)
10277{
10278 vl_api_lisp_map_resolver_dump_t *mp;
10279 f64 timeout = ~0;
10280
10281 if (!vam->json_output) {
10282 fformat(vam->ofp, "%=20s\n",
10283 "Map resolver");
10284 }
10285
10286 M(LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
10287 /* send it... */
10288 S;
10289
10290 /* Use a control ping for synchronization */
10291 {
10292 vl_api_control_ping_t * mp;
10293 M(CONTROL_PING, control_ping);
10294 S;
10295 }
10296 /* Wait for a reply... */
10297 W;
10298
10299 /* NOTREACHED */
10300 return 0;
10301}
10302
Ed Warnickecb9cada2015-12-08 15:45:58 -070010303static int q_or_quit (vat_main_t * vam)
10304{
10305 longjmp (vam->jump_buf, 1);
10306 return 0; /* not so much */
10307}
10308static int q (vat_main_t * vam) {return q_or_quit (vam);}
10309static int quit (vat_main_t * vam) {return q_or_quit (vam);}
10310
10311static int comment (vat_main_t * vam)
10312{
10313 return 0;
10314}
10315
Matus Fabiand2dc3df2015-12-14 10:31:33 -050010316static int cmd_cmp (void * a1, void * a2)
10317{
10318 u8 ** c1 = a1;
10319 u8 ** c2 = a2;
10320
10321 return strcmp ((char *)(c1[0]), (char *)(c2[0]));
10322}
10323
Ed Warnickecb9cada2015-12-08 15:45:58 -070010324static int help (vat_main_t * vam)
10325{
10326 u8 ** cmds = 0;
10327 u8 * name = 0;
10328 hash_pair_t * p;
10329 unformat_input_t * i = vam->input;
10330 int j;
10331
10332 if (unformat (i, "%s", &name)) {
10333 uword *hs;
10334
10335 vec_add1(name, 0);
10336
10337 hs = hash_get_mem (vam->help_by_name, name);
10338 if (hs)
10339 fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
10340 else
10341 fformat (vam->ofp, "No such msg / command '%s'\n", name);
10342 vec_free(name);
10343 return 0;
10344 }
10345
10346 fformat(vam->ofp, "Help is available for the following:\n");
10347
10348 hash_foreach_pair (p, vam->function_by_name,
10349 ({
10350 vec_add1 (cmds, (u8 *)(p->key));
10351 }));
10352
Matus Fabiand2dc3df2015-12-14 10:31:33 -050010353 vec_sort_with_function (cmds, cmd_cmp);
Ed Warnickecb9cada2015-12-08 15:45:58 -070010354
10355 for (j = 0; j < vec_len(cmds); j++)
10356 fformat (vam->ofp, "%s\n", cmds[j]);
10357
10358 vec_free (cmds);
10359 return 0;
10360}
10361
10362static int set (vat_main_t * vam)
10363{
10364 u8 * name = 0, * value = 0;
10365 unformat_input_t * i = vam->input;
10366
10367 if (unformat (i, "%s", &name)) {
10368 /* The input buffer is a vector, not a string. */
10369 value = vec_dup (i->buffer);
10370 vec_delete (value, i->index, 0);
10371 /* Almost certainly has a trailing newline */
10372 if (value[vec_len(value)-1] == '\n')
10373 value[vec_len(value)-1] = 0;
10374 /* Make sure it's a proper string, one way or the other */
10375 vec_add1 (value, 0);
10376 (void) clib_macro_set_value (&vam->macro_main,
10377 (char *)name, (char *)value);
10378 }
10379 else
10380 errmsg ("usage: set <name> <value>\n");
10381
10382 vec_free (name);
10383 vec_free (value);
10384 return 0;
10385}
10386
10387static int unset (vat_main_t * vam)
10388{
10389 u8 * name = 0;
10390
10391 if (unformat (vam->input, "%s", &name))
10392 if (clib_macro_unset (&vam->macro_main, (char *)name) == 1)
10393 errmsg ("unset: %s wasn't set\n", name);
10394 vec_free (name);
10395 return 0;
10396}
10397
10398typedef struct {
10399 u8 * name;
10400 u8 * value;
10401} macro_sort_t;
10402
10403
Matus Fabiand2dc3df2015-12-14 10:31:33 -050010404static int macro_sort_cmp (void * a1, void * a2)
10405{
10406 macro_sort_t * s1 = a1;
10407 macro_sort_t * s2 = a2;
10408
10409 return strcmp ((char *)(s1->name), (char *)(s2->name));
10410}
10411
Ed Warnickecb9cada2015-12-08 15:45:58 -070010412static int dump_macro_table (vat_main_t * vam)
10413{
10414 macro_sort_t * sort_me = 0, * sm;
10415 int i;
10416 hash_pair_t * p;
10417
10418 hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
10419 ({
10420 vec_add2 (sort_me, sm, 1);
10421 sm->name = (u8 *)(p->key);
10422 sm->value = (u8 *) (p->value[0]);
10423 }));
10424
Matus Fabiand2dc3df2015-12-14 10:31:33 -050010425 vec_sort_with_function (sort_me, macro_sort_cmp);
Ed Warnickecb9cada2015-12-08 15:45:58 -070010426
10427 if (vec_len(sort_me))
10428 fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
10429 else
10430 fformat (vam->ofp, "The macro table is empty...\n");
10431
10432 for (i = 0; i < vec_len (sort_me); i++)
10433 fformat (vam->ofp, "%-15s%s\n", sort_me[i].name,
10434 sort_me[i].value);
10435 return 0;
10436}
10437
Dave Barachb44e9bc2016-02-19 09:06:23 -050010438static int dump_node_table (vat_main_t * vam)
10439{
10440 int i, j;
10441 vlib_node_t * node, * next_node;
10442
10443 if (vec_len (vam->graph_nodes) == 0) {
10444 fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
10445 return 0;
10446 }
10447
10448 for (i = 0; i < vec_len (vam->graph_nodes); i++) {
10449 node = vam->graph_nodes[i];
10450 fformat (vam->ofp, "[%d] %s\n", i, node->name);
10451 for (j = 0; j < vec_len (node->next_nodes); j++) {
10452 if (node->next_nodes[j] != ~0) {
10453 next_node = vam->graph_nodes[node->next_nodes[j]];
10454 fformat (vam->ofp, " [%d] %s\n", j, next_node->name);
10455 }
10456 }
10457 }
10458 return 0;
10459}
10460
10461static int search_node_table (vat_main_t * vam)
10462{
10463 unformat_input_t * line_input = vam->input;
10464 u8 * node_to_find;
10465 int j;
10466 vlib_node_t * node, * next_node;
10467 uword * p;
10468
10469 if (vam->graph_node_index_by_name == 0) {
10470 fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
10471 return 0;
10472 }
10473
10474 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
10475 if (unformat (line_input, "%s", &node_to_find)) {
10476 vec_add1 (node_to_find, 0);
10477 p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
10478 if (p == 0) {
10479 fformat (vam->ofp, "%s not found...\n", node_to_find);
10480 goto out;
10481 }
10482 node = vam->graph_nodes[p[0]];
10483 fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
10484 for (j = 0; j < vec_len (node->next_nodes); j++) {
10485 if (node->next_nodes[j] != ~0) {
10486 next_node = vam->graph_nodes[node->next_nodes[j]];
10487 fformat (vam->ofp, " [%d] %s\n", j, next_node->name);
10488 }
10489 }
10490 }
10491
10492 else {
10493 clib_warning ("parse error '%U'", format_unformat_error,
10494 line_input);
10495 return -99;
10496 }
10497
10498 out:
10499 vec_free(node_to_find);
10500
10501 }
10502
10503 return 0;
10504}
10505
10506
Ed Warnickecb9cada2015-12-08 15:45:58 -070010507static int script (vat_main_t * vam)
10508{
10509 u8 * s = 0;
10510 char * save_current_file;
10511 unformat_input_t save_input;
10512 jmp_buf save_jump_buf;
10513 u32 save_line_number;
10514
10515 FILE * new_fp, * save_ifp;
10516
10517 if (unformat (vam->input, "%s", &s)) {
10518 new_fp = fopen ((char *)s, "r");
10519 if (new_fp == 0) {
10520 errmsg ("Couldn't open script file %s\n", s);
10521 vec_free (s);
10522 return -99;
10523 }
10524 } else {
10525 errmsg ("Missing script name\n");
10526 return -99;
10527 }
10528
Damjan Marionf1213b82016-03-13 02:22:06 +010010529 clib_memcpy (&save_input, &vam->input, sizeof (save_input));
10530 clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
Ed Warnickecb9cada2015-12-08 15:45:58 -070010531 save_ifp = vam->ifp;
10532 save_line_number = vam->input_line_number;
10533 save_current_file = (char *) vam->current_file;
10534
10535 vam->input_line_number = 0;
10536 vam->ifp = new_fp;
10537 vam->current_file = s;
10538 do_one_file (vam);
10539
Damjan Marionf1213b82016-03-13 02:22:06 +010010540 clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
10541 clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
Ed Warnickecb9cada2015-12-08 15:45:58 -070010542 vam->ifp = save_ifp;
10543 vam->input_line_number = save_line_number;
10544 vam->current_file = (u8 *) save_current_file;
10545 vec_free (s);
10546
10547 return 0;
10548}
10549
10550static int echo (vat_main_t * vam)
10551{
10552 fformat (vam->ofp, "%v", vam->input->buffer);
10553 return 0;
10554}
10555
10556/* List of API message constructors, CLI names map to api_xxx */
10557#define foreach_vpe_api_msg \
10558_(create_loopback,"[mac <mac-addr>]") \
10559_(sw_interface_dump,"") \
10560_(sw_interface_set_flags, \
10561 "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
10562_(sw_interface_add_del_address, \
10563 "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
10564_(sw_interface_set_table, \
10565 "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]") \
10566_(sw_interface_set_vpath, \
10567 "<intfc> | sw_if_index <id> enable | disable") \
10568_(sw_interface_set_l2_xconnect, \
10569 "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
10570 "enable | disable") \
10571_(sw_interface_set_l2_bridge, \
10572 "rx <intfc> | rx_sw_if_index <id> bd_id <bridge-domain-id>\n" \
10573 "[shg <split-horizon-group>] [bvi]\n" \
10574 "enable | disable") \
10575_(bridge_domain_add_del, \
10576 "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
10577_(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n") \
10578_(l2fib_add_del, \
10579 "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi]\n") \
10580_(l2_flags, \
10581 "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
10582_(bridge_flags, \
10583 "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
10584_(tap_connect, \
10585 "tapname <name> mac <mac-addr> | random-mac") \
10586_(tap_modify, \
10587 "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
10588_(tap_delete, \
10589 "<vpp-if-name> | sw_if_index <id>") \
10590_(sw_interface_tap_dump, "") \
10591_(ip_add_del_route, \
10592 "<addr>/<mask> via <addr> [vrf <n>]\n" \
10593 "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n" \
10594 "[weight <n>] [drop] [local] [classify <n>] [del]\n" \
10595 "[multipath] [count <n>]") \
10596_(proxy_arp_add_del, \
10597 "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]") \
10598_(proxy_arp_intfc_enable_disable, \
10599 "<intfc> | sw_if_index <id> enable | disable") \
10600_(mpls_add_del_encap, \
10601 "label <n> dst <ip4-addr> [vrf <n>] [del]") \
10602_(mpls_add_del_decap, \
10603 "label <n> [rx_vrf_id <n>] [tx_vrf_id] [s-bit-clear][del]") \
10604_(mpls_gre_add_del_tunnel, \
10605 "inner_vrf_id <n> outer_vrf_id <n> src <ip4-address> dst <ip4-address>\n" \
10606 "adj <ip4-address>/<mask-width> [del]") \
10607_(sw_interface_set_unnumbered, \
10608 "<intfc> | sw_if_index <id> unnum_if_index <id> [del]") \
10609_(ip_neighbor_add_del, \
10610 "<intfc> | sw_if_index <id> dst <ip46-address> mac <mac-addr>") \
10611_(reset_vrf, "vrf <id> [ipv6]") \
10612_(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>") \
10613_(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n" \
10614 "[outer_vlan_id <n>][inner_vlan_id <n>]\n" \
10615 "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n" \
10616 "[outer_vlan_id_any][inner_vlan_id_any]") \
10617_(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]") \
10618_(reset_fib, "vrf <n> [ipv6]") \
10619_(dhcp_proxy_config, \
10620 "svr <v46-address> src <v46-address>\n" \
10621 "insert-cid <n> [del]") \
10622_(dhcp_proxy_config_2, \
10623 "svr <v46-address> src <v46-address>\n" \
10624 "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]") \
10625_(dhcp_proxy_set_vss, \
10626 "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]") \
10627_(dhcp_client_config, \
10628 "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
10629_(set_ip_flow_hash, \
10630 "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]") \
10631_(sw_interface_ip6_enable_disable, \
10632 "<intfc> | sw_if_index <id> enable | disable") \
10633_(sw_interface_ip6_set_link_local_address, \
10634 "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>") \
10635_(sw_interface_ip6nd_ra_prefix, \
10636 "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n" \
10637 "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n" \
10638 "[nolink] [isno]") \
10639_(sw_interface_ip6nd_ra_config, \
10640 "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n" \
10641 "[life <n>] [count <n>] [interval <n>] [surpress]\n" \
10642 "[managed] [other] [ll] [send] [cease] [isno] [def]") \
10643_(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]") \
10644_(l2_patch_add_del, \
10645 "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
10646 "enable | disable") \
10647_(mpls_ethernet_add_del_tunnel, \
10648 "tx <intfc> | tx_sw_if_index <n> dst <mac-addr>\n" \
10649 "adj <ip4-addr>/<mw> dst <mac-addr> [del]") \
10650_(mpls_ethernet_add_del_tunnel_2, \
10651 "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n" \
10652 "resolve-attempts <n> resolve-if-needed 0 | 1 [del]") \
10653_(sr_tunnel_add_del, \
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -070010654 "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n" \
10655 "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n" \
10656 "[policy <policy_name>]") \
10657_(sr_policy_add_del, \
10658 "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]") \
10659_(sr_multicast_map_add_del, \
10660 "address [ip6 multicast address] sr-policy [policy name] [del]") \
Ed Warnickecb9cada2015-12-08 15:45:58 -070010661_(classify_add_del_table, \
10662 "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n" \
10663 "[del] mask <mask-value>\n" \
10664 " [l2-miss-next | miss-next | acl-miss-next] <name|nn>") \
10665_(classify_add_del_session, \
10666 "[hit-next|l2-hit-next|acl-hit-next] <name|nn> table-index <nn>\n" \
10667 "skip_n <nn> match_n <nn> match [hex] [l2] [l3 [ip4|ip6]]") \
10668_(classify_set_interface_ip_table, \
10669 "<intfc> | sw_if_index <nn> table <nn>") \
10670_(classify_set_interface_l2_tables, \
10671 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
10672 " [other-table <nn>]") \
10673_(get_node_index, "node <node-name") \
10674_(add_node_next, "node <node-name> next <next-node-name>") \
10675_(l2tpv3_create_tunnel, \
10676 "client_address <ip6-addr> our_address <ip6-addr>\n" \
10677 "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
10678 "[remote_cookie <nn>]\n[l2-sublayer-preset]\n") \
10679_(l2tpv3_set_tunnel_cookies, \
10680 "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n" \
10681 "[new_remote_cookie <nn>]\n") \
10682_(l2tpv3_interface_enable_disable, \
10683 "<intfc> | sw_if_index <nn> enable | disable") \
10684_(l2tpv3_set_lookup_key, \
10685 "lookup_v6_src | lookup_v6_dst | lookup_session_id") \
10686_(sw_if_l2tpv3_tunnel_dump, "") \
10687_(vxlan_add_del_tunnel, \
Chris Luke27fe48f2016-04-28 13:44:38 -040010688 "src <ip4-addr> dst <ip4-addr> vni <vni> [encap-vrf-id <nn>]\n" \
Ed Warnickecb9cada2015-12-08 15:45:58 -070010689 " [decap-next l2|ip4|ip6] [del]") \
Dave Wallace60231f32015-12-17 21:04:30 -050010690_(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
Chris Luke27fe48f2016-04-28 13:44:38 -040010691_(gre_add_del_tunnel, \
10692 "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [del]\n") \
10693_(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
Ed Warnickecb9cada2015-12-08 15:45:58 -070010694_(l2_fib_clear_table, "") \
10695_(l2_interface_efp_filter, "sw_if_index <nn> enable | disable") \
10696_(l2_interface_vlan_tag_rewrite, \
10697 "<intfc> | sw_if_index <nn> \n" \
10698 "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n" \
10699 "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>") \
10700_(create_vhost_user_if, \
Pierre Pfisteref65cb02016-02-19 13:52:44 +000010701 "socket <filename> [server] [renumber <dev_instance>] " \
10702 "[mac <mac_address>]") \
Ed Warnickecb9cada2015-12-08 15:45:58 -070010703_(modify_vhost_user_if, \
10704 "<intfc> | sw_if_index <nn> socket <filename>\n" \
10705 "[server] [renumber <dev_instance>]") \
10706_(delete_vhost_user_if, "<intfc> | sw_if_index <nn>") \
10707_(sw_interface_vhost_user_dump, "") \
10708_(show_version, "") \
10709_(nsh_gre_add_del_tunnel, \
10710 "src <ip4-addr> dst <ip4-addr>" \
10711 "c1 <nn> c2 <nn> c3 <nn> c4 <nn> spi <nn> si <nn>\n" \
10712 "[encap-fib-id <nn>] [decap-fib-id <nn>] [o-bit <1|0>]\n" \
10713 "[c-bit <1|0>] [md-type <nn>][next-ip4][next-ip6][next-ethernet]\n" \
10714 "[tlv <xx>][del]") \
10715_(nsh_vxlan_gpe_add_del_tunnel, \
10716 "src <ip4-addr> dst <ip4-addr> vni <nn>\n" \
10717 "c1 <nn> c2 <nn> c3 <nn> c4 <nn> spi <nn> si <nn>\n" \
10718 "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [o-bit <1|0>]\n" \
10719 "[c-bit <1|0>] [md-type <nn>][next-ip4][next-ip6][next-ethernet]\n" \
10720 "[tlv <xx>][del]") \
10721_(l2_fib_table_dump, "bd_id <bridge-domain-id>") \
10722_(lisp_gpe_add_del_tunnel, \
10723 "src <ip4-addr> dst <ip4-addr> iid <nn>|iidx <0xnn>\n" \
10724 "[encap-vrf-id <nn>] [decap-vrf-id <nn>]\n" \
10725 "[n-bit][l-bit][e-bit][v-bit][i-bit][p-bit][not-p-bit][o-bit]\n" \
10726 "[next-ip4][next-ip6][next-ethernet][next-nsh]\n" \
10727 "[decap-next [ip4|ip6|ethernet|nsh-encap|<nn>]][del]") \
10728_(interface_name_renumber, \
10729 "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>") \
10730_(input_acl_set_interface, \
10731 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
10732 " [l2-table <nn>] [del]") \
10733_(want_ip4_arp_events, "address <ip4-address> [del]") \
10734_(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)") \
10735_(ip_dump, "ipv4 | ipv6") \
10736_(ipsec_spd_add_del, "spd_id <n> [del]") \
10737_(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n" \
10738 " spid_id <n> ") \
10739_(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n" \
10740 " crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n" \
10741 " integ_alg <alg> integ_key <hex>") \
10742_(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n" \
10743 " (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n" \
10744 " laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
10745 " [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
10746_(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>") \
Matus Fabiane5f42fe2016-04-08 11:18:08 +020010747_(ikev2_profile_add_del, "name <profile_name> [del]") \
10748_(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n" \
10749 "(auth_data 0x<data> | auth_data <data>)") \
10750_(ikev2_profile_set_id, "name <profile_name> id_type <type>\n" \
10751 "(id_data 0x<data> | id_data <data>) (local|remote)") \
10752_(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n" \
10753 "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
10754 "(local|remote)") \
10755_(ikev2_set_local_key, "file <absolute_file_path>") \
Ed Warnickecb9cada2015-12-08 15:45:58 -070010756_(delete_loopback,"sw_if_index <nn>") \
10757_(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
10758_(map_add_domain, \
10759 "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> " \
10760 "ip6-src <ip6addr> " \
10761 "ea-bits-len <n> psid-offset <n> psid-len <n>") \
10762_(map_del_domain, "index <n>") \
10763_(map_add_del_rule, \
10764 "index <n> psid <n> dst <ip6addr> [del]") \
10765_(map_domain_dump, "") \
10766_(map_rule_dump, "index <map-domain>") \
10767_(want_interface_events, "enable|disable") \
10768_(want_stats,"enable|disable") \
Dave Barachc07bf5d2016-02-17 17:52:26 -050010769_(get_first_msg_id, "client <name>") \
10770_(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
10771_(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n" \
Dave Barachb44e9bc2016-02-19 09:06:23 -050010772 "fib-id <nn> [ip4][ip6][default]") \
Pavel Kotucek00bbf272016-03-03 13:27:11 +010010773_(get_node_graph, " ") \
Shwetha20a64f52016-03-25 10:55:01 +000010774_(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>") \
10775_(trace_profile_add, "id <nn> trace-type <0x1f|0x3|0x9|0x11|0x19> " \
10776 "trace-elts <nn> trace-tsp <0|1|2|3> node-id <node id in hex> " \
10777 "app-data <app_data in hex> [pow] [ppc <encap|decap>]") \
10778_(trace_profile_apply, "id <nn> <ip6-address>/<width>" \
10779 " vrf_id <nn> add | pop | none") \
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010780_(trace_profile_del, "") \
10781_(lisp_add_del_locator_set, "locator-set <locator_name> [del]") \
10782_(lisp_add_del_locator, "locator-set <locator_name> " \
10783 "iface <intf> | sw_if_index <sw_if_index> " \
10784 "p <priority> w <weight> [del]") \
10785_(lisp_add_del_local_eid, "<ipv4|ipv6>/<prefix> " \
10786 "locator-set <locator_name> [del]") \
10787_(lisp_gpe_add_del_fwd_entry, "eid <ip4|6-addr>/<prefix> " \
10788 "sloc <ip4/6-addr> dloc <ip4|6-addr> [del]") \
10789_(lisp_add_del_map_resolver, "<ip4|6-addr> [del]") \
Florin Coras577c3552016-04-21 00:45:40 +020010790_(lisp_gpe_enable_disable, "enable|disable") \
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010791_(lisp_gpe_add_del_iface, "up|down") \
10792_(lisp_locator_set_dump, "") \
10793_(lisp_local_eid_table_dump, "") \
10794_(lisp_gpe_tunnel_dump, "") \
10795_(lisp_map_resolver_dump, "")
Ed Warnickecb9cada2015-12-08 15:45:58 -070010796
10797/* List of command functions, CLI names map directly to functions */
10798#define foreach_cli_function \
10799_(comment, "usage: comment <ignore-rest-of-line>") \
10800_(dump_interface_table, "usage: dump_interface_table") \
10801_(dump_sub_interface_table, "usage: dump_sub_interface_table") \
10802_(dump_ipv4_table, "usage: dump_ipv4_table") \
10803_(dump_ipv6_table, "usage: dump_ipv6_table") \
10804_(dump_stats_table, "usage: dump_stats_table") \
10805_(dump_macro_table, "usage: dump_macro_table ") \
Dave Barachb44e9bc2016-02-19 09:06:23 -050010806_(dump_node_table, "usage: dump_node_table") \
Ed Warnickecb9cada2015-12-08 15:45:58 -070010807_(echo, "usage: echo <message>") \
10808_(exec, "usage: exec <vpe-debug-CLI-command>") \
10809_(help, "usage: help") \
10810_(q, "usage: quit") \
10811_(quit, "usage: quit") \
Dave Barachb44e9bc2016-02-19 09:06:23 -050010812_(search_node_table, "usage: search_node_table <name>...") \
Ed Warnickecb9cada2015-12-08 15:45:58 -070010813_(set, "usage: set <variable-name> <value>") \
10814_(script, "usage: script <file-name>") \
10815_(unset, "usage: unset <variable-name>")
10816
10817#define _(N,n) \
10818 static void vl_api_##n##_t_handler_uni \
10819 (vl_api_##n##_t * mp) \
10820 { \
10821 vat_main_t * vam = &vat_main; \
10822 if (vam->json_output) { \
10823 vl_api_##n##_t_handler_json(mp); \
10824 } else { \
10825 vl_api_##n##_t_handler(mp); \
10826 } \
10827 }
10828foreach_vpe_api_reply_msg;
10829#undef _
10830
10831void vat_api_hookup (vat_main_t *vam)
10832{
10833#define _(N,n) \
10834 vl_msg_api_set_handlers(VL_API_##N, #n, \
10835 vl_api_##n##_t_handler_uni, \
10836 vl_noop_handler, \
10837 vl_api_##n##_t_endian, \
10838 vl_api_##n##_t_print, \
10839 sizeof(vl_api_##n##_t), 1);
10840 foreach_vpe_api_reply_msg;
10841#undef _
10842
10843 vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
10844
10845 vam->sw_if_index_by_interface_name =
10846 hash_create_string (0, sizeof (uword));
10847
10848 vam->function_by_name =
10849 hash_create_string (0, sizeof(uword));
10850
10851 vam->help_by_name =
10852 hash_create_string (0, sizeof(uword));
10853
10854 /* API messages we can send */
10855#define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
10856 foreach_vpe_api_msg;
10857#undef _
10858
10859 /* Help strings */
10860#define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
10861 foreach_vpe_api_msg;
10862#undef _
10863
10864 /* CLI functions */
10865#define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
10866 foreach_cli_function;
10867#undef _
10868
10869 /* Help strings */
10870#define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
10871 foreach_cli_function;
10872#undef _
10873}
10874
10875#undef vl_api_version
10876#define vl_api_version(n,v) static u32 vpe_api_version = v;
10877#include <api/vpe.api.h>
10878#undef vl_api_version
10879
10880void vl_client_add_api_signatures (vl_api_memclnt_create_t *mp)
10881{
10882 /*
10883 * Send the main API signature in slot 0. This bit of code must
10884 * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
10885 */
10886 mp->api_versions[0] = clib_host_to_net_u32 (vpe_api_version);
10887}