blob: 37af449f371e1998f865c0b32bf2631d1ab54df8 [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
Andrej Kozemcaka9edd852016-05-02 12:14:33 +02002116static void
2117vl_api_lisp_gpe_enable_disable_status_details_t_handler
2118(vl_api_lisp_gpe_enable_disable_status_details_t *mp)
2119{
2120 vat_main_t *vam = &vat_main;
2121
2122 fformat(vam->ofp, "%=20s\n",
2123 mp->is_en ? "enable" : "disable");
2124}
2125
2126static void
2127vl_api_lisp_gpe_enable_disable_status_details_t_handler_json
2128(vl_api_lisp_gpe_enable_disable_status_details_t *mp)
2129{
2130 vat_main_t *vam = &vat_main;
2131 vat_json_node_t *node = NULL;
2132 u8 *str = NULL;
2133
2134 str = format(0, "%s", mp->is_en ? "enable" : "disable");
2135
2136 if (VAT_JSON_ARRAY != vam->json_tree.type) {
2137 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
2138 vat_json_init_array(&vam->json_tree);
2139 }
2140 node = vat_json_array_add(&vam->json_tree);
2141
2142 vat_json_init_object(node);
2143 vat_json_object_add_string_copy(node, "lisp_gpe", str);
2144}
2145
Ed Warnickecb9cada2015-12-08 15:45:58 -07002146#define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
2147#define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
2148#define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
2149#define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
2150
2151/*
2152 * Generate boilerplate reply handlers, which
2153 * dig the return value out of the xxx_reply_t API message,
2154 * stick it into vam->retval, and set vam->result_ready
2155 *
2156 * Could also do this by pointing N message decode slots at
2157 * a single function, but that could break in subtle ways.
2158 */
2159
2160#define foreach_standard_reply_retval_handler \
2161_(sw_interface_set_flags_reply) \
2162_(sw_interface_add_del_address_reply) \
2163_(sw_interface_set_table_reply) \
2164_(sw_interface_set_vpath_reply) \
2165_(sw_interface_set_l2_bridge_reply) \
2166_(bridge_domain_add_del_reply) \
2167_(sw_interface_set_l2_xconnect_reply) \
2168_(l2fib_add_del_reply) \
2169_(ip_add_del_route_reply) \
2170_(proxy_arp_add_del_reply) \
2171_(proxy_arp_intfc_enable_disable_reply) \
2172_(mpls_add_del_encap_reply) \
2173_(mpls_add_del_decap_reply) \
2174_(mpls_ethernet_add_del_tunnel_2_reply) \
2175_(sw_interface_set_unnumbered_reply) \
2176_(ip_neighbor_add_del_reply) \
2177_(reset_vrf_reply) \
2178_(oam_add_del_reply) \
2179_(reset_fib_reply) \
2180_(dhcp_proxy_config_reply) \
2181_(dhcp_proxy_config_2_reply) \
2182_(dhcp_proxy_set_vss_reply) \
2183_(dhcp_client_config_reply) \
2184_(set_ip_flow_hash_reply) \
2185_(sw_interface_ip6_enable_disable_reply) \
2186_(sw_interface_ip6_set_link_local_address_reply) \
2187_(sw_interface_ip6nd_ra_prefix_reply) \
2188_(sw_interface_ip6nd_ra_config_reply) \
2189_(set_arp_neighbor_limit_reply) \
2190_(l2_patch_add_del_reply) \
2191_(sr_tunnel_add_del_reply) \
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07002192_(sr_policy_add_del_reply) \
2193_(sr_multicast_map_add_del_reply) \
Ed Warnickecb9cada2015-12-08 15:45:58 -07002194_(classify_add_del_session_reply) \
2195_(classify_set_interface_ip_table_reply) \
2196_(classify_set_interface_l2_tables_reply) \
2197_(l2tpv3_set_tunnel_cookies_reply) \
2198_(l2tpv3_interface_enable_disable_reply) \
2199_(l2tpv3_set_lookup_key_reply) \
2200_(l2_fib_clear_table_reply) \
2201_(l2_interface_efp_filter_reply) \
2202_(l2_interface_vlan_tag_rewrite_reply) \
2203_(modify_vhost_user_if_reply) \
2204_(delete_vhost_user_if_reply) \
2205_(want_ip4_arp_events_reply) \
2206_(input_acl_set_interface_reply) \
2207_(ipsec_spd_add_del_reply) \
2208_(ipsec_interface_add_del_spd_reply) \
2209_(ipsec_spd_add_del_entry_reply) \
2210_(ipsec_sad_add_del_entry_reply) \
2211_(ipsec_sa_set_key_reply) \
Matus Fabiane5f42fe2016-04-08 11:18:08 +02002212_(ikev2_profile_add_del_reply) \
2213_(ikev2_profile_set_auth_reply) \
2214_(ikev2_profile_set_id_reply) \
2215_(ikev2_profile_set_ts_reply) \
2216_(ikev2_set_local_key_reply) \
Ed Warnickecb9cada2015-12-08 15:45:58 -07002217_(delete_loopback_reply) \
2218_(bd_ip_mac_add_del_reply) \
2219_(map_del_domain_reply) \
2220_(map_add_del_rule_reply) \
2221_(want_interface_events_reply) \
Dave Barachc07bf5d2016-02-17 17:52:26 -05002222_(want_stats_reply) \
2223_(cop_interface_enable_disable_reply) \
Pavel Kotucek00bbf272016-03-03 13:27:11 +01002224_(cop_whitelist_enable_disable_reply) \
Shwetha20a64f52016-03-25 10:55:01 +00002225_(sw_interface_clear_stats_reply) \
2226_(trace_profile_add_reply) \
2227_(trace_profile_apply_reply) \
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002228_(trace_profile_del_reply) \
2229_(lisp_add_del_locator_set_reply) \
2230_(lisp_add_del_locator_reply) \
2231_(lisp_add_del_local_eid_reply) \
2232_(lisp_gpe_add_del_fwd_entry_reply) \
2233_(lisp_add_del_map_resolver_reply) \
Florin Coras577c3552016-04-21 00:45:40 +02002234_(lisp_gpe_enable_disable_reply) \
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002235_(lisp_gpe_add_del_iface_reply)
Ed Warnickecb9cada2015-12-08 15:45:58 -07002236
2237#define _(n) \
2238 static void vl_api_##n##_t_handler \
2239 (vl_api_##n##_t * mp) \
2240 { \
2241 vat_main_t * vam = &vat_main; \
2242 i32 retval = ntohl(mp->retval); \
2243 if (vam->async_mode) { \
2244 vam->async_errors += (retval < 0); \
2245 } else { \
2246 vam->retval = retval; \
2247 vam->result_ready = 1; \
2248 } \
2249 }
2250foreach_standard_reply_retval_handler;
2251#undef _
2252
2253#define _(n) \
2254 static void vl_api_##n##_t_handler_json \
2255 (vl_api_##n##_t * mp) \
2256 { \
2257 vat_main_t * vam = &vat_main; \
2258 vat_json_node_t node; \
2259 vat_json_init_object(&node); \
2260 vat_json_object_add_int(&node, "retval", ntohl(mp->retval)); \
2261 vat_json_print(vam->ofp, &node); \
2262 vam->retval = ntohl(mp->retval); \
2263 vam->result_ready = 1; \
2264 }
2265foreach_standard_reply_retval_handler;
2266#undef _
2267
2268/*
2269 * Table of message reply handlers, must include boilerplate handlers
2270 * we just generated
2271 */
2272
2273#define foreach_vpe_api_reply_msg \
2274_(CREATE_LOOPBACK_REPLY, create_loopback_reply) \
2275_(SW_INTERFACE_DETAILS, sw_interface_details) \
2276_(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags) \
2277_(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply) \
2278_(CONTROL_PING_REPLY, control_ping_reply) \
2279_(CLI_REPLY, cli_reply) \
2280_(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY, \
2281 sw_interface_add_del_address_reply) \
2282_(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply) \
2283_(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply) \
2284_(SW_INTERFACE_SET_L2_XCONNECT_REPLY, \
2285 sw_interface_set_l2_xconnect_reply) \
2286_(SW_INTERFACE_SET_L2_BRIDGE_REPLY, \
2287 sw_interface_set_l2_bridge_reply) \
2288_(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply) \
2289_(BRIDGE_DOMAIN_DETAILS, bridge_domain_details) \
2290_(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details) \
2291_(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply) \
2292_(L2_FLAGS_REPLY, l2_flags_reply) \
2293_(BRIDGE_FLAGS_REPLY, bridge_flags_reply) \
2294_(TAP_CONNECT_REPLY, tap_connect_reply) \
2295_(TAP_MODIFY_REPLY, tap_modify_reply) \
2296_(TAP_DELETE_REPLY, tap_delete_reply) \
2297_(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details) \
2298_(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply) \
2299_(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply) \
2300_(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY, \
2301 proxy_arp_intfc_enable_disable_reply) \
2302_(MPLS_ADD_DEL_ENCAP_REPLY, mpls_add_del_encap_reply) \
2303_(MPLS_ADD_DEL_DECAP_REPLY, mpls_add_del_decap_reply) \
2304_(MPLS_GRE_ADD_DEL_TUNNEL_REPLY, mpls_gre_add_del_tunnel_reply) \
2305_(MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY, \
2306 mpls_ethernet_add_del_tunnel_reply) \
2307_(MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY, \
2308 mpls_ethernet_add_del_tunnel_2_reply) \
2309_(SW_INTERFACE_SET_UNNUMBERED_REPLY, \
2310 sw_interface_set_unnumbered_reply) \
2311_(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply) \
2312_(RESET_VRF_REPLY, reset_vrf_reply) \
2313_(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply) \
2314_(CREATE_SUBIF_REPLY, create_subif_reply) \
2315_(OAM_ADD_DEL_REPLY, oam_add_del_reply) \
2316_(RESET_FIB_REPLY, reset_fib_reply) \
2317_(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply) \
2318_(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply) \
2319_(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply) \
2320_(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply) \
2321_(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply) \
2322_(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY, \
2323 sw_interface_ip6_enable_disable_reply) \
2324_(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY, \
2325 sw_interface_ip6_set_link_local_address_reply) \
2326_(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY, \
2327 sw_interface_ip6nd_ra_prefix_reply) \
2328_(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY, \
2329 sw_interface_ip6nd_ra_config_reply) \
2330_(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply) \
2331_(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply) \
2332_(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply) \
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07002333_(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply) \
2334_(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply) \
Ed Warnickecb9cada2015-12-08 15:45:58 -07002335_(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply) \
2336_(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply) \
2337_(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY, \
2338classify_set_interface_ip_table_reply) \
2339_(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY, \
2340 classify_set_interface_l2_tables_reply) \
2341_(GET_NODE_INDEX_REPLY, get_node_index_reply) \
2342_(ADD_NODE_NEXT_REPLY, add_node_next_reply) \
2343_(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply) \
2344_(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply) \
2345_(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY, \
2346 l2tpv3_interface_enable_disable_reply) \
2347_(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply) \
2348_(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details) \
2349_(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply) \
Dave Wallace60231f32015-12-17 21:04:30 -05002350_(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details) \
Chris Luke27fe48f2016-04-28 13:44:38 -04002351_(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply) \
2352_(GRE_TUNNEL_DETAILS, gre_tunnel_details) \
Ed Warnickecb9cada2015-12-08 15:45:58 -07002353_(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply) \
2354_(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply) \
2355_(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
2356_(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details) \
2357_(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply) \
2358_(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply) \
2359_(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply) \
2360_(SHOW_VERSION_REPLY, show_version_reply) \
2361_(NSH_GRE_ADD_DEL_TUNNEL_REPLY, nsh_gre_add_del_tunnel_reply) \
2362_(L2_FIB_TABLE_ENTRY, l2_fib_table_entry) \
2363_(NSH_VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, nsh_vxlan_gpe_add_del_tunnel_reply) \
2364_(LISP_GPE_ADD_DEL_TUNNEL_REPLY, lisp_gpe_add_del_tunnel_reply) \
2365_(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply) \
2366_(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply) \
2367_(IP4_ARP_EVENT, ip4_arp_event) \
2368_(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply) \
2369_(IP_ADDRESS_DETAILS, ip_address_details) \
2370_(IP_DETAILS, ip_details) \
2371_(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply) \
2372_(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
2373_(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply) \
2374_(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply) \
2375_(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply) \
Matus Fabiane5f42fe2016-04-08 11:18:08 +02002376_(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply) \
2377_(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply) \
2378_(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply) \
2379_(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply) \
2380_(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply) \
Ed Warnickecb9cada2015-12-08 15:45:58 -07002381_(DELETE_LOOPBACK_REPLY, delete_loopback_reply) \
2382_(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply) \
2383_(DHCP_COMPL_EVENT, dhcp_compl_event) \
2384_(VNET_INTERFACE_COUNTERS, vnet_interface_counters) \
2385_(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters) \
2386_(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters) \
2387_(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply) \
2388_(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply) \
Dave Barachc07bf5d2016-02-17 17:52:26 -05002389_(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply) \
Ed Warnickecb9cada2015-12-08 15:45:58 -07002390_(MAP_DOMAIN_DETAILS, map_domain_details) \
2391_(MAP_RULE_DETAILS, map_rule_details) \
2392_(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply) \
2393_(WANT_STATS_REPLY, want_stats_reply) \
Dave Barachc07bf5d2016-02-17 17:52:26 -05002394_(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply) \
2395_(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
Dave Barachb44e9bc2016-02-19 09:06:23 -05002396_(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
Pavel Kotucek00bbf272016-03-03 13:27:11 +01002397_(GET_NODE_GRAPH_REPLY, get_node_graph_reply) \
Shwetha20a64f52016-03-25 10:55:01 +00002398_(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply) \
2399_(TRACE_PROFILE_ADD_REPLY, trace_profile_add_reply) \
2400_(TRACE_PROFILE_APPLY_REPLY, trace_profile_apply_reply) \
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002401_(TRACE_PROFILE_DEL_REPLY, trace_profile_del_reply) \
2402_(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply) \
2403_(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply) \
2404_(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply) \
2405_(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply) \
2406_(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply) \
Florin Coras577c3552016-04-21 00:45:40 +02002407_(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply) \
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002408_(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply) \
2409_(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details) \
2410_(LISP_LOCAL_EID_TABLE_DETAILS, lisp_local_eid_table_details) \
2411_(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details) \
Andrej Kozemcaka9edd852016-05-02 12:14:33 +02002412_(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details) \
2413_(LISP_GPE_ENABLE_DISABLE_STATUS_DETAILS, \
2414 lisp_gpe_enable_disable_status_details)
Ed Warnickecb9cada2015-12-08 15:45:58 -07002415
2416/* M: construct, but don't yet send a message */
2417
2418#define M(T,t) \
2419do { \
2420 vam->result_ready = 0; \
2421 mp = vl_msg_api_alloc(sizeof(*mp)); \
2422 memset (mp, 0, sizeof (*mp)); \
2423 mp->_vl_msg_id = ntohs (VL_API_##T); \
2424 mp->client_index = vam->my_client_index; \
2425} while(0);
2426
2427#define M2(T,t,n) \
2428do { \
2429 vam->result_ready = 0; \
2430 mp = vl_msg_api_alloc(sizeof(*mp)+(n)); \
2431 memset (mp, 0, sizeof (*mp)); \
2432 mp->_vl_msg_id = ntohs (VL_API_##T); \
2433 mp->client_index = vam->my_client_index; \
2434} while(0);
2435
2436
2437/* S: send a message */
2438#define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
2439
2440/* W: wait for results, with timeout */
2441#define W \
2442do { \
2443 timeout = vat_time_now (vam) + 1.0; \
2444 \
2445 while (vat_time_now (vam) < timeout) { \
2446 if (vam->result_ready == 1) { \
2447 return (vam->retval); \
2448 } \
2449 } \
2450 return -99; \
2451} while(0);
2452
2453typedef struct {
2454 u8 * name;
2455 u32 value;
2456} name_sort_t;
2457
2458
2459#define STR_VTR_OP_CASE(op) \
2460 case L2_VTR_ ## op: \
2461 return "" # op;
2462
2463static const char *str_vtr_op(u32 vtr_op)
2464{
2465 switch(vtr_op) {
2466 STR_VTR_OP_CASE(DISABLED);
2467 STR_VTR_OP_CASE(PUSH_1);
2468 STR_VTR_OP_CASE(PUSH_2);
2469 STR_VTR_OP_CASE(POP_1);
2470 STR_VTR_OP_CASE(POP_2);
2471 STR_VTR_OP_CASE(TRANSLATE_1_1);
2472 STR_VTR_OP_CASE(TRANSLATE_1_2);
2473 STR_VTR_OP_CASE(TRANSLATE_2_1);
2474 STR_VTR_OP_CASE(TRANSLATE_2_2);
2475 }
2476
2477 return "UNKNOWN";
2478}
2479
2480static int dump_sub_interface_table (vat_main_t * vam)
2481{
2482 const sw_interface_subif_t * sub = NULL;
2483
2484 if (vam->json_output) {
2485 clib_warning ("JSON output supported only for VPE API calls and dump_stats_table");
2486 return -99;
2487 }
2488
2489 fformat (vam->ofp,
2490 "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
2491 "Interface", "sw_if_index",
2492 "sub id", "dot1ad", "tags", "outer id",
2493 "inner id", "exact", "default",
2494 "outer any", "inner any");
2495
2496 vec_foreach (sub, vam->sw_if_subif_table) {
2497 fformat (vam->ofp,
2498 "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
2499 sub->interface_name,
2500 sub->sw_if_index,
2501 sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
2502 sub->sub_number_of_tags, sub->sub_outer_vlan_id,
2503 sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
2504 sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
2505 if (sub->vtr_op != L2_VTR_DISABLED) {
2506 fformat (vam->ofp,
2507 " vlan-tag-rewrite - op: %-14s [ dot1q: %d "
2508 "tag1: %d tag2: %d ]\n",
2509 str_vtr_op(sub->vtr_op), sub->vtr_push_dot1q,
2510 sub->vtr_tag1, sub->vtr_tag2);
2511 }
2512 }
2513
2514 return 0;
2515}
2516
Matus Fabiand2dc3df2015-12-14 10:31:33 -05002517static int name_sort_cmp (void * a1, void * a2)
2518{
2519 name_sort_t * n1 = a1;
2520 name_sort_t * n2 = a2;
2521
2522 return strcmp ((char *)n1->name, (char *)n2->name);
2523}
2524
Ed Warnickecb9cada2015-12-08 15:45:58 -07002525static int dump_interface_table (vat_main_t * vam)
2526{
2527 hash_pair_t * p;
2528 name_sort_t * nses = 0, * ns;
2529
2530 if (vam->json_output) {
2531 clib_warning ("JSON output supported only for VPE API calls and dump_stats_table");
2532 return -99;
2533 }
2534
2535 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
2536 ({
2537 vec_add2 (nses, ns, 1);
2538 ns->name = (u8 *)(p->key);
2539 ns->value = (u32) p->value[0];
2540 }));
2541
Matus Fabiand2dc3df2015-12-14 10:31:33 -05002542 vec_sort_with_function (nses, name_sort_cmp);
Ed Warnickecb9cada2015-12-08 15:45:58 -07002543
2544 fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
2545 vec_foreach (ns, nses) {
2546 fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
2547 }
2548 vec_free (nses);
2549 return 0;
2550}
2551
2552static int dump_ip_table (vat_main_t * vam, int is_ipv6)
2553{
2554 const ip_details_t * det = NULL;
2555 const ip_address_details_t * address = NULL;
2556 u32 i = ~0;
2557
2558 fformat (vam->ofp,
2559 "%-12s\n",
2560 "sw_if_index");
2561
Damjan Marionfa693552016-04-26 19:30:36 +02002562 if (0 == vam) {
Ed Warnickecb9cada2015-12-08 15:45:58 -07002563 return 0;
2564 }
2565
2566 vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6]) {
2567 i++;
2568 if (!det->present) {
2569 continue;
2570 }
2571 fformat (vam->ofp,
2572 "%-12d\n",
2573 i);
2574 fformat (vam->ofp,
2575 " %-30s%-13s\n",
2576 "Address", "Prefix length");
2577 if (!det->addr) {
2578 continue;
2579 }
2580 vec_foreach (address, det->addr) {
2581 fformat (vam->ofp,
2582 " %-30U%-13d\n",
2583 is_ipv6 ? format_ip6_address : format_ip4_address,
2584 address->ip,
2585 address->prefix_length);
2586 }
2587 }
2588
2589 return 0;
2590}
2591
2592static int dump_ipv4_table (vat_main_t * vam)
2593{
2594 if (vam->json_output) {
2595 clib_warning ("JSON output supported only for VPE API calls and dump_stats_table");
2596 return -99;
2597 }
2598
2599 return dump_ip_table (vam, 0);
2600}
2601
2602static int dump_ipv6_table (vat_main_t * vam)
2603{
2604 if (vam->json_output) {
2605 clib_warning ("JSON output supported only for VPE API calls and dump_stats_table");
2606 return -99;
2607 }
2608
2609 return dump_ip_table (vam, 1);
2610}
2611
2612static char* counter_type_to_str (u8 counter_type, u8 is_combined)
2613{
2614 if (!is_combined) {
2615 switch(counter_type) {
2616 case VNET_INTERFACE_COUNTER_DROP:
2617 return "drop";
2618 case VNET_INTERFACE_COUNTER_PUNT:
2619 return "punt";
2620 case VNET_INTERFACE_COUNTER_IP4:
2621 return "ip4";
2622 case VNET_INTERFACE_COUNTER_IP6:
2623 return "ip6";
2624 case VNET_INTERFACE_COUNTER_RX_NO_BUF:
2625 return "rx-no-buf";
2626 case VNET_INTERFACE_COUNTER_RX_MISS:
2627 return "rx-miss";
2628 case VNET_INTERFACE_COUNTER_RX_ERROR:
2629 return "rx-error";
2630 case VNET_INTERFACE_COUNTER_TX_ERROR:
2631 return "tx-error";
2632 default:
2633 return "INVALID-COUNTER-TYPE";
2634 }
2635 } else {
2636 switch(counter_type) {
2637 case VNET_INTERFACE_COUNTER_RX:
2638 return "rx";
2639 case VNET_INTERFACE_COUNTER_TX:
2640 return "tx";
2641 default:
2642 return "INVALID-COUNTER-TYPE";
2643 }
2644 }
2645}
2646
2647static int dump_stats_table (vat_main_t * vam)
2648{
2649 vat_json_node_t node;
2650 vat_json_node_t *msg_array;
2651 vat_json_node_t *msg;
2652 vat_json_node_t *counter_array;
2653 vat_json_node_t *counter;
2654 interface_counter_t c;
2655 u64 packets;
2656 ip4_fib_counter_t *c4;
2657 ip6_fib_counter_t *c6;
2658 int i, j;
2659
2660 if (!vam->json_output) {
2661 clib_warning ("dump_stats_table supported only in JSON format");
2662 return -99;
2663 }
2664
2665 vat_json_init_object(&node);
2666
2667 /* interface counters */
2668 msg_array = vat_json_object_add(&node, "interface_counters");
2669 vat_json_init_array(msg_array);
2670 for (i = 0; i < vec_len(vam->simple_interface_counters); i++) {
2671 msg = vat_json_array_add(msg_array);
2672 vat_json_init_object(msg);
2673 vat_json_object_add_string_copy(msg, "vnet_counter_type",
2674 (u8*)counter_type_to_str(i, 0));
2675 vat_json_object_add_int(msg, "is_combined", 0);
2676 counter_array = vat_json_object_add(msg, "data");
2677 vat_json_init_array(counter_array);
2678 for (j = 0; j < vec_len(vam->simple_interface_counters[i]); j++) {
2679 packets = vam->simple_interface_counters[i][j];
2680 vat_json_array_add_uint(counter_array, packets);
2681 }
2682 }
2683 for (i = 0; i < vec_len(vam->combined_interface_counters); i++) {
2684 msg = vat_json_array_add(msg_array);
2685 vat_json_init_object(msg);
2686 vat_json_object_add_string_copy(msg, "vnet_counter_type",
2687 (u8*)counter_type_to_str(i, 1));
2688 vat_json_object_add_int(msg, "is_combined", 1);
2689 counter_array = vat_json_object_add(msg, "data");
2690 vat_json_init_array(counter_array);
2691 for (j = 0; j < vec_len(vam->combined_interface_counters[i]); j++) {
2692 c = vam->combined_interface_counters[i][j];
2693 counter = vat_json_array_add(counter_array);
2694 vat_json_init_object(counter);
2695 vat_json_object_add_uint(counter, "packets", c.packets);
2696 vat_json_object_add_uint(counter, "bytes", c.bytes);
2697 }
2698 }
2699
2700 /* ip4 fib counters */
2701 msg_array = vat_json_object_add(&node, "ip4_fib_counters");
2702 vat_json_init_array(msg_array);
2703 for (i = 0; i < vec_len(vam->ip4_fib_counters); i++) {
2704 msg = vat_json_array_add(msg_array);
2705 vat_json_init_object(msg);
2706 vat_json_object_add_uint(msg, "vrf_id", vam->ip4_fib_counters_vrf_id_by_index[i]);
2707 counter_array = vat_json_object_add(msg, "c");
2708 vat_json_init_array(counter_array);
2709 for (j = 0; j < vec_len(vam->ip4_fib_counters[i]); j++) {
2710 counter = vat_json_array_add(counter_array);
2711 vat_json_init_object(counter);
2712 c4 = &vam->ip4_fib_counters[i][j];
2713 vat_json_object_add_ip4(counter, "address", c4->address);
2714 vat_json_object_add_uint(counter, "address_length", c4->address_length);
2715 vat_json_object_add_uint(counter, "packets", c4->packets);
2716 vat_json_object_add_uint(counter, "bytes", c4->bytes);
2717 }
2718 }
2719
2720 /* ip6 fib counters */
2721 msg_array = vat_json_object_add(&node, "ip6_fib_counters");
2722 vat_json_init_array(msg_array);
2723 for (i = 0; i < vec_len(vam->ip6_fib_counters); i++) {
2724 msg = vat_json_array_add(msg_array);
2725 vat_json_init_object(msg);
2726 vat_json_object_add_uint(msg, "vrf_id", vam->ip6_fib_counters_vrf_id_by_index[i]);
2727 counter_array = vat_json_object_add(msg, "c");
2728 vat_json_init_array(counter_array);
2729 for (j = 0; j < vec_len(vam->ip6_fib_counters[i]); j++) {
2730 counter = vat_json_array_add(counter_array);
2731 vat_json_init_object(counter);
2732 c6 = &vam->ip6_fib_counters[i][j];
2733 vat_json_object_add_ip6(counter, "address", c6->address);
2734 vat_json_object_add_uint(counter, "address_length", c6->address_length);
2735 vat_json_object_add_uint(counter, "packets", c6->packets);
2736 vat_json_object_add_uint(counter, "bytes", c6->bytes);
2737 }
2738 }
2739
2740 vat_json_print(vam->ofp, &node);
2741 vat_json_free(&node);
2742
2743 return 0;
2744}
2745
2746int exec (vat_main_t * vam)
2747{
2748 api_main_t * am = &api_main;
2749 vl_api_cli_request_t *mp;
2750 f64 timeout;
2751 void * oldheap;
2752 u8 * cmd = 0;
2753 unformat_input_t * i = vam->input;
2754
2755 if (vec_len(i->buffer) == 0)
2756 return -1;
2757
2758 if (vam->exec_mode == 0 && unformat (i, "mode")) {
2759 vam->exec_mode = 1;
2760 return 0;
2761 }
2762 if (vam->exec_mode == 1 &&
2763 (unformat (i, "exit") || unformat (i, "quit"))) {
2764 vam->exec_mode = 0;
2765 return 0;
2766 }
2767
2768
2769 M(CLI_REQUEST, cli_request);
2770
2771 /*
2772 * Copy cmd into shared memory.
2773 * In order for the CLI command to work, it
2774 * must be a vector ending in \n, not a C-string ending
2775 * in \n\0.
2776 */
2777 pthread_mutex_lock (&am->vlib_rp->mutex);
2778 oldheap = svm_push_data_heap (am->vlib_rp);
2779
2780 vec_validate (cmd, vec_len(vam->input->buffer)-1);
Damjan Marionf1213b82016-03-13 02:22:06 +01002781 clib_memcpy (cmd, vam->input->buffer, vec_len(vam->input->buffer));
Ed Warnickecb9cada2015-12-08 15:45:58 -07002782
2783 svm_pop_heap (oldheap);
2784 pthread_mutex_unlock (&am->vlib_rp->mutex);
2785
2786 mp->cmd_in_shmem = (u64) cmd;
2787 S;
2788 timeout = vat_time_now (vam) + 10.0;
2789
2790 while (vat_time_now (vam) < timeout) {
2791 if (vam->result_ready == 1) {
2792 u8 * free_me;
Pavel Kotucek060c6fc2016-02-24 15:52:42 +01002793 if (vam->shmem_result != NULL)
2794 fformat (vam->ofp, "%s", vam->shmem_result);
Ed Warnickecb9cada2015-12-08 15:45:58 -07002795 pthread_mutex_lock (&am->vlib_rp->mutex);
2796 oldheap = svm_push_data_heap (am->vlib_rp);
2797
2798 free_me = (u8 *)vam->shmem_result;
2799 vec_free (free_me);
2800
2801 svm_pop_heap (oldheap);
2802 pthread_mutex_unlock (&am->vlib_rp->mutex);
2803 return 0;
2804 }
2805 }
2806 return -99;
2807}
2808
2809static int api_create_loopback (vat_main_t * vam)
2810{
2811 unformat_input_t * i = vam->input;
2812 vl_api_create_loopback_t *mp;
2813 f64 timeout;
2814 u8 mac_address[6];
2815 u8 mac_set = 0;
2816
2817 memset (mac_address, 0, sizeof (mac_address));
2818
2819 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2820 {
2821 if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
2822 mac_set = 1;
2823 else
2824 break;
2825 }
2826
2827 /* Construct the API message */
2828 M(CREATE_LOOPBACK, create_loopback);
2829 if (mac_set)
Damjan Marionf1213b82016-03-13 02:22:06 +01002830 clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07002831
2832 S; W;
2833}
2834
2835static int api_delete_loopback (vat_main_t * vam)
2836{
2837 unformat_input_t * i = vam->input;
2838 vl_api_delete_loopback_t *mp;
2839 f64 timeout;
2840 u32 sw_if_index = ~0;
2841
2842 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2843 {
2844 if (unformat (i, "sw_if_index %d", &sw_if_index))
2845 ;
2846 else
2847 break;
2848 }
2849
2850 if (sw_if_index == ~0)
2851 {
2852 errmsg ("missing sw_if_index\n");
2853 return -99;
2854 }
2855
2856 /* Construct the API message */
2857 M(DELETE_LOOPBACK, delete_loopback);
2858 mp->sw_if_index = ntohl (sw_if_index);
2859
2860 S; W;
2861}
2862
2863static int api_want_stats (vat_main_t * vam)
2864{
2865 unformat_input_t * i = vam->input;
2866 vl_api_want_stats_t * mp;
2867 f64 timeout;
2868 int enable = -1;
2869
2870 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2871 {
2872 if (unformat (i, "enable"))
2873 enable = 1;
2874 else if (unformat (i, "disable"))
2875 enable = 0;
2876 else
2877 break;
2878 }
2879
2880 if (enable == -1)
2881 {
2882 errmsg ("missing enable|disable\n");
2883 return -99;
2884 }
2885
2886 M(WANT_STATS, want_stats);
2887 mp->enable_disable = enable;
2888
2889 S; W;
2890}
2891
2892static int api_want_interface_events (vat_main_t * vam)
2893{
2894 unformat_input_t * i = vam->input;
2895 vl_api_want_interface_events_t * mp;
2896 f64 timeout;
2897 int enable = -1;
2898
2899 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2900 {
2901 if (unformat (i, "enable"))
2902 enable = 1;
2903 else if (unformat (i, "disable"))
2904 enable = 0;
2905 else
2906 break;
2907 }
2908
2909 if (enable == -1)
2910 {
2911 errmsg ("missing enable|disable\n");
2912 return -99;
2913 }
2914
2915 M(WANT_INTERFACE_EVENTS, want_interface_events);
2916 mp->enable_disable = enable;
2917
2918 vam->interface_event_display = enable;
2919
2920 S; W;
2921}
2922
2923
2924/* Note: non-static, called once to set up the initial intfc table */
2925int api_sw_interface_dump (vat_main_t * vam)
2926{
2927 vl_api_sw_interface_dump_t *mp;
2928 f64 timeout;
2929 hash_pair_t * p;
2930 name_sort_t * nses = 0, * ns;
2931 sw_interface_subif_t * sub = NULL;
2932
2933 /* Toss the old name table */
2934 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
2935 ({
2936 vec_add2 (nses, ns, 1);
2937 ns->name = (u8 *)(p->key);
2938 ns->value = (u32) p->value[0];
2939 }));
2940
2941 hash_free (vam->sw_if_index_by_interface_name);
2942
2943 vec_foreach (ns, nses)
2944 vec_free (ns->name);
2945
2946 vec_free (nses);
2947
2948 vec_foreach (sub, vam->sw_if_subif_table) {
2949 vec_free (sub->interface_name);
2950 }
2951 vec_free (vam->sw_if_subif_table);
2952
2953 /* recreate the interface name hash table */
2954 vam->sw_if_index_by_interface_name
2955 = hash_create_string (0, sizeof(uword));
2956
2957 /* Get list of ethernets */
2958 M(SW_INTERFACE_DUMP, sw_interface_dump);
2959 mp->name_filter_valid = 1;
Damjan Marionfa693552016-04-26 19:30:36 +02002960 strncpy ((char *) mp->name_filter, "Ether", sizeof(mp->name_filter)-1);
Ed Warnickecb9cada2015-12-08 15:45:58 -07002961 S;
2962
2963 /* and local / loopback interfaces */
2964 M(SW_INTERFACE_DUMP, sw_interface_dump);
2965 mp->name_filter_valid = 1;
Damjan Marionfa693552016-04-26 19:30:36 +02002966 strncpy ((char *) mp->name_filter, "lo", sizeof(mp->name_filter)-1);
Ed Warnickecb9cada2015-12-08 15:45:58 -07002967 S;
2968
2969 /* and vxlan tunnel interfaces */
2970 M(SW_INTERFACE_DUMP, sw_interface_dump);
2971 mp->name_filter_valid = 1;
Damjan Marionfa693552016-04-26 19:30:36 +02002972 strncpy ((char *) mp->name_filter, "vxlan", sizeof(mp->name_filter)-1);
Ed Warnickecb9cada2015-12-08 15:45:58 -07002973 S;
2974
Damjan Marionb02e49c2016-03-31 17:44:25 +02002975 /* and host (af_packet) interfaces */
2976 M(SW_INTERFACE_DUMP, sw_interface_dump);
2977 mp->name_filter_valid = 1;
Damjan Marionfa693552016-04-26 19:30:36 +02002978 strncpy ((char *) mp->name_filter, "host", sizeof(mp->name_filter)-1);
Damjan Marionb02e49c2016-03-31 17:44:25 +02002979 S;
2980
Ed Warnickecb9cada2015-12-08 15:45:58 -07002981 /* and l2tpv3 tunnel interfaces */
2982 M(SW_INTERFACE_DUMP, sw_interface_dump);
2983 mp->name_filter_valid = 1;
Damjan Marionfa693552016-04-26 19:30:36 +02002984 strncpy ((char *) mp->name_filter, "l2tpv3_tunnel", sizeof(mp->name_filter)-1);
Ed Warnickecb9cada2015-12-08 15:45:58 -07002985 S;
2986
Chris Lukea6116ef2016-05-06 10:12:30 -04002987 /* and GRE tunnel interfaces */
2988 M(SW_INTERFACE_DUMP, sw_interface_dump);
2989 mp->name_filter_valid = 1;
2990 strncpy ((char *) mp->name_filter, "gre", sizeof(mp->name_filter)-1);
2991 S;
2992
Ed Warnickecb9cada2015-12-08 15:45:58 -07002993 /* Use a control ping for synchronization */
2994 {
2995 vl_api_control_ping_t * mp;
2996 M(CONTROL_PING, control_ping);
2997 S;
2998 }
2999 W;
3000}
3001
3002static int api_sw_interface_set_flags (vat_main_t * vam)
3003{
3004 unformat_input_t * i = vam->input;
3005 vl_api_sw_interface_set_flags_t *mp;
3006 f64 timeout;
3007 u32 sw_if_index;
3008 u8 sw_if_index_set = 0;
3009 u8 admin_up = 0, link_up = 0;
3010
3011 /* Parse args required to build the message */
3012 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3013 if (unformat (i, "admin-up"))
3014 admin_up = 1;
3015 else if (unformat (i, "admin-down"))
3016 admin_up = 0;
3017 else if (unformat (i, "link-up"))
3018 link_up = 1;
3019 else if (unformat (i, "link-down"))
3020 link_up = 0;
3021 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3022 sw_if_index_set = 1;
3023 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3024 sw_if_index_set = 1;
3025 else
3026 break;
3027 }
3028
3029 if (sw_if_index_set == 0) {
3030 errmsg ("missing interface name or sw_if_index\n");
3031 return -99;
3032 }
3033
3034 /* Construct the API message */
3035 M(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
3036 mp->sw_if_index = ntohl (sw_if_index);
3037 mp->admin_up_down = admin_up;
3038 mp->link_up_down = link_up;
3039
3040 /* send it... */
3041 S;
3042
3043 /* Wait for a reply, return the good/bad news... */
3044 W;
3045}
3046
Pavel Kotucek00bbf272016-03-03 13:27:11 +01003047static int api_sw_interface_clear_stats (vat_main_t * vam)
3048{
3049 unformat_input_t * i = vam->input;
3050 vl_api_sw_interface_clear_stats_t *mp;
3051 f64 timeout;
3052 u32 sw_if_index;
3053 u8 sw_if_index_set = 0;
3054
3055 /* Parse args required to build the message */
3056 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3057 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3058 sw_if_index_set = 1;
3059 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3060 sw_if_index_set = 1;
3061 else
3062 break;
3063 }
3064
3065 /* Construct the API message */
3066 M(SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
3067
3068 if (sw_if_index_set == 1)
3069 mp->sw_if_index = ntohl (sw_if_index);
3070 else
3071 mp->sw_if_index = ~0;
3072
3073 /* send it... */
3074 S;
3075
3076 /* Wait for a reply, return the good/bad news... */
3077 W;
3078}
3079
Ed Warnickecb9cada2015-12-08 15:45:58 -07003080static int api_sw_interface_add_del_address (vat_main_t * vam)
3081{
3082 unformat_input_t * i = vam->input;
3083 vl_api_sw_interface_add_del_address_t *mp;
3084 f64 timeout;
3085 u32 sw_if_index;
3086 u8 sw_if_index_set = 0;
3087 u8 is_add = 1, del_all = 0;
3088 u32 address_length = 0;
3089 u8 v4_address_set = 0;
3090 u8 v6_address_set = 0;
3091 ip4_address_t v4address;
3092 ip6_address_t v6address;
3093
3094 /* Parse args required to build the message */
3095 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3096 if (unformat (i, "del-all"))
3097 del_all = 1;
3098 else if (unformat (i, "del"))
3099 is_add = 0;
3100 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3101 sw_if_index_set = 1;
3102 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3103 sw_if_index_set = 1;
3104 else if (unformat (i, "%U/%d",
3105 unformat_ip4_address, &v4address,
3106 &address_length))
3107 v4_address_set = 1;
3108 else if (unformat (i, "%U/%d",
3109 unformat_ip6_address, &v6address,
3110 &address_length))
3111 v6_address_set = 1;
3112 else
3113 break;
3114 }
3115
3116 if (sw_if_index_set == 0) {
3117 errmsg ("missing interface name or sw_if_index\n");
3118 return -99;
3119 }
3120 if (v4_address_set && v6_address_set) {
3121 errmsg ("both v4 and v6 addresses set\n");
3122 return -99;
3123 }
3124 if (!v4_address_set && !v6_address_set && !del_all) {
3125 errmsg ("no addresses set\n");
3126 return -99;
3127 }
3128
3129 /* Construct the API message */
3130 M(SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
3131
3132 mp->sw_if_index = ntohl (sw_if_index);
3133 mp->is_add = is_add;
3134 mp->del_all = del_all;
3135 if (v6_address_set) {
3136 mp->is_ipv6 = 1;
Damjan Marionf1213b82016-03-13 02:22:06 +01003137 clib_memcpy (mp->address, &v6address, sizeof (v6address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07003138 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01003139 clib_memcpy (mp->address, &v4address, sizeof (v4address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07003140 }
3141 mp->address_length = address_length;
3142
3143 /* send it... */
3144 S;
3145
3146 /* Wait for a reply, return good/bad news */
3147 W;
3148}
3149
3150static int api_sw_interface_set_table (vat_main_t * vam)
3151{
3152 unformat_input_t * i = vam->input;
3153 vl_api_sw_interface_set_table_t *mp;
3154 f64 timeout;
3155 u32 sw_if_index, vrf_id = 0;
3156 u8 sw_if_index_set = 0;
3157 u8 is_ipv6 = 0;
3158
3159 /* Parse args required to build the message */
3160 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3161 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3162 sw_if_index_set = 1;
3163 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3164 sw_if_index_set = 1;
3165 else if (unformat (i, "vrf %d", &vrf_id))
3166 ;
3167 else if (unformat (i, "ipv6"))
3168 is_ipv6 = 1;
3169 else
3170 break;
3171 }
3172
3173 if (sw_if_index_set == 0) {
3174 errmsg ("missing interface name or sw_if_index\n");
3175 return -99;
3176 }
3177
3178 /* Construct the API message */
3179 M(SW_INTERFACE_SET_TABLE, sw_interface_set_table);
3180
3181 mp->sw_if_index = ntohl (sw_if_index);
3182 mp->is_ipv6 = is_ipv6;
3183 mp->vrf_id = ntohl (vrf_id);
3184
3185 /* send it... */
3186 S;
3187
3188 /* Wait for a reply... */
3189 W;
3190}
3191
3192static int api_sw_interface_set_vpath (vat_main_t * vam)
3193{
3194 unformat_input_t * i = vam->input;
3195 vl_api_sw_interface_set_vpath_t *mp;
3196 f64 timeout;
3197 u32 sw_if_index = 0;
3198 u8 sw_if_index_set = 0;
3199 u8 is_enable = 0;
3200
3201 /* Parse args required to build the message */
3202 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3203 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3204 sw_if_index_set = 1;
3205 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3206 sw_if_index_set = 1;
3207 else if (unformat (i, "enable"))
3208 is_enable = 1;
3209 else if (unformat (i, "disable"))
3210 is_enable = 0;
3211 else
3212 break;
3213 }
3214
3215 if (sw_if_index_set == 0) {
3216 errmsg ("missing interface name or sw_if_index\n");
3217 return -99;
3218 }
3219
3220 /* Construct the API message */
3221 M(SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
3222
3223 mp->sw_if_index = ntohl (sw_if_index);
3224 mp->enable = is_enable;
3225
3226 /* send it... */
3227 S;
3228
3229 /* Wait for a reply... */
3230 W;
3231}
3232
3233static int api_sw_interface_set_l2_xconnect (vat_main_t * vam)
3234{
3235 unformat_input_t * i = vam->input;
3236 vl_api_sw_interface_set_l2_xconnect_t *mp;
3237 f64 timeout;
3238 u32 rx_sw_if_index;
3239 u8 rx_sw_if_index_set = 0;
3240 u32 tx_sw_if_index;
3241 u8 tx_sw_if_index_set = 0;
3242 u8 enable = 1;
3243
3244 /* Parse args required to build the message */
3245 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3246 if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
3247 rx_sw_if_index_set = 1;
3248 else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
3249 tx_sw_if_index_set = 1;
3250 else if (unformat (i, "rx")) {
3251 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3252 if (unformat (i, "%U", unformat_sw_if_index, vam,
3253 &rx_sw_if_index))
3254 rx_sw_if_index_set = 1;
3255 } else
3256 break;
3257 } else if (unformat (i, "tx")) {
3258 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3259 if (unformat (i, "%U", unformat_sw_if_index, vam,
3260 &tx_sw_if_index))
3261 tx_sw_if_index_set = 1;
3262 } else
3263 break;
3264 } else if (unformat (i, "enable"))
3265 enable = 1;
3266 else if (unformat (i, "disable"))
3267 enable = 0;
3268 else
3269 break;
3270 }
3271
3272 if (rx_sw_if_index_set == 0) {
3273 errmsg ("missing rx interface name or rx_sw_if_index\n");
3274 return -99;
3275 }
3276
3277 if (enable && (tx_sw_if_index_set == 0)) {
3278 errmsg ("missing tx interface name or tx_sw_if_index\n");
3279 return -99;
3280 }
3281
3282 M(SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
3283
3284 mp->rx_sw_if_index = ntohl(rx_sw_if_index);
3285 mp->tx_sw_if_index = ntohl(tx_sw_if_index);
3286 mp->enable = enable;
3287
3288 S; W;
3289 /* NOTREACHED */
3290 return 0;
3291}
3292
3293static int api_sw_interface_set_l2_bridge (vat_main_t * vam)
3294{
3295 unformat_input_t * i = vam->input;
3296 vl_api_sw_interface_set_l2_bridge_t *mp;
3297 f64 timeout;
3298 u32 rx_sw_if_index;
3299 u8 rx_sw_if_index_set = 0;
3300 u32 bd_id;
3301 u8 bd_id_set = 0;
3302 u8 bvi = 0;
3303 u32 shg = 0;
3304 u8 enable = 1;
3305
3306 /* Parse args required to build the message */
3307 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3308 if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
3309 rx_sw_if_index_set = 1;
3310 else if (unformat (i, "bd_id %d", &bd_id))
3311 bd_id_set = 1;
3312 else if (unformat (i, "%U", unformat_sw_if_index, vam,
3313 &rx_sw_if_index))
3314 rx_sw_if_index_set = 1;
3315 else if (unformat (i, "shg %d", &shg))
3316 ;
3317 else if (unformat (i, "bvi"))
3318 bvi = 1;
3319 else if (unformat (i, "enable"))
3320 enable = 1;
3321 else if (unformat (i, "disable"))
3322 enable = 0;
3323 else
3324 break;
3325 }
3326
3327 if (rx_sw_if_index_set == 0) {
3328 errmsg ("missing rx interface name or sw_if_index\n");
3329 return -99;
3330 }
3331
3332 if (enable && (bd_id_set == 0)) {
3333 errmsg ("missing bridge domain\n");
3334 return -99;
3335 }
3336
3337 M(SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
3338
3339 mp->rx_sw_if_index = ntohl(rx_sw_if_index);
3340 mp->bd_id = ntohl(bd_id);
3341 mp->shg = (u8)shg;
3342 mp->bvi = bvi;
3343 mp->enable = enable;
3344
3345 S; W;
3346 /* NOTREACHED */
3347 return 0;
3348}
3349
3350static int api_bridge_domain_dump (vat_main_t * vam)
3351{
3352 unformat_input_t * i = vam->input;
3353 vl_api_bridge_domain_dump_t *mp;
3354 f64 timeout;
3355 u32 bd_id = ~0;
3356
3357 /* Parse args required to build the message */
3358 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3359 if (unformat (i, "bd_id %d", &bd_id))
3360 ;
3361 else
3362 break;
3363 }
3364
3365 M(BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
3366 mp->bd_id = ntohl(bd_id);
3367 S;
3368
3369 /* Use a control ping for synchronization */
3370 {
3371 vl_api_control_ping_t * mp;
3372 M(CONTROL_PING, control_ping);
3373 S;
3374 }
3375
3376 W;
3377 /* NOTREACHED */
3378 return 0;
3379}
3380
3381static int api_bridge_domain_add_del (vat_main_t * vam)
3382{
3383 unformat_input_t * i = vam->input;
3384 vl_api_bridge_domain_add_del_t *mp;
3385 f64 timeout;
3386 u32 bd_id = ~0;
3387 u8 is_add = 1;
3388 u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
3389
3390 /* Parse args required to build the message */
3391 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3392 if (unformat (i, "bd_id %d", &bd_id))
3393 ;
3394 else if (unformat (i, "flood %d", &flood))
3395 ;
3396 else if (unformat (i, "uu-flood %d", &uu_flood))
3397 ;
3398 else if (unformat (i, "forward %d", &forward))
3399 ;
3400 else if (unformat (i, "learn %d", &learn))
3401 ;
3402 else if (unformat (i, "arp-term %d", &arp_term))
3403 ;
3404 else if (unformat (i, "del")) {
3405 is_add = 0;
3406 flood = uu_flood = forward = learn = 0;
3407 }
3408 else
3409 break;
3410 }
3411
3412 if (bd_id == ~0) {
3413 errmsg ("missing bridge domain\n");
3414 return -99;
3415 }
3416
3417 M(BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
3418
3419 mp->bd_id = ntohl(bd_id);
3420 mp->flood = flood;
3421 mp->uu_flood = uu_flood;
3422 mp->forward = forward;
3423 mp->learn = learn;
3424 mp->arp_term = arp_term;
3425 mp->is_add = is_add;
3426
3427 S; W;
3428 /* NOTREACHED */
3429 return 0;
3430}
3431
3432static int api_l2fib_add_del (vat_main_t * vam)
3433{
3434 unformat_input_t * i = vam->input;
3435 vl_api_l2fib_add_del_t *mp;
3436 f64 timeout;
3437 u64 mac = 0;
3438 u8 mac_set = 0;
3439 u32 bd_id;
3440 u8 bd_id_set = 0;
3441 u32 sw_if_index;
3442 u8 sw_if_index_set = 0;
3443 u8 is_add = 1;
3444 u8 static_mac = 0;
3445 u8 filter_mac = 0;
3446
3447 /* Parse args required to build the message */
3448 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3449 if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
3450 mac_set = 1;
3451 else if (unformat (i, "bd_id %d", &bd_id))
3452 bd_id_set = 1;
3453 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3454 sw_if_index_set = 1;
3455 else if (unformat (i, "sw_if")) {
3456 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3457 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3458 sw_if_index_set = 1;
3459 } else
3460 break;
3461 } else if (unformat (i, "static"))
3462 static_mac = 1;
3463 else if (unformat (i, "filter")) {
3464 filter_mac = 1;
3465 static_mac = 1;
3466 } else if (unformat (i, "del"))
3467 is_add = 0;
3468 else
3469 break;
3470 }
3471
3472 if (mac_set == 0) {
3473 errmsg ("missing mac address\n");
3474 return -99;
3475 }
3476
3477 if (bd_id_set == 0) {
3478 errmsg ("missing bridge domain\n");
3479 return -99;
3480 }
3481
3482 if (is_add && (sw_if_index_set == 0)) {
3483 errmsg ("missing interface name or sw_if_index\n");
3484 return -99;
3485 }
3486
3487 M(L2FIB_ADD_DEL, l2fib_add_del);
3488
3489 mp->mac = mac;
3490 mp->bd_id = ntohl(bd_id);
3491 mp->is_add = is_add;
3492
3493 if (is_add) {
3494 mp->sw_if_index = ntohl(sw_if_index);
3495 mp->static_mac = static_mac;
3496 mp->filter_mac = filter_mac;
3497 }
3498
3499 S; W;
3500 /* NOTREACHED */
3501 return 0;
3502}
3503
3504static int api_l2_flags (vat_main_t * vam)
3505{
3506 unformat_input_t * i = vam->input;
3507 vl_api_l2_flags_t *mp;
3508 f64 timeout;
3509 u32 sw_if_index;
3510 u32 feature_bitmap = 0;
3511 u8 sw_if_index_set = 0;
3512
3513 /* Parse args required to build the message */
3514 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3515 if (unformat (i, "sw_if_index %d", &sw_if_index))
3516 sw_if_index_set = 1;
3517 else if (unformat (i, "sw_if")) {
3518 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3519 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3520 sw_if_index_set = 1;
3521 } else
3522 break;
3523 } else if (unformat (i, "learn"))
3524 feature_bitmap |= L2INPUT_FEAT_LEARN;
3525 else if (unformat (i, "forward"))
3526 feature_bitmap |= L2INPUT_FEAT_FWD;
3527 else if (unformat (i, "flood"))
3528 feature_bitmap |= L2INPUT_FEAT_FLOOD;
3529 else if (unformat (i, "uu-flood"))
3530 feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
3531 else
3532 break;
3533 }
3534
3535 if (sw_if_index_set == 0) {
3536 errmsg ("missing interface name or sw_if_index\n");
3537 return -99;
3538 }
3539
3540 M(L2_FLAGS, l2_flags);
3541
3542 mp->sw_if_index = ntohl(sw_if_index);
3543 mp->feature_bitmap = ntohl(feature_bitmap);
3544
3545 S; W;
3546 /* NOTREACHED */
3547 return 0;
3548}
3549
3550static int api_bridge_flags (vat_main_t * vam)
3551{
3552 unformat_input_t * i = vam->input;
3553 vl_api_bridge_flags_t *mp;
3554 f64 timeout;
3555 u32 bd_id;
3556 u8 bd_id_set = 0;
3557 u8 is_set = 1;
3558 u32 flags = 0;
3559
3560 /* Parse args required to build the message */
3561 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3562 if (unformat (i, "bd_id %d", &bd_id))
3563 bd_id_set = 1;
3564 else if (unformat (i, "learn"))
3565 flags |= L2_LEARN;
3566 else if (unformat (i, "forward"))
3567 flags |= L2_FWD;
3568 else if (unformat (i, "flood"))
3569 flags |= L2_FLOOD;
3570 else if (unformat (i, "uu-flood"))
3571 flags |= L2_UU_FLOOD;
3572 else if (unformat (i, "arp-term"))
3573 flags |= L2_ARP_TERM;
3574 else if (unformat (i, "off"))
3575 is_set = 0;
3576 else if (unformat (i, "disable"))
3577 is_set = 0;
3578 else
3579 break;
3580 }
3581
3582 if (bd_id_set == 0) {
3583 errmsg ("missing bridge domain\n");
3584 return -99;
3585 }
3586
3587 M(BRIDGE_FLAGS, bridge_flags);
3588
3589 mp->bd_id = ntohl(bd_id);
3590 mp->feature_bitmap = ntohl(flags);
3591 mp->is_set = is_set;
3592
3593 S; W;
3594 /* NOTREACHED */
3595 return 0;
3596}
3597
3598static int api_bd_ip_mac_add_del (vat_main_t * vam)
3599{
3600 unformat_input_t * i = vam->input;
3601 vl_api_bd_ip_mac_add_del_t *mp;
3602 f64 timeout;
3603 u32 bd_id;
3604 u8 is_ipv6 = 0;
3605 u8 is_add = 1;
3606 u8 bd_id_set = 0;
3607 u8 ip_set = 0;
3608 u8 mac_set = 0;
3609 ip4_address_t v4addr;
3610 ip6_address_t v6addr;
3611 u8 macaddr[6];
3612
3613
3614 /* Parse args required to build the message */
3615 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3616 if (unformat (i, "bd_id %d", &bd_id)) {
3617 bd_id_set++;
3618 } else if (unformat (i, "%U", unformat_ip4_address, &v4addr)) {
3619 ip_set++;
3620 } else if (unformat (i, "%U", unformat_ip6_address, &v6addr)) {
3621 ip_set++;
3622 is_ipv6++;
3623 } else if (unformat (i, "%U", unformat_ethernet_address, macaddr)) {
3624 mac_set++;
3625 } else if (unformat (i, "del"))
3626 is_add = 0;
3627 else
3628 break;
3629 }
3630
3631 if (bd_id_set == 0) {
3632 errmsg ("missing bridge domain\n");
3633 return -99;
3634 } else if (ip_set == 0) {
3635 errmsg ("missing IP address\n");
3636 return -99;
3637 } else if (mac_set == 0) {
3638 errmsg ("missing MAC address\n");
3639 return -99;
3640 }
3641
3642 M(BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
3643
3644 mp->bd_id = ntohl(bd_id);
3645 mp->is_ipv6 = is_ipv6;
3646 mp->is_add = is_add;
3647 if (is_ipv6)
Damjan Marionf1213b82016-03-13 02:22:06 +01003648 clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
3649 else clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
3650 clib_memcpy (mp->mac_address, macaddr, 6);
Ed Warnickecb9cada2015-12-08 15:45:58 -07003651 S; W;
3652 /* NOTREACHED */
3653 return 0;
3654}
3655
3656static int api_tap_connect (vat_main_t * vam)
3657{
3658 unformat_input_t * i = vam->input;
3659 vl_api_tap_connect_t *mp;
3660 f64 timeout;
3661 u8 mac_address[6];
3662 u8 random_mac = 1;
3663 u8 name_set = 0;
3664 u8 * tap_name;
3665
3666 memset (mac_address, 0, sizeof (mac_address));
3667
3668 /* Parse args required to build the message */
3669 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3670 if (unformat (i, "mac %U", unformat_ethernet_address, mac_address)) {
3671 random_mac = 0;
3672 }
3673 else if (unformat (i, "random-mac"))
3674 random_mac = 1;
3675 else if (unformat (i, "tapname %s", &tap_name))
3676 name_set = 1;
3677 else
3678 break;
3679 }
3680
3681 if (name_set == 0) {
3682 errmsg ("missing tap name\n");
3683 return -99;
3684 }
3685 if (vec_len (tap_name) > 63) {
3686 errmsg ("tap name too long\n");
3687 }
3688 vec_add1 (tap_name, 0);
3689
3690 /* Construct the API message */
3691 M(TAP_CONNECT, tap_connect);
3692
3693 mp->use_random_mac = random_mac;
Damjan Marionf1213b82016-03-13 02:22:06 +01003694 clib_memcpy (mp->mac_address, mac_address, 6);
3695 clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
Ed Warnickecb9cada2015-12-08 15:45:58 -07003696 vec_free (tap_name);
3697
3698 /* send it... */
3699 S;
3700
3701 /* Wait for a reply... */
3702 W;
3703}
3704
3705static int api_tap_modify (vat_main_t * vam)
3706{
3707 unformat_input_t * i = vam->input;
3708 vl_api_tap_modify_t *mp;
3709 f64 timeout;
3710 u8 mac_address[6];
3711 u8 random_mac = 1;
3712 u8 name_set = 0;
3713 u8 * tap_name;
3714 u32 sw_if_index = ~0;
3715 u8 sw_if_index_set = 0;
3716
3717 memset (mac_address, 0, sizeof (mac_address));
3718
3719 /* Parse args required to build the message */
3720 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3721 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3722 sw_if_index_set = 1;
3723 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3724 sw_if_index_set = 1;
3725 else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address)) {
3726 random_mac = 0;
3727 }
3728 else if (unformat (i, "random-mac"))
3729 random_mac = 1;
3730 else if (unformat (i, "tapname %s", &tap_name))
3731 name_set = 1;
3732 else
3733 break;
3734 }
3735
3736 if (sw_if_index_set == 0) {
3737 errmsg ("missing vpp interface name");
3738 return -99;
3739 }
3740 if (name_set == 0) {
3741 errmsg ("missing tap name\n");
3742 return -99;
3743 }
3744 if (vec_len (tap_name) > 63) {
3745 errmsg ("tap name too long\n");
3746 }
3747 vec_add1 (tap_name, 0);
3748
3749 /* Construct the API message */
3750 M(TAP_MODIFY, tap_modify);
3751
3752 mp->use_random_mac = random_mac;
3753 mp->sw_if_index = ntohl(sw_if_index);
Damjan Marionf1213b82016-03-13 02:22:06 +01003754 clib_memcpy (mp->mac_address, mac_address, 6);
3755 clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
Ed Warnickecb9cada2015-12-08 15:45:58 -07003756 vec_free (tap_name);
3757
3758 /* send it... */
3759 S;
3760
3761 /* Wait for a reply... */
3762 W;
3763}
3764
3765static int api_tap_delete (vat_main_t * vam)
3766{
3767 unformat_input_t * i = vam->input;
3768 vl_api_tap_delete_t *mp;
3769 f64 timeout;
3770 u32 sw_if_index = ~0;
3771 u8 sw_if_index_set = 0;
3772
3773 /* Parse args required to build the message */
3774 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3775 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3776 sw_if_index_set = 1;
3777 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3778 sw_if_index_set = 1;
3779 else
3780 break;
3781 }
3782
3783 if (sw_if_index_set == 0) {
3784 errmsg ("missing vpp interface name");
3785 return -99;
3786 }
3787
3788 /* Construct the API message */
3789 M(TAP_DELETE, tap_delete);
3790
3791 mp->sw_if_index = ntohl(sw_if_index);
3792
3793 /* send it... */
3794 S;
3795
3796 /* Wait for a reply... */
3797 W;
3798}
3799
3800static int api_ip_add_del_route (vat_main_t * vam)
3801{
3802 unformat_input_t * i = vam->input;
3803 vl_api_ip_add_del_route_t *mp;
3804 f64 timeout;
3805 u32 sw_if_index = 0, vrf_id = 0;
3806 u8 sw_if_index_set = 0;
3807 u8 is_ipv6 = 0;
3808 u8 is_local = 0, is_drop = 0;
3809 u8 create_vrf_if_needed = 0;
3810 u8 is_add = 1;
3811 u8 next_hop_weight = 1;
3812 u8 not_last = 0;
3813 u8 is_multipath = 0;
3814 u8 address_set = 0;
3815 u8 address_length_set = 0;
3816 u32 lookup_in_vrf = 0;
3817 u32 resolve_attempts = 0;
3818 u32 dst_address_length = 0;
3819 u8 next_hop_set = 0;
3820 ip4_address_t v4_dst_address, v4_next_hop_address;
3821 ip6_address_t v6_dst_address, v6_next_hop_address;
3822 int count = 1;
3823 int j;
3824 f64 before = 0;
3825 u32 random_add_del = 0;
3826 u32 * random_vector = 0;
3827 uword * random_hash;
3828 u32 random_seed = 0xdeaddabe;
3829 u32 classify_table_index = ~0;
3830 u8 is_classify = 0;
3831
3832 /* Parse args required to build the message */
3833 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3834 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3835 sw_if_index_set = 1;
3836 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3837 sw_if_index_set = 1;
3838 else if (unformat (i, "%U", unformat_ip4_address,
3839 &v4_dst_address)) {
3840 address_set = 1;
3841 is_ipv6 = 0;
3842 }
3843 else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address)) {
3844 address_set = 1;
3845 is_ipv6 = 1;
3846 }
3847 else if (unformat (i, "/%d", &dst_address_length)) {
3848 address_length_set = 1;
3849 }
3850
3851 else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
3852 &v4_next_hop_address)) {
3853 next_hop_set = 1;
3854 }
3855 else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
3856 &v6_next_hop_address)) {
3857 next_hop_set = 1;
3858 }
3859 else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
3860 ;
3861 else if (unformat (i, "weight %d", &next_hop_weight))
3862 ;
3863 else if (unformat (i, "drop")) {
3864 is_drop = 1;
3865 } else if (unformat (i, "local")) {
3866 is_local = 1;
3867 } else if (unformat (i, "classify %d", &classify_table_index)) {
3868 is_classify = 1;
3869 } else if (unformat (i, "del"))
3870 is_add = 0;
3871 else if (unformat (i, "add"))
3872 is_add = 1;
3873 else if (unformat (i, "not-last"))
3874 not_last = 1;
3875 else if (unformat (i, "multipath"))
3876 is_multipath = 1;
3877 else if (unformat (i, "vrf %d", &vrf_id))
3878 ;
3879 else if (unformat (i, "create-vrf"))
3880 create_vrf_if_needed = 1;
3881 else if (unformat (i, "count %d", &count))
3882 ;
3883 else if (unformat (i, "lookup-in-vrf %d", &lookup_in_vrf))
3884 ;
3885 else if (unformat (i, "random"))
3886 random_add_del = 1;
3887 else if (unformat (i, "seed %d", &random_seed))
3888 ;
3889 else {
3890 clib_warning ("parse error '%U'", format_unformat_error, i);
3891 return -99;
3892 }
3893 }
3894
3895 if (resolve_attempts > 0 && sw_if_index_set == 0) {
3896 errmsg ("ARP resolution needs explicit interface or sw_if_index\n");
3897 return -99;
3898 }
3899
3900 if (!next_hop_set && !is_drop && !is_local && !is_classify) {
3901 errmsg ("next hop / local / drop / classify not set\n");
3902 return -99;
3903 }
3904
3905 if (address_set == 0) {
3906 errmsg ("missing addresses\n");
3907 return -99;
3908 }
3909
3910 if (address_length_set == 0) {
3911 errmsg ("missing address length\n");
3912 return -99;
3913 }
3914
3915 /* Generate a pile of unique, random routes */
3916 if (random_add_del) {
3917 u32 this_random_address;
3918 random_hash = hash_create (count, sizeof(uword));
3919
3920 hash_set (random_hash, v4_next_hop_address.as_u32, 1);
3921 for (j = 0; j <= count; j++) {
3922 do {
3923 this_random_address = random_u32 (&random_seed);
3924 this_random_address =
3925 clib_host_to_net_u32 (this_random_address);
3926 } while (hash_get (random_hash, this_random_address));
3927 vec_add1 (random_vector, this_random_address);
3928 hash_set (random_hash, this_random_address, 1);
3929 }
3930 hash_free (random_hash);
3931 v4_dst_address.as_u32 = random_vector[0];
3932 }
3933
3934 if (count > 1) {
3935 /* Turn on async mode */
3936 vam->async_mode = 1;
3937 vam->async_errors = 0;
3938 before = vat_time_now(vam);
3939 }
3940
3941 for (j = 0; j < count; j++) {
3942 /* Construct the API message */
3943 M(IP_ADD_DEL_ROUTE, ip_add_del_route);
3944
3945 mp->next_hop_sw_if_index = ntohl (sw_if_index);
3946 mp->vrf_id = ntohl (vrf_id);
3947 if (resolve_attempts > 0) {
3948 mp->resolve_attempts = ntohl (resolve_attempts);
3949 mp->resolve_if_needed = 1;
3950 }
3951 mp->create_vrf_if_needed = create_vrf_if_needed;
3952
3953 mp->is_add = is_add;
3954 mp->is_drop = is_drop;
3955 mp->is_ipv6 = is_ipv6;
3956 mp->is_local = is_local;
3957 mp->is_classify = is_classify;
3958 mp->is_multipath = is_multipath;
3959 mp->not_last = not_last;
3960 mp->next_hop_weight = next_hop_weight;
3961 mp->dst_address_length = dst_address_length;
3962 mp->lookup_in_vrf = ntohl(lookup_in_vrf);
3963 mp->classify_table_index = ntohl(classify_table_index);
3964
3965 if (is_ipv6){
Damjan Marionf1213b82016-03-13 02:22:06 +01003966 clib_memcpy (mp->dst_address, &v6_dst_address, sizeof (v6_dst_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07003967 if (next_hop_set)
Damjan Marionf1213b82016-03-13 02:22:06 +01003968 clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
Ed Warnickecb9cada2015-12-08 15:45:58 -07003969 sizeof (v6_next_hop_address));
3970 increment_v6_address (&v6_dst_address);
3971 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01003972 clib_memcpy (mp->dst_address, &v4_dst_address, sizeof (v4_dst_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07003973 if (next_hop_set)
Damjan Marionf1213b82016-03-13 02:22:06 +01003974 clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
Ed Warnickecb9cada2015-12-08 15:45:58 -07003975 sizeof (v4_next_hop_address));
3976 if (random_add_del)
3977 v4_dst_address.as_u32 = random_vector[j+1];
3978 else
3979 increment_v4_address (&v4_dst_address);
3980 }
3981 /* send it... */
3982 S;
3983 }
3984
3985 /* When testing multiple add/del ops, use a control-ping to sync */
3986 if (count > 1) {
3987 vl_api_control_ping_t * mp;
3988 f64 after;
3989
3990 /* Shut off async mode */
3991 vam->async_mode = 0;
3992
3993 M(CONTROL_PING, control_ping);
3994 S;
3995
3996 timeout = vat_time_now(vam) + 1.0;
3997 while (vat_time_now (vam) < timeout)
3998 if (vam->result_ready == 1)
3999 goto out;
4000 vam->retval = -99;
4001
4002 out:
4003 if (vam->retval == -99)
4004 errmsg ("timeout\n");
4005
4006 if (vam->async_errors > 0) {
4007 errmsg ("%d asynchronous errors\n", vam->async_errors);
4008 vam->retval = -98;
4009 }
4010 vam->async_errors = 0;
4011 after = vat_time_now(vam);
4012
4013 fformat(vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
4014 count, after - before, count / (after - before));
4015 } else {
4016 /* Wait for a reply... */
4017 W;
4018 }
4019
4020 /* Return the good/bad news */
4021 return (vam->retval);
4022}
4023
4024static int api_proxy_arp_add_del (vat_main_t * vam)
4025{
4026 unformat_input_t * i = vam->input;
4027 vl_api_proxy_arp_add_del_t *mp;
4028 f64 timeout;
4029 u32 vrf_id = 0;
4030 u8 is_add = 1;
4031 ip4_address_t lo, hi;
4032 u8 range_set = 0;
4033
4034 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4035 if (unformat (i, "vrf %d", &vrf_id))
4036 ;
4037 else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
4038 unformat_ip4_address, &hi))
4039 range_set = 1;
4040 else if (unformat (i, "del"))
4041 is_add = 0;
4042 else {
4043 clib_warning ("parse error '%U'", format_unformat_error, i);
4044 return -99;
4045 }
4046 }
4047
4048 if (range_set == 0) {
4049 errmsg ("address range not set\n");
4050 return -99;
4051 }
4052
4053 M(PROXY_ARP_ADD_DEL, proxy_arp_add_del);
4054
4055 mp->vrf_id = ntohl(vrf_id);
4056 mp->is_add = is_add;
Damjan Marionf1213b82016-03-13 02:22:06 +01004057 clib_memcpy(mp->low_address, &lo, sizeof (mp->low_address));
4058 clib_memcpy(mp->hi_address, &hi, sizeof (mp->hi_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004059
4060 S; W;
4061 /* NOTREACHED */
4062 return 0;
4063}
4064
4065static int api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
4066{
4067 unformat_input_t * i = vam->input;
4068 vl_api_proxy_arp_intfc_enable_disable_t *mp;
4069 f64 timeout;
4070 u32 sw_if_index;
4071 u8 enable = 1;
4072 u8 sw_if_index_set = 0;
4073
4074 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4075 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4076 sw_if_index_set = 1;
4077 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4078 sw_if_index_set = 1;
4079 else if (unformat (i, "enable"))
4080 enable = 1;
4081 else if (unformat (i, "disable"))
4082 enable = 0;
4083 else {
4084 clib_warning ("parse error '%U'", format_unformat_error, i);
4085 return -99;
4086 }
4087 }
4088
4089 if (sw_if_index_set == 0) {
4090 errmsg ("missing interface name or sw_if_index\n");
4091 return -99;
4092 }
4093
4094 M(PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
4095
4096 mp->sw_if_index = ntohl(sw_if_index);
4097 mp->enable_disable = enable;
4098
4099 S; W;
4100 /* NOTREACHED */
4101 return 0;
4102}
4103
4104static int api_mpls_add_del_decap (vat_main_t * vam)
4105{
4106 unformat_input_t * i = vam->input;
4107 vl_api_mpls_add_del_decap_t *mp;
4108 f64 timeout;
4109 u32 rx_vrf_id = 0;
4110 u32 tx_vrf_id = 0;
4111 u32 label = 0;
4112 u8 is_add = 1;
4113 u8 s_bit = 1;
4114 u32 next_index = 1;
4115
4116 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4117 if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
4118 ;
4119 else if (unformat (i, "tx_vrf_id %d", &tx_vrf_id))
4120 ;
4121 else if (unformat (i, "label %d", &label))
4122 ;
4123 else if (unformat (i, "next-index %d", &next_index))
4124 ;
4125 else if (unformat (i, "del"))
4126 is_add = 0;
4127 else if (unformat (i, "s-bit-clear"))
4128 s_bit = 0;
4129 else {
4130 clib_warning ("parse error '%U'", format_unformat_error, i);
4131 return -99;
4132 }
4133 }
4134
4135 M(MPLS_ADD_DEL_DECAP, mpls_add_del_decap);
4136
4137 mp->rx_vrf_id = ntohl(rx_vrf_id);
4138 mp->tx_vrf_id = ntohl(tx_vrf_id);
4139 mp->label = ntohl(label);
4140 mp->next_index = ntohl(next_index);
4141 mp->s_bit = s_bit;
4142 mp->is_add = is_add;
4143
4144 S; W;
4145 /* NOTREACHED */
4146 return 0;
4147}
4148
4149static int api_mpls_add_del_encap (vat_main_t * vam)
4150{
4151 unformat_input_t * i = vam->input;
4152 vl_api_mpls_add_del_encap_t *mp;
4153 f64 timeout;
4154 u32 vrf_id = 0;
4155 u32 *labels = 0;
4156 u32 label;
4157 ip4_address_t dst_address;
4158 u8 is_add = 1;
4159
4160 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4161 if (unformat (i, "vrf %d", &vrf_id))
4162 ;
4163 else if (unformat (i, "label %d", &label))
4164 vec_add1 (labels, ntohl(label));
4165 else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
4166 ;
4167 else if (unformat (i, "del"))
4168 is_add = 0;
4169 else {
4170 clib_warning ("parse error '%U'", format_unformat_error, i);
4171 return -99;
4172 }
4173 }
4174
4175 if (vec_len (labels) == 0) {
4176 errmsg ("missing encap label stack\n");
4177 return -99;
4178 }
4179
4180 M2(MPLS_ADD_DEL_ENCAP, mpls_add_del_encap,
4181 sizeof (u32) * vec_len (labels));
4182
4183 mp->vrf_id = ntohl(vrf_id);
Damjan Marionf1213b82016-03-13 02:22:06 +01004184 clib_memcpy(mp->dst_address, &dst_address, sizeof (dst_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004185 mp->is_add = is_add;
4186 mp->nlabels = vec_len (labels);
Damjan Marionf1213b82016-03-13 02:22:06 +01004187 clib_memcpy(mp->labels, labels, sizeof(u32)*mp->nlabels);
Ed Warnickecb9cada2015-12-08 15:45:58 -07004188
4189 vec_free(labels);
4190
4191 S; W;
4192 /* NOTREACHED */
4193 return 0;
4194}
4195
4196static int api_mpls_gre_add_del_tunnel (vat_main_t * vam)
4197{
4198 unformat_input_t * i = vam->input;
4199 vl_api_mpls_gre_add_del_tunnel_t *mp;
4200 f64 timeout;
4201 u32 inner_vrf_id = 0;
4202 u32 outer_vrf_id = 0;
4203 ip4_address_t src_address;
4204 ip4_address_t dst_address;
4205 ip4_address_t intfc_address;
4206 u32 tmp;
4207 u8 intfc_address_length = 0;
4208 u8 is_add = 1;
4209 u8 l2_only = 0;
4210
4211 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4212 if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
4213 ;
4214 else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
4215 ;
4216 else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
4217 ;
4218 else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
4219 ;
4220 else if (unformat (i, "adj %U/%d", unformat_ip4_address,
4221 &intfc_address, &tmp))
4222 intfc_address_length = tmp;
4223 else if (unformat (i, "l2-only"))
4224 l2_only = 1;
4225 else if (unformat (i, "del"))
4226 is_add = 0;
4227 else {
4228 clib_warning ("parse error '%U'", format_unformat_error, i);
4229 return -99;
4230 }
4231 }
4232
4233 M(MPLS_GRE_ADD_DEL_TUNNEL, mpls_gre_add_del_tunnel);
4234
4235 mp->inner_vrf_id = ntohl(inner_vrf_id);
4236 mp->outer_vrf_id = ntohl(outer_vrf_id);
Damjan Marionf1213b82016-03-13 02:22:06 +01004237 clib_memcpy(mp->src_address, &src_address, sizeof (src_address));
4238 clib_memcpy(mp->dst_address, &dst_address, sizeof (dst_address));
4239 clib_memcpy(mp->intfc_address, &intfc_address, sizeof (intfc_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004240 mp->intfc_address_length = intfc_address_length;
4241 mp->l2_only = l2_only;
4242 mp->is_add = is_add;
4243
4244 S; W;
4245 /* NOTREACHED */
4246 return 0;
4247}
4248
4249static int api_mpls_ethernet_add_del_tunnel (vat_main_t * vam)
4250{
4251 unformat_input_t * i = vam->input;
4252 vl_api_mpls_ethernet_add_del_tunnel_t *mp;
4253 f64 timeout;
4254 u32 inner_vrf_id = 0;
4255 ip4_address_t intfc_address;
4256 u8 dst_mac_address[6];
4257 int dst_set = 1;
4258 u32 tmp;
4259 u8 intfc_address_length = 0;
4260 u8 is_add = 1;
4261 u8 l2_only = 0;
4262 u32 tx_sw_if_index;
4263 int tx_sw_if_index_set = 0;
4264
4265 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4266 if (unformat (i, "vrf %d", &inner_vrf_id))
4267 ;
4268 else if (unformat (i, "adj %U/%d", unformat_ip4_address,
4269 &intfc_address, &tmp))
4270 intfc_address_length = tmp;
4271 else if (unformat (i, "%U",
4272 unformat_sw_if_index, vam, &tx_sw_if_index))
4273 tx_sw_if_index_set = 1;
4274 else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
4275 tx_sw_if_index_set = 1;
4276 else if (unformat (i, "dst %U", unformat_ethernet_address,
4277 dst_mac_address))
4278 dst_set = 1;
4279 else if (unformat (i, "l2-only"))
4280 l2_only = 1;
4281 else if (unformat (i, "del"))
4282 is_add = 0;
4283 else {
4284 clib_warning ("parse error '%U'", format_unformat_error, i);
4285 return -99;
4286 }
4287 }
4288
4289 if (!dst_set) {
4290 errmsg ("dst (mac address) not set\n");
4291 return -99;
4292 }
4293 if (!tx_sw_if_index_set) {
4294 errmsg ("tx-intfc not set\n");
4295 return -99;
4296 }
4297
4298 M(MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel);
4299
4300 mp->vrf_id = ntohl(inner_vrf_id);
Damjan Marionf1213b82016-03-13 02:22:06 +01004301 clib_memcpy (mp->adj_address, &intfc_address, sizeof (intfc_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004302 mp->adj_address_length = intfc_address_length;
Damjan Marionf1213b82016-03-13 02:22:06 +01004303 clib_memcpy (mp->dst_mac_address, dst_mac_address, sizeof (dst_mac_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004304 mp->tx_sw_if_index = ntohl(tx_sw_if_index);
4305 mp->l2_only = l2_only;
4306 mp->is_add = is_add;
4307
4308 S; W;
4309 /* NOTREACHED */
4310 return 0;
4311}
4312
4313static int api_mpls_ethernet_add_del_tunnel_2 (vat_main_t * vam)
4314{
4315 unformat_input_t * i = vam->input;
4316 vl_api_mpls_ethernet_add_del_tunnel_2_t *mp;
4317 f64 timeout;
4318 u32 inner_vrf_id = 0;
4319 u32 outer_vrf_id = 0;
4320 ip4_address_t adj_address;
4321 int adj_address_set = 0;
4322 ip4_address_t next_hop_address;
4323 int next_hop_address_set = 0;
4324 u32 tmp;
4325 u8 adj_address_length = 0;
4326 u8 l2_only = 0;
4327 u8 is_add = 1;
4328 u32 resolve_attempts = 5;
4329 u8 resolve_if_needed = 1;
4330
4331 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4332 if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
4333 ;
4334 else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
4335 ;
4336 else if (unformat (i, "adj %U/%d", unformat_ip4_address,
4337 &adj_address, &tmp)) {
4338 adj_address_length = tmp;
4339 adj_address_set = 1;
4340 }
4341 else if (unformat (i, "next-hop %U", unformat_ip4_address,
4342 &next_hop_address))
4343 next_hop_address_set = 1;
4344 else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
4345 ;
4346 else if (unformat (i, "resolve-if-needed %d", &tmp))
4347 resolve_if_needed = tmp;
4348 else if (unformat (i, "l2-only"))
4349 l2_only = 1;
4350 else if (unformat (i, "del"))
4351 is_add = 0;
4352 else {
4353 clib_warning ("parse error '%U'", format_unformat_error, i);
4354 return -99;
4355 }
4356 }
4357
4358 if (!adj_address_set) {
4359 errmsg ("adjacency address/mask not set\n");
4360 return -99;
4361 }
4362 if (!next_hop_address_set) {
4363 errmsg ("ip4 next hop address (in outer fib) not set\n");
4364 return -99;
4365 }
4366
4367 M(MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2);
4368
4369 mp->inner_vrf_id = ntohl(inner_vrf_id);
4370 mp->outer_vrf_id = ntohl(outer_vrf_id);
4371 mp->resolve_attempts = ntohl(resolve_attempts);
4372 mp->resolve_if_needed = resolve_if_needed;
4373 mp->is_add = is_add;
4374 mp->l2_only = l2_only;
Damjan Marionf1213b82016-03-13 02:22:06 +01004375 clib_memcpy (mp->adj_address, &adj_address, sizeof (adj_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004376 mp->adj_address_length = adj_address_length;
Damjan Marionf1213b82016-03-13 02:22:06 +01004377 clib_memcpy (mp->next_hop_ip4_address_in_outer_vrf, &next_hop_address,
Ed Warnickecb9cada2015-12-08 15:45:58 -07004378 sizeof (next_hop_address));
4379
4380 S; W;
4381 /* NOTREACHED */
4382 return 0;
4383}
4384
4385static int api_sw_interface_set_unnumbered (vat_main_t * vam)
4386{
4387 unformat_input_t * i = vam->input;
4388 vl_api_sw_interface_set_unnumbered_t *mp;
4389 f64 timeout;
4390 u32 sw_if_index;
4391 u32 unnum_sw_index;
4392 u8 is_add = 1;
4393 u8 sw_if_index_set = 0;
4394
4395 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4396 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4397 sw_if_index_set = 1;
4398 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4399 sw_if_index_set = 1;
4400 else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
4401 ;
4402 else if (unformat (i, "del"))
4403 is_add = 0;
4404 else {
4405 clib_warning ("parse error '%U'", format_unformat_error, i);
4406 return -99;
4407 }
4408 }
4409
4410 if (sw_if_index_set == 0) {
4411 errmsg ("missing interface name or sw_if_index\n");
4412 return -99;
4413 }
4414
4415 M(SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
4416
4417 mp->sw_if_index = ntohl(sw_if_index);
4418 mp->unnumbered_sw_if_index = ntohl(unnum_sw_index);
4419 mp->is_add = is_add;
4420
4421 S; W;
4422 /* NOTREACHED */
4423 return 0;
4424}
4425
4426static int api_ip_neighbor_add_del (vat_main_t * vam)
4427{
4428 unformat_input_t * i = vam->input;
4429 vl_api_ip_neighbor_add_del_t *mp;
4430 f64 timeout;
4431 u32 sw_if_index;
4432 u8 sw_if_index_set = 0;
4433 u32 vrf_id = 0;
4434 u8 is_add = 1;
4435 u8 is_static = 0;
4436 u8 mac_address[6];
4437 u8 mac_set = 0;
4438 u8 v4_address_set = 0;
4439 u8 v6_address_set = 0;
4440 ip4_address_t v4address;
4441 ip6_address_t v6address;
4442
4443 memset (mac_address, 0, sizeof (mac_address));
4444
4445 /* Parse args required to build the message */
4446 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4447 if (unformat (i, "mac %U", unformat_ethernet_address, mac_address)) {
4448 mac_set = 1;
4449 }
4450 else if (unformat (i, "del"))
4451 is_add = 0;
4452 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4453 sw_if_index_set = 1;
4454 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4455 sw_if_index_set = 1;
4456 else if (unformat (i, "is_static"))
4457 is_static = 1;
4458 else if (unformat (i, "vrf %d", &vrf_id))
4459 ;
4460 else if (unformat (i, "dst %U",
4461 unformat_ip4_address, &v4address))
4462 v4_address_set = 1;
4463 else if (unformat (i, "dst %U",
4464 unformat_ip6_address, &v6address))
4465 v6_address_set = 1;
4466 else {
4467 clib_warning ("parse error '%U'", format_unformat_error, i);
4468 return -99;
4469 }
4470 }
4471
4472 if (sw_if_index_set == 0) {
4473 errmsg ("missing interface name or sw_if_index\n");
4474 return -99;
4475 }
4476 if (v4_address_set && v6_address_set) {
4477 errmsg ("both v4 and v6 addresses set\n");
4478 return -99;
4479 }
4480 if (!v4_address_set && !v6_address_set) {
4481 errmsg ("no addresses set\n");
4482 return -99;
4483 }
4484
4485 /* Construct the API message */
4486 M(IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
4487
4488 mp->sw_if_index = ntohl (sw_if_index);
4489 mp->is_add = is_add;
4490 mp->vrf_id = ntohl (vrf_id);
4491 mp->is_static = is_static;
4492 if (mac_set)
Damjan Marionf1213b82016-03-13 02:22:06 +01004493 clib_memcpy (mp->mac_address, mac_address, 6);
Ed Warnickecb9cada2015-12-08 15:45:58 -07004494 if (v6_address_set) {
4495 mp->is_ipv6 = 1;
Damjan Marionf1213b82016-03-13 02:22:06 +01004496 clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004497 } else {
4498 /* mp->is_ipv6 = 0; via memset in M macro above */
Damjan Marionf1213b82016-03-13 02:22:06 +01004499 clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004500 }
4501
4502 /* send it... */
4503 S;
4504
4505 /* Wait for a reply, return good/bad news */
4506 W;
4507
4508 /* NOTREACHED */
4509 return 0;
4510}
4511
4512static int api_reset_vrf (vat_main_t * vam)
4513{
4514 unformat_input_t * i = vam->input;
4515 vl_api_reset_vrf_t *mp;
4516 f64 timeout;
4517 u32 vrf_id = 0;
4518 u8 is_ipv6 = 0;
4519 u8 vrf_id_set = 0;
4520
4521 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4522 if (unformat (i, "vrf %d", &vrf_id))
4523 vrf_id_set = 1;
4524 else if (unformat (i, "ipv6"))
4525 is_ipv6 = 1;
4526 else {
4527 clib_warning ("parse error '%U'", format_unformat_error, i);
4528 return -99;
4529 }
4530 }
4531
4532 if (vrf_id_set == 0) {
4533 errmsg ("missing vrf id\n");
4534 return -99;
4535 }
4536
4537 M(RESET_VRF, reset_vrf);
4538
4539 mp->vrf_id = ntohl(vrf_id);
4540 mp->is_ipv6 = is_ipv6;
4541
4542 S; W;
4543 /* NOTREACHED */
4544 return 0;
4545}
4546
4547static int api_create_vlan_subif (vat_main_t * vam)
4548{
4549 unformat_input_t * i = vam->input;
4550 vl_api_create_vlan_subif_t *mp;
4551 f64 timeout;
4552 u32 sw_if_index;
4553 u8 sw_if_index_set = 0;
4554 u32 vlan_id;
4555 u8 vlan_id_set = 0;
4556
4557 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4558 if (unformat (i, "sw_if_index %d", &sw_if_index))
4559 sw_if_index_set = 1;
4560 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4561 sw_if_index_set = 1;
4562 else if (unformat (i, "vlan %d", &vlan_id))
4563 vlan_id_set = 1;
4564 else {
4565 clib_warning ("parse error '%U'", format_unformat_error, i);
4566 return -99;
4567 }
4568 }
4569
4570 if (sw_if_index_set == 0) {
4571 errmsg ("missing interface name or sw_if_index\n");
4572 return -99;
4573 }
4574
4575 if (vlan_id_set == 0) {
4576 errmsg ("missing vlan_id\n");
4577 return -99;
4578 }
4579 M(CREATE_VLAN_SUBIF, create_vlan_subif);
4580
4581 mp->sw_if_index = ntohl(sw_if_index);
4582 mp->vlan_id = ntohl(vlan_id);
4583
4584 S; W;
4585 /* NOTREACHED */
4586 return 0;
4587}
4588
4589#define foreach_create_subif_bit \
4590_(no_tags) \
4591_(one_tag) \
4592_(two_tags) \
4593_(dot1ad) \
4594_(exact_match) \
4595_(default_sub) \
4596_(outer_vlan_id_any) \
4597_(inner_vlan_id_any)
4598
4599static int api_create_subif (vat_main_t * vam)
4600{
4601 unformat_input_t * i = vam->input;
4602 vl_api_create_subif_t *mp;
4603 f64 timeout;
4604 u32 sw_if_index;
4605 u8 sw_if_index_set = 0;
4606 u32 sub_id;
4607 u8 sub_id_set = 0;
4608 u32 no_tags = 0;
4609 u32 one_tag = 0;
4610 u32 two_tags = 0;
4611 u32 dot1ad = 0;
4612 u32 exact_match = 0;
4613 u32 default_sub = 0;
4614 u32 outer_vlan_id_any = 0;
4615 u32 inner_vlan_id_any = 0;
4616 u32 tmp;
4617 u16 outer_vlan_id = 0;
4618 u16 inner_vlan_id = 0;
4619
4620 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4621 if (unformat (i, "sw_if_index %d", &sw_if_index))
4622 sw_if_index_set = 1;
4623 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4624 sw_if_index_set = 1;
4625 else if (unformat (i, "sub_id %d", &sub_id))
4626 sub_id_set = 1;
4627 else if (unformat (i, "outer_vlan_id %d", &tmp))
4628 outer_vlan_id = tmp;
4629 else if (unformat (i, "inner_vlan_id %d", &tmp))
4630 inner_vlan_id = tmp;
4631
4632#define _(a) else if (unformat (i, #a)) a = 1 ;
4633 foreach_create_subif_bit
4634#undef _
4635
4636 else {
4637 clib_warning ("parse error '%U'", format_unformat_error, i);
4638 return -99;
4639 }
4640 }
4641
4642 if (sw_if_index_set == 0) {
4643 errmsg ("missing interface name or sw_if_index\n");
4644 return -99;
4645 }
4646
4647 if (sub_id_set == 0) {
4648 errmsg ("missing sub_id\n");
4649 return -99;
4650 }
4651 M(CREATE_SUBIF, create_subif);
4652
4653 mp->sw_if_index = ntohl(sw_if_index);
4654 mp->sub_id = ntohl(sub_id);
4655
4656#define _(a) mp->a = a;
4657 foreach_create_subif_bit;
4658#undef _
4659
4660 mp->outer_vlan_id = ntohs (outer_vlan_id);
4661 mp->inner_vlan_id = ntohs (inner_vlan_id);
4662
4663 S; W;
4664 /* NOTREACHED */
4665 return 0;
4666}
4667
4668static int api_oam_add_del (vat_main_t * vam)
4669{
4670 unformat_input_t * i = vam->input;
4671 vl_api_oam_add_del_t *mp;
4672 f64 timeout;
4673 u32 vrf_id = 0;
4674 u8 is_add = 1;
4675 ip4_address_t src, dst;
4676 u8 src_set = 0;
4677 u8 dst_set = 0;
4678
4679 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4680 if (unformat (i, "vrf %d", &vrf_id))
4681 ;
4682 else if (unformat (i, "src %U", unformat_ip4_address, &src))
4683 src_set = 1;
4684 else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
4685 dst_set = 1;
4686 else if (unformat (i, "del"))
4687 is_add = 0;
4688 else {
4689 clib_warning ("parse error '%U'", format_unformat_error, i);
4690 return -99;
4691 }
4692 }
4693
4694 if (src_set == 0) {
4695 errmsg ("missing src addr\n");
4696 return -99;
4697 }
4698
4699 if (dst_set == 0) {
4700 errmsg ("missing dst addr\n");
4701 return -99;
4702 }
4703
4704 M(OAM_ADD_DEL, oam_add_del);
4705
4706 mp->vrf_id = ntohl(vrf_id);
4707 mp->is_add = is_add;
Damjan Marionf1213b82016-03-13 02:22:06 +01004708 clib_memcpy(mp->src_address, &src, sizeof (mp->src_address));
4709 clib_memcpy(mp->dst_address, &dst, sizeof (mp->dst_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004710
4711 S; W;
4712 /* NOTREACHED */
4713 return 0;
4714}
4715
4716static int api_reset_fib (vat_main_t * vam)
4717{
4718 unformat_input_t * i = vam->input;
4719 vl_api_reset_fib_t *mp;
4720 f64 timeout;
4721 u32 vrf_id = 0;
4722 u8 is_ipv6 = 0;
4723 u8 vrf_id_set = 0;
4724
4725 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4726 if (unformat (i, "vrf %d", &vrf_id))
4727 vrf_id_set = 1;
4728 else if (unformat (i, "ipv6"))
4729 is_ipv6 = 1;
4730 else {
4731 clib_warning ("parse error '%U'", format_unformat_error, i);
4732 return -99;
4733 }
4734 }
4735
4736 if (vrf_id_set == 0) {
4737 errmsg ("missing vrf id\n");
4738 return -99;
4739 }
4740
4741 M(RESET_FIB, reset_fib);
4742
4743 mp->vrf_id = ntohl(vrf_id);
4744 mp->is_ipv6 = is_ipv6;
4745
4746 S; W;
4747 /* NOTREACHED */
4748 return 0;
4749}
4750
4751static int api_dhcp_proxy_config (vat_main_t * vam)
4752{
4753 unformat_input_t * i = vam->input;
4754 vl_api_dhcp_proxy_config_t *mp;
4755 f64 timeout;
4756 u32 vrf_id = 0;
4757 u8 is_add = 1;
4758 u8 insert_cid = 1;
4759 u8 v4_address_set = 0;
4760 u8 v6_address_set = 0;
4761 ip4_address_t v4address;
4762 ip6_address_t v6address;
4763 u8 v4_src_address_set = 0;
4764 u8 v6_src_address_set = 0;
4765 ip4_address_t v4srcaddress;
4766 ip6_address_t v6srcaddress;
4767
4768 /* Parse args required to build the message */
4769 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4770 if (unformat (i, "del"))
4771 is_add = 0;
4772 else if (unformat (i, "vrf %d", &vrf_id))
4773 ;
4774 else if (unformat (i, "insert-cid %d", &insert_cid))
4775 ;
4776 else if (unformat (i, "svr %U",
4777 unformat_ip4_address, &v4address))
4778 v4_address_set = 1;
4779 else if (unformat (i, "svr %U",
4780 unformat_ip6_address, &v6address))
4781 v6_address_set = 1;
4782 else if (unformat (i, "src %U",
4783 unformat_ip4_address, &v4srcaddress))
4784 v4_src_address_set = 1;
4785 else if (unformat (i, "src %U",
4786 unformat_ip6_address, &v6srcaddress))
4787 v6_src_address_set = 1;
4788 else
4789 break;
4790 }
4791
4792 if (v4_address_set && v6_address_set) {
4793 errmsg ("both v4 and v6 server addresses set\n");
4794 return -99;
4795 }
4796 if (!v4_address_set && !v6_address_set) {
4797 errmsg ("no server addresses set\n");
4798 return -99;
4799 }
4800
4801 if (v4_src_address_set && v6_src_address_set) {
4802 errmsg ("both v4 and v6 src addresses set\n");
4803 return -99;
4804 }
4805 if (!v4_src_address_set && !v6_src_address_set) {
4806 errmsg ("no src addresses set\n");
4807 return -99;
4808 }
4809
4810 if (!(v4_src_address_set && v4_address_set) &&
4811 !(v6_src_address_set && v6_address_set)) {
4812 errmsg ("no matching server and src addresses set\n");
4813 return -99;
4814 }
4815
4816 /* Construct the API message */
4817 M(DHCP_PROXY_CONFIG, dhcp_proxy_config);
4818
4819 mp->insert_circuit_id = insert_cid;
4820 mp->is_add = is_add;
4821 mp->vrf_id = ntohl (vrf_id);
4822 if (v6_address_set) {
4823 mp->is_ipv6 = 1;
Damjan Marionf1213b82016-03-13 02:22:06 +01004824 clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
4825 clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004826 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01004827 clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
4828 clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004829 }
4830
4831 /* send it... */
4832 S;
4833
4834 /* Wait for a reply, return good/bad news */
4835 W;
4836 /* NOTREACHED */
4837 return 0;
4838}
4839
4840static int api_dhcp_proxy_config_2 (vat_main_t * vam)
4841{
4842 unformat_input_t * i = vam->input;
4843 vl_api_dhcp_proxy_config_2_t *mp;
4844 f64 timeout;
4845 u32 rx_vrf_id = 0;
4846 u32 server_vrf_id = 0;
4847 u8 is_add = 1;
4848 u8 insert_cid = 1;
4849 u8 v4_address_set = 0;
4850 u8 v6_address_set = 0;
4851 ip4_address_t v4address;
4852 ip6_address_t v6address;
4853 u8 v4_src_address_set = 0;
4854 u8 v6_src_address_set = 0;
4855 ip4_address_t v4srcaddress;
4856 ip6_address_t v6srcaddress;
4857
4858 /* Parse args required to build the message */
4859 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4860 if (unformat (i, "del"))
4861 is_add = 0;
4862 else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
4863 ;
4864 else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
4865 ;
4866 else if (unformat (i, "insert-cid %d", &insert_cid))
4867 ;
4868 else if (unformat (i, "svr %U",
4869 unformat_ip4_address, &v4address))
4870 v4_address_set = 1;
4871 else if (unformat (i, "svr %U",
4872 unformat_ip6_address, &v6address))
4873 v6_address_set = 1;
4874 else if (unformat (i, "src %U",
4875 unformat_ip4_address, &v4srcaddress))
4876 v4_src_address_set = 1;
4877 else if (unformat (i, "src %U",
4878 unformat_ip6_address, &v6srcaddress))
4879 v6_src_address_set = 1;
4880 else
4881 break;
4882 }
4883
4884 if (v4_address_set && v6_address_set) {
4885 errmsg ("both v4 and v6 server addresses set\n");
4886 return -99;
4887 }
4888 if (!v4_address_set && !v6_address_set) {
4889 errmsg ("no server addresses set\n");
4890 return -99;
4891 }
4892
4893 if (v4_src_address_set && v6_src_address_set) {
4894 errmsg ("both v4 and v6 src addresses set\n");
4895 return -99;
4896 }
4897 if (!v4_src_address_set && !v6_src_address_set) {
4898 errmsg ("no src addresses set\n");
4899 return -99;
4900 }
4901
4902 if (!(v4_src_address_set && v4_address_set) &&
4903 !(v6_src_address_set && v6_address_set)) {
4904 errmsg ("no matching server and src addresses set\n");
4905 return -99;
4906 }
4907
4908 /* Construct the API message */
4909 M(DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
4910
4911 mp->insert_circuit_id = insert_cid;
4912 mp->is_add = is_add;
4913 mp->rx_vrf_id = ntohl (rx_vrf_id);
4914 mp->server_vrf_id = ntohl (server_vrf_id);
4915 if (v6_address_set) {
4916 mp->is_ipv6 = 1;
Damjan Marionf1213b82016-03-13 02:22:06 +01004917 clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
4918 clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004919 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01004920 clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
4921 clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004922 }
4923
4924 /* send it... */
4925 S;
4926
4927 /* Wait for a reply, return good/bad news */
4928 W;
4929 /* NOTREACHED */
4930 return 0;
4931}
4932
4933static int api_dhcp_proxy_set_vss (vat_main_t * vam)
4934{
4935 unformat_input_t * i = vam->input;
4936 vl_api_dhcp_proxy_set_vss_t *mp;
4937 f64 timeout;
4938 u8 is_ipv6 = 0;
4939 u8 is_add = 1;
4940 u32 tbl_id;
4941 u8 tbl_id_set = 0;
4942 u32 oui;
4943 u8 oui_set = 0;
4944 u32 fib_id;
4945 u8 fib_id_set = 0;
4946
4947 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4948 if (unformat (i, "tbl_id %d", &tbl_id))
4949 tbl_id_set = 1;
4950 if (unformat (i, "fib_id %d", &fib_id))
4951 fib_id_set = 1;
4952 if (unformat (i, "oui %d", &oui))
4953 oui_set = 1;
4954 else if (unformat (i, "ipv6"))
4955 is_ipv6 = 1;
4956 else if (unformat (i, "del"))
4957 is_add = 0;
4958 else {
4959 clib_warning ("parse error '%U'", format_unformat_error, i);
4960 return -99;
4961 }
4962 }
4963
4964 if (tbl_id_set == 0) {
4965 errmsg ("missing tbl id\n");
4966 return -99;
4967 }
4968
4969 if (fib_id_set == 0) {
4970 errmsg ("missing fib id\n");
4971 return -99;
4972 }
4973 if (oui_set == 0) {
4974 errmsg ("missing oui\n");
4975 return -99;
4976 }
4977
4978 M(DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
4979 mp->tbl_id = ntohl(tbl_id);
4980 mp->fib_id = ntohl(fib_id);
4981 mp->oui = ntohl(oui);
4982 mp->is_ipv6 = is_ipv6;
4983 mp->is_add = is_add;
4984
4985 S; W;
4986 /* NOTREACHED */
4987 return 0;
4988}
4989
4990static int api_dhcp_client_config (vat_main_t * vam)
4991{
4992 unformat_input_t * i = vam->input;
4993 vl_api_dhcp_client_config_t *mp;
4994 f64 timeout;
4995 u32 sw_if_index;
4996 u8 sw_if_index_set = 0;
4997 u8 is_add = 1;
4998 u8 * hostname = 0;
4999 u8 disable_event = 0;
5000
5001 /* Parse args required to build the message */
5002 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5003 if (unformat (i, "del"))
5004 is_add = 0;
5005 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5006 sw_if_index_set = 1;
5007 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5008 sw_if_index_set = 1;
5009 else if (unformat (i, "hostname %s", &hostname))
5010 ;
5011 else if (unformat (i, "disable_event"))
5012 disable_event = 1;
5013 else
5014 break;
5015 }
5016
5017 if (sw_if_index_set == 0) {
5018 errmsg ("missing interface name or sw_if_index\n");
5019 return -99;
5020 }
5021
5022 if (vec_len (hostname) > 63) {
5023 errmsg ("hostname too long\n");
5024 }
5025 vec_add1 (hostname, 0);
5026
5027 /* Construct the API message */
5028 M(DHCP_CLIENT_CONFIG, dhcp_client_config);
5029
5030 mp->sw_if_index = ntohl (sw_if_index);
Damjan Marionf1213b82016-03-13 02:22:06 +01005031 clib_memcpy (mp->hostname, hostname, vec_len (hostname));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005032 vec_free (hostname);
5033 mp->is_add = is_add;
5034 mp->want_dhcp_event = disable_event ? 0 : 1;
5035 mp->pid = getpid();
5036
5037 /* send it... */
5038 S;
5039
5040 /* Wait for a reply, return good/bad news */
5041 W;
5042 /* NOTREACHED */
5043 return 0;
5044}
5045
5046static int api_set_ip_flow_hash (vat_main_t * vam)
5047{
5048 unformat_input_t * i = vam->input;
5049 vl_api_set_ip_flow_hash_t *mp;
5050 f64 timeout;
5051 u32 vrf_id = 0;
5052 u8 is_ipv6 = 0;
5053 u8 vrf_id_set = 0;
5054 u8 src = 0;
5055 u8 dst = 0;
5056 u8 sport = 0;
5057 u8 dport = 0;
5058 u8 proto = 0;
5059 u8 reverse = 0;
5060
5061 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5062 if (unformat (i, "vrf %d", &vrf_id))
5063 vrf_id_set = 1;
5064 else if (unformat (i, "ipv6"))
5065 is_ipv6 = 1;
5066 else if (unformat (i, "src"))
5067 src = 1;
5068 else if (unformat (i, "dst"))
5069 dst = 1;
5070 else if (unformat (i, "sport"))
5071 sport = 1;
5072 else if (unformat (i, "dport"))
5073 dport = 1;
5074 else if (unformat (i, "proto"))
5075 proto = 1;
5076 else if (unformat (i, "reverse"))
5077 reverse = 1;
5078
5079 else {
5080 clib_warning ("parse error '%U'", format_unformat_error, i);
5081 return -99;
5082 }
5083 }
5084
5085 if (vrf_id_set == 0) {
5086 errmsg ("missing vrf id\n");
5087 return -99;
5088 }
5089
5090 M(SET_IP_FLOW_HASH, set_ip_flow_hash);
5091 mp->src = src;
5092 mp->dst = dst;
5093 mp->sport = sport;
5094 mp->dport = dport;
5095 mp->proto = proto;
5096 mp->reverse = reverse;
5097 mp->vrf_id = ntohl(vrf_id);
5098 mp->is_ipv6 = is_ipv6;
5099
5100 S; W;
5101 /* NOTREACHED */
5102 return 0;
5103}
5104
5105static int api_sw_interface_ip6_enable_disable (vat_main_t * vam)
5106{
5107 unformat_input_t * i = vam->input;
5108 vl_api_sw_interface_ip6_enable_disable_t *mp;
5109 f64 timeout;
5110 u32 sw_if_index;
5111 u8 sw_if_index_set = 0;
5112 u8 enable = 0;
5113
5114 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5115 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5116 sw_if_index_set = 1;
5117 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5118 sw_if_index_set = 1;
5119 else if (unformat (i, "enable"))
5120 enable = 1;
5121 else if (unformat (i, "disable"))
5122 enable = 0;
5123 else {
5124 clib_warning ("parse error '%U'", format_unformat_error, i);
5125 return -99;
5126 }
5127 }
5128
5129 if (sw_if_index_set == 0) {
5130 errmsg ("missing interface name or sw_if_index\n");
5131 return -99;
5132 }
5133
5134 M(SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
5135
5136 mp->sw_if_index = ntohl(sw_if_index);
5137 mp->enable = enable;
5138
5139 S; W;
5140 /* NOTREACHED */
5141 return 0;
5142}
5143
5144static int api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
5145{
5146 unformat_input_t * i = vam->input;
5147 vl_api_sw_interface_ip6_set_link_local_address_t *mp;
5148 f64 timeout;
5149 u32 sw_if_index;
5150 u8 sw_if_index_set = 0;
5151 u32 address_length = 0;
5152 u8 v6_address_set = 0;
5153 ip6_address_t v6address;
5154
5155 /* Parse args required to build the message */
5156 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5157 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5158 sw_if_index_set = 1;
5159 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5160 sw_if_index_set = 1;
5161 else if (unformat (i, "%U/%d",
5162 unformat_ip6_address, &v6address,
5163 &address_length))
5164 v6_address_set = 1;
5165 else
5166 break;
5167 }
5168
5169 if (sw_if_index_set == 0) {
5170 errmsg ("missing interface name or sw_if_index\n");
5171 return -99;
5172 }
5173 if (!v6_address_set) {
5174 errmsg ("no address set\n");
5175 return -99;
5176 }
5177
5178 /* Construct the API message */
5179 M(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, \
5180 sw_interface_ip6_set_link_local_address);
5181
5182 mp->sw_if_index = ntohl (sw_if_index);
Damjan Marionf1213b82016-03-13 02:22:06 +01005183 clib_memcpy (mp->address, &v6address, sizeof (v6address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005184 mp->address_length = address_length;
5185
5186 /* send it... */
5187 S;
5188
5189 /* Wait for a reply, return good/bad news */
5190 W;
5191
5192 /* NOTREACHED */
5193 return 0;
5194}
5195
5196
5197static int api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
5198{
5199 unformat_input_t * i = vam->input;
5200 vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
5201 f64 timeout;
5202 u32 sw_if_index;
5203 u8 sw_if_index_set = 0;
5204 u32 address_length = 0;
5205 u8 v6_address_set = 0;
5206 ip6_address_t v6address;
5207 u8 use_default = 0;
5208 u8 no_advertise = 0;
5209 u8 off_link = 0;
5210 u8 no_autoconfig = 0;
5211 u8 no_onlink = 0;
5212 u8 is_no = 0;
5213 u32 val_lifetime = 0;
5214 u32 pref_lifetime = 0;
5215
5216 /* Parse args required to build the message */
5217 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5218 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5219 sw_if_index_set = 1;
5220 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5221 sw_if_index_set = 1;
5222 else if (unformat (i, "%U/%d",
5223 unformat_ip6_address, &v6address,
5224 &address_length))
5225 v6_address_set = 1;
5226 else if (unformat (i, "val_life %d", &val_lifetime))
5227 ;
5228 else if (unformat (i, "pref_life %d", &pref_lifetime))
5229 ;
5230 else if (unformat (i, "def"))
5231 use_default = 1;
5232 else if (unformat (i, "noadv"))
5233 no_advertise = 1;
5234 else if (unformat (i, "offl"))
5235 off_link = 1;
5236 else if (unformat (i, "noauto"))
5237 no_autoconfig = 1;
5238 else if (unformat (i, "nolink"))
5239 no_onlink = 1;
5240 else if (unformat (i, "isno"))
5241 is_no = 1;
5242 else {
5243 clib_warning ("parse error '%U'", format_unformat_error, i);
5244 return -99;
5245 }
5246 }
5247
5248 if (sw_if_index_set == 0) {
5249 errmsg ("missing interface name or sw_if_index\n");
5250 return -99;
5251 }
5252 if (!v6_address_set) {
5253 errmsg ("no address set\n");
5254 return -99;
5255 }
5256
5257 /* Construct the API message */
5258 M(SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
5259
5260 mp->sw_if_index = ntohl (sw_if_index);
Damjan Marionf1213b82016-03-13 02:22:06 +01005261 clib_memcpy (mp->address, &v6address, sizeof (v6address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005262 mp->address_length = address_length;
5263 mp->use_default = use_default;
5264 mp->no_advertise = no_advertise;
5265 mp->off_link = off_link;
5266 mp->no_autoconfig = no_autoconfig;
5267 mp->no_onlink = no_onlink;
5268 mp->is_no = is_no;
5269 mp->val_lifetime = ntohl(val_lifetime);
5270 mp->pref_lifetime = ntohl(pref_lifetime);
5271
5272 /* send it... */
5273 S;
5274
5275 /* Wait for a reply, return good/bad news */
5276 W;
5277
5278 /* NOTREACHED */
5279 return 0;
5280}
5281
5282static int api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
5283{
5284 unformat_input_t * i = vam->input;
5285 vl_api_sw_interface_ip6nd_ra_config_t *mp;
5286 f64 timeout;
5287 u32 sw_if_index;
5288 u8 sw_if_index_set = 0;
5289 u8 surpress = 0;
5290 u8 managed = 0;
5291 u8 other = 0;
5292 u8 ll_option = 0;
5293 u8 send_unicast = 0;
5294 u8 cease = 0;
5295 u8 is_no = 0;
5296 u8 default_router = 0;
5297 u32 max_interval = 0;
5298 u32 min_interval = 0;
5299 u32 lifetime = 0;
5300 u32 initial_count = 0;
5301 u32 initial_interval = 0;
5302
5303
5304 /* Parse args required to build the message */
5305 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5306 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5307 sw_if_index_set = 1;
5308 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5309 sw_if_index_set = 1;
5310 else if (unformat (i, "maxint %d", &max_interval))
5311 ;
5312 else if (unformat (i, "minint %d", &min_interval))
5313 ;
5314 else if (unformat (i, "life %d", &lifetime))
5315 ;
5316 else if (unformat (i, "count %d", &initial_count))
5317 ;
5318 else if (unformat (i, "interval %d", &initial_interval))
5319 ;
5320 else if (unformat (i, "surpress"))
5321 surpress = 1;
5322 else if (unformat (i, "managed"))
5323 managed = 1;
5324 else if (unformat (i, "other"))
5325 other = 1;
5326 else if (unformat (i, "ll"))
5327 ll_option = 1;
5328 else if (unformat (i, "send"))
5329 send_unicast = 1;
5330 else if (unformat (i, "cease"))
5331 cease = 1;
5332 else if (unformat (i, "isno"))
5333 is_no = 1;
5334 else if (unformat (i, "def"))
5335 default_router = 1;
5336 else {
5337 clib_warning ("parse error '%U'", format_unformat_error, i);
5338 return -99;
5339 }
5340 }
5341
5342 if (sw_if_index_set == 0) {
5343 errmsg ("missing interface name or sw_if_index\n");
5344 return -99;
5345 }
5346
5347 /* Construct the API message */
5348 M(SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
5349
5350 mp->sw_if_index = ntohl (sw_if_index);
5351 mp->max_interval = ntohl(max_interval);
5352 mp->min_interval = ntohl(min_interval);
5353 mp->lifetime = ntohl(lifetime);
5354 mp->initial_count = ntohl(initial_count);
5355 mp->initial_interval = ntohl(initial_interval);
5356 mp->surpress = surpress;
5357 mp->managed = managed;
5358 mp->other = other;
5359 mp->ll_option = ll_option;
5360 mp->send_unicast = send_unicast;
5361 mp->cease = cease;
5362 mp->is_no = is_no;
5363 mp->default_router = default_router;
5364
5365 /* send it... */
5366 S;
5367
5368 /* Wait for a reply, return good/bad news */
5369 W;
5370
5371 /* NOTREACHED */
5372 return 0;
5373}
5374
5375static int api_set_arp_neighbor_limit (vat_main_t * vam)
5376{
5377 unformat_input_t * i = vam->input;
5378 vl_api_set_arp_neighbor_limit_t *mp;
5379 f64 timeout;
5380 u32 arp_nbr_limit;
5381 u8 limit_set = 0;
5382 u8 is_ipv6 = 0;
5383
5384 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5385 if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
5386 limit_set = 1;
5387 else if (unformat (i, "ipv6"))
5388 is_ipv6 = 1;
5389 else {
5390 clib_warning ("parse error '%U'", format_unformat_error, i);
5391 return -99;
5392 }
5393 }
5394
5395 if (limit_set == 0) {
5396 errmsg ("missing limit value\n");
5397 return -99;
5398 }
5399
5400 M(SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
5401
5402 mp->arp_neighbor_limit = ntohl(arp_nbr_limit);
5403 mp->is_ipv6 = is_ipv6;
5404
5405 S; W;
5406 /* NOTREACHED */
5407 return 0;
5408}
5409
5410static int api_l2_patch_add_del (vat_main_t * vam)
5411{
5412 unformat_input_t * i = vam->input;
5413 vl_api_l2_patch_add_del_t *mp;
5414 f64 timeout;
5415 u32 rx_sw_if_index;
5416 u8 rx_sw_if_index_set = 0;
5417 u32 tx_sw_if_index;
5418 u8 tx_sw_if_index_set = 0;
5419 u8 is_add = 1;
5420
5421 /* Parse args required to build the message */
5422 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5423 if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5424 rx_sw_if_index_set = 1;
5425 else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5426 tx_sw_if_index_set = 1;
5427 else if (unformat (i, "rx")) {
5428 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5429 if (unformat (i, "%U", unformat_sw_if_index, vam,
5430 &rx_sw_if_index))
5431 rx_sw_if_index_set = 1;
5432 } else
5433 break;
5434 } else if (unformat (i, "tx")) {
5435 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5436 if (unformat (i, "%U", unformat_sw_if_index, vam,
5437 &tx_sw_if_index))
5438 tx_sw_if_index_set = 1;
5439 } else
5440 break;
5441 } else if (unformat (i, "del"))
5442 is_add = 0;
5443 else
5444 break;
5445 }
5446
5447 if (rx_sw_if_index_set == 0) {
5448 errmsg ("missing rx interface name or rx_sw_if_index\n");
5449 return -99;
5450 }
5451
5452 if (tx_sw_if_index_set == 0) {
5453 errmsg ("missing tx interface name or tx_sw_if_index\n");
5454 return -99;
5455 }
5456
5457 M(L2_PATCH_ADD_DEL, l2_patch_add_del);
5458
5459 mp->rx_sw_if_index = ntohl(rx_sw_if_index);
5460 mp->tx_sw_if_index = ntohl(tx_sw_if_index);
5461 mp->is_add = is_add;
5462
5463 S; W;
5464 /* NOTREACHED */
5465 return 0;
5466}
Shwetha20a64f52016-03-25 10:55:01 +00005467static int api_trace_profile_add (vat_main_t *vam)
5468{
5469 unformat_input_t * input = vam->input;
5470 vl_api_trace_profile_add_t *mp;
5471 f64 timeout;
5472 u32 id = 0;
5473 u32 trace_option_elts = 0;
5474 u32 trace_type = 0, node_id = 0, app_data = 0, trace_tsp = 2;
5475 int has_pow_option = 0;
5476 int has_ppc_option = 0;
5477
5478 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5479 {
5480 if (unformat (input, "id %d trace-type 0x%x trace-elts %d "
5481 "trace-tsp %d node-id 0x%x app-data 0x%x",
5482 &id, &trace_type, &trace_option_elts, &trace_tsp,
5483 &node_id, &app_data))
5484 ;
5485 else if (unformat (input, "pow"))
5486 has_pow_option = 1;
5487 else if (unformat (input, "ppc encap"))
5488 has_ppc_option = PPC_ENCAP;
5489 else if (unformat (input, "ppc decap"))
5490 has_ppc_option = PPC_DECAP;
5491 else if (unformat (input, "ppc none"))
5492 has_ppc_option = PPC_NONE;
5493 else
5494 break;
5495 }
5496 M(TRACE_PROFILE_ADD, trace_profile_add);
5497 mp->id = htons(id);
5498 mp->trace_type = trace_type;
5499 mp->trace_num_elt = trace_option_elts;
5500 mp->trace_ppc = has_ppc_option;
5501 mp->trace_app_data = htonl(app_data);
5502 mp->pow_enable = has_pow_option;
5503 mp->trace_tsp = trace_tsp;
5504 mp->node_id = htonl(node_id);
5505
5506 S; W;
5507
5508 return(0);
5509
5510}
5511static int api_trace_profile_apply (vat_main_t *vam)
5512{
5513 unformat_input_t * input = vam->input;
5514 vl_api_trace_profile_apply_t *mp;
5515 f64 timeout;
5516 ip6_address_t addr;
5517 u32 mask_width = ~0;
5518 int is_add = 0;
5519 int is_pop = 0;
5520 int is_none = 0;
5521 u32 vrf_id = 0;
5522 u32 id = 0;
5523
5524 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5525 {
5526 if (unformat (input, "%U/%d",
5527 unformat_ip6_address, &addr, &mask_width))
5528 ;
5529 else if (unformat (input, "id %d", &id))
5530 ;
5531 else if (unformat (input, "vrf-id %d", &vrf_id))
5532 ;
5533 else if (unformat (input, "add"))
5534 is_add = 1;
5535 else if (unformat (input, "pop"))
5536 is_pop = 1;
5537 else if (unformat (input, "none"))
5538 is_none = 1;
5539 else
5540 break;
5541 }
Ed Warnickecb9cada2015-12-08 15:45:58 -07005542
Shwetha20a64f52016-03-25 10:55:01 +00005543 if ((is_add + is_pop + is_none) != 1) {
5544 errmsg("One of (add, pop, none) required");
5545 return -99;
5546 }
5547 if (mask_width == ~0) {
5548 errmsg("<address>/<mask-width> required");
5549 return -99;
5550 }
5551 M(TRACE_PROFILE_APPLY, trace_profile_apply);
Damjan Marionf1213b82016-03-13 02:22:06 +01005552 clib_memcpy(mp->dest_ipv6, &addr, sizeof(mp->dest_ipv6));
Shwetha20a64f52016-03-25 10:55:01 +00005553 mp->id = htons(id);
5554 mp->prefix_length = htonl(mask_width);
5555 mp->vrf_id = htonl(vrf_id);
5556 if (is_add)
5557 mp->trace_op = IOAM_HBYH_ADD;
5558 else if (is_pop)
5559 mp->trace_op = IOAM_HBYH_POP;
5560 else
5561 mp->trace_op = IOAM_HBYH_MOD;
5562
5563 if(is_none)
5564 mp->enable = 0;
5565 else
5566 mp->enable = 1;
5567
5568 S; W;
5569
5570 return 0;
5571}
5572
5573static int api_trace_profile_del (vat_main_t *vam)
5574{
5575 vl_api_trace_profile_del_t *mp;
5576 f64 timeout;
5577
5578 M(TRACE_PROFILE_DEL, trace_profile_del);
5579 S; W;
5580 return 0;
5581}
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07005582
Ed Warnickecb9cada2015-12-08 15:45:58 -07005583static int api_sr_tunnel_add_del (vat_main_t * vam)
5584{
5585 unformat_input_t * i = vam->input;
5586 vl_api_sr_tunnel_add_del_t *mp;
5587 f64 timeout;
5588 int is_del = 0;
5589 int pl_index;
5590 ip6_address_t src_address;
5591 int src_address_set = 0;
5592 ip6_address_t dst_address;
5593 u32 dst_mask_width;
5594 int dst_address_set = 0;
5595 u16 flags = 0;
5596 u32 rx_table_id = 0;
5597 u32 tx_table_id = 0;
5598 ip6_address_t * segments = 0;
5599 ip6_address_t * this_seg;
5600 ip6_address_t * tags = 0;
5601 ip6_address_t * this_tag;
5602 ip6_address_t next_address, tag;
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07005603 u8 * name = 0;
5604 u8 * policy_name = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -07005605
5606 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5607 {
5608 if (unformat (i, "del"))
5609 is_del = 1;
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07005610 else if (unformat (i, "name %s", &name))
5611 ;
5612 else if (unformat (i, "policy %s", &policy_name))
5613 ;
Ed Warnickecb9cada2015-12-08 15:45:58 -07005614 else if (unformat (i, "rx_fib_id %d", &rx_table_id))
5615 ;
5616 else if (unformat (i, "tx_fib_id %d", &tx_table_id))
5617 ;
5618 else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
5619 src_address_set = 1;
5620 else if (unformat (i, "dst %U/%d",
5621 unformat_ip6_address, &dst_address,
5622 &dst_mask_width))
5623 dst_address_set = 1;
5624 else if (unformat (i, "next %U", unformat_ip6_address,
5625 &next_address))
5626 {
5627 vec_add2 (segments, this_seg, 1);
Damjan Marionf1213b82016-03-13 02:22:06 +01005628 clib_memcpy (this_seg->as_u8, next_address.as_u8, sizeof (*this_seg));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005629 }
5630 else if (unformat (i, "tag %U", unformat_ip6_address,
5631 &tag))
5632 {
5633 vec_add2 (tags, this_tag, 1);
Damjan Marionf1213b82016-03-13 02:22:06 +01005634 clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005635 }
5636 else if (unformat (i, "clean"))
5637 flags |= IP6_SR_HEADER_FLAG_CLEANUP;
5638 else if (unformat (i, "protected"))
5639 flags |= IP6_SR_HEADER_FLAG_PROTECTED;
5640 else if (unformat (i, "InPE %d", &pl_index))
5641 {
5642 if (pl_index <= 0 || pl_index > 4)
5643 {
5644 pl_index_range_error:
5645 errmsg ("pl index %d out of range\n", pl_index);
5646 return -99;
5647 }
5648 flags |= IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3*(pl_index - 1));
5649 }
5650 else if (unformat (i, "EgPE %d", &pl_index))
5651 {
5652 if (pl_index <= 0 || pl_index > 4)
5653 goto pl_index_range_error;
5654 flags |= IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3*(pl_index - 1));
5655 }
5656 else if (unformat (i, "OrgSrc %d", &pl_index))
5657 {
5658 if (pl_index <= 0 || pl_index > 4)
5659 goto pl_index_range_error;
5660 flags |= IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3*(pl_index - 1));
5661 }
5662 else
5663 break;
5664 }
5665
5666 if (!src_address_set)
5667 {
5668 errmsg ("src address required\n");
5669 return -99;
5670 }
5671
5672 if (!dst_address_set)
5673 {
5674 errmsg ("dst address required\n");
5675 return -99;
5676 }
5677
5678 if (!segments)
5679 {
5680 errmsg ("at least one sr segment required\n");
5681 return -99;
5682 }
5683
5684 M2(SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
5685 vec_len(segments) * sizeof (ip6_address_t)
5686 + vec_len(tags) * sizeof (ip6_address_t));
5687
Damjan Marionf1213b82016-03-13 02:22:06 +01005688 clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
5689 clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005690 mp->dst_mask_width = dst_mask_width;
5691 mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
5692 mp->n_segments = vec_len (segments);
5693 mp->n_tags = vec_len (tags);
5694 mp->is_add = is_del == 0;
Damjan Marionf1213b82016-03-13 02:22:06 +01005695 clib_memcpy (mp->segs_and_tags, segments,
Ed Warnickecb9cada2015-12-08 15:45:58 -07005696 vec_len(segments)* sizeof (ip6_address_t));
Damjan Marionf1213b82016-03-13 02:22:06 +01005697 clib_memcpy (mp->segs_and_tags + vec_len(segments)*sizeof (ip6_address_t),
Ed Warnickecb9cada2015-12-08 15:45:58 -07005698 tags, vec_len(tags)* sizeof (ip6_address_t));
5699
5700 mp->outer_vrf_id = ntohl (rx_table_id);
5701 mp->inner_vrf_id = ntohl (tx_table_id);
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07005702 memcpy (mp->name, name, vec_len(name));
5703 memcpy (mp->policy_name, policy_name, vec_len(policy_name));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005704
5705 vec_free (segments);
5706 vec_free (tags);
5707
5708 S; W;
5709 /* NOTREACHED */
5710}
5711
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07005712static int api_sr_policy_add_del (vat_main_t * vam)
5713{
5714 unformat_input_t * input = vam->input;
5715 vl_api_sr_policy_add_del_t *mp;
5716 f64 timeout;
5717 int is_del = 0;
5718 u8 * name = 0;
5719 u8 * tunnel_name = 0;
5720 u8 ** tunnel_names = 0;
5721
5722 int name_set = 0 ;
5723 int tunnel_set = 0;
5724 int j = 0;
5725 int tunnel_names_length = 1; // Init to 1 to offset the #tunnel_names counter byte
5726 int tun_name_len = 0; // Different naming convention used as confusing these would be "bad" (TM)
5727
5728 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5729 {
5730 if (unformat (input, "del"))
5731 is_del = 1;
5732 else if (unformat (input, "name %s", &name))
5733 name_set = 1;
5734 else if (unformat (input, "tunnel %s", &tunnel_name))
5735 {
5736 if (tunnel_name)
5737 {
5738 vec_add1 (tunnel_names, tunnel_name);
5739 /* For serializer:
5740 - length = #bytes to store in serial vector
5741 - +1 = byte to store that length
5742 */
5743 tunnel_names_length += (vec_len (tunnel_name) + 1);
5744 tunnel_set = 1;
5745 tunnel_name = 0;
5746 }
5747 }
5748 else
5749 break;
5750 }
5751
5752 if (!name_set)
5753 {
5754 errmsg ("policy name required\n");
5755 return -99;
5756 }
5757
5758 if ((!tunnel_set) && (!is_del))
5759 {
5760 errmsg ("tunnel name required\n");
5761 return -99;
5762 }
5763
5764 M2(SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
5765
5766
5767
5768 mp->is_add = !is_del;
5769
5770 memcpy (mp->name, name, vec_len(name));
5771 // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
5772 u8 * serial_orig = 0;
5773 vec_validate (serial_orig, tunnel_names_length);
5774 *serial_orig = vec_len(tunnel_names); // Store the number of tunnels as length in first byte of serialized vector
5775 serial_orig += 1; // Move along one byte to store the length of first tunnel_name
5776
5777 for (j=0; j < vec_len(tunnel_names); j++)
5778 {
5779 tun_name_len = vec_len (tunnel_names[j]);
5780 *serial_orig = tun_name_len; // Store length of tunnel name in first byte of Length/Value pair
5781 serial_orig += 1; // Move along one byte to store the actual tunnel name
5782 memcpy (serial_orig, tunnel_names[j], tun_name_len);
5783 serial_orig += tun_name_len; // Advance past the copy
5784 }
5785 memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length); // Regress serial_orig to head then copy fwd
5786
5787 vec_free (tunnel_names);
5788 vec_free (tunnel_name);
5789
5790 S; W;
5791 /* NOTREACHED */
5792}
5793
5794static int api_sr_multicast_map_add_del (vat_main_t * vam)
5795{
5796 unformat_input_t * input = vam->input;
5797 vl_api_sr_multicast_map_add_del_t *mp;
5798 f64 timeout;
5799 int is_del = 0;
5800 ip6_address_t multicast_address;
5801 u8 * policy_name = 0;
5802 int multicast_address_set = 0;
5803
5804 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5805 {
5806 if (unformat (input, "del"))
5807 is_del = 1;
5808 else if (unformat (input, "address %U", unformat_ip6_address, &multicast_address))
5809 multicast_address_set = 1;
5810 else if (unformat (input, "sr-policy %s", &policy_name))
5811 ;
5812 else
5813 break;
5814 }
5815
5816 if (!is_del && !policy_name)
5817 {
5818 errmsg ("sr-policy name required\n");
5819 return -99;
5820 }
5821
5822
5823 if (!multicast_address_set)
5824 {
5825 errmsg ("address required\n");
5826 return -99;
5827 }
5828
5829 M(SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
5830
5831 mp->is_add = !is_del;
5832 memcpy (mp->policy_name, policy_name, vec_len(policy_name));
5833 clib_memcpy (mp->multicast_address, &multicast_address, sizeof (mp->multicast_address));
5834
5835
5836 vec_free (policy_name);
5837
5838 S; W;
5839 /* NOTREACHED */
5840}
5841
Ed Warnickecb9cada2015-12-08 15:45:58 -07005842
5843#define foreach_ip4_proto_field \
5844_(src_address) \
5845_(dst_address) \
5846_(tos) \
5847_(length) \
5848_(fragment_id) \
5849_(ttl) \
5850_(protocol) \
5851_(checksum)
5852
5853uword unformat_ip4_mask (unformat_input_t * input, va_list * args)
5854{
5855 u8 ** maskp = va_arg (*args, u8 **);
5856 u8 * mask = 0;
5857 u8 found_something = 0;
5858 ip4_header_t * ip;
5859
5860#define _(a) u8 a=0;
5861 foreach_ip4_proto_field;
5862#undef _
5863 u8 version = 0;
5864 u8 hdr_length = 0;
5865
5866
5867 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5868 {
5869 if (unformat (input, "version"))
5870 version = 1;
5871 else if (unformat (input, "hdr_length"))
5872 hdr_length = 1;
5873 else if (unformat (input, "src"))
5874 src_address = 1;
5875 else if (unformat (input, "dst"))
5876 dst_address = 1;
5877 else if (unformat (input, "proto"))
5878 protocol = 1;
5879
5880#define _(a) else if (unformat (input, #a)) a=1;
5881 foreach_ip4_proto_field
5882#undef _
5883 else
5884 break;
5885 }
5886
5887#define _(a) found_something += a;
5888 foreach_ip4_proto_field;
5889#undef _
5890
5891 if (found_something == 0)
5892 return 0;
5893
5894 vec_validate (mask, sizeof (*ip) - 1);
5895
5896 ip = (ip4_header_t *) mask;
5897
5898#define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
5899 foreach_ip4_proto_field;
5900#undef _
5901
5902 ip->ip_version_and_header_length = 0;
5903
5904 if (version)
5905 ip->ip_version_and_header_length |= 0xF0;
5906
5907 if (hdr_length)
5908 ip->ip_version_and_header_length |= 0x0F;
5909
5910 *maskp = mask;
5911 return 1;
5912}
5913
5914#define foreach_ip6_proto_field \
5915_(src_address) \
5916_(dst_address) \
5917_(payload_length) \
5918_(hop_limit) \
5919_(protocol)
5920
5921uword unformat_ip6_mask (unformat_input_t * input, va_list * args)
5922{
5923 u8 ** maskp = va_arg (*args, u8 **);
5924 u8 * mask = 0;
5925 u8 found_something = 0;
5926 ip6_header_t * ip;
5927 u32 ip_version_traffic_class_and_flow_label;
5928
5929#define _(a) u8 a=0;
5930 foreach_ip6_proto_field;
5931#undef _
5932 u8 version = 0;
5933 u8 traffic_class = 0;
5934 u8 flow_label = 0;
5935
5936 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5937 {
5938 if (unformat (input, "version"))
5939 version = 1;
5940 else if (unformat (input, "traffic-class"))
5941 traffic_class = 1;
5942 else if (unformat (input, "flow-label"))
5943 flow_label = 1;
5944 else if (unformat (input, "src"))
5945 src_address = 1;
5946 else if (unformat (input, "dst"))
5947 dst_address = 1;
5948 else if (unformat (input, "proto"))
5949 protocol = 1;
5950
5951#define _(a) else if (unformat (input, #a)) a=1;
5952 foreach_ip6_proto_field
5953#undef _
5954 else
5955 break;
5956 }
5957
5958#define _(a) found_something += a;
5959 foreach_ip6_proto_field;
5960#undef _
5961
5962 if (found_something == 0)
5963 return 0;
5964
5965 vec_validate (mask, sizeof (*ip) - 1);
5966
5967 ip = (ip6_header_t *) mask;
5968
5969#define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
5970 foreach_ip6_proto_field;
5971#undef _
5972
5973 ip_version_traffic_class_and_flow_label = 0;
5974
5975 if (version)
5976 ip_version_traffic_class_and_flow_label |= 0xF0000000;
5977
5978 if (traffic_class)
5979 ip_version_traffic_class_and_flow_label |= 0x0FF00000;
5980
5981 if (flow_label)
5982 ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
5983
5984 ip->ip_version_traffic_class_and_flow_label =
5985 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
5986
5987 *maskp = mask;
5988 return 1;
5989}
5990
5991uword unformat_l3_mask (unformat_input_t * input, va_list * args)
5992{
5993 u8 ** maskp = va_arg (*args, u8 **);
5994
5995 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
5996 if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
5997 return 1;
5998 else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
5999 return 1;
6000 else
6001 break;
6002 }
6003 return 0;
6004}
6005
6006uword unformat_l2_mask (unformat_input_t * input, va_list * args)
6007{
6008 u8 ** maskp = va_arg (*args, u8 **);
6009 u8 * mask = 0;
6010 u8 src = 0;
6011 u8 dst = 0;
6012 u8 proto = 0;
6013 u8 tag1 = 0;
6014 u8 tag2 = 0;
6015 u8 ignore_tag1 = 0;
6016 u8 ignore_tag2 = 0;
6017 u8 cos1 = 0;
6018 u8 cos2 = 0;
6019 u8 dot1q = 0;
6020 u8 dot1ad = 0;
6021 int len = 14;
6022
6023 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
6024 if (unformat (input, "src"))
6025 src = 1;
6026 else if (unformat (input, "dst"))
6027 dst = 1;
6028 else if (unformat (input, "proto"))
6029 proto = 1;
6030 else if (unformat (input, "tag1"))
6031 tag1 = 1;
6032 else if (unformat (input, "tag2"))
6033 tag2 = 1;
6034 else if (unformat (input, "ignore-tag1"))
6035 ignore_tag1 = 1;
6036 else if (unformat (input, "ignore-tag2"))
6037 ignore_tag2 = 1;
6038 else if (unformat (input, "cos1"))
6039 cos1 = 1;
6040 else if (unformat (input, "cos2"))
6041 cos2 = 1;
6042 else if (unformat (input, "dot1q"))
6043 dot1q = 1;
6044 else if (unformat (input, "dot1ad"))
6045 dot1ad = 1;
6046 else
6047 break;
6048 }
6049 if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
6050 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
6051 return 0;
6052
6053 if (tag1 || ignore_tag1 || cos1 || dot1q)
6054 len = 18;
6055 if (tag2 || ignore_tag2 || cos2 || dot1ad)
6056 len = 22;
6057
6058 vec_validate (mask, len-1);
6059
6060 if (dst)
6061 memset (mask, 0xff, 6);
6062
6063 if (src)
6064 memset (mask + 6, 0xff, 6);
6065
6066 if (tag2 || dot1ad)
6067 {
6068 /* inner vlan tag */
6069 if (tag2)
6070 {
6071 mask[19] = 0xff;
6072 mask[18] = 0x0f;
6073 }
6074 if (cos2)
6075 mask[18] |= 0xe0;
6076 if (proto)
6077 mask[21] = mask [20] = 0xff;
6078 if (tag1)
6079 {
6080 mask [15] = 0xff;
6081 mask [14] = 0x0f;
6082 }
6083 if (cos1)
6084 mask[14] |= 0xe0;
6085 *maskp = mask;
6086 return 1;
6087 }
6088 if (tag1 | dot1q)
6089 {
6090 if (tag1)
6091 {
6092 mask [15] = 0xff;
6093 mask [14] = 0x0f;
6094 }
6095 if (cos1)
6096 mask[14] |= 0xe0;
6097 if (proto)
6098 mask[16] = mask [17] = 0xff;
6099
6100 *maskp = mask;
6101 return 1;
6102 }
6103 if (cos2)
6104 mask[18] |= 0xe0;
6105 if (cos1)
6106 mask[14] |= 0xe0;
6107 if (proto)
6108 mask[12] = mask [13] = 0xff;
6109
6110 *maskp = mask;
6111 return 1;
6112}
6113
6114uword unformat_classify_mask (unformat_input_t * input, va_list * args)
6115{
6116 u8 ** maskp = va_arg (*args, u8 **);
6117 u32 * skipp = va_arg (*args, u32 *);
6118 u32 * matchp = va_arg (*args, u32 *);
6119 u32 match;
6120 u8 * mask = 0;
6121 u8 * l2 = 0;
6122 u8 * l3 = 0;
6123 int i;
6124
6125 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
6126 if (unformat (input, "hex %U", unformat_hex_string, &mask))
6127 ;
6128 else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
6129 ;
6130 else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
6131 ;
6132 else
6133 break;
6134 }
6135
6136 if (mask || l2 || l3)
6137 {
6138 if (l2 || l3)
6139 {
6140 /* "With a free Ethernet header in every package" */
6141 if (l2 == 0)
6142 vec_validate (l2, 13);
6143 mask = l2;
6144 vec_append (mask, l3);
6145 vec_free (l3);
6146 }
6147
6148 /* Scan forward looking for the first significant mask octet */
6149 for (i = 0; i < vec_len (mask); i++)
6150 if (mask[i])
6151 break;
6152
6153 /* compute (skip, match) params */
6154 *skipp = i / sizeof(u32x4);
6155 vec_delete (mask, *skipp * sizeof(u32x4), 0);
6156
6157 /* Pad mask to an even multiple of the vector size */
6158 while (vec_len (mask) % sizeof (u32x4))
6159 vec_add1 (mask, 0);
6160
6161 match = vec_len (mask) / sizeof (u32x4);
6162
6163 for (i = match*sizeof(u32x4); i > 0; i-= sizeof(u32x4))
6164 {
6165 u64 *tmp = (u64 *)(mask + (i-sizeof(u32x4)));
6166 if (*tmp || *(tmp+1))
6167 break;
6168 match--;
6169 }
6170 if (match == 0)
6171 clib_warning ("BUG: match 0");
6172
6173 _vec_len (mask) = match * sizeof(u32x4);
6174
6175 *matchp = match;
6176 *maskp = mask;
6177
6178 return 1;
6179 }
6180
6181 return 0;
6182}
6183
6184#define foreach_l2_next \
6185_(drop, DROP) \
6186_(ethernet, ETHERNET_INPUT) \
6187_(ip4, IP4_INPUT) \
6188_(ip6, IP6_INPUT)
6189
6190uword unformat_l2_next_index (unformat_input_t * input, va_list * args)
6191{
6192 u32 * miss_next_indexp = va_arg (*args, u32 *);
6193 u32 next_index = 0;
6194 u32 tmp;
6195
6196#define _(n,N) \
6197 if (unformat (input, #n)) { next_index = L2_CLASSIFY_NEXT_##N; goto out;}
6198 foreach_l2_next;
6199#undef _
6200
6201 if (unformat (input, "%d", &tmp))
6202 {
6203 next_index = tmp;
6204 goto out;
6205 }
6206
6207 return 0;
6208
6209 out:
6210 *miss_next_indexp = next_index;
6211 return 1;
6212}
6213
6214#define foreach_ip_next \
6215_(miss, MISS) \
6216_(drop, DROP) \
6217_(local, LOCAL) \
6218_(rewrite, REWRITE)
6219
6220uword unformat_ip_next_index (unformat_input_t * input, va_list * args)
6221{
6222 u32 * miss_next_indexp = va_arg (*args, u32 *);
6223 u32 next_index = 0;
6224 u32 tmp;
6225
6226#define _(n,N) \
6227 if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
6228 foreach_ip_next;
6229#undef _
6230
6231 if (unformat (input, "%d", &tmp))
6232 {
6233 next_index = tmp;
6234 goto out;
6235 }
6236
6237 return 0;
6238
6239 out:
6240 *miss_next_indexp = next_index;
6241 return 1;
6242}
6243
6244#define foreach_acl_next \
6245_(deny, DENY)
6246
6247uword unformat_acl_next_index (unformat_input_t * input, va_list * args)
6248{
6249 u32 * miss_next_indexp = va_arg (*args, u32 *);
6250 u32 next_index = 0;
6251 u32 tmp;
6252
6253#define _(n,N) \
6254 if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
6255 foreach_acl_next;
6256#undef _
6257
6258 if (unformat (input, "permit"))
6259 {
6260 next_index = ~0;
6261 goto out;
6262 }
6263 else if (unformat (input, "%d", &tmp))
6264 {
6265 next_index = tmp;
6266 goto out;
6267 }
6268
6269 return 0;
6270
6271 out:
6272 *miss_next_indexp = next_index;
6273 return 1;
6274}
6275
6276static int api_classify_add_del_table (vat_main_t * vam)
6277{
6278 unformat_input_t * i = vam->input;
6279 vl_api_classify_add_del_table_t *mp;
6280
6281 u32 nbuckets = 2;
6282 u32 skip = ~0;
6283 u32 match = ~0;
6284 int is_add = 1;
6285 u32 table_index = ~0;
6286 u32 next_table_index = ~0;
6287 u32 miss_next_index = ~0;
6288 u32 memory_size = 32<<20;
6289 u8 * mask = 0;
6290 f64 timeout;
6291
6292 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6293 if (unformat (i, "del"))
6294 is_add = 0;
6295 else if (unformat (i, "buckets %d", &nbuckets))
6296 ;
6297 else if (unformat (i, "memory_size %d", &memory_size))
6298 ;
6299 else if (unformat (i, "skip %d", &skip))
6300 ;
6301 else if (unformat (i, "match %d", &match))
6302 ;
6303 else if (unformat (i, "table %d", &table_index))
6304 ;
6305 else if (unformat (i, "mask %U", unformat_classify_mask,
6306 &mask, &skip, &match))
6307 ;
6308 else if (unformat (i, "next-table %d", &next_table_index))
6309 ;
6310 else if (unformat (i, "miss-next %U", unformat_ip_next_index,
6311 &miss_next_index))
6312 ;
6313 else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
6314 &miss_next_index))
6315 ;
6316 else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
6317 &miss_next_index))
6318 ;
6319 else
6320 break;
6321 }
6322
6323 if (is_add && mask == 0) {
6324 errmsg ("Mask required\n");
6325 return -99;
6326 }
6327
6328 if (is_add && skip == ~0) {
6329 errmsg ("skip count required\n");
6330 return -99;
6331 }
6332
6333 if (is_add && match == ~0) {
6334 errmsg ("match count required\n");
6335 return -99;
6336 }
6337
6338 if (!is_add && table_index == ~0) {
6339 errmsg ("table index required for delete\n");
6340 return -99;
6341 }
6342
6343 M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table,
6344 vec_len(mask));
6345
6346 mp->is_add = is_add;
6347 mp->table_index = ntohl(table_index);
6348 mp->nbuckets = ntohl(nbuckets);
6349 mp->memory_size = ntohl(memory_size);
6350 mp->skip_n_vectors = ntohl(skip);
6351 mp->match_n_vectors = ntohl(match);
6352 mp->next_table_index = ntohl(next_table_index);
6353 mp->miss_next_index = ntohl(miss_next_index);
Damjan Marionf1213b82016-03-13 02:22:06 +01006354 clib_memcpy (mp->mask, mask, vec_len(mask));
Ed Warnickecb9cada2015-12-08 15:45:58 -07006355
6356 vec_free(mask);
6357
6358 S; W;
6359 /* NOTREACHED */
6360}
6361
6362uword unformat_ip4_match (unformat_input_t * input, va_list * args)
6363{
6364 u8 ** matchp = va_arg (*args, u8 **);
6365 u8 * match = 0;
6366 ip4_header_t * ip;
6367 int version = 0;
6368 u32 version_val;
6369 int hdr_length = 0;
6370 u32 hdr_length_val;
6371 int src = 0, dst = 0;
6372 ip4_address_t src_val, dst_val;
6373 int proto = 0;
6374 u32 proto_val;
6375 int tos = 0;
6376 u32 tos_val;
6377 int length = 0;
6378 u32 length_val;
6379 int fragment_id = 0;
6380 u32 fragment_id_val;
6381 int ttl = 0;
6382 int ttl_val;
6383 int checksum = 0;
6384 u32 checksum_val;
6385
6386 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
6387 {
6388 if (unformat (input, "version %d", &version_val))
6389 version = 1;
6390 else if (unformat (input, "hdr_length %d", &hdr_length_val))
6391 hdr_length = 1;
6392 else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
6393 src = 1;
6394 else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
6395 dst = 1;
6396 else if (unformat (input, "proto %d", &proto_val))
6397 proto = 1;
6398 else if (unformat (input, "tos %d", &tos_val))
6399 tos = 1;
6400 else if (unformat (input, "length %d", &length_val))
6401 length = 1;
6402 else if (unformat (input, "fragment_id %d", &fragment_id_val))
6403 fragment_id = 1;
6404 else if (unformat (input, "ttl %d", &ttl_val))
6405 ttl = 1;
6406 else if (unformat (input, "checksum %d", &checksum_val))
6407 checksum = 1;
6408 else
6409 break;
6410 }
6411
6412 if (version + hdr_length + src + dst + proto + tos + length + fragment_id
6413 + ttl + checksum == 0)
6414 return 0;
6415
6416 /*
6417 * Aligned because we use the real comparison functions
6418 */
6419 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof(u32x4));
6420
6421 ip = (ip4_header_t *) match;
6422
6423 /* These are realistically matched in practice */
6424 if (src)
6425 ip->src_address.as_u32 = src_val.as_u32;
6426
6427 if (dst)
6428 ip->dst_address.as_u32 = dst_val.as_u32;
6429
6430 if (proto)
6431 ip->protocol = proto_val;
6432
6433
6434 /* These are not, but they're included for completeness */
6435 if (version)
6436 ip->ip_version_and_header_length |= (version_val & 0xF)<<4;
6437
6438 if (hdr_length)
6439 ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
6440
6441 if (tos)
6442 ip->tos = tos_val;
6443
6444 if (length)
6445 ip->length = length_val;
6446
6447 if (ttl)
6448 ip->ttl = ttl_val;
6449
6450 if (checksum)
6451 ip->checksum = checksum_val;
6452
6453 *matchp = match;
6454 return 1;
6455}
6456
6457uword unformat_ip6_match (unformat_input_t * input, va_list * args)
6458{
6459 u8 ** matchp = va_arg (*args, u8 **);
6460 u8 * match = 0;
6461 ip6_header_t * ip;
6462 int version = 0;
6463 u32 version_val;
6464 u8 traffic_class;
6465 u32 traffic_class_val;
6466 u8 flow_label;
6467 u8 flow_label_val;
6468 int src = 0, dst = 0;
6469 ip6_address_t src_val, dst_val;
6470 int proto = 0;
6471 u32 proto_val;
6472 int payload_length = 0;
6473 u32 payload_length_val;
6474 int hop_limit = 0;
6475 int hop_limit_val;
6476 u32 ip_version_traffic_class_and_flow_label;
6477
6478 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
6479 {
6480 if (unformat (input, "version %d", &version_val))
6481 version = 1;
6482 else if (unformat (input, "traffic_class %d", &traffic_class_val))
6483 traffic_class = 1;
6484 else if (unformat (input, "flow_label %d", &flow_label_val))
6485 flow_label = 1;
6486 else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
6487 src = 1;
6488 else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
6489 dst = 1;
6490 else if (unformat (input, "proto %d", &proto_val))
6491 proto = 1;
6492 else if (unformat (input, "payload_length %d", &payload_length_val))
6493 payload_length = 1;
6494 else if (unformat (input, "hop_limit %d", &hop_limit_val))
6495 hop_limit = 1;
6496 else
6497 break;
6498 }
6499
6500 if (version + traffic_class + flow_label + src + dst + proto +
6501 payload_length + hop_limit == 0)
6502 return 0;
6503
6504 /*
6505 * Aligned because we use the real comparison functions
6506 */
6507 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof(u32x4));
6508
6509 ip = (ip6_header_t *) match;
6510
6511 if (src)
Damjan Marionf1213b82016-03-13 02:22:06 +01006512 clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07006513
6514 if (dst)
Damjan Marionf1213b82016-03-13 02:22:06 +01006515 clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07006516
6517 if (proto)
6518 ip->protocol = proto_val;
6519
6520 ip_version_traffic_class_and_flow_label = 0;
6521
6522 if (version)
6523 ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
6524
6525 if (traffic_class)
6526 ip_version_traffic_class_and_flow_label |= (traffic_class_val & 0xFF) << 20;
6527
6528 if (flow_label)
6529 ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
6530
6531 ip->ip_version_traffic_class_and_flow_label =
6532 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
6533
6534 if (payload_length)
6535 ip->payload_length = clib_host_to_net_u16 (payload_length_val);
6536
6537 if (hop_limit)
6538 ip->hop_limit = hop_limit_val;
6539
6540 *matchp = match;
6541 return 1;
6542}
6543
6544uword unformat_l3_match (unformat_input_t * input, va_list * args)
6545{
6546 u8 ** matchp = va_arg (*args, u8 **);
6547
6548 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
6549 if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
6550 return 1;
6551 else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
6552 return 1;
6553 else
6554 break;
6555 }
6556 return 0;
6557}
6558
6559uword unformat_vlan_tag (unformat_input_t * input, va_list * args)
6560{
6561 u8 * tagp = va_arg (*args, u8 *);
6562 u32 tag;
6563
6564 if (unformat(input, "%d", &tag))
6565 {
6566 tagp[0] = (tag>>8) & 0x0F;
6567 tagp[1] = tag & 0xFF;
6568 return 1;
6569 }
6570
6571 return 0;
6572}
6573
6574uword unformat_l2_match (unformat_input_t * input, va_list * args)
6575{
6576 u8 ** matchp = va_arg (*args, u8 **);
6577 u8 * match = 0;
6578 u8 src = 0;
6579 u8 src_val[6];
6580 u8 dst = 0;
6581 u8 dst_val[6];
6582 u8 proto = 0;
6583 u16 proto_val;
6584 u8 tag1 = 0;
6585 u8 tag1_val [2];
6586 u8 tag2 = 0;
6587 u8 tag2_val [2];
6588 int len = 14;
6589 u8 ignore_tag1 = 0;
6590 u8 ignore_tag2 = 0;
6591 u8 cos1 = 0;
6592 u8 cos2 = 0;
6593 u32 cos1_val = 0;
6594 u32 cos2_val = 0;
6595
6596 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
6597 if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
6598 src = 1;
6599 else if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
6600 dst = 1;
6601 else if (unformat (input, "proto %U",
6602 unformat_ethernet_type_host_byte_order, &proto_val))
6603 proto = 1;
6604 else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
6605 tag1 = 1;
6606 else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
6607 tag2 = 1;
6608 else if (unformat (input, "ignore-tag1"))
6609 ignore_tag1 = 1;
6610 else if (unformat (input, "ignore-tag2"))
6611 ignore_tag2 = 1;
6612 else if (unformat (input, "cos1 %d", &cos1_val))
6613 cos1 = 1;
6614 else if (unformat (input, "cos2 %d", &cos2_val))
6615 cos2 = 1;
6616 else
6617 break;
6618 }
6619 if ((src + dst + proto + tag1 + tag2 +
6620 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
6621 return 0;
6622
6623 if (tag1 || ignore_tag1 || cos1)
6624 len = 18;
6625 if (tag2 || ignore_tag2 || cos2)
6626 len = 22;
6627
6628 vec_validate_aligned (match, len-1, sizeof(u32x4));
6629
6630 if (dst)
Damjan Marionf1213b82016-03-13 02:22:06 +01006631 clib_memcpy (match, dst_val, 6);
Ed Warnickecb9cada2015-12-08 15:45:58 -07006632
6633 if (src)
Damjan Marionf1213b82016-03-13 02:22:06 +01006634 clib_memcpy (match + 6, src_val, 6);
Ed Warnickecb9cada2015-12-08 15:45:58 -07006635
6636 if (tag2)
6637 {
6638 /* inner vlan tag */
6639 match[19] = tag2_val[1];
6640 match[18] = tag2_val[0];
6641 if (cos2)
6642 match [18] |= (cos2_val & 0x7) << 5;
6643 if (proto)
6644 {
6645 match[21] = proto_val & 0xff;
6646 match[20] = proto_val >> 8;
6647 }
6648 if (tag1)
6649 {
6650 match [15] = tag1_val[1];
6651 match [14] = tag1_val[0];
6652 }
6653 if (cos1)
6654 match [14] |= (cos1_val & 0x7) << 5;
6655 *matchp = match;
6656 return 1;
6657 }
6658 if (tag1)
6659 {
6660 match [15] = tag1_val[1];
6661 match [14] = tag1_val[0];
6662 if (proto)
6663 {
6664 match[17] = proto_val & 0xff;
6665 match[16] = proto_val >> 8;
6666 }
6667 if (cos1)
6668 match [14] |= (cos1_val & 0x7) << 5;
6669
6670 *matchp = match;
6671 return 1;
6672 }
6673 if (cos2)
6674 match [18] |= (cos2_val & 0x7) << 5;
6675 if (cos1)
6676 match [14] |= (cos1_val & 0x7) << 5;
6677 if (proto)
6678 {
6679 match[13] = proto_val & 0xff;
6680 match[12] = proto_val >> 8;
6681 }
6682
6683 *matchp = match;
6684 return 1;
6685}
6686
6687
6688uword unformat_classify_match (unformat_input_t * input, va_list * args)
6689{
6690 u8 ** matchp = va_arg (*args, u8 **);
6691 u32 skip_n_vectors = va_arg (*args, u32);
6692 u32 match_n_vectors = va_arg (*args, u32);
6693
6694 u8 * match = 0;
6695 u8 * l2 = 0;
6696 u8 * l3 = 0;
6697
6698 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
6699 if (unformat (input, "hex %U", unformat_hex_string, &match))
6700 ;
6701 else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
6702 ;
6703 else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
6704 ;
6705 else
6706 break;
6707 }
6708
6709 if (match || l2 || l3)
6710 {
6711 if (l2 || l3)
6712 {
6713 /* "Win a free Ethernet header in every packet" */
6714 if (l2 == 0)
6715 vec_validate_aligned (l2, 13, sizeof(u32x4));
6716 match = l2;
6717 vec_append_aligned (match, l3, sizeof(u32x4));
6718 vec_free (l3);
6719 }
6720
6721 /* Make sure the vector is big enough even if key is all 0's */
6722 vec_validate_aligned
6723 (match, ((match_n_vectors + skip_n_vectors) * sizeof(u32x4)) - 1,
6724 sizeof(u32x4));
6725
6726 /* Set size, include skipped vectors*/
6727 _vec_len (match) = (match_n_vectors+skip_n_vectors) * sizeof(u32x4);
6728
6729 *matchp = match;
6730
6731 return 1;
6732 }
6733
6734 return 0;
6735}
6736
6737static int api_classify_add_del_session (vat_main_t * vam)
6738{
6739 unformat_input_t * i = vam->input;
6740 vl_api_classify_add_del_session_t *mp;
6741 int is_add = 1;
6742 u32 table_index = ~0;
6743 u32 hit_next_index = ~0;
6744 u32 opaque_index = ~0;
6745 u8 * match = 0;
6746 i32 advance = 0;
6747 f64 timeout;
6748 u32 skip_n_vectors = 0;
6749 u32 match_n_vectors = 0;
6750
6751 /*
6752 * Warning: you have to supply skip_n and match_n
6753 * because the API client cant simply look at the classify
6754 * table object.
6755 */
6756
6757 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6758 if (unformat (i, "del"))
6759 is_add = 0;
6760 else if (unformat (i, "hit-next %U", unformat_ip_next_index,
6761 &hit_next_index))
6762 ;
6763 else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
6764 &hit_next_index))
6765 ;
6766 else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
6767 &hit_next_index))
6768 ;
6769 else if (unformat (i, "opaque-index %d", &opaque_index))
6770 ;
6771 else if (unformat (i, "skip_n %d", &skip_n_vectors))
6772 ;
6773 else if (unformat (i, "match_n %d", &match_n_vectors))
6774 ;
6775 else if (unformat (i, "match %U", unformat_classify_match,
6776 &match, skip_n_vectors, match_n_vectors))
6777 ;
6778 else if (unformat (i, "advance %d", &advance))
6779 ;
6780 else if (unformat (i, "table-index %d", &table_index))
6781 ;
6782 else
6783 break;
6784 }
6785
6786 if (table_index == ~0) {
6787 errmsg ("Table index required\n");
6788 return -99;
6789 }
6790
6791 if (is_add && match == 0) {
6792 errmsg ("Match value required\n");
6793 return -99;
6794 }
6795
6796 M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session,
6797 vec_len(match));
6798
6799 mp->is_add = is_add;
6800 mp->table_index = ntohl(table_index);
6801 mp->hit_next_index = ntohl(hit_next_index);
6802 mp->opaque_index = ntohl(opaque_index);
6803 mp->advance = ntohl(advance);
Damjan Marionf1213b82016-03-13 02:22:06 +01006804 clib_memcpy (mp->match, match, vec_len(match));
Ed Warnickecb9cada2015-12-08 15:45:58 -07006805 vec_free(match);
6806
6807 S; W;
6808 /* NOTREACHED */
6809}
6810
6811static int api_classify_set_interface_ip_table (vat_main_t * vam)
6812{
6813 unformat_input_t * i = vam->input;
6814 vl_api_classify_set_interface_ip_table_t *mp;
6815 f64 timeout;
6816 u32 sw_if_index;
6817 int sw_if_index_set;
6818 u32 table_index = ~0;
6819 u8 is_ipv6 = 0;
6820
6821 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6822 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6823 sw_if_index_set = 1;
6824 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6825 sw_if_index_set = 1;
6826 else if (unformat (i, "table %d", &table_index))
6827 ;
6828 else {
6829 clib_warning ("parse error '%U'", format_unformat_error, i);
6830 return -99;
6831 }
6832 }
6833
6834 if (sw_if_index_set == 0) {
6835 errmsg ("missing interface name or sw_if_index\n");
6836 return -99;
6837 }
6838
6839
6840 M(CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
6841
6842 mp->sw_if_index = ntohl(sw_if_index);
6843 mp->table_index = ntohl(table_index);
6844 mp->is_ipv6 = is_ipv6;
6845
6846 S; W;
6847 /* NOTREACHED */
6848 return 0;
6849}
6850
6851static int api_classify_set_interface_l2_tables (vat_main_t * vam)
6852{
6853 unformat_input_t * i = vam->input;
6854 vl_api_classify_set_interface_l2_tables_t *mp;
6855 f64 timeout;
6856 u32 sw_if_index;
6857 int sw_if_index_set;
6858 u32 ip4_table_index = ~0;
6859 u32 ip6_table_index = ~0;
6860 u32 other_table_index = ~0;
6861
6862 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6863 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6864 sw_if_index_set = 1;
6865 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6866 sw_if_index_set = 1;
6867 else if (unformat (i, "ip4-table %d", &ip4_table_index))
6868 ;
6869 else if (unformat (i, "ip6-table %d", &ip6_table_index))
6870 ;
6871 else if (unformat (i, "other-table %d", &other_table_index))
6872 ;
6873 else {
6874 clib_warning ("parse error '%U'", format_unformat_error, i);
6875 return -99;
6876 }
6877 }
6878
6879 if (sw_if_index_set == 0) {
6880 errmsg ("missing interface name or sw_if_index\n");
6881 return -99;
6882 }
6883
6884
6885 M(CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
6886
6887 mp->sw_if_index = ntohl(sw_if_index);
6888 mp->ip4_table_index = ntohl(ip4_table_index);
6889 mp->ip6_table_index = ntohl(ip6_table_index);
6890 mp->other_table_index = ntohl(other_table_index);
6891
6892
6893 S; W;
6894 /* NOTREACHED */
6895 return 0;
6896}
6897
6898static int api_get_node_index (vat_main_t * vam)
6899{
6900 unformat_input_t * i = vam->input;
6901 vl_api_get_node_index_t * mp;
6902 f64 timeout;
6903 u8 * name = 0;
6904
6905 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6906 if (unformat (i, "node %s", &name))
6907 ;
6908 else
6909 break;
6910 }
6911 if (name == 0) {
6912 errmsg ("node name required\n");
6913 return -99;
6914 }
6915 if (vec_len (name) >= ARRAY_LEN(mp->node_name)) {
6916 errmsg ("node name too long, max %d\n", ARRAY_LEN(mp->node_name));
6917 return -99;
6918 }
6919
6920 M(GET_NODE_INDEX, get_node_index);
Damjan Marionf1213b82016-03-13 02:22:06 +01006921 clib_memcpy (mp->node_name, name, vec_len(name));
Ed Warnickecb9cada2015-12-08 15:45:58 -07006922 vec_free(name);
6923
6924 S; W;
6925 /* NOTREACHED */
6926 return 0;
6927}
6928
6929static int api_add_node_next (vat_main_t * vam)
6930{
6931 unformat_input_t * i = vam->input;
6932 vl_api_add_node_next_t * mp;
6933 f64 timeout;
6934 u8 * name = 0;
6935 u8 * next = 0;
6936
6937 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6938 if (unformat (i, "node %s", &name))
6939 ;
6940 else if (unformat (i, "next %s", &next))
6941 ;
6942 else
6943 break;
6944 }
6945 if (name == 0) {
6946 errmsg ("node name required\n");
6947 return -99;
6948 }
6949 if (vec_len (name) >= ARRAY_LEN(mp->node_name)) {
6950 errmsg ("node name too long, max %d\n", ARRAY_LEN(mp->node_name));
6951 return -99;
6952 }
6953 if (next == 0) {
6954 errmsg ("next node required\n");
6955 return -99;
6956 }
6957 if (vec_len (next) >= ARRAY_LEN(mp->next_name)) {
6958 errmsg ("next name too long, max %d\n", ARRAY_LEN(mp->next_name));
6959 return -99;
6960 }
6961
6962 M(ADD_NODE_NEXT, add_node_next);
Damjan Marionf1213b82016-03-13 02:22:06 +01006963 clib_memcpy (mp->node_name, name, vec_len(name));
6964 clib_memcpy (mp->next_name, next, vec_len(next));
Ed Warnickecb9cada2015-12-08 15:45:58 -07006965 vec_free(name);
6966 vec_free(next);
6967
6968 S; W;
6969 /* NOTREACHED */
6970 return 0;
6971}
6972
6973static int api_l2tpv3_create_tunnel (vat_main_t * vam)
6974{
6975 unformat_input_t * i = vam->input;
6976 ip6_address_t client_address, our_address;
6977 int client_address_set = 0;
6978 int our_address_set = 0;
6979 u32 local_session_id = 0;
6980 u32 remote_session_id = 0;
6981 u64 local_cookie = 0;
6982 u64 remote_cookie = 0;
6983 u8 l2_sublayer_present = 0;
6984 vl_api_l2tpv3_create_tunnel_t * mp;
6985 f64 timeout;
6986
6987 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6988 if (unformat (i, "client_address %U", unformat_ip6_address,
6989 &client_address))
6990 client_address_set = 1;
6991 else if (unformat (i, "our_address %U", unformat_ip6_address,
6992 &our_address))
6993 our_address_set = 1;
6994 else if (unformat (i, "local_session_id %d", &local_session_id))
6995 ;
6996 else if (unformat (i, "remote_session_id %d", &remote_session_id))
6997 ;
6998 else if (unformat (i, "local_cookie %lld", &local_cookie))
6999 ;
7000 else if (unformat (i, "remote_cookie %lld", &remote_cookie))
7001 ;
7002 else if (unformat (i, "l2-sublayer-present"))
7003 l2_sublayer_present = 1;
7004 else
7005 break;
7006 }
7007
7008 if (client_address_set == 0) {
7009 errmsg ("client_address required\n");
7010 return -99;
7011 }
7012
7013 if (our_address_set == 0) {
7014 errmsg ("our_address required\n");
7015 return -99;
7016 }
7017
7018 M(L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
7019
Damjan Marionf1213b82016-03-13 02:22:06 +01007020 clib_memcpy (mp->client_address, client_address.as_u8,
Ed Warnickecb9cada2015-12-08 15:45:58 -07007021 sizeof (mp->client_address));
7022
Damjan Marionf1213b82016-03-13 02:22:06 +01007023 clib_memcpy (mp->our_address, our_address.as_u8,
Ed Warnickecb9cada2015-12-08 15:45:58 -07007024 sizeof (mp->our_address));
7025
7026 mp->local_session_id = ntohl (local_session_id);
7027 mp->remote_session_id = ntohl (remote_session_id);
7028 mp->local_cookie = clib_host_to_net_u64 (local_cookie);
7029 mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
7030 mp->l2_sublayer_present = l2_sublayer_present;
7031 mp->is_ipv6 = 1;
7032
7033 S; W;
7034 /* NOTREACHED */
7035 return 0;
7036}
7037
7038static int api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
7039{
7040 unformat_input_t * i = vam->input;
7041 u32 sw_if_index;
7042 u8 sw_if_index_set = 0;
7043 u64 new_local_cookie = 0;
7044 u64 new_remote_cookie = 0;
7045 vl_api_l2tpv3_set_tunnel_cookies_t *mp;
7046 f64 timeout;
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, "new_local_cookie %lld", &new_local_cookie))
7054 ;
7055 else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
7056 ;
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_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
7067
7068 mp->sw_if_index = ntohl(sw_if_index);
7069 mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
7070 mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
7071
7072 S; W;
7073 /* NOTREACHED */
7074 return 0;
7075}
7076
7077static int api_l2tpv3_interface_enable_disable (vat_main_t * vam)
7078{
7079 unformat_input_t * i = vam->input;
7080 vl_api_l2tpv3_interface_enable_disable_t *mp;
7081 f64 timeout;
7082 u32 sw_if_index;
7083 u8 sw_if_index_set = 0;
7084 u8 enable_disable = 1;
7085
7086 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7087 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7088 sw_if_index_set = 1;
7089 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7090 sw_if_index_set = 1;
7091 else if (unformat (i, "enable"))
7092 enable_disable = 1;
7093 else if (unformat (i, "disable"))
7094 enable_disable = 0;
7095 else
7096 break;
7097 }
7098
7099 if (sw_if_index_set == 0) {
7100 errmsg ("missing interface name or sw_if_index\n");
7101 return -99;
7102 }
7103
7104 M(L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
7105
7106 mp->sw_if_index = ntohl(sw_if_index);
7107 mp->enable_disable = enable_disable;
7108
7109 S; W;
7110 /* NOTREACHED */
7111 return 0;
7112}
7113
7114static int api_l2tpv3_set_lookup_key (vat_main_t * vam)
7115{
7116 unformat_input_t * i = vam->input;
7117 vl_api_l2tpv3_set_lookup_key_t * mp;
7118 f64 timeout;
7119 u8 key = ~0;
7120
7121 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7122 if (unformat (i, "lookup_v6_src"))
7123 key = L2T_LOOKUP_SRC_ADDRESS;
7124 else if (unformat (i, "lookup_v6_dst"))
7125 key = L2T_LOOKUP_DST_ADDRESS;
7126 else if (unformat (i, "lookup_session_id"))
7127 key = L2T_LOOKUP_SESSION_ID;
7128 else
7129 break;
7130 }
7131
Damjan Marionfa693552016-04-26 19:30:36 +02007132 if (key == (u8) ~0) {
Ed Warnickecb9cada2015-12-08 15:45:58 -07007133 errmsg ("l2tp session lookup key unset\n");
7134 return -99;
7135 }
7136
7137 M(L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
7138
7139 mp->key = key;
7140
7141 S; W;
7142 /* NOTREACHED */
7143 return 0;
7144}
7145
7146static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
7147(vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
7148{
7149 vat_main_t * vam = &vat_main;
7150
7151 fformat(vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
7152 format_ip6_address, mp->our_address,
7153 format_ip6_address, mp->client_address,
7154 clib_net_to_host_u32(mp->sw_if_index));
7155
7156 fformat (vam->ofp, " local cookies %016llx %016llx remote cookie %016llx\n",
7157 clib_net_to_host_u64 (mp->local_cookie[0]),
7158 clib_net_to_host_u64 (mp->local_cookie[1]),
7159 clib_net_to_host_u64 (mp->remote_cookie));
7160
7161 fformat (vam->ofp, " local session-id %d remote session-id %d\n",
7162 clib_net_to_host_u32 (mp->local_session_id),
7163 clib_net_to_host_u32 (mp->remote_session_id));
7164
7165 fformat (vam->ofp, " l2 specific sublayer %s\n\n",
7166 mp->l2_sublayer_present ? "preset" : "absent");
7167
7168}
7169
7170static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
7171(vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
7172{
7173 vat_main_t * vam = &vat_main;
7174 vat_json_node_t *node = NULL;
7175 struct in6_addr addr;
7176
7177 if (VAT_JSON_ARRAY != vam->json_tree.type) {
7178 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
7179 vat_json_init_array(&vam->json_tree);
7180 }
7181 node = vat_json_array_add(&vam->json_tree);
7182
7183 vat_json_init_object(node);
7184
Damjan Marionf1213b82016-03-13 02:22:06 +01007185 clib_memcpy(&addr, mp->our_address, sizeof(addr));
Ed Warnickecb9cada2015-12-08 15:45:58 -07007186 vat_json_object_add_ip6(node, "our_address", addr);
Damjan Marionf1213b82016-03-13 02:22:06 +01007187 clib_memcpy(&addr, mp->client_address, sizeof(addr));
Ed Warnickecb9cada2015-12-08 15:45:58 -07007188 vat_json_object_add_ip6(node, "client_address", addr);
7189
7190 vat_json_node_t * lc = vat_json_object_add(node, "local_cookie");
7191 vat_json_init_array(lc);
7192 vat_json_array_add_uint(lc, clib_net_to_host_u64(mp->local_cookie[0]));
7193 vat_json_array_add_uint(lc, clib_net_to_host_u64(mp->local_cookie[1]));
7194 vat_json_object_add_uint(node, "remote_cookie", clib_net_to_host_u64(mp->remote_cookie));
7195
7196 printf("local id: %u", clib_net_to_host_u32(mp->local_session_id));
7197 vat_json_object_add_uint(node, "local_session_id", clib_net_to_host_u32(mp->local_session_id));
7198 vat_json_object_add_uint(node, "remote_session_id", clib_net_to_host_u32(mp->remote_session_id));
7199 vat_json_object_add_string_copy(node, "l2_sublayer", mp->l2_sublayer_present ?
7200 (u8*)"present" : (u8*)"absent");
7201}
7202
7203static int api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
7204{
7205 vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
7206 f64 timeout;
7207
7208 /* Get list of l2tpv3-tunnel interfaces */
7209 M(SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
7210 S;
7211
7212 /* Use a control ping for synchronization */
7213 {
7214 vl_api_control_ping_t * mp;
7215 M(CONTROL_PING, control_ping);
7216 S;
7217 }
7218 W;
7219}
7220
7221
7222static void vl_api_sw_interface_tap_details_t_handler
7223(vl_api_sw_interface_tap_details_t * mp)
7224{
7225 vat_main_t * vam = &vat_main;
7226
7227 fformat(vam->ofp, "%-16s %d\n",
7228 mp->dev_name,
7229 clib_net_to_host_u32(mp->sw_if_index));
7230}
7231
7232static void vl_api_sw_interface_tap_details_t_handler_json
7233(vl_api_sw_interface_tap_details_t * mp)
7234{
7235 vat_main_t * vam = &vat_main;
7236 vat_json_node_t *node = NULL;
7237
7238 if (VAT_JSON_ARRAY != vam->json_tree.type) {
7239 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
7240 vat_json_init_array(&vam->json_tree);
7241 }
7242 node = vat_json_array_add(&vam->json_tree);
7243
7244 vat_json_init_object(node);
7245 vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
7246 vat_json_object_add_string_copy(node, "dev_name", mp->dev_name);
7247}
7248
7249static int api_sw_interface_tap_dump (vat_main_t * vam)
7250{
7251 vl_api_sw_interface_tap_dump_t *mp;
7252 f64 timeout;
7253
7254 fformat(vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
7255 /* Get list of tap interfaces */
7256 M(SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
7257 S;
7258
7259 /* Use a control ping for synchronization */
7260 {
7261 vl_api_control_ping_t * mp;
7262 M(CONTROL_PING, control_ping);
7263 S;
7264 }
7265 W;
7266}
7267
7268static uword unformat_vxlan_decap_next
7269(unformat_input_t * input, va_list * args)
7270{
7271 u32 * result = va_arg (*args, u32 *);
7272 u32 tmp;
7273
7274 if (unformat (input, "drop"))
7275 *result = VXLAN_INPUT_NEXT_DROP;
7276 else if (unformat (input, "ip4"))
7277 *result = VXLAN_INPUT_NEXT_IP4_INPUT;
7278 else if (unformat (input, "ip6"))
7279 *result = VXLAN_INPUT_NEXT_IP6_INPUT;
7280 else if (unformat (input, "l2"))
7281 *result = VXLAN_INPUT_NEXT_L2_INPUT;
7282 else if (unformat (input, "%d", &tmp))
7283 *result = tmp;
7284 else
7285 return 0;
7286 return 1;
7287}
7288
7289static int api_vxlan_add_del_tunnel (vat_main_t * vam)
7290{
7291 unformat_input_t * line_input = vam->input;
7292 vl_api_vxlan_add_del_tunnel_t *mp;
7293 f64 timeout;
Chris Luke99cb3352016-04-26 10:49:53 -04007294 ip4_address_t src4, dst4;
7295 ip6_address_t src6, dst6;
Ed Warnickecb9cada2015-12-08 15:45:58 -07007296 u8 is_add = 1;
Chris Luke99cb3352016-04-26 10:49:53 -04007297 u8 ipv4_set = 0, ipv6_set = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -07007298 u8 src_set = 0;
7299 u8 dst_set = 0;
7300 u32 encap_vrf_id = 0;
7301 u32 decap_next_index = ~0;
7302 u32 vni = 0;
7303
7304 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
7305 if (unformat (line_input, "del"))
7306 is_add = 0;
7307 else if (unformat (line_input, "src %U",
Chris Luke99cb3352016-04-26 10:49:53 -04007308 unformat_ip4_address, &src4))
7309 {
7310 ipv4_set = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -07007311 src_set = 1;
Chris Luke99cb3352016-04-26 10:49:53 -04007312 }
Ed Warnickecb9cada2015-12-08 15:45:58 -07007313 else if (unformat (line_input, "dst %U",
Chris Luke99cb3352016-04-26 10:49:53 -04007314 unformat_ip4_address, &dst4))
7315 {
7316 ipv4_set = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -07007317 dst_set = 1;
Chris Luke99cb3352016-04-26 10:49:53 -04007318 }
7319 else if (unformat (line_input, "src %U",
7320 unformat_ip6_address, &src6))
7321 {
7322 ipv6_set = 1;
7323 src_set = 1;
7324 }
7325 else if (unformat (line_input, "dst %U",
7326 unformat_ip6_address, &dst6))
7327 {
7328 ipv6_set = 1;
7329 dst_set = 1;
7330 }
Ed Warnickecb9cada2015-12-08 15:45:58 -07007331 else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
7332 ;
7333 else if (unformat (line_input, "decap-next %U",
7334 unformat_vxlan_decap_next, &decap_next_index))
7335 ;
7336 else if (unformat (line_input, "vni %d", &vni))
7337 ;
7338 else {
7339 errmsg ("parse error '%U'\n", format_unformat_error, line_input);
7340 return -99;
7341 }
7342 }
7343
7344 if (src_set == 0) {
7345 errmsg ("tunnel src address not specified\n");
7346 return -99;
7347 }
7348 if (dst_set == 0) {
7349 errmsg ("tunnel dst address not specified\n");
7350 return -99;
7351 }
7352
Chris Luke99cb3352016-04-26 10:49:53 -04007353 if (ipv4_set && ipv6_set) {
7354 errmsg ("both IPv4 and IPv6 addresses specified");
7355 return -99;
7356 }
7357
Ed Warnickecb9cada2015-12-08 15:45:58 -07007358 if ((vni == 0) || (vni>>24)) {
7359 errmsg ("vni not specified or out of range\n");
7360 return -99;
7361 }
7362
7363 M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
Chris Luke99cb3352016-04-26 10:49:53 -04007364
7365 if (ipv6_set) {
7366 clib_memcpy(&mp->dst_address, &src6, sizeof(src6));
7367 clib_memcpy(&mp->dst_address, &src6, sizeof(dst6));
7368 } else {
7369 clib_memcpy(&mp->src_address, &src4, sizeof(src4));
7370 clib_memcpy(&mp->dst_address, &dst4, sizeof(dst4));
7371 }
Ed Warnickecb9cada2015-12-08 15:45:58 -07007372 mp->encap_vrf_id = ntohl(encap_vrf_id);
7373 mp->decap_next_index = ntohl(decap_next_index);
7374 mp->vni = ntohl(vni);
7375 mp->is_add = is_add;
Chris Luke99cb3352016-04-26 10:49:53 -04007376 mp->is_ipv6 = ipv6_set;
Ed Warnickecb9cada2015-12-08 15:45:58 -07007377
7378 S; W;
7379 /* NOTREACHED */
7380 return 0;
7381}
7382
Dave Wallace60231f32015-12-17 21:04:30 -05007383static void vl_api_vxlan_tunnel_details_t_handler
7384(vl_api_vxlan_tunnel_details_t * mp)
7385{
7386 vat_main_t * vam = &vat_main;
7387
Chris Luke99cb3352016-04-26 10:49:53 -04007388 fformat(vam->ofp, "%11d%24U%24U%14d%18d%13d\n",
Dave Wallace60231f32015-12-17 21:04:30 -05007389 ntohl(mp->sw_if_index),
Chris Luke99cb3352016-04-26 10:49:53 -04007390 format_ip46_address, &(mp->src_address[0]),
7391 format_ip46_address, &(mp->dst_address[0]),
Dave Wallace60231f32015-12-17 21:04:30 -05007392 ntohl(mp->encap_vrf_id),
7393 ntohl(mp->decap_next_index),
7394 ntohl(mp->vni));
7395}
7396
7397static void vl_api_vxlan_tunnel_details_t_handler_json
7398(vl_api_vxlan_tunnel_details_t * mp)
7399{
7400 vat_main_t * vam = &vat_main;
7401 vat_json_node_t *node = NULL;
7402 struct in_addr ip4;
Chris Luke99cb3352016-04-26 10:49:53 -04007403 struct in6_addr ip6;
Dave Wallace60231f32015-12-17 21:04:30 -05007404
7405 if (VAT_JSON_ARRAY != vam->json_tree.type) {
7406 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
7407 vat_json_init_array(&vam->json_tree);
7408 }
7409 node = vat_json_array_add(&vam->json_tree);
7410
7411 vat_json_init_object(node);
7412 vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
Chris Luke99cb3352016-04-26 10:49:53 -04007413 if (mp->is_ipv6) {
7414 clib_memcpy(&ip6, &(mp->src_address[0]), sizeof(ip6));
7415 vat_json_object_add_ip6(node, "src_address", ip6);
7416 clib_memcpy(&ip6, &(mp->dst_address[0]), sizeof(ip6));
7417 vat_json_object_add_ip6(node, "dst_address", ip6);
7418 } else {
7419 clib_memcpy(&ip4, &(mp->src_address[0]), sizeof(ip4));
7420 vat_json_object_add_ip4(node, "src_address", ip4);
7421 clib_memcpy(&ip4, &(mp->dst_address[0]), sizeof(ip4));
7422 vat_json_object_add_ip4(node, "dst_address", ip4);
7423 }
Dave Wallace60231f32015-12-17 21:04:30 -05007424 vat_json_object_add_uint(node, "encap_vrf_id", ntohl(mp->encap_vrf_id));
7425 vat_json_object_add_uint(node, "decap_next_index", ntohl(mp->decap_next_index));
7426 vat_json_object_add_uint(node, "vni", ntohl(mp->vni));
Chris Luke99cb3352016-04-26 10:49:53 -04007427 vat_json_object_add_uint(node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
Dave Wallace60231f32015-12-17 21:04:30 -05007428}
7429
7430static int api_vxlan_tunnel_dump (vat_main_t * vam)
7431{
7432 unformat_input_t * i = vam->input;
7433 vl_api_vxlan_tunnel_dump_t *mp;
7434 f64 timeout;
7435 u32 sw_if_index;
7436 u8 sw_if_index_set = 0;
7437
7438 /* Parse args required to build the message */
7439 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7440 if (unformat (i, "sw_if_index %d", &sw_if_index))
7441 sw_if_index_set = 1;
7442 else
7443 break;
7444 }
7445
7446 if (sw_if_index_set == 0) {
7447 sw_if_index = ~0;
7448 }
7449
7450 if (!vam->json_output) {
Chris Luke99cb3352016-04-26 10:49:53 -04007451 fformat(vam->ofp, "%11s%24s%24s%14s%18s%13s\n",
Dave Wallace60231f32015-12-17 21:04:30 -05007452 "sw_if_index", "src_address", "dst_address",
7453 "encap_vrf_id", "decap_next_index", "vni");
7454 }
7455
Chris Luke99cb3352016-04-26 10:49:53 -04007456 /* Get list of vxlan-tunnel interfaces */
Dave Wallace60231f32015-12-17 21:04:30 -05007457 M(VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
7458
7459 mp->sw_if_index = htonl(sw_if_index);
7460
7461 S;
7462
7463 /* Use a control ping for synchronization */
7464 {
7465 vl_api_control_ping_t * mp;
7466 M(CONTROL_PING, control_ping);
7467 S;
7468 }
7469 W;
7470}
7471
Chris Luke27fe48f2016-04-28 13:44:38 -04007472static int api_gre_add_del_tunnel (vat_main_t * vam)
7473{
7474 unformat_input_t * line_input = vam->input;
7475 vl_api_gre_add_del_tunnel_t *mp;
7476 f64 timeout;
7477 ip4_address_t src4, dst4;
7478 u8 is_add = 1;
7479 u8 src_set = 0;
7480 u8 dst_set = 0;
7481 u32 outer_fib_id = 0;
7482
7483 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
7484 if (unformat (line_input, "del"))
7485 is_add = 0;
7486 else if (unformat (line_input, "src %U",
7487 unformat_ip4_address, &src4))
7488 src_set = 1;
7489 else if (unformat (line_input, "dst %U",
7490 unformat_ip4_address, &dst4))
7491 dst_set = 1;
7492 else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
7493 ;
7494 else {
7495 errmsg ("parse error '%U'\n", format_unformat_error, line_input);
7496 return -99;
7497 }
7498 }
7499
7500 if (src_set == 0) {
7501 errmsg ("tunnel src address not specified\n");
7502 return -99;
7503 }
7504 if (dst_set == 0) {
7505 errmsg ("tunnel dst address not specified\n");
7506 return -99;
7507 }
7508
7509
7510 M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
7511
7512 clib_memcpy(&mp->src_address, &src4, sizeof(src4));
7513 clib_memcpy(&mp->dst_address, &dst4, sizeof(dst4));
7514 mp->outer_table_id = ntohl(outer_fib_id);
7515 mp->is_add = is_add;
7516
7517 S; W;
7518 /* NOTREACHED */
7519 return 0;
7520}
7521
7522static void vl_api_gre_tunnel_details_t_handler
7523(vl_api_gre_tunnel_details_t * mp)
7524{
7525 vat_main_t * vam = &vat_main;
7526
7527 fformat(vam->ofp, "%11d%15U%15U%14d\n",
7528 ntohl(mp->sw_if_index),
7529 format_ip4_address, &mp->src_address,
7530 format_ip4_address, &mp->dst_address,
7531 ntohl(mp->outer_table_id));
7532}
7533
7534static void vl_api_gre_tunnel_details_t_handler_json
7535(vl_api_gre_tunnel_details_t * mp)
7536{
7537 vat_main_t * vam = &vat_main;
7538 vat_json_node_t *node = NULL;
7539 struct in_addr ip4;
7540
7541 if (VAT_JSON_ARRAY != vam->json_tree.type) {
7542 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
7543 vat_json_init_array(&vam->json_tree);
7544 }
7545 node = vat_json_array_add(&vam->json_tree);
7546
7547 vat_json_init_object(node);
7548 vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
7549 clib_memcpy(&ip4, &mp->src_address, sizeof(ip4));
7550 vat_json_object_add_ip4(node, "src_address", ip4);
7551 clib_memcpy(&ip4, &mp->dst_address, sizeof(ip4));
7552 vat_json_object_add_ip4(node, "dst_address", ip4);
7553 vat_json_object_add_uint(node, "outer_fib_id", ntohl(mp->outer_table_id));
7554}
7555
7556static int api_gre_tunnel_dump (vat_main_t * vam)
7557{
7558 unformat_input_t * i = vam->input;
7559 vl_api_gre_tunnel_dump_t *mp;
7560 f64 timeout;
7561 u32 sw_if_index;
7562 u8 sw_if_index_set = 0;
7563
7564 /* Parse args required to build the message */
7565 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7566 if (unformat (i, "sw_if_index %d", &sw_if_index))
7567 sw_if_index_set = 1;
7568 else
7569 break;
7570 }
7571
7572 if (sw_if_index_set == 0) {
7573 sw_if_index = ~0;
7574 }
7575
7576 if (!vam->json_output) {
7577 fformat(vam->ofp, "%11s%15s%15s%14s\n",
7578 "sw_if_index", "src_address", "dst_address",
7579 "outer_fib_id");
7580 }
7581
7582 /* Get list of gre-tunnel interfaces */
7583 M(GRE_TUNNEL_DUMP, gre_tunnel_dump);
7584
7585 mp->sw_if_index = htonl(sw_if_index);
7586
7587 S;
7588
7589 /* Use a control ping for synchronization */
7590 {
7591 vl_api_control_ping_t * mp;
7592 M(CONTROL_PING, control_ping);
7593 S;
7594 }
7595 W;
7596}
7597
Ed Warnickecb9cada2015-12-08 15:45:58 -07007598static int api_l2_fib_clear_table (vat_main_t * vam)
7599{
7600// unformat_input_t * i = vam->input;
7601 vl_api_l2_fib_clear_table_t *mp;
7602 f64 timeout;
7603
7604 M(L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
7605
7606 S; W;
7607 /* NOTREACHED */
7608 return 0;
7609}
7610
7611static int api_l2_interface_efp_filter (vat_main_t * vam)
7612{
7613 unformat_input_t * i = vam->input;
7614 vl_api_l2_interface_efp_filter_t *mp;
7615 f64 timeout;
7616 u32 sw_if_index;
7617 u8 enable = 1;
7618 u8 sw_if_index_set = 0;
7619
7620 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7621 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7622 sw_if_index_set = 1;
7623 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7624 sw_if_index_set = 1;
7625 else if (unformat (i, "enable"))
7626 enable = 1;
7627 else if (unformat (i, "disable"))
7628 enable = 0;
7629 else {
7630 clib_warning ("parse error '%U'", format_unformat_error, i);
7631 return -99;
7632 }
7633 }
7634
7635 if (sw_if_index_set == 0) {
7636 errmsg ("missing sw_if_index\n");
7637 return -99;
7638 }
7639
7640 M(L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
7641
7642 mp->sw_if_index = ntohl(sw_if_index);
7643 mp->enable_disable = enable;
7644
7645 S; W;
7646 /* NOTREACHED */
7647 return 0;
7648}
7649
7650#define foreach_vtr_op \
7651_("disable", L2_VTR_DISABLED) \
7652_("push-1", L2_VTR_PUSH_1) \
7653_("push-2", L2_VTR_PUSH_2) \
7654_("pop-1", L2_VTR_POP_1) \
7655_("pop-2", L2_VTR_POP_2) \
7656_("translate-1-1", L2_VTR_TRANSLATE_1_1) \
7657_("translate-1-2", L2_VTR_TRANSLATE_1_2) \
7658_("translate-2-1", L2_VTR_TRANSLATE_2_1) \
7659_("translate-2-2", L2_VTR_TRANSLATE_2_2)
7660
7661static int api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
7662{
7663 unformat_input_t * i = vam->input;
7664 vl_api_l2_interface_vlan_tag_rewrite_t *mp;
7665 f64 timeout;
7666 u32 sw_if_index;
7667 u8 sw_if_index_set = 0;
7668 u8 vtr_op_set = 0;
7669 u32 vtr_op = 0;
7670 u32 push_dot1q = 1;
7671 u32 tag1 = ~0;
7672 u32 tag2 = ~0;
7673
7674 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7675 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7676 sw_if_index_set = 1;
7677 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7678 sw_if_index_set = 1;
7679 else if (unformat (i, "vtr_op %d", &vtr_op))
7680 vtr_op_set = 1;
7681#define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
7682 foreach_vtr_op
7683#undef _
7684
7685 else if (unformat (i, "push_dot1q %d", &push_dot1q))
7686 ;
7687 else if (unformat (i, "tag1 %d", &tag1))
7688 ;
7689 else if (unformat (i, "tag2 %d", &tag2))
7690 ;
7691 else {
7692 clib_warning ("parse error '%U'", format_unformat_error, i);
7693 return -99;
7694 }
7695 }
7696
7697 if ((sw_if_index_set == 0)||(vtr_op_set == 0)) {
7698 errmsg ("missing vtr operation or sw_if_index\n");
7699 return -99;
7700 }
7701
7702 M(L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
7703
7704 mp->sw_if_index = ntohl(sw_if_index);
7705 mp->vtr_op = ntohl(vtr_op);
7706 mp->push_dot1q = ntohl(push_dot1q);
7707 mp->tag1 = ntohl(tag1);
7708 mp->tag2 = ntohl(tag2);
7709
7710 S; W;
7711 /* NOTREACHED */
7712 return 0;
7713}
7714
7715static int api_create_vhost_user_if (vat_main_t * vam)
7716{
7717 unformat_input_t * i = vam->input;
7718 vl_api_create_vhost_user_if_t *mp;
7719 f64 timeout;
7720 u8 * file_name;
7721 u8 is_server = 0;
7722 u8 file_name_set = 0;
7723 u32 custom_dev_instance = ~0;
Pierre Pfisteref65cb02016-02-19 13:52:44 +00007724 u8 hwaddr[6];
7725 u8 use_custom_mac = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -07007726
7727 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7728 if (unformat (i, "socket %s", &file_name)) {
7729 file_name_set = 1;
7730 }
7731 else if (unformat (i, "renumber %"PRIu32, &custom_dev_instance))
7732 ;
Pierre Pfisteref65cb02016-02-19 13:52:44 +00007733 else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
7734 use_custom_mac = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -07007735 else if (unformat (i, "server"))
7736 is_server = 1;
7737 else
7738 break;
7739 }
7740
7741 if (file_name_set == 0) {
7742 errmsg ("missing socket file name\n");
7743 return -99;
7744 }
7745
7746 if (vec_len (file_name) > 255) {
7747 errmsg ("socket file name too long\n");
7748 return -99;
7749 }
7750 vec_add1 (file_name, 0);
7751
7752 M(CREATE_VHOST_USER_IF, create_vhost_user_if);
7753
7754 mp->is_server = is_server;
Damjan Marionf1213b82016-03-13 02:22:06 +01007755 clib_memcpy(mp->sock_filename, file_name, vec_len(file_name));
Ed Warnickecb9cada2015-12-08 15:45:58 -07007756 vec_free(file_name);
7757 if (custom_dev_instance != ~0) {
7758 mp->renumber = 1;
7759 mp->custom_dev_instance = ntohl(custom_dev_instance);
7760 }
Pierre Pfisteref65cb02016-02-19 13:52:44 +00007761 mp->use_custom_mac = use_custom_mac;
Damjan Marionf1213b82016-03-13 02:22:06 +01007762 clib_memcpy(mp->mac_address, hwaddr, 6);
Ed Warnickecb9cada2015-12-08 15:45:58 -07007763
7764 S; W;
7765 /* NOTREACHED */
7766 return 0;
7767}
7768
7769static int api_modify_vhost_user_if (vat_main_t * vam)
7770{
7771 unformat_input_t * i = vam->input;
7772 vl_api_modify_vhost_user_if_t *mp;
7773 f64 timeout;
7774 u8 * file_name;
7775 u8 is_server = 0;
7776 u8 file_name_set = 0;
7777 u32 custom_dev_instance = ~0;
7778 u8 sw_if_index_set = 0;
7779 u32 sw_if_index = (u32)~0;
7780
7781 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7782 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7783 sw_if_index_set = 1;
7784 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7785 sw_if_index_set = 1;
7786 else if (unformat (i, "socket %s", &file_name)) {
7787 file_name_set = 1;
7788 }
7789 else if (unformat (i, "renumber %"PRIu32, &custom_dev_instance))
7790 ;
7791 else if (unformat (i, "server"))
7792 is_server = 1;
7793 else
7794 break;
7795 }
7796
7797 if (sw_if_index_set == 0) {
7798 errmsg ("missing sw_if_index or interface name\n");
7799 return -99;
7800 }
7801
7802 if (file_name_set == 0) {
7803 errmsg ("missing socket file name\n");
7804 return -99;
7805 }
7806
7807 if (vec_len (file_name) > 255) {
7808 errmsg ("socket file name too long\n");
7809 return -99;
7810 }
7811 vec_add1 (file_name, 0);
7812
7813 M(MODIFY_VHOST_USER_IF, modify_vhost_user_if);
7814
7815 mp->sw_if_index = ntohl(sw_if_index);
7816 mp->is_server = is_server;
Damjan Marionf1213b82016-03-13 02:22:06 +01007817 clib_memcpy(mp->sock_filename, file_name, vec_len(file_name));
Ed Warnickecb9cada2015-12-08 15:45:58 -07007818 vec_free(file_name);
7819 if (custom_dev_instance != ~0) {
7820 mp->renumber = 1;
7821 mp->custom_dev_instance = ntohl(custom_dev_instance);
7822 }
7823
7824 S; W;
7825 /* NOTREACHED */
7826 return 0;
7827}
7828
7829static int api_delete_vhost_user_if (vat_main_t * vam)
7830{
7831 unformat_input_t * i = vam->input;
7832 vl_api_delete_vhost_user_if_t *mp;
7833 f64 timeout;
7834 u32 sw_if_index = ~0;
7835 u8 sw_if_index_set = 0;
7836
7837 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7838 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7839 sw_if_index_set = 1;
7840 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7841 sw_if_index_set = 1;
7842 else
7843 break;
7844 }
7845
7846 if (sw_if_index_set == 0) {
7847 errmsg ("missing sw_if_index or interface name\n");
7848 return -99;
7849 }
7850
7851
7852 M(DELETE_VHOST_USER_IF, delete_vhost_user_if);
7853
7854 mp->sw_if_index = ntohl(sw_if_index);
7855
7856 S; W;
7857 /* NOTREACHED */
7858 return 0;
7859}
7860
7861static void vl_api_sw_interface_vhost_user_details_t_handler
7862(vl_api_sw_interface_vhost_user_details_t * mp)
7863{
7864 vat_main_t * vam = &vat_main;
7865
7866 fformat(vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
7867 (char *)mp->interface_name,
7868 ntohl(mp->sw_if_index), ntohl(mp->virtio_net_hdr_sz),
7869 clib_net_to_host_u64(mp->features), mp->is_server,
7870 ntohl(mp->num_regions), (char *)mp->sock_filename);
7871 fformat(vam->ofp, " Status: '%s'\n", strerror(ntohl(mp->sock_errno)));
7872}
7873
7874static void vl_api_sw_interface_vhost_user_details_t_handler_json
7875(vl_api_sw_interface_vhost_user_details_t * mp)
7876{
7877 vat_main_t * vam = &vat_main;
7878 vat_json_node_t *node = NULL;
7879
7880 if (VAT_JSON_ARRAY != vam->json_tree.type) {
7881 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
7882 vat_json_init_array(&vam->json_tree);
7883 }
7884 node = vat_json_array_add(&vam->json_tree);
7885
7886 vat_json_init_object(node);
7887 vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
7888 vat_json_object_add_string_copy(node, "interface_name", mp->interface_name);
7889 vat_json_object_add_uint(node, "virtio_net_hdr_sz", ntohl(mp->virtio_net_hdr_sz));
7890 vat_json_object_add_uint(node, "features", clib_net_to_host_u64(mp->features));
7891 vat_json_object_add_uint(node, "is_server", mp->is_server);
7892 vat_json_object_add_string_copy(node, "sock_filename", mp->sock_filename);
7893 vat_json_object_add_uint(node, "num_regions", ntohl(mp->num_regions));
7894 vat_json_object_add_uint(node, "sock_errno", ntohl(mp->sock_errno));
7895}
7896
7897static int api_sw_interface_vhost_user_dump (vat_main_t * vam)
7898{
7899 vl_api_sw_interface_vhost_user_dump_t *mp;
7900 f64 timeout;
7901 fformat(vam->ofp, "Interface name idx hdr_sz features server regions filename\n");
7902
7903 /* Get list of vhost-user interfaces */
7904 M(SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
7905 S;
7906
7907 /* Use a control ping for synchronization */
7908 {
7909 vl_api_control_ping_t * mp;
7910 M(CONTROL_PING, control_ping);
7911 S;
7912 }
7913 W;
7914}
7915
7916static int api_show_version (vat_main_t * vam)
7917{
7918 vl_api_show_version_t *mp;
7919 f64 timeout;
7920
7921 M(SHOW_VERSION, show_version);
7922
7923 S; W;
7924 /* NOTREACHED */
7925 return 0;
7926}
7927
7928static uword unformat_nsh_gre_decap_next
7929(unformat_input_t * input, va_list * args)
7930{
7931 u32 * result = va_arg (*args, u32 *);
7932 u32 tmp;
7933
7934 if (unformat (input, "drop"))
Keith Burns (alagalah)fdff1e62016-05-04 16:11:38 -07007935 *result = NSH_GRE_INPUT_NEXT_DROP;
Ed Warnickecb9cada2015-12-08 15:45:58 -07007936 else if (unformat (input, "ip4"))
Keith Burns (alagalah)fdff1e62016-05-04 16:11:38 -07007937 *result = NSH_GRE_INPUT_NEXT_IP4_INPUT;
Ed Warnickecb9cada2015-12-08 15:45:58 -07007938 else if (unformat (input, "ip6"))
Keith Burns (alagalah)fdff1e62016-05-04 16:11:38 -07007939 *result = NSH_GRE_INPUT_NEXT_IP6_INPUT;
Ed Warnickecb9cada2015-12-08 15:45:58 -07007940 else if (unformat (input, "ethernet"))
Keith Burns (alagalah)fdff1e62016-05-04 16:11:38 -07007941 *result = NSH_GRE_INPUT_NEXT_ETHERNET_INPUT;
Ed Warnickecb9cada2015-12-08 15:45:58 -07007942 else if (unformat (input, "%d", &tmp))
7943 *result = tmp;
7944 else
7945 return 0;
7946 return 1;
7947}
7948
7949static int api_nsh_gre_add_del_tunnel (vat_main_t * vam)
7950{
7951 unformat_input_t * line_input = vam->input;
7952 vl_api_nsh_gre_add_del_tunnel_t *mp;
7953 f64 timeout;
7954 ip4_address_t src, dst;
7955 u8 is_add = 1;
7956 u8 src_set = 0;
7957 u8 dst_set = 0;
7958 u32 encap_vrf_id = 0;
7959 u32 decap_vrf_id = 0;
7960 u8 ver_o_c = 0;
7961 u8 md_type = 0;
7962 u8 next_protocol = 1; /* ip4 */
7963 u32 spi;
7964 u8 spi_set = 0;
7965 u32 si;
7966 u8 si_set = 0;
7967 u32 spi_si;
7968 u32 c1 = 0;
7969 u32 c2 = 0;
7970 u32 c3 = 0;
7971 u32 c4 = 0;
7972 u32 *tlvs = 0;
Keith Burns (alagalah)fdff1e62016-05-04 16:11:38 -07007973 u32 decap_next_index = NSH_GRE_INPUT_NEXT_IP4_INPUT;
Ed Warnickecb9cada2015-12-08 15:45:58 -07007974 u32 tmp;
7975 int i;
7976
7977 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
7978 if (unformat (line_input, "del"))
7979 is_add = 0;
7980 else if (unformat (line_input, "src %U",
7981 unformat_ip4_address, &src))
7982 src_set = 1;
7983 else if (unformat (line_input, "dst %U",
7984 unformat_ip4_address, &dst))
7985 dst_set = 1;
7986 else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
7987 ;
7988 else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
7989 ;
7990 else if (unformat (line_input, "decap-next %U",
7991 unformat_nsh_gre_decap_next, &decap_next_index))
7992 ;
7993 else if (unformat (line_input, "version %d", &tmp))
7994 ver_o_c |= (tmp & 3) << 6;
7995 else if (unformat (line_input, "o-bit %d", &tmp))
7996 ver_o_c |= (tmp & 1) << 5;
7997 else if (unformat (line_input, "c-bit %d", &tmp))
7998 ver_o_c |= (tmp & 1) << 4;
7999 else if (unformat (line_input, "md-type %d", &tmp))
8000 md_type = tmp;
8001 else if (unformat(line_input, "next-ip4"))
8002 next_protocol = 1;
8003 else if (unformat(line_input, "next-ip6"))
8004 next_protocol = 2;
8005 else if (unformat(line_input, "next-ethernet"))
8006 next_protocol = 3;
8007 else if (unformat (line_input, "c1 %d", &c1))
8008 ;
8009 else if (unformat (line_input, "c2 %d", &c2))
8010 ;
8011 else if (unformat (line_input, "c3 %d", &c3))
8012 ;
8013 else if (unformat (line_input, "c4 %d", &c4))
8014 ;
8015 else if (unformat (line_input, "spi %d", &spi))
8016 spi_set = 1;
8017 else if (unformat (line_input, "si %d", &si))
8018 si_set = 1;
8019 else if (unformat (line_input, "tlv %x"))
8020 vec_add1 (tlvs, tmp);
8021 else {
8022 errmsg ("parse error '%U'\n", format_unformat_error, line_input);
8023 return -99;
8024 }
8025 }
8026
8027 if (src_set == 0) {
8028 errmsg ("tunnel src address not specified\n");
8029 return -99;
8030 }
8031 if (dst_set == 0) {
8032 errmsg ("tunnel dst address not specified\n");
8033 return -99;
8034 }
8035
8036 if (spi_set == 0) {
8037 errmsg ("spi not specified\n");
8038 return -99;
8039 }
8040
8041 if (si_set == 0) {
8042 errmsg ("si not specified\n");
8043 return -99;
8044 }
8045
8046 M2 (NSH_GRE_ADD_DEL_TUNNEL, nsh_gre_add_del_tunnel,
8047 sizeof(u32) * vec_len (tlvs));
8048
8049 spi_si = (spi<<8) | si;
8050
8051 mp->src = src.as_u32;
8052 mp->dst = dst.as_u32;
8053 mp->encap_vrf_id = ntohl(encap_vrf_id);
8054 mp->decap_vrf_id = ntohl(decap_vrf_id);
8055 mp->decap_next_index = ntohl(decap_next_index);
8056 mp->tlv_len_in_words = vec_len (tlvs);
8057 mp->is_add = is_add;
8058 mp->ver_o_c = ver_o_c;
8059 mp->length = 6 + vec_len(tlvs);
8060 mp->md_type = md_type;
8061 mp->next_protocol = next_protocol;
8062 mp->spi_si = ntohl(spi_si);
8063 mp->c1 = ntohl(c1);
8064 mp->c2 = ntohl(c2);
8065 mp->c3 = ntohl(c3);
8066 mp->c4 = ntohl(c4);
8067
8068 for (i = 0; i < vec_len(tlvs); i++)
8069 mp->tlvs[i] = ntohl(tlvs[i]);
8070
8071 vec_free (tlvs);
8072
8073 S; W;
8074 /* NOTREACHED */
8075 return 0;
8076}
8077
8078static uword unformat_nsh_vxlan_gpe_decap_next
8079(unformat_input_t * input, va_list * args)
8080{
8081 u32 * result = va_arg (*args, u32 *);
8082 u32 tmp;
8083
8084 if (unformat (input, "drop"))
8085 *result = NSH_VXLAN_GPE_INPUT_NEXT_DROP;
8086 else if (unformat (input, "ip4"))
8087 *result = NSH_VXLAN_GPE_INPUT_NEXT_IP4_INPUT;
8088 else if (unformat (input, "ip6"))
8089 *result = NSH_VXLAN_GPE_INPUT_NEXT_IP6_INPUT;
8090 else if (unformat (input, "ethernet"))
8091 *result = NSH_VXLAN_GPE_INPUT_NEXT_ETHERNET_INPUT;
8092 else if (unformat (input, "nsh-vxlan-gpe"))
8093 *result = NSH_VXLAN_GPE_INPUT_NEXT_ETHERNET_INPUT;
8094 else if (unformat (input, "%d", &tmp))
8095 *result = tmp;
8096 else
8097 return 0;
8098 return 1;
8099}
8100
8101static int api_nsh_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
8102{
8103 unformat_input_t * line_input = vam->input;
8104 vl_api_nsh_vxlan_gpe_add_del_tunnel_t *mp;
8105 f64 timeout;
8106 ip4_address_t src, dst;
8107 u8 is_add = 1;
8108 u8 src_set = 0;
8109 u8 dst_set = 0;
8110 u32 encap_vrf_id = 0;
8111 u32 decap_vrf_id = 0;
8112 u8 ver_o_c = 0;
8113 u8 md_type = 0;
8114 u8 next_protocol = 1; /* ip4 */
8115 u32 spi;
8116 u8 spi_set = 0;
8117 u32 si;
8118 u8 si_set = 0;
8119 u32 spi_si;
8120 u32 c1 = 0;
8121 u32 c2 = 0;
8122 u32 c3 = 0;
8123 u32 c4 = 0;
8124 u32 *tlvs = 0;
Keith Burns (alagalah)fdff1e62016-05-04 16:11:38 -07008125 u32 decap_next_index = NSH_GRE_INPUT_NEXT_IP4_INPUT;
Ed Warnickecb9cada2015-12-08 15:45:58 -07008126 u32 vni;
8127 u8 vni_set = 0;
8128 u32 tmp;
8129 int i;
8130
8131 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
8132 if (unformat (line_input, "del"))
8133 is_add = 0;
8134 else if (unformat (line_input, "src %U",
8135 unformat_ip4_address, &src))
8136 src_set = 1;
8137 else if (unformat (line_input, "dst %U",
8138 unformat_ip4_address, &dst))
8139 dst_set = 1;
8140 else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
8141 ;
8142 else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
8143 ;
8144 else if (unformat (line_input, "decap-next %U",
8145 unformat_nsh_vxlan_gpe_decap_next,
8146 &decap_next_index))
8147 ;
8148 else if (unformat (line_input, "vni %d", &vni))
8149 vni_set = 1;
8150 else if (unformat (line_input, "version %d", &tmp))
8151 ver_o_c |= (tmp & 3) << 6;
8152 else if (unformat (line_input, "o-bit %d", &tmp))
8153 ver_o_c |= (tmp & 1) << 5;
8154 else if (unformat (line_input, "c-bit %d", &tmp))
8155 ver_o_c |= (tmp & 1) << 4;
8156 else if (unformat (line_input, "md-type %d", &tmp))
8157 md_type = tmp;
8158 else if (unformat(line_input, "next-ip4"))
8159 next_protocol = 1;
8160 else if (unformat(line_input, "next-ip6"))
8161 next_protocol = 2;
8162 else if (unformat(line_input, "next-ethernet"))
8163 next_protocol = 3;
8164 else if (unformat (line_input, "c1 %d", &c1))
8165 ;
8166 else if (unformat (line_input, "c2 %d", &c2))
8167 ;
8168 else if (unformat (line_input, "c3 %d", &c3))
8169 ;
8170 else if (unformat (line_input, "c4 %d", &c4))
8171 ;
8172 else if (unformat (line_input, "spi %d", &spi))
8173 spi_set = 1;
8174 else if (unformat (line_input, "si %d", &si))
8175 si_set = 1;
8176 else if (unformat (line_input, "tlv %x"))
8177 vec_add1 (tlvs, tmp);
8178 else {
8179 errmsg ("parse error '%U'\n", format_unformat_error, line_input);
8180 return -99;
8181 }
8182 }
8183
8184 if (src_set == 0) {
8185 errmsg ("tunnel src address not specified\n");
8186 return -99;
8187 }
8188 if (dst_set == 0) {
8189 errmsg ("tunnel dst address not specified\n");
8190 return -99;
8191 }
8192
8193 if (spi_set == 0) {
8194 errmsg ("spi not specified\n");
8195 return -99;
8196 }
8197
8198 if (si_set == 0) {
8199 errmsg ("si not specified\n");
8200 return -99;
8201 }
8202 if (vni_set == 0) {
8203 errmsg ("vni not specified\n");
8204 return -99;
8205 }
8206
8207 M2 (NSH_VXLAN_GPE_ADD_DEL_TUNNEL, nsh_vxlan_gpe_add_del_tunnel,
8208 sizeof(u32) * vec_len (tlvs));
8209
8210 spi_si = (spi<<8) | si;
8211
8212 mp->src = src.as_u32;
8213 mp->dst = dst.as_u32;
8214 mp->encap_vrf_id = ntohl(encap_vrf_id);
8215 mp->decap_vrf_id = ntohl(decap_vrf_id);
8216 mp->decap_next_index = ntohl(decap_next_index);
8217 mp->tlv_len_in_words = vec_len (tlvs);
8218 mp->vni = ntohl(vni);
8219 mp->is_add = is_add;
8220 mp->ver_o_c = ver_o_c;
8221 mp->length = 6 + vec_len(tlvs);
8222 mp->md_type = md_type;
8223 mp->next_protocol = next_protocol;
8224 mp->spi_si = ntohl(spi_si);
8225 mp->c1 = ntohl(c1);
8226 mp->c2 = ntohl(c2);
8227 mp->c3 = ntohl(c3);
8228 mp->c4 = ntohl(c4);
8229
8230 for (i = 0; i < vec_len(tlvs); i++)
8231 mp->tlvs[i] = ntohl(tlvs[i]);
8232
8233 vec_free (tlvs);
8234
8235 S; W;
8236 /* NOTREACHED */
8237 return 0;
8238}
8239
8240static uword unformat_lisp_gpe_decap_next (unformat_input_t * input,
8241 va_list * args)
8242{
8243 u32 * result = va_arg (*args, u32 *);
8244 u32 tmp;
8245
8246 if (unformat (input, "drop"))
8247 *result = LISP_GPE_INPUT_NEXT_DROP;
8248 else if (unformat (input, "ip4"))
8249 *result = LISP_GPE_INPUT_NEXT_IP4_INPUT;
8250 else if (unformat (input, "ip6"))
8251 *result = LISP_GPE_INPUT_NEXT_IP6_INPUT;
8252 else if (unformat (input, "ethernet"))
8253 *result = LISP_GPE_INPUT_NEXT_IP6_INPUT;
Ed Warnickecb9cada2015-12-08 15:45:58 -07008254 else if (unformat (input, "%d", &tmp))
8255 *result = tmp;
8256 else
8257 return 0;
8258 return 1;
8259}
8260
8261static int
8262api_lisp_gpe_add_del_tunnel (vat_main_t * vam)
8263{
8264 unformat_input_t * line_input = vam->input;
8265 vl_api_lisp_gpe_add_del_tunnel_t *mp;
8266 f64 timeout;
8267 ip4_address_t src, dst;
8268 u8 is_add = 1;
8269 u8 src_set = 0;
8270 u8 dst_set = 0;
8271 u32 encap_vrf_id = 0;
8272 u32 decap_vrf_id = 0;
8273 u8 next_protocol = LISP_GPE_NEXT_PROTOCOL_IP4;
8274 u32 decap_next_index = LISP_GPE_INPUT_NEXT_IP4_INPUT;
8275 u8 flags = LISP_GPE_FLAGS_P;
8276 u8 ver_res = 0;
8277 u8 res = 0;
8278 u32 iid = 0;
8279 u8 iid_set = 0;
8280 u32 tmp;
8281
8282 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
8283 if (unformat (line_input, "del"))
8284 is_add = 0;
8285 else if (unformat (line_input, "src %U",
8286 unformat_ip4_address, &src))
8287 src_set = 1;
8288 else if (unformat (line_input, "dst %U",
8289 unformat_ip4_address, &dst))
8290 dst_set = 1;
8291 else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
8292 ;
8293 else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
8294 ;
8295 else if (unformat (line_input, "decap-next %U",
8296 unformat_lisp_gpe_decap_next,
8297 &decap_next_index))
8298 ;
8299 else if (unformat(line_input, "next-ip4"))
8300 next_protocol = 1;
8301 else if (unformat(line_input, "next-ip6"))
8302 next_protocol = 2;
8303 else if (unformat(line_input, "next-ethernet"))
8304 next_protocol = 3;
8305 else if (unformat(line_input, "next-nsh"))
8306 next_protocol = 4;
8307 /* Allow the user to specify anything they want in the LISP hdr */
8308 else if (unformat (line_input, "ver_res %x", &tmp))
8309 ver_res = tmp;
8310 else if (unformat (line_input, "res %x", &tmp))
8311 res = tmp;
8312 else if (unformat (line_input, "flags %x", &tmp))
8313 flags = tmp;
8314 else if (unformat (line_input, "n-bit"))
8315 flags |= LISP_GPE_FLAGS_N;
8316 else if (unformat (line_input, "l-bit"))
8317 flags |= LISP_GPE_FLAGS_L;
8318 else if (unformat (line_input, "e-bit"))
8319 flags |= LISP_GPE_FLAGS_E;
8320 else if (unformat (line_input, "v-bit"))
8321 flags |= LISP_GPE_FLAGS_V;
8322 else if (unformat (line_input, "i-bit"))
8323 flags |= LISP_GPE_FLAGS_V;
8324 else if (unformat (line_input, "not-p-bit"))
8325 flags &= !LISP_GPE_FLAGS_P;
8326 else if (unformat (line_input, "p-bit"))
8327 flags |= LISP_GPE_FLAGS_P;
8328 else if (unformat (line_input, "o-bit"))
8329 flags |= LISP_GPE_FLAGS_O;
8330 else if (unformat (line_input, "iidx %x", &iid))
8331 iid_set = 1;
8332 else if (unformat (line_input, "iid %d", &iid))
8333 iid_set = 1;
8334 else {
8335 errmsg ("parse error '%U'\n", format_unformat_error, line_input);
8336 return -99;
8337 }
8338 }
8339
8340 if (src_set == 0) {
8341 errmsg ("tunnel src address not specified\n");
8342 return -99;
8343 }
8344 if (dst_set == 0) {
8345 errmsg ("tunnel dst address not specified\n");
8346 return -99;
8347 }
8348 if (iid_set == 0) {
8349 errmsg ("iid not specified\n");
8350 return -99;
8351 }
8352
8353 M(LISP_GPE_ADD_DEL_TUNNEL, lisp_gpe_add_del_tunnel);
8354
8355 mp->src = src.as_u32;
8356 mp->dst = dst.as_u32;
8357 mp->encap_vrf_id = ntohl(encap_vrf_id);
8358 mp->decap_vrf_id = ntohl(decap_vrf_id);
8359 mp->decap_next_index = ntohl(decap_next_index);
8360 mp->is_add = is_add;
8361 mp->flags = flags;
8362 mp->ver_res = ver_res;
8363 mp->res = res;
8364 mp->next_protocol = next_protocol;
8365 mp->iid = ntohl(iid);
8366
8367 S; W;
8368
8369 /* NOTREACHED */
8370 return 0;
8371}
8372
8373
8374u8 * format_l2_fib_mac_address (u8 * s, va_list * args)
8375{
8376 u8 * a = va_arg (*args, u8 *);
8377
8378 return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
8379 a[2], a[3], a[4], a[5], a[6], a[7]);
8380}
8381
8382static void vl_api_l2_fib_table_entry_t_handler
8383(vl_api_l2_fib_table_entry_t * mp)
8384{
8385 vat_main_t * vam = &vat_main;
8386
8387 fformat(vam->ofp, "%3" PRIu32 " %U %3" PRIu32
8388 " %d %d %d\n",
8389 ntohl(mp->bd_id), format_l2_fib_mac_address, &mp->mac,
8390 ntohl(mp->sw_if_index), mp->static_mac, mp->filter_mac,
8391 mp->bvi_mac);
8392}
8393
8394static void vl_api_l2_fib_table_entry_t_handler_json
8395(vl_api_l2_fib_table_entry_t * mp)
8396{
8397 vat_main_t * vam = &vat_main;
8398 vat_json_node_t *node = NULL;
8399
8400 if (VAT_JSON_ARRAY != vam->json_tree.type) {
8401 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
8402 vat_json_init_array(&vam->json_tree);
8403 }
8404 node = vat_json_array_add(&vam->json_tree);
8405
8406 vat_json_init_object(node);
8407 vat_json_object_add_uint(node, "bd_id", ntohl(mp->bd_id));
8408 vat_json_object_add_uint(node, "mac", clib_net_to_host_u64(mp->mac));
8409 vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
8410 vat_json_object_add_uint(node, "static_mac", mp->static_mac);
8411 vat_json_object_add_uint(node, "filter_mac", mp->filter_mac);
8412 vat_json_object_add_uint(node, "bvi_mac", mp->bvi_mac);
8413}
8414
8415static int api_l2_fib_table_dump (vat_main_t * vam)
8416{
8417 unformat_input_t * i = vam->input;
8418 vl_api_l2_fib_table_dump_t *mp;
8419 f64 timeout;
8420 u32 bd_id;
8421 u8 bd_id_set = 0;
8422
8423 /* Parse args required to build the message */
8424 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8425 if (unformat (i, "bd_id %d", &bd_id))
8426 bd_id_set = 1;
8427 else
8428 break;
8429 }
8430
8431 if (bd_id_set == 0) {
8432 errmsg ("missing bridge domain\n");
8433 return -99;
8434 }
8435
8436 fformat(vam->ofp, "BD-ID Mac Address sw-ndx Static Filter BVI\n");
8437
8438 /* Get list of l2 fib entries */
8439 M(L2_FIB_TABLE_DUMP, l2_fib_table_dump);
8440
8441 mp->bd_id = ntohl(bd_id);
8442 S;
8443
8444 /* Use a control ping for synchronization */
8445 {
8446 vl_api_control_ping_t * mp;
8447 M(CONTROL_PING, control_ping);
8448 S;
8449 }
8450 W;
8451}
8452
8453
8454static int
8455api_interface_name_renumber (vat_main_t * vam)
8456{
8457 unformat_input_t * line_input = vam->input;
8458 vl_api_interface_name_renumber_t *mp;
8459 u32 sw_if_index = ~0;
8460 f64 timeout;
8461 u32 new_show_dev_instance = ~0;
8462
8463 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
8464 if (unformat (line_input, "%U", unformat_sw_if_index, vam,
8465 &sw_if_index))
8466 ;
8467 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
8468 ;
8469 else if (unformat (line_input, "new_show_dev_instance %d",
8470 &new_show_dev_instance))
8471 ;
8472 else
8473 break;
8474 }
8475
8476 if (sw_if_index == ~0) {
8477 errmsg ("missing interface name or sw_if_index\n");
8478 return -99;
8479 }
8480
8481 if (new_show_dev_instance == ~0) {
8482 errmsg ("missing new_show_dev_instance\n");
8483 return -99;
8484 }
8485
8486 M(INTERFACE_NAME_RENUMBER, interface_name_renumber);
8487
8488 mp->sw_if_index = ntohl (sw_if_index);
8489 mp->new_show_dev_instance = ntohl (new_show_dev_instance);
8490
8491 S; W;
8492}
8493
8494static int
8495api_want_ip4_arp_events (vat_main_t * vam)
8496{
8497 unformat_input_t * line_input = vam->input;
8498 vl_api_want_ip4_arp_events_t * mp;
8499 f64 timeout;
8500 ip4_address_t address;
8501 int address_set = 0;
8502 u32 enable_disable = 1;
8503
8504 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
8505 if (unformat (line_input, "address %U",
8506 unformat_ip4_address, &address))
8507 address_set = 1;
8508 else if (unformat (line_input, "del"))
8509 enable_disable = 0;
8510 else
8511 break;
8512 }
8513
8514 if (address_set == 0) {
8515 errmsg ("missing addresses\n");
8516 return -99;
8517 }
8518
8519 M(WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
8520 mp->enable_disable = enable_disable;
8521 mp->pid = getpid();
8522 mp->address = address.as_u32;
8523
8524 S; W;
8525}
8526
8527static int api_input_acl_set_interface (vat_main_t * vam)
8528{
8529 unformat_input_t * i = vam->input;
8530 vl_api_input_acl_set_interface_t *mp;
8531 f64 timeout;
8532 u32 sw_if_index;
8533 int sw_if_index_set;
8534 u32 ip4_table_index = ~0;
8535 u32 ip6_table_index = ~0;
8536 u32 l2_table_index = ~0;
8537 u8 is_add = 1;
8538
8539 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8540 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8541 sw_if_index_set = 1;
8542 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8543 sw_if_index_set = 1;
8544 else if (unformat (i, "del"))
8545 is_add = 0;
8546 else if (unformat (i, "ip4-table %d", &ip4_table_index))
8547 ;
8548 else if (unformat (i, "ip6-table %d", &ip6_table_index))
8549 ;
8550 else if (unformat (i, "l2-table %d", &l2_table_index))
8551 ;
8552 else {
8553 clib_warning ("parse error '%U'", format_unformat_error, i);
8554 return -99;
8555 }
8556 }
8557
8558 if (sw_if_index_set == 0) {
8559 errmsg ("missing interface name or sw_if_index\n");
8560 return -99;
8561 }
8562
8563 M(INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
8564
8565 mp->sw_if_index = ntohl(sw_if_index);
8566 mp->ip4_table_index = ntohl(ip4_table_index);
8567 mp->ip6_table_index = ntohl(ip6_table_index);
8568 mp->l2_table_index = ntohl(l2_table_index);
8569 mp->is_add = is_add;
8570
8571 S; W;
8572 /* NOTREACHED */
8573 return 0;
8574}
8575
8576static int
8577api_ip_address_dump (vat_main_t * vam)
8578{
8579 unformat_input_t * i = vam->input;
8580 vl_api_ip_address_dump_t * mp;
8581 u32 sw_if_index = ~0;
8582 u8 sw_if_index_set = 0;
8583 u8 ipv4_set = 0;
8584 u8 ipv6_set = 0;
8585 f64 timeout;
8586
8587 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8588 if (unformat (i, "sw_if_index %d", &sw_if_index))
8589 sw_if_index_set = 1;
8590 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8591 sw_if_index_set = 1;
8592 else if (unformat (i, "ipv4"))
8593 ipv4_set = 1;
8594 else if (unformat (i, "ipv6"))
8595 ipv6_set = 1;
8596 else
8597 break;
8598 }
8599
8600 if (ipv4_set && ipv6_set) {
8601 errmsg ("ipv4 and ipv6 flags cannot be both set\n");
8602 return -99;
8603 }
8604
8605 if ((!ipv4_set) && (!ipv6_set)) {
8606 errmsg ("no ipv4 nor ipv6 flag set\n");
8607 return -99;
8608 }
8609
8610 if (sw_if_index_set == 0) {
8611 errmsg ("missing interface name or sw_if_index\n");
8612 return -99;
8613 }
8614
8615 vam->current_sw_if_index = sw_if_index;
8616 vam->is_ipv6 = ipv6_set;
8617
8618 M(IP_ADDRESS_DUMP, ip_address_dump);
8619 mp->sw_if_index = ntohl(sw_if_index);
8620 mp->is_ipv6 = ipv6_set;
8621 S;
8622
8623 /* Use a control ping for synchronization */
8624 {
8625 vl_api_control_ping_t * mp;
8626 M(CONTROL_PING, control_ping);
8627 S;
8628 }
8629 W;
8630}
8631
8632static int
8633api_ip_dump (vat_main_t * vam)
8634{
8635 vl_api_ip_dump_t * mp;
8636 unformat_input_t * in = vam->input;
8637 int ipv4_set = 0;
8638 int ipv6_set = 0;
8639 int is_ipv6;
8640 f64 timeout;
8641 int i;
8642
8643 while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT) {
8644 if (unformat (in, "ipv4"))
8645 ipv4_set = 1;
8646 else if (unformat (in, "ipv6"))
8647 ipv6_set = 1;
8648 else
8649 break;
8650 }
8651
8652 if (ipv4_set && ipv6_set) {
8653 errmsg ("ipv4 and ipv6 flags cannot be both set\n");
8654 return -99;
8655 }
8656
8657 if ((!ipv4_set) && (!ipv6_set)) {
8658 errmsg ("no ipv4 nor ipv6 flag set\n");
8659 return -99;
8660 }
8661
8662 is_ipv6 = ipv6_set;
8663 vam->is_ipv6 = is_ipv6;
8664
8665 /* free old data */
8666 for (i = 0; i < vec_len(vam->ip_details_by_sw_if_index[is_ipv6]); i++) {
8667 vec_free(vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
8668 }
8669 vec_free(vam->ip_details_by_sw_if_index[is_ipv6]);
8670
8671 M(IP_DUMP, ip_dump);
8672 mp->is_ipv6 = ipv6_set;
8673 S;
8674
8675 /* Use a control ping for synchronization */
8676 {
8677 vl_api_control_ping_t * mp;
8678 M(CONTROL_PING, control_ping);
8679 S;
8680 }
8681 W;
8682}
8683
8684static int
8685api_ipsec_spd_add_del (vat_main_t * vam)
8686{
Dave Barachbfdedbd2016-01-20 09:11:55 -05008687#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -07008688 unformat_input_t * i = vam->input;
8689 vl_api_ipsec_spd_add_del_t *mp;
8690 f64 timeout;
8691 u32 spd_id = ~0;
8692 u8 is_add = 1;
8693
8694 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8695 if (unformat (i, "spd_id %d", &spd_id))
8696 ;
8697 else if (unformat (i, "del"))
8698 is_add = 0;
8699 else {
8700 clib_warning ("parse error '%U'", format_unformat_error, i);
8701 return -99;
8702 }
8703 }
8704 if (spd_id == ~0) {
8705 errmsg ("spd_id must be set\n");
8706 return -99;
8707 }
8708
8709 M(IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
8710
8711 mp->spd_id = ntohl(spd_id);
8712 mp->is_add = is_add;
8713
8714 S; W;
8715 /* NOTREACHED */
8716 return 0;
Dave Barachbfdedbd2016-01-20 09:11:55 -05008717#else
8718 clib_warning ("unsupported (no dpdk)");
8719 return -99;
8720#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -07008721}
8722
8723static int
8724api_ipsec_interface_add_del_spd (vat_main_t * vam)
8725{
Dave Barachbfdedbd2016-01-20 09:11:55 -05008726#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -07008727 unformat_input_t * i = vam->input;
8728 vl_api_ipsec_interface_add_del_spd_t *mp;
8729 f64 timeout;
8730 u32 sw_if_index;
8731 u8 sw_if_index_set = 0;
8732 u32 spd_id = (u32) ~0;
8733 u8 is_add = 1;
8734
8735 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8736 if (unformat (i, "del"))
8737 is_add = 0;
8738 else if (unformat (i, "spd_id %d", &spd_id))
8739 ;
8740 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8741 sw_if_index_set = 1;
8742 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8743 sw_if_index_set = 1;
8744 else {
8745 clib_warning ("parse error '%U'", format_unformat_error, i);
8746 return -99;
8747 }
8748
8749 }
8750
8751 if (spd_id == (u32) ~0) {
8752 errmsg ("spd_id must be set\n");
8753 return -99;
8754 }
8755
8756 if (sw_if_index_set == 0) {
8757 errmsg ("missing interface name or sw_if_index\n");
8758 return -99;
8759 }
8760
8761 M(IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
8762
8763 mp->spd_id = ntohl(spd_id);
8764 mp->sw_if_index = ntohl (sw_if_index);
8765 mp->is_add = is_add;
8766
8767 S; W;
8768 /* NOTREACHED */
8769 return 0;
Dave Barachbfdedbd2016-01-20 09:11:55 -05008770#else
8771 clib_warning ("unsupported (no dpdk)");
8772 return -99;
8773#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -07008774}
8775
8776static int
8777api_ipsec_spd_add_del_entry (vat_main_t * vam)
8778{
Dave Barachbfdedbd2016-01-20 09:11:55 -05008779#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -07008780 unformat_input_t * i = vam->input;
8781 vl_api_ipsec_spd_add_del_entry_t *mp;
8782 f64 timeout;
8783 u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
8784 u32 spd_id, sa_id, protocol = 0, policy = 0;
8785 i32 priority;
8786 u32 rport_start = 0, rport_stop = (u32) ~0;
8787 u32 lport_start = 0, lport_stop = (u32) ~0;
8788 ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
8789 ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
8790
8791 laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
8792 laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~0;
8793 laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
8794 laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
8795 laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~0;
8796 laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~0;
8797
8798 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8799 if (unformat (i, "del"))
8800 is_add = 0;
8801 if (unformat (i, "outbound"))
8802 is_outbound = 1;
8803 if (unformat (i, "inbound"))
8804 is_outbound = 0;
8805 else if (unformat (i, "spd_id %d", &spd_id))
8806 ;
8807 else if (unformat (i, "sa_id %d", &sa_id))
8808 ;
8809 else if (unformat (i, "priority %d", &priority))
8810 ;
8811 else if (unformat (i, "protocol %d", &protocol))
8812 ;
8813 else if (unformat (i, "lport_start %d", &lport_start))
8814 ;
8815 else if (unformat (i, "lport_stop %d", &lport_stop))
8816 ;
8817 else if (unformat (i, "rport_start %d", &rport_start))
8818 ;
8819 else if (unformat (i, "rport_stop %d", &rport_stop))
8820 ;
8821 else if (unformat (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
8822 {
8823 is_ipv6 = 0;
8824 is_ip_any =0;
8825 }
8826 else if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
8827 {
8828 is_ipv6 = 0;
8829 is_ip_any = 0;
8830 }
8831 else if (unformat (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
8832 {
8833 is_ipv6 = 0;
8834 is_ip_any = 0;
8835 }
8836 else if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
8837 {
8838 is_ipv6 = 0;
8839 is_ip_any = 0;
8840 }
8841 else if (unformat (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
8842 {
8843 is_ipv6 = 1;
8844 is_ip_any = 0;
8845 }
8846 else if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
8847 {
8848 is_ipv6 = 1;
8849 is_ip_any = 0;
8850 }
8851 else if (unformat (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
8852 {
8853 is_ipv6 = 1;
8854 is_ip_any = 0;
8855 }
8856 else if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
8857 {
8858 is_ipv6 = 1;
8859 is_ip_any = 0;
8860 }
8861 else if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
8862 {
8863 if (policy == IPSEC_POLICY_ACTION_RESOLVE) {
8864 clib_warning ("unsupported action: 'resolve'");
8865 return -99;
8866 }
8867 }
8868 else {
8869 clib_warning ("parse error '%U'", format_unformat_error, i);
8870 return -99;
8871 }
8872
8873 }
8874
8875 M(IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
8876
8877 mp->spd_id = ntohl(spd_id);
8878 mp->priority = ntohl(priority);
8879 mp->is_outbound = is_outbound;
8880
8881 mp->is_ipv6 = is_ipv6;
8882 if (is_ipv6 || is_ip_any) {
Damjan Marionf1213b82016-03-13 02:22:06 +01008883 clib_memcpy (mp->remote_address_start, &raddr6_start, sizeof(ip6_address_t));
8884 clib_memcpy (mp->remote_address_stop, &raddr6_stop, sizeof(ip6_address_t));
8885 clib_memcpy (mp->local_address_start, &laddr6_start, sizeof(ip6_address_t));
8886 clib_memcpy (mp->local_address_stop, &laddr6_stop, sizeof(ip6_address_t));
Ed Warnickecb9cada2015-12-08 15:45:58 -07008887 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01008888 clib_memcpy (mp->remote_address_start, &raddr4_start, sizeof(ip4_address_t));
8889 clib_memcpy (mp->remote_address_stop, &raddr4_stop, sizeof(ip4_address_t));
8890 clib_memcpy (mp->local_address_start, &laddr4_start, sizeof(ip4_address_t));
8891 clib_memcpy (mp->local_address_stop, &laddr4_stop, sizeof(ip4_address_t));
Ed Warnickecb9cada2015-12-08 15:45:58 -07008892 }
8893 mp->protocol = (u8) protocol;
8894 mp->local_port_start = ntohs((u16) lport_start);
8895 mp->local_port_stop = ntohs((u16) lport_stop);
8896 mp->remote_port_start = ntohs((u16) rport_start);
8897 mp->remote_port_stop = ntohs((u16) rport_stop);
8898 mp->policy = (u8) policy;
8899 mp->sa_id = ntohl(sa_id);
8900 mp->is_add = is_add;
8901 mp->is_ip_any = is_ip_any;
8902 S; W;
8903 /* NOTREACHED */
8904 return 0;
Dave Barachbfdedbd2016-01-20 09:11:55 -05008905#else
8906 clib_warning ("unsupported (no dpdk)");
8907 return -99;
8908#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -07008909}
8910
8911static int
8912api_ipsec_sad_add_del_entry (vat_main_t * vam)
8913{
Dave Barachbfdedbd2016-01-20 09:11:55 -05008914#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -07008915 unformat_input_t * i = vam->input;
8916 vl_api_ipsec_sad_add_del_entry_t *mp;
8917 f64 timeout;
8918 u32 sad_id, spi;
8919 u8 * ck, * ik;
8920 u8 is_add = 1;
8921
8922 u8 protocol = IPSEC_PROTOCOL_AH;
8923 u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
8924 u32 crypto_alg = 0, integ_alg = 0;
8925 ip4_address_t tun_src4;
8926 ip4_address_t tun_dst4;
8927 ip6_address_t tun_src6;
8928 ip6_address_t tun_dst6;
8929
8930 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8931 if (unformat (i, "del"))
8932 is_add = 0;
8933 else if (unformat (i, "sad_id %d", &sad_id))
8934 ;
8935 else if (unformat (i, "spi %d", &spi))
8936 ;
8937 else if (unformat (i, "esp"))
8938 protocol = IPSEC_PROTOCOL_ESP;
8939 else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4)) {
8940 is_tunnel = 1;
8941 is_tunnel_ipv6 = 0;
8942 }
8943 else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4)) {
8944 is_tunnel = 1;
8945 is_tunnel_ipv6 = 0;
8946 }
8947 else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6)) {
8948 is_tunnel = 1;
8949 is_tunnel_ipv6 = 1;
8950 }
8951 else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6)) {
8952 is_tunnel = 1;
8953 is_tunnel_ipv6 = 1;
8954 }
8955 else if (unformat (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg)) {
8956 if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
8957 crypto_alg > IPSEC_INTEG_ALG_SHA_512_256) {
8958 clib_warning ("unsupported crypto-alg: '%U'",
8959 format_ipsec_crypto_alg, crypto_alg);
8960 return -99;
8961 }
8962 }
8963 else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
8964 ;
8965 else if (unformat (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg)) {
8966 if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
8967 integ_alg > IPSEC_INTEG_ALG_SHA_512_256) {
8968 clib_warning ("unsupported integ-alg: '%U'",
8969 format_ipsec_integ_alg, integ_alg);
8970 return -99;
8971 }
8972 }
8973 else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
8974 ;
8975 else {
8976 clib_warning ("parse error '%U'", format_unformat_error, i);
8977 return -99;
8978 }
8979
8980 }
8981
8982 M(IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
8983
8984 mp->sad_id = ntohl(sad_id);
8985 mp->is_add = is_add;
8986 mp->protocol = protocol;
8987 mp->spi = ntohl(spi);
8988 mp->is_tunnel = is_tunnel;
8989 mp->is_tunnel_ipv6 = is_tunnel_ipv6;
8990 mp->crypto_algorithm = crypto_alg;
8991 mp->integrity_algorithm = integ_alg;
8992 mp->crypto_key_length = vec_len(ck);
8993 mp->integrity_key_length = vec_len(ik);
8994
8995 if (mp->crypto_key_length > sizeof(mp->crypto_key))
8996 mp->crypto_key_length = sizeof(mp->crypto_key);
8997
8998 if (mp->integrity_key_length > sizeof(mp->integrity_key))
8999 mp->integrity_key_length = sizeof(mp->integrity_key);
9000
Damjan Marionf1213b82016-03-13 02:22:06 +01009001 clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
9002 clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
Ed Warnickecb9cada2015-12-08 15:45:58 -07009003
9004 if (is_tunnel) {
9005 if (is_tunnel_ipv6) {
Damjan Marionf1213b82016-03-13 02:22:06 +01009006 clib_memcpy (mp->tunnel_src_address, &tun_src6, sizeof(ip6_address_t));
9007 clib_memcpy (mp->tunnel_dst_address, &tun_dst6, sizeof(ip6_address_t));
Ed Warnickecb9cada2015-12-08 15:45:58 -07009008 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01009009 clib_memcpy (mp->tunnel_src_address, &tun_src4, sizeof(ip4_address_t));
9010 clib_memcpy (mp->tunnel_dst_address, &tun_dst4, sizeof(ip4_address_t));
Ed Warnickecb9cada2015-12-08 15:45:58 -07009011 }
9012 }
9013
9014 S; W;
9015 /* NOTREACHED */
9016 return 0;
Dave Barachbfdedbd2016-01-20 09:11:55 -05009017#else
9018 clib_warning ("unsupported (no dpdk)");
9019 return -99;
9020#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -07009021}
9022
9023static int
9024api_ipsec_sa_set_key (vat_main_t * vam)
9025{
Dave Barachbfdedbd2016-01-20 09:11:55 -05009026#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -07009027 unformat_input_t * i = vam->input;
9028 vl_api_ipsec_sa_set_key_t *mp;
9029 f64 timeout;
9030 u32 sa_id;
9031 u8 * ck, * ik;
9032
9033 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9034 if (unformat (i, "sa_id %d", &sa_id))
9035 ;
9036 else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
9037 ;
9038 else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
9039 ;
9040 else {
9041 clib_warning ("parse error '%U'", format_unformat_error, i);
9042 return -99;
9043 }
9044 }
9045
9046 M(IPSEC_SA_SET_KEY, ipsec_set_sa_key);
9047
9048 mp->sa_id = ntohl(sa_id);
9049 mp->crypto_key_length = vec_len(ck);
9050 mp->integrity_key_length = vec_len(ik);
9051
9052 if (mp->crypto_key_length > sizeof(mp->crypto_key))
9053 mp->crypto_key_length = sizeof(mp->crypto_key);
9054
9055 if (mp->integrity_key_length > sizeof(mp->integrity_key))
9056 mp->integrity_key_length = sizeof(mp->integrity_key);
9057
Damjan Marionf1213b82016-03-13 02:22:06 +01009058 clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
9059 clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
Ed Warnickecb9cada2015-12-08 15:45:58 -07009060
9061 S; W;
9062 /* NOTREACHED */
9063 return 0;
Dave Barachbfdedbd2016-01-20 09:11:55 -05009064#else
9065 clib_warning ("unsupported (no dpdk)");
9066 return -99;
9067#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -07009068}
9069
Matus Fabiane5f42fe2016-04-08 11:18:08 +02009070static int
9071api_ikev2_profile_add_del (vat_main_t * vam)
9072{
9073#if DPDK > 0
9074 unformat_input_t * i = vam->input;
9075 vl_api_ikev2_profile_add_del_t * mp;
9076 f64 timeout;
9077 u8 is_add = 1;
9078 u8 * name = 0;
9079
9080 const char * valid_chars = "a-zA-Z0-9_";
9081
9082 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9083 if (unformat (i, "del"))
9084 is_add = 0;
9085 else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
9086 vec_add1 (name, 0);
9087 else {
9088 errmsg ("parse error '%U'", format_unformat_error, i);
9089 return -99;
9090 }
9091 }
9092
9093 if (!vec_len (name)) {
9094 errmsg ("profile name must be specified");
9095 return -99;
9096 }
9097
9098 if (vec_len (name) > 64) {
9099 errmsg ("profile name too long");
9100 return -99;
9101 }
9102
9103 M(IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
9104
Damjan Marionf1213b82016-03-13 02:22:06 +01009105 clib_memcpy(mp->name, name, vec_len (name));
Matus Fabiane5f42fe2016-04-08 11:18:08 +02009106 mp->is_add = is_add;
9107 vec_free (name);
9108
9109 S; W;
9110 /* NOTREACHED */
9111 return 0;
9112#else
9113 clib_warning ("unsupported (no dpdk)");
9114 return -99;
9115#endif
9116}
9117
9118static int
9119api_ikev2_profile_set_auth (vat_main_t * vam)
9120{
9121#if DPDK > 0
9122 unformat_input_t * i = vam->input;
9123 vl_api_ikev2_profile_set_auth_t * mp;
9124 f64 timeout;
9125 u8 * name = 0;
9126 u8 * data = 0;
9127 u32 auth_method = 0;
9128 u8 is_hex = 0;
9129
9130 const char * valid_chars = "a-zA-Z0-9_";
9131
9132 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9133 if (unformat (i, "name %U", unformat_token, valid_chars, &name))
9134 vec_add1 (name, 0);
9135 else if (unformat (i, "auth_method %U",
9136 unformat_ikev2_auth_method, &auth_method))
9137 ;
9138 else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
9139 is_hex = 1;
9140 else if (unformat (i, "auth_data %v", &data))
9141 ;
9142 else {
9143 errmsg ("parse error '%U'", format_unformat_error, i);
9144 return -99;
9145 }
9146 }
9147
9148 if (!vec_len (name)) {
9149 errmsg ("profile name must be specified");
9150 return -99;
9151 }
9152
9153 if (vec_len (name) > 64) {
9154 errmsg ("profile name too long");
9155 return -99;
9156 }
9157
9158 if (!vec_len(data)) {
9159 errmsg ("auth_data must be specified");
9160 return -99;
9161 }
9162
9163 if (!auth_method) {
9164 errmsg ("auth_method must be specified");
9165 return -99;
9166 }
9167
9168 M(IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
9169
9170 mp->is_hex = is_hex;
9171 mp->auth_method = (u8) auth_method;
9172 mp->data_len = vec_len (data);
Damjan Marionf1213b82016-03-13 02:22:06 +01009173 clib_memcpy (mp->name, name, vec_len (name));
9174 clib_memcpy (mp->data, data, vec_len (data));
Matus Fabiane5f42fe2016-04-08 11:18:08 +02009175 vec_free (name);
9176 vec_free (data);
9177
9178 S; W;
9179 /* NOTREACHED */
9180 return 0;
9181#else
9182 clib_warning ("unsupported (no dpdk)");
9183 return -99;
9184#endif
9185}
9186
9187static int
9188api_ikev2_profile_set_id (vat_main_t * vam)
9189{
9190#if DPDK > 0
9191 unformat_input_t * i = vam->input;
9192 vl_api_ikev2_profile_set_id_t * mp;
9193 f64 timeout;
9194 u8 * name = 0;
9195 u8 * data = 0;
9196 u8 is_local = 0;
9197 u32 id_type = 0;
9198 ip4_address_t ip4;
9199
9200 const char * valid_chars = "a-zA-Z0-9_";
9201
9202 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9203 if (unformat (i, "name %U", unformat_token, valid_chars, &name))
9204 vec_add1 (name, 0);
9205 else if (unformat (i, "id_type %U",
9206 unformat_ikev2_id_type, &id_type))
9207 ;
9208 else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
9209 {
9210 data = vec_new(u8, 4);
Damjan Marionf1213b82016-03-13 02:22:06 +01009211 clib_memcpy(data, ip4.as_u8, 4);
Matus Fabiane5f42fe2016-04-08 11:18:08 +02009212 }
9213 else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
9214 ;
9215 else if (unformat (i, "id_data %v", &data))
9216 ;
9217 else if (unformat (i, "local"))
9218 is_local = 1;
9219 else if (unformat (i, "remote"))
9220 is_local = 0;
9221 else {
9222 errmsg ("parse error '%U'", format_unformat_error, i);
9223 return -99;
9224 }
9225 }
9226
9227 if (!vec_len (name)) {
9228 errmsg ("profile name must be specified");
9229 return -99;
9230 }
9231
9232 if (vec_len (name) > 64) {
9233 errmsg ("profile name too long");
9234 return -99;
9235 }
9236
9237 if (!vec_len(data)) {
9238 errmsg ("id_data must be specified");
9239 return -99;
9240 }
9241
9242 if (!id_type) {
9243 errmsg ("id_type must be specified");
9244 return -99;
9245 }
9246
9247 M(IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
9248
9249 mp->is_local = is_local;
9250 mp->id_type = (u8) id_type;
9251 mp->data_len = vec_len (data);
Damjan Marionf1213b82016-03-13 02:22:06 +01009252 clib_memcpy (mp->name, name, vec_len (name));
9253 clib_memcpy (mp->data, data, vec_len (data));
Matus Fabiane5f42fe2016-04-08 11:18:08 +02009254 vec_free (name);
9255 vec_free (data);
9256
9257 S; W;
9258 /* NOTREACHED */
9259 return 0;
9260#else
9261 clib_warning ("unsupported (no dpdk)");
9262 return -99;
9263#endif
9264}
9265
9266static int
9267api_ikev2_profile_set_ts (vat_main_t * vam)
9268{
9269#if DPDK > 0
9270 unformat_input_t * i = vam->input;
9271 vl_api_ikev2_profile_set_ts_t * mp;
9272 f64 timeout;
9273 u8 * name = 0;
9274 u8 is_local = 0;
9275 u32 proto = 0, start_port = 0, end_port = (u32) ~0;
9276 ip4_address_t start_addr, end_addr;
9277
9278 const char * valid_chars = "a-zA-Z0-9_";
9279
9280 start_addr.as_u32 = 0;
9281 end_addr.as_u32 = (u32) ~0;
9282
9283 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9284 if (unformat (i, "name %U", unformat_token, valid_chars, &name))
9285 vec_add1 (name, 0);
9286 else if (unformat (i, "protocol %d", &proto))
9287 ;
9288 else if (unformat (i, "start_port %d", &start_port))
9289 ;
9290 else if (unformat (i, "end_port %d", &end_port))
9291 ;
9292 else if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
9293 ;
9294 else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
9295 ;
9296 else if (unformat (i, "local"))
9297 is_local = 1;
9298 else if (unformat (i, "remote"))
9299 is_local = 0;
9300 else {
9301 errmsg ("parse error '%U'", format_unformat_error, i);
9302 return -99;
9303 }
9304 }
9305
9306 if (!vec_len (name)) {
9307 errmsg ("profile name must be specified");
9308 return -99;
9309 }
9310
9311 if (vec_len (name) > 64) {
9312 errmsg ("profile name too long");
9313 return -99;
9314 }
9315
9316 M(IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
9317
9318 mp->is_local = is_local;
9319 mp->proto = (u8) proto;
9320 mp->start_port = (u16) start_port;
9321 mp->end_port = (u16) end_port;
9322 mp->start_addr = start_addr.as_u32;
9323 mp->end_addr = end_addr.as_u32;
Damjan Marionf1213b82016-03-13 02:22:06 +01009324 clib_memcpy (mp->name, name, vec_len (name));
Matus Fabiane5f42fe2016-04-08 11:18:08 +02009325 vec_free (name);
9326
9327 S; W;
9328 /* NOTREACHED */
9329 return 0;
9330#else
9331 clib_warning ("unsupported (no dpdk)");
9332 return -99;
9333#endif
9334}
9335
9336static int
9337api_ikev2_set_local_key (vat_main_t * vam)
9338{
9339#if DPDK > 0
9340 unformat_input_t * i = vam->input;
9341 vl_api_ikev2_set_local_key_t * mp;
9342 f64 timeout;
9343 u8 * file = 0;
9344
9345 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9346 if (unformat (i, "file %v", &file))
9347 vec_add1 (file, 0);
9348 else {
9349 errmsg ("parse error '%U'", format_unformat_error, i);
9350 return -99;
9351 }
9352 }
9353
9354 if (!vec_len (file)) {
9355 errmsg ("RSA key file must be specified");
9356 return -99;
9357 }
9358
9359 if (vec_len (file) > 256) {
9360 errmsg ("file name too long");
9361 return -99;
9362 }
9363
9364 M(IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
9365
Damjan Marionf1213b82016-03-13 02:22:06 +01009366 clib_memcpy (mp->key_file, file, vec_len (file));
Matus Fabiane5f42fe2016-04-08 11:18:08 +02009367 vec_free (file);
9368
9369 S; W;
9370 /* NOTREACHED */
9371 return 0;
9372#else
9373 clib_warning ("unsupported (no dpdk)");
9374 return -99;
9375#endif
9376}
9377
Ed Warnickecb9cada2015-12-08 15:45:58 -07009378/*
9379 * MAP
9380 */
9381static int api_map_add_domain (vat_main_t * vam)
9382{
9383 unformat_input_t *i = vam->input;
9384 vl_api_map_add_domain_t *mp;
9385 f64 timeout;
9386
9387 ip4_address_t ip4_prefix;
9388 ip6_address_t ip6_prefix;
9389 ip6_address_t ip6_src;
9390 u32 num_m_args = 0;
9391 u32 ip6_prefix_len, ip4_prefix_len, ea_bits_len, psid_offset,
9392 psid_length;
9393 u8 is_translation = 0;
9394 u32 mtu = 0;
9395 u8 ip6_src_len = 128;
9396
9397 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9398 if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
9399 &ip4_prefix, &ip4_prefix_len))
9400 num_m_args++;
9401 else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
9402 &ip6_prefix, &ip6_prefix_len))
9403 num_m_args++;
9404 else if (unformat (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src, &ip6_src_len))
9405 num_m_args++;
9406 else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
9407 num_m_args++;
9408 else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
9409 num_m_args++;
9410 else if (unformat (i, "psid-offset %d", &psid_offset))
9411 num_m_args++;
9412 else if (unformat (i, "psid-len %d", &psid_length))
9413 num_m_args++;
9414 else if (unformat (i, "mtu %d", &mtu))
9415 num_m_args++;
9416 else if (unformat (i, "map-t"))
9417 is_translation = 1;
9418 else {
9419 clib_warning ("parse error '%U'", format_unformat_error, i);
9420 return -99;
9421 }
9422 }
9423
9424 if (num_m_args != 6) {
9425 errmsg("mandatory argument(s) missing\n");
9426 return -99;
9427 }
9428
9429 /* Construct the API message */
9430 M(MAP_ADD_DOMAIN, map_add_domain);
9431
Damjan Marionf1213b82016-03-13 02:22:06 +01009432 clib_memcpy(mp->ip4_prefix, &ip4_prefix, sizeof(ip4_prefix));
Ed Warnickecb9cada2015-12-08 15:45:58 -07009433 mp->ip4_prefix_len = ip4_prefix_len;
9434
Damjan Marionf1213b82016-03-13 02:22:06 +01009435 clib_memcpy(mp->ip6_prefix, &ip6_prefix, sizeof(ip6_prefix));
Ed Warnickecb9cada2015-12-08 15:45:58 -07009436 mp->ip6_prefix_len = ip6_prefix_len;
9437
Damjan Marionf1213b82016-03-13 02:22:06 +01009438 clib_memcpy(mp->ip6_src, &ip6_src, sizeof(ip6_src));
Ed Warnickecb9cada2015-12-08 15:45:58 -07009439 mp->ip6_src_prefix_len = ip6_src_len;
9440
9441 mp->ea_bits_len = ea_bits_len;
9442 mp->psid_offset = psid_offset;
9443 mp->psid_length = psid_length;
9444 mp->is_translation = is_translation;
9445 mp->mtu = htons(mtu);
9446
9447 /* send it... */
9448 S;
9449
9450 /* Wait for a reply, return good/bad news */
9451 W;
9452}
9453
9454static int api_map_del_domain (vat_main_t * vam)
9455{
9456 unformat_input_t *i = vam->input;
9457 vl_api_map_del_domain_t *mp;
9458 f64 timeout;
9459
9460 u32 num_m_args = 0;
9461 u32 index;
9462
9463 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9464 if (unformat (i, "index %d", &index))
9465 num_m_args++;
9466 else {
9467 clib_warning ("parse error '%U'", format_unformat_error, i);
9468 return -99;
9469 }
9470 }
9471
9472 if (num_m_args != 1) {
9473 errmsg("mandatory argument(s) missing\n");
9474 return -99;
9475 }
9476
9477 /* Construct the API message */
9478 M(MAP_DEL_DOMAIN, map_del_domain);
9479
9480 mp->index = ntohl(index);
9481
9482 /* send it... */
9483 S;
9484
9485 /* Wait for a reply, return good/bad news */
9486 W;
9487}
9488
9489static int api_map_add_del_rule (vat_main_t * vam)
9490{
9491 unformat_input_t *i = vam->input;
9492 vl_api_map_add_del_rule_t *mp;
9493 f64 timeout;
9494 u8 is_add = 1;
9495 ip6_address_t ip6_dst;
9496 u32 num_m_args = 0, index, psid;
9497
9498 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9499 if (unformat (i, "index %d", &index))
9500 num_m_args++;
9501 else if (unformat (i, "psid %d", &psid))
9502 num_m_args++;
9503 else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
9504 num_m_args++;
9505 else if (unformat (i, "del")) {
9506 is_add = 0;
9507 } else {
9508 clib_warning ("parse error '%U'", format_unformat_error, i);
9509 return -99;
9510 }
9511 }
9512
9513 /* Construct the API message */
9514 M(MAP_ADD_DEL_RULE, map_add_del_rule);
9515
9516 mp->index = ntohl(index);
9517 mp->is_add = is_add;
Damjan Marionf1213b82016-03-13 02:22:06 +01009518 clib_memcpy(mp->ip6_dst, &ip6_dst, sizeof(ip6_dst));
Ed Warnickecb9cada2015-12-08 15:45:58 -07009519 mp->psid = ntohs(psid);
9520
9521 /* send it... */
9522 S;
9523
9524 /* Wait for a reply, return good/bad news */
9525 W;
9526}
9527
9528static int api_map_domain_dump (vat_main_t * vam)
9529{
9530 vl_api_map_domain_dump_t *mp;
9531 f64 timeout;
9532
9533 /* Construct the API message */
9534 M(MAP_DOMAIN_DUMP, map_domain_dump);
9535
9536 /* send it... */
9537 S;
9538
9539 /* Use a control ping for synchronization */
9540 {
9541 vl_api_control_ping_t * mp;
9542 M(CONTROL_PING, control_ping);
9543 S;
9544 }
9545 W;
9546}
9547
9548static int api_map_rule_dump (vat_main_t * vam)
9549{
9550 unformat_input_t *i = vam->input;
9551 vl_api_map_rule_dump_t *mp;
9552 f64 timeout;
9553 u32 domain_index = ~0;
9554
9555 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9556 if (unformat (i, "index %u", &domain_index))
9557 ;
9558 else
9559 break;
9560 }
9561
9562 if (domain_index == ~0) {
9563 clib_warning("parse error: domain index expected");
9564 return -99;
9565 }
9566
9567 /* Construct the API message */
9568 M(MAP_RULE_DUMP, map_rule_dump);
9569
9570 mp->domain_index = htonl(domain_index);
9571
9572 /* send it... */
9573 S;
9574
9575 /* Use a control ping for synchronization */
9576 {
9577 vl_api_control_ping_t * mp;
9578 M(CONTROL_PING, control_ping);
9579 S;
9580 }
9581 W;
9582}
9583
9584static void vl_api_map_add_domain_reply_t_handler
9585(vl_api_map_add_domain_reply_t * mp)
9586{
9587 vat_main_t * vam = &vat_main;
9588 i32 retval = ntohl(mp->retval);
9589
9590 if (vam->async_mode) {
9591 vam->async_errors += (retval < 0);
9592 } else {
9593 vam->retval = retval;
9594 vam->result_ready = 1;
9595 }
9596}
9597
9598static void vl_api_map_add_domain_reply_t_handler_json
9599(vl_api_map_add_domain_reply_t * mp)
9600{
9601 vat_main_t * vam = &vat_main;
9602 vat_json_node_t node;
9603
9604 vat_json_init_object(&node);
9605 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
9606 vat_json_object_add_uint(&node, "index", ntohl(mp->index));
9607
9608 vat_json_print(vam->ofp, &node);
9609 vat_json_free(&node);
9610
9611 vam->retval = ntohl(mp->retval);
9612 vam->result_ready = 1;
9613}
9614
9615static int
9616api_get_first_msg_id (vat_main_t * vam)
9617{
9618 vl_api_get_first_msg_id_t * mp;
9619 f64 timeout;
9620 unformat_input_t * i = vam->input;
9621 u8 * name;
9622 u8 name_set = 0;
9623
9624 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9625 if (unformat (i, "client %s", &name))
9626 name_set = 1;
9627 else
9628 break;
9629 }
9630
9631 if (name_set == 0) {
9632 errmsg ("missing client name\n");
9633 return -99;
9634 }
9635 vec_add1 (name, 0);
9636
9637 if (vec_len (name) > 63) {
9638 errmsg ("client name too long\n");
9639 return -99;
9640 }
9641
9642 M(GET_FIRST_MSG_ID, get_first_msg_id);
Damjan Marionf1213b82016-03-13 02:22:06 +01009643 clib_memcpy (mp->name, name, vec_len(name));
Ed Warnickecb9cada2015-12-08 15:45:58 -07009644 S; W;
9645 /* NOTREACHED */
9646 return 0;
9647}
9648
Dave Barachc07bf5d2016-02-17 17:52:26 -05009649static int api_cop_interface_enable_disable (vat_main_t * vam)
9650{
9651 unformat_input_t * line_input = vam->input;
9652 vl_api_cop_interface_enable_disable_t * mp;
9653 f64 timeout;
9654 u32 sw_if_index = ~0;
9655 u8 enable_disable = 1;
9656
9657 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
9658 if (unformat (line_input, "disable"))
9659 enable_disable = 0;
9660 if (unformat (line_input, "enable"))
9661 enable_disable = 1;
9662 else if (unformat (line_input, "%U", unformat_sw_if_index,
9663 vam, &sw_if_index))
9664 ;
9665 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
9666 ;
9667 else
9668 break;
9669 }
9670
9671 if (sw_if_index == ~0) {
9672 errmsg ("missing interface name or sw_if_index\n");
9673 return -99;
9674 }
9675
9676 /* Construct the API message */
9677 M(COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
9678 mp->sw_if_index = ntohl(sw_if_index);
9679 mp->enable_disable = enable_disable;
9680
9681 /* send it... */
9682 S;
9683 /* Wait for the reply */
9684 W;
9685}
9686
9687static int api_cop_whitelist_enable_disable (vat_main_t * vam)
9688{
9689 unformat_input_t * line_input = vam->input;
9690 vl_api_cop_whitelist_enable_disable_t * mp;
9691 f64 timeout;
9692 u32 sw_if_index = ~0;
9693 u8 ip4=0, ip6=0, default_cop=0;
9694 u32 fib_id;
9695
9696 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
9697 if (unformat (line_input, "ip4"))
9698 ip4 = 1;
9699 else if (unformat (line_input, "ip6"))
9700 ip6 = 1;
9701 else if (unformat (line_input, "default"))
9702 default_cop = 1;
9703 else if (unformat (line_input, "%U", unformat_sw_if_index,
9704 vam, &sw_if_index))
9705 ;
9706 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
9707 ;
9708 else if (unformat (line_input, "fib-id %d", &fib_id))
9709 ;
9710 else
9711 break;
9712 }
9713
9714 if (sw_if_index == ~0) {
9715 errmsg ("missing interface name or sw_if_index\n");
9716 return -99;
9717 }
9718
9719 /* Construct the API message */
9720 M(COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
9721 mp->sw_if_index = ntohl(sw_if_index);
9722 mp->fib_id = ntohl(fib_id);
9723 mp->ip4 = ip4;
9724 mp->ip6 = ip6;
9725 mp->default_cop = default_cop;
9726
9727 /* send it... */
9728 S;
9729 /* Wait for the reply */
9730 W;
9731}
9732
Dave Barachb44e9bc2016-02-19 09:06:23 -05009733static int api_get_node_graph (vat_main_t * vam)
9734{
9735 vl_api_get_node_graph_t * mp;
9736 f64 timeout;
9737
9738 M(GET_NODE_GRAPH, get_node_graph);
9739
9740 /* send it... */
9741 S;
9742 /* Wait for the reply */
9743 W;
9744}
9745
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02009746static int
9747api_lisp_add_del_locator_set(vat_main_t * vam)
9748{
9749 unformat_input_t * input = vam->input;
9750 vl_api_lisp_add_del_locator_set_t *mp;
9751 f64 timeout = ~0;
9752 u8 is_add = 1;
9753 u8 *locator_set_name = NULL;
9754 u8 locator_set_name_set = 0;
9755
9756 /* Parse args required to build the message */
9757 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
9758 if (unformat(input, "del")) {
9759 is_add = 0;
9760 } else if (unformat(input, "locator-set %s", &locator_set_name)) {
9761 locator_set_name_set = 1;
9762 } else
9763 break;
9764 }
9765
9766 if (locator_set_name_set == 0) {
9767 errmsg ("missing locator-set name");
9768 return -99;
9769 }
9770
9771 if (vec_len(locator_set_name) > 64) {
9772 errmsg ("locator-set name too long\n");
9773 vec_free(locator_set_name);
9774 return -99;
9775 }
9776 vec_add1(locator_set_name, 0);
9777
9778 /* Construct the API message */
9779 M(LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set);
9780
9781 mp->is_add = is_add;
Damjan Marionf1213b82016-03-13 02:22:06 +01009782 clib_memcpy(mp->locator_set_name, locator_set_name,
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02009783 vec_len(locator_set_name));
9784 vec_free(locator_set_name);
9785
9786 /* send it... */
9787 S;
9788
9789 /* Wait for a reply... */
9790 W;
9791
9792 /* NOTREACHED */
9793 return 0;
9794}
9795
9796static int
9797api_lisp_add_del_locator(vat_main_t * vam)
9798{
9799 unformat_input_t * input = vam->input;
9800 vl_api_lisp_add_del_locator_t *mp;
9801 f64 timeout = ~0;
9802 u32 tmp_if_index = ~0;
9803 u32 sw_if_index = ~0;
9804 u8 sw_if_index_set = 0;
9805 u8 sw_if_index_if_name_set = 0;
9806 u8 priority = ~0;
9807 u8 priority_set = 0;
9808 u8 weight = ~0;
9809 u8 weight_set = 0;
9810 u8 is_add = 1;
9811 u8 *locator_set_name = NULL;
9812 u8 locator_set_name_set = 0;
9813
9814 /* Parse args required to build the message */
9815 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
9816 if (unformat(input, "del")) {
9817 is_add = 0;
9818 } else if (unformat(input, "locator-set %s", &locator_set_name)) {
9819 locator_set_name_set = 1;
9820 } else if (unformat(input, "iface %U", unformat_sw_if_index, vam,
9821 &tmp_if_index)) {
9822 sw_if_index_if_name_set = 1;
9823 sw_if_index = tmp_if_index;
9824 } else if (unformat(input,"sw_if_index %d", &tmp_if_index)) {
9825 sw_if_index_set = 1;
9826 sw_if_index = tmp_if_index;
9827 } else if (unformat(input, "p %d", &priority)) {
9828 priority_set = 1;
9829 } else if (unformat(input, "w %d", &weight)) {
9830 weight_set = 1;
9831 } else
9832 break;
9833 }
9834
9835 if (locator_set_name_set == 0) {
9836 errmsg ("missing locator-set name");
9837 return -99;
9838 }
9839
9840 if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0) {
9841 errmsg ("missing sw_if_index");
9842 vec_free(locator_set_name);
9843 return -99;
9844 }
9845
9846 if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0) {
9847 errmsg ("cannot use both params interface name and sw_if_index");
9848 vec_free(locator_set_name);
9849 return -99;
9850 }
9851
9852 if (priority_set == 0) {
9853 errmsg ("missing locator-set priority\n");
9854 vec_free(locator_set_name);
9855 return -99;
9856 }
9857
9858 if (weight_set == 0) {
9859 errmsg ("missing locator-set weight\n");
9860 vec_free(locator_set_name);
9861 return -99;
9862 }
9863
9864 if (vec_len(locator_set_name) > 64) {
9865 errmsg ("locator-set name too long\n");
9866 vec_free(locator_set_name);
9867 return -99;
9868 }
9869 vec_add1(locator_set_name, 0);
9870
9871 /* Construct the API message */
9872 M(LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
9873
9874 mp->is_add = is_add;
9875 mp->sw_if_index = ntohl(sw_if_index);
9876 mp->priority = priority;
9877 mp->weight = weight;
Damjan Marionf1213b82016-03-13 02:22:06 +01009878 clib_memcpy(mp->locator_set_name, locator_set_name,
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02009879 vec_len(locator_set_name));
9880 vec_free(locator_set_name);
9881
9882 /* send it... */
9883 S;
9884
9885 /* Wait for a reply... */
9886 W;
9887
9888 /* NOTREACHED */
9889 return 0;
9890}
9891
9892static int
9893api_lisp_add_del_local_eid(vat_main_t * vam)
9894{
9895 unformat_input_t * input = vam->input;
9896 vl_api_lisp_add_del_local_eid_t *mp;
9897 f64 timeout = ~0;
9898 u8 is_add = 1;
9899 u8 eidv4_set = 0;
9900 u8 eidv6_set = 0;
9901 ip4_address_t eidv4;
9902 ip6_address_t eidv6;
9903 u8 tmp_eid_lenght = ~0;
9904 u8 eid_lenght = ~0;
9905 u8 *locator_set_name = NULL;
9906 u8 locator_set_name_set = 0;
9907
9908 /* Parse args required to build the message */
9909 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
9910 if (unformat(input, "del")) {
9911 is_add = 0;
9912 } else if (unformat(input, "eid %U/%d", unformat_ip4_address,
9913 &eidv4, &tmp_eid_lenght)) {
9914 eid_lenght = tmp_eid_lenght;
9915 eidv4_set = 1;
9916 } else if (unformat(input, "eid %U/%d", unformat_ip6_address,
9917 &eidv6, &tmp_eid_lenght)) {
9918 eid_lenght = tmp_eid_lenght;
9919 eidv6_set = 1;
9920 } else if (unformat(input, "locator-set %s", &locator_set_name)) {
9921 locator_set_name_set = 1;
9922 } else
9923 break;
9924 }
9925
9926 if (locator_set_name_set == 0) {
9927 errmsg ("missing locator-set name\n");
9928 return -99;
9929 }
9930
9931 if (vec_len(locator_set_name) > 64) {
9932 errmsg ("locator-set name too long\n");
9933 vec_free(locator_set_name);
9934 return -99;
9935 }
9936 vec_add1(locator_set_name, 0);
9937
9938 if (eidv4_set && eidv6_set) {
9939 errmsg ("both eid v4 and v6 addresses set\n");
9940 vec_free(locator_set_name);
9941 return -99;
9942 }
9943
9944 if (!eidv4_set && !eidv6_set) {
9945 errmsg ("eid addresses not set\n");
9946 vec_free(locator_set_name);
9947 return -99;
9948 }
9949
9950 /* Construct the API message */
9951 M(LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
9952
9953 mp->is_add = is_add;
9954 if (eidv6_set) {
9955 mp->is_ipv6 = 1;
Damjan Marionf1213b82016-03-13 02:22:06 +01009956 clib_memcpy(mp->ip_address, &eidv6, sizeof(eidv6));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02009957 } else {
9958 mp->is_ipv6 = 0;
Damjan Marionf1213b82016-03-13 02:22:06 +01009959 clib_memcpy(mp->ip_address, &eidv4, sizeof(eidv4));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02009960 }
9961 mp->prefix_len = eid_lenght;
Damjan Marionf1213b82016-03-13 02:22:06 +01009962 clib_memcpy(mp->locator_set_name, locator_set_name,
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02009963 vec_len(locator_set_name));
9964 vec_free(locator_set_name);
9965
9966 /* send it... */
9967 S;
9968
9969 /* Wait for a reply... */
9970 W;
9971
9972 /* NOTREACHED */
9973 return 0;
9974}
9975
9976static int
9977api_lisp_gpe_add_del_fwd_entry(vat_main_t * vam)
9978{
9979 unformat_input_t * input = vam->input;
9980 vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
9981 f64 timeout = ~0;
9982 u8 is_add = 1;
9983 u8 eidv4_set = 0, slocv4_set = 0, dlocv4_set = 0;
9984 u8 eidv6_set = 0, slocv6_set = 0, dlocv6_set = 0;
9985 ip4_address_t eidv4, slocv4, dlocv4;
9986 ip6_address_t eidv6, slocv6, dlocv6;
9987 u8 tmp_eid_lenght = ~0;
9988 u8 eid_lenght = ~0;
9989
9990 /* Parse args required to build the message */
9991 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
9992 if (unformat(input, "del")) {
9993 is_add = 0;
9994 } else if (unformat(input, "eid %U/%d", unformat_ip4_address,
9995 &eidv4, &tmp_eid_lenght)) {
9996 eid_lenght = tmp_eid_lenght;
9997 eidv4_set = 1;
9998 } else if (unformat(input, "eid %U/%d", unformat_ip6_address,
9999 &eidv6, &tmp_eid_lenght)) {
10000 eid_lenght = tmp_eid_lenght;
10001 eidv6_set = 1;
10002 } else if (unformat(input, "sloc %U", unformat_ip4_address, &slocv4)) {
10003 slocv4_set = 1;
10004 } else if (unformat(input, "sloc %U", unformat_ip6_address, &slocv6)) {
10005 slocv6_set = 1;
10006 } else if (unformat(input, "dloc %U", unformat_ip4_address, &dlocv4)) {
10007 dlocv4_set = 1;
10008 } else if (unformat(input, "dloc %U", unformat_ip6_address, &dlocv6)) {
10009 dlocv6_set = 1;
10010 } else
10011 break;
10012 }
10013
10014 if (eidv4_set && eidv6_set) {
10015 errmsg ("both eid v4 and v6 addresses set\n");
10016 return -99;
10017 }
10018
10019 if (!eidv4_set && !eidv6_set) {
10020 errmsg ("eid addresses not set\n");
10021 return -99;
10022 }
10023
10024 if (slocv4_set && slocv6_set) {
10025 errmsg ("both source v4 and v6 addresses set\n");
10026 return -99;
10027 }
10028
10029 if (!slocv4_set && !slocv6_set) {
10030 errmsg ("source addresses not set\n");
10031 return -99;
10032 }
10033
10034 if (dlocv4_set && dlocv6_set) {
10035 errmsg ("both destination v4 and v6 addresses set\n");
10036 return -99;
10037 }
10038
10039 if (dlocv4_set && dlocv6_set) {
10040 errmsg ("destination addresses not set\n");
10041 return -99;
10042 }
10043
10044 if (!(slocv4_set == dlocv4_set && slocv6_set == dlocv6_set)) {
10045 errmsg ("mixing type of source and destination address\n");
10046 return -99;
10047 }
10048
10049 /* Construct the API message */
10050 M(LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
10051
10052 mp->is_add = is_add;
10053 if (eidv6_set) {
10054 mp->eid_is_ipv6 = 1;
Damjan Marionf1213b82016-03-13 02:22:06 +010010055 clib_memcpy(mp->eid_ip_address, &eidv6, sizeof(eidv6));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010056 } else {
10057 mp->eid_is_ipv6 = 0;
Damjan Marionf1213b82016-03-13 02:22:06 +010010058 clib_memcpy(mp->eid_ip_address, &eidv4, sizeof(eidv4));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010059 }
10060 mp->eid_prefix_len = eid_lenght;
10061 if (slocv6_set) {
10062 mp->address_is_ipv6 = 1;
Damjan Marionf1213b82016-03-13 02:22:06 +010010063 clib_memcpy(mp->source_ip_address, &slocv6, sizeof(slocv6));
10064 clib_memcpy(mp->destination_ip_address, &dlocv6, sizeof(dlocv6));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010065 } else {
10066 mp->address_is_ipv6 = 0;
Damjan Marionf1213b82016-03-13 02:22:06 +010010067 clib_memcpy(mp->source_ip_address, &slocv4, sizeof(slocv4));
10068 clib_memcpy(mp->destination_ip_address, &dlocv4, sizeof(dlocv4));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010069 }
10070
10071 /* send it... */
10072 S;
10073
10074 /* Wait for a reply... */
10075 W;
10076
10077 /* NOTREACHED */
10078 return 0;
10079}
10080
10081static int
10082api_lisp_add_del_map_resolver(vat_main_t * vam)
10083{
10084 unformat_input_t * input = vam->input;
10085 vl_api_lisp_add_del_map_resolver_t *mp;
10086 f64 timeout = ~0;
10087 u8 is_add = 1;
10088 u8 ipv4_set = 0;
10089 u8 ipv6_set = 0;
10090 ip4_address_t ipv4;
10091 ip6_address_t ipv6;
10092
10093 /* Parse args required to build the message */
10094 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
10095 if (unformat(input, "del")) {
10096 is_add = 0;
10097 } else if (unformat(input, "%U", unformat_ip4_address, &ipv4)) {
10098 ipv4_set = 1;
10099 } else if (unformat(input, "%U", unformat_ip6_address, &ipv6)) {
10100 ipv6_set = 1;
10101 } else
10102 break;
10103 }
10104
10105 if (ipv4_set && ipv6_set) {
10106 errmsg ("both eid v4 and v6 addresses set\n");
10107 return -99;
10108 }
10109
10110 if (!ipv4_set && !ipv6_set) {
10111 errmsg ("eid addresses not set\n");
10112 return -99;
10113 }
10114
10115 /* Construct the API message */
10116 M(LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
10117
10118 mp->is_add = is_add;
10119 if (ipv6_set) {
10120 mp->is_ipv6 = 1;
Damjan Marionf1213b82016-03-13 02:22:06 +010010121 clib_memcpy(mp->ip_address, &ipv6, sizeof(ipv6));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010122 } else {
10123 mp->is_ipv6 = 0;
Damjan Marionf1213b82016-03-13 02:22:06 +010010124 clib_memcpy(mp->ip_address, &ipv4, sizeof(ipv4));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010125 }
10126
10127 /* send it... */
10128 S;
10129
10130 /* Wait for a reply... */
10131 W;
10132
10133 /* NOTREACHED */
10134 return 0;
10135}
10136
10137static int
Florin Coras577c3552016-04-21 00:45:40 +020010138api_lisp_gpe_enable_disable (vat_main_t * vam)
10139{
10140 unformat_input_t * input = vam->input;
10141 vl_api_lisp_gpe_enable_disable_t *mp;
10142 f64 timeout = ~0;
10143 u8 is_set = 0;
10144 u8 is_en = 1;
10145
10146 /* Parse args required to build the message */
10147 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
10148 if (unformat(input, "enable")) {
10149 is_set = 1;
10150 is_en = 1;
10151 } else if (unformat(input, "disable")) {
10152 is_set = 1;
10153 is_en = 0;
10154 } else
10155 break;
10156 }
10157
10158 if (is_set == 0) {
10159 errmsg("Value not set\n");
10160 return -99;
10161 }
10162
10163 /* Construct the API message */
10164 M(LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
10165
10166 mp->is_en = is_en;
10167
10168 /* send it... */
10169 S;
10170
10171 /* Wait for a reply... */
10172 W;
10173
10174 /* NOTREACHED */
10175 return 0;
10176}
10177
10178static int
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010179api_lisp_gpe_add_del_iface(vat_main_t * vam)
10180{
10181 unformat_input_t * input = vam->input;
10182 vl_api_lisp_gpe_add_del_iface_t *mp;
10183 f64 timeout = ~0;
10184 u8 is_set = 0;
Florin Coras577c3552016-04-21 00:45:40 +020010185 u8 is_add = 1;
10186 u32 table_id, vni;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010187
10188 /* Parse args required to build the message */
10189 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
10190 if (unformat(input, "up")) {
10191 is_set = 1;
10192 is_add = 1;
10193 } else if (unformat(input, "down")) {
10194 is_set = 1;
10195 is_add = 0;
Florin Coras577c3552016-04-21 00:45:40 +020010196 } else if (unformat(input, "table_id %d", &table_id)) {
10197 ;
10198 } else if (unformat(input, "vni %d", &vni)) {
10199 ;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010200 } else
10201 break;
10202 }
10203
10204 if (is_set == 0) {
10205 errmsg("Value not set\n");
10206 return -99;
10207 }
10208
10209 /* Construct the API message */
10210 M(LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
10211
10212 mp->is_add = is_add;
Florin Coras577c3552016-04-21 00:45:40 +020010213 mp->table_id = table_id;
10214 mp->vni = vni;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010215
10216 /* send it... */
10217 S;
10218
10219 /* Wait for a reply... */
10220 W;
10221
10222 /* NOTREACHED */
10223 return 0;
10224}
10225
10226static int
10227api_lisp_locator_set_dump(vat_main_t *vam)
10228{
10229 vl_api_lisp_locator_set_dump_t *mp;
10230 f64 timeout = ~0;
10231
10232 if (!vam->json_output) {
10233 fformat(vam->ofp, "%=20s%=16s%=16s%=16s\n",
10234 "Locator-set", "Locator", "Priority", "Weight");
10235 }
10236
10237 M(LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
10238 /* send it... */
10239 S;
10240
10241 /* Use a control ping for synchronization */
10242 {
10243 vl_api_control_ping_t * mp;
10244 M(CONTROL_PING, control_ping);
10245 S;
10246 }
10247 /* Wait for a reply... */
10248 W;
10249
10250 /* NOTREACHED */
10251 return 0;
10252}
10253
10254static int
10255api_lisp_local_eid_table_dump(vat_main_t *vam)
10256{
10257 vl_api_lisp_local_eid_table_dump_t *mp;
10258 f64 timeout = ~0;
10259
10260 if (!vam->json_output) {
10261 fformat(vam->ofp, "%=20s%=30s\n",
10262 "Locator-set", "Eid");
10263 }
10264
10265 M(LISP_LOCAL_EID_TABLE_DUMP, lisp_local_eid_table_dump);
10266 /* send it... */
10267 S;
10268
10269 /* Use a control ping for synchronization */
10270 {
10271 vl_api_control_ping_t * mp;
10272 M(CONTROL_PING, control_ping);
10273 S;
10274 }
10275 /* Wait for a reply... */
10276 W;
10277
10278 /* NOTREACHED */
10279 return 0;
10280}
10281
10282static int
10283api_lisp_gpe_tunnel_dump(vat_main_t *vam)
10284{
10285 vl_api_lisp_gpe_tunnel_dump_t *mp;
10286 f64 timeout = ~0;
10287
10288 if (!vam->json_output) {
10289 fformat(vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
10290 "%=16s%=16s%=16s%=16s%=16s\n",
10291 "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
10292 "Decap next", "Lisp version", "Flags", "Next protocol",
10293 "ver_res", "res", "iid");
10294 }
10295
10296 M(LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
10297 /* send it... */
10298 S;
10299
10300 /* Use a control ping for synchronization */
10301 {
10302 vl_api_control_ping_t * mp;
10303 M(CONTROL_PING, control_ping);
10304 S;
10305 }
10306 /* Wait for a reply... */
10307 W;
10308
10309 /* NOTREACHED */
10310 return 0;
10311}
10312
10313static int
10314api_lisp_map_resolver_dump(vat_main_t *vam)
10315{
10316 vl_api_lisp_map_resolver_dump_t *mp;
10317 f64 timeout = ~0;
10318
10319 if (!vam->json_output) {
10320 fformat(vam->ofp, "%=20s\n",
10321 "Map resolver");
10322 }
10323
10324 M(LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
10325 /* send it... */
10326 S;
10327
10328 /* Use a control ping for synchronization */
10329 {
10330 vl_api_control_ping_t * mp;
10331 M(CONTROL_PING, control_ping);
10332 S;
10333 }
10334 /* Wait for a reply... */
10335 W;
10336
10337 /* NOTREACHED */
10338 return 0;
10339}
10340
Andrej Kozemcaka9edd852016-05-02 12:14:33 +020010341static int
10342api_lisp_gpe_enable_disable_status_dump(vat_main_t *vam)
10343{
10344 vl_api_lisp_gpe_enable_disable_status_dump_t *mp;
10345 f64 timeout = ~0;
10346
10347 if (!vam->json_output) {
10348 fformat(vam->ofp, "%=20s\n",
10349 "lisp gpe");
10350 }
10351
10352 M(LISP_GPE_ENABLE_DISABLE_STATUS_DUMP,
10353 lisp_gpe_enable_disable_status_dump);
10354 /* send it... */
10355 S;
10356
10357 /* Use a control ping for synchronization */
10358 {
10359 vl_api_control_ping_t * mp;
10360 M(CONTROL_PING, control_ping);
10361 S;
10362 }
10363 /* Wait for a reply... */
10364 W;
10365
10366 /* NOTREACHED */
10367 return 0;
10368}
10369
Ed Warnickecb9cada2015-12-08 15:45:58 -070010370static int q_or_quit (vat_main_t * vam)
10371{
10372 longjmp (vam->jump_buf, 1);
10373 return 0; /* not so much */
10374}
10375static int q (vat_main_t * vam) {return q_or_quit (vam);}
10376static int quit (vat_main_t * vam) {return q_or_quit (vam);}
10377
10378static int comment (vat_main_t * vam)
10379{
10380 return 0;
10381}
10382
Matus Fabiand2dc3df2015-12-14 10:31:33 -050010383static int cmd_cmp (void * a1, void * a2)
10384{
10385 u8 ** c1 = a1;
10386 u8 ** c2 = a2;
10387
10388 return strcmp ((char *)(c1[0]), (char *)(c2[0]));
10389}
10390
Ed Warnickecb9cada2015-12-08 15:45:58 -070010391static int help (vat_main_t * vam)
10392{
10393 u8 ** cmds = 0;
10394 u8 * name = 0;
10395 hash_pair_t * p;
10396 unformat_input_t * i = vam->input;
10397 int j;
10398
10399 if (unformat (i, "%s", &name)) {
10400 uword *hs;
10401
10402 vec_add1(name, 0);
10403
10404 hs = hash_get_mem (vam->help_by_name, name);
10405 if (hs)
10406 fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
10407 else
10408 fformat (vam->ofp, "No such msg / command '%s'\n", name);
10409 vec_free(name);
10410 return 0;
10411 }
10412
10413 fformat(vam->ofp, "Help is available for the following:\n");
10414
10415 hash_foreach_pair (p, vam->function_by_name,
10416 ({
10417 vec_add1 (cmds, (u8 *)(p->key));
10418 }));
10419
Matus Fabiand2dc3df2015-12-14 10:31:33 -050010420 vec_sort_with_function (cmds, cmd_cmp);
Ed Warnickecb9cada2015-12-08 15:45:58 -070010421
10422 for (j = 0; j < vec_len(cmds); j++)
10423 fformat (vam->ofp, "%s\n", cmds[j]);
10424
10425 vec_free (cmds);
10426 return 0;
10427}
10428
10429static int set (vat_main_t * vam)
10430{
10431 u8 * name = 0, * value = 0;
10432 unformat_input_t * i = vam->input;
10433
10434 if (unformat (i, "%s", &name)) {
10435 /* The input buffer is a vector, not a string. */
10436 value = vec_dup (i->buffer);
10437 vec_delete (value, i->index, 0);
10438 /* Almost certainly has a trailing newline */
10439 if (value[vec_len(value)-1] == '\n')
10440 value[vec_len(value)-1] = 0;
10441 /* Make sure it's a proper string, one way or the other */
10442 vec_add1 (value, 0);
10443 (void) clib_macro_set_value (&vam->macro_main,
10444 (char *)name, (char *)value);
10445 }
10446 else
10447 errmsg ("usage: set <name> <value>\n");
10448
10449 vec_free (name);
10450 vec_free (value);
10451 return 0;
10452}
10453
10454static int unset (vat_main_t * vam)
10455{
10456 u8 * name = 0;
10457
10458 if (unformat (vam->input, "%s", &name))
10459 if (clib_macro_unset (&vam->macro_main, (char *)name) == 1)
10460 errmsg ("unset: %s wasn't set\n", name);
10461 vec_free (name);
10462 return 0;
10463}
10464
10465typedef struct {
10466 u8 * name;
10467 u8 * value;
10468} macro_sort_t;
10469
10470
Matus Fabiand2dc3df2015-12-14 10:31:33 -050010471static int macro_sort_cmp (void * a1, void * a2)
10472{
10473 macro_sort_t * s1 = a1;
10474 macro_sort_t * s2 = a2;
10475
10476 return strcmp ((char *)(s1->name), (char *)(s2->name));
10477}
10478
Ed Warnickecb9cada2015-12-08 15:45:58 -070010479static int dump_macro_table (vat_main_t * vam)
10480{
10481 macro_sort_t * sort_me = 0, * sm;
10482 int i;
10483 hash_pair_t * p;
10484
10485 hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
10486 ({
10487 vec_add2 (sort_me, sm, 1);
10488 sm->name = (u8 *)(p->key);
10489 sm->value = (u8 *) (p->value[0]);
10490 }));
10491
Matus Fabiand2dc3df2015-12-14 10:31:33 -050010492 vec_sort_with_function (sort_me, macro_sort_cmp);
Ed Warnickecb9cada2015-12-08 15:45:58 -070010493
10494 if (vec_len(sort_me))
10495 fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
10496 else
10497 fformat (vam->ofp, "The macro table is empty...\n");
10498
10499 for (i = 0; i < vec_len (sort_me); i++)
10500 fformat (vam->ofp, "%-15s%s\n", sort_me[i].name,
10501 sort_me[i].value);
10502 return 0;
10503}
10504
Dave Barachb44e9bc2016-02-19 09:06:23 -050010505static int dump_node_table (vat_main_t * vam)
10506{
10507 int i, j;
10508 vlib_node_t * node, * next_node;
10509
10510 if (vec_len (vam->graph_nodes) == 0) {
10511 fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
10512 return 0;
10513 }
10514
10515 for (i = 0; i < vec_len (vam->graph_nodes); i++) {
10516 node = vam->graph_nodes[i];
10517 fformat (vam->ofp, "[%d] %s\n", i, node->name);
10518 for (j = 0; j < vec_len (node->next_nodes); j++) {
10519 if (node->next_nodes[j] != ~0) {
10520 next_node = vam->graph_nodes[node->next_nodes[j]];
10521 fformat (vam->ofp, " [%d] %s\n", j, next_node->name);
10522 }
10523 }
10524 }
10525 return 0;
10526}
10527
10528static int search_node_table (vat_main_t * vam)
10529{
10530 unformat_input_t * line_input = vam->input;
10531 u8 * node_to_find;
10532 int j;
10533 vlib_node_t * node, * next_node;
10534 uword * p;
10535
10536 if (vam->graph_node_index_by_name == 0) {
10537 fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
10538 return 0;
10539 }
10540
10541 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
10542 if (unformat (line_input, "%s", &node_to_find)) {
10543 vec_add1 (node_to_find, 0);
10544 p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
10545 if (p == 0) {
10546 fformat (vam->ofp, "%s not found...\n", node_to_find);
10547 goto out;
10548 }
10549 node = vam->graph_nodes[p[0]];
10550 fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
10551 for (j = 0; j < vec_len (node->next_nodes); j++) {
10552 if (node->next_nodes[j] != ~0) {
10553 next_node = vam->graph_nodes[node->next_nodes[j]];
10554 fformat (vam->ofp, " [%d] %s\n", j, next_node->name);
10555 }
10556 }
10557 }
10558
10559 else {
10560 clib_warning ("parse error '%U'", format_unformat_error,
10561 line_input);
10562 return -99;
10563 }
10564
10565 out:
10566 vec_free(node_to_find);
10567
10568 }
10569
10570 return 0;
10571}
10572
10573
Ed Warnickecb9cada2015-12-08 15:45:58 -070010574static int script (vat_main_t * vam)
10575{
10576 u8 * s = 0;
10577 char * save_current_file;
10578 unformat_input_t save_input;
10579 jmp_buf save_jump_buf;
10580 u32 save_line_number;
10581
10582 FILE * new_fp, * save_ifp;
10583
10584 if (unformat (vam->input, "%s", &s)) {
10585 new_fp = fopen ((char *)s, "r");
10586 if (new_fp == 0) {
10587 errmsg ("Couldn't open script file %s\n", s);
10588 vec_free (s);
10589 return -99;
10590 }
10591 } else {
10592 errmsg ("Missing script name\n");
10593 return -99;
10594 }
10595
Damjan Marionf1213b82016-03-13 02:22:06 +010010596 clib_memcpy (&save_input, &vam->input, sizeof (save_input));
10597 clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
Ed Warnickecb9cada2015-12-08 15:45:58 -070010598 save_ifp = vam->ifp;
10599 save_line_number = vam->input_line_number;
10600 save_current_file = (char *) vam->current_file;
10601
10602 vam->input_line_number = 0;
10603 vam->ifp = new_fp;
10604 vam->current_file = s;
10605 do_one_file (vam);
10606
Damjan Marionf1213b82016-03-13 02:22:06 +010010607 clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
10608 clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
Ed Warnickecb9cada2015-12-08 15:45:58 -070010609 vam->ifp = save_ifp;
10610 vam->input_line_number = save_line_number;
10611 vam->current_file = (u8 *) save_current_file;
10612 vec_free (s);
10613
10614 return 0;
10615}
10616
10617static int echo (vat_main_t * vam)
10618{
10619 fformat (vam->ofp, "%v", vam->input->buffer);
10620 return 0;
10621}
10622
10623/* List of API message constructors, CLI names map to api_xxx */
10624#define foreach_vpe_api_msg \
10625_(create_loopback,"[mac <mac-addr>]") \
10626_(sw_interface_dump,"") \
10627_(sw_interface_set_flags, \
10628 "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
10629_(sw_interface_add_del_address, \
10630 "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
10631_(sw_interface_set_table, \
10632 "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]") \
10633_(sw_interface_set_vpath, \
10634 "<intfc> | sw_if_index <id> enable | disable") \
10635_(sw_interface_set_l2_xconnect, \
10636 "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
10637 "enable | disable") \
10638_(sw_interface_set_l2_bridge, \
10639 "rx <intfc> | rx_sw_if_index <id> bd_id <bridge-domain-id>\n" \
10640 "[shg <split-horizon-group>] [bvi]\n" \
10641 "enable | disable") \
10642_(bridge_domain_add_del, \
10643 "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
10644_(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n") \
10645_(l2fib_add_del, \
10646 "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi]\n") \
10647_(l2_flags, \
10648 "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
10649_(bridge_flags, \
10650 "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
10651_(tap_connect, \
10652 "tapname <name> mac <mac-addr> | random-mac") \
10653_(tap_modify, \
10654 "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
10655_(tap_delete, \
10656 "<vpp-if-name> | sw_if_index <id>") \
10657_(sw_interface_tap_dump, "") \
10658_(ip_add_del_route, \
10659 "<addr>/<mask> via <addr> [vrf <n>]\n" \
10660 "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n" \
10661 "[weight <n>] [drop] [local] [classify <n>] [del]\n" \
10662 "[multipath] [count <n>]") \
10663_(proxy_arp_add_del, \
10664 "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]") \
10665_(proxy_arp_intfc_enable_disable, \
10666 "<intfc> | sw_if_index <id> enable | disable") \
10667_(mpls_add_del_encap, \
10668 "label <n> dst <ip4-addr> [vrf <n>] [del]") \
10669_(mpls_add_del_decap, \
10670 "label <n> [rx_vrf_id <n>] [tx_vrf_id] [s-bit-clear][del]") \
10671_(mpls_gre_add_del_tunnel, \
10672 "inner_vrf_id <n> outer_vrf_id <n> src <ip4-address> dst <ip4-address>\n" \
10673 "adj <ip4-address>/<mask-width> [del]") \
10674_(sw_interface_set_unnumbered, \
10675 "<intfc> | sw_if_index <id> unnum_if_index <id> [del]") \
10676_(ip_neighbor_add_del, \
10677 "<intfc> | sw_if_index <id> dst <ip46-address> mac <mac-addr>") \
10678_(reset_vrf, "vrf <id> [ipv6]") \
10679_(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>") \
10680_(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n" \
10681 "[outer_vlan_id <n>][inner_vlan_id <n>]\n" \
10682 "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n" \
10683 "[outer_vlan_id_any][inner_vlan_id_any]") \
10684_(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]") \
10685_(reset_fib, "vrf <n> [ipv6]") \
10686_(dhcp_proxy_config, \
10687 "svr <v46-address> src <v46-address>\n" \
10688 "insert-cid <n> [del]") \
10689_(dhcp_proxy_config_2, \
10690 "svr <v46-address> src <v46-address>\n" \
10691 "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]") \
10692_(dhcp_proxy_set_vss, \
10693 "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]") \
10694_(dhcp_client_config, \
10695 "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
10696_(set_ip_flow_hash, \
10697 "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]") \
10698_(sw_interface_ip6_enable_disable, \
10699 "<intfc> | sw_if_index <id> enable | disable") \
10700_(sw_interface_ip6_set_link_local_address, \
10701 "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>") \
10702_(sw_interface_ip6nd_ra_prefix, \
10703 "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n" \
10704 "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n" \
10705 "[nolink] [isno]") \
10706_(sw_interface_ip6nd_ra_config, \
10707 "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n" \
10708 "[life <n>] [count <n>] [interval <n>] [surpress]\n" \
10709 "[managed] [other] [ll] [send] [cease] [isno] [def]") \
10710_(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]") \
10711_(l2_patch_add_del, \
10712 "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
10713 "enable | disable") \
10714_(mpls_ethernet_add_del_tunnel, \
10715 "tx <intfc> | tx_sw_if_index <n> dst <mac-addr>\n" \
10716 "adj <ip4-addr>/<mw> dst <mac-addr> [del]") \
10717_(mpls_ethernet_add_del_tunnel_2, \
10718 "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n" \
10719 "resolve-attempts <n> resolve-if-needed 0 | 1 [del]") \
10720_(sr_tunnel_add_del, \
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -070010721 "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n" \
10722 "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n" \
10723 "[policy <policy_name>]") \
10724_(sr_policy_add_del, \
10725 "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]") \
10726_(sr_multicast_map_add_del, \
10727 "address [ip6 multicast address] sr-policy [policy name] [del]") \
Ed Warnickecb9cada2015-12-08 15:45:58 -070010728_(classify_add_del_table, \
10729 "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n" \
10730 "[del] mask <mask-value>\n" \
10731 " [l2-miss-next | miss-next | acl-miss-next] <name|nn>") \
10732_(classify_add_del_session, \
10733 "[hit-next|l2-hit-next|acl-hit-next] <name|nn> table-index <nn>\n" \
10734 "skip_n <nn> match_n <nn> match [hex] [l2] [l3 [ip4|ip6]]") \
10735_(classify_set_interface_ip_table, \
10736 "<intfc> | sw_if_index <nn> table <nn>") \
10737_(classify_set_interface_l2_tables, \
10738 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
10739 " [other-table <nn>]") \
10740_(get_node_index, "node <node-name") \
10741_(add_node_next, "node <node-name> next <next-node-name>") \
10742_(l2tpv3_create_tunnel, \
10743 "client_address <ip6-addr> our_address <ip6-addr>\n" \
10744 "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
10745 "[remote_cookie <nn>]\n[l2-sublayer-preset]\n") \
10746_(l2tpv3_set_tunnel_cookies, \
10747 "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n" \
10748 "[new_remote_cookie <nn>]\n") \
10749_(l2tpv3_interface_enable_disable, \
10750 "<intfc> | sw_if_index <nn> enable | disable") \
10751_(l2tpv3_set_lookup_key, \
10752 "lookup_v6_src | lookup_v6_dst | lookup_session_id") \
10753_(sw_if_l2tpv3_tunnel_dump, "") \
10754_(vxlan_add_del_tunnel, \
Chris Luke27fe48f2016-04-28 13:44:38 -040010755 "src <ip4-addr> dst <ip4-addr> vni <vni> [encap-vrf-id <nn>]\n" \
Ed Warnickecb9cada2015-12-08 15:45:58 -070010756 " [decap-next l2|ip4|ip6] [del]") \
Dave Wallace60231f32015-12-17 21:04:30 -050010757_(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
Chris Luke27fe48f2016-04-28 13:44:38 -040010758_(gre_add_del_tunnel, \
10759 "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [del]\n") \
10760_(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
Ed Warnickecb9cada2015-12-08 15:45:58 -070010761_(l2_fib_clear_table, "") \
10762_(l2_interface_efp_filter, "sw_if_index <nn> enable | disable") \
10763_(l2_interface_vlan_tag_rewrite, \
10764 "<intfc> | sw_if_index <nn> \n" \
10765 "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n" \
10766 "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>") \
10767_(create_vhost_user_if, \
Pierre Pfisteref65cb02016-02-19 13:52:44 +000010768 "socket <filename> [server] [renumber <dev_instance>] " \
10769 "[mac <mac_address>]") \
Ed Warnickecb9cada2015-12-08 15:45:58 -070010770_(modify_vhost_user_if, \
10771 "<intfc> | sw_if_index <nn> socket <filename>\n" \
10772 "[server] [renumber <dev_instance>]") \
10773_(delete_vhost_user_if, "<intfc> | sw_if_index <nn>") \
10774_(sw_interface_vhost_user_dump, "") \
10775_(show_version, "") \
10776_(nsh_gre_add_del_tunnel, \
10777 "src <ip4-addr> dst <ip4-addr>" \
10778 "c1 <nn> c2 <nn> c3 <nn> c4 <nn> spi <nn> si <nn>\n" \
10779 "[encap-fib-id <nn>] [decap-fib-id <nn>] [o-bit <1|0>]\n" \
10780 "[c-bit <1|0>] [md-type <nn>][next-ip4][next-ip6][next-ethernet]\n" \
10781 "[tlv <xx>][del]") \
10782_(nsh_vxlan_gpe_add_del_tunnel, \
10783 "src <ip4-addr> dst <ip4-addr> vni <nn>\n" \
10784 "c1 <nn> c2 <nn> c3 <nn> c4 <nn> spi <nn> si <nn>\n" \
10785 "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [o-bit <1|0>]\n" \
10786 "[c-bit <1|0>] [md-type <nn>][next-ip4][next-ip6][next-ethernet]\n" \
10787 "[tlv <xx>][del]") \
10788_(l2_fib_table_dump, "bd_id <bridge-domain-id>") \
10789_(lisp_gpe_add_del_tunnel, \
10790 "src <ip4-addr> dst <ip4-addr> iid <nn>|iidx <0xnn>\n" \
10791 "[encap-vrf-id <nn>] [decap-vrf-id <nn>]\n" \
10792 "[n-bit][l-bit][e-bit][v-bit][i-bit][p-bit][not-p-bit][o-bit]\n" \
10793 "[next-ip4][next-ip6][next-ethernet][next-nsh]\n" \
10794 "[decap-next [ip4|ip6|ethernet|nsh-encap|<nn>]][del]") \
10795_(interface_name_renumber, \
10796 "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>") \
10797_(input_acl_set_interface, \
10798 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
10799 " [l2-table <nn>] [del]") \
10800_(want_ip4_arp_events, "address <ip4-address> [del]") \
10801_(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)") \
10802_(ip_dump, "ipv4 | ipv6") \
10803_(ipsec_spd_add_del, "spd_id <n> [del]") \
10804_(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n" \
10805 " spid_id <n> ") \
10806_(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n" \
10807 " crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n" \
10808 " integ_alg <alg> integ_key <hex>") \
10809_(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n" \
10810 " (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n" \
10811 " laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
10812 " [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
10813_(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>") \
Matus Fabiane5f42fe2016-04-08 11:18:08 +020010814_(ikev2_profile_add_del, "name <profile_name> [del]") \
10815_(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n" \
10816 "(auth_data 0x<data> | auth_data <data>)") \
10817_(ikev2_profile_set_id, "name <profile_name> id_type <type>\n" \
10818 "(id_data 0x<data> | id_data <data>) (local|remote)") \
10819_(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n" \
10820 "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
10821 "(local|remote)") \
10822_(ikev2_set_local_key, "file <absolute_file_path>") \
Ed Warnickecb9cada2015-12-08 15:45:58 -070010823_(delete_loopback,"sw_if_index <nn>") \
10824_(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
10825_(map_add_domain, \
10826 "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> " \
10827 "ip6-src <ip6addr> " \
10828 "ea-bits-len <n> psid-offset <n> psid-len <n>") \
10829_(map_del_domain, "index <n>") \
10830_(map_add_del_rule, \
10831 "index <n> psid <n> dst <ip6addr> [del]") \
10832_(map_domain_dump, "") \
10833_(map_rule_dump, "index <map-domain>") \
10834_(want_interface_events, "enable|disable") \
10835_(want_stats,"enable|disable") \
Dave Barachc07bf5d2016-02-17 17:52:26 -050010836_(get_first_msg_id, "client <name>") \
10837_(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
10838_(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n" \
Dave Barachb44e9bc2016-02-19 09:06:23 -050010839 "fib-id <nn> [ip4][ip6][default]") \
Pavel Kotucek00bbf272016-03-03 13:27:11 +010010840_(get_node_graph, " ") \
Shwetha20a64f52016-03-25 10:55:01 +000010841_(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>") \
10842_(trace_profile_add, "id <nn> trace-type <0x1f|0x3|0x9|0x11|0x19> " \
10843 "trace-elts <nn> trace-tsp <0|1|2|3> node-id <node id in hex> " \
10844 "app-data <app_data in hex> [pow] [ppc <encap|decap>]") \
10845_(trace_profile_apply, "id <nn> <ip6-address>/<width>" \
10846 " vrf_id <nn> add | pop | none") \
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010847_(trace_profile_del, "") \
10848_(lisp_add_del_locator_set, "locator-set <locator_name> [del]") \
10849_(lisp_add_del_locator, "locator-set <locator_name> " \
10850 "iface <intf> | sw_if_index <sw_if_index> " \
10851 "p <priority> w <weight> [del]") \
10852_(lisp_add_del_local_eid, "<ipv4|ipv6>/<prefix> " \
10853 "locator-set <locator_name> [del]") \
10854_(lisp_gpe_add_del_fwd_entry, "eid <ip4|6-addr>/<prefix> " \
10855 "sloc <ip4/6-addr> dloc <ip4|6-addr> [del]") \
10856_(lisp_add_del_map_resolver, "<ip4|6-addr> [del]") \
Florin Coras577c3552016-04-21 00:45:40 +020010857_(lisp_gpe_enable_disable, "enable|disable") \
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010858_(lisp_gpe_add_del_iface, "up|down") \
10859_(lisp_locator_set_dump, "") \
10860_(lisp_local_eid_table_dump, "") \
10861_(lisp_gpe_tunnel_dump, "") \
Andrej Kozemcaka9edd852016-05-02 12:14:33 +020010862_(lisp_map_resolver_dump, "") \
10863_(lisp_gpe_enable_disable_status_dump, "")
Ed Warnickecb9cada2015-12-08 15:45:58 -070010864
10865/* List of command functions, CLI names map directly to functions */
10866#define foreach_cli_function \
10867_(comment, "usage: comment <ignore-rest-of-line>") \
10868_(dump_interface_table, "usage: dump_interface_table") \
10869_(dump_sub_interface_table, "usage: dump_sub_interface_table") \
10870_(dump_ipv4_table, "usage: dump_ipv4_table") \
10871_(dump_ipv6_table, "usage: dump_ipv6_table") \
10872_(dump_stats_table, "usage: dump_stats_table") \
10873_(dump_macro_table, "usage: dump_macro_table ") \
Dave Barachb44e9bc2016-02-19 09:06:23 -050010874_(dump_node_table, "usage: dump_node_table") \
Ed Warnickecb9cada2015-12-08 15:45:58 -070010875_(echo, "usage: echo <message>") \
10876_(exec, "usage: exec <vpe-debug-CLI-command>") \
10877_(help, "usage: help") \
10878_(q, "usage: quit") \
10879_(quit, "usage: quit") \
Dave Barachb44e9bc2016-02-19 09:06:23 -050010880_(search_node_table, "usage: search_node_table <name>...") \
Ed Warnickecb9cada2015-12-08 15:45:58 -070010881_(set, "usage: set <variable-name> <value>") \
10882_(script, "usage: script <file-name>") \
10883_(unset, "usage: unset <variable-name>")
10884
10885#define _(N,n) \
10886 static void vl_api_##n##_t_handler_uni \
10887 (vl_api_##n##_t * mp) \
10888 { \
10889 vat_main_t * vam = &vat_main; \
10890 if (vam->json_output) { \
10891 vl_api_##n##_t_handler_json(mp); \
10892 } else { \
10893 vl_api_##n##_t_handler(mp); \
10894 } \
10895 }
10896foreach_vpe_api_reply_msg;
10897#undef _
10898
10899void vat_api_hookup (vat_main_t *vam)
10900{
10901#define _(N,n) \
10902 vl_msg_api_set_handlers(VL_API_##N, #n, \
10903 vl_api_##n##_t_handler_uni, \
10904 vl_noop_handler, \
10905 vl_api_##n##_t_endian, \
10906 vl_api_##n##_t_print, \
10907 sizeof(vl_api_##n##_t), 1);
10908 foreach_vpe_api_reply_msg;
10909#undef _
10910
10911 vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
10912
10913 vam->sw_if_index_by_interface_name =
10914 hash_create_string (0, sizeof (uword));
10915
10916 vam->function_by_name =
10917 hash_create_string (0, sizeof(uword));
10918
10919 vam->help_by_name =
10920 hash_create_string (0, sizeof(uword));
10921
10922 /* API messages we can send */
10923#define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
10924 foreach_vpe_api_msg;
10925#undef _
10926
10927 /* Help strings */
10928#define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
10929 foreach_vpe_api_msg;
10930#undef _
10931
10932 /* CLI functions */
10933#define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
10934 foreach_cli_function;
10935#undef _
10936
10937 /* Help strings */
10938#define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
10939 foreach_cli_function;
10940#undef _
10941}
10942
10943#undef vl_api_version
10944#define vl_api_version(n,v) static u32 vpe_api_version = v;
10945#include <api/vpe.api.h>
10946#undef vl_api_version
10947
10948void vl_client_add_api_signatures (vl_api_memclnt_create_t *mp)
10949{
10950 /*
10951 * Send the main API signature in slot 0. This bit of code must
10952 * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
10953 */
10954 mp->api_versions[0] = clib_host_to_net_u32 (vpe_api_version);
10955}