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