blob: a1a023be28b231789a89a364744a388fbca72ce2 [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>
29#include <vnet/nsh-gre/nsh_gre.h>
30#include <vnet/nsh-vxlan-gpe/nsh_vxlan_gpe.h>
31#include <vnet/lisp-gpe/lisp_gpe.h>
32
33#include <api/vpe_msg_enum.h>
34#include <vnet/l2/l2_classify.h>
35#include <vnet/l2/l2_vtr.h>
36#include <vnet/classify/input_acl.h>
Dave Barachbfdedbd2016-01-20 09:11:55 -050037#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -070038#include <vnet/ipsec/ipsec.h>
Dave Barachbfdedbd2016-01-20 09:11:55 -050039#else
40#include <inttypes.h>
41#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -070042#include <vnet/map/map.h>
Dave Barachc07bf5d2016-02-17 17:52:26 -050043#include <vnet/cop/cop.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070044
45#include "vat/json_format.h"
46
47#define vl_typedefs /* define message structures */
48#include <api/vpe_all_api_h.h>
49#undef vl_typedefs
50
51/* declare message handlers for each api */
52
53#define vl_endianfun /* define message structures */
54#include <api/vpe_all_api_h.h>
55#undef vl_endianfun
56
57/* instantiate all the print functions we know about */
58#define vl_print(handle, ...)
59#define vl_printfun
60#include <api/vpe_all_api_h.h>
61#undef vl_printfun
62
63uword unformat_sw_if_index (unformat_input_t * input, va_list * args)
64{
65 vat_main_t * vam = va_arg (*args, vat_main_t *);
66 u32 * result = va_arg (*args, u32 *);
67 u8 * if_name;
68 uword * p;
69
70 if (!unformat (input, "%s", &if_name))
71 return 0;
72
73 p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
74 if (p == 0)
75 return 0;
76 *result = p[0];
77 return 1;
78}
79
80/* Parse an IP4 address %d.%d.%d.%d. */
81uword unformat_ip4_address (unformat_input_t * input, va_list * args)
82{
83 u8 * result = va_arg (*args, u8 *);
84 unsigned a[4];
85
86 if (! unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
87 return 0;
88
89 if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
90 return 0;
91
92 result[0] = a[0];
93 result[1] = a[1];
94 result[2] = a[2];
95 result[3] = a[3];
96
97 return 1;
98}
99
100
101uword
102unformat_ethernet_address (unformat_input_t * input, va_list * args)
103{
104 u8 * result = va_arg (*args, u8 *);
105 u32 i, a[6];
106
107 if (! unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
108 &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
109 return 0;
110
111 /* Check range. */
112 for (i = 0; i < 6; i++)
113 if (a[i] >= (1 << 8))
114 return 0;
115
116 for (i = 0; i < 6; i++)
117 result[i] = a[i];
118
119 return 1;
120}
121
122/* Returns ethernet type as an int in host byte order. */
123uword
124unformat_ethernet_type_host_byte_order (unformat_input_t * input,
125 va_list * args)
126{
127 u16 * result = va_arg (*args, u16 *);
128 int type;
129
130 /* Numeric type. */
131 if (unformat (input, "0x%x", &type)
132 || unformat (input, "%d", &type))
133 {
134 if (type >= (1 << 16))
135 return 0;
136 *result = type;
137 return 1;
138 }
139 return 0;
140}
141
142/* Parse an IP6 address. */
143uword unformat_ip6_address (unformat_input_t * input, va_list * args)
144{
145 ip6_address_t * result = va_arg (*args, ip6_address_t *);
146 u16 hex_quads[8];
147 uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
148 uword c, n_colon, double_colon_index;
149
150 n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
151 double_colon_index = ARRAY_LEN (hex_quads);
152 while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
153 {
154 hex_digit = 16;
155 if (c >= '0' && c <= '9')
156 hex_digit = c - '0';
157 else if (c >= 'a' && c <= 'f')
158 hex_digit = c + 10 - 'a';
159 else if (c >= 'A' && c <= 'F')
160 hex_digit = c + 10 - 'A';
161 else if (c == ':' && n_colon < 2)
162 n_colon++;
163 else
164 {
165 unformat_put_input (input);
166 break;
167 }
168
169 /* Too many hex quads. */
170 if (n_hex_quads >= ARRAY_LEN (hex_quads))
171 return 0;
172
173 if (hex_digit < 16)
174 {
175 hex_quad = (hex_quad << 4) | hex_digit;
176
177 /* Hex quad must fit in 16 bits. */
178 if (n_hex_digits >= 4)
179 return 0;
180
181 n_colon = 0;
182 n_hex_digits++;
183 }
184
185 /* Save position of :: */
186 if (n_colon == 2)
187 {
188 /* More than one :: ? */
189 if (double_colon_index < ARRAY_LEN (hex_quads))
190 return 0;
191 double_colon_index = n_hex_quads;
192 }
193
194 if (n_colon > 0 && n_hex_digits > 0)
195 {
196 hex_quads[n_hex_quads++] = hex_quad;
197 hex_quad = 0;
198 n_hex_digits = 0;
199 }
200 }
201
202 if (n_hex_digits > 0)
203 hex_quads[n_hex_quads++] = hex_quad;
204
205 {
206 word i;
207
208 /* Expand :: to appropriate number of zero hex quads. */
209 if (double_colon_index < ARRAY_LEN (hex_quads))
210 {
211 word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
212
213 for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
214 hex_quads[n_zero + i] = hex_quads[i];
215
216 for (i = 0; i < n_zero; i++)
217 hex_quads[double_colon_index + i] = 0;
218
219 n_hex_quads = ARRAY_LEN (hex_quads);
220 }
221
222 /* Too few hex quads given. */
223 if (n_hex_quads < ARRAY_LEN (hex_quads))
224 return 0;
225
226 for (i = 0; i < ARRAY_LEN (hex_quads); i++)
227 result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
228
229 return 1;
230 }
231}
232
233uword
234unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
235{
Dave Barachbfdedbd2016-01-20 09:11:55 -0500236#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -0700237 u32 * r = va_arg (*args, u32 *);
238
239 if (0) ;
240#define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
241 foreach_ipsec_policy_action
242#undef _
243 else
244 return 0;
245 return 1;
Dave Barachbfdedbd2016-01-20 09:11:55 -0500246#else
247 return 0;
248#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -0700249}
250
251uword
252unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
253{
Dave Barachbfdedbd2016-01-20 09:11:55 -0500254#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -0700255 u32 * r = va_arg (*args, u32 *);
256
257 if (0) ;
258#define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
259 foreach_ipsec_crypto_alg
260#undef _
261 else
262 return 0;
263 return 1;
Dave Barachbfdedbd2016-01-20 09:11:55 -0500264#else
265 return 0;
266#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -0700267}
268
269u8 *
270format_ipsec_crypto_alg (u8 * s, va_list * args)
271{
Dave Barachbfdedbd2016-01-20 09:11:55 -0500272#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -0700273 u32 i = va_arg (*args, u32);
274 u8 * t = 0;
275
276 switch (i)
277 {
278#define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
279 foreach_ipsec_crypto_alg
280#undef _
281 default:
282 return format (s, "unknown");
283 }
284 return format (s, "%s", t);
Dave Barachbfdedbd2016-01-20 09:11:55 -0500285#else
286 return format (s, "Unimplemented");
287#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -0700288}
289
290uword
291unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
292{
Dave Barachbfdedbd2016-01-20 09:11:55 -0500293#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -0700294 u32 * r = va_arg (*args, u32 *);
295
296 if (0) ;
297#define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
298 foreach_ipsec_integ_alg
299#undef _
300 else
301 return 0;
302 return 1;
Dave Barachbfdedbd2016-01-20 09:11:55 -0500303#else
304 return 0;
305#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -0700306}
307
308u8 *
309format_ipsec_integ_alg (u8 * s, va_list * args)
310{
Dave Barachbfdedbd2016-01-20 09:11:55 -0500311#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -0700312 u32 i = va_arg (*args, u32);
313 u8 * t = 0;
314
315 switch (i)
316 {
317#define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
318 foreach_ipsec_integ_alg
319#undef _
320 default:
321 return format (s, "unknown");
322 }
323 return format (s, "%s", t);
Dave Barachbfdedbd2016-01-20 09:11:55 -0500324#else
325 return format (s, "Unsupported");
326#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -0700327}
328
329u8 * format_ip4_address (u8 * s, va_list * args)
330{
331 u8 * a = va_arg (*args, u8 *);
332 return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
333}
334
335u8 * format_ip6_address (u8 * s, va_list * args)
336{
337 ip6_address_t * a = va_arg (*args, ip6_address_t *);
338 u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
339
340 i_max_n_zero = ARRAY_LEN (a->as_u16);
341 max_n_zeros = 0;
342 i_first_zero = i_max_n_zero;
343 n_zeros = 0;
344 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
345 {
346 u32 is_zero = a->as_u16[i] == 0;
347 if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
348 {
349 i_first_zero = i;
350 n_zeros = 0;
351 }
352 n_zeros += is_zero;
353 if ((! is_zero && n_zeros > max_n_zeros)
354 || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
355 {
356 i_max_n_zero = i_first_zero;
357 max_n_zeros = n_zeros;
358 i_first_zero = ARRAY_LEN (a->as_u16);
359 n_zeros = 0;
360 }
361 }
362
363 last_double_colon = 0;
364 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
365 {
366 if (i == i_max_n_zero && max_n_zeros > 1)
367 {
368 s = format (s, "::");
369 i += max_n_zeros - 1;
370 last_double_colon = 1;
371 }
372 else
373 {
374 s = format (s, "%s%x",
375 (last_double_colon || i == 0) ? "" : ":",
376 clib_net_to_host_u16 (a->as_u16[i]));
377 last_double_colon = 0;
378 }
379 }
380
381 return s;
382}
383
384u8 * format_ethernet_address (u8 * s, va_list * args)
385{
386 u8 * a = va_arg (*args, u8 *);
387
388 return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
389 a[0], a[1], a[2], a[3], a[4], a[5]);
390}
391
392void increment_v4_address (ip4_address_t * a)
393{
394 u32 v;
395
396 v = ntohl(a->as_u32) + 1;
397 a->as_u32 = ntohl(v);
398}
399
400void increment_v6_address (ip6_address_t * a)
401{
402 u64 v0, v1;
403
404 v0 = clib_net_to_host_u64 (a->as_u64[0]);
405 v1 = clib_net_to_host_u64 (a->as_u64[1]);
406
407 v1 += 1;
408 if (v1 == 0)
409 v0 += 1;
410 a->as_u64[0] = clib_net_to_host_u64 (v0);
411 a->as_u64[1] = clib_net_to_host_u64 (v1);
412}
413
414
415static void vl_api_create_loopback_reply_t_handler
416(vl_api_create_loopback_reply_t * mp)
417{
418 vat_main_t * vam = &vat_main;
419 i32 retval = ntohl(mp->retval);
420
421 vam->retval = retval;
422 vam->result_ready = 1;
423 vam->regenerate_interface_table = 1;
424}
425
426static void vl_api_create_loopback_reply_t_handler_json
427(vl_api_create_loopback_reply_t * mp)
428{
429 vat_main_t * vam = &vat_main;
430 vat_json_node_t node;
431
432 vat_json_init_object(&node);
433 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
434 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
435
436 vat_json_print(vam->ofp, &node);
437 vat_json_free(&node);
438
439 vam->retval = ntohl(mp->retval);
440 vam->result_ready = 1;
441}
442
443static void vl_api_create_vlan_subif_reply_t_handler
444(vl_api_create_vlan_subif_reply_t * mp)
445{
446 vat_main_t * vam = &vat_main;
447 i32 retval = ntohl(mp->retval);
448
449 vam->retval = retval;
450 vam->result_ready = 1;
451 vam->regenerate_interface_table = 1;
452}
453
454static void vl_api_create_vlan_subif_reply_t_handler_json
455(vl_api_create_vlan_subif_reply_t * mp)
456{
457 vat_main_t * vam = &vat_main;
458 vat_json_node_t node;
459
460 vat_json_init_object(&node);
461 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
462 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
463
464 vat_json_print(vam->ofp, &node);
465 vat_json_free(&node);
466
467 vam->retval = ntohl(mp->retval);
468 vam->result_ready = 1;
469}
470
471static void vl_api_create_subif_reply_t_handler
472(vl_api_create_subif_reply_t * mp)
473{
474 vat_main_t * vam = &vat_main;
475 i32 retval = ntohl(mp->retval);
476
477 vam->retval = retval;
478 vam->result_ready = 1;
479 vam->regenerate_interface_table = 1;
480}
481
482static void vl_api_create_subif_reply_t_handler_json
483(vl_api_create_subif_reply_t * mp)
484{
485 vat_main_t * vam = &vat_main;
486 vat_json_node_t node;
487
488 vat_json_init_object(&node);
489 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
490 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
491
492 vat_json_print(vam->ofp, &node);
493 vat_json_free(&node);
494
495 vam->retval = ntohl(mp->retval);
496 vam->result_ready = 1;
497}
498
499static void vl_api_interface_name_renumber_reply_t_handler
500(vl_api_interface_name_renumber_reply_t * mp)
501{
502 vat_main_t * vam = &vat_main;
503 i32 retval = ntohl(mp->retval);
504
505 vam->retval = retval;
506 vam->result_ready = 1;
507 vam->regenerate_interface_table = 1;
508}
509
510static void vl_api_interface_name_renumber_reply_t_handler_json
511(vl_api_interface_name_renumber_reply_t * mp)
512{
513 vat_main_t * vam = &vat_main;
514 vat_json_node_t node;
515
516 vat_json_init_object(&node);
517 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
518
519 vat_json_print(vam->ofp, &node);
520 vat_json_free(&node);
521
522 vam->retval = ntohl(mp->retval);
523 vam->result_ready = 1;
524}
525
526/*
527 * Special-case: build the interface table, maintain
528 * the next loopback sw_if_index vbl.
529 */
530static void vl_api_sw_interface_details_t_handler
531(vl_api_sw_interface_details_t * mp)
532{
533 vat_main_t * vam = &vat_main;
534 u8 * s = format (0, "%s%c", mp->interface_name, 0);
535
536 hash_set_mem (vam->sw_if_index_by_interface_name, s,
537 ntohl(mp->sw_if_index));
538
539 /* In sub interface case, fill the sub interface table entry */
540 if (mp->sw_if_index != mp->sup_sw_if_index) {
541 sw_interface_subif_t * sub = NULL;
542
543 vec_add2(vam->sw_if_subif_table, sub, 1);
544
545 vec_validate(sub->interface_name, strlen((char *)s) + 1);
546 strncpy((char *)sub->interface_name, (char *)s,
547 vec_len(sub->interface_name));
548 sub->sw_if_index = ntohl(mp->sw_if_index);
549 sub->sub_id = ntohl(mp->sub_id);
550
551 sub->sub_dot1ad = mp->sub_dot1ad;
552 sub->sub_number_of_tags = mp->sub_number_of_tags;
553 sub->sub_outer_vlan_id = ntohs(mp->sub_outer_vlan_id);
554 sub->sub_inner_vlan_id = ntohs(mp->sub_inner_vlan_id);
555 sub->sub_exact_match = mp->sub_exact_match;
556 sub->sub_default = mp->sub_default;
557 sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
558 sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
559
560 /* vlan tag rewrite */
561 sub->vtr_op = ntohl(mp->vtr_op);
562 sub->vtr_push_dot1q = ntohl(mp->vtr_push_dot1q);
563 sub->vtr_tag1 = ntohl(mp->vtr_tag1);
564 sub->vtr_tag2 = ntohl(mp->vtr_tag2);
565 }
566}
567
568static void vl_api_sw_interface_details_t_handler_json
569(vl_api_sw_interface_details_t * mp)
570{
571 vat_main_t * vam = &vat_main;
572 vat_json_node_t *node = NULL;
573
574 if (VAT_JSON_ARRAY != vam->json_tree.type) {
575 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
576 vat_json_init_array(&vam->json_tree);
577 }
578 node = vat_json_array_add(&vam->json_tree);
579
580 vat_json_init_object(node);
581 vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
582 vat_json_object_add_uint(node, "sup_sw_if_index", ntohl(mp->sup_sw_if_index));
583 vat_json_object_add_uint(node, "l2_address_length", ntohl(mp->l2_address_length));
584 vat_json_object_add_bytes(node, "l2_address", mp->l2_address, sizeof(mp->l2_address));
585 vat_json_object_add_string_copy(node, "interface_name", mp->interface_name);
586 vat_json_object_add_uint(node, "admin_up_down", mp->admin_up_down);
587 vat_json_object_add_uint(node, "link_up_down", mp->link_up_down);
588 vat_json_object_add_uint(node, "link_duplex", mp->link_duplex);
589 vat_json_object_add_uint(node, "link_speed", mp->link_speed);
590 vat_json_object_add_uint(node, "sub_id", ntohl(mp->sub_id));
591 vat_json_object_add_uint(node, "sub_dot1ad", mp->sub_dot1ad);
592 vat_json_object_add_uint(node, "sub_number_of_tags", mp->sub_number_of_tags);
593 vat_json_object_add_uint(node, "sub_outer_vlan_id", ntohs(mp->sub_outer_vlan_id));
594 vat_json_object_add_uint(node, "sub_inner_vlan_id", ntohs(mp->sub_inner_vlan_id));
595 vat_json_object_add_uint(node, "sub_exact_match", mp->sub_exact_match);
596 vat_json_object_add_uint(node, "sub_default", mp->sub_default);
597 vat_json_object_add_uint(node, "sub_outer_vlan_id_any", mp->sub_outer_vlan_id_any);
598 vat_json_object_add_uint(node, "sub_inner_vlan_id_any", mp->sub_inner_vlan_id_any);
599 vat_json_object_add_uint(node, "vtr_op", ntohl(mp->vtr_op));
600 vat_json_object_add_uint(node, "vtr_push_dot1q", ntohl(mp->vtr_push_dot1q));
601 vat_json_object_add_uint(node, "vtr_tag1", ntohl(mp->vtr_tag1));
602 vat_json_object_add_uint(node, "vtr_tag2", ntohl(mp->vtr_tag2));
603}
604
605static void vl_api_sw_interface_set_flags_t_handler
606(vl_api_sw_interface_set_flags_t * mp)
607{
608 vat_main_t * vam = &vat_main;
609 if (vam->interface_event_display)
610 errmsg ("interface flags: sw_if_index %d %s %s\n",
611 ntohl(mp->sw_if_index),
612 mp->admin_up_down ? "admin-up" : "admin-down",
613 mp->link_up_down ? "link-up" : "link-down");
614}
615
616static void vl_api_sw_interface_set_flags_t_handler_json
617(vl_api_sw_interface_set_flags_t * mp)
618{
619 /* JSON output not supported */
620}
621
622static void vl_api_cli_reply_t_handler
623(vl_api_cli_reply_t * mp)
624{
625 vat_main_t * vam = &vat_main;
626 i32 retval = ntohl(mp->retval);
627
628 vam->retval = retval;
629 vam->shmem_result = (u8 *) mp->reply_in_shmem;
630 vam->result_ready = 1;
631}
632
633static void vl_api_cli_reply_t_handler_json
634(vl_api_cli_reply_t * mp)
635{
636 vat_main_t * vam = &vat_main;
637 vat_json_node_t node;
Dave Barachb44e9bc2016-02-19 09:06:23 -0500638 api_main_t * am = &api_main;
639 void * oldheap;
640 u8 * reply;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700641
642 vat_json_init_object(&node);
643 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
Dave Barachb44e9bc2016-02-19 09:06:23 -0500644 vat_json_object_add_uint(&node, "reply_in_shmem",
645 ntohl(mp->reply_in_shmem));
646 /* Toss the shared-memory original... */
647 pthread_mutex_lock (&am->vlib_rp->mutex);
648 oldheap = svm_push_data_heap (am->vlib_rp);
649
650 reply = (u8 *)(mp->reply_in_shmem);
651 vec_free (reply);
652
653 svm_pop_heap (oldheap);
654 pthread_mutex_unlock (&am->vlib_rp->mutex);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700655
656 vat_json_print(vam->ofp, &node);
657 vat_json_free(&node);
658
659 vam->retval = ntohl(mp->retval);
660 vam->result_ready = 1;
661}
662
663static void vl_api_classify_add_del_table_reply_t_handler
664(vl_api_classify_add_del_table_reply_t * mp)
665{
666 vat_main_t * vam = &vat_main;
667 i32 retval = ntohl(mp->retval);
668 if (vam->async_mode) {
669 vam->async_errors += (retval < 0);
670 } else {
671 vam->retval = retval;
672 vam->result_ready = 1;
673 if (retval == 0 &&
674 ((mp->new_table_index != 0xFFFFFFFF) ||
675 (mp->skip_n_vectors != 0xFFFFFFFF) ||
676 (mp->match_n_vectors != 0xFFFFFFFF)))
677 /*
678 * Note: this is just barely thread-safe, depends on
679 * the main thread spinning waiting for an answer...
680 */
681 errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d\n",
682 ntohl(mp->new_table_index),
683 ntohl(mp->skip_n_vectors), ntohl(mp->match_n_vectors));
684 }
685}
686
687static void vl_api_classify_add_del_table_reply_t_handler_json
688(vl_api_classify_add_del_table_reply_t * mp)
689{
690 vat_main_t * vam = &vat_main;
691 vat_json_node_t node;
692
693 vat_json_init_object(&node);
694 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
695 vat_json_object_add_uint(&node, "new_table_index", ntohl(mp->new_table_index));
696 vat_json_object_add_uint(&node, "skip_n_vectors", ntohl(mp->skip_n_vectors));
697 vat_json_object_add_uint(&node, "match_n_vectors", ntohl(mp->match_n_vectors));
698
699 vat_json_print(vam->ofp, &node);
700 vat_json_free(&node);
701
702 vam->retval = ntohl(mp->retval);
703 vam->result_ready = 1;
704}
705
706static void vl_api_get_node_index_reply_t_handler
707(vl_api_get_node_index_reply_t * mp)
708{
709 vat_main_t * vam = &vat_main;
710 i32 retval = ntohl(mp->retval);
711 if (vam->async_mode) {
712 vam->async_errors += (retval < 0);
713 } else {
714 vam->retval = retval;
715 vam->result_ready = 1;
716 if (retval == 0)
717 errmsg ("node index %d\n", ntohl(mp->node_index));
718 }
719}
720
721static void vl_api_get_node_index_reply_t_handler_json
722(vl_api_get_node_index_reply_t * mp)
723{
724 vat_main_t * vam = &vat_main;
725 vat_json_node_t node;
726
727 vat_json_init_object(&node);
728 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
729 vat_json_object_add_uint(&node, "node_index", ntohl(mp->node_index));
730
731 vat_json_print(vam->ofp, &node);
732 vat_json_free(&node);
733
734 vam->retval = ntohl(mp->retval);
735 vam->result_ready = 1;
736}
737
738static void vl_api_add_node_next_reply_t_handler
739(vl_api_add_node_next_reply_t * mp)
740{
741 vat_main_t * vam = &vat_main;
742 i32 retval = ntohl(mp->retval);
743 if (vam->async_mode) {
744 vam->async_errors += (retval < 0);
745 } else {
746 vam->retval = retval;
747 vam->result_ready = 1;
748 if (retval == 0)
749 errmsg ("next index %d\n", ntohl(mp->next_index));
750 }
751}
752
753static void vl_api_add_node_next_reply_t_handler_json
754(vl_api_add_node_next_reply_t * mp)
755{
756 vat_main_t * vam = &vat_main;
757 vat_json_node_t node;
758
759 vat_json_init_object(&node);
760 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
761 vat_json_object_add_uint(&node, "next_index", ntohl(mp->next_index));
762
763 vat_json_print(vam->ofp, &node);
764 vat_json_free(&node);
765
766 vam->retval = ntohl(mp->retval);
767 vam->result_ready = 1;
768}
769
770static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler
771(vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
772{
773 vat_main_t * vam = &vat_main;
774 i32 retval = ntohl(mp->retval);
775 u32 sw_if_index = ntohl(mp->tunnel_sw_if_index);
776
777 if (retval >= 0 && sw_if_index != (u32)~0) {
778 errmsg ("tunnel_sw_if_index %d\n", sw_if_index);
779 }
780 vam->retval = retval;
781 vam->result_ready = 1;
782}
783
784static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler_json
785(vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
786{
787 vat_main_t * vam = &vat_main;
788 vat_json_node_t node;
789
790 vat_json_init_object(&node);
791 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
792 vat_json_object_add_uint(&node, "tunnel_sw_if_index", ntohl(mp->tunnel_sw_if_index));
793
794 vat_json_print(vam->ofp, &node);
795 vat_json_free(&node);
796
797 vam->retval = ntohl(mp->retval);
798 vam->result_ready = 1;
799}
800
801static void vl_api_nsh_gre_add_del_tunnel_reply_t_handler
802(vl_api_nsh_gre_add_del_tunnel_reply_t * mp)
803{
804 vat_main_t * vam = &vat_main;
805 i32 retval = ntohl(mp->retval);
806 u32 sw_if_index = ntohl(mp->sw_if_index);
807
808 if (retval >= 0 && sw_if_index != (u32)~0) {
809 errmsg ("sw_if_index %d\n", ntohl(mp->sw_if_index));
810 }
811 vam->retval = retval;
812 vam->result_ready = 1;
813}
814
815static void vl_api_nsh_gre_add_del_tunnel_reply_t_handler_json
816(vl_api_nsh_gre_add_del_tunnel_reply_t * mp)
817{
818 vat_main_t * vam = &vat_main;
819 vat_json_node_t node;
820
821 vat_json_init_object(&node);
822 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
823 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
824
825 vat_json_print(vam->ofp, &node);
826 vat_json_free(&node);
827
828 vam->retval = ntohl(mp->retval);
829 vam->result_ready = 1;
830}
831
832static void vl_api_nsh_vxlan_gpe_add_del_tunnel_reply_t_handler
833(vl_api_nsh_vxlan_gpe_add_del_tunnel_reply_t * mp)
834{
835 vat_main_t * vam = &vat_main;
836 i32 retval = ntohl(mp->retval);
837 u32 sw_if_index = ntohl(mp->sw_if_index);
838
839 if (retval >= 0 && sw_if_index != (u32)~0) {
840 errmsg ("sw_if_index %d\n", ntohl(mp->sw_if_index));
841 }
842 vam->retval = retval;
843 vam->result_ready = 1;
844}
845
846static void vl_api_nsh_vxlan_gpe_add_del_tunnel_reply_t_handler_json
847(vl_api_nsh_vxlan_gpe_add_del_tunnel_reply_t * mp)
848{
849 vat_main_t * vam = &vat_main;
850 vat_json_node_t node;
851
852 vat_json_init_object(&node);
853 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
854 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
855
856 vat_json_print(vam->ofp, &node);
857 vat_json_free(&node);
858
859 vam->retval = ntohl(mp->retval);
860 vam->result_ready = 1;
861}
862
863static void vl_api_lisp_gpe_add_del_tunnel_reply_t_handler
864(vl_api_lisp_gpe_add_del_tunnel_reply_t * mp)
865{
866 vat_main_t * vam = &vat_main;
867 i32 retval = ntohl(mp->retval);
868 u32 sw_if_index = ntohl(mp->sw_if_index);
869
870 if (retval >= 0 && sw_if_index != (u32)~0) {
871 errmsg ("sw_if_index %d\n", ntohl(mp->sw_if_index));
872 }
873 vam->retval = retval;
874 vam->result_ready = 1;
875}
876
877static void vl_api_lisp_gpe_add_del_tunnel_reply_t_handler_json
878(vl_api_lisp_gpe_add_del_tunnel_reply_t * mp)
879{
880 vat_main_t * vam = &vat_main;
881 vat_json_node_t node;
882
883 vat_json_init_object(&node);
884 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
885 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
886
887 vat_json_print(vam->ofp, &node);
888 vat_json_free(&node);
889
890 vam->retval = ntohl(mp->retval);
891 vam->result_ready = 1;
892}
893
894static void vl_api_show_version_reply_t_handler
895(vl_api_show_version_reply_t * mp)
896{
897 vat_main_t * vam = &vat_main;
898 i32 retval = ntohl(mp->retval);
899
900 if (retval >= 0) {
901 errmsg (" program: %s\n", mp->program);
Damjan Mariona0d4a1a2015-12-12 14:40:59 +0100902 errmsg (" version: %s\n", mp->version);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700903 errmsg (" build date: %s\n", mp->build_date);
904 errmsg ("build directory: %s\n", mp->build_directory);
905 }
906 vam->retval = retval;
907 vam->result_ready = 1;
908}
909
910static void vl_api_show_version_reply_t_handler_json
911(vl_api_show_version_reply_t * mp)
912{
913 vat_main_t * vam = &vat_main;
914 vat_json_node_t node;
915
916 vat_json_init_object(&node);
917 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
918 vat_json_object_add_string_copy(&node, "program", mp->program);
Damjan Mariona0d4a1a2015-12-12 14:40:59 +0100919 vat_json_object_add_string_copy(&node, "version", mp->version);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700920 vat_json_object_add_string_copy(&node, "build_date", mp->build_date);
921 vat_json_object_add_string_copy(&node, "build_directory", mp->build_directory);
922
923 vat_json_print(vam->ofp, &node);
924 vat_json_free(&node);
925
926 vam->retval = ntohl(mp->retval);
927 vam->result_ready = 1;
928}
929
930static void vl_api_ip4_arp_event_t_handler
931(vl_api_ip4_arp_event_t * mp)
932{
933 vat_main_t * vam = &vat_main;
934 errmsg ("arp event: address %U new mac %U sw_if_index %d\n",
935 format_ip4_address, &mp->address,
936 format_ethernet_address, mp->new_mac, mp->sw_if_index);
937}
938
939static void vl_api_ip4_arp_event_t_handler_json
940(vl_api_ip4_arp_event_t * mp)
941{
942 /* JSON output not supported */
943}
944
945/*
946 * Special-case: build the bridge domain table, maintain
947 * the next bd id vbl.
948 */
949static void vl_api_bridge_domain_details_t_handler
950(vl_api_bridge_domain_details_t * mp)
951{
952 vat_main_t * vam = &vat_main;
953 u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
954
955 fformat (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s\n",
956 " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
957
958 fformat (vam->ofp, "%3d %3d %3d %3d %3d %3d\n",
959 ntohl (mp->bd_id), mp->learn, mp->forward,
960 mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
961
962 if (n_sw_ifs)
963 fformat (vam->ofp, "\n\n%s %s %s\n", "sw_if_index", "SHG",
964 "Interface Name");
965}
966
967static void vl_api_bridge_domain_details_t_handler_json
968(vl_api_bridge_domain_details_t * mp)
969{
970 vat_main_t * vam = &vat_main;
971 vat_json_node_t *node, *array = NULL;
972
973 if (VAT_JSON_ARRAY != vam->json_tree.type) {
974 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
975 vat_json_init_array(&vam->json_tree);
976 }
977 node = vat_json_array_add(&vam->json_tree);
978
979 vat_json_init_object(node);
980 vat_json_object_add_uint(node, "bd_id", ntohl(mp->bd_id));
981 vat_json_object_add_uint(node, "flood", mp->flood);
982 vat_json_object_add_uint(node, "forward", mp->forward);
983 vat_json_object_add_uint(node, "learn", mp->learn);
984 vat_json_object_add_uint(node, "bvi_sw_if_index", ntohl(mp->bvi_sw_if_index));
985 vat_json_object_add_uint(node, "n_sw_ifs", ntohl(mp->n_sw_ifs));
986 array = vat_json_object_add(node, "sw_if");
987 vat_json_init_array(array);
988}
989
990/*
991 * Special-case: build the bridge domain sw if table.
992 */
993static void vl_api_bridge_domain_sw_if_details_t_handler
994(vl_api_bridge_domain_sw_if_details_t * mp)
995{
996 vat_main_t * vam = &vat_main;
997 hash_pair_t * p;
998 u8 * sw_if_name = 0;
999 u32 sw_if_index;
1000
1001 sw_if_index = ntohl (mp->sw_if_index);
1002 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1003 ({
1004 if ((u32) p->value[0] == sw_if_index) {
1005 sw_if_name = (u8 *)(p->key);
1006 break;
1007 }
1008 }));
1009
1010 fformat (vam->ofp, "%7d %3d %s", sw_if_index,
1011 mp->shg, sw_if_name ? (char *)sw_if_name :
1012 "sw_if_index not found!");
1013}
1014
1015static void vl_api_bridge_domain_sw_if_details_t_handler_json
1016(vl_api_bridge_domain_sw_if_details_t * mp)
1017{
1018 vat_main_t * vam = &vat_main;
1019 vat_json_node_t *node = NULL;
1020 uword last_index = 0;
1021
1022 ASSERT(VAT_JSON_ARRAY == vam->json_tree.type);
1023 ASSERT(vec_len(vam->json_tree.array) >= 1);
1024 last_index = vec_len(vam->json_tree.array) - 1;
1025 node = &vam->json_tree.array[last_index];
1026 node = vat_json_object_get_element(node, "sw_if");
1027 ASSERT(NULL != node);
1028 node = vat_json_array_add(node);
1029
1030 vat_json_init_object(node);
1031 vat_json_object_add_uint(node, "bd_id", ntohl(mp->bd_id));
1032 vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
1033 vat_json_object_add_uint(node, "shg", mp->shg);
1034}
1035
1036static void vl_api_control_ping_reply_t_handler
1037(vl_api_control_ping_reply_t * mp)
1038{
1039 vat_main_t * vam = &vat_main;
1040 i32 retval = ntohl(mp->retval);
1041 if (vam->async_mode) {
1042 vam->async_errors += (retval < 0);
1043 } else {
1044 vam->retval = retval;
1045 vam->result_ready = 1;
1046 }
1047}
1048
1049static void vl_api_control_ping_reply_t_handler_json
1050(vl_api_control_ping_reply_t * mp)
1051{
1052 vat_main_t * vam = &vat_main;
1053 i32 retval = ntohl(mp->retval);
1054
1055 if (VAT_JSON_NONE != vam->json_tree.type) {
1056 vat_json_print(vam->ofp, &vam->json_tree);
1057 vat_json_free(&vam->json_tree);
1058 vam->json_tree.type = VAT_JSON_NONE;
1059 } else {
1060 /* just print [] */
1061 vat_json_init_array(&vam->json_tree);
1062 vat_json_print(vam->ofp, &vam->json_tree);
1063 vam->json_tree.type = VAT_JSON_NONE;
1064 }
1065
1066 vam->retval = retval;
1067 vam->result_ready = 1;
1068}
1069
1070static void vl_api_l2_flags_reply_t_handler
1071(vl_api_l2_flags_reply_t * mp)
1072{
1073 vat_main_t * vam = &vat_main;
1074 i32 retval = ntohl(mp->retval);
1075 if (vam->async_mode) {
1076 vam->async_errors += (retval < 0);
1077 } else {
1078 vam->retval = retval;
1079 vam->result_ready = 1;
1080 }
1081}
1082
1083static void vl_api_l2_flags_reply_t_handler_json
1084(vl_api_l2_flags_reply_t * mp)
1085{
1086 vat_main_t * vam = &vat_main;
1087 vat_json_node_t node;
1088
1089 vat_json_init_object(&node);
1090 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1091 vat_json_object_add_uint(&node, "resulting_feature_bitmap", ntohl(mp->resulting_feature_bitmap));
1092
1093 vat_json_print(vam->ofp, &node);
1094 vat_json_free(&node);
1095
1096 vam->retval = ntohl(mp->retval);
1097 vam->result_ready = 1;
1098}
1099
1100static void vl_api_bridge_flags_reply_t_handler
1101(vl_api_bridge_flags_reply_t * mp)
1102{
1103 vat_main_t * vam = &vat_main;
1104 i32 retval = ntohl(mp->retval);
1105 if (vam->async_mode) {
1106 vam->async_errors += (retval < 0);
1107 } else {
1108 vam->retval = retval;
1109 vam->result_ready = 1;
1110 }
1111}
1112
1113static void vl_api_bridge_flags_reply_t_handler_json
1114(vl_api_bridge_flags_reply_t * mp)
1115{
1116 vat_main_t * vam = &vat_main;
1117 vat_json_node_t node;
1118
1119 vat_json_init_object(&node);
1120 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1121 vat_json_object_add_uint(&node, "resulting_feature_bitmap", ntohl(mp->resulting_feature_bitmap));
1122
1123 vat_json_print(vam->ofp, &node);
1124 vat_json_free(&node);
1125
1126 vam->retval = ntohl(mp->retval);
1127 vam->result_ready = 1;
1128}
1129
1130static void vl_api_tap_connect_reply_t_handler
1131(vl_api_tap_connect_reply_t * mp)
1132{
1133 vat_main_t * vam = &vat_main;
1134 i32 retval = ntohl(mp->retval);
1135 if (vam->async_mode) {
1136 vam->async_errors += (retval < 0);
1137 } else {
1138 vam->retval = retval;
1139 vam->result_ready = 1;
1140 }
1141}
1142
1143static void vl_api_tap_connect_reply_t_handler_json
1144(vl_api_tap_connect_reply_t * mp)
1145{
1146 vat_main_t * vam = &vat_main;
1147 vat_json_node_t node;
1148
1149 vat_json_init_object(&node);
1150 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1151 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
1152
1153 vat_json_print(vam->ofp, &node);
1154 vat_json_free(&node);
1155
1156 vam->retval = ntohl(mp->retval);
1157 vam->result_ready = 1;
1158}
1159
1160static void vl_api_tap_modify_reply_t_handler
1161(vl_api_tap_modify_reply_t * mp)
1162{
1163 vat_main_t * vam = &vat_main;
1164 i32 retval = ntohl(mp->retval);
1165 if (vam->async_mode) {
1166 vam->async_errors += (retval < 0);
1167 } else {
1168 vam->retval = retval;
1169 vam->result_ready = 1;
1170 }
1171}
1172
1173static void vl_api_tap_modify_reply_t_handler_json
1174(vl_api_tap_modify_reply_t * mp)
1175{
1176 vat_main_t * vam = &vat_main;
1177 vat_json_node_t node;
1178
1179 vat_json_init_object(&node);
1180 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1181 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
1182
1183 vat_json_print(vam->ofp, &node);
1184 vat_json_free(&node);
1185
1186 vam->retval = ntohl(mp->retval);
1187 vam->result_ready = 1;
1188}
1189
1190static void vl_api_tap_delete_reply_t_handler
1191(vl_api_tap_delete_reply_t * mp)
1192{
1193 vat_main_t * vam = &vat_main;
1194 i32 retval = ntohl(mp->retval);
1195 if (vam->async_mode) {
1196 vam->async_errors += (retval < 0);
1197 } else {
1198 vam->retval = retval;
1199 vam->result_ready = 1;
1200 }
1201}
1202
1203static void vl_api_tap_delete_reply_t_handler_json
1204(vl_api_tap_delete_reply_t * mp)
1205{
1206 vat_main_t * vam = &vat_main;
1207 vat_json_node_t node;
1208
1209 vat_json_init_object(&node);
1210 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1211
1212 vat_json_print(vam->ofp, &node);
1213 vat_json_free(&node);
1214
1215 vam->retval = ntohl(mp->retval);
1216 vam->result_ready = 1;
1217}
1218
1219static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler
1220(vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1221{
1222 vat_main_t * vam = &vat_main;
1223 i32 retval = ntohl(mp->retval);
1224 if (vam->async_mode) {
1225 vam->async_errors += (retval < 0);
1226 } else {
1227 vam->retval = retval;
1228 vam->result_ready = 1;
1229 }
1230}
1231
1232static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler_json
1233(vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1234{
1235 vat_main_t * vam = &vat_main;
1236 vat_json_node_t node;
1237
1238 vat_json_init_object(&node);
1239 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1240 vat_json_object_add_uint(&node, "tunnel_sw_if_index", ntohl(mp->tunnel_sw_if_index));
1241
1242 vat_json_print(vam->ofp, &node);
1243 vat_json_free(&node);
1244
1245 vam->retval = ntohl(mp->retval);
1246 vam->result_ready = 1;
1247}
1248
1249static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1250(vl_api_l2tpv3_create_tunnel_reply_t * mp)
1251{
1252 vat_main_t * vam = &vat_main;
1253 i32 retval = ntohl(mp->retval);
1254 if (vam->async_mode) {
1255 vam->async_errors += (retval < 0);
1256 } else {
1257 vam->retval = retval;
1258 vam->result_ready = 1;
1259 }
1260}
1261
1262static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1263(vl_api_l2tpv3_create_tunnel_reply_t * mp)
1264{
1265 vat_main_t * vam = &vat_main;
1266 vat_json_node_t node;
1267
1268 vat_json_init_object(&node);
1269 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1270 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
1271
1272 vat_json_print(vam->ofp, &node);
1273 vat_json_free(&node);
1274
1275 vam->retval = ntohl(mp->retval);
1276 vam->result_ready = 1;
1277}
1278
1279static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1280(vl_api_vxlan_add_del_tunnel_reply_t * mp)
1281{
1282 vat_main_t * vam = &vat_main;
1283 i32 retval = ntohl(mp->retval);
1284 if (vam->async_mode) {
1285 vam->async_errors += (retval < 0);
1286 } else {
1287 vam->retval = retval;
1288 vam->result_ready = 1;
1289 }
1290}
1291
1292static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1293(vl_api_vxlan_add_del_tunnel_reply_t * mp)
1294{
1295 vat_main_t * vam = &vat_main;
1296 vat_json_node_t node;
1297
1298 vat_json_init_object(&node);
1299 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1300 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
1301
1302 vat_json_print(vam->ofp, &node);
1303 vat_json_free(&node);
1304
1305 vam->retval = ntohl(mp->retval);
1306 vam->result_ready = 1;
1307}
1308
1309static void vl_api_create_vhost_user_if_reply_t_handler
1310(vl_api_create_vhost_user_if_reply_t * mp)
1311{
1312 vat_main_t * vam = &vat_main;
1313 i32 retval = ntohl(mp->retval);
1314 if (vam->async_mode) {
1315 vam->async_errors += (retval < 0);
1316 } else {
1317 vam->retval = retval;
1318 vam->result_ready = 1;
1319 }
1320}
1321
1322static void vl_api_create_vhost_user_if_reply_t_handler_json
1323(vl_api_create_vhost_user_if_reply_t * mp)
1324{
1325 vat_main_t * vam = &vat_main;
1326 vat_json_node_t node;
1327
1328 vat_json_init_object(&node);
1329 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1330 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
1331
1332 vat_json_print(vam->ofp, &node);
1333 vat_json_free(&node);
1334
1335 vam->retval = ntohl(mp->retval);
1336 vam->result_ready = 1;
1337}
1338
1339static void vl_api_ip_address_details_t_handler
1340(vl_api_ip_address_details_t * mp)
1341{
1342 vat_main_t * vam = &vat_main;
1343 static ip_address_details_t empty_ip_address_details = {{0}};
1344 ip_address_details_t * address = NULL;
1345 ip_details_t * current_ip_details = NULL;
1346 ip_details_t * details = NULL;
1347
1348 details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1349
1350 if (!details || vam->current_sw_if_index >= vec_len(details)
1351 || !details[vam->current_sw_if_index].present) {
1352 errmsg ("ip address details arrived but not stored\n");
1353 errmsg ("ip_dump should be called first\n");
1354 return;
1355 }
1356
1357 current_ip_details = vec_elt_at_index(details,
1358 vam->current_sw_if_index);
1359
1360#define addresses (current_ip_details->addr)
1361
1362 vec_validate_init_empty(addresses, vec_len(addresses),
1363 empty_ip_address_details);
1364
1365 address = vec_elt_at_index(addresses, vec_len(addresses) - 1);
1366
1367 memcpy(&address->ip, &mp->ip, sizeof(address->ip));
1368 address->prefix_length = mp->prefix_length;
1369#undef addresses
1370}
1371
1372static void vl_api_ip_address_details_t_handler_json
1373(vl_api_ip_address_details_t * mp)
1374{
1375 vat_main_t * vam = &vat_main;
1376 vat_json_node_t *node = NULL;
1377 struct in6_addr ip6;
1378 struct in_addr ip4;
1379
1380 if (VAT_JSON_ARRAY != vam->json_tree.type) {
1381 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
1382 vat_json_init_array(&vam->json_tree);
1383 }
1384 node = vat_json_array_add(&vam->json_tree);
1385
1386 vat_json_init_object(node);
1387 if (vam->is_ipv6) {
1388 memcpy(&ip6, mp->ip, sizeof(ip6));
1389 vat_json_object_add_ip6(node, "ip", ip6);
1390 } else {
1391 memcpy(&ip4, mp->ip, sizeof(ip4));
1392 vat_json_object_add_ip4(node, "ip", ip4);
1393 }
1394 vat_json_object_add_uint(node, "prefix_length", mp->prefix_length);
1395}
1396
1397static void vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1398{
1399 vat_main_t * vam = &vat_main;
1400 static ip_details_t empty_ip_details = {0};
1401 ip_details_t * ip = NULL;
1402 u32 sw_if_index = ~0;
1403
1404 sw_if_index = ntohl(mp->sw_if_index);
1405
1406 vec_validate_init_empty(vam->ip_details_by_sw_if_index[vam->is_ipv6],
1407 sw_if_index, empty_ip_details);
1408
1409 ip = vec_elt_at_index(vam->ip_details_by_sw_if_index[vam->is_ipv6],
1410 sw_if_index);
1411
1412 ip->present = 1;
1413}
1414
1415static void vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1416{
1417 vat_main_t * vam = &vat_main;
1418
1419 if (VAT_JSON_ARRAY != vam->json_tree.type) {
1420 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
1421 vat_json_init_array(&vam->json_tree);
1422 }
1423 vat_json_array_add_uint(&vam->json_tree, clib_net_to_host_u32(mp->sw_if_index));
1424}
1425
1426static void vl_api_map_domain_details_t_handler_json
1427(vl_api_map_domain_details_t * mp)
1428{
1429 vat_json_node_t * node = NULL;
1430 vat_main_t * vam = &vat_main;
1431 struct in6_addr ip6;
1432 struct in_addr ip4;
1433
1434 if (VAT_JSON_ARRAY != vam->json_tree.type) {
1435 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
1436 vat_json_init_array(&vam->json_tree);
1437 }
1438
1439 node = vat_json_array_add(&vam->json_tree);
1440 vat_json_init_object(node);
1441
1442 vat_json_object_add_uint(node, "domain_index", clib_net_to_host_u32(mp->domain_index));
1443 memcpy(&ip6, mp->ip6_prefix, sizeof(ip6));
1444 vat_json_object_add_ip6(node, "ip6_prefix", ip6);
1445 memcpy(&ip4, mp->ip4_prefix, sizeof(ip4));
1446 vat_json_object_add_ip4(node, "ip4_prefix", ip4);
1447 memcpy(&ip6, mp->ip6_src, sizeof(ip6));
1448 vat_json_object_add_ip6(node, "ip6_src", ip6);
1449 vat_json_object_add_int(node, "ip6_prefix_len", mp->ip6_prefix_len);
1450 vat_json_object_add_int(node, "ip4_prefix_len", mp->ip4_prefix_len);
1451 vat_json_object_add_int(node, "ip6_src_len", mp->ip6_src_len);
1452 vat_json_object_add_int(node, "ea_bits_len", mp->ea_bits_len);
1453 vat_json_object_add_int(node, "psid_offset", mp->psid_offset);
1454 vat_json_object_add_int(node, "psid_length", mp->psid_length);
1455 vat_json_object_add_uint(node, "flags", mp->flags);
1456 vat_json_object_add_uint(node, "mtu", clib_net_to_host_u16(mp->mtu));
1457 vat_json_object_add_int(node, "is_translation", mp->is_translation);
1458}
1459
1460static void vl_api_map_domain_details_t_handler
1461(vl_api_map_domain_details_t * mp)
1462{
1463 vat_main_t * vam = &vat_main;
1464
1465 if (mp->is_translation) {
1466 fformat(vam->ofp, "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u\n",
1467 format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1468 format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1469 format_ip6_address, mp->ip6_src, mp->ip6_src_len, clib_net_to_host_u32(mp->domain_index));
1470 } else {
1471 fformat(vam->ofp, "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u\n",
1472 format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1473 format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1474 format_ip6_address, mp->ip6_src, clib_net_to_host_u32(mp->domain_index));
1475 }
1476 fformat(vam->ofp, " ea-len %d psid-offset %d psid-len %d mtu %d %s\n",
1477 mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu, mp->is_translation? "map-t":"");
1478}
1479
1480static void vl_api_map_rule_details_t_handler_json
1481(vl_api_map_rule_details_t * mp)
1482{
1483 struct in6_addr ip6;
1484 vat_json_node_t * node = NULL;
1485 vat_main_t * vam = &vat_main;
1486
1487 if (VAT_JSON_ARRAY != vam->json_tree.type) {
1488 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
1489 vat_json_init_array(&vam->json_tree);
1490 }
1491
1492 node = vat_json_array_add(&vam->json_tree);
1493 vat_json_init_object(node);
1494
1495 vat_json_object_add_uint(node, "psid", clib_net_to_host_u16(mp->psid));
1496 memcpy(&ip6, mp->ip6_dst, sizeof(ip6));
1497 vat_json_object_add_ip6(node, "ip6_dst", ip6);
1498}
1499
1500static void vl_api_map_rule_details_t_handler
1501(vl_api_map_rule_details_t * mp)
1502{
1503 vat_main_t * vam = &vat_main;
1504 fformat(vam->ofp, " %d (psid) %U (ip6-dst)\n", clib_net_to_host_u16(mp->psid),
1505 format_ip6_address, mp->ip6_dst);
1506}
1507
1508static void vl_api_dhcp_compl_event_t_handler
1509(vl_api_dhcp_compl_event_t * mp)
1510{
1511 vat_main_t * vam = &vat_main;
1512 errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1513 "router_addr %U host_mac %U\n",
1514 mp->pid, mp->is_ipv6 ? "ipv6":"ipv4", mp->hostname,
1515 format_ip4_address, &mp->host_address,
1516 format_ip4_address, &mp->router_address,
1517 format_ethernet_address, mp->host_mac);
1518}
1519
1520static void vl_api_dhcp_compl_event_t_handler_json
1521(vl_api_dhcp_compl_event_t * mp)
1522{
1523 /* JSON output not supported */
1524}
1525
1526static void set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1527 u32 counter)
1528{
1529 vat_main_t * vam = &vat_main;
1530 static u64 default_counter = 0;
1531
1532 vec_validate_init_empty(vam->simple_interface_counters, vnet_counter_type, NULL);
1533 vec_validate_init_empty(vam->simple_interface_counters[vnet_counter_type],
1534 sw_if_index, default_counter);
1535 vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1536}
1537
1538static void set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1539 interface_counter_t counter)
1540{
1541 vat_main_t * vam = &vat_main;
1542 static interface_counter_t default_counter = {0, };
1543
1544 vec_validate_init_empty(vam->combined_interface_counters, vnet_counter_type, NULL);
1545 vec_validate_init_empty(vam->combined_interface_counters[vnet_counter_type],
1546 sw_if_index, default_counter);
1547 vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1548}
1549
1550static void vl_api_vnet_interface_counters_t_handler
1551(vl_api_vnet_interface_counters_t *mp)
1552{
1553 /* not supported */
1554}
1555
1556static void vl_api_vnet_interface_counters_t_handler_json
1557(vl_api_vnet_interface_counters_t *mp)
1558{
1559 interface_counter_t counter;
1560 vlib_counter_t *v;
1561 u64 *v_packets;
1562 u64 packets;
1563 u32 count;
1564 u32 first_sw_if_index;
1565 int i;
1566
1567 count = ntohl(mp->count);
1568 first_sw_if_index = ntohl(mp->first_sw_if_index);
1569
1570 if (!mp->is_combined) {
1571 v_packets = (u64*)&mp->data;
1572 for (i = 0; i < count; i++) {
1573 packets = clib_net_to_host_u64(clib_mem_unaligned(v_packets, u64));
1574 set_simple_interface_counter(mp->vnet_counter_type,
1575 first_sw_if_index + i, packets);
1576 v_packets++;
1577 }
1578 } else {
1579 v = (vlib_counter_t*)&mp->data;
1580 for (i = 0; i < count; i++) {
1581 counter.packets = clib_net_to_host_u64(
1582 clib_mem_unaligned(&v->packets, u64));
1583 counter.bytes = clib_net_to_host_u64(
1584 clib_mem_unaligned(&v->bytes, u64));
1585 set_combined_interface_counter(mp->vnet_counter_type,
1586 first_sw_if_index + i, counter);
1587 v++;
1588 }
1589 }
1590}
1591
1592static u32 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1593{
1594 vat_main_t * vam = &vat_main;
1595 u32 i;
1596
1597 for (i = 0; i < vec_len(vam->ip4_fib_counters_vrf_id_by_index); i++) {
1598 if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id) {
1599 return i;
1600 }
1601 }
1602 return ~0;
1603}
1604
1605static u32 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1606{
1607 vat_main_t * vam = &vat_main;
1608 u32 i;
1609
1610 for (i = 0; i < vec_len(vam->ip6_fib_counters_vrf_id_by_index); i++) {
1611 if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id) {
1612 return i;
1613 }
1614 }
1615 return ~0;
1616}
1617
1618static void vl_api_vnet_ip4_fib_counters_t_handler
1619(vl_api_vnet_ip4_fib_counters_t *mp)
1620{
1621 /* not supported */
1622}
1623
1624static void vl_api_vnet_ip4_fib_counters_t_handler_json
1625(vl_api_vnet_ip4_fib_counters_t *mp)
1626{
1627 vat_main_t * vam = &vat_main;
1628 vl_api_ip4_fib_counter_t *v;
1629 ip4_fib_counter_t *counter;
1630 struct in_addr ip4;
1631 u32 vrf_id;
1632 u32 vrf_index;
1633 u32 count;
1634 int i;
1635
1636 vrf_id = ntohl(mp->vrf_id);
1637 vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id(vrf_id);
1638 if (~0 == vrf_index) {
1639 vrf_index = vec_len(vam->ip4_fib_counters_vrf_id_by_index);
1640 vec_validate(vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
1641 vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
1642 vec_validate(vam->ip4_fib_counters, vrf_index);
1643 vam->ip4_fib_counters[vrf_index] = NULL;
1644 }
1645
1646 vec_free(vam->ip4_fib_counters[vrf_index]);
1647 v = (vl_api_ip4_fib_counter_t*)&mp->c;
1648 count = ntohl(mp->count);
1649 for (i = 0; i < count; i++) {
1650 vec_validate(vam->ip4_fib_counters[vrf_index], i);
1651 counter = &vam->ip4_fib_counters[vrf_index][i];
1652 memcpy(&ip4, &v->address, sizeof(ip4));
1653 counter->address = ip4;
1654 counter->address_length = v->address_length;
1655 counter->packets = clib_net_to_host_u64(v->packets);
1656 counter->bytes = clib_net_to_host_u64(v->bytes);
1657 v++;
1658 }
1659}
1660
1661static void vl_api_vnet_ip6_fib_counters_t_handler
1662(vl_api_vnet_ip6_fib_counters_t *mp)
1663{
1664 /* not supported */
1665}
1666
1667static void vl_api_vnet_ip6_fib_counters_t_handler_json
1668(vl_api_vnet_ip6_fib_counters_t *mp)
1669{
1670 vat_main_t * vam = &vat_main;
1671 vl_api_ip6_fib_counter_t *v;
1672 ip6_fib_counter_t *counter;
1673 struct in6_addr ip6;
1674 u32 vrf_id;
1675 u32 vrf_index;
1676 u32 count;
1677 int i;
1678
1679 vrf_id = ntohl(mp->vrf_id);
1680 vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id(vrf_id);
1681 if (~0 == vrf_index) {
1682 vrf_index = vec_len(vam->ip6_fib_counters_vrf_id_by_index);
1683 vec_validate(vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
1684 vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
1685 vec_validate(vam->ip6_fib_counters, vrf_index);
1686 vam->ip6_fib_counters[vrf_index] = NULL;
1687 }
1688
1689 vec_free(vam->ip6_fib_counters[vrf_index]);
1690 v = (vl_api_ip6_fib_counter_t*)&mp->c;
1691 count = ntohl(mp->count);
1692 for (i = 0; i < count; i++) {
1693 vec_validate(vam->ip6_fib_counters[vrf_index], i);
1694 counter = &vam->ip6_fib_counters[vrf_index][i];
1695 memcpy(&ip6, &v->address, sizeof(ip6));
1696 counter->address = ip6;
1697 counter->address_length = v->address_length;
1698 counter->packets = clib_net_to_host_u64(v->packets);
1699 counter->bytes = clib_net_to_host_u64(v->bytes);
1700 v++;
1701 }
1702}
1703
1704static void vl_api_get_first_msg_id_reply_t_handler
1705(vl_api_get_first_msg_id_reply_t * mp)
1706{
1707 vat_main_t * vam = &vat_main;
1708 i32 retval = ntohl(mp->retval);
1709
1710 if (vam->async_mode) {
1711 vam->async_errors += (retval < 0);
1712 } else {
1713 vam->retval = retval;
1714 vam->result_ready = 1;
1715 }
1716 if (retval >= 0) {
1717 errmsg ("first message id %d\n", ntohs(mp->first_msg_id));
1718 }
1719}
1720
1721static void vl_api_get_first_msg_id_reply_t_handler_json
1722(vl_api_get_first_msg_id_reply_t * mp)
1723{
1724 vat_main_t * vam = &vat_main;
1725 vat_json_node_t node;
1726
1727 vat_json_init_object(&node);
1728 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1729 vat_json_object_add_uint(&node, "first_msg_id",
1730 (uint) ntohs(mp->first_msg_id));
1731
1732 vat_json_print(vam->ofp, &node);
1733 vat_json_free(&node);
1734
1735 vam->retval = ntohl(mp->retval);
1736 vam->result_ready = 1;
1737}
1738
Dave Barachb44e9bc2016-02-19 09:06:23 -05001739static void vl_api_get_node_graph_reply_t_handler
1740(vl_api_get_node_graph_reply_t * mp)
1741{
1742 vat_main_t * vam = &vat_main;
1743 api_main_t * am = &api_main;
1744 i32 retval = ntohl(mp->retval);
1745 u8 * pvt_copy, * reply;
1746 void * oldheap;
1747 vlib_node_t * node;
1748 int i;
1749
1750 if (vam->async_mode) {
1751 vam->async_errors += (retval < 0);
1752 } else {
1753 vam->retval = retval;
1754 vam->result_ready = 1;
1755 }
1756
1757 /* "Should never happen..." */
1758 if (retval != 0)
1759 return;
1760
1761 reply = (u8 *)(mp->reply_in_shmem);
1762 pvt_copy = vec_dup (reply);
1763
1764 /* Toss the shared-memory original... */
1765 pthread_mutex_lock (&am->vlib_rp->mutex);
1766 oldheap = svm_push_data_heap (am->vlib_rp);
1767
1768 vec_free (reply);
1769
1770 svm_pop_heap (oldheap);
1771 pthread_mutex_unlock (&am->vlib_rp->mutex);
1772
1773 if (vam->graph_nodes) {
1774 hash_free (vam->graph_node_index_by_name);
1775
1776 for (i = 0; i < vec_len (vam->graph_nodes); i++) {
1777 node = vam->graph_nodes[i];
1778 vec_free (node->name);
1779 vec_free (node->next_nodes);
1780 vec_free (node);
1781 }
1782 vec_free(vam->graph_nodes);
1783 }
1784
1785 vam->graph_node_index_by_name = hash_create_string (0, sizeof(uword));
1786 vam->graph_nodes = vlib_node_unserialize (pvt_copy);
1787 vec_free (pvt_copy);
1788
1789 for (i = 0; i < vec_len (vam->graph_nodes); i++) {
1790 node = vam->graph_nodes[i];
1791 hash_set_mem (vam->graph_node_index_by_name, node->name, i);
1792 }
1793}
1794
1795static void vl_api_get_node_graph_reply_t_handler_json
1796(vl_api_get_node_graph_reply_t * mp)
1797{
1798 vat_main_t * vam = &vat_main;
1799 api_main_t * am = &api_main;
1800 void * oldheap;
1801 vat_json_node_t node;
1802 u8 * reply;
1803
1804 /* $$$$ make this real? */
1805 vat_json_init_object(&node);
1806 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1807 vat_json_object_add_uint(&node, "reply_in_shmem", mp->reply_in_shmem);
1808
1809 reply = (u8 *)(mp->reply_in_shmem);
1810
1811 /* Toss the shared-memory original... */
1812 pthread_mutex_lock (&am->vlib_rp->mutex);
1813 oldheap = svm_push_data_heap (am->vlib_rp);
1814
1815 vec_free (reply);
1816
1817 svm_pop_heap (oldheap);
1818 pthread_mutex_unlock (&am->vlib_rp->mutex);
1819
1820 vat_json_print(vam->ofp, &node);
1821 vat_json_free(&node);
1822
1823 vam->retval = ntohl(mp->retval);
1824 vam->result_ready = 1;
1825}
1826
Ed Warnickecb9cada2015-12-08 15:45:58 -07001827#define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
1828#define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
1829#define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
1830#define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
1831
1832/*
1833 * Generate boilerplate reply handlers, which
1834 * dig the return value out of the xxx_reply_t API message,
1835 * stick it into vam->retval, and set vam->result_ready
1836 *
1837 * Could also do this by pointing N message decode slots at
1838 * a single function, but that could break in subtle ways.
1839 */
1840
1841#define foreach_standard_reply_retval_handler \
1842_(sw_interface_set_flags_reply) \
1843_(sw_interface_add_del_address_reply) \
1844_(sw_interface_set_table_reply) \
1845_(sw_interface_set_vpath_reply) \
1846_(sw_interface_set_l2_bridge_reply) \
1847_(bridge_domain_add_del_reply) \
1848_(sw_interface_set_l2_xconnect_reply) \
1849_(l2fib_add_del_reply) \
1850_(ip_add_del_route_reply) \
1851_(proxy_arp_add_del_reply) \
1852_(proxy_arp_intfc_enable_disable_reply) \
1853_(mpls_add_del_encap_reply) \
1854_(mpls_add_del_decap_reply) \
1855_(mpls_ethernet_add_del_tunnel_2_reply) \
1856_(sw_interface_set_unnumbered_reply) \
1857_(ip_neighbor_add_del_reply) \
1858_(reset_vrf_reply) \
1859_(oam_add_del_reply) \
1860_(reset_fib_reply) \
1861_(dhcp_proxy_config_reply) \
1862_(dhcp_proxy_config_2_reply) \
1863_(dhcp_proxy_set_vss_reply) \
1864_(dhcp_client_config_reply) \
1865_(set_ip_flow_hash_reply) \
1866_(sw_interface_ip6_enable_disable_reply) \
1867_(sw_interface_ip6_set_link_local_address_reply) \
1868_(sw_interface_ip6nd_ra_prefix_reply) \
1869_(sw_interface_ip6nd_ra_config_reply) \
1870_(set_arp_neighbor_limit_reply) \
1871_(l2_patch_add_del_reply) \
1872_(sr_tunnel_add_del_reply) \
1873_(classify_add_del_session_reply) \
1874_(classify_set_interface_ip_table_reply) \
1875_(classify_set_interface_l2_tables_reply) \
1876_(l2tpv3_set_tunnel_cookies_reply) \
1877_(l2tpv3_interface_enable_disable_reply) \
1878_(l2tpv3_set_lookup_key_reply) \
1879_(l2_fib_clear_table_reply) \
1880_(l2_interface_efp_filter_reply) \
1881_(l2_interface_vlan_tag_rewrite_reply) \
1882_(modify_vhost_user_if_reply) \
1883_(delete_vhost_user_if_reply) \
1884_(want_ip4_arp_events_reply) \
1885_(input_acl_set_interface_reply) \
1886_(ipsec_spd_add_del_reply) \
1887_(ipsec_interface_add_del_spd_reply) \
1888_(ipsec_spd_add_del_entry_reply) \
1889_(ipsec_sad_add_del_entry_reply) \
1890_(ipsec_sa_set_key_reply) \
1891_(delete_loopback_reply) \
1892_(bd_ip_mac_add_del_reply) \
1893_(map_del_domain_reply) \
1894_(map_add_del_rule_reply) \
1895_(want_interface_events_reply) \
Dave Barachc07bf5d2016-02-17 17:52:26 -05001896_(want_stats_reply) \
1897_(cop_interface_enable_disable_reply) \
1898_(cop_whitelist_enable_disable_reply)
Ed Warnickecb9cada2015-12-08 15:45:58 -07001899
1900#define _(n) \
1901 static void vl_api_##n##_t_handler \
1902 (vl_api_##n##_t * mp) \
1903 { \
1904 vat_main_t * vam = &vat_main; \
1905 i32 retval = ntohl(mp->retval); \
1906 if (vam->async_mode) { \
1907 vam->async_errors += (retval < 0); \
1908 } else { \
1909 vam->retval = retval; \
1910 vam->result_ready = 1; \
1911 } \
1912 }
1913foreach_standard_reply_retval_handler;
1914#undef _
1915
1916#define _(n) \
1917 static void vl_api_##n##_t_handler_json \
1918 (vl_api_##n##_t * mp) \
1919 { \
1920 vat_main_t * vam = &vat_main; \
1921 vat_json_node_t node; \
1922 vat_json_init_object(&node); \
1923 vat_json_object_add_int(&node, "retval", ntohl(mp->retval)); \
1924 vat_json_print(vam->ofp, &node); \
1925 vam->retval = ntohl(mp->retval); \
1926 vam->result_ready = 1; \
1927 }
1928foreach_standard_reply_retval_handler;
1929#undef _
1930
1931/*
1932 * Table of message reply handlers, must include boilerplate handlers
1933 * we just generated
1934 */
1935
1936#define foreach_vpe_api_reply_msg \
1937_(CREATE_LOOPBACK_REPLY, create_loopback_reply) \
1938_(SW_INTERFACE_DETAILS, sw_interface_details) \
1939_(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags) \
1940_(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply) \
1941_(CONTROL_PING_REPLY, control_ping_reply) \
1942_(CLI_REPLY, cli_reply) \
1943_(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY, \
1944 sw_interface_add_del_address_reply) \
1945_(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply) \
1946_(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply) \
1947_(SW_INTERFACE_SET_L2_XCONNECT_REPLY, \
1948 sw_interface_set_l2_xconnect_reply) \
1949_(SW_INTERFACE_SET_L2_BRIDGE_REPLY, \
1950 sw_interface_set_l2_bridge_reply) \
1951_(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply) \
1952_(BRIDGE_DOMAIN_DETAILS, bridge_domain_details) \
1953_(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details) \
1954_(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply) \
1955_(L2_FLAGS_REPLY, l2_flags_reply) \
1956_(BRIDGE_FLAGS_REPLY, bridge_flags_reply) \
1957_(TAP_CONNECT_REPLY, tap_connect_reply) \
1958_(TAP_MODIFY_REPLY, tap_modify_reply) \
1959_(TAP_DELETE_REPLY, tap_delete_reply) \
1960_(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details) \
1961_(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply) \
1962_(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply) \
1963_(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY, \
1964 proxy_arp_intfc_enable_disable_reply) \
1965_(MPLS_ADD_DEL_ENCAP_REPLY, mpls_add_del_encap_reply) \
1966_(MPLS_ADD_DEL_DECAP_REPLY, mpls_add_del_decap_reply) \
1967_(MPLS_GRE_ADD_DEL_TUNNEL_REPLY, mpls_gre_add_del_tunnel_reply) \
1968_(MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY, \
1969 mpls_ethernet_add_del_tunnel_reply) \
1970_(MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY, \
1971 mpls_ethernet_add_del_tunnel_2_reply) \
1972_(SW_INTERFACE_SET_UNNUMBERED_REPLY, \
1973 sw_interface_set_unnumbered_reply) \
1974_(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply) \
1975_(RESET_VRF_REPLY, reset_vrf_reply) \
1976_(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply) \
1977_(CREATE_SUBIF_REPLY, create_subif_reply) \
1978_(OAM_ADD_DEL_REPLY, oam_add_del_reply) \
1979_(RESET_FIB_REPLY, reset_fib_reply) \
1980_(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply) \
1981_(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply) \
1982_(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply) \
1983_(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply) \
1984_(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply) \
1985_(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY, \
1986 sw_interface_ip6_enable_disable_reply) \
1987_(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY, \
1988 sw_interface_ip6_set_link_local_address_reply) \
1989_(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY, \
1990 sw_interface_ip6nd_ra_prefix_reply) \
1991_(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY, \
1992 sw_interface_ip6nd_ra_config_reply) \
1993_(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply) \
1994_(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply) \
1995_(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply) \
1996_(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply) \
1997_(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply) \
1998_(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY, \
1999classify_set_interface_ip_table_reply) \
2000_(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY, \
2001 classify_set_interface_l2_tables_reply) \
2002_(GET_NODE_INDEX_REPLY, get_node_index_reply) \
2003_(ADD_NODE_NEXT_REPLY, add_node_next_reply) \
2004_(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply) \
2005_(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply) \
2006_(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY, \
2007 l2tpv3_interface_enable_disable_reply) \
2008_(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply) \
2009_(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details) \
2010_(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply) \
Dave Wallace60231f32015-12-17 21:04:30 -05002011_(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details) \
Ed Warnickecb9cada2015-12-08 15:45:58 -07002012_(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply) \
2013_(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply) \
2014_(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
2015_(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details) \
2016_(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply) \
2017_(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply) \
2018_(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply) \
2019_(SHOW_VERSION_REPLY, show_version_reply) \
2020_(NSH_GRE_ADD_DEL_TUNNEL_REPLY, nsh_gre_add_del_tunnel_reply) \
2021_(L2_FIB_TABLE_ENTRY, l2_fib_table_entry) \
2022_(NSH_VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, nsh_vxlan_gpe_add_del_tunnel_reply) \
2023_(LISP_GPE_ADD_DEL_TUNNEL_REPLY, lisp_gpe_add_del_tunnel_reply) \
2024_(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply) \
2025_(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply) \
2026_(IP4_ARP_EVENT, ip4_arp_event) \
2027_(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply) \
2028_(IP_ADDRESS_DETAILS, ip_address_details) \
2029_(IP_DETAILS, ip_details) \
2030_(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply) \
2031_(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
2032_(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply) \
2033_(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply) \
2034_(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply) \
2035_(DELETE_LOOPBACK_REPLY, delete_loopback_reply) \
2036_(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply) \
2037_(DHCP_COMPL_EVENT, dhcp_compl_event) \
2038_(VNET_INTERFACE_COUNTERS, vnet_interface_counters) \
2039_(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters) \
2040_(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters) \
2041_(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply) \
2042_(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply) \
Dave Barachc07bf5d2016-02-17 17:52:26 -05002043_(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply) \
Ed Warnickecb9cada2015-12-08 15:45:58 -07002044_(MAP_DOMAIN_DETAILS, map_domain_details) \
2045_(MAP_RULE_DETAILS, map_rule_details) \
2046_(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply) \
2047_(WANT_STATS_REPLY, want_stats_reply) \
Dave Barachc07bf5d2016-02-17 17:52:26 -05002048_(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply) \
2049_(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
Dave Barachb44e9bc2016-02-19 09:06:23 -05002050_(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
2051_(GET_NODE_GRAPH_REPLY, get_node_graph_reply)
Ed Warnickecb9cada2015-12-08 15:45:58 -07002052
2053/* M: construct, but don't yet send a message */
2054
2055#define M(T,t) \
2056do { \
2057 vam->result_ready = 0; \
2058 mp = vl_msg_api_alloc(sizeof(*mp)); \
2059 memset (mp, 0, sizeof (*mp)); \
2060 mp->_vl_msg_id = ntohs (VL_API_##T); \
2061 mp->client_index = vam->my_client_index; \
2062} while(0);
2063
2064#define M2(T,t,n) \
2065do { \
2066 vam->result_ready = 0; \
2067 mp = vl_msg_api_alloc(sizeof(*mp)+(n)); \
2068 memset (mp, 0, sizeof (*mp)); \
2069 mp->_vl_msg_id = ntohs (VL_API_##T); \
2070 mp->client_index = vam->my_client_index; \
2071} while(0);
2072
2073
2074/* S: send a message */
2075#define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
2076
2077/* W: wait for results, with timeout */
2078#define W \
2079do { \
2080 timeout = vat_time_now (vam) + 1.0; \
2081 \
2082 while (vat_time_now (vam) < timeout) { \
2083 if (vam->result_ready == 1) { \
2084 return (vam->retval); \
2085 } \
2086 } \
2087 return -99; \
2088} while(0);
2089
2090typedef struct {
2091 u8 * name;
2092 u32 value;
2093} name_sort_t;
2094
2095
2096#define STR_VTR_OP_CASE(op) \
2097 case L2_VTR_ ## op: \
2098 return "" # op;
2099
2100static const char *str_vtr_op(u32 vtr_op)
2101{
2102 switch(vtr_op) {
2103 STR_VTR_OP_CASE(DISABLED);
2104 STR_VTR_OP_CASE(PUSH_1);
2105 STR_VTR_OP_CASE(PUSH_2);
2106 STR_VTR_OP_CASE(POP_1);
2107 STR_VTR_OP_CASE(POP_2);
2108 STR_VTR_OP_CASE(TRANSLATE_1_1);
2109 STR_VTR_OP_CASE(TRANSLATE_1_2);
2110 STR_VTR_OP_CASE(TRANSLATE_2_1);
2111 STR_VTR_OP_CASE(TRANSLATE_2_2);
2112 }
2113
2114 return "UNKNOWN";
2115}
2116
2117static int dump_sub_interface_table (vat_main_t * vam)
2118{
2119 const sw_interface_subif_t * sub = NULL;
2120
2121 if (vam->json_output) {
2122 clib_warning ("JSON output supported only for VPE API calls and dump_stats_table");
2123 return -99;
2124 }
2125
2126 fformat (vam->ofp,
2127 "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
2128 "Interface", "sw_if_index",
2129 "sub id", "dot1ad", "tags", "outer id",
2130 "inner id", "exact", "default",
2131 "outer any", "inner any");
2132
2133 vec_foreach (sub, vam->sw_if_subif_table) {
2134 fformat (vam->ofp,
2135 "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
2136 sub->interface_name,
2137 sub->sw_if_index,
2138 sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
2139 sub->sub_number_of_tags, sub->sub_outer_vlan_id,
2140 sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
2141 sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
2142 if (sub->vtr_op != L2_VTR_DISABLED) {
2143 fformat (vam->ofp,
2144 " vlan-tag-rewrite - op: %-14s [ dot1q: %d "
2145 "tag1: %d tag2: %d ]\n",
2146 str_vtr_op(sub->vtr_op), sub->vtr_push_dot1q,
2147 sub->vtr_tag1, sub->vtr_tag2);
2148 }
2149 }
2150
2151 return 0;
2152}
2153
Matus Fabiand2dc3df2015-12-14 10:31:33 -05002154static int name_sort_cmp (void * a1, void * a2)
2155{
2156 name_sort_t * n1 = a1;
2157 name_sort_t * n2 = a2;
2158
2159 return strcmp ((char *)n1->name, (char *)n2->name);
2160}
2161
Ed Warnickecb9cada2015-12-08 15:45:58 -07002162static int dump_interface_table (vat_main_t * vam)
2163{
2164 hash_pair_t * p;
2165 name_sort_t * nses = 0, * ns;
2166
2167 if (vam->json_output) {
2168 clib_warning ("JSON output supported only for VPE API calls and dump_stats_table");
2169 return -99;
2170 }
2171
2172 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
2173 ({
2174 vec_add2 (nses, ns, 1);
2175 ns->name = (u8 *)(p->key);
2176 ns->value = (u32) p->value[0];
2177 }));
2178
Matus Fabiand2dc3df2015-12-14 10:31:33 -05002179 vec_sort_with_function (nses, name_sort_cmp);
Ed Warnickecb9cada2015-12-08 15:45:58 -07002180
2181 fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
2182 vec_foreach (ns, nses) {
2183 fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
2184 }
2185 vec_free (nses);
2186 return 0;
2187}
2188
2189static int dump_ip_table (vat_main_t * vam, int is_ipv6)
2190{
2191 const ip_details_t * det = NULL;
2192 const ip_address_details_t * address = NULL;
2193 u32 i = ~0;
2194
2195 fformat (vam->ofp,
2196 "%-12s\n",
2197 "sw_if_index");
2198
2199 if (0 == vam->ip_details_by_sw_if_index) {
2200 return 0;
2201 }
2202
2203 vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6]) {
2204 i++;
2205 if (!det->present) {
2206 continue;
2207 }
2208 fformat (vam->ofp,
2209 "%-12d\n",
2210 i);
2211 fformat (vam->ofp,
2212 " %-30s%-13s\n",
2213 "Address", "Prefix length");
2214 if (!det->addr) {
2215 continue;
2216 }
2217 vec_foreach (address, det->addr) {
2218 fformat (vam->ofp,
2219 " %-30U%-13d\n",
2220 is_ipv6 ? format_ip6_address : format_ip4_address,
2221 address->ip,
2222 address->prefix_length);
2223 }
2224 }
2225
2226 return 0;
2227}
2228
2229static int dump_ipv4_table (vat_main_t * vam)
2230{
2231 if (vam->json_output) {
2232 clib_warning ("JSON output supported only for VPE API calls and dump_stats_table");
2233 return -99;
2234 }
2235
2236 return dump_ip_table (vam, 0);
2237}
2238
2239static int dump_ipv6_table (vat_main_t * vam)
2240{
2241 if (vam->json_output) {
2242 clib_warning ("JSON output supported only for VPE API calls and dump_stats_table");
2243 return -99;
2244 }
2245
2246 return dump_ip_table (vam, 1);
2247}
2248
2249static char* counter_type_to_str (u8 counter_type, u8 is_combined)
2250{
2251 if (!is_combined) {
2252 switch(counter_type) {
2253 case VNET_INTERFACE_COUNTER_DROP:
2254 return "drop";
2255 case VNET_INTERFACE_COUNTER_PUNT:
2256 return "punt";
2257 case VNET_INTERFACE_COUNTER_IP4:
2258 return "ip4";
2259 case VNET_INTERFACE_COUNTER_IP6:
2260 return "ip6";
2261 case VNET_INTERFACE_COUNTER_RX_NO_BUF:
2262 return "rx-no-buf";
2263 case VNET_INTERFACE_COUNTER_RX_MISS:
2264 return "rx-miss";
2265 case VNET_INTERFACE_COUNTER_RX_ERROR:
2266 return "rx-error";
2267 case VNET_INTERFACE_COUNTER_TX_ERROR:
2268 return "tx-error";
2269 default:
2270 return "INVALID-COUNTER-TYPE";
2271 }
2272 } else {
2273 switch(counter_type) {
2274 case VNET_INTERFACE_COUNTER_RX:
2275 return "rx";
2276 case VNET_INTERFACE_COUNTER_TX:
2277 return "tx";
2278 default:
2279 return "INVALID-COUNTER-TYPE";
2280 }
2281 }
2282}
2283
2284static int dump_stats_table (vat_main_t * vam)
2285{
2286 vat_json_node_t node;
2287 vat_json_node_t *msg_array;
2288 vat_json_node_t *msg;
2289 vat_json_node_t *counter_array;
2290 vat_json_node_t *counter;
2291 interface_counter_t c;
2292 u64 packets;
2293 ip4_fib_counter_t *c4;
2294 ip6_fib_counter_t *c6;
2295 int i, j;
2296
2297 if (!vam->json_output) {
2298 clib_warning ("dump_stats_table supported only in JSON format");
2299 return -99;
2300 }
2301
2302 vat_json_init_object(&node);
2303
2304 /* interface counters */
2305 msg_array = vat_json_object_add(&node, "interface_counters");
2306 vat_json_init_array(msg_array);
2307 for (i = 0; i < vec_len(vam->simple_interface_counters); i++) {
2308 msg = vat_json_array_add(msg_array);
2309 vat_json_init_object(msg);
2310 vat_json_object_add_string_copy(msg, "vnet_counter_type",
2311 (u8*)counter_type_to_str(i, 0));
2312 vat_json_object_add_int(msg, "is_combined", 0);
2313 counter_array = vat_json_object_add(msg, "data");
2314 vat_json_init_array(counter_array);
2315 for (j = 0; j < vec_len(vam->simple_interface_counters[i]); j++) {
2316 packets = vam->simple_interface_counters[i][j];
2317 vat_json_array_add_uint(counter_array, packets);
2318 }
2319 }
2320 for (i = 0; i < vec_len(vam->combined_interface_counters); i++) {
2321 msg = vat_json_array_add(msg_array);
2322 vat_json_init_object(msg);
2323 vat_json_object_add_string_copy(msg, "vnet_counter_type",
2324 (u8*)counter_type_to_str(i, 1));
2325 vat_json_object_add_int(msg, "is_combined", 1);
2326 counter_array = vat_json_object_add(msg, "data");
2327 vat_json_init_array(counter_array);
2328 for (j = 0; j < vec_len(vam->combined_interface_counters[i]); j++) {
2329 c = vam->combined_interface_counters[i][j];
2330 counter = vat_json_array_add(counter_array);
2331 vat_json_init_object(counter);
2332 vat_json_object_add_uint(counter, "packets", c.packets);
2333 vat_json_object_add_uint(counter, "bytes", c.bytes);
2334 }
2335 }
2336
2337 /* ip4 fib counters */
2338 msg_array = vat_json_object_add(&node, "ip4_fib_counters");
2339 vat_json_init_array(msg_array);
2340 for (i = 0; i < vec_len(vam->ip4_fib_counters); i++) {
2341 msg = vat_json_array_add(msg_array);
2342 vat_json_init_object(msg);
2343 vat_json_object_add_uint(msg, "vrf_id", vam->ip4_fib_counters_vrf_id_by_index[i]);
2344 counter_array = vat_json_object_add(msg, "c");
2345 vat_json_init_array(counter_array);
2346 for (j = 0; j < vec_len(vam->ip4_fib_counters[i]); j++) {
2347 counter = vat_json_array_add(counter_array);
2348 vat_json_init_object(counter);
2349 c4 = &vam->ip4_fib_counters[i][j];
2350 vat_json_object_add_ip4(counter, "address", c4->address);
2351 vat_json_object_add_uint(counter, "address_length", c4->address_length);
2352 vat_json_object_add_uint(counter, "packets", c4->packets);
2353 vat_json_object_add_uint(counter, "bytes", c4->bytes);
2354 }
2355 }
2356
2357 /* ip6 fib counters */
2358 msg_array = vat_json_object_add(&node, "ip6_fib_counters");
2359 vat_json_init_array(msg_array);
2360 for (i = 0; i < vec_len(vam->ip6_fib_counters); i++) {
2361 msg = vat_json_array_add(msg_array);
2362 vat_json_init_object(msg);
2363 vat_json_object_add_uint(msg, "vrf_id", vam->ip6_fib_counters_vrf_id_by_index[i]);
2364 counter_array = vat_json_object_add(msg, "c");
2365 vat_json_init_array(counter_array);
2366 for (j = 0; j < vec_len(vam->ip6_fib_counters[i]); j++) {
2367 counter = vat_json_array_add(counter_array);
2368 vat_json_init_object(counter);
2369 c6 = &vam->ip6_fib_counters[i][j];
2370 vat_json_object_add_ip6(counter, "address", c6->address);
2371 vat_json_object_add_uint(counter, "address_length", c6->address_length);
2372 vat_json_object_add_uint(counter, "packets", c6->packets);
2373 vat_json_object_add_uint(counter, "bytes", c6->bytes);
2374 }
2375 }
2376
2377 vat_json_print(vam->ofp, &node);
2378 vat_json_free(&node);
2379
2380 return 0;
2381}
2382
2383int exec (vat_main_t * vam)
2384{
2385 api_main_t * am = &api_main;
2386 vl_api_cli_request_t *mp;
2387 f64 timeout;
2388 void * oldheap;
2389 u8 * cmd = 0;
2390 unformat_input_t * i = vam->input;
2391
2392 if (vec_len(i->buffer) == 0)
2393 return -1;
2394
2395 if (vam->exec_mode == 0 && unformat (i, "mode")) {
2396 vam->exec_mode = 1;
2397 return 0;
2398 }
2399 if (vam->exec_mode == 1 &&
2400 (unformat (i, "exit") || unformat (i, "quit"))) {
2401 vam->exec_mode = 0;
2402 return 0;
2403 }
2404
2405
2406 M(CLI_REQUEST, cli_request);
2407
2408 /*
2409 * Copy cmd into shared memory.
2410 * In order for the CLI command to work, it
2411 * must be a vector ending in \n, not a C-string ending
2412 * in \n\0.
2413 */
2414 pthread_mutex_lock (&am->vlib_rp->mutex);
2415 oldheap = svm_push_data_heap (am->vlib_rp);
2416
2417 vec_validate (cmd, vec_len(vam->input->buffer)-1);
2418 memcpy (cmd, vam->input->buffer, vec_len(vam->input->buffer));
2419
2420 svm_pop_heap (oldheap);
2421 pthread_mutex_unlock (&am->vlib_rp->mutex);
2422
2423 mp->cmd_in_shmem = (u64) cmd;
2424 S;
2425 timeout = vat_time_now (vam) + 10.0;
2426
2427 while (vat_time_now (vam) < timeout) {
2428 if (vam->result_ready == 1) {
2429 u8 * free_me;
2430 fformat (vam->ofp, "%s", vam->shmem_result);
2431 pthread_mutex_lock (&am->vlib_rp->mutex);
2432 oldheap = svm_push_data_heap (am->vlib_rp);
2433
2434 free_me = (u8 *)vam->shmem_result;
2435 vec_free (free_me);
2436
2437 svm_pop_heap (oldheap);
2438 pthread_mutex_unlock (&am->vlib_rp->mutex);
2439 return 0;
2440 }
2441 }
2442 return -99;
2443}
2444
2445static int api_create_loopback (vat_main_t * vam)
2446{
2447 unformat_input_t * i = vam->input;
2448 vl_api_create_loopback_t *mp;
2449 f64 timeout;
2450 u8 mac_address[6];
2451 u8 mac_set = 0;
2452
2453 memset (mac_address, 0, sizeof (mac_address));
2454
2455 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2456 {
2457 if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
2458 mac_set = 1;
2459 else
2460 break;
2461 }
2462
2463 /* Construct the API message */
2464 M(CREATE_LOOPBACK, create_loopback);
2465 if (mac_set)
2466 memcpy (mp->mac_address, mac_address, sizeof (mac_address));
2467
2468 S; W;
2469}
2470
2471static int api_delete_loopback (vat_main_t * vam)
2472{
2473 unformat_input_t * i = vam->input;
2474 vl_api_delete_loopback_t *mp;
2475 f64 timeout;
2476 u32 sw_if_index = ~0;
2477
2478 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2479 {
2480 if (unformat (i, "sw_if_index %d", &sw_if_index))
2481 ;
2482 else
2483 break;
2484 }
2485
2486 if (sw_if_index == ~0)
2487 {
2488 errmsg ("missing sw_if_index\n");
2489 return -99;
2490 }
2491
2492 /* Construct the API message */
2493 M(DELETE_LOOPBACK, delete_loopback);
2494 mp->sw_if_index = ntohl (sw_if_index);
2495
2496 S; W;
2497}
2498
2499static int api_want_stats (vat_main_t * vam)
2500{
2501 unformat_input_t * i = vam->input;
2502 vl_api_want_stats_t * mp;
2503 f64 timeout;
2504 int enable = -1;
2505
2506 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2507 {
2508 if (unformat (i, "enable"))
2509 enable = 1;
2510 else if (unformat (i, "disable"))
2511 enable = 0;
2512 else
2513 break;
2514 }
2515
2516 if (enable == -1)
2517 {
2518 errmsg ("missing enable|disable\n");
2519 return -99;
2520 }
2521
2522 M(WANT_STATS, want_stats);
2523 mp->enable_disable = enable;
2524
2525 S; W;
2526}
2527
2528static int api_want_interface_events (vat_main_t * vam)
2529{
2530 unformat_input_t * i = vam->input;
2531 vl_api_want_interface_events_t * mp;
2532 f64 timeout;
2533 int enable = -1;
2534
2535 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2536 {
2537 if (unformat (i, "enable"))
2538 enable = 1;
2539 else if (unformat (i, "disable"))
2540 enable = 0;
2541 else
2542 break;
2543 }
2544
2545 if (enable == -1)
2546 {
2547 errmsg ("missing enable|disable\n");
2548 return -99;
2549 }
2550
2551 M(WANT_INTERFACE_EVENTS, want_interface_events);
2552 mp->enable_disable = enable;
2553
2554 vam->interface_event_display = enable;
2555
2556 S; W;
2557}
2558
2559
2560/* Note: non-static, called once to set up the initial intfc table */
2561int api_sw_interface_dump (vat_main_t * vam)
2562{
2563 vl_api_sw_interface_dump_t *mp;
2564 f64 timeout;
2565 hash_pair_t * p;
2566 name_sort_t * nses = 0, * ns;
2567 sw_interface_subif_t * sub = NULL;
2568
2569 /* Toss the old name table */
2570 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
2571 ({
2572 vec_add2 (nses, ns, 1);
2573 ns->name = (u8 *)(p->key);
2574 ns->value = (u32) p->value[0];
2575 }));
2576
2577 hash_free (vam->sw_if_index_by_interface_name);
2578
2579 vec_foreach (ns, nses)
2580 vec_free (ns->name);
2581
2582 vec_free (nses);
2583
2584 vec_foreach (sub, vam->sw_if_subif_table) {
2585 vec_free (sub->interface_name);
2586 }
2587 vec_free (vam->sw_if_subif_table);
2588
2589 /* recreate the interface name hash table */
2590 vam->sw_if_index_by_interface_name
2591 = hash_create_string (0, sizeof(uword));
2592
2593 /* Get list of ethernets */
2594 M(SW_INTERFACE_DUMP, sw_interface_dump);
2595 mp->name_filter_valid = 1;
2596 strncpy ((char *) mp->name_filter, "Ether", sizeof(mp->name_filter-1));
2597 S;
2598
2599 /* and local / loopback interfaces */
2600 M(SW_INTERFACE_DUMP, sw_interface_dump);
2601 mp->name_filter_valid = 1;
2602 strncpy ((char *) mp->name_filter, "lo", sizeof(mp->name_filter-1));
2603 S;
2604
2605 /* and vxlan tunnel interfaces */
2606 M(SW_INTERFACE_DUMP, sw_interface_dump);
2607 mp->name_filter_valid = 1;
2608 strncpy ((char *) mp->name_filter, "vxlan", sizeof(mp->name_filter-1));
2609 S;
2610
2611 /* and l2tpv3 tunnel interfaces */
2612 M(SW_INTERFACE_DUMP, sw_interface_dump);
2613 mp->name_filter_valid = 1;
2614 strncpy ((char *) mp->name_filter, "l2tpv3_tunnel", sizeof(mp->name_filter-1));
2615 S;
2616
2617 /* Use a control ping for synchronization */
2618 {
2619 vl_api_control_ping_t * mp;
2620 M(CONTROL_PING, control_ping);
2621 S;
2622 }
2623 W;
2624}
2625
2626static int api_sw_interface_set_flags (vat_main_t * vam)
2627{
2628 unformat_input_t * i = vam->input;
2629 vl_api_sw_interface_set_flags_t *mp;
2630 f64 timeout;
2631 u32 sw_if_index;
2632 u8 sw_if_index_set = 0;
2633 u8 admin_up = 0, link_up = 0;
2634
2635 /* Parse args required to build the message */
2636 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
2637 if (unformat (i, "admin-up"))
2638 admin_up = 1;
2639 else if (unformat (i, "admin-down"))
2640 admin_up = 0;
2641 else if (unformat (i, "link-up"))
2642 link_up = 1;
2643 else if (unformat (i, "link-down"))
2644 link_up = 0;
2645 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
2646 sw_if_index_set = 1;
2647 else if (unformat (i, "sw_if_index %d", &sw_if_index))
2648 sw_if_index_set = 1;
2649 else
2650 break;
2651 }
2652
2653 if (sw_if_index_set == 0) {
2654 errmsg ("missing interface name or sw_if_index\n");
2655 return -99;
2656 }
2657
2658 /* Construct the API message */
2659 M(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
2660 mp->sw_if_index = ntohl (sw_if_index);
2661 mp->admin_up_down = admin_up;
2662 mp->link_up_down = link_up;
2663
2664 /* send it... */
2665 S;
2666
2667 /* Wait for a reply, return the good/bad news... */
2668 W;
2669}
2670
2671static int api_sw_interface_add_del_address (vat_main_t * vam)
2672{
2673 unformat_input_t * i = vam->input;
2674 vl_api_sw_interface_add_del_address_t *mp;
2675 f64 timeout;
2676 u32 sw_if_index;
2677 u8 sw_if_index_set = 0;
2678 u8 is_add = 1, del_all = 0;
2679 u32 address_length = 0;
2680 u8 v4_address_set = 0;
2681 u8 v6_address_set = 0;
2682 ip4_address_t v4address;
2683 ip6_address_t v6address;
2684
2685 /* Parse args required to build the message */
2686 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
2687 if (unformat (i, "del-all"))
2688 del_all = 1;
2689 else if (unformat (i, "del"))
2690 is_add = 0;
2691 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
2692 sw_if_index_set = 1;
2693 else if (unformat (i, "sw_if_index %d", &sw_if_index))
2694 sw_if_index_set = 1;
2695 else if (unformat (i, "%U/%d",
2696 unformat_ip4_address, &v4address,
2697 &address_length))
2698 v4_address_set = 1;
2699 else if (unformat (i, "%U/%d",
2700 unformat_ip6_address, &v6address,
2701 &address_length))
2702 v6_address_set = 1;
2703 else
2704 break;
2705 }
2706
2707 if (sw_if_index_set == 0) {
2708 errmsg ("missing interface name or sw_if_index\n");
2709 return -99;
2710 }
2711 if (v4_address_set && v6_address_set) {
2712 errmsg ("both v4 and v6 addresses set\n");
2713 return -99;
2714 }
2715 if (!v4_address_set && !v6_address_set && !del_all) {
2716 errmsg ("no addresses set\n");
2717 return -99;
2718 }
2719
2720 /* Construct the API message */
2721 M(SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
2722
2723 mp->sw_if_index = ntohl (sw_if_index);
2724 mp->is_add = is_add;
2725 mp->del_all = del_all;
2726 if (v6_address_set) {
2727 mp->is_ipv6 = 1;
2728 memcpy (mp->address, &v6address, sizeof (v6address));
2729 } else {
2730 memcpy (mp->address, &v4address, sizeof (v4address));
2731 }
2732 mp->address_length = address_length;
2733
2734 /* send it... */
2735 S;
2736
2737 /* Wait for a reply, return good/bad news */
2738 W;
2739}
2740
2741static int api_sw_interface_set_table (vat_main_t * vam)
2742{
2743 unformat_input_t * i = vam->input;
2744 vl_api_sw_interface_set_table_t *mp;
2745 f64 timeout;
2746 u32 sw_if_index, vrf_id = 0;
2747 u8 sw_if_index_set = 0;
2748 u8 is_ipv6 = 0;
2749
2750 /* Parse args required to build the message */
2751 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
2752 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
2753 sw_if_index_set = 1;
2754 else if (unformat (i, "sw_if_index %d", &sw_if_index))
2755 sw_if_index_set = 1;
2756 else if (unformat (i, "vrf %d", &vrf_id))
2757 ;
2758 else if (unformat (i, "ipv6"))
2759 is_ipv6 = 1;
2760 else
2761 break;
2762 }
2763
2764 if (sw_if_index_set == 0) {
2765 errmsg ("missing interface name or sw_if_index\n");
2766 return -99;
2767 }
2768
2769 /* Construct the API message */
2770 M(SW_INTERFACE_SET_TABLE, sw_interface_set_table);
2771
2772 mp->sw_if_index = ntohl (sw_if_index);
2773 mp->is_ipv6 = is_ipv6;
2774 mp->vrf_id = ntohl (vrf_id);
2775
2776 /* send it... */
2777 S;
2778
2779 /* Wait for a reply... */
2780 W;
2781}
2782
2783static int api_sw_interface_set_vpath (vat_main_t * vam)
2784{
2785 unformat_input_t * i = vam->input;
2786 vl_api_sw_interface_set_vpath_t *mp;
2787 f64 timeout;
2788 u32 sw_if_index = 0;
2789 u8 sw_if_index_set = 0;
2790 u8 is_enable = 0;
2791
2792 /* Parse args required to build the message */
2793 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
2794 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
2795 sw_if_index_set = 1;
2796 else if (unformat (i, "sw_if_index %d", &sw_if_index))
2797 sw_if_index_set = 1;
2798 else if (unformat (i, "enable"))
2799 is_enable = 1;
2800 else if (unformat (i, "disable"))
2801 is_enable = 0;
2802 else
2803 break;
2804 }
2805
2806 if (sw_if_index_set == 0) {
2807 errmsg ("missing interface name or sw_if_index\n");
2808 return -99;
2809 }
2810
2811 /* Construct the API message */
2812 M(SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
2813
2814 mp->sw_if_index = ntohl (sw_if_index);
2815 mp->enable = is_enable;
2816
2817 /* send it... */
2818 S;
2819
2820 /* Wait for a reply... */
2821 W;
2822}
2823
2824static int api_sw_interface_set_l2_xconnect (vat_main_t * vam)
2825{
2826 unformat_input_t * i = vam->input;
2827 vl_api_sw_interface_set_l2_xconnect_t *mp;
2828 f64 timeout;
2829 u32 rx_sw_if_index;
2830 u8 rx_sw_if_index_set = 0;
2831 u32 tx_sw_if_index;
2832 u8 tx_sw_if_index_set = 0;
2833 u8 enable = 1;
2834
2835 /* Parse args required to build the message */
2836 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
2837 if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
2838 rx_sw_if_index_set = 1;
2839 else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
2840 tx_sw_if_index_set = 1;
2841 else if (unformat (i, "rx")) {
2842 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
2843 if (unformat (i, "%U", unformat_sw_if_index, vam,
2844 &rx_sw_if_index))
2845 rx_sw_if_index_set = 1;
2846 } else
2847 break;
2848 } else if (unformat (i, "tx")) {
2849 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
2850 if (unformat (i, "%U", unformat_sw_if_index, vam,
2851 &tx_sw_if_index))
2852 tx_sw_if_index_set = 1;
2853 } else
2854 break;
2855 } else if (unformat (i, "enable"))
2856 enable = 1;
2857 else if (unformat (i, "disable"))
2858 enable = 0;
2859 else
2860 break;
2861 }
2862
2863 if (rx_sw_if_index_set == 0) {
2864 errmsg ("missing rx interface name or rx_sw_if_index\n");
2865 return -99;
2866 }
2867
2868 if (enable && (tx_sw_if_index_set == 0)) {
2869 errmsg ("missing tx interface name or tx_sw_if_index\n");
2870 return -99;
2871 }
2872
2873 M(SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
2874
2875 mp->rx_sw_if_index = ntohl(rx_sw_if_index);
2876 mp->tx_sw_if_index = ntohl(tx_sw_if_index);
2877 mp->enable = enable;
2878
2879 S; W;
2880 /* NOTREACHED */
2881 return 0;
2882}
2883
2884static int api_sw_interface_set_l2_bridge (vat_main_t * vam)
2885{
2886 unformat_input_t * i = vam->input;
2887 vl_api_sw_interface_set_l2_bridge_t *mp;
2888 f64 timeout;
2889 u32 rx_sw_if_index;
2890 u8 rx_sw_if_index_set = 0;
2891 u32 bd_id;
2892 u8 bd_id_set = 0;
2893 u8 bvi = 0;
2894 u32 shg = 0;
2895 u8 enable = 1;
2896
2897 /* Parse args required to build the message */
2898 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
2899 if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
2900 rx_sw_if_index_set = 1;
2901 else if (unformat (i, "bd_id %d", &bd_id))
2902 bd_id_set = 1;
2903 else if (unformat (i, "%U", unformat_sw_if_index, vam,
2904 &rx_sw_if_index))
2905 rx_sw_if_index_set = 1;
2906 else if (unformat (i, "shg %d", &shg))
2907 ;
2908 else if (unformat (i, "bvi"))
2909 bvi = 1;
2910 else if (unformat (i, "enable"))
2911 enable = 1;
2912 else if (unformat (i, "disable"))
2913 enable = 0;
2914 else
2915 break;
2916 }
2917
2918 if (rx_sw_if_index_set == 0) {
2919 errmsg ("missing rx interface name or sw_if_index\n");
2920 return -99;
2921 }
2922
2923 if (enable && (bd_id_set == 0)) {
2924 errmsg ("missing bridge domain\n");
2925 return -99;
2926 }
2927
2928 M(SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
2929
2930 mp->rx_sw_if_index = ntohl(rx_sw_if_index);
2931 mp->bd_id = ntohl(bd_id);
2932 mp->shg = (u8)shg;
2933 mp->bvi = bvi;
2934 mp->enable = enable;
2935
2936 S; W;
2937 /* NOTREACHED */
2938 return 0;
2939}
2940
2941static int api_bridge_domain_dump (vat_main_t * vam)
2942{
2943 unformat_input_t * i = vam->input;
2944 vl_api_bridge_domain_dump_t *mp;
2945 f64 timeout;
2946 u32 bd_id = ~0;
2947
2948 /* Parse args required to build the message */
2949 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
2950 if (unformat (i, "bd_id %d", &bd_id))
2951 ;
2952 else
2953 break;
2954 }
2955
2956 M(BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
2957 mp->bd_id = ntohl(bd_id);
2958 S;
2959
2960 /* Use a control ping for synchronization */
2961 {
2962 vl_api_control_ping_t * mp;
2963 M(CONTROL_PING, control_ping);
2964 S;
2965 }
2966
2967 W;
2968 /* NOTREACHED */
2969 return 0;
2970}
2971
2972static int api_bridge_domain_add_del (vat_main_t * vam)
2973{
2974 unformat_input_t * i = vam->input;
2975 vl_api_bridge_domain_add_del_t *mp;
2976 f64 timeout;
2977 u32 bd_id = ~0;
2978 u8 is_add = 1;
2979 u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
2980
2981 /* Parse args required to build the message */
2982 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
2983 if (unformat (i, "bd_id %d", &bd_id))
2984 ;
2985 else if (unformat (i, "flood %d", &flood))
2986 ;
2987 else if (unformat (i, "uu-flood %d", &uu_flood))
2988 ;
2989 else if (unformat (i, "forward %d", &forward))
2990 ;
2991 else if (unformat (i, "learn %d", &learn))
2992 ;
2993 else if (unformat (i, "arp-term %d", &arp_term))
2994 ;
2995 else if (unformat (i, "del")) {
2996 is_add = 0;
2997 flood = uu_flood = forward = learn = 0;
2998 }
2999 else
3000 break;
3001 }
3002
3003 if (bd_id == ~0) {
3004 errmsg ("missing bridge domain\n");
3005 return -99;
3006 }
3007
3008 M(BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
3009
3010 mp->bd_id = ntohl(bd_id);
3011 mp->flood = flood;
3012 mp->uu_flood = uu_flood;
3013 mp->forward = forward;
3014 mp->learn = learn;
3015 mp->arp_term = arp_term;
3016 mp->is_add = is_add;
3017
3018 S; W;
3019 /* NOTREACHED */
3020 return 0;
3021}
3022
3023static int api_l2fib_add_del (vat_main_t * vam)
3024{
3025 unformat_input_t * i = vam->input;
3026 vl_api_l2fib_add_del_t *mp;
3027 f64 timeout;
3028 u64 mac = 0;
3029 u8 mac_set = 0;
3030 u32 bd_id;
3031 u8 bd_id_set = 0;
3032 u32 sw_if_index;
3033 u8 sw_if_index_set = 0;
3034 u8 is_add = 1;
3035 u8 static_mac = 0;
3036 u8 filter_mac = 0;
3037
3038 /* Parse args required to build the message */
3039 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3040 if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
3041 mac_set = 1;
3042 else if (unformat (i, "bd_id %d", &bd_id))
3043 bd_id_set = 1;
3044 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3045 sw_if_index_set = 1;
3046 else if (unformat (i, "sw_if")) {
3047 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3048 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3049 sw_if_index_set = 1;
3050 } else
3051 break;
3052 } else if (unformat (i, "static"))
3053 static_mac = 1;
3054 else if (unformat (i, "filter")) {
3055 filter_mac = 1;
3056 static_mac = 1;
3057 } else if (unformat (i, "del"))
3058 is_add = 0;
3059 else
3060 break;
3061 }
3062
3063 if (mac_set == 0) {
3064 errmsg ("missing mac address\n");
3065 return -99;
3066 }
3067
3068 if (bd_id_set == 0) {
3069 errmsg ("missing bridge domain\n");
3070 return -99;
3071 }
3072
3073 if (is_add && (sw_if_index_set == 0)) {
3074 errmsg ("missing interface name or sw_if_index\n");
3075 return -99;
3076 }
3077
3078 M(L2FIB_ADD_DEL, l2fib_add_del);
3079
3080 mp->mac = mac;
3081 mp->bd_id = ntohl(bd_id);
3082 mp->is_add = is_add;
3083
3084 if (is_add) {
3085 mp->sw_if_index = ntohl(sw_if_index);
3086 mp->static_mac = static_mac;
3087 mp->filter_mac = filter_mac;
3088 }
3089
3090 S; W;
3091 /* NOTREACHED */
3092 return 0;
3093}
3094
3095static int api_l2_flags (vat_main_t * vam)
3096{
3097 unformat_input_t * i = vam->input;
3098 vl_api_l2_flags_t *mp;
3099 f64 timeout;
3100 u32 sw_if_index;
3101 u32 feature_bitmap = 0;
3102 u8 sw_if_index_set = 0;
3103
3104 /* Parse args required to build the message */
3105 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3106 if (unformat (i, "sw_if_index %d", &sw_if_index))
3107 sw_if_index_set = 1;
3108 else if (unformat (i, "sw_if")) {
3109 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3110 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3111 sw_if_index_set = 1;
3112 } else
3113 break;
3114 } else if (unformat (i, "learn"))
3115 feature_bitmap |= L2INPUT_FEAT_LEARN;
3116 else if (unformat (i, "forward"))
3117 feature_bitmap |= L2INPUT_FEAT_FWD;
3118 else if (unformat (i, "flood"))
3119 feature_bitmap |= L2INPUT_FEAT_FLOOD;
3120 else if (unformat (i, "uu-flood"))
3121 feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
3122 else
3123 break;
3124 }
3125
3126 if (sw_if_index_set == 0) {
3127 errmsg ("missing interface name or sw_if_index\n");
3128 return -99;
3129 }
3130
3131 M(L2_FLAGS, l2_flags);
3132
3133 mp->sw_if_index = ntohl(sw_if_index);
3134 mp->feature_bitmap = ntohl(feature_bitmap);
3135
3136 S; W;
3137 /* NOTREACHED */
3138 return 0;
3139}
3140
3141static int api_bridge_flags (vat_main_t * vam)
3142{
3143 unformat_input_t * i = vam->input;
3144 vl_api_bridge_flags_t *mp;
3145 f64 timeout;
3146 u32 bd_id;
3147 u8 bd_id_set = 0;
3148 u8 is_set = 1;
3149 u32 flags = 0;
3150
3151 /* Parse args required to build the message */
3152 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3153 if (unformat (i, "bd_id %d", &bd_id))
3154 bd_id_set = 1;
3155 else if (unformat (i, "learn"))
3156 flags |= L2_LEARN;
3157 else if (unformat (i, "forward"))
3158 flags |= L2_FWD;
3159 else if (unformat (i, "flood"))
3160 flags |= L2_FLOOD;
3161 else if (unformat (i, "uu-flood"))
3162 flags |= L2_UU_FLOOD;
3163 else if (unformat (i, "arp-term"))
3164 flags |= L2_ARP_TERM;
3165 else if (unformat (i, "off"))
3166 is_set = 0;
3167 else if (unformat (i, "disable"))
3168 is_set = 0;
3169 else
3170 break;
3171 }
3172
3173 if (bd_id_set == 0) {
3174 errmsg ("missing bridge domain\n");
3175 return -99;
3176 }
3177
3178 M(BRIDGE_FLAGS, bridge_flags);
3179
3180 mp->bd_id = ntohl(bd_id);
3181 mp->feature_bitmap = ntohl(flags);
3182 mp->is_set = is_set;
3183
3184 S; W;
3185 /* NOTREACHED */
3186 return 0;
3187}
3188
3189static int api_bd_ip_mac_add_del (vat_main_t * vam)
3190{
3191 unformat_input_t * i = vam->input;
3192 vl_api_bd_ip_mac_add_del_t *mp;
3193 f64 timeout;
3194 u32 bd_id;
3195 u8 is_ipv6 = 0;
3196 u8 is_add = 1;
3197 u8 bd_id_set = 0;
3198 u8 ip_set = 0;
3199 u8 mac_set = 0;
3200 ip4_address_t v4addr;
3201 ip6_address_t v6addr;
3202 u8 macaddr[6];
3203
3204
3205 /* Parse args required to build the message */
3206 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3207 if (unformat (i, "bd_id %d", &bd_id)) {
3208 bd_id_set++;
3209 } else if (unformat (i, "%U", unformat_ip4_address, &v4addr)) {
3210 ip_set++;
3211 } else if (unformat (i, "%U", unformat_ip6_address, &v6addr)) {
3212 ip_set++;
3213 is_ipv6++;
3214 } else if (unformat (i, "%U", unformat_ethernet_address, macaddr)) {
3215 mac_set++;
3216 } else if (unformat (i, "del"))
3217 is_add = 0;
3218 else
3219 break;
3220 }
3221
3222 if (bd_id_set == 0) {
3223 errmsg ("missing bridge domain\n");
3224 return -99;
3225 } else if (ip_set == 0) {
3226 errmsg ("missing IP address\n");
3227 return -99;
3228 } else if (mac_set == 0) {
3229 errmsg ("missing MAC address\n");
3230 return -99;
3231 }
3232
3233 M(BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
3234
3235 mp->bd_id = ntohl(bd_id);
3236 mp->is_ipv6 = is_ipv6;
3237 mp->is_add = is_add;
3238 if (is_ipv6)
3239 memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
3240 else memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
3241 memcpy (mp->mac_address, macaddr, 6);
3242 S; W;
3243 /* NOTREACHED */
3244 return 0;
3245}
3246
3247static int api_tap_connect (vat_main_t * vam)
3248{
3249 unformat_input_t * i = vam->input;
3250 vl_api_tap_connect_t *mp;
3251 f64 timeout;
3252 u8 mac_address[6];
3253 u8 random_mac = 1;
3254 u8 name_set = 0;
3255 u8 * tap_name;
3256
3257 memset (mac_address, 0, sizeof (mac_address));
3258
3259 /* Parse args required to build the message */
3260 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3261 if (unformat (i, "mac %U", unformat_ethernet_address, mac_address)) {
3262 random_mac = 0;
3263 }
3264 else if (unformat (i, "random-mac"))
3265 random_mac = 1;
3266 else if (unformat (i, "tapname %s", &tap_name))
3267 name_set = 1;
3268 else
3269 break;
3270 }
3271
3272 if (name_set == 0) {
3273 errmsg ("missing tap name\n");
3274 return -99;
3275 }
3276 if (vec_len (tap_name) > 63) {
3277 errmsg ("tap name too long\n");
3278 }
3279 vec_add1 (tap_name, 0);
3280
3281 /* Construct the API message */
3282 M(TAP_CONNECT, tap_connect);
3283
3284 mp->use_random_mac = random_mac;
3285 memcpy (mp->mac_address, mac_address, 6);
3286 memcpy (mp->tap_name, tap_name, vec_len (tap_name));
3287 vec_free (tap_name);
3288
3289 /* send it... */
3290 S;
3291
3292 /* Wait for a reply... */
3293 W;
3294}
3295
3296static int api_tap_modify (vat_main_t * vam)
3297{
3298 unformat_input_t * i = vam->input;
3299 vl_api_tap_modify_t *mp;
3300 f64 timeout;
3301 u8 mac_address[6];
3302 u8 random_mac = 1;
3303 u8 name_set = 0;
3304 u8 * tap_name;
3305 u32 sw_if_index = ~0;
3306 u8 sw_if_index_set = 0;
3307
3308 memset (mac_address, 0, sizeof (mac_address));
3309
3310 /* Parse args required to build the message */
3311 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3312 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3313 sw_if_index_set = 1;
3314 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3315 sw_if_index_set = 1;
3316 else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address)) {
3317 random_mac = 0;
3318 }
3319 else if (unformat (i, "random-mac"))
3320 random_mac = 1;
3321 else if (unformat (i, "tapname %s", &tap_name))
3322 name_set = 1;
3323 else
3324 break;
3325 }
3326
3327 if (sw_if_index_set == 0) {
3328 errmsg ("missing vpp interface name");
3329 return -99;
3330 }
3331 if (name_set == 0) {
3332 errmsg ("missing tap name\n");
3333 return -99;
3334 }
3335 if (vec_len (tap_name) > 63) {
3336 errmsg ("tap name too long\n");
3337 }
3338 vec_add1 (tap_name, 0);
3339
3340 /* Construct the API message */
3341 M(TAP_MODIFY, tap_modify);
3342
3343 mp->use_random_mac = random_mac;
3344 mp->sw_if_index = ntohl(sw_if_index);
3345 memcpy (mp->mac_address, mac_address, 6);
3346 memcpy (mp->tap_name, tap_name, vec_len (tap_name));
3347 vec_free (tap_name);
3348
3349 /* send it... */
3350 S;
3351
3352 /* Wait for a reply... */
3353 W;
3354}
3355
3356static int api_tap_delete (vat_main_t * vam)
3357{
3358 unformat_input_t * i = vam->input;
3359 vl_api_tap_delete_t *mp;
3360 f64 timeout;
3361 u32 sw_if_index = ~0;
3362 u8 sw_if_index_set = 0;
3363
3364 /* Parse args required to build the message */
3365 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3366 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3367 sw_if_index_set = 1;
3368 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3369 sw_if_index_set = 1;
3370 else
3371 break;
3372 }
3373
3374 if (sw_if_index_set == 0) {
3375 errmsg ("missing vpp interface name");
3376 return -99;
3377 }
3378
3379 /* Construct the API message */
3380 M(TAP_DELETE, tap_delete);
3381
3382 mp->sw_if_index = ntohl(sw_if_index);
3383
3384 /* send it... */
3385 S;
3386
3387 /* Wait for a reply... */
3388 W;
3389}
3390
3391static int api_ip_add_del_route (vat_main_t * vam)
3392{
3393 unformat_input_t * i = vam->input;
3394 vl_api_ip_add_del_route_t *mp;
3395 f64 timeout;
3396 u32 sw_if_index = 0, vrf_id = 0;
3397 u8 sw_if_index_set = 0;
3398 u8 is_ipv6 = 0;
3399 u8 is_local = 0, is_drop = 0;
3400 u8 create_vrf_if_needed = 0;
3401 u8 is_add = 1;
3402 u8 next_hop_weight = 1;
3403 u8 not_last = 0;
3404 u8 is_multipath = 0;
3405 u8 address_set = 0;
3406 u8 address_length_set = 0;
3407 u32 lookup_in_vrf = 0;
3408 u32 resolve_attempts = 0;
3409 u32 dst_address_length = 0;
3410 u8 next_hop_set = 0;
3411 ip4_address_t v4_dst_address, v4_next_hop_address;
3412 ip6_address_t v6_dst_address, v6_next_hop_address;
3413 int count = 1;
3414 int j;
3415 f64 before = 0;
3416 u32 random_add_del = 0;
3417 u32 * random_vector = 0;
3418 uword * random_hash;
3419 u32 random_seed = 0xdeaddabe;
3420 u32 classify_table_index = ~0;
3421 u8 is_classify = 0;
3422
3423 /* Parse args required to build the message */
3424 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3425 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3426 sw_if_index_set = 1;
3427 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3428 sw_if_index_set = 1;
3429 else if (unformat (i, "%U", unformat_ip4_address,
3430 &v4_dst_address)) {
3431 address_set = 1;
3432 is_ipv6 = 0;
3433 }
3434 else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address)) {
3435 address_set = 1;
3436 is_ipv6 = 1;
3437 }
3438 else if (unformat (i, "/%d", &dst_address_length)) {
3439 address_length_set = 1;
3440 }
3441
3442 else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
3443 &v4_next_hop_address)) {
3444 next_hop_set = 1;
3445 }
3446 else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
3447 &v6_next_hop_address)) {
3448 next_hop_set = 1;
3449 }
3450 else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
3451 ;
3452 else if (unformat (i, "weight %d", &next_hop_weight))
3453 ;
3454 else if (unformat (i, "drop")) {
3455 is_drop = 1;
3456 } else if (unformat (i, "local")) {
3457 is_local = 1;
3458 } else if (unformat (i, "classify %d", &classify_table_index)) {
3459 is_classify = 1;
3460 } else if (unformat (i, "del"))
3461 is_add = 0;
3462 else if (unformat (i, "add"))
3463 is_add = 1;
3464 else if (unformat (i, "not-last"))
3465 not_last = 1;
3466 else if (unformat (i, "multipath"))
3467 is_multipath = 1;
3468 else if (unformat (i, "vrf %d", &vrf_id))
3469 ;
3470 else if (unformat (i, "create-vrf"))
3471 create_vrf_if_needed = 1;
3472 else if (unformat (i, "count %d", &count))
3473 ;
3474 else if (unformat (i, "lookup-in-vrf %d", &lookup_in_vrf))
3475 ;
3476 else if (unformat (i, "random"))
3477 random_add_del = 1;
3478 else if (unformat (i, "seed %d", &random_seed))
3479 ;
3480 else {
3481 clib_warning ("parse error '%U'", format_unformat_error, i);
3482 return -99;
3483 }
3484 }
3485
3486 if (resolve_attempts > 0 && sw_if_index_set == 0) {
3487 errmsg ("ARP resolution needs explicit interface or sw_if_index\n");
3488 return -99;
3489 }
3490
3491 if (!next_hop_set && !is_drop && !is_local && !is_classify) {
3492 errmsg ("next hop / local / drop / classify not set\n");
3493 return -99;
3494 }
3495
3496 if (address_set == 0) {
3497 errmsg ("missing addresses\n");
3498 return -99;
3499 }
3500
3501 if (address_length_set == 0) {
3502 errmsg ("missing address length\n");
3503 return -99;
3504 }
3505
3506 /* Generate a pile of unique, random routes */
3507 if (random_add_del) {
3508 u32 this_random_address;
3509 random_hash = hash_create (count, sizeof(uword));
3510
3511 hash_set (random_hash, v4_next_hop_address.as_u32, 1);
3512 for (j = 0; j <= count; j++) {
3513 do {
3514 this_random_address = random_u32 (&random_seed);
3515 this_random_address =
3516 clib_host_to_net_u32 (this_random_address);
3517 } while (hash_get (random_hash, this_random_address));
3518 vec_add1 (random_vector, this_random_address);
3519 hash_set (random_hash, this_random_address, 1);
3520 }
3521 hash_free (random_hash);
3522 v4_dst_address.as_u32 = random_vector[0];
3523 }
3524
3525 if (count > 1) {
3526 /* Turn on async mode */
3527 vam->async_mode = 1;
3528 vam->async_errors = 0;
3529 before = vat_time_now(vam);
3530 }
3531
3532 for (j = 0; j < count; j++) {
3533 /* Construct the API message */
3534 M(IP_ADD_DEL_ROUTE, ip_add_del_route);
3535
3536 mp->next_hop_sw_if_index = ntohl (sw_if_index);
3537 mp->vrf_id = ntohl (vrf_id);
3538 if (resolve_attempts > 0) {
3539 mp->resolve_attempts = ntohl (resolve_attempts);
3540 mp->resolve_if_needed = 1;
3541 }
3542 mp->create_vrf_if_needed = create_vrf_if_needed;
3543
3544 mp->is_add = is_add;
3545 mp->is_drop = is_drop;
3546 mp->is_ipv6 = is_ipv6;
3547 mp->is_local = is_local;
3548 mp->is_classify = is_classify;
3549 mp->is_multipath = is_multipath;
3550 mp->not_last = not_last;
3551 mp->next_hop_weight = next_hop_weight;
3552 mp->dst_address_length = dst_address_length;
3553 mp->lookup_in_vrf = ntohl(lookup_in_vrf);
3554 mp->classify_table_index = ntohl(classify_table_index);
3555
3556 if (is_ipv6){
3557 memcpy (mp->dst_address, &v6_dst_address, sizeof (v6_dst_address));
3558 if (next_hop_set)
3559 memcpy (mp->next_hop_address, &v6_next_hop_address,
3560 sizeof (v6_next_hop_address));
3561 increment_v6_address (&v6_dst_address);
3562 } else {
3563 memcpy (mp->dst_address, &v4_dst_address, sizeof (v4_dst_address));
3564 if (next_hop_set)
3565 memcpy (mp->next_hop_address, &v4_next_hop_address,
3566 sizeof (v4_next_hop_address));
3567 if (random_add_del)
3568 v4_dst_address.as_u32 = random_vector[j+1];
3569 else
3570 increment_v4_address (&v4_dst_address);
3571 }
3572 /* send it... */
3573 S;
3574 }
3575
3576 /* When testing multiple add/del ops, use a control-ping to sync */
3577 if (count > 1) {
3578 vl_api_control_ping_t * mp;
3579 f64 after;
3580
3581 /* Shut off async mode */
3582 vam->async_mode = 0;
3583
3584 M(CONTROL_PING, control_ping);
3585 S;
3586
3587 timeout = vat_time_now(vam) + 1.0;
3588 while (vat_time_now (vam) < timeout)
3589 if (vam->result_ready == 1)
3590 goto out;
3591 vam->retval = -99;
3592
3593 out:
3594 if (vam->retval == -99)
3595 errmsg ("timeout\n");
3596
3597 if (vam->async_errors > 0) {
3598 errmsg ("%d asynchronous errors\n", vam->async_errors);
3599 vam->retval = -98;
3600 }
3601 vam->async_errors = 0;
3602 after = vat_time_now(vam);
3603
3604 fformat(vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
3605 count, after - before, count / (after - before));
3606 } else {
3607 /* Wait for a reply... */
3608 W;
3609 }
3610
3611 /* Return the good/bad news */
3612 return (vam->retval);
3613}
3614
3615static int api_proxy_arp_add_del (vat_main_t * vam)
3616{
3617 unformat_input_t * i = vam->input;
3618 vl_api_proxy_arp_add_del_t *mp;
3619 f64 timeout;
3620 u32 vrf_id = 0;
3621 u8 is_add = 1;
3622 ip4_address_t lo, hi;
3623 u8 range_set = 0;
3624
3625 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3626 if (unformat (i, "vrf %d", &vrf_id))
3627 ;
3628 else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
3629 unformat_ip4_address, &hi))
3630 range_set = 1;
3631 else if (unformat (i, "del"))
3632 is_add = 0;
3633 else {
3634 clib_warning ("parse error '%U'", format_unformat_error, i);
3635 return -99;
3636 }
3637 }
3638
3639 if (range_set == 0) {
3640 errmsg ("address range not set\n");
3641 return -99;
3642 }
3643
3644 M(PROXY_ARP_ADD_DEL, proxy_arp_add_del);
3645
3646 mp->vrf_id = ntohl(vrf_id);
3647 mp->is_add = is_add;
3648 memcpy(mp->low_address, &lo, sizeof (mp->low_address));
3649 memcpy(mp->hi_address, &hi, sizeof (mp->hi_address));
3650
3651 S; W;
3652 /* NOTREACHED */
3653 return 0;
3654}
3655
3656static int api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
3657{
3658 unformat_input_t * i = vam->input;
3659 vl_api_proxy_arp_intfc_enable_disable_t *mp;
3660 f64 timeout;
3661 u32 sw_if_index;
3662 u8 enable = 1;
3663 u8 sw_if_index_set = 0;
3664
3665 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3666 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3667 sw_if_index_set = 1;
3668 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3669 sw_if_index_set = 1;
3670 else if (unformat (i, "enable"))
3671 enable = 1;
3672 else if (unformat (i, "disable"))
3673 enable = 0;
3674 else {
3675 clib_warning ("parse error '%U'", format_unformat_error, i);
3676 return -99;
3677 }
3678 }
3679
3680 if (sw_if_index_set == 0) {
3681 errmsg ("missing interface name or sw_if_index\n");
3682 return -99;
3683 }
3684
3685 M(PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
3686
3687 mp->sw_if_index = ntohl(sw_if_index);
3688 mp->enable_disable = enable;
3689
3690 S; W;
3691 /* NOTREACHED */
3692 return 0;
3693}
3694
3695static int api_mpls_add_del_decap (vat_main_t * vam)
3696{
3697 unformat_input_t * i = vam->input;
3698 vl_api_mpls_add_del_decap_t *mp;
3699 f64 timeout;
3700 u32 rx_vrf_id = 0;
3701 u32 tx_vrf_id = 0;
3702 u32 label = 0;
3703 u8 is_add = 1;
3704 u8 s_bit = 1;
3705 u32 next_index = 1;
3706
3707 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3708 if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
3709 ;
3710 else if (unformat (i, "tx_vrf_id %d", &tx_vrf_id))
3711 ;
3712 else if (unformat (i, "label %d", &label))
3713 ;
3714 else if (unformat (i, "next-index %d", &next_index))
3715 ;
3716 else if (unformat (i, "del"))
3717 is_add = 0;
3718 else if (unformat (i, "s-bit-clear"))
3719 s_bit = 0;
3720 else {
3721 clib_warning ("parse error '%U'", format_unformat_error, i);
3722 return -99;
3723 }
3724 }
3725
3726 M(MPLS_ADD_DEL_DECAP, mpls_add_del_decap);
3727
3728 mp->rx_vrf_id = ntohl(rx_vrf_id);
3729 mp->tx_vrf_id = ntohl(tx_vrf_id);
3730 mp->label = ntohl(label);
3731 mp->next_index = ntohl(next_index);
3732 mp->s_bit = s_bit;
3733 mp->is_add = is_add;
3734
3735 S; W;
3736 /* NOTREACHED */
3737 return 0;
3738}
3739
3740static int api_mpls_add_del_encap (vat_main_t * vam)
3741{
3742 unformat_input_t * i = vam->input;
3743 vl_api_mpls_add_del_encap_t *mp;
3744 f64 timeout;
3745 u32 vrf_id = 0;
3746 u32 *labels = 0;
3747 u32 label;
3748 ip4_address_t dst_address;
3749 u8 is_add = 1;
3750
3751 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3752 if (unformat (i, "vrf %d", &vrf_id))
3753 ;
3754 else if (unformat (i, "label %d", &label))
3755 vec_add1 (labels, ntohl(label));
3756 else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
3757 ;
3758 else if (unformat (i, "del"))
3759 is_add = 0;
3760 else {
3761 clib_warning ("parse error '%U'", format_unformat_error, i);
3762 return -99;
3763 }
3764 }
3765
3766 if (vec_len (labels) == 0) {
3767 errmsg ("missing encap label stack\n");
3768 return -99;
3769 }
3770
3771 M2(MPLS_ADD_DEL_ENCAP, mpls_add_del_encap,
3772 sizeof (u32) * vec_len (labels));
3773
3774 mp->vrf_id = ntohl(vrf_id);
3775 memcpy(mp->dst_address, &dst_address, sizeof (dst_address));
3776 mp->is_add = is_add;
3777 mp->nlabels = vec_len (labels);
3778 memcpy(mp->labels, labels, sizeof(u32)*mp->nlabels);
3779
3780 vec_free(labels);
3781
3782 S; W;
3783 /* NOTREACHED */
3784 return 0;
3785}
3786
3787static int api_mpls_gre_add_del_tunnel (vat_main_t * vam)
3788{
3789 unformat_input_t * i = vam->input;
3790 vl_api_mpls_gre_add_del_tunnel_t *mp;
3791 f64 timeout;
3792 u32 inner_vrf_id = 0;
3793 u32 outer_vrf_id = 0;
3794 ip4_address_t src_address;
3795 ip4_address_t dst_address;
3796 ip4_address_t intfc_address;
3797 u32 tmp;
3798 u8 intfc_address_length = 0;
3799 u8 is_add = 1;
3800 u8 l2_only = 0;
3801
3802 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3803 if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
3804 ;
3805 else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
3806 ;
3807 else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
3808 ;
3809 else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
3810 ;
3811 else if (unformat (i, "adj %U/%d", unformat_ip4_address,
3812 &intfc_address, &tmp))
3813 intfc_address_length = tmp;
3814 else if (unformat (i, "l2-only"))
3815 l2_only = 1;
3816 else if (unformat (i, "del"))
3817 is_add = 0;
3818 else {
3819 clib_warning ("parse error '%U'", format_unformat_error, i);
3820 return -99;
3821 }
3822 }
3823
3824 M(MPLS_GRE_ADD_DEL_TUNNEL, mpls_gre_add_del_tunnel);
3825
3826 mp->inner_vrf_id = ntohl(inner_vrf_id);
3827 mp->outer_vrf_id = ntohl(outer_vrf_id);
3828 memcpy(mp->src_address, &src_address, sizeof (src_address));
3829 memcpy(mp->dst_address, &dst_address, sizeof (dst_address));
3830 memcpy(mp->intfc_address, &intfc_address, sizeof (intfc_address));
3831 mp->intfc_address_length = intfc_address_length;
3832 mp->l2_only = l2_only;
3833 mp->is_add = is_add;
3834
3835 S; W;
3836 /* NOTREACHED */
3837 return 0;
3838}
3839
3840static int api_mpls_ethernet_add_del_tunnel (vat_main_t * vam)
3841{
3842 unformat_input_t * i = vam->input;
3843 vl_api_mpls_ethernet_add_del_tunnel_t *mp;
3844 f64 timeout;
3845 u32 inner_vrf_id = 0;
3846 ip4_address_t intfc_address;
3847 u8 dst_mac_address[6];
3848 int dst_set = 1;
3849 u32 tmp;
3850 u8 intfc_address_length = 0;
3851 u8 is_add = 1;
3852 u8 l2_only = 0;
3853 u32 tx_sw_if_index;
3854 int tx_sw_if_index_set = 0;
3855
3856 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3857 if (unformat (i, "vrf %d", &inner_vrf_id))
3858 ;
3859 else if (unformat (i, "adj %U/%d", unformat_ip4_address,
3860 &intfc_address, &tmp))
3861 intfc_address_length = tmp;
3862 else if (unformat (i, "%U",
3863 unformat_sw_if_index, vam, &tx_sw_if_index))
3864 tx_sw_if_index_set = 1;
3865 else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
3866 tx_sw_if_index_set = 1;
3867 else if (unformat (i, "dst %U", unformat_ethernet_address,
3868 dst_mac_address))
3869 dst_set = 1;
3870 else if (unformat (i, "l2-only"))
3871 l2_only = 1;
3872 else if (unformat (i, "del"))
3873 is_add = 0;
3874 else {
3875 clib_warning ("parse error '%U'", format_unformat_error, i);
3876 return -99;
3877 }
3878 }
3879
3880 if (!dst_set) {
3881 errmsg ("dst (mac address) not set\n");
3882 return -99;
3883 }
3884 if (!tx_sw_if_index_set) {
3885 errmsg ("tx-intfc not set\n");
3886 return -99;
3887 }
3888
3889 M(MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel);
3890
3891 mp->vrf_id = ntohl(inner_vrf_id);
3892 memcpy (mp->adj_address, &intfc_address, sizeof (intfc_address));
3893 mp->adj_address_length = intfc_address_length;
3894 memcpy (mp->dst_mac_address, dst_mac_address, sizeof (dst_mac_address));
3895 mp->tx_sw_if_index = ntohl(tx_sw_if_index);
3896 mp->l2_only = l2_only;
3897 mp->is_add = is_add;
3898
3899 S; W;
3900 /* NOTREACHED */
3901 return 0;
3902}
3903
3904static int api_mpls_ethernet_add_del_tunnel_2 (vat_main_t * vam)
3905{
3906 unformat_input_t * i = vam->input;
3907 vl_api_mpls_ethernet_add_del_tunnel_2_t *mp;
3908 f64 timeout;
3909 u32 inner_vrf_id = 0;
3910 u32 outer_vrf_id = 0;
3911 ip4_address_t adj_address;
3912 int adj_address_set = 0;
3913 ip4_address_t next_hop_address;
3914 int next_hop_address_set = 0;
3915 u32 tmp;
3916 u8 adj_address_length = 0;
3917 u8 l2_only = 0;
3918 u8 is_add = 1;
3919 u32 resolve_attempts = 5;
3920 u8 resolve_if_needed = 1;
3921
3922 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3923 if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
3924 ;
3925 else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
3926 ;
3927 else if (unformat (i, "adj %U/%d", unformat_ip4_address,
3928 &adj_address, &tmp)) {
3929 adj_address_length = tmp;
3930 adj_address_set = 1;
3931 }
3932 else if (unformat (i, "next-hop %U", unformat_ip4_address,
3933 &next_hop_address))
3934 next_hop_address_set = 1;
3935 else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
3936 ;
3937 else if (unformat (i, "resolve-if-needed %d", &tmp))
3938 resolve_if_needed = tmp;
3939 else if (unformat (i, "l2-only"))
3940 l2_only = 1;
3941 else if (unformat (i, "del"))
3942 is_add = 0;
3943 else {
3944 clib_warning ("parse error '%U'", format_unformat_error, i);
3945 return -99;
3946 }
3947 }
3948
3949 if (!adj_address_set) {
3950 errmsg ("adjacency address/mask not set\n");
3951 return -99;
3952 }
3953 if (!next_hop_address_set) {
3954 errmsg ("ip4 next hop address (in outer fib) not set\n");
3955 return -99;
3956 }
3957
3958 M(MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2);
3959
3960 mp->inner_vrf_id = ntohl(inner_vrf_id);
3961 mp->outer_vrf_id = ntohl(outer_vrf_id);
3962 mp->resolve_attempts = ntohl(resolve_attempts);
3963 mp->resolve_if_needed = resolve_if_needed;
3964 mp->is_add = is_add;
3965 mp->l2_only = l2_only;
3966 memcpy (mp->adj_address, &adj_address, sizeof (adj_address));
3967 mp->adj_address_length = adj_address_length;
3968 memcpy (mp->next_hop_ip4_address_in_outer_vrf, &next_hop_address,
3969 sizeof (next_hop_address));
3970
3971 S; W;
3972 /* NOTREACHED */
3973 return 0;
3974}
3975
3976static int api_sw_interface_set_unnumbered (vat_main_t * vam)
3977{
3978 unformat_input_t * i = vam->input;
3979 vl_api_sw_interface_set_unnumbered_t *mp;
3980 f64 timeout;
3981 u32 sw_if_index;
3982 u32 unnum_sw_index;
3983 u8 is_add = 1;
3984 u8 sw_if_index_set = 0;
3985
3986 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3987 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3988 sw_if_index_set = 1;
3989 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3990 sw_if_index_set = 1;
3991 else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
3992 ;
3993 else if (unformat (i, "del"))
3994 is_add = 0;
3995 else {
3996 clib_warning ("parse error '%U'", format_unformat_error, i);
3997 return -99;
3998 }
3999 }
4000
4001 if (sw_if_index_set == 0) {
4002 errmsg ("missing interface name or sw_if_index\n");
4003 return -99;
4004 }
4005
4006 M(SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
4007
4008 mp->sw_if_index = ntohl(sw_if_index);
4009 mp->unnumbered_sw_if_index = ntohl(unnum_sw_index);
4010 mp->is_add = is_add;
4011
4012 S; W;
4013 /* NOTREACHED */
4014 return 0;
4015}
4016
4017static int api_ip_neighbor_add_del (vat_main_t * vam)
4018{
4019 unformat_input_t * i = vam->input;
4020 vl_api_ip_neighbor_add_del_t *mp;
4021 f64 timeout;
4022 u32 sw_if_index;
4023 u8 sw_if_index_set = 0;
4024 u32 vrf_id = 0;
4025 u8 is_add = 1;
4026 u8 is_static = 0;
4027 u8 mac_address[6];
4028 u8 mac_set = 0;
4029 u8 v4_address_set = 0;
4030 u8 v6_address_set = 0;
4031 ip4_address_t v4address;
4032 ip6_address_t v6address;
4033
4034 memset (mac_address, 0, sizeof (mac_address));
4035
4036 /* Parse args required to build the message */
4037 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4038 if (unformat (i, "mac %U", unformat_ethernet_address, mac_address)) {
4039 mac_set = 1;
4040 }
4041 else if (unformat (i, "del"))
4042 is_add = 0;
4043 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4044 sw_if_index_set = 1;
4045 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4046 sw_if_index_set = 1;
4047 else if (unformat (i, "is_static"))
4048 is_static = 1;
4049 else if (unformat (i, "vrf %d", &vrf_id))
4050 ;
4051 else if (unformat (i, "dst %U",
4052 unformat_ip4_address, &v4address))
4053 v4_address_set = 1;
4054 else if (unformat (i, "dst %U",
4055 unformat_ip6_address, &v6address))
4056 v6_address_set = 1;
4057 else {
4058 clib_warning ("parse error '%U'", format_unformat_error, i);
4059 return -99;
4060 }
4061 }
4062
4063 if (sw_if_index_set == 0) {
4064 errmsg ("missing interface name or sw_if_index\n");
4065 return -99;
4066 }
4067 if (v4_address_set && v6_address_set) {
4068 errmsg ("both v4 and v6 addresses set\n");
4069 return -99;
4070 }
4071 if (!v4_address_set && !v6_address_set) {
4072 errmsg ("no addresses set\n");
4073 return -99;
4074 }
4075
4076 /* Construct the API message */
4077 M(IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
4078
4079 mp->sw_if_index = ntohl (sw_if_index);
4080 mp->is_add = is_add;
4081 mp->vrf_id = ntohl (vrf_id);
4082 mp->is_static = is_static;
4083 if (mac_set)
4084 memcpy (mp->mac_address, mac_address, 6);
4085 if (v6_address_set) {
4086 mp->is_ipv6 = 1;
4087 memcpy (mp->dst_address, &v6address, sizeof (v6address));
4088 } else {
4089 /* mp->is_ipv6 = 0; via memset in M macro above */
4090 memcpy (mp->dst_address, &v4address, sizeof (v4address));
4091 }
4092
4093 /* send it... */
4094 S;
4095
4096 /* Wait for a reply, return good/bad news */
4097 W;
4098
4099 /* NOTREACHED */
4100 return 0;
4101}
4102
4103static int api_reset_vrf (vat_main_t * vam)
4104{
4105 unformat_input_t * i = vam->input;
4106 vl_api_reset_vrf_t *mp;
4107 f64 timeout;
4108 u32 vrf_id = 0;
4109 u8 is_ipv6 = 0;
4110 u8 vrf_id_set = 0;
4111
4112 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4113 if (unformat (i, "vrf %d", &vrf_id))
4114 vrf_id_set = 1;
4115 else if (unformat (i, "ipv6"))
4116 is_ipv6 = 1;
4117 else {
4118 clib_warning ("parse error '%U'", format_unformat_error, i);
4119 return -99;
4120 }
4121 }
4122
4123 if (vrf_id_set == 0) {
4124 errmsg ("missing vrf id\n");
4125 return -99;
4126 }
4127
4128 M(RESET_VRF, reset_vrf);
4129
4130 mp->vrf_id = ntohl(vrf_id);
4131 mp->is_ipv6 = is_ipv6;
4132
4133 S; W;
4134 /* NOTREACHED */
4135 return 0;
4136}
4137
4138static int api_create_vlan_subif (vat_main_t * vam)
4139{
4140 unformat_input_t * i = vam->input;
4141 vl_api_create_vlan_subif_t *mp;
4142 f64 timeout;
4143 u32 sw_if_index;
4144 u8 sw_if_index_set = 0;
4145 u32 vlan_id;
4146 u8 vlan_id_set = 0;
4147
4148 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4149 if (unformat (i, "sw_if_index %d", &sw_if_index))
4150 sw_if_index_set = 1;
4151 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4152 sw_if_index_set = 1;
4153 else if (unformat (i, "vlan %d", &vlan_id))
4154 vlan_id_set = 1;
4155 else {
4156 clib_warning ("parse error '%U'", format_unformat_error, i);
4157 return -99;
4158 }
4159 }
4160
4161 if (sw_if_index_set == 0) {
4162 errmsg ("missing interface name or sw_if_index\n");
4163 return -99;
4164 }
4165
4166 if (vlan_id_set == 0) {
4167 errmsg ("missing vlan_id\n");
4168 return -99;
4169 }
4170 M(CREATE_VLAN_SUBIF, create_vlan_subif);
4171
4172 mp->sw_if_index = ntohl(sw_if_index);
4173 mp->vlan_id = ntohl(vlan_id);
4174
4175 S; W;
4176 /* NOTREACHED */
4177 return 0;
4178}
4179
4180#define foreach_create_subif_bit \
4181_(no_tags) \
4182_(one_tag) \
4183_(two_tags) \
4184_(dot1ad) \
4185_(exact_match) \
4186_(default_sub) \
4187_(outer_vlan_id_any) \
4188_(inner_vlan_id_any)
4189
4190static int api_create_subif (vat_main_t * vam)
4191{
4192 unformat_input_t * i = vam->input;
4193 vl_api_create_subif_t *mp;
4194 f64 timeout;
4195 u32 sw_if_index;
4196 u8 sw_if_index_set = 0;
4197 u32 sub_id;
4198 u8 sub_id_set = 0;
4199 u32 no_tags = 0;
4200 u32 one_tag = 0;
4201 u32 two_tags = 0;
4202 u32 dot1ad = 0;
4203 u32 exact_match = 0;
4204 u32 default_sub = 0;
4205 u32 outer_vlan_id_any = 0;
4206 u32 inner_vlan_id_any = 0;
4207 u32 tmp;
4208 u16 outer_vlan_id = 0;
4209 u16 inner_vlan_id = 0;
4210
4211 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4212 if (unformat (i, "sw_if_index %d", &sw_if_index))
4213 sw_if_index_set = 1;
4214 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4215 sw_if_index_set = 1;
4216 else if (unformat (i, "sub_id %d", &sub_id))
4217 sub_id_set = 1;
4218 else if (unformat (i, "outer_vlan_id %d", &tmp))
4219 outer_vlan_id = tmp;
4220 else if (unformat (i, "inner_vlan_id %d", &tmp))
4221 inner_vlan_id = tmp;
4222
4223#define _(a) else if (unformat (i, #a)) a = 1 ;
4224 foreach_create_subif_bit
4225#undef _
4226
4227 else {
4228 clib_warning ("parse error '%U'", format_unformat_error, i);
4229 return -99;
4230 }
4231 }
4232
4233 if (sw_if_index_set == 0) {
4234 errmsg ("missing interface name or sw_if_index\n");
4235 return -99;
4236 }
4237
4238 if (sub_id_set == 0) {
4239 errmsg ("missing sub_id\n");
4240 return -99;
4241 }
4242 M(CREATE_SUBIF, create_subif);
4243
4244 mp->sw_if_index = ntohl(sw_if_index);
4245 mp->sub_id = ntohl(sub_id);
4246
4247#define _(a) mp->a = a;
4248 foreach_create_subif_bit;
4249#undef _
4250
4251 mp->outer_vlan_id = ntohs (outer_vlan_id);
4252 mp->inner_vlan_id = ntohs (inner_vlan_id);
4253
4254 S; W;
4255 /* NOTREACHED */
4256 return 0;
4257}
4258
4259static int api_oam_add_del (vat_main_t * vam)
4260{
4261 unformat_input_t * i = vam->input;
4262 vl_api_oam_add_del_t *mp;
4263 f64 timeout;
4264 u32 vrf_id = 0;
4265 u8 is_add = 1;
4266 ip4_address_t src, dst;
4267 u8 src_set = 0;
4268 u8 dst_set = 0;
4269
4270 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4271 if (unformat (i, "vrf %d", &vrf_id))
4272 ;
4273 else if (unformat (i, "src %U", unformat_ip4_address, &src))
4274 src_set = 1;
4275 else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
4276 dst_set = 1;
4277 else if (unformat (i, "del"))
4278 is_add = 0;
4279 else {
4280 clib_warning ("parse error '%U'", format_unformat_error, i);
4281 return -99;
4282 }
4283 }
4284
4285 if (src_set == 0) {
4286 errmsg ("missing src addr\n");
4287 return -99;
4288 }
4289
4290 if (dst_set == 0) {
4291 errmsg ("missing dst addr\n");
4292 return -99;
4293 }
4294
4295 M(OAM_ADD_DEL, oam_add_del);
4296
4297 mp->vrf_id = ntohl(vrf_id);
4298 mp->is_add = is_add;
4299 memcpy(mp->src_address, &src, sizeof (mp->src_address));
4300 memcpy(mp->dst_address, &dst, sizeof (mp->dst_address));
4301
4302 S; W;
4303 /* NOTREACHED */
4304 return 0;
4305}
4306
4307static int api_reset_fib (vat_main_t * vam)
4308{
4309 unformat_input_t * i = vam->input;
4310 vl_api_reset_fib_t *mp;
4311 f64 timeout;
4312 u32 vrf_id = 0;
4313 u8 is_ipv6 = 0;
4314 u8 vrf_id_set = 0;
4315
4316 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4317 if (unformat (i, "vrf %d", &vrf_id))
4318 vrf_id_set = 1;
4319 else if (unformat (i, "ipv6"))
4320 is_ipv6 = 1;
4321 else {
4322 clib_warning ("parse error '%U'", format_unformat_error, i);
4323 return -99;
4324 }
4325 }
4326
4327 if (vrf_id_set == 0) {
4328 errmsg ("missing vrf id\n");
4329 return -99;
4330 }
4331
4332 M(RESET_FIB, reset_fib);
4333
4334 mp->vrf_id = ntohl(vrf_id);
4335 mp->is_ipv6 = is_ipv6;
4336
4337 S; W;
4338 /* NOTREACHED */
4339 return 0;
4340}
4341
4342static int api_dhcp_proxy_config (vat_main_t * vam)
4343{
4344 unformat_input_t * i = vam->input;
4345 vl_api_dhcp_proxy_config_t *mp;
4346 f64 timeout;
4347 u32 vrf_id = 0;
4348 u8 is_add = 1;
4349 u8 insert_cid = 1;
4350 u8 v4_address_set = 0;
4351 u8 v6_address_set = 0;
4352 ip4_address_t v4address;
4353 ip6_address_t v6address;
4354 u8 v4_src_address_set = 0;
4355 u8 v6_src_address_set = 0;
4356 ip4_address_t v4srcaddress;
4357 ip6_address_t v6srcaddress;
4358
4359 /* Parse args required to build the message */
4360 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4361 if (unformat (i, "del"))
4362 is_add = 0;
4363 else if (unformat (i, "vrf %d", &vrf_id))
4364 ;
4365 else if (unformat (i, "insert-cid %d", &insert_cid))
4366 ;
4367 else if (unformat (i, "svr %U",
4368 unformat_ip4_address, &v4address))
4369 v4_address_set = 1;
4370 else if (unformat (i, "svr %U",
4371 unformat_ip6_address, &v6address))
4372 v6_address_set = 1;
4373 else if (unformat (i, "src %U",
4374 unformat_ip4_address, &v4srcaddress))
4375 v4_src_address_set = 1;
4376 else if (unformat (i, "src %U",
4377 unformat_ip6_address, &v6srcaddress))
4378 v6_src_address_set = 1;
4379 else
4380 break;
4381 }
4382
4383 if (v4_address_set && v6_address_set) {
4384 errmsg ("both v4 and v6 server addresses set\n");
4385 return -99;
4386 }
4387 if (!v4_address_set && !v6_address_set) {
4388 errmsg ("no server addresses set\n");
4389 return -99;
4390 }
4391
4392 if (v4_src_address_set && v6_src_address_set) {
4393 errmsg ("both v4 and v6 src addresses set\n");
4394 return -99;
4395 }
4396 if (!v4_src_address_set && !v6_src_address_set) {
4397 errmsg ("no src addresses set\n");
4398 return -99;
4399 }
4400
4401 if (!(v4_src_address_set && v4_address_set) &&
4402 !(v6_src_address_set && v6_address_set)) {
4403 errmsg ("no matching server and src addresses set\n");
4404 return -99;
4405 }
4406
4407 /* Construct the API message */
4408 M(DHCP_PROXY_CONFIG, dhcp_proxy_config);
4409
4410 mp->insert_circuit_id = insert_cid;
4411 mp->is_add = is_add;
4412 mp->vrf_id = ntohl (vrf_id);
4413 if (v6_address_set) {
4414 mp->is_ipv6 = 1;
4415 memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
4416 memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
4417 } else {
4418 memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
4419 memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
4420 }
4421
4422 /* send it... */
4423 S;
4424
4425 /* Wait for a reply, return good/bad news */
4426 W;
4427 /* NOTREACHED */
4428 return 0;
4429}
4430
4431static int api_dhcp_proxy_config_2 (vat_main_t * vam)
4432{
4433 unformat_input_t * i = vam->input;
4434 vl_api_dhcp_proxy_config_2_t *mp;
4435 f64 timeout;
4436 u32 rx_vrf_id = 0;
4437 u32 server_vrf_id = 0;
4438 u8 is_add = 1;
4439 u8 insert_cid = 1;
4440 u8 v4_address_set = 0;
4441 u8 v6_address_set = 0;
4442 ip4_address_t v4address;
4443 ip6_address_t v6address;
4444 u8 v4_src_address_set = 0;
4445 u8 v6_src_address_set = 0;
4446 ip4_address_t v4srcaddress;
4447 ip6_address_t v6srcaddress;
4448
4449 /* Parse args required to build the message */
4450 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4451 if (unformat (i, "del"))
4452 is_add = 0;
4453 else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
4454 ;
4455 else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
4456 ;
4457 else if (unformat (i, "insert-cid %d", &insert_cid))
4458 ;
4459 else if (unformat (i, "svr %U",
4460 unformat_ip4_address, &v4address))
4461 v4_address_set = 1;
4462 else if (unformat (i, "svr %U",
4463 unformat_ip6_address, &v6address))
4464 v6_address_set = 1;
4465 else if (unformat (i, "src %U",
4466 unformat_ip4_address, &v4srcaddress))
4467 v4_src_address_set = 1;
4468 else if (unformat (i, "src %U",
4469 unformat_ip6_address, &v6srcaddress))
4470 v6_src_address_set = 1;
4471 else
4472 break;
4473 }
4474
4475 if (v4_address_set && v6_address_set) {
4476 errmsg ("both v4 and v6 server addresses set\n");
4477 return -99;
4478 }
4479 if (!v4_address_set && !v6_address_set) {
4480 errmsg ("no server addresses set\n");
4481 return -99;
4482 }
4483
4484 if (v4_src_address_set && v6_src_address_set) {
4485 errmsg ("both v4 and v6 src addresses set\n");
4486 return -99;
4487 }
4488 if (!v4_src_address_set && !v6_src_address_set) {
4489 errmsg ("no src addresses set\n");
4490 return -99;
4491 }
4492
4493 if (!(v4_src_address_set && v4_address_set) &&
4494 !(v6_src_address_set && v6_address_set)) {
4495 errmsg ("no matching server and src addresses set\n");
4496 return -99;
4497 }
4498
4499 /* Construct the API message */
4500 M(DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
4501
4502 mp->insert_circuit_id = insert_cid;
4503 mp->is_add = is_add;
4504 mp->rx_vrf_id = ntohl (rx_vrf_id);
4505 mp->server_vrf_id = ntohl (server_vrf_id);
4506 if (v6_address_set) {
4507 mp->is_ipv6 = 1;
4508 memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
4509 memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
4510 } else {
4511 memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
4512 memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
4513 }
4514
4515 /* send it... */
4516 S;
4517
4518 /* Wait for a reply, return good/bad news */
4519 W;
4520 /* NOTREACHED */
4521 return 0;
4522}
4523
4524static int api_dhcp_proxy_set_vss (vat_main_t * vam)
4525{
4526 unformat_input_t * i = vam->input;
4527 vl_api_dhcp_proxy_set_vss_t *mp;
4528 f64 timeout;
4529 u8 is_ipv6 = 0;
4530 u8 is_add = 1;
4531 u32 tbl_id;
4532 u8 tbl_id_set = 0;
4533 u32 oui;
4534 u8 oui_set = 0;
4535 u32 fib_id;
4536 u8 fib_id_set = 0;
4537
4538 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4539 if (unformat (i, "tbl_id %d", &tbl_id))
4540 tbl_id_set = 1;
4541 if (unformat (i, "fib_id %d", &fib_id))
4542 fib_id_set = 1;
4543 if (unformat (i, "oui %d", &oui))
4544 oui_set = 1;
4545 else if (unformat (i, "ipv6"))
4546 is_ipv6 = 1;
4547 else if (unformat (i, "del"))
4548 is_add = 0;
4549 else {
4550 clib_warning ("parse error '%U'", format_unformat_error, i);
4551 return -99;
4552 }
4553 }
4554
4555 if (tbl_id_set == 0) {
4556 errmsg ("missing tbl id\n");
4557 return -99;
4558 }
4559
4560 if (fib_id_set == 0) {
4561 errmsg ("missing fib id\n");
4562 return -99;
4563 }
4564 if (oui_set == 0) {
4565 errmsg ("missing oui\n");
4566 return -99;
4567 }
4568
4569 M(DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
4570 mp->tbl_id = ntohl(tbl_id);
4571 mp->fib_id = ntohl(fib_id);
4572 mp->oui = ntohl(oui);
4573 mp->is_ipv6 = is_ipv6;
4574 mp->is_add = is_add;
4575
4576 S; W;
4577 /* NOTREACHED */
4578 return 0;
4579}
4580
4581static int api_dhcp_client_config (vat_main_t * vam)
4582{
4583 unformat_input_t * i = vam->input;
4584 vl_api_dhcp_client_config_t *mp;
4585 f64 timeout;
4586 u32 sw_if_index;
4587 u8 sw_if_index_set = 0;
4588 u8 is_add = 1;
4589 u8 * hostname = 0;
4590 u8 disable_event = 0;
4591
4592 /* Parse args required to build the message */
4593 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4594 if (unformat (i, "del"))
4595 is_add = 0;
4596 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4597 sw_if_index_set = 1;
4598 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4599 sw_if_index_set = 1;
4600 else if (unformat (i, "hostname %s", &hostname))
4601 ;
4602 else if (unformat (i, "disable_event"))
4603 disable_event = 1;
4604 else
4605 break;
4606 }
4607
4608 if (sw_if_index_set == 0) {
4609 errmsg ("missing interface name or sw_if_index\n");
4610 return -99;
4611 }
4612
4613 if (vec_len (hostname) > 63) {
4614 errmsg ("hostname too long\n");
4615 }
4616 vec_add1 (hostname, 0);
4617
4618 /* Construct the API message */
4619 M(DHCP_CLIENT_CONFIG, dhcp_client_config);
4620
4621 mp->sw_if_index = ntohl (sw_if_index);
4622 memcpy (mp->hostname, hostname, vec_len (hostname));
4623 vec_free (hostname);
4624 mp->is_add = is_add;
4625 mp->want_dhcp_event = disable_event ? 0 : 1;
4626 mp->pid = getpid();
4627
4628 /* send it... */
4629 S;
4630
4631 /* Wait for a reply, return good/bad news */
4632 W;
4633 /* NOTREACHED */
4634 return 0;
4635}
4636
4637static int api_set_ip_flow_hash (vat_main_t * vam)
4638{
4639 unformat_input_t * i = vam->input;
4640 vl_api_set_ip_flow_hash_t *mp;
4641 f64 timeout;
4642 u32 vrf_id = 0;
4643 u8 is_ipv6 = 0;
4644 u8 vrf_id_set = 0;
4645 u8 src = 0;
4646 u8 dst = 0;
4647 u8 sport = 0;
4648 u8 dport = 0;
4649 u8 proto = 0;
4650 u8 reverse = 0;
4651
4652 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4653 if (unformat (i, "vrf %d", &vrf_id))
4654 vrf_id_set = 1;
4655 else if (unformat (i, "ipv6"))
4656 is_ipv6 = 1;
4657 else if (unformat (i, "src"))
4658 src = 1;
4659 else if (unformat (i, "dst"))
4660 dst = 1;
4661 else if (unformat (i, "sport"))
4662 sport = 1;
4663 else if (unformat (i, "dport"))
4664 dport = 1;
4665 else if (unformat (i, "proto"))
4666 proto = 1;
4667 else if (unformat (i, "reverse"))
4668 reverse = 1;
4669
4670 else {
4671 clib_warning ("parse error '%U'", format_unformat_error, i);
4672 return -99;
4673 }
4674 }
4675
4676 if (vrf_id_set == 0) {
4677 errmsg ("missing vrf id\n");
4678 return -99;
4679 }
4680
4681 M(SET_IP_FLOW_HASH, set_ip_flow_hash);
4682 mp->src = src;
4683 mp->dst = dst;
4684 mp->sport = sport;
4685 mp->dport = dport;
4686 mp->proto = proto;
4687 mp->reverse = reverse;
4688 mp->vrf_id = ntohl(vrf_id);
4689 mp->is_ipv6 = is_ipv6;
4690
4691 S; W;
4692 /* NOTREACHED */
4693 return 0;
4694}
4695
4696static int api_sw_interface_ip6_enable_disable (vat_main_t * vam)
4697{
4698 unformat_input_t * i = vam->input;
4699 vl_api_sw_interface_ip6_enable_disable_t *mp;
4700 f64 timeout;
4701 u32 sw_if_index;
4702 u8 sw_if_index_set = 0;
4703 u8 enable = 0;
4704
4705 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4706 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4707 sw_if_index_set = 1;
4708 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4709 sw_if_index_set = 1;
4710 else if (unformat (i, "enable"))
4711 enable = 1;
4712 else if (unformat (i, "disable"))
4713 enable = 0;
4714 else {
4715 clib_warning ("parse error '%U'", format_unformat_error, i);
4716 return -99;
4717 }
4718 }
4719
4720 if (sw_if_index_set == 0) {
4721 errmsg ("missing interface name or sw_if_index\n");
4722 return -99;
4723 }
4724
4725 M(SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
4726
4727 mp->sw_if_index = ntohl(sw_if_index);
4728 mp->enable = enable;
4729
4730 S; W;
4731 /* NOTREACHED */
4732 return 0;
4733}
4734
4735static int api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
4736{
4737 unformat_input_t * i = vam->input;
4738 vl_api_sw_interface_ip6_set_link_local_address_t *mp;
4739 f64 timeout;
4740 u32 sw_if_index;
4741 u8 sw_if_index_set = 0;
4742 u32 address_length = 0;
4743 u8 v6_address_set = 0;
4744 ip6_address_t v6address;
4745
4746 /* Parse args required to build the message */
4747 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4748 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4749 sw_if_index_set = 1;
4750 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4751 sw_if_index_set = 1;
4752 else if (unformat (i, "%U/%d",
4753 unformat_ip6_address, &v6address,
4754 &address_length))
4755 v6_address_set = 1;
4756 else
4757 break;
4758 }
4759
4760 if (sw_if_index_set == 0) {
4761 errmsg ("missing interface name or sw_if_index\n");
4762 return -99;
4763 }
4764 if (!v6_address_set) {
4765 errmsg ("no address set\n");
4766 return -99;
4767 }
4768
4769 /* Construct the API message */
4770 M(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, \
4771 sw_interface_ip6_set_link_local_address);
4772
4773 mp->sw_if_index = ntohl (sw_if_index);
4774 memcpy (mp->address, &v6address, sizeof (v6address));
4775 mp->address_length = address_length;
4776
4777 /* send it... */
4778 S;
4779
4780 /* Wait for a reply, return good/bad news */
4781 W;
4782
4783 /* NOTREACHED */
4784 return 0;
4785}
4786
4787
4788static int api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
4789{
4790 unformat_input_t * i = vam->input;
4791 vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
4792 f64 timeout;
4793 u32 sw_if_index;
4794 u8 sw_if_index_set = 0;
4795 u32 address_length = 0;
4796 u8 v6_address_set = 0;
4797 ip6_address_t v6address;
4798 u8 use_default = 0;
4799 u8 no_advertise = 0;
4800 u8 off_link = 0;
4801 u8 no_autoconfig = 0;
4802 u8 no_onlink = 0;
4803 u8 is_no = 0;
4804 u32 val_lifetime = 0;
4805 u32 pref_lifetime = 0;
4806
4807 /* Parse args required to build the message */
4808 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4809 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4810 sw_if_index_set = 1;
4811 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4812 sw_if_index_set = 1;
4813 else if (unformat (i, "%U/%d",
4814 unformat_ip6_address, &v6address,
4815 &address_length))
4816 v6_address_set = 1;
4817 else if (unformat (i, "val_life %d", &val_lifetime))
4818 ;
4819 else if (unformat (i, "pref_life %d", &pref_lifetime))
4820 ;
4821 else if (unformat (i, "def"))
4822 use_default = 1;
4823 else if (unformat (i, "noadv"))
4824 no_advertise = 1;
4825 else if (unformat (i, "offl"))
4826 off_link = 1;
4827 else if (unformat (i, "noauto"))
4828 no_autoconfig = 1;
4829 else if (unformat (i, "nolink"))
4830 no_onlink = 1;
4831 else if (unformat (i, "isno"))
4832 is_no = 1;
4833 else {
4834 clib_warning ("parse error '%U'", format_unformat_error, i);
4835 return -99;
4836 }
4837 }
4838
4839 if (sw_if_index_set == 0) {
4840 errmsg ("missing interface name or sw_if_index\n");
4841 return -99;
4842 }
4843 if (!v6_address_set) {
4844 errmsg ("no address set\n");
4845 return -99;
4846 }
4847
4848 /* Construct the API message */
4849 M(SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
4850
4851 mp->sw_if_index = ntohl (sw_if_index);
4852 memcpy (mp->address, &v6address, sizeof (v6address));
4853 mp->address_length = address_length;
4854 mp->use_default = use_default;
4855 mp->no_advertise = no_advertise;
4856 mp->off_link = off_link;
4857 mp->no_autoconfig = no_autoconfig;
4858 mp->no_onlink = no_onlink;
4859 mp->is_no = is_no;
4860 mp->val_lifetime = ntohl(val_lifetime);
4861 mp->pref_lifetime = ntohl(pref_lifetime);
4862
4863 /* send it... */
4864 S;
4865
4866 /* Wait for a reply, return good/bad news */
4867 W;
4868
4869 /* NOTREACHED */
4870 return 0;
4871}
4872
4873static int api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
4874{
4875 unformat_input_t * i = vam->input;
4876 vl_api_sw_interface_ip6nd_ra_config_t *mp;
4877 f64 timeout;
4878 u32 sw_if_index;
4879 u8 sw_if_index_set = 0;
4880 u8 surpress = 0;
4881 u8 managed = 0;
4882 u8 other = 0;
4883 u8 ll_option = 0;
4884 u8 send_unicast = 0;
4885 u8 cease = 0;
4886 u8 is_no = 0;
4887 u8 default_router = 0;
4888 u32 max_interval = 0;
4889 u32 min_interval = 0;
4890 u32 lifetime = 0;
4891 u32 initial_count = 0;
4892 u32 initial_interval = 0;
4893
4894
4895 /* Parse args required to build the message */
4896 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4897 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4898 sw_if_index_set = 1;
4899 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4900 sw_if_index_set = 1;
4901 else if (unformat (i, "maxint %d", &max_interval))
4902 ;
4903 else if (unformat (i, "minint %d", &min_interval))
4904 ;
4905 else if (unformat (i, "life %d", &lifetime))
4906 ;
4907 else if (unformat (i, "count %d", &initial_count))
4908 ;
4909 else if (unformat (i, "interval %d", &initial_interval))
4910 ;
4911 else if (unformat (i, "surpress"))
4912 surpress = 1;
4913 else if (unformat (i, "managed"))
4914 managed = 1;
4915 else if (unformat (i, "other"))
4916 other = 1;
4917 else if (unformat (i, "ll"))
4918 ll_option = 1;
4919 else if (unformat (i, "send"))
4920 send_unicast = 1;
4921 else if (unformat (i, "cease"))
4922 cease = 1;
4923 else if (unformat (i, "isno"))
4924 is_no = 1;
4925 else if (unformat (i, "def"))
4926 default_router = 1;
4927 else {
4928 clib_warning ("parse error '%U'", format_unformat_error, i);
4929 return -99;
4930 }
4931 }
4932
4933 if (sw_if_index_set == 0) {
4934 errmsg ("missing interface name or sw_if_index\n");
4935 return -99;
4936 }
4937
4938 /* Construct the API message */
4939 M(SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
4940
4941 mp->sw_if_index = ntohl (sw_if_index);
4942 mp->max_interval = ntohl(max_interval);
4943 mp->min_interval = ntohl(min_interval);
4944 mp->lifetime = ntohl(lifetime);
4945 mp->initial_count = ntohl(initial_count);
4946 mp->initial_interval = ntohl(initial_interval);
4947 mp->surpress = surpress;
4948 mp->managed = managed;
4949 mp->other = other;
4950 mp->ll_option = ll_option;
4951 mp->send_unicast = send_unicast;
4952 mp->cease = cease;
4953 mp->is_no = is_no;
4954 mp->default_router = default_router;
4955
4956 /* send it... */
4957 S;
4958
4959 /* Wait for a reply, return good/bad news */
4960 W;
4961
4962 /* NOTREACHED */
4963 return 0;
4964}
4965
4966static int api_set_arp_neighbor_limit (vat_main_t * vam)
4967{
4968 unformat_input_t * i = vam->input;
4969 vl_api_set_arp_neighbor_limit_t *mp;
4970 f64 timeout;
4971 u32 arp_nbr_limit;
4972 u8 limit_set = 0;
4973 u8 is_ipv6 = 0;
4974
4975 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4976 if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
4977 limit_set = 1;
4978 else if (unformat (i, "ipv6"))
4979 is_ipv6 = 1;
4980 else {
4981 clib_warning ("parse error '%U'", format_unformat_error, i);
4982 return -99;
4983 }
4984 }
4985
4986 if (limit_set == 0) {
4987 errmsg ("missing limit value\n");
4988 return -99;
4989 }
4990
4991 M(SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
4992
4993 mp->arp_neighbor_limit = ntohl(arp_nbr_limit);
4994 mp->is_ipv6 = is_ipv6;
4995
4996 S; W;
4997 /* NOTREACHED */
4998 return 0;
4999}
5000
5001static int api_l2_patch_add_del (vat_main_t * vam)
5002{
5003 unformat_input_t * i = vam->input;
5004 vl_api_l2_patch_add_del_t *mp;
5005 f64 timeout;
5006 u32 rx_sw_if_index;
5007 u8 rx_sw_if_index_set = 0;
5008 u32 tx_sw_if_index;
5009 u8 tx_sw_if_index_set = 0;
5010 u8 is_add = 1;
5011
5012 /* Parse args required to build the message */
5013 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5014 if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5015 rx_sw_if_index_set = 1;
5016 else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5017 tx_sw_if_index_set = 1;
5018 else if (unformat (i, "rx")) {
5019 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5020 if (unformat (i, "%U", unformat_sw_if_index, vam,
5021 &rx_sw_if_index))
5022 rx_sw_if_index_set = 1;
5023 } else
5024 break;
5025 } else if (unformat (i, "tx")) {
5026 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5027 if (unformat (i, "%U", unformat_sw_if_index, vam,
5028 &tx_sw_if_index))
5029 tx_sw_if_index_set = 1;
5030 } else
5031 break;
5032 } else if (unformat (i, "del"))
5033 is_add = 0;
5034 else
5035 break;
5036 }
5037
5038 if (rx_sw_if_index_set == 0) {
5039 errmsg ("missing rx interface name or rx_sw_if_index\n");
5040 return -99;
5041 }
5042
5043 if (tx_sw_if_index_set == 0) {
5044 errmsg ("missing tx interface name or tx_sw_if_index\n");
5045 return -99;
5046 }
5047
5048 M(L2_PATCH_ADD_DEL, l2_patch_add_del);
5049
5050 mp->rx_sw_if_index = ntohl(rx_sw_if_index);
5051 mp->tx_sw_if_index = ntohl(tx_sw_if_index);
5052 mp->is_add = is_add;
5053
5054 S; W;
5055 /* NOTREACHED */
5056 return 0;
5057}
5058
5059static int api_sr_tunnel_add_del (vat_main_t * vam)
5060{
5061 unformat_input_t * i = vam->input;
5062 vl_api_sr_tunnel_add_del_t *mp;
5063 f64 timeout;
5064 int is_del = 0;
5065 int pl_index;
5066 ip6_address_t src_address;
5067 int src_address_set = 0;
5068 ip6_address_t dst_address;
5069 u32 dst_mask_width;
5070 int dst_address_set = 0;
5071 u16 flags = 0;
5072 u32 rx_table_id = 0;
5073 u32 tx_table_id = 0;
5074 ip6_address_t * segments = 0;
5075 ip6_address_t * this_seg;
5076 ip6_address_t * tags = 0;
5077 ip6_address_t * this_tag;
5078 ip6_address_t next_address, tag;
5079
5080 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5081 {
5082 if (unformat (i, "del"))
5083 is_del = 1;
5084 else if (unformat (i, "rx_fib_id %d", &rx_table_id))
5085 ;
5086 else if (unformat (i, "tx_fib_id %d", &tx_table_id))
5087 ;
5088 else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
5089 src_address_set = 1;
5090 else if (unformat (i, "dst %U/%d",
5091 unformat_ip6_address, &dst_address,
5092 &dst_mask_width))
5093 dst_address_set = 1;
5094 else if (unformat (i, "next %U", unformat_ip6_address,
5095 &next_address))
5096 {
5097 vec_add2 (segments, this_seg, 1);
5098 memcpy (this_seg->as_u8, next_address.as_u8, sizeof (*this_seg));
5099 }
5100 else if (unformat (i, "tag %U", unformat_ip6_address,
5101 &tag))
5102 {
5103 vec_add2 (tags, this_tag, 1);
5104 memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
5105 }
5106 else if (unformat (i, "clean"))
5107 flags |= IP6_SR_HEADER_FLAG_CLEANUP;
5108 else if (unformat (i, "protected"))
5109 flags |= IP6_SR_HEADER_FLAG_PROTECTED;
5110 else if (unformat (i, "InPE %d", &pl_index))
5111 {
5112 if (pl_index <= 0 || pl_index > 4)
5113 {
5114 pl_index_range_error:
5115 errmsg ("pl index %d out of range\n", pl_index);
5116 return -99;
5117 }
5118 flags |= IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3*(pl_index - 1));
5119 }
5120 else if (unformat (i, "EgPE %d", &pl_index))
5121 {
5122 if (pl_index <= 0 || pl_index > 4)
5123 goto pl_index_range_error;
5124 flags |= IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3*(pl_index - 1));
5125 }
5126 else if (unformat (i, "OrgSrc %d", &pl_index))
5127 {
5128 if (pl_index <= 0 || pl_index > 4)
5129 goto pl_index_range_error;
5130 flags |= IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3*(pl_index - 1));
5131 }
5132 else
5133 break;
5134 }
5135
5136 if (!src_address_set)
5137 {
5138 errmsg ("src address required\n");
5139 return -99;
5140 }
5141
5142 if (!dst_address_set)
5143 {
5144 errmsg ("dst address required\n");
5145 return -99;
5146 }
5147
5148 if (!segments)
5149 {
5150 errmsg ("at least one sr segment required\n");
5151 return -99;
5152 }
5153
5154 M2(SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
5155 vec_len(segments) * sizeof (ip6_address_t)
5156 + vec_len(tags) * sizeof (ip6_address_t));
5157
5158 memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
5159 memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
5160 mp->dst_mask_width = dst_mask_width;
5161 mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
5162 mp->n_segments = vec_len (segments);
5163 mp->n_tags = vec_len (tags);
5164 mp->is_add = is_del == 0;
5165 memcpy (mp->segs_and_tags, segments,
5166 vec_len(segments)* sizeof (ip6_address_t));
5167 memcpy (mp->segs_and_tags + vec_len(segments)*sizeof (ip6_address_t),
5168 tags, vec_len(tags)* sizeof (ip6_address_t));
5169
5170 mp->outer_vrf_id = ntohl (rx_table_id);
5171 mp->inner_vrf_id = ntohl (tx_table_id);
5172
5173 vec_free (segments);
5174 vec_free (tags);
5175
5176 S; W;
5177 /* NOTREACHED */
5178}
5179
5180
5181#define foreach_ip4_proto_field \
5182_(src_address) \
5183_(dst_address) \
5184_(tos) \
5185_(length) \
5186_(fragment_id) \
5187_(ttl) \
5188_(protocol) \
5189_(checksum)
5190
5191uword unformat_ip4_mask (unformat_input_t * input, va_list * args)
5192{
5193 u8 ** maskp = va_arg (*args, u8 **);
5194 u8 * mask = 0;
5195 u8 found_something = 0;
5196 ip4_header_t * ip;
5197
5198#define _(a) u8 a=0;
5199 foreach_ip4_proto_field;
5200#undef _
5201 u8 version = 0;
5202 u8 hdr_length = 0;
5203
5204
5205 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5206 {
5207 if (unformat (input, "version"))
5208 version = 1;
5209 else if (unformat (input, "hdr_length"))
5210 hdr_length = 1;
5211 else if (unformat (input, "src"))
5212 src_address = 1;
5213 else if (unformat (input, "dst"))
5214 dst_address = 1;
5215 else if (unformat (input, "proto"))
5216 protocol = 1;
5217
5218#define _(a) else if (unformat (input, #a)) a=1;
5219 foreach_ip4_proto_field
5220#undef _
5221 else
5222 break;
5223 }
5224
5225#define _(a) found_something += a;
5226 foreach_ip4_proto_field;
5227#undef _
5228
5229 if (found_something == 0)
5230 return 0;
5231
5232 vec_validate (mask, sizeof (*ip) - 1);
5233
5234 ip = (ip4_header_t *) mask;
5235
5236#define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
5237 foreach_ip4_proto_field;
5238#undef _
5239
5240 ip->ip_version_and_header_length = 0;
5241
5242 if (version)
5243 ip->ip_version_and_header_length |= 0xF0;
5244
5245 if (hdr_length)
5246 ip->ip_version_and_header_length |= 0x0F;
5247
5248 *maskp = mask;
5249 return 1;
5250}
5251
5252#define foreach_ip6_proto_field \
5253_(src_address) \
5254_(dst_address) \
5255_(payload_length) \
5256_(hop_limit) \
5257_(protocol)
5258
5259uword unformat_ip6_mask (unformat_input_t * input, va_list * args)
5260{
5261 u8 ** maskp = va_arg (*args, u8 **);
5262 u8 * mask = 0;
5263 u8 found_something = 0;
5264 ip6_header_t * ip;
5265 u32 ip_version_traffic_class_and_flow_label;
5266
5267#define _(a) u8 a=0;
5268 foreach_ip6_proto_field;
5269#undef _
5270 u8 version = 0;
5271 u8 traffic_class = 0;
5272 u8 flow_label = 0;
5273
5274 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5275 {
5276 if (unformat (input, "version"))
5277 version = 1;
5278 else if (unformat (input, "traffic-class"))
5279 traffic_class = 1;
5280 else if (unformat (input, "flow-label"))
5281 flow_label = 1;
5282 else if (unformat (input, "src"))
5283 src_address = 1;
5284 else if (unformat (input, "dst"))
5285 dst_address = 1;
5286 else if (unformat (input, "proto"))
5287 protocol = 1;
5288
5289#define _(a) else if (unformat (input, #a)) a=1;
5290 foreach_ip6_proto_field
5291#undef _
5292 else
5293 break;
5294 }
5295
5296#define _(a) found_something += a;
5297 foreach_ip6_proto_field;
5298#undef _
5299
5300 if (found_something == 0)
5301 return 0;
5302
5303 vec_validate (mask, sizeof (*ip) - 1);
5304
5305 ip = (ip6_header_t *) mask;
5306
5307#define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
5308 foreach_ip6_proto_field;
5309#undef _
5310
5311 ip_version_traffic_class_and_flow_label = 0;
5312
5313 if (version)
5314 ip_version_traffic_class_and_flow_label |= 0xF0000000;
5315
5316 if (traffic_class)
5317 ip_version_traffic_class_and_flow_label |= 0x0FF00000;
5318
5319 if (flow_label)
5320 ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
5321
5322 ip->ip_version_traffic_class_and_flow_label =
5323 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
5324
5325 *maskp = mask;
5326 return 1;
5327}
5328
5329uword unformat_l3_mask (unformat_input_t * input, va_list * args)
5330{
5331 u8 ** maskp = va_arg (*args, u8 **);
5332
5333 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
5334 if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
5335 return 1;
5336 else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
5337 return 1;
5338 else
5339 break;
5340 }
5341 return 0;
5342}
5343
5344uword unformat_l2_mask (unformat_input_t * input, va_list * args)
5345{
5346 u8 ** maskp = va_arg (*args, u8 **);
5347 u8 * mask = 0;
5348 u8 src = 0;
5349 u8 dst = 0;
5350 u8 proto = 0;
5351 u8 tag1 = 0;
5352 u8 tag2 = 0;
5353 u8 ignore_tag1 = 0;
5354 u8 ignore_tag2 = 0;
5355 u8 cos1 = 0;
5356 u8 cos2 = 0;
5357 u8 dot1q = 0;
5358 u8 dot1ad = 0;
5359 int len = 14;
5360
5361 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
5362 if (unformat (input, "src"))
5363 src = 1;
5364 else if (unformat (input, "dst"))
5365 dst = 1;
5366 else if (unformat (input, "proto"))
5367 proto = 1;
5368 else if (unformat (input, "tag1"))
5369 tag1 = 1;
5370 else if (unformat (input, "tag2"))
5371 tag2 = 1;
5372 else if (unformat (input, "ignore-tag1"))
5373 ignore_tag1 = 1;
5374 else if (unformat (input, "ignore-tag2"))
5375 ignore_tag2 = 1;
5376 else if (unformat (input, "cos1"))
5377 cos1 = 1;
5378 else if (unformat (input, "cos2"))
5379 cos2 = 1;
5380 else if (unformat (input, "dot1q"))
5381 dot1q = 1;
5382 else if (unformat (input, "dot1ad"))
5383 dot1ad = 1;
5384 else
5385 break;
5386 }
5387 if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
5388 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
5389 return 0;
5390
5391 if (tag1 || ignore_tag1 || cos1 || dot1q)
5392 len = 18;
5393 if (tag2 || ignore_tag2 || cos2 || dot1ad)
5394 len = 22;
5395
5396 vec_validate (mask, len-1);
5397
5398 if (dst)
5399 memset (mask, 0xff, 6);
5400
5401 if (src)
5402 memset (mask + 6, 0xff, 6);
5403
5404 if (tag2 || dot1ad)
5405 {
5406 /* inner vlan tag */
5407 if (tag2)
5408 {
5409 mask[19] = 0xff;
5410 mask[18] = 0x0f;
5411 }
5412 if (cos2)
5413 mask[18] |= 0xe0;
5414 if (proto)
5415 mask[21] = mask [20] = 0xff;
5416 if (tag1)
5417 {
5418 mask [15] = 0xff;
5419 mask [14] = 0x0f;
5420 }
5421 if (cos1)
5422 mask[14] |= 0xe0;
5423 *maskp = mask;
5424 return 1;
5425 }
5426 if (tag1 | dot1q)
5427 {
5428 if (tag1)
5429 {
5430 mask [15] = 0xff;
5431 mask [14] = 0x0f;
5432 }
5433 if (cos1)
5434 mask[14] |= 0xe0;
5435 if (proto)
5436 mask[16] = mask [17] = 0xff;
5437
5438 *maskp = mask;
5439 return 1;
5440 }
5441 if (cos2)
5442 mask[18] |= 0xe0;
5443 if (cos1)
5444 mask[14] |= 0xe0;
5445 if (proto)
5446 mask[12] = mask [13] = 0xff;
5447
5448 *maskp = mask;
5449 return 1;
5450}
5451
5452uword unformat_classify_mask (unformat_input_t * input, va_list * args)
5453{
5454 u8 ** maskp = va_arg (*args, u8 **);
5455 u32 * skipp = va_arg (*args, u32 *);
5456 u32 * matchp = va_arg (*args, u32 *);
5457 u32 match;
5458 u8 * mask = 0;
5459 u8 * l2 = 0;
5460 u8 * l3 = 0;
5461 int i;
5462
5463 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
5464 if (unformat (input, "hex %U", unformat_hex_string, &mask))
5465 ;
5466 else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
5467 ;
5468 else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
5469 ;
5470 else
5471 break;
5472 }
5473
5474 if (mask || l2 || l3)
5475 {
5476 if (l2 || l3)
5477 {
5478 /* "With a free Ethernet header in every package" */
5479 if (l2 == 0)
5480 vec_validate (l2, 13);
5481 mask = l2;
5482 vec_append (mask, l3);
5483 vec_free (l3);
5484 }
5485
5486 /* Scan forward looking for the first significant mask octet */
5487 for (i = 0; i < vec_len (mask); i++)
5488 if (mask[i])
5489 break;
5490
5491 /* compute (skip, match) params */
5492 *skipp = i / sizeof(u32x4);
5493 vec_delete (mask, *skipp * sizeof(u32x4), 0);
5494
5495 /* Pad mask to an even multiple of the vector size */
5496 while (vec_len (mask) % sizeof (u32x4))
5497 vec_add1 (mask, 0);
5498
5499 match = vec_len (mask) / sizeof (u32x4);
5500
5501 for (i = match*sizeof(u32x4); i > 0; i-= sizeof(u32x4))
5502 {
5503 u64 *tmp = (u64 *)(mask + (i-sizeof(u32x4)));
5504 if (*tmp || *(tmp+1))
5505 break;
5506 match--;
5507 }
5508 if (match == 0)
5509 clib_warning ("BUG: match 0");
5510
5511 _vec_len (mask) = match * sizeof(u32x4);
5512
5513 *matchp = match;
5514 *maskp = mask;
5515
5516 return 1;
5517 }
5518
5519 return 0;
5520}
5521
5522#define foreach_l2_next \
5523_(drop, DROP) \
5524_(ethernet, ETHERNET_INPUT) \
5525_(ip4, IP4_INPUT) \
5526_(ip6, IP6_INPUT)
5527
5528uword unformat_l2_next_index (unformat_input_t * input, va_list * args)
5529{
5530 u32 * miss_next_indexp = va_arg (*args, u32 *);
5531 u32 next_index = 0;
5532 u32 tmp;
5533
5534#define _(n,N) \
5535 if (unformat (input, #n)) { next_index = L2_CLASSIFY_NEXT_##N; goto out;}
5536 foreach_l2_next;
5537#undef _
5538
5539 if (unformat (input, "%d", &tmp))
5540 {
5541 next_index = tmp;
5542 goto out;
5543 }
5544
5545 return 0;
5546
5547 out:
5548 *miss_next_indexp = next_index;
5549 return 1;
5550}
5551
5552#define foreach_ip_next \
5553_(miss, MISS) \
5554_(drop, DROP) \
5555_(local, LOCAL) \
5556_(rewrite, REWRITE)
5557
5558uword unformat_ip_next_index (unformat_input_t * input, va_list * args)
5559{
5560 u32 * miss_next_indexp = va_arg (*args, u32 *);
5561 u32 next_index = 0;
5562 u32 tmp;
5563
5564#define _(n,N) \
5565 if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
5566 foreach_ip_next;
5567#undef _
5568
5569 if (unformat (input, "%d", &tmp))
5570 {
5571 next_index = tmp;
5572 goto out;
5573 }
5574
5575 return 0;
5576
5577 out:
5578 *miss_next_indexp = next_index;
5579 return 1;
5580}
5581
5582#define foreach_acl_next \
5583_(deny, DENY)
5584
5585uword unformat_acl_next_index (unformat_input_t * input, va_list * args)
5586{
5587 u32 * miss_next_indexp = va_arg (*args, u32 *);
5588 u32 next_index = 0;
5589 u32 tmp;
5590
5591#define _(n,N) \
5592 if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
5593 foreach_acl_next;
5594#undef _
5595
5596 if (unformat (input, "permit"))
5597 {
5598 next_index = ~0;
5599 goto out;
5600 }
5601 else if (unformat (input, "%d", &tmp))
5602 {
5603 next_index = tmp;
5604 goto out;
5605 }
5606
5607 return 0;
5608
5609 out:
5610 *miss_next_indexp = next_index;
5611 return 1;
5612}
5613
5614static int api_classify_add_del_table (vat_main_t * vam)
5615{
5616 unformat_input_t * i = vam->input;
5617 vl_api_classify_add_del_table_t *mp;
5618
5619 u32 nbuckets = 2;
5620 u32 skip = ~0;
5621 u32 match = ~0;
5622 int is_add = 1;
5623 u32 table_index = ~0;
5624 u32 next_table_index = ~0;
5625 u32 miss_next_index = ~0;
5626 u32 memory_size = 32<<20;
5627 u8 * mask = 0;
5628 f64 timeout;
5629
5630 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5631 if (unformat (i, "del"))
5632 is_add = 0;
5633 else if (unformat (i, "buckets %d", &nbuckets))
5634 ;
5635 else if (unformat (i, "memory_size %d", &memory_size))
5636 ;
5637 else if (unformat (i, "skip %d", &skip))
5638 ;
5639 else if (unformat (i, "match %d", &match))
5640 ;
5641 else if (unformat (i, "table %d", &table_index))
5642 ;
5643 else if (unformat (i, "mask %U", unformat_classify_mask,
5644 &mask, &skip, &match))
5645 ;
5646 else if (unformat (i, "next-table %d", &next_table_index))
5647 ;
5648 else if (unformat (i, "miss-next %U", unformat_ip_next_index,
5649 &miss_next_index))
5650 ;
5651 else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
5652 &miss_next_index))
5653 ;
5654 else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
5655 &miss_next_index))
5656 ;
5657 else
5658 break;
5659 }
5660
5661 if (is_add && mask == 0) {
5662 errmsg ("Mask required\n");
5663 return -99;
5664 }
5665
5666 if (is_add && skip == ~0) {
5667 errmsg ("skip count required\n");
5668 return -99;
5669 }
5670
5671 if (is_add && match == ~0) {
5672 errmsg ("match count required\n");
5673 return -99;
5674 }
5675
5676 if (!is_add && table_index == ~0) {
5677 errmsg ("table index required for delete\n");
5678 return -99;
5679 }
5680
5681 M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table,
5682 vec_len(mask));
5683
5684 mp->is_add = is_add;
5685 mp->table_index = ntohl(table_index);
5686 mp->nbuckets = ntohl(nbuckets);
5687 mp->memory_size = ntohl(memory_size);
5688 mp->skip_n_vectors = ntohl(skip);
5689 mp->match_n_vectors = ntohl(match);
5690 mp->next_table_index = ntohl(next_table_index);
5691 mp->miss_next_index = ntohl(miss_next_index);
5692 memcpy (mp->mask, mask, vec_len(mask));
5693
5694 vec_free(mask);
5695
5696 S; W;
5697 /* NOTREACHED */
5698}
5699
5700uword unformat_ip4_match (unformat_input_t * input, va_list * args)
5701{
5702 u8 ** matchp = va_arg (*args, u8 **);
5703 u8 * match = 0;
5704 ip4_header_t * ip;
5705 int version = 0;
5706 u32 version_val;
5707 int hdr_length = 0;
5708 u32 hdr_length_val;
5709 int src = 0, dst = 0;
5710 ip4_address_t src_val, dst_val;
5711 int proto = 0;
5712 u32 proto_val;
5713 int tos = 0;
5714 u32 tos_val;
5715 int length = 0;
5716 u32 length_val;
5717 int fragment_id = 0;
5718 u32 fragment_id_val;
5719 int ttl = 0;
5720 int ttl_val;
5721 int checksum = 0;
5722 u32 checksum_val;
5723
5724 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5725 {
5726 if (unformat (input, "version %d", &version_val))
5727 version = 1;
5728 else if (unformat (input, "hdr_length %d", &hdr_length_val))
5729 hdr_length = 1;
5730 else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
5731 src = 1;
5732 else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
5733 dst = 1;
5734 else if (unformat (input, "proto %d", &proto_val))
5735 proto = 1;
5736 else if (unformat (input, "tos %d", &tos_val))
5737 tos = 1;
5738 else if (unformat (input, "length %d", &length_val))
5739 length = 1;
5740 else if (unformat (input, "fragment_id %d", &fragment_id_val))
5741 fragment_id = 1;
5742 else if (unformat (input, "ttl %d", &ttl_val))
5743 ttl = 1;
5744 else if (unformat (input, "checksum %d", &checksum_val))
5745 checksum = 1;
5746 else
5747 break;
5748 }
5749
5750 if (version + hdr_length + src + dst + proto + tos + length + fragment_id
5751 + ttl + checksum == 0)
5752 return 0;
5753
5754 /*
5755 * Aligned because we use the real comparison functions
5756 */
5757 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof(u32x4));
5758
5759 ip = (ip4_header_t *) match;
5760
5761 /* These are realistically matched in practice */
5762 if (src)
5763 ip->src_address.as_u32 = src_val.as_u32;
5764
5765 if (dst)
5766 ip->dst_address.as_u32 = dst_val.as_u32;
5767
5768 if (proto)
5769 ip->protocol = proto_val;
5770
5771
5772 /* These are not, but they're included for completeness */
5773 if (version)
5774 ip->ip_version_and_header_length |= (version_val & 0xF)<<4;
5775
5776 if (hdr_length)
5777 ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
5778
5779 if (tos)
5780 ip->tos = tos_val;
5781
5782 if (length)
5783 ip->length = length_val;
5784
5785 if (ttl)
5786 ip->ttl = ttl_val;
5787
5788 if (checksum)
5789 ip->checksum = checksum_val;
5790
5791 *matchp = match;
5792 return 1;
5793}
5794
5795uword unformat_ip6_match (unformat_input_t * input, va_list * args)
5796{
5797 u8 ** matchp = va_arg (*args, u8 **);
5798 u8 * match = 0;
5799 ip6_header_t * ip;
5800 int version = 0;
5801 u32 version_val;
5802 u8 traffic_class;
5803 u32 traffic_class_val;
5804 u8 flow_label;
5805 u8 flow_label_val;
5806 int src = 0, dst = 0;
5807 ip6_address_t src_val, dst_val;
5808 int proto = 0;
5809 u32 proto_val;
5810 int payload_length = 0;
5811 u32 payload_length_val;
5812 int hop_limit = 0;
5813 int hop_limit_val;
5814 u32 ip_version_traffic_class_and_flow_label;
5815
5816 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5817 {
5818 if (unformat (input, "version %d", &version_val))
5819 version = 1;
5820 else if (unformat (input, "traffic_class %d", &traffic_class_val))
5821 traffic_class = 1;
5822 else if (unformat (input, "flow_label %d", &flow_label_val))
5823 flow_label = 1;
5824 else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
5825 src = 1;
5826 else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
5827 dst = 1;
5828 else if (unformat (input, "proto %d", &proto_val))
5829 proto = 1;
5830 else if (unformat (input, "payload_length %d", &payload_length_val))
5831 payload_length = 1;
5832 else if (unformat (input, "hop_limit %d", &hop_limit_val))
5833 hop_limit = 1;
5834 else
5835 break;
5836 }
5837
5838 if (version + traffic_class + flow_label + src + dst + proto +
5839 payload_length + hop_limit == 0)
5840 return 0;
5841
5842 /*
5843 * Aligned because we use the real comparison functions
5844 */
5845 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof(u32x4));
5846
5847 ip = (ip6_header_t *) match;
5848
5849 if (src)
5850 memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
5851
5852 if (dst)
5853 memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
5854
5855 if (proto)
5856 ip->protocol = proto_val;
5857
5858 ip_version_traffic_class_and_flow_label = 0;
5859
5860 if (version)
5861 ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
5862
5863 if (traffic_class)
5864 ip_version_traffic_class_and_flow_label |= (traffic_class_val & 0xFF) << 20;
5865
5866 if (flow_label)
5867 ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
5868
5869 ip->ip_version_traffic_class_and_flow_label =
5870 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
5871
5872 if (payload_length)
5873 ip->payload_length = clib_host_to_net_u16 (payload_length_val);
5874
5875 if (hop_limit)
5876 ip->hop_limit = hop_limit_val;
5877
5878 *matchp = match;
5879 return 1;
5880}
5881
5882uword unformat_l3_match (unformat_input_t * input, va_list * args)
5883{
5884 u8 ** matchp = va_arg (*args, u8 **);
5885
5886 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
5887 if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
5888 return 1;
5889 else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
5890 return 1;
5891 else
5892 break;
5893 }
5894 return 0;
5895}
5896
5897uword unformat_vlan_tag (unformat_input_t * input, va_list * args)
5898{
5899 u8 * tagp = va_arg (*args, u8 *);
5900 u32 tag;
5901
5902 if (unformat(input, "%d", &tag))
5903 {
5904 tagp[0] = (tag>>8) & 0x0F;
5905 tagp[1] = tag & 0xFF;
5906 return 1;
5907 }
5908
5909 return 0;
5910}
5911
5912uword unformat_l2_match (unformat_input_t * input, va_list * args)
5913{
5914 u8 ** matchp = va_arg (*args, u8 **);
5915 u8 * match = 0;
5916 u8 src = 0;
5917 u8 src_val[6];
5918 u8 dst = 0;
5919 u8 dst_val[6];
5920 u8 proto = 0;
5921 u16 proto_val;
5922 u8 tag1 = 0;
5923 u8 tag1_val [2];
5924 u8 tag2 = 0;
5925 u8 tag2_val [2];
5926 int len = 14;
5927 u8 ignore_tag1 = 0;
5928 u8 ignore_tag2 = 0;
5929 u8 cos1 = 0;
5930 u8 cos2 = 0;
5931 u32 cos1_val = 0;
5932 u32 cos2_val = 0;
5933
5934 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
5935 if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
5936 src = 1;
5937 else if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
5938 dst = 1;
5939 else if (unformat (input, "proto %U",
5940 unformat_ethernet_type_host_byte_order, &proto_val))
5941 proto = 1;
5942 else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
5943 tag1 = 1;
5944 else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
5945 tag2 = 1;
5946 else if (unformat (input, "ignore-tag1"))
5947 ignore_tag1 = 1;
5948 else if (unformat (input, "ignore-tag2"))
5949 ignore_tag2 = 1;
5950 else if (unformat (input, "cos1 %d", &cos1_val))
5951 cos1 = 1;
5952 else if (unformat (input, "cos2 %d", &cos2_val))
5953 cos2 = 1;
5954 else
5955 break;
5956 }
5957 if ((src + dst + proto + tag1 + tag2 +
5958 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
5959 return 0;
5960
5961 if (tag1 || ignore_tag1 || cos1)
5962 len = 18;
5963 if (tag2 || ignore_tag2 || cos2)
5964 len = 22;
5965
5966 vec_validate_aligned (match, len-1, sizeof(u32x4));
5967
5968 if (dst)
5969 memcpy (match, dst_val, 6);
5970
5971 if (src)
5972 memcpy (match + 6, src_val, 6);
5973
5974 if (tag2)
5975 {
5976 /* inner vlan tag */
5977 match[19] = tag2_val[1];
5978 match[18] = tag2_val[0];
5979 if (cos2)
5980 match [18] |= (cos2_val & 0x7) << 5;
5981 if (proto)
5982 {
5983 match[21] = proto_val & 0xff;
5984 match[20] = proto_val >> 8;
5985 }
5986 if (tag1)
5987 {
5988 match [15] = tag1_val[1];
5989 match [14] = tag1_val[0];
5990 }
5991 if (cos1)
5992 match [14] |= (cos1_val & 0x7) << 5;
5993 *matchp = match;
5994 return 1;
5995 }
5996 if (tag1)
5997 {
5998 match [15] = tag1_val[1];
5999 match [14] = tag1_val[0];
6000 if (proto)
6001 {
6002 match[17] = proto_val & 0xff;
6003 match[16] = proto_val >> 8;
6004 }
6005 if (cos1)
6006 match [14] |= (cos1_val & 0x7) << 5;
6007
6008 *matchp = match;
6009 return 1;
6010 }
6011 if (cos2)
6012 match [18] |= (cos2_val & 0x7) << 5;
6013 if (cos1)
6014 match [14] |= (cos1_val & 0x7) << 5;
6015 if (proto)
6016 {
6017 match[13] = proto_val & 0xff;
6018 match[12] = proto_val >> 8;
6019 }
6020
6021 *matchp = match;
6022 return 1;
6023}
6024
6025
6026uword unformat_classify_match (unformat_input_t * input, va_list * args)
6027{
6028 u8 ** matchp = va_arg (*args, u8 **);
6029 u32 skip_n_vectors = va_arg (*args, u32);
6030 u32 match_n_vectors = va_arg (*args, u32);
6031
6032 u8 * match = 0;
6033 u8 * l2 = 0;
6034 u8 * l3 = 0;
6035
6036 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
6037 if (unformat (input, "hex %U", unformat_hex_string, &match))
6038 ;
6039 else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
6040 ;
6041 else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
6042 ;
6043 else
6044 break;
6045 }
6046
6047 if (match || l2 || l3)
6048 {
6049 if (l2 || l3)
6050 {
6051 /* "Win a free Ethernet header in every packet" */
6052 if (l2 == 0)
6053 vec_validate_aligned (l2, 13, sizeof(u32x4));
6054 match = l2;
6055 vec_append_aligned (match, l3, sizeof(u32x4));
6056 vec_free (l3);
6057 }
6058
6059 /* Make sure the vector is big enough even if key is all 0's */
6060 vec_validate_aligned
6061 (match, ((match_n_vectors + skip_n_vectors) * sizeof(u32x4)) - 1,
6062 sizeof(u32x4));
6063
6064 /* Set size, include skipped vectors*/
6065 _vec_len (match) = (match_n_vectors+skip_n_vectors) * sizeof(u32x4);
6066
6067 *matchp = match;
6068
6069 return 1;
6070 }
6071
6072 return 0;
6073}
6074
6075static int api_classify_add_del_session (vat_main_t * vam)
6076{
6077 unformat_input_t * i = vam->input;
6078 vl_api_classify_add_del_session_t *mp;
6079 int is_add = 1;
6080 u32 table_index = ~0;
6081 u32 hit_next_index = ~0;
6082 u32 opaque_index = ~0;
6083 u8 * match = 0;
6084 i32 advance = 0;
6085 f64 timeout;
6086 u32 skip_n_vectors = 0;
6087 u32 match_n_vectors = 0;
6088
6089 /*
6090 * Warning: you have to supply skip_n and match_n
6091 * because the API client cant simply look at the classify
6092 * table object.
6093 */
6094
6095 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6096 if (unformat (i, "del"))
6097 is_add = 0;
6098 else if (unformat (i, "hit-next %U", unformat_ip_next_index,
6099 &hit_next_index))
6100 ;
6101 else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
6102 &hit_next_index))
6103 ;
6104 else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
6105 &hit_next_index))
6106 ;
6107 else if (unformat (i, "opaque-index %d", &opaque_index))
6108 ;
6109 else if (unformat (i, "skip_n %d", &skip_n_vectors))
6110 ;
6111 else if (unformat (i, "match_n %d", &match_n_vectors))
6112 ;
6113 else if (unformat (i, "match %U", unformat_classify_match,
6114 &match, skip_n_vectors, match_n_vectors))
6115 ;
6116 else if (unformat (i, "advance %d", &advance))
6117 ;
6118 else if (unformat (i, "table-index %d", &table_index))
6119 ;
6120 else
6121 break;
6122 }
6123
6124 if (table_index == ~0) {
6125 errmsg ("Table index required\n");
6126 return -99;
6127 }
6128
6129 if (is_add && match == 0) {
6130 errmsg ("Match value required\n");
6131 return -99;
6132 }
6133
6134 M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session,
6135 vec_len(match));
6136
6137 mp->is_add = is_add;
6138 mp->table_index = ntohl(table_index);
6139 mp->hit_next_index = ntohl(hit_next_index);
6140 mp->opaque_index = ntohl(opaque_index);
6141 mp->advance = ntohl(advance);
6142 memcpy (mp->match, match, vec_len(match));
6143 vec_free(match);
6144
6145 S; W;
6146 /* NOTREACHED */
6147}
6148
6149static int api_classify_set_interface_ip_table (vat_main_t * vam)
6150{
6151 unformat_input_t * i = vam->input;
6152 vl_api_classify_set_interface_ip_table_t *mp;
6153 f64 timeout;
6154 u32 sw_if_index;
6155 int sw_if_index_set;
6156 u32 table_index = ~0;
6157 u8 is_ipv6 = 0;
6158
6159 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6160 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6161 sw_if_index_set = 1;
6162 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6163 sw_if_index_set = 1;
6164 else if (unformat (i, "table %d", &table_index))
6165 ;
6166 else {
6167 clib_warning ("parse error '%U'", format_unformat_error, i);
6168 return -99;
6169 }
6170 }
6171
6172 if (sw_if_index_set == 0) {
6173 errmsg ("missing interface name or sw_if_index\n");
6174 return -99;
6175 }
6176
6177
6178 M(CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
6179
6180 mp->sw_if_index = ntohl(sw_if_index);
6181 mp->table_index = ntohl(table_index);
6182 mp->is_ipv6 = is_ipv6;
6183
6184 S; W;
6185 /* NOTREACHED */
6186 return 0;
6187}
6188
6189static int api_classify_set_interface_l2_tables (vat_main_t * vam)
6190{
6191 unformat_input_t * i = vam->input;
6192 vl_api_classify_set_interface_l2_tables_t *mp;
6193 f64 timeout;
6194 u32 sw_if_index;
6195 int sw_if_index_set;
6196 u32 ip4_table_index = ~0;
6197 u32 ip6_table_index = ~0;
6198 u32 other_table_index = ~0;
6199
6200 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6201 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6202 sw_if_index_set = 1;
6203 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6204 sw_if_index_set = 1;
6205 else if (unformat (i, "ip4-table %d", &ip4_table_index))
6206 ;
6207 else if (unformat (i, "ip6-table %d", &ip6_table_index))
6208 ;
6209 else if (unformat (i, "other-table %d", &other_table_index))
6210 ;
6211 else {
6212 clib_warning ("parse error '%U'", format_unformat_error, i);
6213 return -99;
6214 }
6215 }
6216
6217 if (sw_if_index_set == 0) {
6218 errmsg ("missing interface name or sw_if_index\n");
6219 return -99;
6220 }
6221
6222
6223 M(CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
6224
6225 mp->sw_if_index = ntohl(sw_if_index);
6226 mp->ip4_table_index = ntohl(ip4_table_index);
6227 mp->ip6_table_index = ntohl(ip6_table_index);
6228 mp->other_table_index = ntohl(other_table_index);
6229
6230
6231 S; W;
6232 /* NOTREACHED */
6233 return 0;
6234}
6235
6236static int api_get_node_index (vat_main_t * vam)
6237{
6238 unformat_input_t * i = vam->input;
6239 vl_api_get_node_index_t * mp;
6240 f64 timeout;
6241 u8 * name = 0;
6242
6243 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6244 if (unformat (i, "node %s", &name))
6245 ;
6246 else
6247 break;
6248 }
6249 if (name == 0) {
6250 errmsg ("node name required\n");
6251 return -99;
6252 }
6253 if (vec_len (name) >= ARRAY_LEN(mp->node_name)) {
6254 errmsg ("node name too long, max %d\n", ARRAY_LEN(mp->node_name));
6255 return -99;
6256 }
6257
6258 M(GET_NODE_INDEX, get_node_index);
6259 memcpy (mp->node_name, name, vec_len(name));
6260 vec_free(name);
6261
6262 S; W;
6263 /* NOTREACHED */
6264 return 0;
6265}
6266
6267static int api_add_node_next (vat_main_t * vam)
6268{
6269 unformat_input_t * i = vam->input;
6270 vl_api_add_node_next_t * mp;
6271 f64 timeout;
6272 u8 * name = 0;
6273 u8 * next = 0;
6274
6275 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6276 if (unformat (i, "node %s", &name))
6277 ;
6278 else if (unformat (i, "next %s", &next))
6279 ;
6280 else
6281 break;
6282 }
6283 if (name == 0) {
6284 errmsg ("node name required\n");
6285 return -99;
6286 }
6287 if (vec_len (name) >= ARRAY_LEN(mp->node_name)) {
6288 errmsg ("node name too long, max %d\n", ARRAY_LEN(mp->node_name));
6289 return -99;
6290 }
6291 if (next == 0) {
6292 errmsg ("next node required\n");
6293 return -99;
6294 }
6295 if (vec_len (next) >= ARRAY_LEN(mp->next_name)) {
6296 errmsg ("next name too long, max %d\n", ARRAY_LEN(mp->next_name));
6297 return -99;
6298 }
6299
6300 M(ADD_NODE_NEXT, add_node_next);
6301 memcpy (mp->node_name, name, vec_len(name));
6302 memcpy (mp->next_name, next, vec_len(next));
6303 vec_free(name);
6304 vec_free(next);
6305
6306 S; W;
6307 /* NOTREACHED */
6308 return 0;
6309}
6310
6311static int api_l2tpv3_create_tunnel (vat_main_t * vam)
6312{
6313 unformat_input_t * i = vam->input;
6314 ip6_address_t client_address, our_address;
6315 int client_address_set = 0;
6316 int our_address_set = 0;
6317 u32 local_session_id = 0;
6318 u32 remote_session_id = 0;
6319 u64 local_cookie = 0;
6320 u64 remote_cookie = 0;
6321 u8 l2_sublayer_present = 0;
6322 vl_api_l2tpv3_create_tunnel_t * mp;
6323 f64 timeout;
6324
6325 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6326 if (unformat (i, "client_address %U", unformat_ip6_address,
6327 &client_address))
6328 client_address_set = 1;
6329 else if (unformat (i, "our_address %U", unformat_ip6_address,
6330 &our_address))
6331 our_address_set = 1;
6332 else if (unformat (i, "local_session_id %d", &local_session_id))
6333 ;
6334 else if (unformat (i, "remote_session_id %d", &remote_session_id))
6335 ;
6336 else if (unformat (i, "local_cookie %lld", &local_cookie))
6337 ;
6338 else if (unformat (i, "remote_cookie %lld", &remote_cookie))
6339 ;
6340 else if (unformat (i, "l2-sublayer-present"))
6341 l2_sublayer_present = 1;
6342 else
6343 break;
6344 }
6345
6346 if (client_address_set == 0) {
6347 errmsg ("client_address required\n");
6348 return -99;
6349 }
6350
6351 if (our_address_set == 0) {
6352 errmsg ("our_address required\n");
6353 return -99;
6354 }
6355
6356 M(L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
6357
6358 memcpy (mp->client_address, client_address.as_u8,
6359 sizeof (mp->client_address));
6360
6361 memcpy (mp->our_address, our_address.as_u8,
6362 sizeof (mp->our_address));
6363
6364 mp->local_session_id = ntohl (local_session_id);
6365 mp->remote_session_id = ntohl (remote_session_id);
6366 mp->local_cookie = clib_host_to_net_u64 (local_cookie);
6367 mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
6368 mp->l2_sublayer_present = l2_sublayer_present;
6369 mp->is_ipv6 = 1;
6370
6371 S; W;
6372 /* NOTREACHED */
6373 return 0;
6374}
6375
6376static int api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
6377{
6378 unformat_input_t * i = vam->input;
6379 u32 sw_if_index;
6380 u8 sw_if_index_set = 0;
6381 u64 new_local_cookie = 0;
6382 u64 new_remote_cookie = 0;
6383 vl_api_l2tpv3_set_tunnel_cookies_t *mp;
6384 f64 timeout;
6385
6386 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6387 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6388 sw_if_index_set = 1;
6389 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6390 sw_if_index_set = 1;
6391 else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
6392 ;
6393 else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
6394 ;
6395 else
6396 break;
6397 }
6398
6399 if (sw_if_index_set == 0) {
6400 errmsg ("missing interface name or sw_if_index\n");
6401 return -99;
6402 }
6403
6404 M(L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
6405
6406 mp->sw_if_index = ntohl(sw_if_index);
6407 mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
6408 mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
6409
6410 S; W;
6411 /* NOTREACHED */
6412 return 0;
6413}
6414
6415static int api_l2tpv3_interface_enable_disable (vat_main_t * vam)
6416{
6417 unformat_input_t * i = vam->input;
6418 vl_api_l2tpv3_interface_enable_disable_t *mp;
6419 f64 timeout;
6420 u32 sw_if_index;
6421 u8 sw_if_index_set = 0;
6422 u8 enable_disable = 1;
6423
6424 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6425 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6426 sw_if_index_set = 1;
6427 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6428 sw_if_index_set = 1;
6429 else if (unformat (i, "enable"))
6430 enable_disable = 1;
6431 else if (unformat (i, "disable"))
6432 enable_disable = 0;
6433 else
6434 break;
6435 }
6436
6437 if (sw_if_index_set == 0) {
6438 errmsg ("missing interface name or sw_if_index\n");
6439 return -99;
6440 }
6441
6442 M(L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
6443
6444 mp->sw_if_index = ntohl(sw_if_index);
6445 mp->enable_disable = enable_disable;
6446
6447 S; W;
6448 /* NOTREACHED */
6449 return 0;
6450}
6451
6452static int api_l2tpv3_set_lookup_key (vat_main_t * vam)
6453{
6454 unformat_input_t * i = vam->input;
6455 vl_api_l2tpv3_set_lookup_key_t * mp;
6456 f64 timeout;
6457 u8 key = ~0;
6458
6459 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6460 if (unformat (i, "lookup_v6_src"))
6461 key = L2T_LOOKUP_SRC_ADDRESS;
6462 else if (unformat (i, "lookup_v6_dst"))
6463 key = L2T_LOOKUP_DST_ADDRESS;
6464 else if (unformat (i, "lookup_session_id"))
6465 key = L2T_LOOKUP_SESSION_ID;
6466 else
6467 break;
6468 }
6469
6470 if (key == ~0) {
6471 errmsg ("l2tp session lookup key unset\n");
6472 return -99;
6473 }
6474
6475 M(L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
6476
6477 mp->key = key;
6478
6479 S; W;
6480 /* NOTREACHED */
6481 return 0;
6482}
6483
6484static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
6485(vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
6486{
6487 vat_main_t * vam = &vat_main;
6488
6489 fformat(vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
6490 format_ip6_address, mp->our_address,
6491 format_ip6_address, mp->client_address,
6492 clib_net_to_host_u32(mp->sw_if_index));
6493
6494 fformat (vam->ofp, " local cookies %016llx %016llx remote cookie %016llx\n",
6495 clib_net_to_host_u64 (mp->local_cookie[0]),
6496 clib_net_to_host_u64 (mp->local_cookie[1]),
6497 clib_net_to_host_u64 (mp->remote_cookie));
6498
6499 fformat (vam->ofp, " local session-id %d remote session-id %d\n",
6500 clib_net_to_host_u32 (mp->local_session_id),
6501 clib_net_to_host_u32 (mp->remote_session_id));
6502
6503 fformat (vam->ofp, " l2 specific sublayer %s\n\n",
6504 mp->l2_sublayer_present ? "preset" : "absent");
6505
6506}
6507
6508static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
6509(vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
6510{
6511 vat_main_t * vam = &vat_main;
6512 vat_json_node_t *node = NULL;
6513 struct in6_addr addr;
6514
6515 if (VAT_JSON_ARRAY != vam->json_tree.type) {
6516 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
6517 vat_json_init_array(&vam->json_tree);
6518 }
6519 node = vat_json_array_add(&vam->json_tree);
6520
6521 vat_json_init_object(node);
6522
6523 memcpy(&addr, mp->our_address, sizeof(addr));
6524 vat_json_object_add_ip6(node, "our_address", addr);
6525 memcpy(&addr, mp->client_address, sizeof(addr));
6526 vat_json_object_add_ip6(node, "client_address", addr);
6527
6528 vat_json_node_t * lc = vat_json_object_add(node, "local_cookie");
6529 vat_json_init_array(lc);
6530 vat_json_array_add_uint(lc, clib_net_to_host_u64(mp->local_cookie[0]));
6531 vat_json_array_add_uint(lc, clib_net_to_host_u64(mp->local_cookie[1]));
6532 vat_json_object_add_uint(node, "remote_cookie", clib_net_to_host_u64(mp->remote_cookie));
6533
6534 printf("local id: %u", clib_net_to_host_u32(mp->local_session_id));
6535 vat_json_object_add_uint(node, "local_session_id", clib_net_to_host_u32(mp->local_session_id));
6536 vat_json_object_add_uint(node, "remote_session_id", clib_net_to_host_u32(mp->remote_session_id));
6537 vat_json_object_add_string_copy(node, "l2_sublayer", mp->l2_sublayer_present ?
6538 (u8*)"present" : (u8*)"absent");
6539}
6540
6541static int api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
6542{
6543 vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
6544 f64 timeout;
6545
6546 /* Get list of l2tpv3-tunnel interfaces */
6547 M(SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
6548 S;
6549
6550 /* Use a control ping for synchronization */
6551 {
6552 vl_api_control_ping_t * mp;
6553 M(CONTROL_PING, control_ping);
6554 S;
6555 }
6556 W;
6557}
6558
6559
6560static void vl_api_sw_interface_tap_details_t_handler
6561(vl_api_sw_interface_tap_details_t * mp)
6562{
6563 vat_main_t * vam = &vat_main;
6564
6565 fformat(vam->ofp, "%-16s %d\n",
6566 mp->dev_name,
6567 clib_net_to_host_u32(mp->sw_if_index));
6568}
6569
6570static void vl_api_sw_interface_tap_details_t_handler_json
6571(vl_api_sw_interface_tap_details_t * mp)
6572{
6573 vat_main_t * vam = &vat_main;
6574 vat_json_node_t *node = NULL;
6575
6576 if (VAT_JSON_ARRAY != vam->json_tree.type) {
6577 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
6578 vat_json_init_array(&vam->json_tree);
6579 }
6580 node = vat_json_array_add(&vam->json_tree);
6581
6582 vat_json_init_object(node);
6583 vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
6584 vat_json_object_add_string_copy(node, "dev_name", mp->dev_name);
6585}
6586
6587static int api_sw_interface_tap_dump (vat_main_t * vam)
6588{
6589 vl_api_sw_interface_tap_dump_t *mp;
6590 f64 timeout;
6591
6592 fformat(vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
6593 /* Get list of tap interfaces */
6594 M(SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
6595 S;
6596
6597 /* Use a control ping for synchronization */
6598 {
6599 vl_api_control_ping_t * mp;
6600 M(CONTROL_PING, control_ping);
6601 S;
6602 }
6603 W;
6604}
6605
6606static uword unformat_vxlan_decap_next
6607(unformat_input_t * input, va_list * args)
6608{
6609 u32 * result = va_arg (*args, u32 *);
6610 u32 tmp;
6611
6612 if (unformat (input, "drop"))
6613 *result = VXLAN_INPUT_NEXT_DROP;
6614 else if (unformat (input, "ip4"))
6615 *result = VXLAN_INPUT_NEXT_IP4_INPUT;
6616 else if (unformat (input, "ip6"))
6617 *result = VXLAN_INPUT_NEXT_IP6_INPUT;
6618 else if (unformat (input, "l2"))
6619 *result = VXLAN_INPUT_NEXT_L2_INPUT;
6620 else if (unformat (input, "%d", &tmp))
6621 *result = tmp;
6622 else
6623 return 0;
6624 return 1;
6625}
6626
6627static int api_vxlan_add_del_tunnel (vat_main_t * vam)
6628{
6629 unformat_input_t * line_input = vam->input;
6630 vl_api_vxlan_add_del_tunnel_t *mp;
6631 f64 timeout;
6632 ip4_address_t src, dst;
6633 u8 is_add = 1;
6634 u8 src_set = 0;
6635 u8 dst_set = 0;
6636 u32 encap_vrf_id = 0;
6637 u32 decap_next_index = ~0;
6638 u32 vni = 0;
6639
6640 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
6641 if (unformat (line_input, "del"))
6642 is_add = 0;
6643 else if (unformat (line_input, "src %U",
6644 unformat_ip4_address, &src))
6645 src_set = 1;
6646 else if (unformat (line_input, "dst %U",
6647 unformat_ip4_address, &dst))
6648 dst_set = 1;
6649 else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
6650 ;
6651 else if (unformat (line_input, "decap-next %U",
6652 unformat_vxlan_decap_next, &decap_next_index))
6653 ;
6654 else if (unformat (line_input, "vni %d", &vni))
6655 ;
6656 else {
6657 errmsg ("parse error '%U'\n", format_unformat_error, line_input);
6658 return -99;
6659 }
6660 }
6661
6662 if (src_set == 0) {
6663 errmsg ("tunnel src address not specified\n");
6664 return -99;
6665 }
6666 if (dst_set == 0) {
6667 errmsg ("tunnel dst address not specified\n");
6668 return -99;
6669 }
6670
6671 if ((vni == 0) || (vni>>24)) {
6672 errmsg ("vni not specified or out of range\n");
6673 return -99;
6674 }
6675
6676 M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
6677
6678 mp->src_address = src.as_u32;
6679 mp->dst_address = dst.as_u32;
6680 mp->encap_vrf_id = ntohl(encap_vrf_id);
6681 mp->decap_next_index = ntohl(decap_next_index);
6682 mp->vni = ntohl(vni);
6683 mp->is_add = is_add;
6684
6685 S; W;
6686 /* NOTREACHED */
6687 return 0;
6688}
6689
Dave Wallace60231f32015-12-17 21:04:30 -05006690static void vl_api_vxlan_tunnel_details_t_handler
6691(vl_api_vxlan_tunnel_details_t * mp)
6692{
6693 vat_main_t * vam = &vat_main;
6694
6695 fformat(vam->ofp, "%11d%13U%13U%14d%18d%13d\n",
6696 ntohl(mp->sw_if_index),
6697 format_ip4_address, &mp->src_address,
6698 format_ip4_address, &mp->dst_address,
6699 ntohl(mp->encap_vrf_id),
6700 ntohl(mp->decap_next_index),
6701 ntohl(mp->vni));
6702}
6703
6704static void vl_api_vxlan_tunnel_details_t_handler_json
6705(vl_api_vxlan_tunnel_details_t * mp)
6706{
6707 vat_main_t * vam = &vat_main;
6708 vat_json_node_t *node = NULL;
6709 struct in_addr ip4;
6710
6711 if (VAT_JSON_ARRAY != vam->json_tree.type) {
6712 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
6713 vat_json_init_array(&vam->json_tree);
6714 }
6715 node = vat_json_array_add(&vam->json_tree);
6716
6717 vat_json_init_object(node);
6718 vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
6719 memcpy(&ip4, &mp->src_address, sizeof(ip4));
6720 vat_json_object_add_ip4(node, "src_address", ip4);
6721 memcpy(&ip4, &mp->dst_address, sizeof(ip4));
6722 vat_json_object_add_ip4(node, "dst_address", ip4);
6723 vat_json_object_add_uint(node, "encap_vrf_id", ntohl(mp->encap_vrf_id));
6724 vat_json_object_add_uint(node, "decap_next_index", ntohl(mp->decap_next_index));
6725 vat_json_object_add_uint(node, "vni", ntohl(mp->vni));
6726}
6727
6728static int api_vxlan_tunnel_dump (vat_main_t * vam)
6729{
6730 unformat_input_t * i = vam->input;
6731 vl_api_vxlan_tunnel_dump_t *mp;
6732 f64 timeout;
6733 u32 sw_if_index;
6734 u8 sw_if_index_set = 0;
6735
6736 /* Parse args required to build the message */
6737 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6738 if (unformat (i, "sw_if_index %d", &sw_if_index))
6739 sw_if_index_set = 1;
6740 else
6741 break;
6742 }
6743
6744 if (sw_if_index_set == 0) {
6745 sw_if_index = ~0;
6746 }
6747
6748 if (!vam->json_output) {
6749 fformat(vam->ofp, "%11s%13s%13s%14s%18s%13s\n",
6750 "sw_if_index", "src_address", "dst_address",
6751 "encap_vrf_id", "decap_next_index", "vni");
6752 }
6753
6754 /* Get list of l2tpv3-tunnel interfaces */
6755 M(VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
6756
6757 mp->sw_if_index = htonl(sw_if_index);
6758
6759 S;
6760
6761 /* Use a control ping for synchronization */
6762 {
6763 vl_api_control_ping_t * mp;
6764 M(CONTROL_PING, control_ping);
6765 S;
6766 }
6767 W;
6768}
6769
Ed Warnickecb9cada2015-12-08 15:45:58 -07006770static int api_l2_fib_clear_table (vat_main_t * vam)
6771{
6772// unformat_input_t * i = vam->input;
6773 vl_api_l2_fib_clear_table_t *mp;
6774 f64 timeout;
6775
6776 M(L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
6777
6778 S; W;
6779 /* NOTREACHED */
6780 return 0;
6781}
6782
6783static int api_l2_interface_efp_filter (vat_main_t * vam)
6784{
6785 unformat_input_t * i = vam->input;
6786 vl_api_l2_interface_efp_filter_t *mp;
6787 f64 timeout;
6788 u32 sw_if_index;
6789 u8 enable = 1;
6790 u8 sw_if_index_set = 0;
6791
6792 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6793 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6794 sw_if_index_set = 1;
6795 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6796 sw_if_index_set = 1;
6797 else if (unformat (i, "enable"))
6798 enable = 1;
6799 else if (unformat (i, "disable"))
6800 enable = 0;
6801 else {
6802 clib_warning ("parse error '%U'", format_unformat_error, i);
6803 return -99;
6804 }
6805 }
6806
6807 if (sw_if_index_set == 0) {
6808 errmsg ("missing sw_if_index\n");
6809 return -99;
6810 }
6811
6812 M(L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
6813
6814 mp->sw_if_index = ntohl(sw_if_index);
6815 mp->enable_disable = enable;
6816
6817 S; W;
6818 /* NOTREACHED */
6819 return 0;
6820}
6821
6822#define foreach_vtr_op \
6823_("disable", L2_VTR_DISABLED) \
6824_("push-1", L2_VTR_PUSH_1) \
6825_("push-2", L2_VTR_PUSH_2) \
6826_("pop-1", L2_VTR_POP_1) \
6827_("pop-2", L2_VTR_POP_2) \
6828_("translate-1-1", L2_VTR_TRANSLATE_1_1) \
6829_("translate-1-2", L2_VTR_TRANSLATE_1_2) \
6830_("translate-2-1", L2_VTR_TRANSLATE_2_1) \
6831_("translate-2-2", L2_VTR_TRANSLATE_2_2)
6832
6833static int api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
6834{
6835 unformat_input_t * i = vam->input;
6836 vl_api_l2_interface_vlan_tag_rewrite_t *mp;
6837 f64 timeout;
6838 u32 sw_if_index;
6839 u8 sw_if_index_set = 0;
6840 u8 vtr_op_set = 0;
6841 u32 vtr_op = 0;
6842 u32 push_dot1q = 1;
6843 u32 tag1 = ~0;
6844 u32 tag2 = ~0;
6845
6846 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6847 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6848 sw_if_index_set = 1;
6849 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6850 sw_if_index_set = 1;
6851 else if (unformat (i, "vtr_op %d", &vtr_op))
6852 vtr_op_set = 1;
6853#define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
6854 foreach_vtr_op
6855#undef _
6856
6857 else if (unformat (i, "push_dot1q %d", &push_dot1q))
6858 ;
6859 else if (unformat (i, "tag1 %d", &tag1))
6860 ;
6861 else if (unformat (i, "tag2 %d", &tag2))
6862 ;
6863 else {
6864 clib_warning ("parse error '%U'", format_unformat_error, i);
6865 return -99;
6866 }
6867 }
6868
6869 if ((sw_if_index_set == 0)||(vtr_op_set == 0)) {
6870 errmsg ("missing vtr operation or sw_if_index\n");
6871 return -99;
6872 }
6873
6874 M(L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
6875
6876 mp->sw_if_index = ntohl(sw_if_index);
6877 mp->vtr_op = ntohl(vtr_op);
6878 mp->push_dot1q = ntohl(push_dot1q);
6879 mp->tag1 = ntohl(tag1);
6880 mp->tag2 = ntohl(tag2);
6881
6882 S; W;
6883 /* NOTREACHED */
6884 return 0;
6885}
6886
6887static int api_create_vhost_user_if (vat_main_t * vam)
6888{
6889 unformat_input_t * i = vam->input;
6890 vl_api_create_vhost_user_if_t *mp;
6891 f64 timeout;
6892 u8 * file_name;
6893 u8 is_server = 0;
6894 u8 file_name_set = 0;
6895 u32 custom_dev_instance = ~0;
Pierre Pfisteref65cb02016-02-19 13:52:44 +00006896 u8 hwaddr[6];
6897 u8 use_custom_mac = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -07006898
6899 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6900 if (unformat (i, "socket %s", &file_name)) {
6901 file_name_set = 1;
6902 }
6903 else if (unformat (i, "renumber %"PRIu32, &custom_dev_instance))
6904 ;
Pierre Pfisteref65cb02016-02-19 13:52:44 +00006905 else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
6906 use_custom_mac = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -07006907 else if (unformat (i, "server"))
6908 is_server = 1;
6909 else
6910 break;
6911 }
6912
6913 if (file_name_set == 0) {
6914 errmsg ("missing socket file name\n");
6915 return -99;
6916 }
6917
6918 if (vec_len (file_name) > 255) {
6919 errmsg ("socket file name too long\n");
6920 return -99;
6921 }
6922 vec_add1 (file_name, 0);
6923
6924 M(CREATE_VHOST_USER_IF, create_vhost_user_if);
6925
6926 mp->is_server = is_server;
6927 memcpy(mp->sock_filename, file_name, vec_len(file_name));
6928 vec_free(file_name);
6929 if (custom_dev_instance != ~0) {
6930 mp->renumber = 1;
6931 mp->custom_dev_instance = ntohl(custom_dev_instance);
6932 }
Pierre Pfisteref65cb02016-02-19 13:52:44 +00006933 mp->use_custom_mac = use_custom_mac;
6934 memcpy(mp->mac_address, hwaddr, 6);
Ed Warnickecb9cada2015-12-08 15:45:58 -07006935
6936 S; W;
6937 /* NOTREACHED */
6938 return 0;
6939}
6940
6941static int api_modify_vhost_user_if (vat_main_t * vam)
6942{
6943 unformat_input_t * i = vam->input;
6944 vl_api_modify_vhost_user_if_t *mp;
6945 f64 timeout;
6946 u8 * file_name;
6947 u8 is_server = 0;
6948 u8 file_name_set = 0;
6949 u32 custom_dev_instance = ~0;
6950 u8 sw_if_index_set = 0;
6951 u32 sw_if_index = (u32)~0;
6952
6953 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6954 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6955 sw_if_index_set = 1;
6956 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6957 sw_if_index_set = 1;
6958 else if (unformat (i, "socket %s", &file_name)) {
6959 file_name_set = 1;
6960 }
6961 else if (unformat (i, "renumber %"PRIu32, &custom_dev_instance))
6962 ;
6963 else if (unformat (i, "server"))
6964 is_server = 1;
6965 else
6966 break;
6967 }
6968
6969 if (sw_if_index_set == 0) {
6970 errmsg ("missing sw_if_index or interface name\n");
6971 return -99;
6972 }
6973
6974 if (file_name_set == 0) {
6975 errmsg ("missing socket file name\n");
6976 return -99;
6977 }
6978
6979 if (vec_len (file_name) > 255) {
6980 errmsg ("socket file name too long\n");
6981 return -99;
6982 }
6983 vec_add1 (file_name, 0);
6984
6985 M(MODIFY_VHOST_USER_IF, modify_vhost_user_if);
6986
6987 mp->sw_if_index = ntohl(sw_if_index);
6988 mp->is_server = is_server;
6989 memcpy(mp->sock_filename, file_name, vec_len(file_name));
6990 vec_free(file_name);
6991 if (custom_dev_instance != ~0) {
6992 mp->renumber = 1;
6993 mp->custom_dev_instance = ntohl(custom_dev_instance);
6994 }
6995
6996 S; W;
6997 /* NOTREACHED */
6998 return 0;
6999}
7000
7001static int api_delete_vhost_user_if (vat_main_t * vam)
7002{
7003 unformat_input_t * i = vam->input;
7004 vl_api_delete_vhost_user_if_t *mp;
7005 f64 timeout;
7006 u32 sw_if_index = ~0;
7007 u8 sw_if_index_set = 0;
7008
7009 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7010 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7011 sw_if_index_set = 1;
7012 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7013 sw_if_index_set = 1;
7014 else
7015 break;
7016 }
7017
7018 if (sw_if_index_set == 0) {
7019 errmsg ("missing sw_if_index or interface name\n");
7020 return -99;
7021 }
7022
7023
7024 M(DELETE_VHOST_USER_IF, delete_vhost_user_if);
7025
7026 mp->sw_if_index = ntohl(sw_if_index);
7027
7028 S; W;
7029 /* NOTREACHED */
7030 return 0;
7031}
7032
7033static void vl_api_sw_interface_vhost_user_details_t_handler
7034(vl_api_sw_interface_vhost_user_details_t * mp)
7035{
7036 vat_main_t * vam = &vat_main;
7037
7038 fformat(vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
7039 (char *)mp->interface_name,
7040 ntohl(mp->sw_if_index), ntohl(mp->virtio_net_hdr_sz),
7041 clib_net_to_host_u64(mp->features), mp->is_server,
7042 ntohl(mp->num_regions), (char *)mp->sock_filename);
7043 fformat(vam->ofp, " Status: '%s'\n", strerror(ntohl(mp->sock_errno)));
7044}
7045
7046static void vl_api_sw_interface_vhost_user_details_t_handler_json
7047(vl_api_sw_interface_vhost_user_details_t * mp)
7048{
7049 vat_main_t * vam = &vat_main;
7050 vat_json_node_t *node = NULL;
7051
7052 if (VAT_JSON_ARRAY != vam->json_tree.type) {
7053 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
7054 vat_json_init_array(&vam->json_tree);
7055 }
7056 node = vat_json_array_add(&vam->json_tree);
7057
7058 vat_json_init_object(node);
7059 vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
7060 vat_json_object_add_string_copy(node, "interface_name", mp->interface_name);
7061 vat_json_object_add_uint(node, "virtio_net_hdr_sz", ntohl(mp->virtio_net_hdr_sz));
7062 vat_json_object_add_uint(node, "features", clib_net_to_host_u64(mp->features));
7063 vat_json_object_add_uint(node, "is_server", mp->is_server);
7064 vat_json_object_add_string_copy(node, "sock_filename", mp->sock_filename);
7065 vat_json_object_add_uint(node, "num_regions", ntohl(mp->num_regions));
7066 vat_json_object_add_uint(node, "sock_errno", ntohl(mp->sock_errno));
7067}
7068
7069static int api_sw_interface_vhost_user_dump (vat_main_t * vam)
7070{
7071 vl_api_sw_interface_vhost_user_dump_t *mp;
7072 f64 timeout;
7073 fformat(vam->ofp, "Interface name idx hdr_sz features server regions filename\n");
7074
7075 /* Get list of vhost-user interfaces */
7076 M(SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
7077 S;
7078
7079 /* Use a control ping for synchronization */
7080 {
7081 vl_api_control_ping_t * mp;
7082 M(CONTROL_PING, control_ping);
7083 S;
7084 }
7085 W;
7086}
7087
7088static int api_show_version (vat_main_t * vam)
7089{
7090 vl_api_show_version_t *mp;
7091 f64 timeout;
7092
7093 M(SHOW_VERSION, show_version);
7094
7095 S; W;
7096 /* NOTREACHED */
7097 return 0;
7098}
7099
7100static uword unformat_nsh_gre_decap_next
7101(unformat_input_t * input, va_list * args)
7102{
7103 u32 * result = va_arg (*args, u32 *);
7104 u32 tmp;
7105
7106 if (unformat (input, "drop"))
7107 *result = NSH_INPUT_NEXT_DROP;
7108 else if (unformat (input, "ip4"))
7109 *result = NSH_INPUT_NEXT_IP4_INPUT;
7110 else if (unformat (input, "ip6"))
7111 *result = NSH_INPUT_NEXT_IP6_INPUT;
7112 else if (unformat (input, "ethernet"))
7113 *result = NSH_INPUT_NEXT_ETHERNET_INPUT;
7114 else if (unformat (input, "%d", &tmp))
7115 *result = tmp;
7116 else
7117 return 0;
7118 return 1;
7119}
7120
7121static int api_nsh_gre_add_del_tunnel (vat_main_t * vam)
7122{
7123 unformat_input_t * line_input = vam->input;
7124 vl_api_nsh_gre_add_del_tunnel_t *mp;
7125 f64 timeout;
7126 ip4_address_t src, dst;
7127 u8 is_add = 1;
7128 u8 src_set = 0;
7129 u8 dst_set = 0;
7130 u32 encap_vrf_id = 0;
7131 u32 decap_vrf_id = 0;
7132 u8 ver_o_c = 0;
7133 u8 md_type = 0;
7134 u8 next_protocol = 1; /* ip4 */
7135 u32 spi;
7136 u8 spi_set = 0;
7137 u32 si;
7138 u8 si_set = 0;
7139 u32 spi_si;
7140 u32 c1 = 0;
7141 u32 c2 = 0;
7142 u32 c3 = 0;
7143 u32 c4 = 0;
7144 u32 *tlvs = 0;
7145 u32 decap_next_index = NSH_INPUT_NEXT_IP4_INPUT;
7146 u32 tmp;
7147 int i;
7148
7149 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
7150 if (unformat (line_input, "del"))
7151 is_add = 0;
7152 else if (unformat (line_input, "src %U",
7153 unformat_ip4_address, &src))
7154 src_set = 1;
7155 else if (unformat (line_input, "dst %U",
7156 unformat_ip4_address, &dst))
7157 dst_set = 1;
7158 else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
7159 ;
7160 else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
7161 ;
7162 else if (unformat (line_input, "decap-next %U",
7163 unformat_nsh_gre_decap_next, &decap_next_index))
7164 ;
7165 else if (unformat (line_input, "version %d", &tmp))
7166 ver_o_c |= (tmp & 3) << 6;
7167 else if (unformat (line_input, "o-bit %d", &tmp))
7168 ver_o_c |= (tmp & 1) << 5;
7169 else if (unformat (line_input, "c-bit %d", &tmp))
7170 ver_o_c |= (tmp & 1) << 4;
7171 else if (unformat (line_input, "md-type %d", &tmp))
7172 md_type = tmp;
7173 else if (unformat(line_input, "next-ip4"))
7174 next_protocol = 1;
7175 else if (unformat(line_input, "next-ip6"))
7176 next_protocol = 2;
7177 else if (unformat(line_input, "next-ethernet"))
7178 next_protocol = 3;
7179 else if (unformat (line_input, "c1 %d", &c1))
7180 ;
7181 else if (unformat (line_input, "c2 %d", &c2))
7182 ;
7183 else if (unformat (line_input, "c3 %d", &c3))
7184 ;
7185 else if (unformat (line_input, "c4 %d", &c4))
7186 ;
7187 else if (unformat (line_input, "spi %d", &spi))
7188 spi_set = 1;
7189 else if (unformat (line_input, "si %d", &si))
7190 si_set = 1;
7191 else if (unformat (line_input, "tlv %x"))
7192 vec_add1 (tlvs, tmp);
7193 else {
7194 errmsg ("parse error '%U'\n", format_unformat_error, line_input);
7195 return -99;
7196 }
7197 }
7198
7199 if (src_set == 0) {
7200 errmsg ("tunnel src address not specified\n");
7201 return -99;
7202 }
7203 if (dst_set == 0) {
7204 errmsg ("tunnel dst address not specified\n");
7205 return -99;
7206 }
7207
7208 if (spi_set == 0) {
7209 errmsg ("spi not specified\n");
7210 return -99;
7211 }
7212
7213 if (si_set == 0) {
7214 errmsg ("si not specified\n");
7215 return -99;
7216 }
7217
7218 M2 (NSH_GRE_ADD_DEL_TUNNEL, nsh_gre_add_del_tunnel,
7219 sizeof(u32) * vec_len (tlvs));
7220
7221 spi_si = (spi<<8) | si;
7222
7223 mp->src = src.as_u32;
7224 mp->dst = dst.as_u32;
7225 mp->encap_vrf_id = ntohl(encap_vrf_id);
7226 mp->decap_vrf_id = ntohl(decap_vrf_id);
7227 mp->decap_next_index = ntohl(decap_next_index);
7228 mp->tlv_len_in_words = vec_len (tlvs);
7229 mp->is_add = is_add;
7230 mp->ver_o_c = ver_o_c;
7231 mp->length = 6 + vec_len(tlvs);
7232 mp->md_type = md_type;
7233 mp->next_protocol = next_protocol;
7234 mp->spi_si = ntohl(spi_si);
7235 mp->c1 = ntohl(c1);
7236 mp->c2 = ntohl(c2);
7237 mp->c3 = ntohl(c3);
7238 mp->c4 = ntohl(c4);
7239
7240 for (i = 0; i < vec_len(tlvs); i++)
7241 mp->tlvs[i] = ntohl(tlvs[i]);
7242
7243 vec_free (tlvs);
7244
7245 S; W;
7246 /* NOTREACHED */
7247 return 0;
7248}
7249
7250static uword unformat_nsh_vxlan_gpe_decap_next
7251(unformat_input_t * input, va_list * args)
7252{
7253 u32 * result = va_arg (*args, u32 *);
7254 u32 tmp;
7255
7256 if (unformat (input, "drop"))
7257 *result = NSH_VXLAN_GPE_INPUT_NEXT_DROP;
7258 else if (unformat (input, "ip4"))
7259 *result = NSH_VXLAN_GPE_INPUT_NEXT_IP4_INPUT;
7260 else if (unformat (input, "ip6"))
7261 *result = NSH_VXLAN_GPE_INPUT_NEXT_IP6_INPUT;
7262 else if (unformat (input, "ethernet"))
7263 *result = NSH_VXLAN_GPE_INPUT_NEXT_ETHERNET_INPUT;
7264 else if (unformat (input, "nsh-vxlan-gpe"))
7265 *result = NSH_VXLAN_GPE_INPUT_NEXT_ETHERNET_INPUT;
7266 else if (unformat (input, "%d", &tmp))
7267 *result = tmp;
7268 else
7269 return 0;
7270 return 1;
7271}
7272
7273static int api_nsh_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
7274{
7275 unformat_input_t * line_input = vam->input;
7276 vl_api_nsh_vxlan_gpe_add_del_tunnel_t *mp;
7277 f64 timeout;
7278 ip4_address_t src, dst;
7279 u8 is_add = 1;
7280 u8 src_set = 0;
7281 u8 dst_set = 0;
7282 u32 encap_vrf_id = 0;
7283 u32 decap_vrf_id = 0;
7284 u8 ver_o_c = 0;
7285 u8 md_type = 0;
7286 u8 next_protocol = 1; /* ip4 */
7287 u32 spi;
7288 u8 spi_set = 0;
7289 u32 si;
7290 u8 si_set = 0;
7291 u32 spi_si;
7292 u32 c1 = 0;
7293 u32 c2 = 0;
7294 u32 c3 = 0;
7295 u32 c4 = 0;
7296 u32 *tlvs = 0;
7297 u32 decap_next_index = NSH_INPUT_NEXT_IP4_INPUT;
7298 u32 vni;
7299 u8 vni_set = 0;
7300 u32 tmp;
7301 int i;
7302
7303 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
7304 if (unformat (line_input, "del"))
7305 is_add = 0;
7306 else if (unformat (line_input, "src %U",
7307 unformat_ip4_address, &src))
7308 src_set = 1;
7309 else if (unformat (line_input, "dst %U",
7310 unformat_ip4_address, &dst))
7311 dst_set = 1;
7312 else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
7313 ;
7314 else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
7315 ;
7316 else if (unformat (line_input, "decap-next %U",
7317 unformat_nsh_vxlan_gpe_decap_next,
7318 &decap_next_index))
7319 ;
7320 else if (unformat (line_input, "vni %d", &vni))
7321 vni_set = 1;
7322 else if (unformat (line_input, "version %d", &tmp))
7323 ver_o_c |= (tmp & 3) << 6;
7324 else if (unformat (line_input, "o-bit %d", &tmp))
7325 ver_o_c |= (tmp & 1) << 5;
7326 else if (unformat (line_input, "c-bit %d", &tmp))
7327 ver_o_c |= (tmp & 1) << 4;
7328 else if (unformat (line_input, "md-type %d", &tmp))
7329 md_type = tmp;
7330 else if (unformat(line_input, "next-ip4"))
7331 next_protocol = 1;
7332 else if (unformat(line_input, "next-ip6"))
7333 next_protocol = 2;
7334 else if (unformat(line_input, "next-ethernet"))
7335 next_protocol = 3;
7336 else if (unformat (line_input, "c1 %d", &c1))
7337 ;
7338 else if (unformat (line_input, "c2 %d", &c2))
7339 ;
7340 else if (unformat (line_input, "c3 %d", &c3))
7341 ;
7342 else if (unformat (line_input, "c4 %d", &c4))
7343 ;
7344 else if (unformat (line_input, "spi %d", &spi))
7345 spi_set = 1;
7346 else if (unformat (line_input, "si %d", &si))
7347 si_set = 1;
7348 else if (unformat (line_input, "tlv %x"))
7349 vec_add1 (tlvs, tmp);
7350 else {
7351 errmsg ("parse error '%U'\n", format_unformat_error, line_input);
7352 return -99;
7353 }
7354 }
7355
7356 if (src_set == 0) {
7357 errmsg ("tunnel src address not specified\n");
7358 return -99;
7359 }
7360 if (dst_set == 0) {
7361 errmsg ("tunnel dst address not specified\n");
7362 return -99;
7363 }
7364
7365 if (spi_set == 0) {
7366 errmsg ("spi not specified\n");
7367 return -99;
7368 }
7369
7370 if (si_set == 0) {
7371 errmsg ("si not specified\n");
7372 return -99;
7373 }
7374 if (vni_set == 0) {
7375 errmsg ("vni not specified\n");
7376 return -99;
7377 }
7378
7379 M2 (NSH_VXLAN_GPE_ADD_DEL_TUNNEL, nsh_vxlan_gpe_add_del_tunnel,
7380 sizeof(u32) * vec_len (tlvs));
7381
7382 spi_si = (spi<<8) | si;
7383
7384 mp->src = src.as_u32;
7385 mp->dst = dst.as_u32;
7386 mp->encap_vrf_id = ntohl(encap_vrf_id);
7387 mp->decap_vrf_id = ntohl(decap_vrf_id);
7388 mp->decap_next_index = ntohl(decap_next_index);
7389 mp->tlv_len_in_words = vec_len (tlvs);
7390 mp->vni = ntohl(vni);
7391 mp->is_add = is_add;
7392 mp->ver_o_c = ver_o_c;
7393 mp->length = 6 + vec_len(tlvs);
7394 mp->md_type = md_type;
7395 mp->next_protocol = next_protocol;
7396 mp->spi_si = ntohl(spi_si);
7397 mp->c1 = ntohl(c1);
7398 mp->c2 = ntohl(c2);
7399 mp->c3 = ntohl(c3);
7400 mp->c4 = ntohl(c4);
7401
7402 for (i = 0; i < vec_len(tlvs); i++)
7403 mp->tlvs[i] = ntohl(tlvs[i]);
7404
7405 vec_free (tlvs);
7406
7407 S; W;
7408 /* NOTREACHED */
7409 return 0;
7410}
7411
7412static uword unformat_lisp_gpe_decap_next (unformat_input_t * input,
7413 va_list * args)
7414{
7415 u32 * result = va_arg (*args, u32 *);
7416 u32 tmp;
7417
7418 if (unformat (input, "drop"))
7419 *result = LISP_GPE_INPUT_NEXT_DROP;
7420 else if (unformat (input, "ip4"))
7421 *result = LISP_GPE_INPUT_NEXT_IP4_INPUT;
7422 else if (unformat (input, "ip6"))
7423 *result = LISP_GPE_INPUT_NEXT_IP6_INPUT;
7424 else if (unformat (input, "ethernet"))
7425 *result = LISP_GPE_INPUT_NEXT_IP6_INPUT;
7426 else if (unformat (input, "lisp-gpe"))
7427 *result = LISP_GPE_INPUT_NEXT_LISP_GPE_ENCAP;
7428 else if (unformat (input, "%d", &tmp))
7429 *result = tmp;
7430 else
7431 return 0;
7432 return 1;
7433}
7434
7435static int
7436api_lisp_gpe_add_del_tunnel (vat_main_t * vam)
7437{
7438 unformat_input_t * line_input = vam->input;
7439 vl_api_lisp_gpe_add_del_tunnel_t *mp;
7440 f64 timeout;
7441 ip4_address_t src, dst;
7442 u8 is_add = 1;
7443 u8 src_set = 0;
7444 u8 dst_set = 0;
7445 u32 encap_vrf_id = 0;
7446 u32 decap_vrf_id = 0;
7447 u8 next_protocol = LISP_GPE_NEXT_PROTOCOL_IP4;
7448 u32 decap_next_index = LISP_GPE_INPUT_NEXT_IP4_INPUT;
7449 u8 flags = LISP_GPE_FLAGS_P;
7450 u8 ver_res = 0;
7451 u8 res = 0;
7452 u32 iid = 0;
7453 u8 iid_set = 0;
7454 u32 tmp;
7455
7456 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
7457 if (unformat (line_input, "del"))
7458 is_add = 0;
7459 else if (unformat (line_input, "src %U",
7460 unformat_ip4_address, &src))
7461 src_set = 1;
7462 else if (unformat (line_input, "dst %U",
7463 unformat_ip4_address, &dst))
7464 dst_set = 1;
7465 else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
7466 ;
7467 else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
7468 ;
7469 else if (unformat (line_input, "decap-next %U",
7470 unformat_lisp_gpe_decap_next,
7471 &decap_next_index))
7472 ;
7473 else if (unformat(line_input, "next-ip4"))
7474 next_protocol = 1;
7475 else if (unformat(line_input, "next-ip6"))
7476 next_protocol = 2;
7477 else if (unformat(line_input, "next-ethernet"))
7478 next_protocol = 3;
7479 else if (unformat(line_input, "next-nsh"))
7480 next_protocol = 4;
7481 /* Allow the user to specify anything they want in the LISP hdr */
7482 else if (unformat (line_input, "ver_res %x", &tmp))
7483 ver_res = tmp;
7484 else if (unformat (line_input, "res %x", &tmp))
7485 res = tmp;
7486 else if (unformat (line_input, "flags %x", &tmp))
7487 flags = tmp;
7488 else if (unformat (line_input, "n-bit"))
7489 flags |= LISP_GPE_FLAGS_N;
7490 else if (unformat (line_input, "l-bit"))
7491 flags |= LISP_GPE_FLAGS_L;
7492 else if (unformat (line_input, "e-bit"))
7493 flags |= LISP_GPE_FLAGS_E;
7494 else if (unformat (line_input, "v-bit"))
7495 flags |= LISP_GPE_FLAGS_V;
7496 else if (unformat (line_input, "i-bit"))
7497 flags |= LISP_GPE_FLAGS_V;
7498 else if (unformat (line_input, "not-p-bit"))
7499 flags &= !LISP_GPE_FLAGS_P;
7500 else if (unformat (line_input, "p-bit"))
7501 flags |= LISP_GPE_FLAGS_P;
7502 else if (unformat (line_input, "o-bit"))
7503 flags |= LISP_GPE_FLAGS_O;
7504 else if (unformat (line_input, "iidx %x", &iid))
7505 iid_set = 1;
7506 else if (unformat (line_input, "iid %d", &iid))
7507 iid_set = 1;
7508 else {
7509 errmsg ("parse error '%U'\n", format_unformat_error, line_input);
7510 return -99;
7511 }
7512 }
7513
7514 if (src_set == 0) {
7515 errmsg ("tunnel src address not specified\n");
7516 return -99;
7517 }
7518 if (dst_set == 0) {
7519 errmsg ("tunnel dst address not specified\n");
7520 return -99;
7521 }
7522 if (iid_set == 0) {
7523 errmsg ("iid not specified\n");
7524 return -99;
7525 }
7526
7527 M(LISP_GPE_ADD_DEL_TUNNEL, lisp_gpe_add_del_tunnel);
7528
7529 mp->src = src.as_u32;
7530 mp->dst = dst.as_u32;
7531 mp->encap_vrf_id = ntohl(encap_vrf_id);
7532 mp->decap_vrf_id = ntohl(decap_vrf_id);
7533 mp->decap_next_index = ntohl(decap_next_index);
7534 mp->is_add = is_add;
7535 mp->flags = flags;
7536 mp->ver_res = ver_res;
7537 mp->res = res;
7538 mp->next_protocol = next_protocol;
7539 mp->iid = ntohl(iid);
7540
7541 S; W;
7542
7543 /* NOTREACHED */
7544 return 0;
7545}
7546
7547
7548u8 * format_l2_fib_mac_address (u8 * s, va_list * args)
7549{
7550 u8 * a = va_arg (*args, u8 *);
7551
7552 return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
7553 a[2], a[3], a[4], a[5], a[6], a[7]);
7554}
7555
7556static void vl_api_l2_fib_table_entry_t_handler
7557(vl_api_l2_fib_table_entry_t * mp)
7558{
7559 vat_main_t * vam = &vat_main;
7560
7561 fformat(vam->ofp, "%3" PRIu32 " %U %3" PRIu32
7562 " %d %d %d\n",
7563 ntohl(mp->bd_id), format_l2_fib_mac_address, &mp->mac,
7564 ntohl(mp->sw_if_index), mp->static_mac, mp->filter_mac,
7565 mp->bvi_mac);
7566}
7567
7568static void vl_api_l2_fib_table_entry_t_handler_json
7569(vl_api_l2_fib_table_entry_t * mp)
7570{
7571 vat_main_t * vam = &vat_main;
7572 vat_json_node_t *node = NULL;
7573
7574 if (VAT_JSON_ARRAY != vam->json_tree.type) {
7575 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
7576 vat_json_init_array(&vam->json_tree);
7577 }
7578 node = vat_json_array_add(&vam->json_tree);
7579
7580 vat_json_init_object(node);
7581 vat_json_object_add_uint(node, "bd_id", ntohl(mp->bd_id));
7582 vat_json_object_add_uint(node, "mac", clib_net_to_host_u64(mp->mac));
7583 vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
7584 vat_json_object_add_uint(node, "static_mac", mp->static_mac);
7585 vat_json_object_add_uint(node, "filter_mac", mp->filter_mac);
7586 vat_json_object_add_uint(node, "bvi_mac", mp->bvi_mac);
7587}
7588
7589static int api_l2_fib_table_dump (vat_main_t * vam)
7590{
7591 unformat_input_t * i = vam->input;
7592 vl_api_l2_fib_table_dump_t *mp;
7593 f64 timeout;
7594 u32 bd_id;
7595 u8 bd_id_set = 0;
7596
7597 /* Parse args required to build the message */
7598 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7599 if (unformat (i, "bd_id %d", &bd_id))
7600 bd_id_set = 1;
7601 else
7602 break;
7603 }
7604
7605 if (bd_id_set == 0) {
7606 errmsg ("missing bridge domain\n");
7607 return -99;
7608 }
7609
7610 fformat(vam->ofp, "BD-ID Mac Address sw-ndx Static Filter BVI\n");
7611
7612 /* Get list of l2 fib entries */
7613 M(L2_FIB_TABLE_DUMP, l2_fib_table_dump);
7614
7615 mp->bd_id = ntohl(bd_id);
7616 S;
7617
7618 /* Use a control ping for synchronization */
7619 {
7620 vl_api_control_ping_t * mp;
7621 M(CONTROL_PING, control_ping);
7622 S;
7623 }
7624 W;
7625}
7626
7627
7628static int
7629api_interface_name_renumber (vat_main_t * vam)
7630{
7631 unformat_input_t * line_input = vam->input;
7632 vl_api_interface_name_renumber_t *mp;
7633 u32 sw_if_index = ~0;
7634 f64 timeout;
7635 u32 new_show_dev_instance = ~0;
7636
7637 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
7638 if (unformat (line_input, "%U", unformat_sw_if_index, vam,
7639 &sw_if_index))
7640 ;
7641 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
7642 ;
7643 else if (unformat (line_input, "new_show_dev_instance %d",
7644 &new_show_dev_instance))
7645 ;
7646 else
7647 break;
7648 }
7649
7650 if (sw_if_index == ~0) {
7651 errmsg ("missing interface name or sw_if_index\n");
7652 return -99;
7653 }
7654
7655 if (new_show_dev_instance == ~0) {
7656 errmsg ("missing new_show_dev_instance\n");
7657 return -99;
7658 }
7659
7660 M(INTERFACE_NAME_RENUMBER, interface_name_renumber);
7661
7662 mp->sw_if_index = ntohl (sw_if_index);
7663 mp->new_show_dev_instance = ntohl (new_show_dev_instance);
7664
7665 S; W;
7666}
7667
7668static int
7669api_want_ip4_arp_events (vat_main_t * vam)
7670{
7671 unformat_input_t * line_input = vam->input;
7672 vl_api_want_ip4_arp_events_t * mp;
7673 f64 timeout;
7674 ip4_address_t address;
7675 int address_set = 0;
7676 u32 enable_disable = 1;
7677
7678 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
7679 if (unformat (line_input, "address %U",
7680 unformat_ip4_address, &address))
7681 address_set = 1;
7682 else if (unformat (line_input, "del"))
7683 enable_disable = 0;
7684 else
7685 break;
7686 }
7687
7688 if (address_set == 0) {
7689 errmsg ("missing addresses\n");
7690 return -99;
7691 }
7692
7693 M(WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
7694 mp->enable_disable = enable_disable;
7695 mp->pid = getpid();
7696 mp->address = address.as_u32;
7697
7698 S; W;
7699}
7700
7701static int api_input_acl_set_interface (vat_main_t * vam)
7702{
7703 unformat_input_t * i = vam->input;
7704 vl_api_input_acl_set_interface_t *mp;
7705 f64 timeout;
7706 u32 sw_if_index;
7707 int sw_if_index_set;
7708 u32 ip4_table_index = ~0;
7709 u32 ip6_table_index = ~0;
7710 u32 l2_table_index = ~0;
7711 u8 is_add = 1;
7712
7713 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7714 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7715 sw_if_index_set = 1;
7716 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7717 sw_if_index_set = 1;
7718 else if (unformat (i, "del"))
7719 is_add = 0;
7720 else if (unformat (i, "ip4-table %d", &ip4_table_index))
7721 ;
7722 else if (unformat (i, "ip6-table %d", &ip6_table_index))
7723 ;
7724 else if (unformat (i, "l2-table %d", &l2_table_index))
7725 ;
7726 else {
7727 clib_warning ("parse error '%U'", format_unformat_error, i);
7728 return -99;
7729 }
7730 }
7731
7732 if (sw_if_index_set == 0) {
7733 errmsg ("missing interface name or sw_if_index\n");
7734 return -99;
7735 }
7736
7737 M(INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
7738
7739 mp->sw_if_index = ntohl(sw_if_index);
7740 mp->ip4_table_index = ntohl(ip4_table_index);
7741 mp->ip6_table_index = ntohl(ip6_table_index);
7742 mp->l2_table_index = ntohl(l2_table_index);
7743 mp->is_add = is_add;
7744
7745 S; W;
7746 /* NOTREACHED */
7747 return 0;
7748}
7749
7750static int
7751api_ip_address_dump (vat_main_t * vam)
7752{
7753 unformat_input_t * i = vam->input;
7754 vl_api_ip_address_dump_t * mp;
7755 u32 sw_if_index = ~0;
7756 u8 sw_if_index_set = 0;
7757 u8 ipv4_set = 0;
7758 u8 ipv6_set = 0;
7759 f64 timeout;
7760
7761 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7762 if (unformat (i, "sw_if_index %d", &sw_if_index))
7763 sw_if_index_set = 1;
7764 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7765 sw_if_index_set = 1;
7766 else if (unformat (i, "ipv4"))
7767 ipv4_set = 1;
7768 else if (unformat (i, "ipv6"))
7769 ipv6_set = 1;
7770 else
7771 break;
7772 }
7773
7774 if (ipv4_set && ipv6_set) {
7775 errmsg ("ipv4 and ipv6 flags cannot be both set\n");
7776 return -99;
7777 }
7778
7779 if ((!ipv4_set) && (!ipv6_set)) {
7780 errmsg ("no ipv4 nor ipv6 flag set\n");
7781 return -99;
7782 }
7783
7784 if (sw_if_index_set == 0) {
7785 errmsg ("missing interface name or sw_if_index\n");
7786 return -99;
7787 }
7788
7789 vam->current_sw_if_index = sw_if_index;
7790 vam->is_ipv6 = ipv6_set;
7791
7792 M(IP_ADDRESS_DUMP, ip_address_dump);
7793 mp->sw_if_index = ntohl(sw_if_index);
7794 mp->is_ipv6 = ipv6_set;
7795 S;
7796
7797 /* Use a control ping for synchronization */
7798 {
7799 vl_api_control_ping_t * mp;
7800 M(CONTROL_PING, control_ping);
7801 S;
7802 }
7803 W;
7804}
7805
7806static int
7807api_ip_dump (vat_main_t * vam)
7808{
7809 vl_api_ip_dump_t * mp;
7810 unformat_input_t * in = vam->input;
7811 int ipv4_set = 0;
7812 int ipv6_set = 0;
7813 int is_ipv6;
7814 f64 timeout;
7815 int i;
7816
7817 while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT) {
7818 if (unformat (in, "ipv4"))
7819 ipv4_set = 1;
7820 else if (unformat (in, "ipv6"))
7821 ipv6_set = 1;
7822 else
7823 break;
7824 }
7825
7826 if (ipv4_set && ipv6_set) {
7827 errmsg ("ipv4 and ipv6 flags cannot be both set\n");
7828 return -99;
7829 }
7830
7831 if ((!ipv4_set) && (!ipv6_set)) {
7832 errmsg ("no ipv4 nor ipv6 flag set\n");
7833 return -99;
7834 }
7835
7836 is_ipv6 = ipv6_set;
7837 vam->is_ipv6 = is_ipv6;
7838
7839 /* free old data */
7840 for (i = 0; i < vec_len(vam->ip_details_by_sw_if_index[is_ipv6]); i++) {
7841 vec_free(vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
7842 }
7843 vec_free(vam->ip_details_by_sw_if_index[is_ipv6]);
7844
7845 M(IP_DUMP, ip_dump);
7846 mp->is_ipv6 = ipv6_set;
7847 S;
7848
7849 /* Use a control ping for synchronization */
7850 {
7851 vl_api_control_ping_t * mp;
7852 M(CONTROL_PING, control_ping);
7853 S;
7854 }
7855 W;
7856}
7857
7858static int
7859api_ipsec_spd_add_del (vat_main_t * vam)
7860{
Dave Barachbfdedbd2016-01-20 09:11:55 -05007861#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -07007862 unformat_input_t * i = vam->input;
7863 vl_api_ipsec_spd_add_del_t *mp;
7864 f64 timeout;
7865 u32 spd_id = ~0;
7866 u8 is_add = 1;
7867
7868 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7869 if (unformat (i, "spd_id %d", &spd_id))
7870 ;
7871 else if (unformat (i, "del"))
7872 is_add = 0;
7873 else {
7874 clib_warning ("parse error '%U'", format_unformat_error, i);
7875 return -99;
7876 }
7877 }
7878 if (spd_id == ~0) {
7879 errmsg ("spd_id must be set\n");
7880 return -99;
7881 }
7882
7883 M(IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
7884
7885 mp->spd_id = ntohl(spd_id);
7886 mp->is_add = is_add;
7887
7888 S; W;
7889 /* NOTREACHED */
7890 return 0;
Dave Barachbfdedbd2016-01-20 09:11:55 -05007891#else
7892 clib_warning ("unsupported (no dpdk)");
7893 return -99;
7894#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -07007895}
7896
7897static int
7898api_ipsec_interface_add_del_spd (vat_main_t * vam)
7899{
Dave Barachbfdedbd2016-01-20 09:11:55 -05007900#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -07007901 unformat_input_t * i = vam->input;
7902 vl_api_ipsec_interface_add_del_spd_t *mp;
7903 f64 timeout;
7904 u32 sw_if_index;
7905 u8 sw_if_index_set = 0;
7906 u32 spd_id = (u32) ~0;
7907 u8 is_add = 1;
7908
7909 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7910 if (unformat (i, "del"))
7911 is_add = 0;
7912 else if (unformat (i, "spd_id %d", &spd_id))
7913 ;
7914 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7915 sw_if_index_set = 1;
7916 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7917 sw_if_index_set = 1;
7918 else {
7919 clib_warning ("parse error '%U'", format_unformat_error, i);
7920 return -99;
7921 }
7922
7923 }
7924
7925 if (spd_id == (u32) ~0) {
7926 errmsg ("spd_id must be set\n");
7927 return -99;
7928 }
7929
7930 if (sw_if_index_set == 0) {
7931 errmsg ("missing interface name or sw_if_index\n");
7932 return -99;
7933 }
7934
7935 M(IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
7936
7937 mp->spd_id = ntohl(spd_id);
7938 mp->sw_if_index = ntohl (sw_if_index);
7939 mp->is_add = is_add;
7940
7941 S; W;
7942 /* NOTREACHED */
7943 return 0;
Dave Barachbfdedbd2016-01-20 09:11:55 -05007944#else
7945 clib_warning ("unsupported (no dpdk)");
7946 return -99;
7947#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -07007948}
7949
7950static int
7951api_ipsec_spd_add_del_entry (vat_main_t * vam)
7952{
Dave Barachbfdedbd2016-01-20 09:11:55 -05007953#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -07007954 unformat_input_t * i = vam->input;
7955 vl_api_ipsec_spd_add_del_entry_t *mp;
7956 f64 timeout;
7957 u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
7958 u32 spd_id, sa_id, protocol = 0, policy = 0;
7959 i32 priority;
7960 u32 rport_start = 0, rport_stop = (u32) ~0;
7961 u32 lport_start = 0, lport_stop = (u32) ~0;
7962 ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
7963 ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
7964
7965 laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
7966 laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~0;
7967 laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
7968 laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
7969 laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~0;
7970 laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~0;
7971
7972 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7973 if (unformat (i, "del"))
7974 is_add = 0;
7975 if (unformat (i, "outbound"))
7976 is_outbound = 1;
7977 if (unformat (i, "inbound"))
7978 is_outbound = 0;
7979 else if (unformat (i, "spd_id %d", &spd_id))
7980 ;
7981 else if (unformat (i, "sa_id %d", &sa_id))
7982 ;
7983 else if (unformat (i, "priority %d", &priority))
7984 ;
7985 else if (unformat (i, "protocol %d", &protocol))
7986 ;
7987 else if (unformat (i, "lport_start %d", &lport_start))
7988 ;
7989 else if (unformat (i, "lport_stop %d", &lport_stop))
7990 ;
7991 else if (unformat (i, "rport_start %d", &rport_start))
7992 ;
7993 else if (unformat (i, "rport_stop %d", &rport_stop))
7994 ;
7995 else if (unformat (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
7996 {
7997 is_ipv6 = 0;
7998 is_ip_any =0;
7999 }
8000 else if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
8001 {
8002 is_ipv6 = 0;
8003 is_ip_any = 0;
8004 }
8005 else if (unformat (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
8006 {
8007 is_ipv6 = 0;
8008 is_ip_any = 0;
8009 }
8010 else if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
8011 {
8012 is_ipv6 = 0;
8013 is_ip_any = 0;
8014 }
8015 else if (unformat (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
8016 {
8017 is_ipv6 = 1;
8018 is_ip_any = 0;
8019 }
8020 else if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
8021 {
8022 is_ipv6 = 1;
8023 is_ip_any = 0;
8024 }
8025 else if (unformat (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
8026 {
8027 is_ipv6 = 1;
8028 is_ip_any = 0;
8029 }
8030 else if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
8031 {
8032 is_ipv6 = 1;
8033 is_ip_any = 0;
8034 }
8035 else if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
8036 {
8037 if (policy == IPSEC_POLICY_ACTION_RESOLVE) {
8038 clib_warning ("unsupported action: 'resolve'");
8039 return -99;
8040 }
8041 }
8042 else {
8043 clib_warning ("parse error '%U'", format_unformat_error, i);
8044 return -99;
8045 }
8046
8047 }
8048
8049 M(IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
8050
8051 mp->spd_id = ntohl(spd_id);
8052 mp->priority = ntohl(priority);
8053 mp->is_outbound = is_outbound;
8054
8055 mp->is_ipv6 = is_ipv6;
8056 if (is_ipv6 || is_ip_any) {
8057 memcpy (mp->remote_address_start, &raddr6_start, sizeof(ip6_address_t));
8058 memcpy (mp->remote_address_stop, &raddr6_stop, sizeof(ip6_address_t));
8059 memcpy (mp->local_address_start, &laddr6_start, sizeof(ip6_address_t));
8060 memcpy (mp->local_address_stop, &laddr6_stop, sizeof(ip6_address_t));
8061 } else {
8062 memcpy (mp->remote_address_start, &raddr4_start, sizeof(ip4_address_t));
8063 memcpy (mp->remote_address_stop, &raddr4_stop, sizeof(ip4_address_t));
8064 memcpy (mp->local_address_start, &laddr4_start, sizeof(ip4_address_t));
8065 memcpy (mp->local_address_stop, &laddr4_stop, sizeof(ip4_address_t));
8066 }
8067 mp->protocol = (u8) protocol;
8068 mp->local_port_start = ntohs((u16) lport_start);
8069 mp->local_port_stop = ntohs((u16) lport_stop);
8070 mp->remote_port_start = ntohs((u16) rport_start);
8071 mp->remote_port_stop = ntohs((u16) rport_stop);
8072 mp->policy = (u8) policy;
8073 mp->sa_id = ntohl(sa_id);
8074 mp->is_add = is_add;
8075 mp->is_ip_any = is_ip_any;
8076 S; W;
8077 /* NOTREACHED */
8078 return 0;
Dave Barachbfdedbd2016-01-20 09:11:55 -05008079#else
8080 clib_warning ("unsupported (no dpdk)");
8081 return -99;
8082#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -07008083}
8084
8085static int
8086api_ipsec_sad_add_del_entry (vat_main_t * vam)
8087{
Dave Barachbfdedbd2016-01-20 09:11:55 -05008088#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -07008089 unformat_input_t * i = vam->input;
8090 vl_api_ipsec_sad_add_del_entry_t *mp;
8091 f64 timeout;
8092 u32 sad_id, spi;
8093 u8 * ck, * ik;
8094 u8 is_add = 1;
8095
8096 u8 protocol = IPSEC_PROTOCOL_AH;
8097 u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
8098 u32 crypto_alg = 0, integ_alg = 0;
8099 ip4_address_t tun_src4;
8100 ip4_address_t tun_dst4;
8101 ip6_address_t tun_src6;
8102 ip6_address_t tun_dst6;
8103
8104 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8105 if (unformat (i, "del"))
8106 is_add = 0;
8107 else if (unformat (i, "sad_id %d", &sad_id))
8108 ;
8109 else if (unformat (i, "spi %d", &spi))
8110 ;
8111 else if (unformat (i, "esp"))
8112 protocol = IPSEC_PROTOCOL_ESP;
8113 else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4)) {
8114 is_tunnel = 1;
8115 is_tunnel_ipv6 = 0;
8116 }
8117 else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4)) {
8118 is_tunnel = 1;
8119 is_tunnel_ipv6 = 0;
8120 }
8121 else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6)) {
8122 is_tunnel = 1;
8123 is_tunnel_ipv6 = 1;
8124 }
8125 else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6)) {
8126 is_tunnel = 1;
8127 is_tunnel_ipv6 = 1;
8128 }
8129 else if (unformat (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg)) {
8130 if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
8131 crypto_alg > IPSEC_INTEG_ALG_SHA_512_256) {
8132 clib_warning ("unsupported crypto-alg: '%U'",
8133 format_ipsec_crypto_alg, crypto_alg);
8134 return -99;
8135 }
8136 }
8137 else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
8138 ;
8139 else if (unformat (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg)) {
8140 if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
8141 integ_alg > IPSEC_INTEG_ALG_SHA_512_256) {
8142 clib_warning ("unsupported integ-alg: '%U'",
8143 format_ipsec_integ_alg, integ_alg);
8144 return -99;
8145 }
8146 }
8147 else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
8148 ;
8149 else {
8150 clib_warning ("parse error '%U'", format_unformat_error, i);
8151 return -99;
8152 }
8153
8154 }
8155
8156 M(IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
8157
8158 mp->sad_id = ntohl(sad_id);
8159 mp->is_add = is_add;
8160 mp->protocol = protocol;
8161 mp->spi = ntohl(spi);
8162 mp->is_tunnel = is_tunnel;
8163 mp->is_tunnel_ipv6 = is_tunnel_ipv6;
8164 mp->crypto_algorithm = crypto_alg;
8165 mp->integrity_algorithm = integ_alg;
8166 mp->crypto_key_length = vec_len(ck);
8167 mp->integrity_key_length = vec_len(ik);
8168
8169 if (mp->crypto_key_length > sizeof(mp->crypto_key))
8170 mp->crypto_key_length = sizeof(mp->crypto_key);
8171
8172 if (mp->integrity_key_length > sizeof(mp->integrity_key))
8173 mp->integrity_key_length = sizeof(mp->integrity_key);
8174
8175 memcpy (mp->crypto_key, ck, mp->crypto_key_length);
8176 memcpy (mp->integrity_key, ik, mp->integrity_key_length);
8177
8178 if (is_tunnel) {
8179 if (is_tunnel_ipv6) {
8180 memcpy (mp->tunnel_src_address, &tun_src6, sizeof(ip6_address_t));
8181 memcpy (mp->tunnel_dst_address, &tun_dst6, sizeof(ip6_address_t));
8182 } else {
8183 memcpy (mp->tunnel_src_address, &tun_src4, sizeof(ip4_address_t));
8184 memcpy (mp->tunnel_dst_address, &tun_dst4, sizeof(ip4_address_t));
8185 }
8186 }
8187
8188 S; W;
8189 /* NOTREACHED */
8190 return 0;
Dave Barachbfdedbd2016-01-20 09:11:55 -05008191#else
8192 clib_warning ("unsupported (no dpdk)");
8193 return -99;
8194#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -07008195}
8196
8197static int
8198api_ipsec_sa_set_key (vat_main_t * vam)
8199{
Dave Barachbfdedbd2016-01-20 09:11:55 -05008200#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -07008201 unformat_input_t * i = vam->input;
8202 vl_api_ipsec_sa_set_key_t *mp;
8203 f64 timeout;
8204 u32 sa_id;
8205 u8 * ck, * ik;
8206
8207 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8208 if (unformat (i, "sa_id %d", &sa_id))
8209 ;
8210 else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
8211 ;
8212 else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
8213 ;
8214 else {
8215 clib_warning ("parse error '%U'", format_unformat_error, i);
8216 return -99;
8217 }
8218 }
8219
8220 M(IPSEC_SA_SET_KEY, ipsec_set_sa_key);
8221
8222 mp->sa_id = ntohl(sa_id);
8223 mp->crypto_key_length = vec_len(ck);
8224 mp->integrity_key_length = vec_len(ik);
8225
8226 if (mp->crypto_key_length > sizeof(mp->crypto_key))
8227 mp->crypto_key_length = sizeof(mp->crypto_key);
8228
8229 if (mp->integrity_key_length > sizeof(mp->integrity_key))
8230 mp->integrity_key_length = sizeof(mp->integrity_key);
8231
8232 memcpy (mp->crypto_key, ck, mp->crypto_key_length);
8233 memcpy (mp->integrity_key, ik, mp->integrity_key_length);
8234
8235 S; W;
8236 /* NOTREACHED */
8237 return 0;
Dave Barachbfdedbd2016-01-20 09:11:55 -05008238#else
8239 clib_warning ("unsupported (no dpdk)");
8240 return -99;
8241#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -07008242}
8243
8244/*
8245 * MAP
8246 */
8247static int api_map_add_domain (vat_main_t * vam)
8248{
8249 unformat_input_t *i = vam->input;
8250 vl_api_map_add_domain_t *mp;
8251 f64 timeout;
8252
8253 ip4_address_t ip4_prefix;
8254 ip6_address_t ip6_prefix;
8255 ip6_address_t ip6_src;
8256 u32 num_m_args = 0;
8257 u32 ip6_prefix_len, ip4_prefix_len, ea_bits_len, psid_offset,
8258 psid_length;
8259 u8 is_translation = 0;
8260 u32 mtu = 0;
8261 u8 ip6_src_len = 128;
8262
8263 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8264 if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
8265 &ip4_prefix, &ip4_prefix_len))
8266 num_m_args++;
8267 else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
8268 &ip6_prefix, &ip6_prefix_len))
8269 num_m_args++;
8270 else if (unformat (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src, &ip6_src_len))
8271 num_m_args++;
8272 else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
8273 num_m_args++;
8274 else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
8275 num_m_args++;
8276 else if (unformat (i, "psid-offset %d", &psid_offset))
8277 num_m_args++;
8278 else if (unformat (i, "psid-len %d", &psid_length))
8279 num_m_args++;
8280 else if (unformat (i, "mtu %d", &mtu))
8281 num_m_args++;
8282 else if (unformat (i, "map-t"))
8283 is_translation = 1;
8284 else {
8285 clib_warning ("parse error '%U'", format_unformat_error, i);
8286 return -99;
8287 }
8288 }
8289
8290 if (num_m_args != 6) {
8291 errmsg("mandatory argument(s) missing\n");
8292 return -99;
8293 }
8294
8295 /* Construct the API message */
8296 M(MAP_ADD_DOMAIN, map_add_domain);
8297
8298 memcpy(mp->ip4_prefix, &ip4_prefix, sizeof(ip4_prefix));
8299 mp->ip4_prefix_len = ip4_prefix_len;
8300
8301 memcpy(mp->ip6_prefix, &ip6_prefix, sizeof(ip6_prefix));
8302 mp->ip6_prefix_len = ip6_prefix_len;
8303
8304 memcpy(mp->ip6_src, &ip6_src, sizeof(ip6_src));
8305 mp->ip6_src_prefix_len = ip6_src_len;
8306
8307 mp->ea_bits_len = ea_bits_len;
8308 mp->psid_offset = psid_offset;
8309 mp->psid_length = psid_length;
8310 mp->is_translation = is_translation;
8311 mp->mtu = htons(mtu);
8312
8313 /* send it... */
8314 S;
8315
8316 /* Wait for a reply, return good/bad news */
8317 W;
8318}
8319
8320static int api_map_del_domain (vat_main_t * vam)
8321{
8322 unformat_input_t *i = vam->input;
8323 vl_api_map_del_domain_t *mp;
8324 f64 timeout;
8325
8326 u32 num_m_args = 0;
8327 u32 index;
8328
8329 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8330 if (unformat (i, "index %d", &index))
8331 num_m_args++;
8332 else {
8333 clib_warning ("parse error '%U'", format_unformat_error, i);
8334 return -99;
8335 }
8336 }
8337
8338 if (num_m_args != 1) {
8339 errmsg("mandatory argument(s) missing\n");
8340 return -99;
8341 }
8342
8343 /* Construct the API message */
8344 M(MAP_DEL_DOMAIN, map_del_domain);
8345
8346 mp->index = ntohl(index);
8347
8348 /* send it... */
8349 S;
8350
8351 /* Wait for a reply, return good/bad news */
8352 W;
8353}
8354
8355static int api_map_add_del_rule (vat_main_t * vam)
8356{
8357 unformat_input_t *i = vam->input;
8358 vl_api_map_add_del_rule_t *mp;
8359 f64 timeout;
8360 u8 is_add = 1;
8361 ip6_address_t ip6_dst;
8362 u32 num_m_args = 0, index, psid;
8363
8364 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8365 if (unformat (i, "index %d", &index))
8366 num_m_args++;
8367 else if (unformat (i, "psid %d", &psid))
8368 num_m_args++;
8369 else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
8370 num_m_args++;
8371 else if (unformat (i, "del")) {
8372 is_add = 0;
8373 } else {
8374 clib_warning ("parse error '%U'", format_unformat_error, i);
8375 return -99;
8376 }
8377 }
8378
8379 /* Construct the API message */
8380 M(MAP_ADD_DEL_RULE, map_add_del_rule);
8381
8382 mp->index = ntohl(index);
8383 mp->is_add = is_add;
8384 memcpy(mp->ip6_dst, &ip6_dst, sizeof(ip6_dst));
8385 mp->psid = ntohs(psid);
8386
8387 /* send it... */
8388 S;
8389
8390 /* Wait for a reply, return good/bad news */
8391 W;
8392}
8393
8394static int api_map_domain_dump (vat_main_t * vam)
8395{
8396 vl_api_map_domain_dump_t *mp;
8397 f64 timeout;
8398
8399 /* Construct the API message */
8400 M(MAP_DOMAIN_DUMP, map_domain_dump);
8401
8402 /* send it... */
8403 S;
8404
8405 /* Use a control ping for synchronization */
8406 {
8407 vl_api_control_ping_t * mp;
8408 M(CONTROL_PING, control_ping);
8409 S;
8410 }
8411 W;
8412}
8413
8414static int api_map_rule_dump (vat_main_t * vam)
8415{
8416 unformat_input_t *i = vam->input;
8417 vl_api_map_rule_dump_t *mp;
8418 f64 timeout;
8419 u32 domain_index = ~0;
8420
8421 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8422 if (unformat (i, "index %u", &domain_index))
8423 ;
8424 else
8425 break;
8426 }
8427
8428 if (domain_index == ~0) {
8429 clib_warning("parse error: domain index expected");
8430 return -99;
8431 }
8432
8433 /* Construct the API message */
8434 M(MAP_RULE_DUMP, map_rule_dump);
8435
8436 mp->domain_index = htonl(domain_index);
8437
8438 /* send it... */
8439 S;
8440
8441 /* Use a control ping for synchronization */
8442 {
8443 vl_api_control_ping_t * mp;
8444 M(CONTROL_PING, control_ping);
8445 S;
8446 }
8447 W;
8448}
8449
8450static void vl_api_map_add_domain_reply_t_handler
8451(vl_api_map_add_domain_reply_t * mp)
8452{
8453 vat_main_t * vam = &vat_main;
8454 i32 retval = ntohl(mp->retval);
8455
8456 if (vam->async_mode) {
8457 vam->async_errors += (retval < 0);
8458 } else {
8459 vam->retval = retval;
8460 vam->result_ready = 1;
8461 }
8462}
8463
8464static void vl_api_map_add_domain_reply_t_handler_json
8465(vl_api_map_add_domain_reply_t * mp)
8466{
8467 vat_main_t * vam = &vat_main;
8468 vat_json_node_t node;
8469
8470 vat_json_init_object(&node);
8471 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
8472 vat_json_object_add_uint(&node, "index", ntohl(mp->index));
8473
8474 vat_json_print(vam->ofp, &node);
8475 vat_json_free(&node);
8476
8477 vam->retval = ntohl(mp->retval);
8478 vam->result_ready = 1;
8479}
8480
8481static int
8482api_get_first_msg_id (vat_main_t * vam)
8483{
8484 vl_api_get_first_msg_id_t * mp;
8485 f64 timeout;
8486 unformat_input_t * i = vam->input;
8487 u8 * name;
8488 u8 name_set = 0;
8489
8490 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8491 if (unformat (i, "client %s", &name))
8492 name_set = 1;
8493 else
8494 break;
8495 }
8496
8497 if (name_set == 0) {
8498 errmsg ("missing client name\n");
8499 return -99;
8500 }
8501 vec_add1 (name, 0);
8502
8503 if (vec_len (name) > 63) {
8504 errmsg ("client name too long\n");
8505 return -99;
8506 }
8507
8508 M(GET_FIRST_MSG_ID, get_first_msg_id);
8509 memcpy (mp->name, name, vec_len(name));
8510 S; W;
8511 /* NOTREACHED */
8512 return 0;
8513}
8514
Dave Barachc07bf5d2016-02-17 17:52:26 -05008515static int api_cop_interface_enable_disable (vat_main_t * vam)
8516{
8517 unformat_input_t * line_input = vam->input;
8518 vl_api_cop_interface_enable_disable_t * mp;
8519 f64 timeout;
8520 u32 sw_if_index = ~0;
8521 u8 enable_disable = 1;
8522
8523 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
8524 if (unformat (line_input, "disable"))
8525 enable_disable = 0;
8526 if (unformat (line_input, "enable"))
8527 enable_disable = 1;
8528 else if (unformat (line_input, "%U", unformat_sw_if_index,
8529 vam, &sw_if_index))
8530 ;
8531 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
8532 ;
8533 else
8534 break;
8535 }
8536
8537 if (sw_if_index == ~0) {
8538 errmsg ("missing interface name or sw_if_index\n");
8539 return -99;
8540 }
8541
8542 /* Construct the API message */
8543 M(COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
8544 mp->sw_if_index = ntohl(sw_if_index);
8545 mp->enable_disable = enable_disable;
8546
8547 /* send it... */
8548 S;
8549 /* Wait for the reply */
8550 W;
8551}
8552
8553static int api_cop_whitelist_enable_disable (vat_main_t * vam)
8554{
8555 unformat_input_t * line_input = vam->input;
8556 vl_api_cop_whitelist_enable_disable_t * mp;
8557 f64 timeout;
8558 u32 sw_if_index = ~0;
8559 u8 ip4=0, ip6=0, default_cop=0;
8560 u32 fib_id;
8561
8562 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
8563 if (unformat (line_input, "ip4"))
8564 ip4 = 1;
8565 else if (unformat (line_input, "ip6"))
8566 ip6 = 1;
8567 else if (unformat (line_input, "default"))
8568 default_cop = 1;
8569 else if (unformat (line_input, "%U", unformat_sw_if_index,
8570 vam, &sw_if_index))
8571 ;
8572 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
8573 ;
8574 else if (unformat (line_input, "fib-id %d", &fib_id))
8575 ;
8576 else
8577 break;
8578 }
8579
8580 if (sw_if_index == ~0) {
8581 errmsg ("missing interface name or sw_if_index\n");
8582 return -99;
8583 }
8584
8585 /* Construct the API message */
8586 M(COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
8587 mp->sw_if_index = ntohl(sw_if_index);
8588 mp->fib_id = ntohl(fib_id);
8589 mp->ip4 = ip4;
8590 mp->ip6 = ip6;
8591 mp->default_cop = default_cop;
8592
8593 /* send it... */
8594 S;
8595 /* Wait for the reply */
8596 W;
8597}
8598
Dave Barachb44e9bc2016-02-19 09:06:23 -05008599static int api_get_node_graph (vat_main_t * vam)
8600{
8601 vl_api_get_node_graph_t * mp;
8602 f64 timeout;
8603
8604 M(GET_NODE_GRAPH, get_node_graph);
8605
8606 /* send it... */
8607 S;
8608 /* Wait for the reply */
8609 W;
8610}
8611
Ed Warnickecb9cada2015-12-08 15:45:58 -07008612static int q_or_quit (vat_main_t * vam)
8613{
8614 longjmp (vam->jump_buf, 1);
8615 return 0; /* not so much */
8616}
8617static int q (vat_main_t * vam) {return q_or_quit (vam);}
8618static int quit (vat_main_t * vam) {return q_or_quit (vam);}
8619
8620static int comment (vat_main_t * vam)
8621{
8622 return 0;
8623}
8624
Matus Fabiand2dc3df2015-12-14 10:31:33 -05008625static int cmd_cmp (void * a1, void * a2)
8626{
8627 u8 ** c1 = a1;
8628 u8 ** c2 = a2;
8629
8630 return strcmp ((char *)(c1[0]), (char *)(c2[0]));
8631}
8632
Ed Warnickecb9cada2015-12-08 15:45:58 -07008633static int help (vat_main_t * vam)
8634{
8635 u8 ** cmds = 0;
8636 u8 * name = 0;
8637 hash_pair_t * p;
8638 unformat_input_t * i = vam->input;
8639 int j;
8640
8641 if (unformat (i, "%s", &name)) {
8642 uword *hs;
8643
8644 vec_add1(name, 0);
8645
8646 hs = hash_get_mem (vam->help_by_name, name);
8647 if (hs)
8648 fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
8649 else
8650 fformat (vam->ofp, "No such msg / command '%s'\n", name);
8651 vec_free(name);
8652 return 0;
8653 }
8654
8655 fformat(vam->ofp, "Help is available for the following:\n");
8656
8657 hash_foreach_pair (p, vam->function_by_name,
8658 ({
8659 vec_add1 (cmds, (u8 *)(p->key));
8660 }));
8661
Matus Fabiand2dc3df2015-12-14 10:31:33 -05008662 vec_sort_with_function (cmds, cmd_cmp);
Ed Warnickecb9cada2015-12-08 15:45:58 -07008663
8664 for (j = 0; j < vec_len(cmds); j++)
8665 fformat (vam->ofp, "%s\n", cmds[j]);
8666
8667 vec_free (cmds);
8668 return 0;
8669}
8670
8671static int set (vat_main_t * vam)
8672{
8673 u8 * name = 0, * value = 0;
8674 unformat_input_t * i = vam->input;
8675
8676 if (unformat (i, "%s", &name)) {
8677 /* The input buffer is a vector, not a string. */
8678 value = vec_dup (i->buffer);
8679 vec_delete (value, i->index, 0);
8680 /* Almost certainly has a trailing newline */
8681 if (value[vec_len(value)-1] == '\n')
8682 value[vec_len(value)-1] = 0;
8683 /* Make sure it's a proper string, one way or the other */
8684 vec_add1 (value, 0);
8685 (void) clib_macro_set_value (&vam->macro_main,
8686 (char *)name, (char *)value);
8687 }
8688 else
8689 errmsg ("usage: set <name> <value>\n");
8690
8691 vec_free (name);
8692 vec_free (value);
8693 return 0;
8694}
8695
8696static int unset (vat_main_t * vam)
8697{
8698 u8 * name = 0;
8699
8700 if (unformat (vam->input, "%s", &name))
8701 if (clib_macro_unset (&vam->macro_main, (char *)name) == 1)
8702 errmsg ("unset: %s wasn't set\n", name);
8703 vec_free (name);
8704 return 0;
8705}
8706
8707typedef struct {
8708 u8 * name;
8709 u8 * value;
8710} macro_sort_t;
8711
8712
Matus Fabiand2dc3df2015-12-14 10:31:33 -05008713static int macro_sort_cmp (void * a1, void * a2)
8714{
8715 macro_sort_t * s1 = a1;
8716 macro_sort_t * s2 = a2;
8717
8718 return strcmp ((char *)(s1->name), (char *)(s2->name));
8719}
8720
Ed Warnickecb9cada2015-12-08 15:45:58 -07008721static int dump_macro_table (vat_main_t * vam)
8722{
8723 macro_sort_t * sort_me = 0, * sm;
8724 int i;
8725 hash_pair_t * p;
8726
8727 hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
8728 ({
8729 vec_add2 (sort_me, sm, 1);
8730 sm->name = (u8 *)(p->key);
8731 sm->value = (u8 *) (p->value[0]);
8732 }));
8733
Matus Fabiand2dc3df2015-12-14 10:31:33 -05008734 vec_sort_with_function (sort_me, macro_sort_cmp);
Ed Warnickecb9cada2015-12-08 15:45:58 -07008735
8736 if (vec_len(sort_me))
8737 fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
8738 else
8739 fformat (vam->ofp, "The macro table is empty...\n");
8740
8741 for (i = 0; i < vec_len (sort_me); i++)
8742 fformat (vam->ofp, "%-15s%s\n", sort_me[i].name,
8743 sort_me[i].value);
8744 return 0;
8745}
8746
Dave Barachb44e9bc2016-02-19 09:06:23 -05008747static int dump_node_table (vat_main_t * vam)
8748{
8749 int i, j;
8750 vlib_node_t * node, * next_node;
8751
8752 if (vec_len (vam->graph_nodes) == 0) {
8753 fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
8754 return 0;
8755 }
8756
8757 for (i = 0; i < vec_len (vam->graph_nodes); i++) {
8758 node = vam->graph_nodes[i];
8759 fformat (vam->ofp, "[%d] %s\n", i, node->name);
8760 for (j = 0; j < vec_len (node->next_nodes); j++) {
8761 if (node->next_nodes[j] != ~0) {
8762 next_node = vam->graph_nodes[node->next_nodes[j]];
8763 fformat (vam->ofp, " [%d] %s\n", j, next_node->name);
8764 }
8765 }
8766 }
8767 return 0;
8768}
8769
8770static int search_node_table (vat_main_t * vam)
8771{
8772 unformat_input_t * line_input = vam->input;
8773 u8 * node_to_find;
8774 int j;
8775 vlib_node_t * node, * next_node;
8776 uword * p;
8777
8778 if (vam->graph_node_index_by_name == 0) {
8779 fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
8780 return 0;
8781 }
8782
8783 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
8784 if (unformat (line_input, "%s", &node_to_find)) {
8785 vec_add1 (node_to_find, 0);
8786 p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
8787 if (p == 0) {
8788 fformat (vam->ofp, "%s not found...\n", node_to_find);
8789 goto out;
8790 }
8791 node = vam->graph_nodes[p[0]];
8792 fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
8793 for (j = 0; j < vec_len (node->next_nodes); j++) {
8794 if (node->next_nodes[j] != ~0) {
8795 next_node = vam->graph_nodes[node->next_nodes[j]];
8796 fformat (vam->ofp, " [%d] %s\n", j, next_node->name);
8797 }
8798 }
8799 }
8800
8801 else {
8802 clib_warning ("parse error '%U'", format_unformat_error,
8803 line_input);
8804 return -99;
8805 }
8806
8807 out:
8808 vec_free(node_to_find);
8809
8810 }
8811
8812 return 0;
8813}
8814
8815
Ed Warnickecb9cada2015-12-08 15:45:58 -07008816static int script (vat_main_t * vam)
8817{
8818 u8 * s = 0;
8819 char * save_current_file;
8820 unformat_input_t save_input;
8821 jmp_buf save_jump_buf;
8822 u32 save_line_number;
8823
8824 FILE * new_fp, * save_ifp;
8825
8826 if (unformat (vam->input, "%s", &s)) {
8827 new_fp = fopen ((char *)s, "r");
8828 if (new_fp == 0) {
8829 errmsg ("Couldn't open script file %s\n", s);
8830 vec_free (s);
8831 return -99;
8832 }
8833 } else {
8834 errmsg ("Missing script name\n");
8835 return -99;
8836 }
8837
8838 memcpy (&save_input, &vam->input, sizeof (save_input));
8839 memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
8840 save_ifp = vam->ifp;
8841 save_line_number = vam->input_line_number;
8842 save_current_file = (char *) vam->current_file;
8843
8844 vam->input_line_number = 0;
8845 vam->ifp = new_fp;
8846 vam->current_file = s;
8847 do_one_file (vam);
8848
8849 memcpy (&vam->input, &save_input, sizeof (vam->input));
8850 memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
8851 vam->ifp = save_ifp;
8852 vam->input_line_number = save_line_number;
8853 vam->current_file = (u8 *) save_current_file;
8854 vec_free (s);
8855
8856 return 0;
8857}
8858
8859static int echo (vat_main_t * vam)
8860{
8861 fformat (vam->ofp, "%v", vam->input->buffer);
8862 return 0;
8863}
8864
8865/* List of API message constructors, CLI names map to api_xxx */
8866#define foreach_vpe_api_msg \
8867_(create_loopback,"[mac <mac-addr>]") \
8868_(sw_interface_dump,"") \
8869_(sw_interface_set_flags, \
8870 "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
8871_(sw_interface_add_del_address, \
8872 "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
8873_(sw_interface_set_table, \
8874 "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]") \
8875_(sw_interface_set_vpath, \
8876 "<intfc> | sw_if_index <id> enable | disable") \
8877_(sw_interface_set_l2_xconnect, \
8878 "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
8879 "enable | disable") \
8880_(sw_interface_set_l2_bridge, \
8881 "rx <intfc> | rx_sw_if_index <id> bd_id <bridge-domain-id>\n" \
8882 "[shg <split-horizon-group>] [bvi]\n" \
8883 "enable | disable") \
8884_(bridge_domain_add_del, \
8885 "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
8886_(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n") \
8887_(l2fib_add_del, \
8888 "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi]\n") \
8889_(l2_flags, \
8890 "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
8891_(bridge_flags, \
8892 "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
8893_(tap_connect, \
8894 "tapname <name> mac <mac-addr> | random-mac") \
8895_(tap_modify, \
8896 "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
8897_(tap_delete, \
8898 "<vpp-if-name> | sw_if_index <id>") \
8899_(sw_interface_tap_dump, "") \
8900_(ip_add_del_route, \
8901 "<addr>/<mask> via <addr> [vrf <n>]\n" \
8902 "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n" \
8903 "[weight <n>] [drop] [local] [classify <n>] [del]\n" \
8904 "[multipath] [count <n>]") \
8905_(proxy_arp_add_del, \
8906 "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]") \
8907_(proxy_arp_intfc_enable_disable, \
8908 "<intfc> | sw_if_index <id> enable | disable") \
8909_(mpls_add_del_encap, \
8910 "label <n> dst <ip4-addr> [vrf <n>] [del]") \
8911_(mpls_add_del_decap, \
8912 "label <n> [rx_vrf_id <n>] [tx_vrf_id] [s-bit-clear][del]") \
8913_(mpls_gre_add_del_tunnel, \
8914 "inner_vrf_id <n> outer_vrf_id <n> src <ip4-address> dst <ip4-address>\n" \
8915 "adj <ip4-address>/<mask-width> [del]") \
8916_(sw_interface_set_unnumbered, \
8917 "<intfc> | sw_if_index <id> unnum_if_index <id> [del]") \
8918_(ip_neighbor_add_del, \
8919 "<intfc> | sw_if_index <id> dst <ip46-address> mac <mac-addr>") \
8920_(reset_vrf, "vrf <id> [ipv6]") \
8921_(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>") \
8922_(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n" \
8923 "[outer_vlan_id <n>][inner_vlan_id <n>]\n" \
8924 "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n" \
8925 "[outer_vlan_id_any][inner_vlan_id_any]") \
8926_(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]") \
8927_(reset_fib, "vrf <n> [ipv6]") \
8928_(dhcp_proxy_config, \
8929 "svr <v46-address> src <v46-address>\n" \
8930 "insert-cid <n> [del]") \
8931_(dhcp_proxy_config_2, \
8932 "svr <v46-address> src <v46-address>\n" \
8933 "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]") \
8934_(dhcp_proxy_set_vss, \
8935 "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]") \
8936_(dhcp_client_config, \
8937 "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
8938_(set_ip_flow_hash, \
8939 "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]") \
8940_(sw_interface_ip6_enable_disable, \
8941 "<intfc> | sw_if_index <id> enable | disable") \
8942_(sw_interface_ip6_set_link_local_address, \
8943 "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>") \
8944_(sw_interface_ip6nd_ra_prefix, \
8945 "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n" \
8946 "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n" \
8947 "[nolink] [isno]") \
8948_(sw_interface_ip6nd_ra_config, \
8949 "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n" \
8950 "[life <n>] [count <n>] [interval <n>] [surpress]\n" \
8951 "[managed] [other] [ll] [send] [cease] [isno] [def]") \
8952_(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]") \
8953_(l2_patch_add_del, \
8954 "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
8955 "enable | disable") \
8956_(mpls_ethernet_add_del_tunnel, \
8957 "tx <intfc> | tx_sw_if_index <n> dst <mac-addr>\n" \
8958 "adj <ip4-addr>/<mw> dst <mac-addr> [del]") \
8959_(mpls_ethernet_add_del_tunnel_2, \
8960 "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n" \
8961 "resolve-attempts <n> resolve-if-needed 0 | 1 [del]") \
8962_(sr_tunnel_add_del, \
8963 "src <ip6-addr> dst <ip6-addr>/<mw> (next <ip6-addr>)+\n" \
8964 " [tag <ip6-addr>]* [clean] [reroute]") \
8965_(classify_add_del_table, \
8966 "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n" \
8967 "[del] mask <mask-value>\n" \
8968 " [l2-miss-next | miss-next | acl-miss-next] <name|nn>") \
8969_(classify_add_del_session, \
8970 "[hit-next|l2-hit-next|acl-hit-next] <name|nn> table-index <nn>\n" \
8971 "skip_n <nn> match_n <nn> match [hex] [l2] [l3 [ip4|ip6]]") \
8972_(classify_set_interface_ip_table, \
8973 "<intfc> | sw_if_index <nn> table <nn>") \
8974_(classify_set_interface_l2_tables, \
8975 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
8976 " [other-table <nn>]") \
8977_(get_node_index, "node <node-name") \
8978_(add_node_next, "node <node-name> next <next-node-name>") \
8979_(l2tpv3_create_tunnel, \
8980 "client_address <ip6-addr> our_address <ip6-addr>\n" \
8981 "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
8982 "[remote_cookie <nn>]\n[l2-sublayer-preset]\n") \
8983_(l2tpv3_set_tunnel_cookies, \
8984 "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n" \
8985 "[new_remote_cookie <nn>]\n") \
8986_(l2tpv3_interface_enable_disable, \
8987 "<intfc> | sw_if_index <nn> enable | disable") \
8988_(l2tpv3_set_lookup_key, \
8989 "lookup_v6_src | lookup_v6_dst | lookup_session_id") \
8990_(sw_if_l2tpv3_tunnel_dump, "") \
8991_(vxlan_add_del_tunnel, \
8992 "src <ip4-addr> dst <ip4-addr> vni [encap-vrf-id <nn>]\n" \
8993 " [decap-next l2|ip4|ip6] [del]") \
Dave Wallace60231f32015-12-17 21:04:30 -05008994_(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
Ed Warnickecb9cada2015-12-08 15:45:58 -07008995_(l2_fib_clear_table, "") \
8996_(l2_interface_efp_filter, "sw_if_index <nn> enable | disable") \
8997_(l2_interface_vlan_tag_rewrite, \
8998 "<intfc> | sw_if_index <nn> \n" \
8999 "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n" \
9000 "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>") \
9001_(create_vhost_user_if, \
Pierre Pfisteref65cb02016-02-19 13:52:44 +00009002 "socket <filename> [server] [renumber <dev_instance>] " \
9003 "[mac <mac_address>]") \
Ed Warnickecb9cada2015-12-08 15:45:58 -07009004_(modify_vhost_user_if, \
9005 "<intfc> | sw_if_index <nn> socket <filename>\n" \
9006 "[server] [renumber <dev_instance>]") \
9007_(delete_vhost_user_if, "<intfc> | sw_if_index <nn>") \
9008_(sw_interface_vhost_user_dump, "") \
9009_(show_version, "") \
9010_(nsh_gre_add_del_tunnel, \
9011 "src <ip4-addr> dst <ip4-addr>" \
9012 "c1 <nn> c2 <nn> c3 <nn> c4 <nn> spi <nn> si <nn>\n" \
9013 "[encap-fib-id <nn>] [decap-fib-id <nn>] [o-bit <1|0>]\n" \
9014 "[c-bit <1|0>] [md-type <nn>][next-ip4][next-ip6][next-ethernet]\n" \
9015 "[tlv <xx>][del]") \
9016_(nsh_vxlan_gpe_add_del_tunnel, \
9017 "src <ip4-addr> dst <ip4-addr> vni <nn>\n" \
9018 "c1 <nn> c2 <nn> c3 <nn> c4 <nn> spi <nn> si <nn>\n" \
9019 "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [o-bit <1|0>]\n" \
9020 "[c-bit <1|0>] [md-type <nn>][next-ip4][next-ip6][next-ethernet]\n" \
9021 "[tlv <xx>][del]") \
9022_(l2_fib_table_dump, "bd_id <bridge-domain-id>") \
9023_(lisp_gpe_add_del_tunnel, \
9024 "src <ip4-addr> dst <ip4-addr> iid <nn>|iidx <0xnn>\n" \
9025 "[encap-vrf-id <nn>] [decap-vrf-id <nn>]\n" \
9026 "[n-bit][l-bit][e-bit][v-bit][i-bit][p-bit][not-p-bit][o-bit]\n" \
9027 "[next-ip4][next-ip6][next-ethernet][next-nsh]\n" \
9028 "[decap-next [ip4|ip6|ethernet|nsh-encap|<nn>]][del]") \
9029_(interface_name_renumber, \
9030 "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>") \
9031_(input_acl_set_interface, \
9032 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
9033 " [l2-table <nn>] [del]") \
9034_(want_ip4_arp_events, "address <ip4-address> [del]") \
9035_(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)") \
9036_(ip_dump, "ipv4 | ipv6") \
9037_(ipsec_spd_add_del, "spd_id <n> [del]") \
9038_(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n" \
9039 " spid_id <n> ") \
9040_(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n" \
9041 " crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n" \
9042 " integ_alg <alg> integ_key <hex>") \
9043_(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n" \
9044 " (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n" \
9045 " laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
9046 " [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
9047_(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>") \
9048_(delete_loopback,"sw_if_index <nn>") \
9049_(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
9050_(map_add_domain, \
9051 "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> " \
9052 "ip6-src <ip6addr> " \
9053 "ea-bits-len <n> psid-offset <n> psid-len <n>") \
9054_(map_del_domain, "index <n>") \
9055_(map_add_del_rule, \
9056 "index <n> psid <n> dst <ip6addr> [del]") \
9057_(map_domain_dump, "") \
9058_(map_rule_dump, "index <map-domain>") \
9059_(want_interface_events, "enable|disable") \
9060_(want_stats,"enable|disable") \
Dave Barachc07bf5d2016-02-17 17:52:26 -05009061_(get_first_msg_id, "client <name>") \
9062_(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
9063_(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n" \
Dave Barachb44e9bc2016-02-19 09:06:23 -05009064 "fib-id <nn> [ip4][ip6][default]") \
9065_(get_node_graph, " ")
Ed Warnickecb9cada2015-12-08 15:45:58 -07009066
9067/* List of command functions, CLI names map directly to functions */
9068#define foreach_cli_function \
9069_(comment, "usage: comment <ignore-rest-of-line>") \
9070_(dump_interface_table, "usage: dump_interface_table") \
9071_(dump_sub_interface_table, "usage: dump_sub_interface_table") \
9072_(dump_ipv4_table, "usage: dump_ipv4_table") \
9073_(dump_ipv6_table, "usage: dump_ipv6_table") \
9074_(dump_stats_table, "usage: dump_stats_table") \
9075_(dump_macro_table, "usage: dump_macro_table ") \
Dave Barachb44e9bc2016-02-19 09:06:23 -05009076_(dump_node_table, "usage: dump_node_table") \
Ed Warnickecb9cada2015-12-08 15:45:58 -07009077_(echo, "usage: echo <message>") \
9078_(exec, "usage: exec <vpe-debug-CLI-command>") \
9079_(help, "usage: help") \
9080_(q, "usage: quit") \
9081_(quit, "usage: quit") \
Dave Barachb44e9bc2016-02-19 09:06:23 -05009082_(search_node_table, "usage: search_node_table <name>...") \
Ed Warnickecb9cada2015-12-08 15:45:58 -07009083_(set, "usage: set <variable-name> <value>") \
9084_(script, "usage: script <file-name>") \
9085_(unset, "usage: unset <variable-name>")
9086
9087#define _(N,n) \
9088 static void vl_api_##n##_t_handler_uni \
9089 (vl_api_##n##_t * mp) \
9090 { \
9091 vat_main_t * vam = &vat_main; \
9092 if (vam->json_output) { \
9093 vl_api_##n##_t_handler_json(mp); \
9094 } else { \
9095 vl_api_##n##_t_handler(mp); \
9096 } \
9097 }
9098foreach_vpe_api_reply_msg;
9099#undef _
9100
9101void vat_api_hookup (vat_main_t *vam)
9102{
9103#define _(N,n) \
9104 vl_msg_api_set_handlers(VL_API_##N, #n, \
9105 vl_api_##n##_t_handler_uni, \
9106 vl_noop_handler, \
9107 vl_api_##n##_t_endian, \
9108 vl_api_##n##_t_print, \
9109 sizeof(vl_api_##n##_t), 1);
9110 foreach_vpe_api_reply_msg;
9111#undef _
9112
9113 vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
9114
9115 vam->sw_if_index_by_interface_name =
9116 hash_create_string (0, sizeof (uword));
9117
9118 vam->function_by_name =
9119 hash_create_string (0, sizeof(uword));
9120
9121 vam->help_by_name =
9122 hash_create_string (0, sizeof(uword));
9123
9124 /* API messages we can send */
9125#define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
9126 foreach_vpe_api_msg;
9127#undef _
9128
9129 /* Help strings */
9130#define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
9131 foreach_vpe_api_msg;
9132#undef _
9133
9134 /* CLI functions */
9135#define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
9136 foreach_cli_function;
9137#undef _
9138
9139 /* Help strings */
9140#define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
9141 foreach_cli_function;
9142#undef _
9143}
9144
9145#undef vl_api_version
9146#define vl_api_version(n,v) static u32 vpe_api_version = v;
9147#include <api/vpe.api.h>
9148#undef vl_api_version
9149
9150void vl_client_add_api_signatures (vl_api_memclnt_create_t *mp)
9151{
9152 /*
9153 * Send the main API signature in slot 0. This bit of code must
9154 * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
9155 */
9156 mp->api_versions[0] = clib_host_to_net_u32 (vpe_api_version);
9157}