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