blob: fea24684c6a434556dda91d9880421c9c3347f25 [file] [log] [blame]
Ed Warnickecb9cada2015-12-08 15:45:58 -07001/*
2 *------------------------------------------------------------------
3 * api_format.c
4 *
5 * Copyright (c) 2014 Cisco and/or its affiliates.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at:
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *------------------------------------------------------------------
18 */
19
20#include <vat/vat.h>
21#include <vlibapi/api.h>
22#include <vlibmemory/api.h>
23#include <vlibsocket/api.h>
24#include <vnet/ip/ip.h>
25#include <vnet/sr/sr_packet.h>
26#include <vnet/l2/l2_input.h>
27#include <vnet/l2tp/l2tp.h>
28#include <vnet/vxlan/vxlan.h>
Chris Luke27fe48f2016-04-28 13:44:38 -040029#include <vnet/gre/gre.h>
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -070030#include <vnet/vxlan-gpe/vxlan_gpe.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070031#include <vnet/lisp-gpe/lisp_gpe.h>
32
Dave Barachaa6920e2016-06-27 09:25:13 -040033#include <vpp-api/vpe_msg_enum.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070034#include <vnet/l2/l2_classify.h>
35#include <vnet/l2/l2_vtr.h>
36#include <vnet/classify/input_acl.h>
marek zavodsky2c21a9a2016-06-21 05:35:16 +020037#include <vnet/mpls-gre/mpls.h>
Dave Barachbfdedbd2016-01-20 09:11:55 -050038#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -070039#include <vnet/ipsec/ipsec.h>
Matus Fabiane5f42fe2016-04-08 11:18:08 +020040#include <vnet/ipsec/ikev2.h>
Dave Barachbfdedbd2016-01-20 09:11:55 -050041#else
42#include <inttypes.h>
43#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -070044#include <vnet/map/map.h>
Dave Barachc07bf5d2016-02-17 17:52:26 -050045#include <vnet/cop/cop.h>
Shwetha20a64f52016-03-25 10:55:01 +000046#include <vnet/ip/ip6_hop_by_hop.h>
Matus Fabian65fcd4d2016-05-13 05:44:48 -070047#include <vnet/policer/xlate.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070048
49#include "vat/json_format.h"
50
51#define vl_typedefs /* define message structures */
Dave Barachaa6920e2016-06-27 09:25:13 -040052#include <vpp-api/vpe_all_api_h.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070053#undef vl_typedefs
54
55/* declare message handlers for each api */
56
57#define vl_endianfun /* define message structures */
Dave Barachaa6920e2016-06-27 09:25:13 -040058#include <vpp-api/vpe_all_api_h.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070059#undef vl_endianfun
60
61/* instantiate all the print functions we know about */
62#define vl_print(handle, ...)
63#define vl_printfun
Dave Barachaa6920e2016-06-27 09:25:13 -040064#include <vpp-api/vpe_all_api_h.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070065#undef vl_printfun
66
67uword unformat_sw_if_index (unformat_input_t * input, va_list * args)
68{
69 vat_main_t * vam = va_arg (*args, vat_main_t *);
70 u32 * result = va_arg (*args, u32 *);
71 u8 * if_name;
72 uword * p;
73
74 if (!unformat (input, "%s", &if_name))
75 return 0;
76
77 p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
78 if (p == 0)
79 return 0;
80 *result = p[0];
81 return 1;
82}
83
84/* Parse an IP4 address %d.%d.%d.%d. */
85uword unformat_ip4_address (unformat_input_t * input, va_list * args)
86{
87 u8 * result = va_arg (*args, u8 *);
88 unsigned a[4];
89
90 if (! unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
91 return 0;
92
93 if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
94 return 0;
95
96 result[0] = a[0];
97 result[1] = a[1];
98 result[2] = a[2];
99 result[3] = a[3];
100
101 return 1;
102}
103
104
105uword
106unformat_ethernet_address (unformat_input_t * input, va_list * args)
107{
108 u8 * result = va_arg (*args, u8 *);
109 u32 i, a[6];
110
111 if (! unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
112 &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
113 return 0;
114
115 /* Check range. */
116 for (i = 0; i < 6; i++)
117 if (a[i] >= (1 << 8))
118 return 0;
119
120 for (i = 0; i < 6; i++)
121 result[i] = a[i];
122
123 return 1;
124}
125
126/* Returns ethernet type as an int in host byte order. */
127uword
128unformat_ethernet_type_host_byte_order (unformat_input_t * input,
129 va_list * args)
130{
131 u16 * result = va_arg (*args, u16 *);
132 int type;
133
134 /* Numeric type. */
135 if (unformat (input, "0x%x", &type)
136 || unformat (input, "%d", &type))
137 {
138 if (type >= (1 << 16))
139 return 0;
140 *result = type;
141 return 1;
142 }
143 return 0;
144}
145
146/* Parse an IP6 address. */
147uword unformat_ip6_address (unformat_input_t * input, va_list * args)
148{
149 ip6_address_t * result = va_arg (*args, ip6_address_t *);
150 u16 hex_quads[8];
151 uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
152 uword c, n_colon, double_colon_index;
153
154 n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
155 double_colon_index = ARRAY_LEN (hex_quads);
156 while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
157 {
158 hex_digit = 16;
159 if (c >= '0' && c <= '9')
160 hex_digit = c - '0';
161 else if (c >= 'a' && c <= 'f')
162 hex_digit = c + 10 - 'a';
163 else if (c >= 'A' && c <= 'F')
164 hex_digit = c + 10 - 'A';
165 else if (c == ':' && n_colon < 2)
166 n_colon++;
167 else
168 {
169 unformat_put_input (input);
170 break;
171 }
172
173 /* Too many hex quads. */
174 if (n_hex_quads >= ARRAY_LEN (hex_quads))
175 return 0;
176
177 if (hex_digit < 16)
178 {
179 hex_quad = (hex_quad << 4) | hex_digit;
180
181 /* Hex quad must fit in 16 bits. */
182 if (n_hex_digits >= 4)
183 return 0;
184
185 n_colon = 0;
186 n_hex_digits++;
187 }
188
189 /* Save position of :: */
190 if (n_colon == 2)
191 {
192 /* More than one :: ? */
193 if (double_colon_index < ARRAY_LEN (hex_quads))
194 return 0;
195 double_colon_index = n_hex_quads;
196 }
197
198 if (n_colon > 0 && n_hex_digits > 0)
199 {
200 hex_quads[n_hex_quads++] = hex_quad;
201 hex_quad = 0;
202 n_hex_digits = 0;
203 }
204 }
205
206 if (n_hex_digits > 0)
207 hex_quads[n_hex_quads++] = hex_quad;
208
209 {
210 word i;
211
212 /* Expand :: to appropriate number of zero hex quads. */
213 if (double_colon_index < ARRAY_LEN (hex_quads))
214 {
215 word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
216
217 for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
218 hex_quads[n_zero + i] = hex_quads[i];
219
220 for (i = 0; i < n_zero; i++)
221 hex_quads[double_colon_index + i] = 0;
222
223 n_hex_quads = ARRAY_LEN (hex_quads);
224 }
225
226 /* Too few hex quads given. */
227 if (n_hex_quads < ARRAY_LEN (hex_quads))
228 return 0;
229
230 for (i = 0; i < ARRAY_LEN (hex_quads); i++)
231 result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
232
233 return 1;
234 }
235}
236
237uword
238unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
239{
Dave Barachbfdedbd2016-01-20 09:11:55 -0500240#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -0700241 u32 * r = va_arg (*args, u32 *);
242
243 if (0) ;
244#define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
245 foreach_ipsec_policy_action
246#undef _
247 else
248 return 0;
249 return 1;
Dave Barachbfdedbd2016-01-20 09:11:55 -0500250#else
251 return 0;
252#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -0700253}
254
255uword
256unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
257{
Dave Barachbfdedbd2016-01-20 09:11:55 -0500258#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -0700259 u32 * r = va_arg (*args, u32 *);
260
261 if (0) ;
262#define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
263 foreach_ipsec_crypto_alg
264#undef _
265 else
266 return 0;
267 return 1;
Dave Barachbfdedbd2016-01-20 09:11:55 -0500268#else
269 return 0;
270#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -0700271}
272
273u8 *
274format_ipsec_crypto_alg (u8 * s, va_list * args)
275{
Dave Barachbfdedbd2016-01-20 09:11:55 -0500276#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -0700277 u32 i = va_arg (*args, u32);
278 u8 * t = 0;
279
280 switch (i)
281 {
282#define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
283 foreach_ipsec_crypto_alg
284#undef _
285 default:
286 return format (s, "unknown");
287 }
288 return format (s, "%s", t);
Dave Barachbfdedbd2016-01-20 09:11:55 -0500289#else
290 return format (s, "Unimplemented");
291#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -0700292}
293
294uword
295unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
296{
Dave Barachbfdedbd2016-01-20 09:11:55 -0500297#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -0700298 u32 * r = va_arg (*args, u32 *);
299
300 if (0) ;
301#define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
302 foreach_ipsec_integ_alg
303#undef _
304 else
305 return 0;
306 return 1;
Dave Barachbfdedbd2016-01-20 09:11:55 -0500307#else
308 return 0;
309#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -0700310}
311
312u8 *
313format_ipsec_integ_alg (u8 * s, va_list * args)
314{
Dave Barachbfdedbd2016-01-20 09:11:55 -0500315#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -0700316 u32 i = va_arg (*args, u32);
317 u8 * t = 0;
318
319 switch (i)
320 {
321#define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
322 foreach_ipsec_integ_alg
323#undef _
324 default:
325 return format (s, "unknown");
326 }
327 return format (s, "%s", t);
Dave Barachbfdedbd2016-01-20 09:11:55 -0500328#else
329 return format (s, "Unsupported");
330#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -0700331}
332
Matus Fabiane5f42fe2016-04-08 11:18:08 +0200333uword
334unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
335{
336#if DPDK > 0
337 u32 * r = va_arg (*args, u32 *);
338
339 if (0) ;
340#define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
341 foreach_ikev2_auth_method
342#undef _
343 else
344 return 0;
345 return 1;
346#else
347 return 0;
348#endif
349}
350
351uword
352unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
353{
354#if DPDK > 0
355 u32 * r = va_arg (*args, u32 *);
356
357 if (0) ;
358#define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
359 foreach_ikev2_id_type
360#undef _
361 else
362 return 0;
363 return 1;
364#else
365 return 0;
366#endif
367}
368
Matus Fabian65fcd4d2016-05-13 05:44:48 -0700369uword
370unformat_policer_rate_type (unformat_input_t * input, va_list * args)
371{
372 u8 * r = va_arg (*args, u8 *);
373
374 if (unformat (input, "kbps"))
375 *r = SSE2_QOS_RATE_KBPS;
376 else if (unformat(input, "pps"))
377 *r = SSE2_QOS_RATE_PPS;
378 else
379 return 0;
380 return 1;
381}
382
383uword
384unformat_policer_round_type (unformat_input_t * input, va_list * args)
385{
386 u8 * r = va_arg (*args, u8 *);
387
388 if (unformat(input, "closest"))
389 *r = SSE2_QOS_ROUND_TO_CLOSEST;
390 else if (unformat (input, "up"))
391 *r = SSE2_QOS_ROUND_TO_UP;
392 else if (unformat (input, "down"))
393 *r = SSE2_QOS_ROUND_TO_DOWN;
394 else
395 return 0;
396 return 1;
397}
398
399uword
400unformat_policer_type (unformat_input_t * input, va_list * args)
401{
402 u8 * r = va_arg (*args, u8 *);
403
404 if (unformat (input, "1r2c"))
405 *r = SSE2_QOS_POLICER_TYPE_1R2C;
406 else if (unformat (input, "1r3c"))
407 *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
408 else if (unformat (input, "2r3c-2698"))
409 *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
410 else if (unformat (input, "2r3c-4115"))
411 *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
412 else if (unformat (input, "2r3c-mef5cf1"))
413 *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
414 else
415 return 0;
416 return 1;
417}
418
Ed Warnickecb9cada2015-12-08 15:45:58 -0700419u8 * format_ip4_address (u8 * s, va_list * args)
420{
421 u8 * a = va_arg (*args, u8 *);
422 return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
423}
424
425u8 * format_ip6_address (u8 * s, va_list * args)
426{
427 ip6_address_t * a = va_arg (*args, ip6_address_t *);
428 u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
429
430 i_max_n_zero = ARRAY_LEN (a->as_u16);
431 max_n_zeros = 0;
432 i_first_zero = i_max_n_zero;
433 n_zeros = 0;
434 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
435 {
436 u32 is_zero = a->as_u16[i] == 0;
437 if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
438 {
439 i_first_zero = i;
440 n_zeros = 0;
441 }
442 n_zeros += is_zero;
443 if ((! is_zero && n_zeros > max_n_zeros)
444 || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
445 {
446 i_max_n_zero = i_first_zero;
447 max_n_zeros = n_zeros;
448 i_first_zero = ARRAY_LEN (a->as_u16);
449 n_zeros = 0;
450 }
451 }
452
453 last_double_colon = 0;
454 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
455 {
456 if (i == i_max_n_zero && max_n_zeros > 1)
457 {
458 s = format (s, "::");
459 i += max_n_zeros - 1;
460 last_double_colon = 1;
461 }
462 else
463 {
464 s = format (s, "%s%x",
465 (last_double_colon || i == 0) ? "" : ":",
466 clib_net_to_host_u16 (a->as_u16[i]));
467 last_double_colon = 0;
468 }
469 }
470
471 return s;
472}
473
Chris Luke99cb3352016-04-26 10:49:53 -0400474/* Format an IP46 address. */
475u8 * format_ip46_address (u8 * s, va_list * args)
476{
477 ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
Damjan Marion86be4872016-05-24 23:19:11 +0200478 ip46_type_t type = va_arg (*args, ip46_type_t);
479 int is_ip4 = 1;
480
481 switch (type)
482 {
483 case IP46_TYPE_ANY:
484 is_ip4 = ip46_address_is_ip4(ip46);
485 break;
486 case IP46_TYPE_IP4:
487 is_ip4 = 1;
488 break;
489 case IP46_TYPE_IP6:
490 is_ip4 = 0;
491 break;
492 }
493
494 return is_ip4 ?
Chris Luke99cb3352016-04-26 10:49:53 -0400495 format(s, "%U", format_ip4_address, &ip46->ip4):
496 format(s, "%U", format_ip6_address, &ip46->ip6);
497}
498
Ed Warnickecb9cada2015-12-08 15:45:58 -0700499u8 * format_ethernet_address (u8 * s, va_list * args)
500{
501 u8 * a = va_arg (*args, u8 *);
502
503 return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
504 a[0], a[1], a[2], a[3], a[4], a[5]);
505}
506
507void increment_v4_address (ip4_address_t * a)
508{
509 u32 v;
510
511 v = ntohl(a->as_u32) + 1;
512 a->as_u32 = ntohl(v);
513}
514
515void increment_v6_address (ip6_address_t * a)
516{
517 u64 v0, v1;
518
519 v0 = clib_net_to_host_u64 (a->as_u64[0]);
520 v1 = clib_net_to_host_u64 (a->as_u64[1]);
521
522 v1 += 1;
523 if (v1 == 0)
524 v0 += 1;
525 a->as_u64[0] = clib_net_to_host_u64 (v0);
526 a->as_u64[1] = clib_net_to_host_u64 (v1);
527}
528
529
530static void vl_api_create_loopback_reply_t_handler
531(vl_api_create_loopback_reply_t * mp)
532{
533 vat_main_t * vam = &vat_main;
534 i32 retval = ntohl(mp->retval);
535
536 vam->retval = retval;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700537 vam->regenerate_interface_table = 1;
Keith Burns (alagalah)802255c2016-06-13 16:56:04 -0700538 vam->sw_if_index = ntohl (mp->sw_if_index);
539 vam->result_ready = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700540}
541
542static void vl_api_create_loopback_reply_t_handler_json
543(vl_api_create_loopback_reply_t * mp)
544{
545 vat_main_t * vam = &vat_main;
546 vat_json_node_t node;
547
548 vat_json_init_object(&node);
549 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
550 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
551
552 vat_json_print(vam->ofp, &node);
553 vat_json_free(&node);
Keith Burns (alagalah)802255c2016-06-13 16:56:04 -0700554 vam->retval = ntohl(mp->retval);
555 vam->result_ready = 1;
556}
557
558static void vl_api_af_packet_create_reply_t_handler
559(vl_api_af_packet_create_reply_t * mp)
560{
561 vat_main_t * vam = &vat_main;
562 i32 retval = ntohl(mp->retval);
563
564 vam->retval = retval;
565 vam->regenerate_interface_table = 1;
566 vam->sw_if_index = ntohl (mp->sw_if_index);
567 vam->result_ready = 1;
568}
569
570static void vl_api_af_packet_create_reply_t_handler_json
571(vl_api_af_packet_create_reply_t * mp)
572{
573 vat_main_t * vam = &vat_main;
574 vat_json_node_t node;
575
576 vat_json_init_object(&node);
577 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
578 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
579
580 vat_json_print(vam->ofp, &node);
581 vat_json_free(&node);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700582
583 vam->retval = ntohl(mp->retval);
584 vam->result_ready = 1;
585}
586
587static void vl_api_create_vlan_subif_reply_t_handler
588(vl_api_create_vlan_subif_reply_t * mp)
589{
590 vat_main_t * vam = &vat_main;
591 i32 retval = ntohl(mp->retval);
592
593 vam->retval = retval;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700594 vam->regenerate_interface_table = 1;
Keith Burns (alagalah)802255c2016-06-13 16:56:04 -0700595 vam->sw_if_index = ntohl (mp->sw_if_index);
596 vam->result_ready = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700597}
598
599static void vl_api_create_vlan_subif_reply_t_handler_json
600(vl_api_create_vlan_subif_reply_t * mp)
601{
602 vat_main_t * vam = &vat_main;
603 vat_json_node_t node;
604
605 vat_json_init_object(&node);
606 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
607 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
608
609 vat_json_print(vam->ofp, &node);
610 vat_json_free(&node);
611
612 vam->retval = ntohl(mp->retval);
613 vam->result_ready = 1;
614}
615
616static void vl_api_create_subif_reply_t_handler
617(vl_api_create_subif_reply_t * mp)
618{
619 vat_main_t * vam = &vat_main;
620 i32 retval = ntohl(mp->retval);
621
622 vam->retval = retval;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700623 vam->regenerate_interface_table = 1;
Keith Burns (alagalah)802255c2016-06-13 16:56:04 -0700624 vam->sw_if_index = ntohl (mp->sw_if_index);
625 vam->result_ready = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700626}
627
628static void vl_api_create_subif_reply_t_handler_json
629(vl_api_create_subif_reply_t * mp)
630{
631 vat_main_t * vam = &vat_main;
632 vat_json_node_t node;
633
634 vat_json_init_object(&node);
635 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
636 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
637
638 vat_json_print(vam->ofp, &node);
639 vat_json_free(&node);
640
641 vam->retval = ntohl(mp->retval);
642 vam->result_ready = 1;
643}
644
645static void vl_api_interface_name_renumber_reply_t_handler
646(vl_api_interface_name_renumber_reply_t * mp)
647{
648 vat_main_t * vam = &vat_main;
649 i32 retval = ntohl(mp->retval);
650
651 vam->retval = retval;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700652 vam->regenerate_interface_table = 1;
Keith Burns (alagalah)802255c2016-06-13 16:56:04 -0700653 vam->result_ready = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700654}
655
656static void vl_api_interface_name_renumber_reply_t_handler_json
657(vl_api_interface_name_renumber_reply_t * mp)
658{
659 vat_main_t * vam = &vat_main;
660 vat_json_node_t node;
661
662 vat_json_init_object(&node);
663 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
664
665 vat_json_print(vam->ofp, &node);
666 vat_json_free(&node);
667
668 vam->retval = ntohl(mp->retval);
669 vam->result_ready = 1;
670}
671
672/*
673 * Special-case: build the interface table, maintain
674 * the next loopback sw_if_index vbl.
675 */
676static void vl_api_sw_interface_details_t_handler
677(vl_api_sw_interface_details_t * mp)
678{
679 vat_main_t * vam = &vat_main;
680 u8 * s = format (0, "%s%c", mp->interface_name, 0);
681
682 hash_set_mem (vam->sw_if_index_by_interface_name, s,
683 ntohl(mp->sw_if_index));
684
685 /* In sub interface case, fill the sub interface table entry */
686 if (mp->sw_if_index != mp->sup_sw_if_index) {
687 sw_interface_subif_t * sub = NULL;
688
689 vec_add2(vam->sw_if_subif_table, sub, 1);
690
691 vec_validate(sub->interface_name, strlen((char *)s) + 1);
692 strncpy((char *)sub->interface_name, (char *)s,
693 vec_len(sub->interface_name));
694 sub->sw_if_index = ntohl(mp->sw_if_index);
695 sub->sub_id = ntohl(mp->sub_id);
696
697 sub->sub_dot1ad = mp->sub_dot1ad;
698 sub->sub_number_of_tags = mp->sub_number_of_tags;
699 sub->sub_outer_vlan_id = ntohs(mp->sub_outer_vlan_id);
700 sub->sub_inner_vlan_id = ntohs(mp->sub_inner_vlan_id);
701 sub->sub_exact_match = mp->sub_exact_match;
702 sub->sub_default = mp->sub_default;
703 sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
704 sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
705
706 /* vlan tag rewrite */
707 sub->vtr_op = ntohl(mp->vtr_op);
708 sub->vtr_push_dot1q = ntohl(mp->vtr_push_dot1q);
709 sub->vtr_tag1 = ntohl(mp->vtr_tag1);
710 sub->vtr_tag2 = ntohl(mp->vtr_tag2);
711 }
712}
713
714static void vl_api_sw_interface_details_t_handler_json
715(vl_api_sw_interface_details_t * mp)
716{
717 vat_main_t * vam = &vat_main;
718 vat_json_node_t *node = NULL;
719
720 if (VAT_JSON_ARRAY != vam->json_tree.type) {
721 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
722 vat_json_init_array(&vam->json_tree);
723 }
724 node = vat_json_array_add(&vam->json_tree);
725
726 vat_json_init_object(node);
727 vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
728 vat_json_object_add_uint(node, "sup_sw_if_index", ntohl(mp->sup_sw_if_index));
729 vat_json_object_add_uint(node, "l2_address_length", ntohl(mp->l2_address_length));
730 vat_json_object_add_bytes(node, "l2_address", mp->l2_address, sizeof(mp->l2_address));
731 vat_json_object_add_string_copy(node, "interface_name", mp->interface_name);
732 vat_json_object_add_uint(node, "admin_up_down", mp->admin_up_down);
733 vat_json_object_add_uint(node, "link_up_down", mp->link_up_down);
734 vat_json_object_add_uint(node, "link_duplex", mp->link_duplex);
735 vat_json_object_add_uint(node, "link_speed", mp->link_speed);
Pavel84e4ffe2016-02-17 15:10:04 +0100736 vat_json_object_add_uint(node, "mtu", ntohs(mp->link_mtu));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700737 vat_json_object_add_uint(node, "sub_id", ntohl(mp->sub_id));
738 vat_json_object_add_uint(node, "sub_dot1ad", mp->sub_dot1ad);
739 vat_json_object_add_uint(node, "sub_number_of_tags", mp->sub_number_of_tags);
740 vat_json_object_add_uint(node, "sub_outer_vlan_id", ntohs(mp->sub_outer_vlan_id));
741 vat_json_object_add_uint(node, "sub_inner_vlan_id", ntohs(mp->sub_inner_vlan_id));
742 vat_json_object_add_uint(node, "sub_exact_match", mp->sub_exact_match);
743 vat_json_object_add_uint(node, "sub_default", mp->sub_default);
744 vat_json_object_add_uint(node, "sub_outer_vlan_id_any", mp->sub_outer_vlan_id_any);
745 vat_json_object_add_uint(node, "sub_inner_vlan_id_any", mp->sub_inner_vlan_id_any);
746 vat_json_object_add_uint(node, "vtr_op", ntohl(mp->vtr_op));
747 vat_json_object_add_uint(node, "vtr_push_dot1q", ntohl(mp->vtr_push_dot1q));
748 vat_json_object_add_uint(node, "vtr_tag1", ntohl(mp->vtr_tag1));
749 vat_json_object_add_uint(node, "vtr_tag2", ntohl(mp->vtr_tag2));
750}
751
752static void vl_api_sw_interface_set_flags_t_handler
753(vl_api_sw_interface_set_flags_t * mp)
754{
755 vat_main_t * vam = &vat_main;
756 if (vam->interface_event_display)
757 errmsg ("interface flags: sw_if_index %d %s %s\n",
758 ntohl(mp->sw_if_index),
759 mp->admin_up_down ? "admin-up" : "admin-down",
760 mp->link_up_down ? "link-up" : "link-down");
761}
762
763static void vl_api_sw_interface_set_flags_t_handler_json
764(vl_api_sw_interface_set_flags_t * mp)
765{
766 /* JSON output not supported */
767}
768
Pavel Kotucek00bbf272016-03-03 13:27:11 +0100769static void vl_api_cli_reply_t_handler
Ed Warnickecb9cada2015-12-08 15:45:58 -0700770(vl_api_cli_reply_t * mp)
771{
772 vat_main_t * vam = &vat_main;
773 i32 retval = ntohl(mp->retval);
774
775 vam->retval = retval;
776 vam->shmem_result = (u8 *) mp->reply_in_shmem;
777 vam->result_ready = 1;
778}
779
780static void vl_api_cli_reply_t_handler_json
781(vl_api_cli_reply_t * mp)
782{
783 vat_main_t * vam = &vat_main;
784 vat_json_node_t node;
Dave Barachb44e9bc2016-02-19 09:06:23 -0500785 api_main_t * am = &api_main;
786 void * oldheap;
787 u8 * reply;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700788
789 vat_json_init_object(&node);
790 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
Dave Barachb44e9bc2016-02-19 09:06:23 -0500791 vat_json_object_add_uint(&node, "reply_in_shmem",
792 ntohl(mp->reply_in_shmem));
793 /* Toss the shared-memory original... */
794 pthread_mutex_lock (&am->vlib_rp->mutex);
795 oldheap = svm_push_data_heap (am->vlib_rp);
796
797 reply = (u8 *)(mp->reply_in_shmem);
798 vec_free (reply);
799
800 svm_pop_heap (oldheap);
801 pthread_mutex_unlock (&am->vlib_rp->mutex);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700802
803 vat_json_print(vam->ofp, &node);
804 vat_json_free(&node);
805
806 vam->retval = ntohl(mp->retval);
807 vam->result_ready = 1;
808}
809
810static void vl_api_classify_add_del_table_reply_t_handler
811(vl_api_classify_add_del_table_reply_t * mp)
812{
813 vat_main_t * vam = &vat_main;
814 i32 retval = ntohl(mp->retval);
815 if (vam->async_mode) {
816 vam->async_errors += (retval < 0);
817 } else {
818 vam->retval = retval;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700819 if (retval == 0 &&
820 ((mp->new_table_index != 0xFFFFFFFF) ||
821 (mp->skip_n_vectors != 0xFFFFFFFF) ||
822 (mp->match_n_vectors != 0xFFFFFFFF)))
823 /*
824 * Note: this is just barely thread-safe, depends on
825 * the main thread spinning waiting for an answer...
826 */
827 errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d\n",
828 ntohl(mp->new_table_index),
829 ntohl(mp->skip_n_vectors), ntohl(mp->match_n_vectors));
Keith Burns (alagalah)802255c2016-06-13 16:56:04 -0700830 vam->result_ready = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700831 }
832}
833
834static void vl_api_classify_add_del_table_reply_t_handler_json
835(vl_api_classify_add_del_table_reply_t * mp)
836{
837 vat_main_t * vam = &vat_main;
838 vat_json_node_t node;
839
840 vat_json_init_object(&node);
841 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
842 vat_json_object_add_uint(&node, "new_table_index", ntohl(mp->new_table_index));
843 vat_json_object_add_uint(&node, "skip_n_vectors", ntohl(mp->skip_n_vectors));
844 vat_json_object_add_uint(&node, "match_n_vectors", ntohl(mp->match_n_vectors));
845
846 vat_json_print(vam->ofp, &node);
847 vat_json_free(&node);
848
849 vam->retval = ntohl(mp->retval);
850 vam->result_ready = 1;
851}
852
853static void vl_api_get_node_index_reply_t_handler
854(vl_api_get_node_index_reply_t * mp)
855{
856 vat_main_t * vam = &vat_main;
857 i32 retval = ntohl(mp->retval);
858 if (vam->async_mode) {
859 vam->async_errors += (retval < 0);
860 } else {
861 vam->retval = retval;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700862 if (retval == 0)
863 errmsg ("node index %d\n", ntohl(mp->node_index));
Keith Burns (alagalah)802255c2016-06-13 16:56:04 -0700864 vam->result_ready = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700865 }
866}
867
868static void vl_api_get_node_index_reply_t_handler_json
869(vl_api_get_node_index_reply_t * mp)
870{
871 vat_main_t * vam = &vat_main;
872 vat_json_node_t node;
873
874 vat_json_init_object(&node);
875 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
876 vat_json_object_add_uint(&node, "node_index", ntohl(mp->node_index));
877
878 vat_json_print(vam->ofp, &node);
879 vat_json_free(&node);
880
881 vam->retval = ntohl(mp->retval);
882 vam->result_ready = 1;
883}
884
885static void vl_api_add_node_next_reply_t_handler
886(vl_api_add_node_next_reply_t * mp)
887{
888 vat_main_t * vam = &vat_main;
889 i32 retval = ntohl(mp->retval);
890 if (vam->async_mode) {
891 vam->async_errors += (retval < 0);
892 } else {
893 vam->retval = retval;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700894 if (retval == 0)
895 errmsg ("next index %d\n", ntohl(mp->next_index));
Keith Burns (alagalah)802255c2016-06-13 16:56:04 -0700896 vam->result_ready = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700897 }
898}
899
900static void vl_api_add_node_next_reply_t_handler_json
901(vl_api_add_node_next_reply_t * mp)
902{
903 vat_main_t * vam = &vat_main;
904 vat_json_node_t node;
905
906 vat_json_init_object(&node);
907 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
908 vat_json_object_add_uint(&node, "next_index", ntohl(mp->next_index));
909
910 vat_json_print(vam->ofp, &node);
911 vat_json_free(&node);
912
913 vam->retval = ntohl(mp->retval);
914 vam->result_ready = 1;
915}
916
917static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler
918(vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
919{
920 vat_main_t * vam = &vat_main;
921 i32 retval = ntohl(mp->retval);
922 u32 sw_if_index = ntohl(mp->tunnel_sw_if_index);
923
924 if (retval >= 0 && sw_if_index != (u32)~0) {
925 errmsg ("tunnel_sw_if_index %d\n", sw_if_index);
926 }
927 vam->retval = retval;
928 vam->result_ready = 1;
929}
930
931static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler_json
932(vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
933{
934 vat_main_t * vam = &vat_main;
935 vat_json_node_t node;
936
937 vat_json_init_object(&node);
938 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
939 vat_json_object_add_uint(&node, "tunnel_sw_if_index", ntohl(mp->tunnel_sw_if_index));
940
941 vat_json_print(vam->ofp, &node);
942 vat_json_free(&node);
943
944 vam->retval = ntohl(mp->retval);
945 vam->result_ready = 1;
946}
947
Ed Warnickecb9cada2015-12-08 15:45:58 -0700948
Ed Warnickecb9cada2015-12-08 15:45:58 -0700949static void vl_api_show_version_reply_t_handler
950(vl_api_show_version_reply_t * mp)
951{
952 vat_main_t * vam = &vat_main;
953 i32 retval = ntohl(mp->retval);
954
955 if (retval >= 0) {
956 errmsg (" program: %s\n", mp->program);
Damjan Mariona0d4a1a2015-12-12 14:40:59 +0100957 errmsg (" version: %s\n", mp->version);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700958 errmsg (" build date: %s\n", mp->build_date);
959 errmsg ("build directory: %s\n", mp->build_directory);
960 }
961 vam->retval = retval;
962 vam->result_ready = 1;
963}
964
965static void vl_api_show_version_reply_t_handler_json
966(vl_api_show_version_reply_t * mp)
967{
968 vat_main_t * vam = &vat_main;
969 vat_json_node_t node;
970
971 vat_json_init_object(&node);
972 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
973 vat_json_object_add_string_copy(&node, "program", mp->program);
Damjan Mariona0d4a1a2015-12-12 14:40:59 +0100974 vat_json_object_add_string_copy(&node, "version", mp->version);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700975 vat_json_object_add_string_copy(&node, "build_date", mp->build_date);
976 vat_json_object_add_string_copy(&node, "build_directory", mp->build_directory);
977
978 vat_json_print(vam->ofp, &node);
979 vat_json_free(&node);
980
981 vam->retval = ntohl(mp->retval);
982 vam->result_ready = 1;
983}
984
985static void vl_api_ip4_arp_event_t_handler
986(vl_api_ip4_arp_event_t * mp)
987{
988 vat_main_t * vam = &vat_main;
989 errmsg ("arp event: address %U new mac %U sw_if_index %d\n",
990 format_ip4_address, &mp->address,
991 format_ethernet_address, mp->new_mac, mp->sw_if_index);
992}
993
994static void vl_api_ip4_arp_event_t_handler_json
995(vl_api_ip4_arp_event_t * mp)
996{
997 /* JSON output not supported */
998}
999
1000/*
1001 * Special-case: build the bridge domain table, maintain
1002 * the next bd id vbl.
1003 */
1004static void vl_api_bridge_domain_details_t_handler
1005(vl_api_bridge_domain_details_t * mp)
1006{
1007 vat_main_t * vam = &vat_main;
1008 u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1009
1010 fformat (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s\n",
1011 " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1012
1013 fformat (vam->ofp, "%3d %3d %3d %3d %3d %3d\n",
1014 ntohl (mp->bd_id), mp->learn, mp->forward,
1015 mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1016
1017 if (n_sw_ifs)
1018 fformat (vam->ofp, "\n\n%s %s %s\n", "sw_if_index", "SHG",
1019 "Interface Name");
1020}
1021
1022static void vl_api_bridge_domain_details_t_handler_json
1023(vl_api_bridge_domain_details_t * mp)
1024{
1025 vat_main_t * vam = &vat_main;
1026 vat_json_node_t *node, *array = NULL;
1027
1028 if (VAT_JSON_ARRAY != vam->json_tree.type) {
1029 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
1030 vat_json_init_array(&vam->json_tree);
1031 }
1032 node = vat_json_array_add(&vam->json_tree);
1033
1034 vat_json_init_object(node);
1035 vat_json_object_add_uint(node, "bd_id", ntohl(mp->bd_id));
1036 vat_json_object_add_uint(node, "flood", mp->flood);
1037 vat_json_object_add_uint(node, "forward", mp->forward);
1038 vat_json_object_add_uint(node, "learn", mp->learn);
1039 vat_json_object_add_uint(node, "bvi_sw_if_index", ntohl(mp->bvi_sw_if_index));
1040 vat_json_object_add_uint(node, "n_sw_ifs", ntohl(mp->n_sw_ifs));
1041 array = vat_json_object_add(node, "sw_if");
1042 vat_json_init_array(array);
1043}
1044
1045/*
1046 * Special-case: build the bridge domain sw if table.
1047 */
1048static void vl_api_bridge_domain_sw_if_details_t_handler
1049(vl_api_bridge_domain_sw_if_details_t * mp)
1050{
1051 vat_main_t * vam = &vat_main;
1052 hash_pair_t * p;
1053 u8 * sw_if_name = 0;
1054 u32 sw_if_index;
1055
1056 sw_if_index = ntohl (mp->sw_if_index);
1057 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1058 ({
1059 if ((u32) p->value[0] == sw_if_index) {
1060 sw_if_name = (u8 *)(p->key);
1061 break;
1062 }
1063 }));
1064
1065 fformat (vam->ofp, "%7d %3d %s", sw_if_index,
1066 mp->shg, sw_if_name ? (char *)sw_if_name :
1067 "sw_if_index not found!");
1068}
1069
1070static void vl_api_bridge_domain_sw_if_details_t_handler_json
1071(vl_api_bridge_domain_sw_if_details_t * mp)
1072{
1073 vat_main_t * vam = &vat_main;
1074 vat_json_node_t *node = NULL;
1075 uword last_index = 0;
1076
1077 ASSERT(VAT_JSON_ARRAY == vam->json_tree.type);
1078 ASSERT(vec_len(vam->json_tree.array) >= 1);
1079 last_index = vec_len(vam->json_tree.array) - 1;
1080 node = &vam->json_tree.array[last_index];
1081 node = vat_json_object_get_element(node, "sw_if");
1082 ASSERT(NULL != node);
1083 node = vat_json_array_add(node);
1084
1085 vat_json_init_object(node);
1086 vat_json_object_add_uint(node, "bd_id", ntohl(mp->bd_id));
1087 vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
1088 vat_json_object_add_uint(node, "shg", mp->shg);
1089}
1090
1091static void vl_api_control_ping_reply_t_handler
1092(vl_api_control_ping_reply_t * mp)
1093{
1094 vat_main_t * vam = &vat_main;
1095 i32 retval = ntohl(mp->retval);
1096 if (vam->async_mode) {
1097 vam->async_errors += (retval < 0);
1098 } else {
1099 vam->retval = retval;
1100 vam->result_ready = 1;
1101 }
1102}
1103
1104static void vl_api_control_ping_reply_t_handler_json
1105(vl_api_control_ping_reply_t * mp)
1106{
1107 vat_main_t * vam = &vat_main;
1108 i32 retval = ntohl(mp->retval);
1109
1110 if (VAT_JSON_NONE != vam->json_tree.type) {
1111 vat_json_print(vam->ofp, &vam->json_tree);
1112 vat_json_free(&vam->json_tree);
1113 vam->json_tree.type = VAT_JSON_NONE;
1114 } else {
1115 /* just print [] */
1116 vat_json_init_array(&vam->json_tree);
1117 vat_json_print(vam->ofp, &vam->json_tree);
1118 vam->json_tree.type = VAT_JSON_NONE;
1119 }
1120
1121 vam->retval = retval;
1122 vam->result_ready = 1;
1123}
1124
1125static void vl_api_l2_flags_reply_t_handler
1126(vl_api_l2_flags_reply_t * mp)
1127{
1128 vat_main_t * vam = &vat_main;
1129 i32 retval = ntohl(mp->retval);
1130 if (vam->async_mode) {
1131 vam->async_errors += (retval < 0);
1132 } else {
1133 vam->retval = retval;
1134 vam->result_ready = 1;
1135 }
1136}
1137
1138static void vl_api_l2_flags_reply_t_handler_json
1139(vl_api_l2_flags_reply_t * mp)
1140{
1141 vat_main_t * vam = &vat_main;
1142 vat_json_node_t node;
1143
1144 vat_json_init_object(&node);
1145 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1146 vat_json_object_add_uint(&node, "resulting_feature_bitmap", ntohl(mp->resulting_feature_bitmap));
1147
1148 vat_json_print(vam->ofp, &node);
1149 vat_json_free(&node);
1150
1151 vam->retval = ntohl(mp->retval);
1152 vam->result_ready = 1;
1153}
1154
1155static void vl_api_bridge_flags_reply_t_handler
1156(vl_api_bridge_flags_reply_t * mp)
1157{
1158 vat_main_t * vam = &vat_main;
1159 i32 retval = ntohl(mp->retval);
1160 if (vam->async_mode) {
1161 vam->async_errors += (retval < 0);
1162 } else {
1163 vam->retval = retval;
1164 vam->result_ready = 1;
1165 }
1166}
1167
1168static void vl_api_bridge_flags_reply_t_handler_json
1169(vl_api_bridge_flags_reply_t * mp)
1170{
1171 vat_main_t * vam = &vat_main;
1172 vat_json_node_t node;
1173
1174 vat_json_init_object(&node);
1175 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1176 vat_json_object_add_uint(&node, "resulting_feature_bitmap", ntohl(mp->resulting_feature_bitmap));
1177
1178 vat_json_print(vam->ofp, &node);
1179 vat_json_free(&node);
1180
1181 vam->retval = ntohl(mp->retval);
1182 vam->result_ready = 1;
1183}
1184
1185static void vl_api_tap_connect_reply_t_handler
1186(vl_api_tap_connect_reply_t * mp)
1187{
1188 vat_main_t * vam = &vat_main;
1189 i32 retval = ntohl(mp->retval);
1190 if (vam->async_mode) {
1191 vam->async_errors += (retval < 0);
1192 } else {
1193 vam->retval = retval;
Keith Burns (alagalah)802255c2016-06-13 16:56:04 -07001194 vam->sw_if_index = ntohl (mp->sw_if_index);
1195 vam->result_ready = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -07001196 }
Keith Burns (alagalah)802255c2016-06-13 16:56:04 -07001197
Ed Warnickecb9cada2015-12-08 15:45:58 -07001198}
1199
1200static void vl_api_tap_connect_reply_t_handler_json
1201(vl_api_tap_connect_reply_t * mp)
1202{
1203 vat_main_t * vam = &vat_main;
1204 vat_json_node_t node;
1205
1206 vat_json_init_object(&node);
1207 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1208 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
1209
1210 vat_json_print(vam->ofp, &node);
1211 vat_json_free(&node);
1212
1213 vam->retval = ntohl(mp->retval);
1214 vam->result_ready = 1;
Keith Burns (alagalah)802255c2016-06-13 16:56:04 -07001215
Ed Warnickecb9cada2015-12-08 15:45:58 -07001216}
1217
1218static void vl_api_tap_modify_reply_t_handler
1219(vl_api_tap_modify_reply_t * mp)
1220{
1221 vat_main_t * vam = &vat_main;
1222 i32 retval = ntohl(mp->retval);
1223 if (vam->async_mode) {
1224 vam->async_errors += (retval < 0);
1225 } else {
1226 vam->retval = retval;
Keith Burns (alagalah)802255c2016-06-13 16:56:04 -07001227 vam->sw_if_index = ntohl (mp->sw_if_index);
Ed Warnickecb9cada2015-12-08 15:45:58 -07001228 vam->result_ready = 1;
1229 }
1230}
1231
1232static void vl_api_tap_modify_reply_t_handler_json
1233(vl_api_tap_modify_reply_t * mp)
1234{
1235 vat_main_t * vam = &vat_main;
1236 vat_json_node_t node;
1237
1238 vat_json_init_object(&node);
1239 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1240 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
1241
1242 vat_json_print(vam->ofp, &node);
1243 vat_json_free(&node);
1244
1245 vam->retval = ntohl(mp->retval);
1246 vam->result_ready = 1;
1247}
1248
1249static void vl_api_tap_delete_reply_t_handler
1250(vl_api_tap_delete_reply_t * mp)
1251{
1252 vat_main_t * vam = &vat_main;
1253 i32 retval = ntohl(mp->retval);
1254 if (vam->async_mode) {
1255 vam->async_errors += (retval < 0);
1256 } else {
1257 vam->retval = retval;
1258 vam->result_ready = 1;
1259 }
1260}
1261
1262static void vl_api_tap_delete_reply_t_handler_json
1263(vl_api_tap_delete_reply_t * mp)
1264{
1265 vat_main_t * vam = &vat_main;
1266 vat_json_node_t node;
1267
1268 vat_json_init_object(&node);
1269 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1270
1271 vat_json_print(vam->ofp, &node);
1272 vat_json_free(&node);
1273
1274 vam->retval = ntohl(mp->retval);
1275 vam->result_ready = 1;
1276}
1277
1278static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler
1279(vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1280{
1281 vat_main_t * vam = &vat_main;
1282 i32 retval = ntohl(mp->retval);
1283 if (vam->async_mode) {
1284 vam->async_errors += (retval < 0);
1285 } else {
1286 vam->retval = retval;
1287 vam->result_ready = 1;
1288 }
1289}
1290
1291static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler_json
1292(vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1293{
1294 vat_main_t * vam = &vat_main;
1295 vat_json_node_t node;
1296
1297 vat_json_init_object(&node);
1298 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1299 vat_json_object_add_uint(&node, "tunnel_sw_if_index", ntohl(mp->tunnel_sw_if_index));
1300
1301 vat_json_print(vam->ofp, &node);
1302 vat_json_free(&node);
1303
1304 vam->retval = ntohl(mp->retval);
1305 vam->result_ready = 1;
1306}
1307
1308static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1309(vl_api_l2tpv3_create_tunnel_reply_t * mp)
1310{
1311 vat_main_t * vam = &vat_main;
1312 i32 retval = ntohl(mp->retval);
1313 if (vam->async_mode) {
1314 vam->async_errors += (retval < 0);
1315 } else {
1316 vam->retval = retval;
Keith Burns (alagalah)802255c2016-06-13 16:56:04 -07001317 vam->sw_if_index = ntohl (mp->sw_if_index);
Ed Warnickecb9cada2015-12-08 15:45:58 -07001318 vam->result_ready = 1;
1319 }
1320}
1321
1322static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1323(vl_api_l2tpv3_create_tunnel_reply_t * mp)
1324{
1325 vat_main_t * vam = &vat_main;
1326 vat_json_node_t node;
1327
1328 vat_json_init_object(&node);
1329 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1330 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
1331
1332 vat_json_print(vam->ofp, &node);
1333 vat_json_free(&node);
1334
1335 vam->retval = ntohl(mp->retval);
1336 vam->result_ready = 1;
1337}
1338
1339static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1340(vl_api_vxlan_add_del_tunnel_reply_t * mp)
1341{
1342 vat_main_t * vam = &vat_main;
1343 i32 retval = ntohl(mp->retval);
1344 if (vam->async_mode) {
1345 vam->async_errors += (retval < 0);
1346 } else {
1347 vam->retval = retval;
Keith Burns (alagalah)802255c2016-06-13 16:56:04 -07001348 vam->sw_if_index = ntohl (mp->sw_if_index);
Ed Warnickecb9cada2015-12-08 15:45:58 -07001349 vam->result_ready = 1;
1350 }
1351}
1352
1353static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1354(vl_api_vxlan_add_del_tunnel_reply_t * mp)
1355{
1356 vat_main_t * vam = &vat_main;
1357 vat_json_node_t node;
1358
1359 vat_json_init_object(&node);
1360 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1361 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
1362
1363 vat_json_print(vam->ofp, &node);
1364 vat_json_free(&node);
1365
1366 vam->retval = ntohl(mp->retval);
1367 vam->result_ready = 1;
1368}
1369
Chris Luke27fe48f2016-04-28 13:44:38 -04001370static void vl_api_gre_add_del_tunnel_reply_t_handler
1371(vl_api_gre_add_del_tunnel_reply_t * mp)
1372{
1373 vat_main_t * vam = &vat_main;
1374 i32 retval = ntohl(mp->retval);
1375 if (vam->async_mode) {
1376 vam->async_errors += (retval < 0);
1377 } else {
1378 vam->retval = retval;
Keith Burns (alagalah)802255c2016-06-13 16:56:04 -07001379 vam->sw_if_index = ntohl (mp->sw_if_index);
Chris Luke27fe48f2016-04-28 13:44:38 -04001380 vam->result_ready = 1;
1381 }
1382}
1383
1384static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1385(vl_api_gre_add_del_tunnel_reply_t * mp)
1386{
1387 vat_main_t * vam = &vat_main;
1388 vat_json_node_t node;
1389
1390 vat_json_init_object(&node);
1391 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1392 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
1393
1394 vat_json_print(vam->ofp, &node);
1395 vat_json_free(&node);
1396
1397 vam->retval = ntohl(mp->retval);
1398 vam->result_ready = 1;
1399}
1400
Ed Warnickecb9cada2015-12-08 15:45:58 -07001401static void vl_api_create_vhost_user_if_reply_t_handler
1402(vl_api_create_vhost_user_if_reply_t * mp)
1403{
1404 vat_main_t * vam = &vat_main;
1405 i32 retval = ntohl(mp->retval);
1406 if (vam->async_mode) {
1407 vam->async_errors += (retval < 0);
1408 } else {
1409 vam->retval = retval;
Keith Burns (alagalah)802255c2016-06-13 16:56:04 -07001410 vam->sw_if_index = ntohl (mp->sw_if_index);
Ed Warnickecb9cada2015-12-08 15:45:58 -07001411 vam->result_ready = 1;
1412 }
1413}
1414
1415static void vl_api_create_vhost_user_if_reply_t_handler_json
1416(vl_api_create_vhost_user_if_reply_t * mp)
1417{
1418 vat_main_t * vam = &vat_main;
1419 vat_json_node_t node;
1420
1421 vat_json_init_object(&node);
1422 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1423 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
1424
1425 vat_json_print(vam->ofp, &node);
1426 vat_json_free(&node);
1427
1428 vam->retval = ntohl(mp->retval);
1429 vam->result_ready = 1;
1430}
1431
1432static void vl_api_ip_address_details_t_handler
1433(vl_api_ip_address_details_t * mp)
1434{
1435 vat_main_t * vam = &vat_main;
1436 static ip_address_details_t empty_ip_address_details = {{0}};
1437 ip_address_details_t * address = NULL;
1438 ip_details_t * current_ip_details = NULL;
1439 ip_details_t * details = NULL;
1440
1441 details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1442
1443 if (!details || vam->current_sw_if_index >= vec_len(details)
1444 || !details[vam->current_sw_if_index].present) {
1445 errmsg ("ip address details arrived but not stored\n");
1446 errmsg ("ip_dump should be called first\n");
1447 return;
1448 }
1449
1450 current_ip_details = vec_elt_at_index(details,
1451 vam->current_sw_if_index);
1452
1453#define addresses (current_ip_details->addr)
1454
1455 vec_validate_init_empty(addresses, vec_len(addresses),
1456 empty_ip_address_details);
1457
1458 address = vec_elt_at_index(addresses, vec_len(addresses) - 1);
1459
Damjan Marionf1213b82016-03-13 02:22:06 +01001460 clib_memcpy(&address->ip, &mp->ip, sizeof(address->ip));
Ed Warnickecb9cada2015-12-08 15:45:58 -07001461 address->prefix_length = mp->prefix_length;
1462#undef addresses
1463}
1464
1465static void vl_api_ip_address_details_t_handler_json
1466(vl_api_ip_address_details_t * mp)
1467{
1468 vat_main_t * vam = &vat_main;
1469 vat_json_node_t *node = NULL;
1470 struct in6_addr ip6;
1471 struct in_addr ip4;
1472
1473 if (VAT_JSON_ARRAY != vam->json_tree.type) {
1474 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
1475 vat_json_init_array(&vam->json_tree);
1476 }
1477 node = vat_json_array_add(&vam->json_tree);
1478
1479 vat_json_init_object(node);
1480 if (vam->is_ipv6) {
Damjan Marionf1213b82016-03-13 02:22:06 +01001481 clib_memcpy(&ip6, mp->ip, sizeof(ip6));
Ed Warnickecb9cada2015-12-08 15:45:58 -07001482 vat_json_object_add_ip6(node, "ip", ip6);
1483 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01001484 clib_memcpy(&ip4, mp->ip, sizeof(ip4));
Ed Warnickecb9cada2015-12-08 15:45:58 -07001485 vat_json_object_add_ip4(node, "ip", ip4);
1486 }
1487 vat_json_object_add_uint(node, "prefix_length", mp->prefix_length);
1488}
1489
1490static void vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1491{
1492 vat_main_t * vam = &vat_main;
1493 static ip_details_t empty_ip_details = {0};
1494 ip_details_t * ip = NULL;
1495 u32 sw_if_index = ~0;
1496
1497 sw_if_index = ntohl(mp->sw_if_index);
1498
1499 vec_validate_init_empty(vam->ip_details_by_sw_if_index[vam->is_ipv6],
1500 sw_if_index, empty_ip_details);
1501
1502 ip = vec_elt_at_index(vam->ip_details_by_sw_if_index[vam->is_ipv6],
1503 sw_if_index);
1504
1505 ip->present = 1;
1506}
1507
1508static void vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1509{
1510 vat_main_t * vam = &vat_main;
1511
1512 if (VAT_JSON_ARRAY != vam->json_tree.type) {
1513 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
1514 vat_json_init_array(&vam->json_tree);
1515 }
1516 vat_json_array_add_uint(&vam->json_tree, clib_net_to_host_u32(mp->sw_if_index));
1517}
1518
1519static void vl_api_map_domain_details_t_handler_json
1520(vl_api_map_domain_details_t * mp)
1521{
1522 vat_json_node_t * node = NULL;
1523 vat_main_t * vam = &vat_main;
1524 struct in6_addr ip6;
1525 struct in_addr ip4;
1526
1527 if (VAT_JSON_ARRAY != vam->json_tree.type) {
1528 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
1529 vat_json_init_array(&vam->json_tree);
1530 }
1531
1532 node = vat_json_array_add(&vam->json_tree);
1533 vat_json_init_object(node);
1534
1535 vat_json_object_add_uint(node, "domain_index", clib_net_to_host_u32(mp->domain_index));
Damjan Marionf1213b82016-03-13 02:22:06 +01001536 clib_memcpy(&ip6, mp->ip6_prefix, sizeof(ip6));
Ed Warnickecb9cada2015-12-08 15:45:58 -07001537 vat_json_object_add_ip6(node, "ip6_prefix", ip6);
Damjan Marionf1213b82016-03-13 02:22:06 +01001538 clib_memcpy(&ip4, mp->ip4_prefix, sizeof(ip4));
Ed Warnickecb9cada2015-12-08 15:45:58 -07001539 vat_json_object_add_ip4(node, "ip4_prefix", ip4);
Damjan Marionf1213b82016-03-13 02:22:06 +01001540 clib_memcpy(&ip6, mp->ip6_src, sizeof(ip6));
Ed Warnickecb9cada2015-12-08 15:45:58 -07001541 vat_json_object_add_ip6(node, "ip6_src", ip6);
1542 vat_json_object_add_int(node, "ip6_prefix_len", mp->ip6_prefix_len);
1543 vat_json_object_add_int(node, "ip4_prefix_len", mp->ip4_prefix_len);
1544 vat_json_object_add_int(node, "ip6_src_len", mp->ip6_src_len);
1545 vat_json_object_add_int(node, "ea_bits_len", mp->ea_bits_len);
1546 vat_json_object_add_int(node, "psid_offset", mp->psid_offset);
1547 vat_json_object_add_int(node, "psid_length", mp->psid_length);
1548 vat_json_object_add_uint(node, "flags", mp->flags);
1549 vat_json_object_add_uint(node, "mtu", clib_net_to_host_u16(mp->mtu));
1550 vat_json_object_add_int(node, "is_translation", mp->is_translation);
1551}
1552
1553static void vl_api_map_domain_details_t_handler
1554(vl_api_map_domain_details_t * mp)
1555{
1556 vat_main_t * vam = &vat_main;
1557
1558 if (mp->is_translation) {
1559 fformat(vam->ofp, "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u\n",
1560 format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1561 format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1562 format_ip6_address, mp->ip6_src, mp->ip6_src_len, clib_net_to_host_u32(mp->domain_index));
1563 } else {
1564 fformat(vam->ofp, "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u\n",
1565 format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1566 format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1567 format_ip6_address, mp->ip6_src, clib_net_to_host_u32(mp->domain_index));
1568 }
1569 fformat(vam->ofp, " ea-len %d psid-offset %d psid-len %d mtu %d %s\n",
1570 mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu, mp->is_translation? "map-t":"");
1571}
1572
1573static void vl_api_map_rule_details_t_handler_json
1574(vl_api_map_rule_details_t * mp)
1575{
1576 struct in6_addr ip6;
1577 vat_json_node_t * node = NULL;
1578 vat_main_t * vam = &vat_main;
1579
1580 if (VAT_JSON_ARRAY != vam->json_tree.type) {
1581 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
1582 vat_json_init_array(&vam->json_tree);
1583 }
1584
1585 node = vat_json_array_add(&vam->json_tree);
1586 vat_json_init_object(node);
1587
1588 vat_json_object_add_uint(node, "psid", clib_net_to_host_u16(mp->psid));
Damjan Marionf1213b82016-03-13 02:22:06 +01001589 clib_memcpy(&ip6, mp->ip6_dst, sizeof(ip6));
Ed Warnickecb9cada2015-12-08 15:45:58 -07001590 vat_json_object_add_ip6(node, "ip6_dst", ip6);
1591}
1592
1593static void vl_api_map_rule_details_t_handler
1594(vl_api_map_rule_details_t * mp)
1595{
1596 vat_main_t * vam = &vat_main;
1597 fformat(vam->ofp, " %d (psid) %U (ip6-dst)\n", clib_net_to_host_u16(mp->psid),
1598 format_ip6_address, mp->ip6_dst);
1599}
1600
1601static void vl_api_dhcp_compl_event_t_handler
1602(vl_api_dhcp_compl_event_t * mp)
1603{
1604 vat_main_t * vam = &vat_main;
1605 errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1606 "router_addr %U host_mac %U\n",
1607 mp->pid, mp->is_ipv6 ? "ipv6":"ipv4", mp->hostname,
1608 format_ip4_address, &mp->host_address,
1609 format_ip4_address, &mp->router_address,
1610 format_ethernet_address, mp->host_mac);
1611}
1612
1613static void vl_api_dhcp_compl_event_t_handler_json
1614(vl_api_dhcp_compl_event_t * mp)
1615{
1616 /* JSON output not supported */
1617}
1618
1619static void set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1620 u32 counter)
1621{
1622 vat_main_t * vam = &vat_main;
1623 static u64 default_counter = 0;
1624
1625 vec_validate_init_empty(vam->simple_interface_counters, vnet_counter_type, NULL);
1626 vec_validate_init_empty(vam->simple_interface_counters[vnet_counter_type],
1627 sw_if_index, default_counter);
1628 vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1629}
1630
1631static void set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1632 interface_counter_t counter)
1633{
1634 vat_main_t * vam = &vat_main;
1635 static interface_counter_t default_counter = {0, };
1636
1637 vec_validate_init_empty(vam->combined_interface_counters, vnet_counter_type, NULL);
1638 vec_validate_init_empty(vam->combined_interface_counters[vnet_counter_type],
1639 sw_if_index, default_counter);
1640 vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1641}
1642
1643static void vl_api_vnet_interface_counters_t_handler
1644(vl_api_vnet_interface_counters_t *mp)
1645{
1646 /* not supported */
1647}
1648
1649static void vl_api_vnet_interface_counters_t_handler_json
1650(vl_api_vnet_interface_counters_t *mp)
1651{
1652 interface_counter_t counter;
1653 vlib_counter_t *v;
1654 u64 *v_packets;
1655 u64 packets;
1656 u32 count;
1657 u32 first_sw_if_index;
1658 int i;
1659
1660 count = ntohl(mp->count);
1661 first_sw_if_index = ntohl(mp->first_sw_if_index);
1662
1663 if (!mp->is_combined) {
1664 v_packets = (u64*)&mp->data;
1665 for (i = 0; i < count; i++) {
1666 packets = clib_net_to_host_u64(clib_mem_unaligned(v_packets, u64));
1667 set_simple_interface_counter(mp->vnet_counter_type,
1668 first_sw_if_index + i, packets);
1669 v_packets++;
1670 }
1671 } else {
1672 v = (vlib_counter_t*)&mp->data;
1673 for (i = 0; i < count; i++) {
1674 counter.packets = clib_net_to_host_u64(
1675 clib_mem_unaligned(&v->packets, u64));
1676 counter.bytes = clib_net_to_host_u64(
1677 clib_mem_unaligned(&v->bytes, u64));
1678 set_combined_interface_counter(mp->vnet_counter_type,
1679 first_sw_if_index + i, counter);
1680 v++;
1681 }
1682 }
1683}
1684
1685static u32 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1686{
1687 vat_main_t * vam = &vat_main;
1688 u32 i;
1689
1690 for (i = 0; i < vec_len(vam->ip4_fib_counters_vrf_id_by_index); i++) {
1691 if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id) {
1692 return i;
1693 }
1694 }
1695 return ~0;
1696}
1697
1698static u32 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1699{
1700 vat_main_t * vam = &vat_main;
1701 u32 i;
1702
1703 for (i = 0; i < vec_len(vam->ip6_fib_counters_vrf_id_by_index); i++) {
1704 if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id) {
1705 return i;
1706 }
1707 }
1708 return ~0;
1709}
1710
1711static void vl_api_vnet_ip4_fib_counters_t_handler
1712(vl_api_vnet_ip4_fib_counters_t *mp)
1713{
1714 /* not supported */
1715}
1716
1717static void vl_api_vnet_ip4_fib_counters_t_handler_json
1718(vl_api_vnet_ip4_fib_counters_t *mp)
1719{
1720 vat_main_t * vam = &vat_main;
1721 vl_api_ip4_fib_counter_t *v;
1722 ip4_fib_counter_t *counter;
1723 struct in_addr ip4;
1724 u32 vrf_id;
1725 u32 vrf_index;
1726 u32 count;
1727 int i;
1728
1729 vrf_id = ntohl(mp->vrf_id);
1730 vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id(vrf_id);
1731 if (~0 == vrf_index) {
1732 vrf_index = vec_len(vam->ip4_fib_counters_vrf_id_by_index);
1733 vec_validate(vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
1734 vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
1735 vec_validate(vam->ip4_fib_counters, vrf_index);
1736 vam->ip4_fib_counters[vrf_index] = NULL;
1737 }
1738
1739 vec_free(vam->ip4_fib_counters[vrf_index]);
1740 v = (vl_api_ip4_fib_counter_t*)&mp->c;
1741 count = ntohl(mp->count);
1742 for (i = 0; i < count; i++) {
1743 vec_validate(vam->ip4_fib_counters[vrf_index], i);
1744 counter = &vam->ip4_fib_counters[vrf_index][i];
Damjan Marionf1213b82016-03-13 02:22:06 +01001745 clib_memcpy(&ip4, &v->address, sizeof(ip4));
Ed Warnickecb9cada2015-12-08 15:45:58 -07001746 counter->address = ip4;
1747 counter->address_length = v->address_length;
1748 counter->packets = clib_net_to_host_u64(v->packets);
1749 counter->bytes = clib_net_to_host_u64(v->bytes);
1750 v++;
1751 }
1752}
1753
1754static void vl_api_vnet_ip6_fib_counters_t_handler
1755(vl_api_vnet_ip6_fib_counters_t *mp)
1756{
1757 /* not supported */
1758}
1759
1760static void vl_api_vnet_ip6_fib_counters_t_handler_json
1761(vl_api_vnet_ip6_fib_counters_t *mp)
1762{
1763 vat_main_t * vam = &vat_main;
1764 vl_api_ip6_fib_counter_t *v;
1765 ip6_fib_counter_t *counter;
1766 struct in6_addr ip6;
1767 u32 vrf_id;
1768 u32 vrf_index;
1769 u32 count;
1770 int i;
1771
1772 vrf_id = ntohl(mp->vrf_id);
1773 vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id(vrf_id);
1774 if (~0 == vrf_index) {
1775 vrf_index = vec_len(vam->ip6_fib_counters_vrf_id_by_index);
1776 vec_validate(vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
1777 vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
1778 vec_validate(vam->ip6_fib_counters, vrf_index);
1779 vam->ip6_fib_counters[vrf_index] = NULL;
1780 }
1781
1782 vec_free(vam->ip6_fib_counters[vrf_index]);
1783 v = (vl_api_ip6_fib_counter_t*)&mp->c;
1784 count = ntohl(mp->count);
1785 for (i = 0; i < count; i++) {
1786 vec_validate(vam->ip6_fib_counters[vrf_index], i);
1787 counter = &vam->ip6_fib_counters[vrf_index][i];
Damjan Marionf1213b82016-03-13 02:22:06 +01001788 clib_memcpy(&ip6, &v->address, sizeof(ip6));
Ed Warnickecb9cada2015-12-08 15:45:58 -07001789 counter->address = ip6;
1790 counter->address_length = v->address_length;
1791 counter->packets = clib_net_to_host_u64(v->packets);
1792 counter->bytes = clib_net_to_host_u64(v->bytes);
1793 v++;
1794 }
1795}
1796
1797static void vl_api_get_first_msg_id_reply_t_handler
1798(vl_api_get_first_msg_id_reply_t * mp)
1799{
1800 vat_main_t * vam = &vat_main;
1801 i32 retval = ntohl(mp->retval);
1802
1803 if (vam->async_mode) {
1804 vam->async_errors += (retval < 0);
1805 } else {
1806 vam->retval = retval;
1807 vam->result_ready = 1;
1808 }
1809 if (retval >= 0) {
1810 errmsg ("first message id %d\n", ntohs(mp->first_msg_id));
1811 }
1812}
1813
1814static void vl_api_get_first_msg_id_reply_t_handler_json
1815(vl_api_get_first_msg_id_reply_t * mp)
1816{
1817 vat_main_t * vam = &vat_main;
1818 vat_json_node_t node;
1819
1820 vat_json_init_object(&node);
1821 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1822 vat_json_object_add_uint(&node, "first_msg_id",
1823 (uint) ntohs(mp->first_msg_id));
1824
1825 vat_json_print(vam->ofp, &node);
1826 vat_json_free(&node);
1827
1828 vam->retval = ntohl(mp->retval);
1829 vam->result_ready = 1;
1830}
1831
Dave Barachb44e9bc2016-02-19 09:06:23 -05001832static void vl_api_get_node_graph_reply_t_handler
1833(vl_api_get_node_graph_reply_t * mp)
1834{
1835 vat_main_t * vam = &vat_main;
1836 api_main_t * am = &api_main;
1837 i32 retval = ntohl(mp->retval);
1838 u8 * pvt_copy, * reply;
1839 void * oldheap;
1840 vlib_node_t * node;
1841 int i;
1842
1843 if (vam->async_mode) {
1844 vam->async_errors += (retval < 0);
1845 } else {
1846 vam->retval = retval;
1847 vam->result_ready = 1;
1848 }
1849
1850 /* "Should never happen..." */
1851 if (retval != 0)
1852 return;
1853
1854 reply = (u8 *)(mp->reply_in_shmem);
1855 pvt_copy = vec_dup (reply);
1856
1857 /* Toss the shared-memory original... */
1858 pthread_mutex_lock (&am->vlib_rp->mutex);
1859 oldheap = svm_push_data_heap (am->vlib_rp);
1860
1861 vec_free (reply);
1862
1863 svm_pop_heap (oldheap);
1864 pthread_mutex_unlock (&am->vlib_rp->mutex);
1865
1866 if (vam->graph_nodes) {
1867 hash_free (vam->graph_node_index_by_name);
1868
1869 for (i = 0; i < vec_len (vam->graph_nodes); i++) {
1870 node = vam->graph_nodes[i];
1871 vec_free (node->name);
1872 vec_free (node->next_nodes);
1873 vec_free (node);
1874 }
1875 vec_free(vam->graph_nodes);
1876 }
1877
1878 vam->graph_node_index_by_name = hash_create_string (0, sizeof(uword));
1879 vam->graph_nodes = vlib_node_unserialize (pvt_copy);
1880 vec_free (pvt_copy);
1881
1882 for (i = 0; i < vec_len (vam->graph_nodes); i++) {
1883 node = vam->graph_nodes[i];
1884 hash_set_mem (vam->graph_node_index_by_name, node->name, i);
1885 }
1886}
1887
1888static void vl_api_get_node_graph_reply_t_handler_json
1889(vl_api_get_node_graph_reply_t * mp)
1890{
1891 vat_main_t * vam = &vat_main;
1892 api_main_t * am = &api_main;
1893 void * oldheap;
1894 vat_json_node_t node;
1895 u8 * reply;
1896
1897 /* $$$$ make this real? */
1898 vat_json_init_object(&node);
1899 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1900 vat_json_object_add_uint(&node, "reply_in_shmem", mp->reply_in_shmem);
1901
1902 reply = (u8 *)(mp->reply_in_shmem);
1903
1904 /* Toss the shared-memory original... */
1905 pthread_mutex_lock (&am->vlib_rp->mutex);
1906 oldheap = svm_push_data_heap (am->vlib_rp);
1907
1908 vec_free (reply);
1909
1910 svm_pop_heap (oldheap);
1911 pthread_mutex_unlock (&am->vlib_rp->mutex);
1912
1913 vat_json_print(vam->ofp, &node);
1914 vat_json_free(&node);
1915
1916 vam->retval = ntohl(mp->retval);
1917 vam->result_ready = 1;
1918}
1919
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02001920static void
1921vl_api_lisp_locator_set_details_t_handler (
1922 vl_api_lisp_locator_set_details_t *mp)
1923{
1924 vat_main_t *vam = &vat_main;
Andrej Kozemcak3e53fc52016-05-09 10:52:16 +02001925 u8 * tmp_str = NULL;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02001926
Andrej Kozemcak3e53fc52016-05-09 10:52:16 +02001927 if (mp->local) {
1928 fformat(vam->ofp, "%=20s%=16d%=16d%=16d\n",
1929 mp->locator_set_name,
1930 ntohl(mp->sw_if_index),
1931 mp->priority,
1932 mp->weight);
1933 } else {
1934 tmp_str = format(0,"%U/%d",
1935 mp->is_ipv6 ? format_ip6_address : format_ip4_address,
1936 mp->ip_address,
1937 mp->prefix_len);
1938
1939 fformat(vam->ofp, "%=20s%=16s%=16d%=16d\n",
1940 mp->locator_set_name,
1941 tmp_str,
1942 mp->priority,
1943 mp->weight);
1944 vec_free(tmp_str);
1945 }
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02001946}
1947
1948static void
1949vl_api_lisp_locator_set_details_t_handler_json (
1950 vl_api_lisp_locator_set_details_t *mp)
1951{
1952 vat_main_t *vam = &vat_main;
1953 vat_json_node_t *node = NULL;
Andrej Kozemcak3e53fc52016-05-09 10:52:16 +02001954 struct in6_addr ip6;
1955 struct in_addr ip4;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02001956
1957 if (VAT_JSON_ARRAY != vam->json_tree.type) {
1958 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
1959 vat_json_init_array(&vam->json_tree);
1960 }
1961 node = vat_json_array_add(&vam->json_tree);
1962
1963 vat_json_init_object(node);
1964 vat_json_object_add_string_copy(node, "locator-set", mp->locator_set_name);
Andrej Kozemcak3e53fc52016-05-09 10:52:16 +02001965 if (mp->local) {
1966 vat_json_object_add_uint(node, "locator", ntohl(mp->sw_if_index));
1967 } else {
1968 if (mp->is_ipv6) {
1969 clib_memcpy(&ip6, mp->ip_address, sizeof(ip6));
1970 vat_json_object_add_ip6(node, "locator", ip6);
1971 } else {
1972 clib_memcpy(&ip4, mp->ip_address, sizeof(ip4));
1973 vat_json_object_add_ip4(node, "locator", ip4);
1974 }
1975 vat_json_object_add_uint(node, "prefix-length", mp->prefix_len);
1976 }
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02001977 vat_json_object_add_uint(node, "priority", mp->priority);
1978 vat_json_object_add_uint(node, "weight", mp->weight);
1979}
1980
1981static void
1982vl_api_lisp_local_eid_table_details_t_handler (
1983 vl_api_lisp_local_eid_table_details_t *mp)
1984{
1985 vat_main_t *vam = &vat_main;
1986 u8 *prefix;
Filip Tehlar006eb262016-06-27 13:09:20 +02001987 u8 * (*format_eid)(u8 *, va_list *) = 0;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02001988
Filip Tehlar006eb262016-06-27 13:09:20 +02001989 switch (mp->eid_type)
1990 {
1991 case 0: format_eid = format_ip4_address; break;
1992 case 1: format_eid = format_ip6_address; break;
1993 case 2: format_eid = format_ethernet_address; break;
1994 default:
1995 errmsg ("unknown EID type %d!", mp->eid_type);
1996 return;
1997 }
1998
1999 prefix = format(0, "[%d] %U/%d",
Filip Tehlar324112f2016-06-02 16:07:38 +02002000 clib_net_to_host_u32 (mp->vni),
Filip Tehlar006eb262016-06-27 13:09:20 +02002001 format_eid, mp->eid, mp->eid_prefix_len);
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002002
2003 fformat(vam->ofp, "%=20s%=30s\n",
2004 mp->locator_set_name, prefix);
2005
2006 vec_free(prefix);
2007}
2008
2009static void
2010vl_api_lisp_local_eid_table_details_t_handler_json (
2011 vl_api_lisp_local_eid_table_details_t *mp)
2012{
2013 vat_main_t *vam = &vat_main;
2014 vat_json_node_t *node = NULL;
2015 struct in6_addr ip6;
2016 struct in_addr ip4;
Filip Tehlar006eb262016-06-27 13:09:20 +02002017 u8 * s = 0;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002018
2019 if (VAT_JSON_ARRAY != vam->json_tree.type) {
2020 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
2021 vat_json_init_array(&vam->json_tree);
2022 }
2023 node = vat_json_array_add(&vam->json_tree);
2024
2025 vat_json_init_object(node);
2026 vat_json_object_add_string_copy(node, "locator-set", mp->locator_set_name);
Filip Tehlar006eb262016-06-27 13:09:20 +02002027 switch (mp->eid_type)
2028 {
2029 case 0:
2030 clib_memcpy(&ip4, mp->eid, sizeof(ip4));
2031 vat_json_object_add_ip4(node, "eid-address", ip4);
Florin Corasf727db92016-06-23 15:01:58 +02002032 break;
Filip Tehlar006eb262016-06-27 13:09:20 +02002033 case 1:
2034 clib_memcpy(&ip6, mp->eid, sizeof(ip6));
2035 vat_json_object_add_ip6(node, "eid-address", ip6);
2036 break;
2037 case 2:
2038 s = format (0, "%U", format_ethernet_address, mp->eid);
2039 vec_add1(s, 0);
2040 vat_json_object_add_string_copy(node, "eid-address", s);
2041 vec_free(s);
2042 break;
2043 default:
2044 errmsg ("unknown EID type %d!", mp->eid_type);
2045 return;
2046 }
Filip Tehlar324112f2016-06-02 16:07:38 +02002047 vat_json_object_add_uint(node, "vni", clib_net_to_host_u32 (mp->vni));
Filip Tehlar006eb262016-06-27 13:09:20 +02002048 vat_json_object_add_uint(node, "eid-prefix-len", mp->eid_prefix_len);
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002049}
2050
2051static u8 *
2052format_decap_next (u8 * s, va_list * args)
2053{
2054 u32 next_index = va_arg (*args, u32);
2055
2056 switch (next_index)
2057 {
2058 case LISP_GPE_INPUT_NEXT_DROP:
2059 return format (s, "drop");
2060 case LISP_GPE_INPUT_NEXT_IP4_INPUT:
2061 return format (s, "ip4");
2062 case LISP_GPE_INPUT_NEXT_IP6_INPUT:
2063 return format (s, "ip6");
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002064 default:
2065 return format (s, "unknown %d", next_index);
2066 }
2067 return s;
2068}
2069
2070static void
2071vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *mp)
2072{
2073 vat_main_t *vam = &vat_main;
2074 u8 *iid_str;
2075 u8 *flag_str = NULL;
2076
2077 iid_str = format(0, "%d (0x%x)", ntohl(mp->iid), ntohl(mp->iid));
2078
2079#define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n);
2080 foreach_lisp_gpe_flag_bit;
2081#undef _
2082
2083 fformat(vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U"
2084 "%=16d%=16d%=16sd=16d%=16s%=16s\n",
2085 mp->tunnels,
2086 mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2087 mp->source_ip,
2088 mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2089 mp->destination_ip,
2090 ntohl(mp->encap_fib_id),
2091 ntohl(mp->decap_fib_id),
2092 format_decap_next, ntohl(mp->dcap_next),
2093 mp->ver_res >> 6,
2094 flag_str,
2095 mp->next_protocol,
2096 mp->ver_res,
2097 mp->res,
2098 iid_str);
2099
2100 vec_free(iid_str);
2101}
2102
2103static void
2104vl_api_lisp_gpe_tunnel_details_t_handler_json (
2105 vl_api_lisp_gpe_tunnel_details_t *mp)
2106{
2107 vat_main_t *vam = &vat_main;
2108 vat_json_node_t *node = NULL;
2109 struct in6_addr ip6;
2110 struct in_addr ip4;
2111 u8 *next_decap_str;
2112
2113 next_decap_str = format(0, "%U", format_decap_next, htonl(mp->dcap_next));
2114
2115 if (VAT_JSON_ARRAY != vam->json_tree.type) {
2116 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
2117 vat_json_init_array(&vam->json_tree);
2118 }
2119 node = vat_json_array_add(&vam->json_tree);
2120
2121 vat_json_init_object(node);
2122 vat_json_object_add_uint(node, "tunel", mp->tunnels);
2123 if (mp->is_ipv6) {
Damjan Marionf1213b82016-03-13 02:22:06 +01002124 clib_memcpy(&ip6, mp->source_ip, sizeof(ip6));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002125 vat_json_object_add_ip6(node, "source address", ip6);
Damjan Marionf1213b82016-03-13 02:22:06 +01002126 clib_memcpy(&ip6, mp->destination_ip, sizeof(ip6));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002127 vat_json_object_add_ip6(node, "destination address", ip6);
2128 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01002129 clib_memcpy(&ip4, mp->source_ip, sizeof(ip4));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002130 vat_json_object_add_ip4(node, "source address", ip4);
Damjan Marionf1213b82016-03-13 02:22:06 +01002131 clib_memcpy(&ip4, mp->destination_ip, sizeof(ip4));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002132 vat_json_object_add_ip4(node, "destination address", ip4);
2133 }
2134 vat_json_object_add_uint(node, "fib encap", ntohl(mp->encap_fib_id));
2135 vat_json_object_add_uint(node, "fib decap", ntohl(mp->decap_fib_id));
2136 vat_json_object_add_string_copy(node, "decap next", next_decap_str);
2137 vat_json_object_add_uint(node, "lisp version", mp->ver_res >> 6);
2138 vat_json_object_add_uint(node, "flags", mp->flags);
2139 vat_json_object_add_uint(node, "next protocol", mp->next_protocol);
2140 vat_json_object_add_uint(node, "ver_res", mp->ver_res);
2141 vat_json_object_add_uint(node, "res", mp->res);
2142 vat_json_object_add_uint(node, "iid", ntohl(mp->iid));
2143
2144 vec_free(next_decap_str);
2145}
2146
2147static void
2148vl_api_lisp_map_resolver_details_t_handler (
2149 vl_api_lisp_map_resolver_details_t *mp)
2150{
2151 vat_main_t *vam = &vat_main;
2152
2153 fformat(vam->ofp, "%=20U\n",
2154 mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2155 mp->ip_address);
2156}
2157
2158static void
2159vl_api_lisp_map_resolver_details_t_handler_json (
2160 vl_api_lisp_map_resolver_details_t *mp)
2161{
2162 vat_main_t *vam = &vat_main;
2163 vat_json_node_t *node = NULL;
2164 struct in6_addr ip6;
2165 struct in_addr ip4;
2166
2167 if (VAT_JSON_ARRAY != vam->json_tree.type) {
2168 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
2169 vat_json_init_array(&vam->json_tree);
2170 }
2171 node = vat_json_array_add(&vam->json_tree);
2172
2173 vat_json_init_object(node);
2174 if (mp->is_ipv6) {
Damjan Marionf1213b82016-03-13 02:22:06 +01002175 clib_memcpy(&ip6, mp->ip_address, sizeof(ip6));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002176 vat_json_object_add_ip6(node, "map resolver", ip6);
2177 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01002178 clib_memcpy(&ip4, mp->ip_address, sizeof(ip4));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002179 vat_json_object_add_ip4(node, "map resolver", ip4);
2180 }
2181}
2182
Andrej Kozemcaka9edd852016-05-02 12:14:33 +02002183static void
Filip Tehlar46d4e362016-05-09 09:39:26 +02002184vl_api_lisp_enable_disable_status_details_t_handler
2185(vl_api_lisp_enable_disable_status_details_t *mp)
Andrej Kozemcaka9edd852016-05-02 12:14:33 +02002186{
2187 vat_main_t *vam = &vat_main;
2188
Filip Tehlar46d4e362016-05-09 09:39:26 +02002189 fformat(vam->ofp, "feature: %s\ngpe: %s\n",
2190 mp->feature_status ? "enabled" : "disabled",
2191 mp->gpe_status ? "enabled" : "disabled");
Andrej Kozemcaka9edd852016-05-02 12:14:33 +02002192}
2193
2194static void
Filip Tehlar46d4e362016-05-09 09:39:26 +02002195vl_api_lisp_enable_disable_status_details_t_handler_json
2196(vl_api_lisp_enable_disable_status_details_t *mp)
Andrej Kozemcaka9edd852016-05-02 12:14:33 +02002197{
2198 vat_main_t *vam = &vat_main;
2199 vat_json_node_t *node = NULL;
Filip Tehlar46d4e362016-05-09 09:39:26 +02002200 u8 * gpe_status = NULL;
2201 u8 * feature_status = NULL;
Andrej Kozemcaka9edd852016-05-02 12:14:33 +02002202
Filip Tehlar46d4e362016-05-09 09:39:26 +02002203 gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2204 feature_status = format (0, "%s",
2205 mp->feature_status ? "enabled" : "disabled");
Filip Tehlar6f91cfe2016-06-06 13:13:16 +02002206 vec_add1 (gpe_status, 0);
2207 vec_add1 (feature_status, 0);
Andrej Kozemcaka9edd852016-05-02 12:14:33 +02002208
2209 if (VAT_JSON_ARRAY != vam->json_tree.type) {
2210 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
2211 vat_json_init_array(&vam->json_tree);
2212 }
2213 node = vat_json_array_add(&vam->json_tree);
2214
2215 vat_json_init_object(node);
Filip Tehlar46d4e362016-05-09 09:39:26 +02002216 vat_json_object_add_string_copy(node, "gpe_status", gpe_status);
2217 vat_json_object_add_string_copy(node, "feature_status", feature_status);
2218
2219 vec_free (gpe_status);
2220 vec_free (feature_status);
Andrej Kozemcaka9edd852016-05-02 12:14:33 +02002221}
2222
Andrej Kozemcakb6e4d392016-06-14 13:55:57 +02002223static void
2224vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler (
2225 vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2226{
2227 vat_main_t * vam = &vat_main;
2228 i32 retval = ntohl(mp->retval);
2229
2230 if (retval >= 0) {
2231 fformat(vam->ofp, "%=20s\n",
2232 mp->locator_set_name);
2233 }
2234
2235 vam->retval = retval;
2236 vam->result_ready = 1;
2237}
2238
2239static void
2240vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json (
2241 vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2242{
2243 vat_main_t * vam = &vat_main;
2244 vat_json_node_t * node = NULL;
2245
2246 if (VAT_JSON_ARRAY != vam->json_tree.type) {
2247 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
2248 vat_json_init_array(&vam->json_tree);
2249 }
2250 node = vat_json_array_add(&vam->json_tree);
2251
2252 vat_json_init_object(node);
2253 vat_json_object_add_string_copy(node, "itr-rlocs", mp->locator_set_name);
2254
2255 vat_json_print(vam->ofp, node);
2256 vat_json_free(node);
2257
2258 vam->retval = ntohl(mp->retval);
2259 vam->result_ready = 1;
2260}
2261
Matus Fabiane8554802016-05-18 23:40:37 -07002262static u8 * format_policer_type (u8 * s, va_list * va)
2263{
2264 u32 i = va_arg (*va, u32);
2265
2266 if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2267 s = format (s, "1r2c");
2268 else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2269 s = format (s, "1r3c");
2270 else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2271 s = format (s, "2r3c-2698");
2272 else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2273 s = format (s, "2r3c-4115");
2274 else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2275 s = format (s, "2r3c-mef5cf1");
2276 else
2277 s = format (s, "ILLEGAL");
2278 return s;
2279}
2280
2281static u8 * format_policer_rate_type (u8 * s, va_list * va)
2282{
2283 u32 i = va_arg (*va, u32);
2284
2285 if (i == SSE2_QOS_RATE_KBPS)
2286 s = format (s, "kbps");
2287 else if (i == SSE2_QOS_RATE_PPS)
2288 s = format(s, "pps");
2289 else
2290 s = format (s, "ILLEGAL");
2291 return s;
2292}
2293
2294static u8 * format_policer_round_type (u8 * s, va_list * va)
2295{
2296 u32 i = va_arg (*va, u32);
2297
2298 if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2299 s = format(s, "closest");
2300 else if (i == SSE2_QOS_ROUND_TO_UP)
2301 s = format (s, "up");
2302 else if (i == SSE2_QOS_ROUND_TO_DOWN)
2303 s = format (s, "down");
2304 else
2305 s = format (s, "ILLEGAL");
2306 return s;
2307}
2308
2309static void vl_api_policer_details_t_handler
2310(vl_api_policer_details_t * mp)
2311{
2312 vat_main_t * vam = &vat_main;
2313
2314 fformat (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2315 "rate type %U, round type %U, %s rate, %s color-aware, "
2316 "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2317 "cur bkt %u, ext lim %u, ext bkt %u, last update %llu\n",
2318 mp->name,
2319 format_policer_type, mp->type,
2320 ntohl(mp->cir),
2321 ntohl(mp->eir),
2322 ntohl(mp->cb),
2323 ntohl(mp->eb),
2324 format_policer_rate_type, mp->rate_type,
2325 format_policer_round_type, mp->round_type,
2326 mp->single_rate ? "single" : "dual",
2327 mp->color_aware ? "is" : "not",
2328 ntohl(mp->cir_tokens_per_period),
2329 ntohl(mp->pir_tokens_per_period),
2330 ntohl(mp->scale),
2331 ntohl(mp->current_limit),
2332 ntohl(mp->current_bucket),
2333 ntohl(mp->extended_limit),
2334 ntohl(mp->extended_bucket),
2335 clib_net_to_host_u64(mp->last_update_time));
2336}
2337
2338static void vl_api_policer_details_t_handler_json
2339(vl_api_policer_details_t * mp)
2340{
2341 vat_main_t * vam = &vat_main;
2342 vat_json_node_t *node;
2343 u8 *rate_type_str, *round_type_str, *type_str;
2344
2345 rate_type_str = format(0, "%U", format_policer_rate_type, mp->rate_type);
2346 round_type_str = format(0, "%U", format_policer_round_type, mp->round_type);
2347 type_str = format(0, "%U", format_policer_type, mp->type);
2348
2349 if (VAT_JSON_ARRAY != vam->json_tree.type) {
2350 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
2351 vat_json_init_array(&vam->json_tree);
2352 }
2353 node = vat_json_array_add(&vam->json_tree);
2354
2355 vat_json_init_object(node);
2356 vat_json_object_add_string_copy(node, "name", mp->name);
2357 vat_json_object_add_uint(node, "cir", ntohl(mp->cir));
2358 vat_json_object_add_uint(node, "eir", ntohl(mp->eir));
2359 vat_json_object_add_uint(node, "cb", ntohl(mp->cb));
2360 vat_json_object_add_uint(node, "eb", ntohl(mp->eb));
2361 vat_json_object_add_string_copy(node, "rate_type", rate_type_str);
2362 vat_json_object_add_string_copy(node, "round_type", round_type_str);
2363 vat_json_object_add_string_copy(node, "type", type_str);
2364 vat_json_object_add_uint(node, "single_rate", mp->single_rate);
2365 vat_json_object_add_uint(node, "color_aware", mp->color_aware);
2366 vat_json_object_add_uint(node, "scale", ntohl(mp->scale));
2367 vat_json_object_add_uint(node, "cir_tokens_per_period",
2368 ntohl(mp->cir_tokens_per_period));
2369 vat_json_object_add_uint(node, "eir_tokens_per_period",
2370 ntohl(mp->pir_tokens_per_period));
2371 vat_json_object_add_uint(node, "current_limit", ntohl(mp->current_limit));
2372 vat_json_object_add_uint(node, "current_bucket", ntohl(mp->current_bucket));
2373 vat_json_object_add_uint(node, "extended_limit", ntohl(mp->extended_limit));
2374 vat_json_object_add_uint(node, "extended_bucket",
2375 ntohl(mp->extended_bucket));
2376 vat_json_object_add_uint(node, "last_update_time",
2377 ntohl(mp->last_update_time));
2378
2379 vec_free(rate_type_str);
2380 vec_free(round_type_str);
2381 vec_free(type_str);
2382}
2383
Pavel Kotucek20c90f72016-06-07 14:44:26 +02002384static void vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t * mp)
2385{
2386 vat_main_t * vam = &vat_main;
2387 int i, count = ntohl(mp->count);
2388
2389 if (count>0)
2390 fformat (vam->ofp, "classify table ids (%d) : ", count);
2391 for (i = 0; i < count; i++)
2392 {
2393 fformat (vam->ofp, "%d", ntohl(mp->ids[i]));
2394 fformat (vam->ofp, (i<count-1)?",":"\n");
2395 }
2396 vam->retval = ntohl(mp->retval);
2397 vam->result_ready = 1;
2398}
2399
2400static void vl_api_classify_table_ids_reply_t_handler_json (vl_api_classify_table_ids_reply_t * mp)
2401{
2402 vat_main_t * vam = &vat_main;
2403 int i, count = ntohl(mp->count);
2404
2405 if (count>0) {
2406 vat_json_node_t node;
2407
2408 vat_json_init_object(&node);
2409 for (i = 0; i < count; i++)
2410 {
2411 vat_json_object_add_uint(&node, "table_id", ntohl(mp->ids[i]));
2412 }
2413 vat_json_print(vam->ofp, &node);
2414 vat_json_free(&node);
2415 }
2416 vam->retval = ntohl(mp->retval);
2417 vam->result_ready = 1;
2418}
2419
2420static void vl_api_classify_table_by_interface_reply_t_handler (vl_api_classify_table_by_interface_reply_t * mp)
2421{
2422 vat_main_t * vam = &vat_main;
2423 u32 table_id;
2424
2425 table_id = ntohl(mp->l2_table_id);
2426 if (table_id != ~0)
2427 fformat (vam->ofp, "l2 table id : %d\n", table_id);
2428 else
2429 fformat (vam->ofp, "l2 table id : No input ACL tables configured\n");
2430 table_id = ntohl(mp->ip4_table_id);
2431 if (table_id != ~0)
2432 fformat (vam->ofp, "ip4 table id : %d\n", table_id);
2433 else
2434 fformat (vam->ofp, "ip4 table id : No input ACL tables configured\n");
2435 table_id = ntohl(mp->ip6_table_id);
2436 if (table_id != ~0)
2437 fformat (vam->ofp, "ip6 table id : %d\n", table_id);
2438 else
2439 fformat (vam->ofp, "ip6 table id : No input ACL tables configured\n");
2440 vam->retval = ntohl(mp->retval);
2441 vam->result_ready = 1;
2442}
2443
2444static void vl_api_classify_table_by_interface_reply_t_handler_json (vl_api_classify_table_by_interface_reply_t * mp)
2445{
2446 vat_main_t * vam = &vat_main;
2447 vat_json_node_t node;
2448
2449 vat_json_init_object(&node);
2450
2451 vat_json_object_add_int(&node, "l2_table_id", ntohl(mp->l2_table_id));
2452 vat_json_object_add_int(&node, "ip4_table_id", ntohl(mp->ip4_table_id));
2453 vat_json_object_add_int(&node, "ip6_table_id", ntohl(mp->ip6_table_id));
2454
2455 vat_json_print(vam->ofp, &node);
2456 vat_json_free(&node);
2457
2458 vam->retval = ntohl(mp->retval);
2459 vam->result_ready = 1;
2460}
2461
2462/* Format hex dump. */
2463u8 * format_hex_bytes (u8 * s, va_list * va)
2464{
2465 u8 * bytes = va_arg (*va, u8 *);
2466 int n_bytes = va_arg (*va, int);
2467 uword i;
2468
2469 /* Print short or long form depending on byte count. */
2470 uword short_form = n_bytes <= 32;
2471 uword indent = format_get_indent (s);
2472
2473 if (n_bytes == 0)
2474 return s;
2475
2476 for (i = 0; i < n_bytes; i++)
2477 {
2478 if (! short_form && (i % 32) == 0)
2479 s = format (s, "%08x: ", i);
2480 s = format (s, "%02x", bytes[i]);
2481 if (! short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
2482 s = format (s, "\n%U", format_white_space, indent);
2483 }
2484
2485 return s;
2486}
2487
2488static void vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t * mp)
2489{
2490 vat_main_t * vam = &vat_main;
2491 i32 retval = ntohl(mp->retval);
2492 if (retval == 0) {
2493 fformat (vam->ofp, "classify table info :\n");
2494 fformat (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d\n", ntohl(mp->active_sessions), ntohl(mp->next_table_index), ntohl(mp->miss_next_index));
2495 fformat (vam->ofp, "nbuckets: %d skip: %d match: %d\n", ntohl(mp->nbuckets), ntohl(mp->skip_n_vectors), ntohl(mp->match_n_vectors));
2496 fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->mask, ntohl(mp->mask_length));
2497 }
2498 vam->retval = retval;
2499 vam->result_ready = 1;
2500}
2501
2502static void vl_api_classify_table_info_reply_t_handler_json (vl_api_classify_table_info_reply_t * mp)
2503{
2504 vat_main_t * vam = &vat_main;
2505 vat_json_node_t node;
2506
2507 i32 retval = ntohl(mp->retval);
2508 if (retval == 0) {
2509 vat_json_init_object(&node);
2510
2511 vat_json_object_add_int(&node, "sessions", ntohl(mp->active_sessions));
2512 vat_json_object_add_int(&node, "nexttbl", ntohl(mp->next_table_index));
2513 vat_json_object_add_int(&node, "nextnode", ntohl(mp->miss_next_index));
2514 vat_json_object_add_int(&node, "nbuckets", ntohl(mp->nbuckets));
2515 vat_json_object_add_int(&node, "skip", ntohl(mp->skip_n_vectors));
2516 vat_json_object_add_int(&node, "match", ntohl(mp->match_n_vectors));
2517 u8 * s = format (0, "%U%c",format_hex_bytes, mp->mask, ntohl(mp->mask_length), 0);
2518 vat_json_object_add_string_copy(&node, "mask", s);
2519
2520 vat_json_print(vam->ofp, &node);
2521 vat_json_free(&node);
2522 }
2523 vam->retval = ntohl(mp->retval);
2524 vam->result_ready = 1;
2525}
2526
2527static void vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t * mp)
2528{
2529 vat_main_t * vam = &vat_main;
2530
2531 fformat (vam->ofp, "next_index: %d advance: %d opaque: %d ", ntohl(mp->hit_next_index), ntohl(mp->advance), ntohl(mp->opaque_index));
2532 fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->match, ntohl(mp->match_length));
2533}
2534
2535static void vl_api_classify_session_details_t_handler_json (vl_api_classify_session_details_t * mp)
2536{
2537 vat_main_t * vam = &vat_main;
2538 vat_json_node_t *node = NULL;
2539
2540 if (VAT_JSON_ARRAY != vam->json_tree.type) {
2541 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
2542 vat_json_init_array(&vam->json_tree);
2543 }
2544 node = vat_json_array_add(&vam->json_tree);
2545
2546 vat_json_init_object(node);
2547 vat_json_object_add_int(node, "next_index", ntohl(mp->hit_next_index));
2548 vat_json_object_add_int(node, "advance", ntohl(mp->advance));
2549 vat_json_object_add_int(node, "opaque", ntohl(mp->opaque_index));
2550 u8 * s = format (0, "%U%c",format_hex_bytes, mp->match, ntohl(mp->match_length), 0);
2551 vat_json_object_add_string_copy(node, "match", s);
2552}
Matus Fabiane8554802016-05-18 23:40:37 -07002553
Ed Warnickecb9cada2015-12-08 15:45:58 -07002554#define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
2555#define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
2556#define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
2557#define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
2558
2559/*
2560 * Generate boilerplate reply handlers, which
2561 * dig the return value out of the xxx_reply_t API message,
2562 * stick it into vam->retval, and set vam->result_ready
2563 *
2564 * Could also do this by pointing N message decode slots at
2565 * a single function, but that could break in subtle ways.
2566 */
2567
2568#define foreach_standard_reply_retval_handler \
2569_(sw_interface_set_flags_reply) \
2570_(sw_interface_add_del_address_reply) \
2571_(sw_interface_set_table_reply) \
2572_(sw_interface_set_vpath_reply) \
2573_(sw_interface_set_l2_bridge_reply) \
2574_(bridge_domain_add_del_reply) \
2575_(sw_interface_set_l2_xconnect_reply) \
2576_(l2fib_add_del_reply) \
2577_(ip_add_del_route_reply) \
2578_(proxy_arp_add_del_reply) \
2579_(proxy_arp_intfc_enable_disable_reply) \
2580_(mpls_add_del_encap_reply) \
2581_(mpls_add_del_decap_reply) \
2582_(mpls_ethernet_add_del_tunnel_2_reply) \
2583_(sw_interface_set_unnumbered_reply) \
2584_(ip_neighbor_add_del_reply) \
2585_(reset_vrf_reply) \
2586_(oam_add_del_reply) \
2587_(reset_fib_reply) \
2588_(dhcp_proxy_config_reply) \
2589_(dhcp_proxy_config_2_reply) \
2590_(dhcp_proxy_set_vss_reply) \
2591_(dhcp_client_config_reply) \
2592_(set_ip_flow_hash_reply) \
2593_(sw_interface_ip6_enable_disable_reply) \
2594_(sw_interface_ip6_set_link_local_address_reply) \
2595_(sw_interface_ip6nd_ra_prefix_reply) \
2596_(sw_interface_ip6nd_ra_config_reply) \
2597_(set_arp_neighbor_limit_reply) \
2598_(l2_patch_add_del_reply) \
2599_(sr_tunnel_add_del_reply) \
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07002600_(sr_policy_add_del_reply) \
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07002601_(sr_multicast_map_add_del_reply) \
Ed Warnickecb9cada2015-12-08 15:45:58 -07002602_(classify_add_del_session_reply) \
2603_(classify_set_interface_ip_table_reply) \
2604_(classify_set_interface_l2_tables_reply) \
2605_(l2tpv3_set_tunnel_cookies_reply) \
2606_(l2tpv3_interface_enable_disable_reply) \
2607_(l2tpv3_set_lookup_key_reply) \
2608_(l2_fib_clear_table_reply) \
2609_(l2_interface_efp_filter_reply) \
2610_(l2_interface_vlan_tag_rewrite_reply) \
2611_(modify_vhost_user_if_reply) \
2612_(delete_vhost_user_if_reply) \
2613_(want_ip4_arp_events_reply) \
2614_(input_acl_set_interface_reply) \
2615_(ipsec_spd_add_del_reply) \
2616_(ipsec_interface_add_del_spd_reply) \
2617_(ipsec_spd_add_del_entry_reply) \
2618_(ipsec_sad_add_del_entry_reply) \
2619_(ipsec_sa_set_key_reply) \
Matus Fabiane5f42fe2016-04-08 11:18:08 +02002620_(ikev2_profile_add_del_reply) \
2621_(ikev2_profile_set_auth_reply) \
2622_(ikev2_profile_set_id_reply) \
2623_(ikev2_profile_set_ts_reply) \
2624_(ikev2_set_local_key_reply) \
Ed Warnickecb9cada2015-12-08 15:45:58 -07002625_(delete_loopback_reply) \
2626_(bd_ip_mac_add_del_reply) \
2627_(map_del_domain_reply) \
2628_(map_add_del_rule_reply) \
2629_(want_interface_events_reply) \
Dave Barachc07bf5d2016-02-17 17:52:26 -05002630_(want_stats_reply) \
2631_(cop_interface_enable_disable_reply) \
Pavel Kotucek00bbf272016-03-03 13:27:11 +01002632_(cop_whitelist_enable_disable_reply) \
Shwetha20a64f52016-03-25 10:55:01 +00002633_(sw_interface_clear_stats_reply) \
2634_(trace_profile_add_reply) \
2635_(trace_profile_apply_reply) \
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002636_(trace_profile_del_reply) \
2637_(lisp_add_del_locator_set_reply) \
2638_(lisp_add_del_locator_reply) \
2639_(lisp_add_del_local_eid_reply) \
Florin Corasf727db92016-06-23 15:01:58 +02002640_(lisp_add_del_remote_mapping_reply) \
2641_(lisp_add_del_adjacency_reply) \
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002642_(lisp_gpe_add_del_fwd_entry_reply) \
2643_(lisp_add_del_map_resolver_reply) \
Florin Coras577c3552016-04-21 00:45:40 +02002644_(lisp_gpe_enable_disable_reply) \
Matus Fabian8a95a482016-05-06 15:14:13 +02002645_(lisp_gpe_add_del_iface_reply) \
Filip Tehlar46d4e362016-05-09 09:39:26 +02002646_(lisp_enable_disable_reply) \
Filip Tehlar53f09e32016-05-19 14:25:44 +02002647_(lisp_pitr_set_locator_set_reply) \
Andrej Kozemcakb6e4d392016-06-14 13:55:57 +02002648_(lisp_add_del_map_request_itr_rlocs_reply) \
Filip Tehlar324112f2016-06-02 16:07:38 +02002649_(lisp_eid_table_add_del_map_reply) \
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07002650_(vxlan_gpe_add_del_tunnel_reply) \
Matus Fabian65fcd4d2016-05-13 05:44:48 -07002651_(af_packet_delete_reply) \
Matus Fabian82e29c42016-05-11 04:49:46 -07002652_(policer_add_del_reply) \
2653_(netmap_create_reply) \
2654_(netmap_delete_reply)
Ed Warnickecb9cada2015-12-08 15:45:58 -07002655
2656#define _(n) \
2657 static void vl_api_##n##_t_handler \
2658 (vl_api_##n##_t * mp) \
2659 { \
2660 vat_main_t * vam = &vat_main; \
2661 i32 retval = ntohl(mp->retval); \
2662 if (vam->async_mode) { \
2663 vam->async_errors += (retval < 0); \
2664 } else { \
2665 vam->retval = retval; \
2666 vam->result_ready = 1; \
2667 } \
2668 }
2669foreach_standard_reply_retval_handler;
2670#undef _
2671
2672#define _(n) \
2673 static void vl_api_##n##_t_handler_json \
2674 (vl_api_##n##_t * mp) \
2675 { \
2676 vat_main_t * vam = &vat_main; \
2677 vat_json_node_t node; \
2678 vat_json_init_object(&node); \
2679 vat_json_object_add_int(&node, "retval", ntohl(mp->retval)); \
2680 vat_json_print(vam->ofp, &node); \
2681 vam->retval = ntohl(mp->retval); \
2682 vam->result_ready = 1; \
2683 }
2684foreach_standard_reply_retval_handler;
2685#undef _
2686
2687/*
2688 * Table of message reply handlers, must include boilerplate handlers
2689 * we just generated
2690 */
2691
2692#define foreach_vpe_api_reply_msg \
2693_(CREATE_LOOPBACK_REPLY, create_loopback_reply) \
2694_(SW_INTERFACE_DETAILS, sw_interface_details) \
2695_(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags) \
2696_(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply) \
2697_(CONTROL_PING_REPLY, control_ping_reply) \
2698_(CLI_REPLY, cli_reply) \
2699_(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY, \
2700 sw_interface_add_del_address_reply) \
2701_(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply) \
2702_(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply) \
2703_(SW_INTERFACE_SET_L2_XCONNECT_REPLY, \
2704 sw_interface_set_l2_xconnect_reply) \
2705_(SW_INTERFACE_SET_L2_BRIDGE_REPLY, \
2706 sw_interface_set_l2_bridge_reply) \
2707_(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply) \
2708_(BRIDGE_DOMAIN_DETAILS, bridge_domain_details) \
2709_(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details) \
2710_(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply) \
2711_(L2_FLAGS_REPLY, l2_flags_reply) \
2712_(BRIDGE_FLAGS_REPLY, bridge_flags_reply) \
2713_(TAP_CONNECT_REPLY, tap_connect_reply) \
2714_(TAP_MODIFY_REPLY, tap_modify_reply) \
2715_(TAP_DELETE_REPLY, tap_delete_reply) \
2716_(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details) \
2717_(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply) \
2718_(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply) \
2719_(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY, \
2720 proxy_arp_intfc_enable_disable_reply) \
2721_(MPLS_ADD_DEL_ENCAP_REPLY, mpls_add_del_encap_reply) \
2722_(MPLS_ADD_DEL_DECAP_REPLY, mpls_add_del_decap_reply) \
2723_(MPLS_GRE_ADD_DEL_TUNNEL_REPLY, mpls_gre_add_del_tunnel_reply) \
2724_(MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY, \
2725 mpls_ethernet_add_del_tunnel_reply) \
2726_(MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY, \
2727 mpls_ethernet_add_del_tunnel_2_reply) \
2728_(SW_INTERFACE_SET_UNNUMBERED_REPLY, \
2729 sw_interface_set_unnumbered_reply) \
2730_(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply) \
2731_(RESET_VRF_REPLY, reset_vrf_reply) \
2732_(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply) \
2733_(CREATE_SUBIF_REPLY, create_subif_reply) \
2734_(OAM_ADD_DEL_REPLY, oam_add_del_reply) \
2735_(RESET_FIB_REPLY, reset_fib_reply) \
2736_(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply) \
2737_(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply) \
2738_(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply) \
2739_(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply) \
2740_(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply) \
2741_(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY, \
2742 sw_interface_ip6_enable_disable_reply) \
2743_(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY, \
2744 sw_interface_ip6_set_link_local_address_reply) \
2745_(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY, \
2746 sw_interface_ip6nd_ra_prefix_reply) \
2747_(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY, \
2748 sw_interface_ip6nd_ra_config_reply) \
2749_(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply) \
2750_(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply) \
2751_(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply) \
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07002752_(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply) \
2753_(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply) \
Ed Warnickecb9cada2015-12-08 15:45:58 -07002754_(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply) \
2755_(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply) \
2756_(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY, \
2757classify_set_interface_ip_table_reply) \
2758_(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY, \
2759 classify_set_interface_l2_tables_reply) \
2760_(GET_NODE_INDEX_REPLY, get_node_index_reply) \
2761_(ADD_NODE_NEXT_REPLY, add_node_next_reply) \
2762_(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply) \
2763_(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply) \
2764_(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY, \
2765 l2tpv3_interface_enable_disable_reply) \
2766_(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply) \
2767_(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details) \
2768_(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply) \
Dave Wallace60231f32015-12-17 21:04:30 -05002769_(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details) \
Chris Luke27fe48f2016-04-28 13:44:38 -04002770_(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply) \
2771_(GRE_TUNNEL_DETAILS, gre_tunnel_details) \
Ed Warnickecb9cada2015-12-08 15:45:58 -07002772_(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply) \
2773_(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply) \
2774_(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
2775_(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details) \
2776_(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply) \
2777_(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply) \
2778_(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply) \
2779_(SHOW_VERSION_REPLY, show_version_reply) \
Ed Warnickecb9cada2015-12-08 15:45:58 -07002780_(L2_FIB_TABLE_ENTRY, l2_fib_table_entry) \
Hongjun Ni0e06e2b2016-05-30 19:45:51 +08002781_(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply) \
2782_(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details) \
Ed Warnickecb9cada2015-12-08 15:45:58 -07002783_(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply) \
2784_(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply) \
2785_(IP4_ARP_EVENT, ip4_arp_event) \
2786_(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply) \
2787_(IP_ADDRESS_DETAILS, ip_address_details) \
2788_(IP_DETAILS, ip_details) \
2789_(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply) \
2790_(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
2791_(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply) \
2792_(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply) \
2793_(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply) \
Matus Fabiane5f42fe2016-04-08 11:18:08 +02002794_(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply) \
2795_(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply) \
2796_(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply) \
2797_(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply) \
2798_(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply) \
Ed Warnickecb9cada2015-12-08 15:45:58 -07002799_(DELETE_LOOPBACK_REPLY, delete_loopback_reply) \
2800_(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply) \
2801_(DHCP_COMPL_EVENT, dhcp_compl_event) \
2802_(VNET_INTERFACE_COUNTERS, vnet_interface_counters) \
2803_(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters) \
2804_(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters) \
2805_(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply) \
2806_(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply) \
Dave Barachc07bf5d2016-02-17 17:52:26 -05002807_(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply) \
Ed Warnickecb9cada2015-12-08 15:45:58 -07002808_(MAP_DOMAIN_DETAILS, map_domain_details) \
2809_(MAP_RULE_DETAILS, map_rule_details) \
2810_(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply) \
2811_(WANT_STATS_REPLY, want_stats_reply) \
Dave Barachc07bf5d2016-02-17 17:52:26 -05002812_(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply) \
2813_(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
Dave Barachb44e9bc2016-02-19 09:06:23 -05002814_(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
Pavel Kotucek00bbf272016-03-03 13:27:11 +01002815_(GET_NODE_GRAPH_REPLY, get_node_graph_reply) \
Shwetha20a64f52016-03-25 10:55:01 +00002816_(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply) \
2817_(TRACE_PROFILE_ADD_REPLY, trace_profile_add_reply) \
2818_(TRACE_PROFILE_APPLY_REPLY, trace_profile_apply_reply) \
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002819_(TRACE_PROFILE_DEL_REPLY, trace_profile_del_reply) \
2820_(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply) \
2821_(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply) \
2822_(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply) \
Florin Corasf727db92016-06-23 15:01:58 +02002823_(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
2824_(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply) \
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002825_(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply) \
2826_(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply) \
Florin Coras577c3552016-04-21 00:45:40 +02002827_(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply) \
Filip Tehlar46d4e362016-05-09 09:39:26 +02002828_(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply) \
Filip Tehlar53f09e32016-05-19 14:25:44 +02002829_(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply) \
Filip Tehlar324112f2016-06-02 16:07:38 +02002830_(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply) \
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002831_(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply) \
2832_(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details) \
2833_(LISP_LOCAL_EID_TABLE_DETAILS, lisp_local_eid_table_details) \
2834_(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details) \
Andrej Kozemcaka9edd852016-05-02 12:14:33 +02002835_(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details) \
Filip Tehlar46d4e362016-05-09 09:39:26 +02002836_(LISP_ENABLE_DISABLE_STATUS_DETAILS, \
2837 lisp_enable_disable_status_details) \
Andrej Kozemcakb6e4d392016-06-14 13:55:57 +02002838_(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY, \
2839 lisp_add_del_map_request_itr_rlocs_reply) \
2840_(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY, \
2841 lisp_get_map_request_itr_rlocs_reply) \
Matus Fabian8a95a482016-05-06 15:14:13 +02002842_(AF_PACKET_CREATE_REPLY, af_packet_create_reply) \
Matus Fabian65fcd4d2016-05-13 05:44:48 -07002843_(AF_PACKET_DELETE_REPLY, af_packet_delete_reply) \
Matus Fabian82e29c42016-05-11 04:49:46 -07002844_(POLICER_ADD_DEL_REPLY, policer_add_del_reply) \
Matus Fabiane8554802016-05-18 23:40:37 -07002845_(POLICER_DETAILS, policer_details) \
Matus Fabian82e29c42016-05-11 04:49:46 -07002846_(NETMAP_CREATE_REPLY, netmap_create_reply) \
marek zavodsky2c21a9a2016-06-21 05:35:16 +02002847_(NETMAP_DELETE_REPLY, netmap_delete_reply) \
2848_(MPLS_GRE_TUNNEL_DETAILS, mpls_gre_tunnel_details) \
2849_(MPLS_ETH_TUNNEL_DETAILS, mpls_eth_tunnel_details) \
2850_(MPLS_FIB_ENCAP_DETAILS, mpls_fib_encap_details) \
Pavel Kotucek20c90f72016-06-07 14:44:26 +02002851_(MPLS_FIB_DECAP_DETAILS, mpls_fib_decap_details) \
2852_(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply) \
2853_(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
2854_(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply) \
2855_(CLASSIFY_SESSION_DETAILS, classify_session_details)
Ed Warnickecb9cada2015-12-08 15:45:58 -07002856
2857/* M: construct, but don't yet send a message */
2858
2859#define M(T,t) \
2860do { \
2861 vam->result_ready = 0; \
2862 mp = vl_msg_api_alloc(sizeof(*mp)); \
2863 memset (mp, 0, sizeof (*mp)); \
2864 mp->_vl_msg_id = ntohs (VL_API_##T); \
2865 mp->client_index = vam->my_client_index; \
2866} while(0);
2867
2868#define M2(T,t,n) \
2869do { \
2870 vam->result_ready = 0; \
2871 mp = vl_msg_api_alloc(sizeof(*mp)+(n)); \
2872 memset (mp, 0, sizeof (*mp)); \
2873 mp->_vl_msg_id = ntohs (VL_API_##T); \
2874 mp->client_index = vam->my_client_index; \
2875} while(0);
2876
2877
2878/* S: send a message */
2879#define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
2880
2881/* W: wait for results, with timeout */
2882#define W \
2883do { \
2884 timeout = vat_time_now (vam) + 1.0; \
2885 \
2886 while (vat_time_now (vam) < timeout) { \
2887 if (vam->result_ready == 1) { \
2888 return (vam->retval); \
2889 } \
2890 } \
2891 return -99; \
2892} while(0);
2893
Keith Burns (alagalah)802255c2016-06-13 16:56:04 -07002894/* W2: wait for results, with timeout */
2895#define W2(body) \
2896do { \
2897 timeout = vat_time_now (vam) + 1.0; \
2898 \
2899 while (vat_time_now (vam) < timeout) { \
2900 if (vam->result_ready == 1) { \
2901 (body); \
2902 return (vam->retval); \
2903 } \
2904 } \
2905 return -99; \
2906} while(0);
2907
Ed Warnickecb9cada2015-12-08 15:45:58 -07002908typedef struct {
2909 u8 * name;
2910 u32 value;
2911} name_sort_t;
2912
2913
2914#define STR_VTR_OP_CASE(op) \
2915 case L2_VTR_ ## op: \
2916 return "" # op;
2917
2918static const char *str_vtr_op(u32 vtr_op)
2919{
2920 switch(vtr_op) {
2921 STR_VTR_OP_CASE(DISABLED);
2922 STR_VTR_OP_CASE(PUSH_1);
2923 STR_VTR_OP_CASE(PUSH_2);
2924 STR_VTR_OP_CASE(POP_1);
2925 STR_VTR_OP_CASE(POP_2);
2926 STR_VTR_OP_CASE(TRANSLATE_1_1);
2927 STR_VTR_OP_CASE(TRANSLATE_1_2);
2928 STR_VTR_OP_CASE(TRANSLATE_2_1);
2929 STR_VTR_OP_CASE(TRANSLATE_2_2);
2930 }
2931
2932 return "UNKNOWN";
2933}
2934
2935static int dump_sub_interface_table (vat_main_t * vam)
2936{
2937 const sw_interface_subif_t * sub = NULL;
2938
2939 if (vam->json_output) {
2940 clib_warning ("JSON output supported only for VPE API calls and dump_stats_table");
2941 return -99;
2942 }
2943
2944 fformat (vam->ofp,
2945 "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
2946 "Interface", "sw_if_index",
2947 "sub id", "dot1ad", "tags", "outer id",
2948 "inner id", "exact", "default",
2949 "outer any", "inner any");
2950
2951 vec_foreach (sub, vam->sw_if_subif_table) {
2952 fformat (vam->ofp,
2953 "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
2954 sub->interface_name,
2955 sub->sw_if_index,
2956 sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
2957 sub->sub_number_of_tags, sub->sub_outer_vlan_id,
2958 sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
2959 sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
2960 if (sub->vtr_op != L2_VTR_DISABLED) {
2961 fformat (vam->ofp,
2962 " vlan-tag-rewrite - op: %-14s [ dot1q: %d "
2963 "tag1: %d tag2: %d ]\n",
2964 str_vtr_op(sub->vtr_op), sub->vtr_push_dot1q,
2965 sub->vtr_tag1, sub->vtr_tag2);
2966 }
2967 }
2968
2969 return 0;
2970}
2971
Matus Fabiand2dc3df2015-12-14 10:31:33 -05002972static int name_sort_cmp (void * a1, void * a2)
2973{
2974 name_sort_t * n1 = a1;
2975 name_sort_t * n2 = a2;
2976
2977 return strcmp ((char *)n1->name, (char *)n2->name);
2978}
2979
Ed Warnickecb9cada2015-12-08 15:45:58 -07002980static int dump_interface_table (vat_main_t * vam)
2981{
2982 hash_pair_t * p;
2983 name_sort_t * nses = 0, * ns;
2984
2985 if (vam->json_output) {
2986 clib_warning ("JSON output supported only for VPE API calls and dump_stats_table");
2987 return -99;
2988 }
2989
2990 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
2991 ({
2992 vec_add2 (nses, ns, 1);
2993 ns->name = (u8 *)(p->key);
2994 ns->value = (u32) p->value[0];
2995 }));
2996
Matus Fabiand2dc3df2015-12-14 10:31:33 -05002997 vec_sort_with_function (nses, name_sort_cmp);
Ed Warnickecb9cada2015-12-08 15:45:58 -07002998
2999 fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
3000 vec_foreach (ns, nses) {
3001 fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
3002 }
3003 vec_free (nses);
3004 return 0;
3005}
3006
3007static int dump_ip_table (vat_main_t * vam, int is_ipv6)
3008{
3009 const ip_details_t * det = NULL;
3010 const ip_address_details_t * address = NULL;
3011 u32 i = ~0;
3012
3013 fformat (vam->ofp,
3014 "%-12s\n",
3015 "sw_if_index");
3016
Damjan Marionfa693552016-04-26 19:30:36 +02003017 if (0 == vam) {
Ed Warnickecb9cada2015-12-08 15:45:58 -07003018 return 0;
3019 }
3020
3021 vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6]) {
3022 i++;
3023 if (!det->present) {
3024 continue;
3025 }
3026 fformat (vam->ofp,
3027 "%-12d\n",
3028 i);
3029 fformat (vam->ofp,
3030 " %-30s%-13s\n",
3031 "Address", "Prefix length");
3032 if (!det->addr) {
3033 continue;
3034 }
3035 vec_foreach (address, det->addr) {
3036 fformat (vam->ofp,
3037 " %-30U%-13d\n",
3038 is_ipv6 ? format_ip6_address : format_ip4_address,
3039 address->ip,
3040 address->prefix_length);
3041 }
3042 }
3043
3044 return 0;
3045}
3046
3047static int dump_ipv4_table (vat_main_t * vam)
3048{
3049 if (vam->json_output) {
3050 clib_warning ("JSON output supported only for VPE API calls and dump_stats_table");
3051 return -99;
3052 }
3053
3054 return dump_ip_table (vam, 0);
3055}
3056
3057static int dump_ipv6_table (vat_main_t * vam)
3058{
3059 if (vam->json_output) {
3060 clib_warning ("JSON output supported only for VPE API calls and dump_stats_table");
3061 return -99;
3062 }
3063
3064 return dump_ip_table (vam, 1);
3065}
3066
3067static char* counter_type_to_str (u8 counter_type, u8 is_combined)
3068{
3069 if (!is_combined) {
3070 switch(counter_type) {
3071 case VNET_INTERFACE_COUNTER_DROP:
3072 return "drop";
3073 case VNET_INTERFACE_COUNTER_PUNT:
3074 return "punt";
3075 case VNET_INTERFACE_COUNTER_IP4:
3076 return "ip4";
3077 case VNET_INTERFACE_COUNTER_IP6:
3078 return "ip6";
3079 case VNET_INTERFACE_COUNTER_RX_NO_BUF:
3080 return "rx-no-buf";
3081 case VNET_INTERFACE_COUNTER_RX_MISS:
3082 return "rx-miss";
3083 case VNET_INTERFACE_COUNTER_RX_ERROR:
3084 return "rx-error";
3085 case VNET_INTERFACE_COUNTER_TX_ERROR:
3086 return "tx-error";
3087 default:
3088 return "INVALID-COUNTER-TYPE";
3089 }
3090 } else {
3091 switch(counter_type) {
3092 case VNET_INTERFACE_COUNTER_RX:
3093 return "rx";
3094 case VNET_INTERFACE_COUNTER_TX:
3095 return "tx";
3096 default:
3097 return "INVALID-COUNTER-TYPE";
3098 }
3099 }
3100}
3101
3102static int dump_stats_table (vat_main_t * vam)
3103{
3104 vat_json_node_t node;
3105 vat_json_node_t *msg_array;
3106 vat_json_node_t *msg;
3107 vat_json_node_t *counter_array;
3108 vat_json_node_t *counter;
3109 interface_counter_t c;
3110 u64 packets;
3111 ip4_fib_counter_t *c4;
3112 ip6_fib_counter_t *c6;
3113 int i, j;
3114
3115 if (!vam->json_output) {
3116 clib_warning ("dump_stats_table supported only in JSON format");
3117 return -99;
3118 }
3119
3120 vat_json_init_object(&node);
3121
3122 /* interface counters */
3123 msg_array = vat_json_object_add(&node, "interface_counters");
3124 vat_json_init_array(msg_array);
3125 for (i = 0; i < vec_len(vam->simple_interface_counters); i++) {
3126 msg = vat_json_array_add(msg_array);
3127 vat_json_init_object(msg);
3128 vat_json_object_add_string_copy(msg, "vnet_counter_type",
3129 (u8*)counter_type_to_str(i, 0));
3130 vat_json_object_add_int(msg, "is_combined", 0);
3131 counter_array = vat_json_object_add(msg, "data");
3132 vat_json_init_array(counter_array);
3133 for (j = 0; j < vec_len(vam->simple_interface_counters[i]); j++) {
3134 packets = vam->simple_interface_counters[i][j];
3135 vat_json_array_add_uint(counter_array, packets);
3136 }
3137 }
3138 for (i = 0; i < vec_len(vam->combined_interface_counters); i++) {
3139 msg = vat_json_array_add(msg_array);
3140 vat_json_init_object(msg);
3141 vat_json_object_add_string_copy(msg, "vnet_counter_type",
3142 (u8*)counter_type_to_str(i, 1));
3143 vat_json_object_add_int(msg, "is_combined", 1);
3144 counter_array = vat_json_object_add(msg, "data");
3145 vat_json_init_array(counter_array);
3146 for (j = 0; j < vec_len(vam->combined_interface_counters[i]); j++) {
3147 c = vam->combined_interface_counters[i][j];
3148 counter = vat_json_array_add(counter_array);
3149 vat_json_init_object(counter);
3150 vat_json_object_add_uint(counter, "packets", c.packets);
3151 vat_json_object_add_uint(counter, "bytes", c.bytes);
3152 }
3153 }
3154
3155 /* ip4 fib counters */
3156 msg_array = vat_json_object_add(&node, "ip4_fib_counters");
3157 vat_json_init_array(msg_array);
3158 for (i = 0; i < vec_len(vam->ip4_fib_counters); i++) {
3159 msg = vat_json_array_add(msg_array);
3160 vat_json_init_object(msg);
3161 vat_json_object_add_uint(msg, "vrf_id", vam->ip4_fib_counters_vrf_id_by_index[i]);
3162 counter_array = vat_json_object_add(msg, "c");
3163 vat_json_init_array(counter_array);
3164 for (j = 0; j < vec_len(vam->ip4_fib_counters[i]); j++) {
3165 counter = vat_json_array_add(counter_array);
3166 vat_json_init_object(counter);
3167 c4 = &vam->ip4_fib_counters[i][j];
3168 vat_json_object_add_ip4(counter, "address", c4->address);
3169 vat_json_object_add_uint(counter, "address_length", c4->address_length);
3170 vat_json_object_add_uint(counter, "packets", c4->packets);
3171 vat_json_object_add_uint(counter, "bytes", c4->bytes);
3172 }
3173 }
3174
3175 /* ip6 fib counters */
3176 msg_array = vat_json_object_add(&node, "ip6_fib_counters");
3177 vat_json_init_array(msg_array);
3178 for (i = 0; i < vec_len(vam->ip6_fib_counters); i++) {
3179 msg = vat_json_array_add(msg_array);
3180 vat_json_init_object(msg);
3181 vat_json_object_add_uint(msg, "vrf_id", vam->ip6_fib_counters_vrf_id_by_index[i]);
3182 counter_array = vat_json_object_add(msg, "c");
3183 vat_json_init_array(counter_array);
3184 for (j = 0; j < vec_len(vam->ip6_fib_counters[i]); j++) {
3185 counter = vat_json_array_add(counter_array);
3186 vat_json_init_object(counter);
3187 c6 = &vam->ip6_fib_counters[i][j];
3188 vat_json_object_add_ip6(counter, "address", c6->address);
3189 vat_json_object_add_uint(counter, "address_length", c6->address_length);
3190 vat_json_object_add_uint(counter, "packets", c6->packets);
3191 vat_json_object_add_uint(counter, "bytes", c6->bytes);
3192 }
3193 }
3194
3195 vat_json_print(vam->ofp, &node);
3196 vat_json_free(&node);
3197
3198 return 0;
3199}
3200
3201int exec (vat_main_t * vam)
3202{
3203 api_main_t * am = &api_main;
3204 vl_api_cli_request_t *mp;
3205 f64 timeout;
3206 void * oldheap;
3207 u8 * cmd = 0;
3208 unformat_input_t * i = vam->input;
3209
3210 if (vec_len(i->buffer) == 0)
3211 return -1;
3212
3213 if (vam->exec_mode == 0 && unformat (i, "mode")) {
3214 vam->exec_mode = 1;
3215 return 0;
3216 }
3217 if (vam->exec_mode == 1 &&
3218 (unformat (i, "exit") || unformat (i, "quit"))) {
3219 vam->exec_mode = 0;
3220 return 0;
3221 }
3222
3223
3224 M(CLI_REQUEST, cli_request);
3225
3226 /*
3227 * Copy cmd into shared memory.
3228 * In order for the CLI command to work, it
3229 * must be a vector ending in \n, not a C-string ending
3230 * in \n\0.
3231 */
3232 pthread_mutex_lock (&am->vlib_rp->mutex);
3233 oldheap = svm_push_data_heap (am->vlib_rp);
3234
3235 vec_validate (cmd, vec_len(vam->input->buffer)-1);
Damjan Marionf1213b82016-03-13 02:22:06 +01003236 clib_memcpy (cmd, vam->input->buffer, vec_len(vam->input->buffer));
Ed Warnickecb9cada2015-12-08 15:45:58 -07003237
3238 svm_pop_heap (oldheap);
3239 pthread_mutex_unlock (&am->vlib_rp->mutex);
3240
3241 mp->cmd_in_shmem = (u64) cmd;
3242 S;
3243 timeout = vat_time_now (vam) + 10.0;
3244
3245 while (vat_time_now (vam) < timeout) {
3246 if (vam->result_ready == 1) {
3247 u8 * free_me;
Pavel Kotucek060c6fc2016-02-24 15:52:42 +01003248 if (vam->shmem_result != NULL)
3249 fformat (vam->ofp, "%s", vam->shmem_result);
Ed Warnickecb9cada2015-12-08 15:45:58 -07003250 pthread_mutex_lock (&am->vlib_rp->mutex);
3251 oldheap = svm_push_data_heap (am->vlib_rp);
3252
3253 free_me = (u8 *)vam->shmem_result;
3254 vec_free (free_me);
3255
3256 svm_pop_heap (oldheap);
3257 pthread_mutex_unlock (&am->vlib_rp->mutex);
3258 return 0;
3259 }
3260 }
3261 return -99;
3262}
3263
3264static int api_create_loopback (vat_main_t * vam)
3265{
3266 unformat_input_t * i = vam->input;
3267 vl_api_create_loopback_t *mp;
3268 f64 timeout;
3269 u8 mac_address[6];
3270 u8 mac_set = 0;
3271
3272 memset (mac_address, 0, sizeof (mac_address));
3273
3274 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3275 {
3276 if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
3277 mac_set = 1;
3278 else
3279 break;
3280 }
3281
3282 /* Construct the API message */
3283 M(CREATE_LOOPBACK, create_loopback);
3284 if (mac_set)
Damjan Marionf1213b82016-03-13 02:22:06 +01003285 clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07003286
3287 S; W;
3288}
3289
3290static int api_delete_loopback (vat_main_t * vam)
3291{
3292 unformat_input_t * i = vam->input;
3293 vl_api_delete_loopback_t *mp;
3294 f64 timeout;
3295 u32 sw_if_index = ~0;
3296
3297 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3298 {
3299 if (unformat (i, "sw_if_index %d", &sw_if_index))
3300 ;
3301 else
3302 break;
3303 }
3304
3305 if (sw_if_index == ~0)
3306 {
3307 errmsg ("missing sw_if_index\n");
3308 return -99;
3309 }
3310
3311 /* Construct the API message */
3312 M(DELETE_LOOPBACK, delete_loopback);
3313 mp->sw_if_index = ntohl (sw_if_index);
3314
3315 S; W;
3316}
3317
3318static int api_want_stats (vat_main_t * vam)
3319{
3320 unformat_input_t * i = vam->input;
3321 vl_api_want_stats_t * mp;
3322 f64 timeout;
3323 int enable = -1;
3324
3325 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3326 {
3327 if (unformat (i, "enable"))
3328 enable = 1;
3329 else if (unformat (i, "disable"))
3330 enable = 0;
3331 else
3332 break;
3333 }
3334
3335 if (enable == -1)
3336 {
3337 errmsg ("missing enable|disable\n");
3338 return -99;
3339 }
3340
3341 M(WANT_STATS, want_stats);
3342 mp->enable_disable = enable;
3343
3344 S; W;
3345}
3346
3347static int api_want_interface_events (vat_main_t * vam)
3348{
3349 unformat_input_t * i = vam->input;
3350 vl_api_want_interface_events_t * mp;
3351 f64 timeout;
3352 int enable = -1;
3353
3354 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3355 {
3356 if (unformat (i, "enable"))
3357 enable = 1;
3358 else if (unformat (i, "disable"))
3359 enable = 0;
3360 else
3361 break;
3362 }
3363
3364 if (enable == -1)
3365 {
3366 errmsg ("missing enable|disable\n");
3367 return -99;
3368 }
3369
3370 M(WANT_INTERFACE_EVENTS, want_interface_events);
3371 mp->enable_disable = enable;
3372
3373 vam->interface_event_display = enable;
3374
3375 S; W;
3376}
3377
3378
3379/* Note: non-static, called once to set up the initial intfc table */
3380int api_sw_interface_dump (vat_main_t * vam)
3381{
3382 vl_api_sw_interface_dump_t *mp;
3383 f64 timeout;
3384 hash_pair_t * p;
3385 name_sort_t * nses = 0, * ns;
3386 sw_interface_subif_t * sub = NULL;
3387
3388 /* Toss the old name table */
3389 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3390 ({
3391 vec_add2 (nses, ns, 1);
3392 ns->name = (u8 *)(p->key);
3393 ns->value = (u32) p->value[0];
3394 }));
3395
3396 hash_free (vam->sw_if_index_by_interface_name);
3397
3398 vec_foreach (ns, nses)
3399 vec_free (ns->name);
3400
3401 vec_free (nses);
3402
3403 vec_foreach (sub, vam->sw_if_subif_table) {
3404 vec_free (sub->interface_name);
3405 }
3406 vec_free (vam->sw_if_subif_table);
3407
3408 /* recreate the interface name hash table */
3409 vam->sw_if_index_by_interface_name
3410 = hash_create_string (0, sizeof(uword));
3411
3412 /* Get list of ethernets */
3413 M(SW_INTERFACE_DUMP, sw_interface_dump);
3414 mp->name_filter_valid = 1;
Damjan Marionfa693552016-04-26 19:30:36 +02003415 strncpy ((char *) mp->name_filter, "Ether", sizeof(mp->name_filter)-1);
Ed Warnickecb9cada2015-12-08 15:45:58 -07003416 S;
3417
3418 /* and local / loopback interfaces */
3419 M(SW_INTERFACE_DUMP, sw_interface_dump);
3420 mp->name_filter_valid = 1;
Damjan Marionfa693552016-04-26 19:30:36 +02003421 strncpy ((char *) mp->name_filter, "lo", sizeof(mp->name_filter)-1);
Ed Warnickecb9cada2015-12-08 15:45:58 -07003422 S;
3423
Hongjun Nic4248792016-06-08 01:07:12 +08003424
3425 /* and vxlan-gpe tunnel interfaces */
3426 M(SW_INTERFACE_DUMP, sw_interface_dump);
3427 mp->name_filter_valid = 1;
3428 strncpy ((char *) mp->name_filter, "vxlan_gpe", sizeof(mp->name_filter)-1);
3429 S;
3430
Ed Warnickecb9cada2015-12-08 15:45:58 -07003431 /* and vxlan tunnel interfaces */
3432 M(SW_INTERFACE_DUMP, sw_interface_dump);
3433 mp->name_filter_valid = 1;
Damjan Marionfa693552016-04-26 19:30:36 +02003434 strncpy ((char *) mp->name_filter, "vxlan", sizeof(mp->name_filter)-1);
Ed Warnickecb9cada2015-12-08 15:45:58 -07003435 S;
3436
Damjan Marionb02e49c2016-03-31 17:44:25 +02003437 /* and host (af_packet) interfaces */
3438 M(SW_INTERFACE_DUMP, sw_interface_dump);
3439 mp->name_filter_valid = 1;
Damjan Marionfa693552016-04-26 19:30:36 +02003440 strncpy ((char *) mp->name_filter, "host", sizeof(mp->name_filter)-1);
Damjan Marionb02e49c2016-03-31 17:44:25 +02003441 S;
3442
Ed Warnickecb9cada2015-12-08 15:45:58 -07003443 /* and l2tpv3 tunnel interfaces */
3444 M(SW_INTERFACE_DUMP, sw_interface_dump);
3445 mp->name_filter_valid = 1;
Damjan Marionfa693552016-04-26 19:30:36 +02003446 strncpy ((char *) mp->name_filter, "l2tpv3_tunnel", sizeof(mp->name_filter)-1);
Ed Warnickecb9cada2015-12-08 15:45:58 -07003447 S;
3448
Chris Lukea6116ef2016-05-06 10:12:30 -04003449 /* and GRE tunnel interfaces */
3450 M(SW_INTERFACE_DUMP, sw_interface_dump);
3451 mp->name_filter_valid = 1;
3452 strncpy ((char *) mp->name_filter, "gre", sizeof(mp->name_filter)-1);
3453 S;
3454
Ed Warnickecb9cada2015-12-08 15:45:58 -07003455 /* Use a control ping for synchronization */
3456 {
3457 vl_api_control_ping_t * mp;
3458 M(CONTROL_PING, control_ping);
3459 S;
3460 }
3461 W;
3462}
3463
3464static int api_sw_interface_set_flags (vat_main_t * vam)
3465{
3466 unformat_input_t * i = vam->input;
3467 vl_api_sw_interface_set_flags_t *mp;
3468 f64 timeout;
3469 u32 sw_if_index;
3470 u8 sw_if_index_set = 0;
3471 u8 admin_up = 0, link_up = 0;
3472
3473 /* Parse args required to build the message */
3474 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3475 if (unformat (i, "admin-up"))
3476 admin_up = 1;
3477 else if (unformat (i, "admin-down"))
3478 admin_up = 0;
3479 else if (unformat (i, "link-up"))
3480 link_up = 1;
3481 else if (unformat (i, "link-down"))
3482 link_up = 0;
3483 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3484 sw_if_index_set = 1;
3485 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3486 sw_if_index_set = 1;
3487 else
3488 break;
3489 }
3490
3491 if (sw_if_index_set == 0) {
3492 errmsg ("missing interface name or sw_if_index\n");
3493 return -99;
3494 }
3495
3496 /* Construct the API message */
3497 M(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
3498 mp->sw_if_index = ntohl (sw_if_index);
3499 mp->admin_up_down = admin_up;
3500 mp->link_up_down = link_up;
3501
3502 /* send it... */
3503 S;
3504
3505 /* Wait for a reply, return the good/bad news... */
3506 W;
3507}
3508
Pavel Kotucek00bbf272016-03-03 13:27:11 +01003509static int api_sw_interface_clear_stats (vat_main_t * vam)
3510{
3511 unformat_input_t * i = vam->input;
3512 vl_api_sw_interface_clear_stats_t *mp;
3513 f64 timeout;
3514 u32 sw_if_index;
3515 u8 sw_if_index_set = 0;
3516
3517 /* Parse args required to build the message */
3518 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3519 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3520 sw_if_index_set = 1;
3521 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3522 sw_if_index_set = 1;
3523 else
3524 break;
3525 }
3526
3527 /* Construct the API message */
3528 M(SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
3529
3530 if (sw_if_index_set == 1)
3531 mp->sw_if_index = ntohl (sw_if_index);
3532 else
3533 mp->sw_if_index = ~0;
3534
3535 /* send it... */
3536 S;
3537
3538 /* Wait for a reply, return the good/bad news... */
3539 W;
3540}
3541
Ed Warnickecb9cada2015-12-08 15:45:58 -07003542static int api_sw_interface_add_del_address (vat_main_t * vam)
3543{
3544 unformat_input_t * i = vam->input;
3545 vl_api_sw_interface_add_del_address_t *mp;
3546 f64 timeout;
3547 u32 sw_if_index;
3548 u8 sw_if_index_set = 0;
3549 u8 is_add = 1, del_all = 0;
3550 u32 address_length = 0;
3551 u8 v4_address_set = 0;
3552 u8 v6_address_set = 0;
3553 ip4_address_t v4address;
3554 ip6_address_t v6address;
3555
3556 /* Parse args required to build the message */
3557 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3558 if (unformat (i, "del-all"))
3559 del_all = 1;
3560 else if (unformat (i, "del"))
3561 is_add = 0;
3562 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3563 sw_if_index_set = 1;
3564 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3565 sw_if_index_set = 1;
3566 else if (unformat (i, "%U/%d",
3567 unformat_ip4_address, &v4address,
3568 &address_length))
3569 v4_address_set = 1;
3570 else if (unformat (i, "%U/%d",
3571 unformat_ip6_address, &v6address,
3572 &address_length))
3573 v6_address_set = 1;
3574 else
3575 break;
3576 }
3577
3578 if (sw_if_index_set == 0) {
3579 errmsg ("missing interface name or sw_if_index\n");
3580 return -99;
3581 }
3582 if (v4_address_set && v6_address_set) {
3583 errmsg ("both v4 and v6 addresses set\n");
3584 return -99;
3585 }
3586 if (!v4_address_set && !v6_address_set && !del_all) {
3587 errmsg ("no addresses set\n");
3588 return -99;
3589 }
3590
3591 /* Construct the API message */
3592 M(SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
3593
3594 mp->sw_if_index = ntohl (sw_if_index);
3595 mp->is_add = is_add;
3596 mp->del_all = del_all;
3597 if (v6_address_set) {
3598 mp->is_ipv6 = 1;
Damjan Marionf1213b82016-03-13 02:22:06 +01003599 clib_memcpy (mp->address, &v6address, sizeof (v6address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07003600 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01003601 clib_memcpy (mp->address, &v4address, sizeof (v4address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07003602 }
3603 mp->address_length = address_length;
3604
3605 /* send it... */
3606 S;
3607
3608 /* Wait for a reply, return good/bad news */
3609 W;
3610}
3611
3612static int api_sw_interface_set_table (vat_main_t * vam)
3613{
3614 unformat_input_t * i = vam->input;
3615 vl_api_sw_interface_set_table_t *mp;
3616 f64 timeout;
3617 u32 sw_if_index, vrf_id = 0;
3618 u8 sw_if_index_set = 0;
3619 u8 is_ipv6 = 0;
3620
3621 /* Parse args required to build the message */
3622 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3623 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3624 sw_if_index_set = 1;
3625 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3626 sw_if_index_set = 1;
3627 else if (unformat (i, "vrf %d", &vrf_id))
3628 ;
3629 else if (unformat (i, "ipv6"))
3630 is_ipv6 = 1;
3631 else
3632 break;
3633 }
3634
3635 if (sw_if_index_set == 0) {
3636 errmsg ("missing interface name or sw_if_index\n");
3637 return -99;
3638 }
3639
3640 /* Construct the API message */
3641 M(SW_INTERFACE_SET_TABLE, sw_interface_set_table);
3642
3643 mp->sw_if_index = ntohl (sw_if_index);
3644 mp->is_ipv6 = is_ipv6;
3645 mp->vrf_id = ntohl (vrf_id);
3646
3647 /* send it... */
3648 S;
3649
3650 /* Wait for a reply... */
3651 W;
3652}
3653
3654static int api_sw_interface_set_vpath (vat_main_t * vam)
3655{
3656 unformat_input_t * i = vam->input;
3657 vl_api_sw_interface_set_vpath_t *mp;
3658 f64 timeout;
3659 u32 sw_if_index = 0;
3660 u8 sw_if_index_set = 0;
3661 u8 is_enable = 0;
3662
3663 /* Parse args required to build the message */
3664 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3665 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3666 sw_if_index_set = 1;
3667 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3668 sw_if_index_set = 1;
3669 else if (unformat (i, "enable"))
3670 is_enable = 1;
3671 else if (unformat (i, "disable"))
3672 is_enable = 0;
3673 else
3674 break;
3675 }
3676
3677 if (sw_if_index_set == 0) {
3678 errmsg ("missing interface name or sw_if_index\n");
3679 return -99;
3680 }
3681
3682 /* Construct the API message */
3683 M(SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
3684
3685 mp->sw_if_index = ntohl (sw_if_index);
3686 mp->enable = is_enable;
3687
3688 /* send it... */
3689 S;
3690
3691 /* Wait for a reply... */
3692 W;
3693}
3694
3695static int api_sw_interface_set_l2_xconnect (vat_main_t * vam)
3696{
3697 unformat_input_t * i = vam->input;
3698 vl_api_sw_interface_set_l2_xconnect_t *mp;
3699 f64 timeout;
3700 u32 rx_sw_if_index;
3701 u8 rx_sw_if_index_set = 0;
3702 u32 tx_sw_if_index;
3703 u8 tx_sw_if_index_set = 0;
3704 u8 enable = 1;
3705
3706 /* Parse args required to build the message */
3707 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3708 if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
3709 rx_sw_if_index_set = 1;
3710 else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
3711 tx_sw_if_index_set = 1;
3712 else if (unformat (i, "rx")) {
3713 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3714 if (unformat (i, "%U", unformat_sw_if_index, vam,
3715 &rx_sw_if_index))
3716 rx_sw_if_index_set = 1;
3717 } else
3718 break;
3719 } else if (unformat (i, "tx")) {
3720 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3721 if (unformat (i, "%U", unformat_sw_if_index, vam,
3722 &tx_sw_if_index))
3723 tx_sw_if_index_set = 1;
3724 } else
3725 break;
3726 } else if (unformat (i, "enable"))
3727 enable = 1;
3728 else if (unformat (i, "disable"))
3729 enable = 0;
3730 else
3731 break;
3732 }
3733
3734 if (rx_sw_if_index_set == 0) {
3735 errmsg ("missing rx interface name or rx_sw_if_index\n");
3736 return -99;
3737 }
3738
3739 if (enable && (tx_sw_if_index_set == 0)) {
3740 errmsg ("missing tx interface name or tx_sw_if_index\n");
3741 return -99;
3742 }
3743
3744 M(SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
3745
3746 mp->rx_sw_if_index = ntohl(rx_sw_if_index);
3747 mp->tx_sw_if_index = ntohl(tx_sw_if_index);
3748 mp->enable = enable;
3749
3750 S; W;
3751 /* NOTREACHED */
3752 return 0;
3753}
3754
3755static int api_sw_interface_set_l2_bridge (vat_main_t * vam)
3756{
3757 unformat_input_t * i = vam->input;
3758 vl_api_sw_interface_set_l2_bridge_t *mp;
3759 f64 timeout;
3760 u32 rx_sw_if_index;
3761 u8 rx_sw_if_index_set = 0;
3762 u32 bd_id;
3763 u8 bd_id_set = 0;
3764 u8 bvi = 0;
3765 u32 shg = 0;
3766 u8 enable = 1;
3767
3768 /* Parse args required to build the message */
3769 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3770 if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
3771 rx_sw_if_index_set = 1;
3772 else if (unformat (i, "bd_id %d", &bd_id))
3773 bd_id_set = 1;
3774 else if (unformat (i, "%U", unformat_sw_if_index, vam,
3775 &rx_sw_if_index))
3776 rx_sw_if_index_set = 1;
3777 else if (unformat (i, "shg %d", &shg))
3778 ;
3779 else if (unformat (i, "bvi"))
3780 bvi = 1;
3781 else if (unformat (i, "enable"))
3782 enable = 1;
3783 else if (unformat (i, "disable"))
3784 enable = 0;
3785 else
3786 break;
3787 }
3788
3789 if (rx_sw_if_index_set == 0) {
3790 errmsg ("missing rx interface name or sw_if_index\n");
3791 return -99;
3792 }
3793
3794 if (enable && (bd_id_set == 0)) {
3795 errmsg ("missing bridge domain\n");
3796 return -99;
3797 }
3798
3799 M(SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
3800
3801 mp->rx_sw_if_index = ntohl(rx_sw_if_index);
3802 mp->bd_id = ntohl(bd_id);
3803 mp->shg = (u8)shg;
3804 mp->bvi = bvi;
3805 mp->enable = enable;
3806
3807 S; W;
3808 /* NOTREACHED */
3809 return 0;
3810}
3811
3812static int api_bridge_domain_dump (vat_main_t * vam)
3813{
3814 unformat_input_t * i = vam->input;
3815 vl_api_bridge_domain_dump_t *mp;
3816 f64 timeout;
3817 u32 bd_id = ~0;
3818
3819 /* Parse args required to build the message */
3820 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3821 if (unformat (i, "bd_id %d", &bd_id))
3822 ;
3823 else
3824 break;
3825 }
3826
3827 M(BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
3828 mp->bd_id = ntohl(bd_id);
3829 S;
3830
3831 /* Use a control ping for synchronization */
3832 {
3833 vl_api_control_ping_t * mp;
3834 M(CONTROL_PING, control_ping);
3835 S;
3836 }
3837
3838 W;
3839 /* NOTREACHED */
3840 return 0;
3841}
3842
3843static int api_bridge_domain_add_del (vat_main_t * vam)
3844{
3845 unformat_input_t * i = vam->input;
3846 vl_api_bridge_domain_add_del_t *mp;
3847 f64 timeout;
3848 u32 bd_id = ~0;
3849 u8 is_add = 1;
3850 u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
3851
3852 /* Parse args required to build the message */
3853 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3854 if (unformat (i, "bd_id %d", &bd_id))
3855 ;
3856 else if (unformat (i, "flood %d", &flood))
3857 ;
3858 else if (unformat (i, "uu-flood %d", &uu_flood))
3859 ;
3860 else if (unformat (i, "forward %d", &forward))
3861 ;
3862 else if (unformat (i, "learn %d", &learn))
3863 ;
3864 else if (unformat (i, "arp-term %d", &arp_term))
3865 ;
3866 else if (unformat (i, "del")) {
3867 is_add = 0;
3868 flood = uu_flood = forward = learn = 0;
3869 }
3870 else
3871 break;
3872 }
3873
3874 if (bd_id == ~0) {
3875 errmsg ("missing bridge domain\n");
3876 return -99;
3877 }
3878
3879 M(BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
3880
3881 mp->bd_id = ntohl(bd_id);
3882 mp->flood = flood;
3883 mp->uu_flood = uu_flood;
3884 mp->forward = forward;
3885 mp->learn = learn;
3886 mp->arp_term = arp_term;
3887 mp->is_add = is_add;
3888
3889 S; W;
3890 /* NOTREACHED */
3891 return 0;
3892}
3893
3894static int api_l2fib_add_del (vat_main_t * vam)
3895{
3896 unformat_input_t * i = vam->input;
3897 vl_api_l2fib_add_del_t *mp;
3898 f64 timeout;
3899 u64 mac = 0;
3900 u8 mac_set = 0;
3901 u32 bd_id;
3902 u8 bd_id_set = 0;
3903 u32 sw_if_index;
3904 u8 sw_if_index_set = 0;
3905 u8 is_add = 1;
3906 u8 static_mac = 0;
3907 u8 filter_mac = 0;
3908
3909 /* Parse args required to build the message */
3910 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3911 if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
3912 mac_set = 1;
3913 else if (unformat (i, "bd_id %d", &bd_id))
3914 bd_id_set = 1;
3915 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3916 sw_if_index_set = 1;
3917 else if (unformat (i, "sw_if")) {
3918 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3919 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3920 sw_if_index_set = 1;
3921 } else
3922 break;
3923 } else if (unformat (i, "static"))
3924 static_mac = 1;
3925 else if (unformat (i, "filter")) {
3926 filter_mac = 1;
3927 static_mac = 1;
3928 } else if (unformat (i, "del"))
3929 is_add = 0;
3930 else
3931 break;
3932 }
3933
3934 if (mac_set == 0) {
3935 errmsg ("missing mac address\n");
3936 return -99;
3937 }
3938
3939 if (bd_id_set == 0) {
3940 errmsg ("missing bridge domain\n");
3941 return -99;
3942 }
3943
3944 if (is_add && (sw_if_index_set == 0)) {
3945 errmsg ("missing interface name or sw_if_index\n");
3946 return -99;
3947 }
3948
3949 M(L2FIB_ADD_DEL, l2fib_add_del);
3950
3951 mp->mac = mac;
3952 mp->bd_id = ntohl(bd_id);
3953 mp->is_add = is_add;
3954
3955 if (is_add) {
3956 mp->sw_if_index = ntohl(sw_if_index);
3957 mp->static_mac = static_mac;
3958 mp->filter_mac = filter_mac;
3959 }
3960
3961 S; W;
3962 /* NOTREACHED */
3963 return 0;
3964}
3965
3966static int api_l2_flags (vat_main_t * vam)
3967{
3968 unformat_input_t * i = vam->input;
3969 vl_api_l2_flags_t *mp;
3970 f64 timeout;
3971 u32 sw_if_index;
3972 u32 feature_bitmap = 0;
3973 u8 sw_if_index_set = 0;
3974
3975 /* Parse args required to build the message */
3976 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3977 if (unformat (i, "sw_if_index %d", &sw_if_index))
3978 sw_if_index_set = 1;
3979 else if (unformat (i, "sw_if")) {
3980 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3981 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3982 sw_if_index_set = 1;
3983 } else
3984 break;
3985 } else if (unformat (i, "learn"))
3986 feature_bitmap |= L2INPUT_FEAT_LEARN;
3987 else if (unformat (i, "forward"))
3988 feature_bitmap |= L2INPUT_FEAT_FWD;
3989 else if (unformat (i, "flood"))
3990 feature_bitmap |= L2INPUT_FEAT_FLOOD;
3991 else if (unformat (i, "uu-flood"))
3992 feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
3993 else
3994 break;
3995 }
3996
3997 if (sw_if_index_set == 0) {
3998 errmsg ("missing interface name or sw_if_index\n");
3999 return -99;
4000 }
4001
4002 M(L2_FLAGS, l2_flags);
4003
4004 mp->sw_if_index = ntohl(sw_if_index);
4005 mp->feature_bitmap = ntohl(feature_bitmap);
4006
4007 S; W;
4008 /* NOTREACHED */
4009 return 0;
4010}
4011
4012static int api_bridge_flags (vat_main_t * vam)
4013{
4014 unformat_input_t * i = vam->input;
4015 vl_api_bridge_flags_t *mp;
4016 f64 timeout;
4017 u32 bd_id;
4018 u8 bd_id_set = 0;
4019 u8 is_set = 1;
4020 u32 flags = 0;
4021
4022 /* Parse args required to build the message */
4023 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4024 if (unformat (i, "bd_id %d", &bd_id))
4025 bd_id_set = 1;
4026 else if (unformat (i, "learn"))
4027 flags |= L2_LEARN;
4028 else if (unformat (i, "forward"))
4029 flags |= L2_FWD;
4030 else if (unformat (i, "flood"))
4031 flags |= L2_FLOOD;
4032 else if (unformat (i, "uu-flood"))
4033 flags |= L2_UU_FLOOD;
4034 else if (unformat (i, "arp-term"))
4035 flags |= L2_ARP_TERM;
4036 else if (unformat (i, "off"))
4037 is_set = 0;
4038 else if (unformat (i, "disable"))
4039 is_set = 0;
4040 else
4041 break;
4042 }
4043
4044 if (bd_id_set == 0) {
4045 errmsg ("missing bridge domain\n");
4046 return -99;
4047 }
4048
4049 M(BRIDGE_FLAGS, bridge_flags);
4050
4051 mp->bd_id = ntohl(bd_id);
4052 mp->feature_bitmap = ntohl(flags);
4053 mp->is_set = is_set;
4054
4055 S; W;
4056 /* NOTREACHED */
4057 return 0;
4058}
4059
4060static int api_bd_ip_mac_add_del (vat_main_t * vam)
4061{
4062 unformat_input_t * i = vam->input;
4063 vl_api_bd_ip_mac_add_del_t *mp;
4064 f64 timeout;
4065 u32 bd_id;
4066 u8 is_ipv6 = 0;
4067 u8 is_add = 1;
4068 u8 bd_id_set = 0;
4069 u8 ip_set = 0;
4070 u8 mac_set = 0;
4071 ip4_address_t v4addr;
4072 ip6_address_t v6addr;
4073 u8 macaddr[6];
4074
4075
4076 /* Parse args required to build the message */
4077 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4078 if (unformat (i, "bd_id %d", &bd_id)) {
4079 bd_id_set++;
4080 } else if (unformat (i, "%U", unformat_ip4_address, &v4addr)) {
4081 ip_set++;
4082 } else if (unformat (i, "%U", unformat_ip6_address, &v6addr)) {
4083 ip_set++;
4084 is_ipv6++;
4085 } else if (unformat (i, "%U", unformat_ethernet_address, macaddr)) {
4086 mac_set++;
4087 } else if (unformat (i, "del"))
4088 is_add = 0;
4089 else
4090 break;
4091 }
4092
4093 if (bd_id_set == 0) {
4094 errmsg ("missing bridge domain\n");
4095 return -99;
4096 } else if (ip_set == 0) {
4097 errmsg ("missing IP address\n");
4098 return -99;
4099 } else if (mac_set == 0) {
4100 errmsg ("missing MAC address\n");
4101 return -99;
4102 }
4103
4104 M(BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
4105
4106 mp->bd_id = ntohl(bd_id);
4107 mp->is_ipv6 = is_ipv6;
4108 mp->is_add = is_add;
4109 if (is_ipv6)
Damjan Marionf1213b82016-03-13 02:22:06 +01004110 clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
4111 else clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
4112 clib_memcpy (mp->mac_address, macaddr, 6);
Ed Warnickecb9cada2015-12-08 15:45:58 -07004113 S; W;
4114 /* NOTREACHED */
4115 return 0;
4116}
4117
4118static int api_tap_connect (vat_main_t * vam)
4119{
4120 unformat_input_t * i = vam->input;
4121 vl_api_tap_connect_t *mp;
4122 f64 timeout;
4123 u8 mac_address[6];
4124 u8 random_mac = 1;
4125 u8 name_set = 0;
4126 u8 * tap_name;
4127
4128 memset (mac_address, 0, sizeof (mac_address));
4129
4130 /* Parse args required to build the message */
4131 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4132 if (unformat (i, "mac %U", unformat_ethernet_address, mac_address)) {
4133 random_mac = 0;
4134 }
4135 else if (unformat (i, "random-mac"))
4136 random_mac = 1;
4137 else if (unformat (i, "tapname %s", &tap_name))
4138 name_set = 1;
4139 else
4140 break;
4141 }
4142
4143 if (name_set == 0) {
4144 errmsg ("missing tap name\n");
4145 return -99;
4146 }
4147 if (vec_len (tap_name) > 63) {
4148 errmsg ("tap name too long\n");
4149 }
4150 vec_add1 (tap_name, 0);
4151
4152 /* Construct the API message */
4153 M(TAP_CONNECT, tap_connect);
4154
4155 mp->use_random_mac = random_mac;
Damjan Marionf1213b82016-03-13 02:22:06 +01004156 clib_memcpy (mp->mac_address, mac_address, 6);
4157 clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004158 vec_free (tap_name);
4159
4160 /* send it... */
4161 S;
4162
4163 /* Wait for a reply... */
4164 W;
4165}
4166
4167static int api_tap_modify (vat_main_t * vam)
4168{
4169 unformat_input_t * i = vam->input;
4170 vl_api_tap_modify_t *mp;
4171 f64 timeout;
4172 u8 mac_address[6];
4173 u8 random_mac = 1;
4174 u8 name_set = 0;
4175 u8 * tap_name;
4176 u32 sw_if_index = ~0;
4177 u8 sw_if_index_set = 0;
4178
4179 memset (mac_address, 0, sizeof (mac_address));
4180
4181 /* Parse args required to build the message */
4182 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4183 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4184 sw_if_index_set = 1;
4185 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4186 sw_if_index_set = 1;
4187 else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address)) {
4188 random_mac = 0;
4189 }
4190 else if (unformat (i, "random-mac"))
4191 random_mac = 1;
4192 else if (unformat (i, "tapname %s", &tap_name))
4193 name_set = 1;
4194 else
4195 break;
4196 }
4197
4198 if (sw_if_index_set == 0) {
4199 errmsg ("missing vpp interface name");
4200 return -99;
4201 }
4202 if (name_set == 0) {
4203 errmsg ("missing tap name\n");
4204 return -99;
4205 }
4206 if (vec_len (tap_name) > 63) {
4207 errmsg ("tap name too long\n");
4208 }
4209 vec_add1 (tap_name, 0);
4210
4211 /* Construct the API message */
4212 M(TAP_MODIFY, tap_modify);
4213
4214 mp->use_random_mac = random_mac;
4215 mp->sw_if_index = ntohl(sw_if_index);
Damjan Marionf1213b82016-03-13 02:22:06 +01004216 clib_memcpy (mp->mac_address, mac_address, 6);
4217 clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004218 vec_free (tap_name);
4219
4220 /* send it... */
4221 S;
4222
4223 /* Wait for a reply... */
4224 W;
4225}
4226
4227static int api_tap_delete (vat_main_t * vam)
4228{
4229 unformat_input_t * i = vam->input;
4230 vl_api_tap_delete_t *mp;
4231 f64 timeout;
4232 u32 sw_if_index = ~0;
4233 u8 sw_if_index_set = 0;
4234
4235 /* Parse args required to build the message */
4236 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4237 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4238 sw_if_index_set = 1;
4239 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4240 sw_if_index_set = 1;
4241 else
4242 break;
4243 }
4244
4245 if (sw_if_index_set == 0) {
4246 errmsg ("missing vpp interface name");
4247 return -99;
4248 }
4249
4250 /* Construct the API message */
4251 M(TAP_DELETE, tap_delete);
4252
4253 mp->sw_if_index = ntohl(sw_if_index);
4254
4255 /* send it... */
4256 S;
4257
4258 /* Wait for a reply... */
4259 W;
4260}
4261
4262static int api_ip_add_del_route (vat_main_t * vam)
4263{
4264 unformat_input_t * i = vam->input;
4265 vl_api_ip_add_del_route_t *mp;
4266 f64 timeout;
4267 u32 sw_if_index = 0, vrf_id = 0;
4268 u8 sw_if_index_set = 0;
4269 u8 is_ipv6 = 0;
4270 u8 is_local = 0, is_drop = 0;
4271 u8 create_vrf_if_needed = 0;
4272 u8 is_add = 1;
4273 u8 next_hop_weight = 1;
4274 u8 not_last = 0;
4275 u8 is_multipath = 0;
4276 u8 address_set = 0;
4277 u8 address_length_set = 0;
4278 u32 lookup_in_vrf = 0;
4279 u32 resolve_attempts = 0;
4280 u32 dst_address_length = 0;
4281 u8 next_hop_set = 0;
4282 ip4_address_t v4_dst_address, v4_next_hop_address;
4283 ip6_address_t v6_dst_address, v6_next_hop_address;
4284 int count = 1;
4285 int j;
4286 f64 before = 0;
4287 u32 random_add_del = 0;
4288 u32 * random_vector = 0;
4289 uword * random_hash;
4290 u32 random_seed = 0xdeaddabe;
4291 u32 classify_table_index = ~0;
4292 u8 is_classify = 0;
4293
4294 /* Parse args required to build the message */
4295 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4296 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4297 sw_if_index_set = 1;
4298 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4299 sw_if_index_set = 1;
4300 else if (unformat (i, "%U", unformat_ip4_address,
4301 &v4_dst_address)) {
4302 address_set = 1;
4303 is_ipv6 = 0;
4304 }
4305 else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address)) {
4306 address_set = 1;
4307 is_ipv6 = 1;
4308 }
4309 else if (unformat (i, "/%d", &dst_address_length)) {
4310 address_length_set = 1;
4311 }
4312
4313 else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
4314 &v4_next_hop_address)) {
4315 next_hop_set = 1;
4316 }
4317 else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
4318 &v6_next_hop_address)) {
4319 next_hop_set = 1;
4320 }
4321 else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
4322 ;
4323 else if (unformat (i, "weight %d", &next_hop_weight))
4324 ;
4325 else if (unformat (i, "drop")) {
4326 is_drop = 1;
4327 } else if (unformat (i, "local")) {
4328 is_local = 1;
4329 } else if (unformat (i, "classify %d", &classify_table_index)) {
4330 is_classify = 1;
4331 } else if (unformat (i, "del"))
4332 is_add = 0;
4333 else if (unformat (i, "add"))
4334 is_add = 1;
4335 else if (unformat (i, "not-last"))
4336 not_last = 1;
4337 else if (unformat (i, "multipath"))
4338 is_multipath = 1;
4339 else if (unformat (i, "vrf %d", &vrf_id))
4340 ;
4341 else if (unformat (i, "create-vrf"))
4342 create_vrf_if_needed = 1;
4343 else if (unformat (i, "count %d", &count))
4344 ;
4345 else if (unformat (i, "lookup-in-vrf %d", &lookup_in_vrf))
4346 ;
4347 else if (unformat (i, "random"))
4348 random_add_del = 1;
4349 else if (unformat (i, "seed %d", &random_seed))
4350 ;
4351 else {
4352 clib_warning ("parse error '%U'", format_unformat_error, i);
4353 return -99;
4354 }
4355 }
4356
4357 if (resolve_attempts > 0 && sw_if_index_set == 0) {
4358 errmsg ("ARP resolution needs explicit interface or sw_if_index\n");
4359 return -99;
4360 }
4361
4362 if (!next_hop_set && !is_drop && !is_local && !is_classify) {
4363 errmsg ("next hop / local / drop / classify not set\n");
4364 return -99;
4365 }
4366
4367 if (address_set == 0) {
4368 errmsg ("missing addresses\n");
4369 return -99;
4370 }
4371
4372 if (address_length_set == 0) {
4373 errmsg ("missing address length\n");
4374 return -99;
4375 }
4376
4377 /* Generate a pile of unique, random routes */
4378 if (random_add_del) {
4379 u32 this_random_address;
4380 random_hash = hash_create (count, sizeof(uword));
4381
4382 hash_set (random_hash, v4_next_hop_address.as_u32, 1);
4383 for (j = 0; j <= count; j++) {
4384 do {
4385 this_random_address = random_u32 (&random_seed);
4386 this_random_address =
4387 clib_host_to_net_u32 (this_random_address);
4388 } while (hash_get (random_hash, this_random_address));
4389 vec_add1 (random_vector, this_random_address);
4390 hash_set (random_hash, this_random_address, 1);
4391 }
4392 hash_free (random_hash);
4393 v4_dst_address.as_u32 = random_vector[0];
4394 }
4395
4396 if (count > 1) {
4397 /* Turn on async mode */
4398 vam->async_mode = 1;
4399 vam->async_errors = 0;
4400 before = vat_time_now(vam);
4401 }
4402
4403 for (j = 0; j < count; j++) {
4404 /* Construct the API message */
4405 M(IP_ADD_DEL_ROUTE, ip_add_del_route);
4406
4407 mp->next_hop_sw_if_index = ntohl (sw_if_index);
4408 mp->vrf_id = ntohl (vrf_id);
4409 if (resolve_attempts > 0) {
4410 mp->resolve_attempts = ntohl (resolve_attempts);
4411 mp->resolve_if_needed = 1;
4412 }
4413 mp->create_vrf_if_needed = create_vrf_if_needed;
4414
4415 mp->is_add = is_add;
4416 mp->is_drop = is_drop;
4417 mp->is_ipv6 = is_ipv6;
4418 mp->is_local = is_local;
4419 mp->is_classify = is_classify;
4420 mp->is_multipath = is_multipath;
4421 mp->not_last = not_last;
4422 mp->next_hop_weight = next_hop_weight;
4423 mp->dst_address_length = dst_address_length;
4424 mp->lookup_in_vrf = ntohl(lookup_in_vrf);
4425 mp->classify_table_index = ntohl(classify_table_index);
4426
4427 if (is_ipv6){
Damjan Marionf1213b82016-03-13 02:22:06 +01004428 clib_memcpy (mp->dst_address, &v6_dst_address, sizeof (v6_dst_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004429 if (next_hop_set)
Damjan Marionf1213b82016-03-13 02:22:06 +01004430 clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
Ed Warnickecb9cada2015-12-08 15:45:58 -07004431 sizeof (v6_next_hop_address));
4432 increment_v6_address (&v6_dst_address);
4433 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01004434 clib_memcpy (mp->dst_address, &v4_dst_address, sizeof (v4_dst_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004435 if (next_hop_set)
Damjan Marionf1213b82016-03-13 02:22:06 +01004436 clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
Ed Warnickecb9cada2015-12-08 15:45:58 -07004437 sizeof (v4_next_hop_address));
4438 if (random_add_del)
4439 v4_dst_address.as_u32 = random_vector[j+1];
4440 else
4441 increment_v4_address (&v4_dst_address);
4442 }
4443 /* send it... */
4444 S;
4445 }
4446
4447 /* When testing multiple add/del ops, use a control-ping to sync */
4448 if (count > 1) {
4449 vl_api_control_ping_t * mp;
4450 f64 after;
4451
4452 /* Shut off async mode */
4453 vam->async_mode = 0;
4454
4455 M(CONTROL_PING, control_ping);
4456 S;
4457
4458 timeout = vat_time_now(vam) + 1.0;
4459 while (vat_time_now (vam) < timeout)
4460 if (vam->result_ready == 1)
4461 goto out;
4462 vam->retval = -99;
4463
4464 out:
4465 if (vam->retval == -99)
4466 errmsg ("timeout\n");
4467
4468 if (vam->async_errors > 0) {
4469 errmsg ("%d asynchronous errors\n", vam->async_errors);
4470 vam->retval = -98;
4471 }
4472 vam->async_errors = 0;
4473 after = vat_time_now(vam);
4474
4475 fformat(vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
4476 count, after - before, count / (after - before));
4477 } else {
4478 /* Wait for a reply... */
4479 W;
4480 }
4481
4482 /* Return the good/bad news */
4483 return (vam->retval);
4484}
4485
4486static int api_proxy_arp_add_del (vat_main_t * vam)
4487{
4488 unformat_input_t * i = vam->input;
4489 vl_api_proxy_arp_add_del_t *mp;
4490 f64 timeout;
4491 u32 vrf_id = 0;
4492 u8 is_add = 1;
4493 ip4_address_t lo, hi;
4494 u8 range_set = 0;
4495
4496 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4497 if (unformat (i, "vrf %d", &vrf_id))
4498 ;
4499 else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
4500 unformat_ip4_address, &hi))
4501 range_set = 1;
4502 else if (unformat (i, "del"))
4503 is_add = 0;
4504 else {
4505 clib_warning ("parse error '%U'", format_unformat_error, i);
4506 return -99;
4507 }
4508 }
4509
4510 if (range_set == 0) {
4511 errmsg ("address range not set\n");
4512 return -99;
4513 }
4514
4515 M(PROXY_ARP_ADD_DEL, proxy_arp_add_del);
4516
4517 mp->vrf_id = ntohl(vrf_id);
4518 mp->is_add = is_add;
Damjan Marionf1213b82016-03-13 02:22:06 +01004519 clib_memcpy(mp->low_address, &lo, sizeof (mp->low_address));
4520 clib_memcpy(mp->hi_address, &hi, sizeof (mp->hi_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004521
4522 S; W;
4523 /* NOTREACHED */
4524 return 0;
4525}
4526
4527static int api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
4528{
4529 unformat_input_t * i = vam->input;
4530 vl_api_proxy_arp_intfc_enable_disable_t *mp;
4531 f64 timeout;
4532 u32 sw_if_index;
4533 u8 enable = 1;
4534 u8 sw_if_index_set = 0;
4535
4536 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4537 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4538 sw_if_index_set = 1;
4539 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4540 sw_if_index_set = 1;
4541 else if (unformat (i, "enable"))
4542 enable = 1;
4543 else if (unformat (i, "disable"))
4544 enable = 0;
4545 else {
4546 clib_warning ("parse error '%U'", format_unformat_error, i);
4547 return -99;
4548 }
4549 }
4550
4551 if (sw_if_index_set == 0) {
4552 errmsg ("missing interface name or sw_if_index\n");
4553 return -99;
4554 }
4555
4556 M(PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
4557
4558 mp->sw_if_index = ntohl(sw_if_index);
4559 mp->enable_disable = enable;
4560
4561 S; W;
4562 /* NOTREACHED */
4563 return 0;
4564}
4565
4566static int api_mpls_add_del_decap (vat_main_t * vam)
4567{
4568 unformat_input_t * i = vam->input;
4569 vl_api_mpls_add_del_decap_t *mp;
4570 f64 timeout;
4571 u32 rx_vrf_id = 0;
4572 u32 tx_vrf_id = 0;
4573 u32 label = 0;
4574 u8 is_add = 1;
4575 u8 s_bit = 1;
4576 u32 next_index = 1;
4577
4578 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4579 if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
4580 ;
4581 else if (unformat (i, "tx_vrf_id %d", &tx_vrf_id))
4582 ;
4583 else if (unformat (i, "label %d", &label))
4584 ;
4585 else if (unformat (i, "next-index %d", &next_index))
4586 ;
4587 else if (unformat (i, "del"))
4588 is_add = 0;
4589 else if (unformat (i, "s-bit-clear"))
4590 s_bit = 0;
4591 else {
4592 clib_warning ("parse error '%U'", format_unformat_error, i);
4593 return -99;
4594 }
4595 }
4596
4597 M(MPLS_ADD_DEL_DECAP, mpls_add_del_decap);
4598
4599 mp->rx_vrf_id = ntohl(rx_vrf_id);
4600 mp->tx_vrf_id = ntohl(tx_vrf_id);
4601 mp->label = ntohl(label);
4602 mp->next_index = ntohl(next_index);
4603 mp->s_bit = s_bit;
4604 mp->is_add = is_add;
4605
4606 S; W;
4607 /* NOTREACHED */
4608 return 0;
4609}
4610
4611static int api_mpls_add_del_encap (vat_main_t * vam)
4612{
4613 unformat_input_t * i = vam->input;
4614 vl_api_mpls_add_del_encap_t *mp;
4615 f64 timeout;
4616 u32 vrf_id = 0;
4617 u32 *labels = 0;
4618 u32 label;
4619 ip4_address_t dst_address;
4620 u8 is_add = 1;
4621
4622 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4623 if (unformat (i, "vrf %d", &vrf_id))
4624 ;
4625 else if (unformat (i, "label %d", &label))
4626 vec_add1 (labels, ntohl(label));
4627 else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
4628 ;
4629 else if (unformat (i, "del"))
4630 is_add = 0;
4631 else {
4632 clib_warning ("parse error '%U'", format_unformat_error, i);
4633 return -99;
4634 }
4635 }
4636
4637 if (vec_len (labels) == 0) {
4638 errmsg ("missing encap label stack\n");
4639 return -99;
4640 }
4641
4642 M2(MPLS_ADD_DEL_ENCAP, mpls_add_del_encap,
4643 sizeof (u32) * vec_len (labels));
4644
4645 mp->vrf_id = ntohl(vrf_id);
Damjan Marionf1213b82016-03-13 02:22:06 +01004646 clib_memcpy(mp->dst_address, &dst_address, sizeof (dst_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004647 mp->is_add = is_add;
4648 mp->nlabels = vec_len (labels);
Damjan Marionf1213b82016-03-13 02:22:06 +01004649 clib_memcpy(mp->labels, labels, sizeof(u32)*mp->nlabels);
Ed Warnickecb9cada2015-12-08 15:45:58 -07004650
4651 vec_free(labels);
4652
4653 S; W;
4654 /* NOTREACHED */
4655 return 0;
4656}
4657
4658static int api_mpls_gre_add_del_tunnel (vat_main_t * vam)
4659{
4660 unformat_input_t * i = vam->input;
4661 vl_api_mpls_gre_add_del_tunnel_t *mp;
4662 f64 timeout;
4663 u32 inner_vrf_id = 0;
4664 u32 outer_vrf_id = 0;
4665 ip4_address_t src_address;
4666 ip4_address_t dst_address;
4667 ip4_address_t intfc_address;
4668 u32 tmp;
4669 u8 intfc_address_length = 0;
4670 u8 is_add = 1;
4671 u8 l2_only = 0;
4672
4673 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4674 if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
4675 ;
4676 else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
4677 ;
4678 else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
4679 ;
4680 else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
4681 ;
4682 else if (unformat (i, "adj %U/%d", unformat_ip4_address,
4683 &intfc_address, &tmp))
4684 intfc_address_length = tmp;
4685 else if (unformat (i, "l2-only"))
4686 l2_only = 1;
4687 else if (unformat (i, "del"))
4688 is_add = 0;
4689 else {
4690 clib_warning ("parse error '%U'", format_unformat_error, i);
4691 return -99;
4692 }
4693 }
4694
4695 M(MPLS_GRE_ADD_DEL_TUNNEL, mpls_gre_add_del_tunnel);
4696
4697 mp->inner_vrf_id = ntohl(inner_vrf_id);
4698 mp->outer_vrf_id = ntohl(outer_vrf_id);
Damjan Marionf1213b82016-03-13 02:22:06 +01004699 clib_memcpy(mp->src_address, &src_address, sizeof (src_address));
4700 clib_memcpy(mp->dst_address, &dst_address, sizeof (dst_address));
4701 clib_memcpy(mp->intfc_address, &intfc_address, sizeof (intfc_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004702 mp->intfc_address_length = intfc_address_length;
4703 mp->l2_only = l2_only;
4704 mp->is_add = is_add;
4705
4706 S; W;
4707 /* NOTREACHED */
4708 return 0;
4709}
4710
4711static int api_mpls_ethernet_add_del_tunnel (vat_main_t * vam)
4712{
4713 unformat_input_t * i = vam->input;
4714 vl_api_mpls_ethernet_add_del_tunnel_t *mp;
4715 f64 timeout;
4716 u32 inner_vrf_id = 0;
4717 ip4_address_t intfc_address;
4718 u8 dst_mac_address[6];
4719 int dst_set = 1;
4720 u32 tmp;
4721 u8 intfc_address_length = 0;
4722 u8 is_add = 1;
4723 u8 l2_only = 0;
4724 u32 tx_sw_if_index;
4725 int tx_sw_if_index_set = 0;
4726
4727 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4728 if (unformat (i, "vrf %d", &inner_vrf_id))
4729 ;
4730 else if (unformat (i, "adj %U/%d", unformat_ip4_address,
4731 &intfc_address, &tmp))
4732 intfc_address_length = tmp;
4733 else if (unformat (i, "%U",
4734 unformat_sw_if_index, vam, &tx_sw_if_index))
4735 tx_sw_if_index_set = 1;
4736 else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
4737 tx_sw_if_index_set = 1;
4738 else if (unformat (i, "dst %U", unformat_ethernet_address,
4739 dst_mac_address))
4740 dst_set = 1;
4741 else if (unformat (i, "l2-only"))
4742 l2_only = 1;
4743 else if (unformat (i, "del"))
4744 is_add = 0;
4745 else {
4746 clib_warning ("parse error '%U'", format_unformat_error, i);
4747 return -99;
4748 }
4749 }
4750
4751 if (!dst_set) {
4752 errmsg ("dst (mac address) not set\n");
4753 return -99;
4754 }
4755 if (!tx_sw_if_index_set) {
4756 errmsg ("tx-intfc not set\n");
4757 return -99;
4758 }
4759
4760 M(MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel);
4761
4762 mp->vrf_id = ntohl(inner_vrf_id);
Damjan Marionf1213b82016-03-13 02:22:06 +01004763 clib_memcpy (mp->adj_address, &intfc_address, sizeof (intfc_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004764 mp->adj_address_length = intfc_address_length;
Damjan Marionf1213b82016-03-13 02:22:06 +01004765 clib_memcpy (mp->dst_mac_address, dst_mac_address, sizeof (dst_mac_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004766 mp->tx_sw_if_index = ntohl(tx_sw_if_index);
4767 mp->l2_only = l2_only;
4768 mp->is_add = is_add;
4769
4770 S; W;
4771 /* NOTREACHED */
4772 return 0;
4773}
4774
4775static int api_mpls_ethernet_add_del_tunnel_2 (vat_main_t * vam)
4776{
4777 unformat_input_t * i = vam->input;
4778 vl_api_mpls_ethernet_add_del_tunnel_2_t *mp;
4779 f64 timeout;
4780 u32 inner_vrf_id = 0;
4781 u32 outer_vrf_id = 0;
4782 ip4_address_t adj_address;
4783 int adj_address_set = 0;
4784 ip4_address_t next_hop_address;
4785 int next_hop_address_set = 0;
4786 u32 tmp;
4787 u8 adj_address_length = 0;
4788 u8 l2_only = 0;
4789 u8 is_add = 1;
4790 u32 resolve_attempts = 5;
4791 u8 resolve_if_needed = 1;
4792
4793 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4794 if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
4795 ;
4796 else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
4797 ;
4798 else if (unformat (i, "adj %U/%d", unformat_ip4_address,
4799 &adj_address, &tmp)) {
4800 adj_address_length = tmp;
4801 adj_address_set = 1;
4802 }
4803 else if (unformat (i, "next-hop %U", unformat_ip4_address,
4804 &next_hop_address))
4805 next_hop_address_set = 1;
4806 else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
4807 ;
4808 else if (unformat (i, "resolve-if-needed %d", &tmp))
4809 resolve_if_needed = tmp;
4810 else if (unformat (i, "l2-only"))
4811 l2_only = 1;
4812 else if (unformat (i, "del"))
4813 is_add = 0;
4814 else {
4815 clib_warning ("parse error '%U'", format_unformat_error, i);
4816 return -99;
4817 }
4818 }
4819
4820 if (!adj_address_set) {
4821 errmsg ("adjacency address/mask not set\n");
4822 return -99;
4823 }
4824 if (!next_hop_address_set) {
4825 errmsg ("ip4 next hop address (in outer fib) not set\n");
4826 return -99;
4827 }
4828
4829 M(MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2);
4830
4831 mp->inner_vrf_id = ntohl(inner_vrf_id);
4832 mp->outer_vrf_id = ntohl(outer_vrf_id);
4833 mp->resolve_attempts = ntohl(resolve_attempts);
4834 mp->resolve_if_needed = resolve_if_needed;
4835 mp->is_add = is_add;
4836 mp->l2_only = l2_only;
Damjan Marionf1213b82016-03-13 02:22:06 +01004837 clib_memcpy (mp->adj_address, &adj_address, sizeof (adj_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004838 mp->adj_address_length = adj_address_length;
Damjan Marionf1213b82016-03-13 02:22:06 +01004839 clib_memcpy (mp->next_hop_ip4_address_in_outer_vrf, &next_hop_address,
Ed Warnickecb9cada2015-12-08 15:45:58 -07004840 sizeof (next_hop_address));
4841
4842 S; W;
4843 /* NOTREACHED */
4844 return 0;
4845}
4846
4847static int api_sw_interface_set_unnumbered (vat_main_t * vam)
4848{
4849 unformat_input_t * i = vam->input;
4850 vl_api_sw_interface_set_unnumbered_t *mp;
4851 f64 timeout;
4852 u32 sw_if_index;
4853 u32 unnum_sw_index;
4854 u8 is_add = 1;
4855 u8 sw_if_index_set = 0;
4856
4857 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4858 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4859 sw_if_index_set = 1;
4860 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4861 sw_if_index_set = 1;
4862 else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
4863 ;
4864 else if (unformat (i, "del"))
4865 is_add = 0;
4866 else {
4867 clib_warning ("parse error '%U'", format_unformat_error, i);
4868 return -99;
4869 }
4870 }
4871
4872 if (sw_if_index_set == 0) {
4873 errmsg ("missing interface name or sw_if_index\n");
4874 return -99;
4875 }
4876
4877 M(SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
4878
4879 mp->sw_if_index = ntohl(sw_if_index);
4880 mp->unnumbered_sw_if_index = ntohl(unnum_sw_index);
4881 mp->is_add = is_add;
4882
4883 S; W;
4884 /* NOTREACHED */
4885 return 0;
4886}
4887
4888static int api_ip_neighbor_add_del (vat_main_t * vam)
4889{
4890 unformat_input_t * i = vam->input;
4891 vl_api_ip_neighbor_add_del_t *mp;
4892 f64 timeout;
4893 u32 sw_if_index;
4894 u8 sw_if_index_set = 0;
4895 u32 vrf_id = 0;
4896 u8 is_add = 1;
4897 u8 is_static = 0;
4898 u8 mac_address[6];
4899 u8 mac_set = 0;
4900 u8 v4_address_set = 0;
4901 u8 v6_address_set = 0;
4902 ip4_address_t v4address;
4903 ip6_address_t v6address;
4904
4905 memset (mac_address, 0, sizeof (mac_address));
4906
4907 /* Parse args required to build the message */
4908 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4909 if (unformat (i, "mac %U", unformat_ethernet_address, mac_address)) {
4910 mac_set = 1;
4911 }
4912 else if (unformat (i, "del"))
4913 is_add = 0;
4914 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4915 sw_if_index_set = 1;
4916 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4917 sw_if_index_set = 1;
4918 else if (unformat (i, "is_static"))
4919 is_static = 1;
4920 else if (unformat (i, "vrf %d", &vrf_id))
4921 ;
4922 else if (unformat (i, "dst %U",
4923 unformat_ip4_address, &v4address))
4924 v4_address_set = 1;
4925 else if (unformat (i, "dst %U",
4926 unformat_ip6_address, &v6address))
4927 v6_address_set = 1;
4928 else {
4929 clib_warning ("parse error '%U'", format_unformat_error, i);
4930 return -99;
4931 }
4932 }
4933
4934 if (sw_if_index_set == 0) {
4935 errmsg ("missing interface name or sw_if_index\n");
4936 return -99;
4937 }
4938 if (v4_address_set && v6_address_set) {
4939 errmsg ("both v4 and v6 addresses set\n");
4940 return -99;
4941 }
4942 if (!v4_address_set && !v6_address_set) {
4943 errmsg ("no addresses set\n");
4944 return -99;
4945 }
4946
4947 /* Construct the API message */
4948 M(IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
4949
4950 mp->sw_if_index = ntohl (sw_if_index);
4951 mp->is_add = is_add;
4952 mp->vrf_id = ntohl (vrf_id);
4953 mp->is_static = is_static;
4954 if (mac_set)
Damjan Marionf1213b82016-03-13 02:22:06 +01004955 clib_memcpy (mp->mac_address, mac_address, 6);
Ed Warnickecb9cada2015-12-08 15:45:58 -07004956 if (v6_address_set) {
4957 mp->is_ipv6 = 1;
Damjan Marionf1213b82016-03-13 02:22:06 +01004958 clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004959 } else {
4960 /* mp->is_ipv6 = 0; via memset in M macro above */
Damjan Marionf1213b82016-03-13 02:22:06 +01004961 clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004962 }
4963
4964 /* send it... */
4965 S;
4966
4967 /* Wait for a reply, return good/bad news */
4968 W;
4969
4970 /* NOTREACHED */
4971 return 0;
4972}
4973
4974static int api_reset_vrf (vat_main_t * vam)
4975{
4976 unformat_input_t * i = vam->input;
4977 vl_api_reset_vrf_t *mp;
4978 f64 timeout;
4979 u32 vrf_id = 0;
4980 u8 is_ipv6 = 0;
4981 u8 vrf_id_set = 0;
4982
4983 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4984 if (unformat (i, "vrf %d", &vrf_id))
4985 vrf_id_set = 1;
4986 else if (unformat (i, "ipv6"))
4987 is_ipv6 = 1;
4988 else {
4989 clib_warning ("parse error '%U'", format_unformat_error, i);
4990 return -99;
4991 }
4992 }
4993
4994 if (vrf_id_set == 0) {
4995 errmsg ("missing vrf id\n");
4996 return -99;
4997 }
4998
4999 M(RESET_VRF, reset_vrf);
5000
5001 mp->vrf_id = ntohl(vrf_id);
5002 mp->is_ipv6 = is_ipv6;
5003
5004 S; W;
5005 /* NOTREACHED */
5006 return 0;
5007}
5008
5009static int api_create_vlan_subif (vat_main_t * vam)
5010{
5011 unformat_input_t * i = vam->input;
5012 vl_api_create_vlan_subif_t *mp;
5013 f64 timeout;
5014 u32 sw_if_index;
5015 u8 sw_if_index_set = 0;
5016 u32 vlan_id;
5017 u8 vlan_id_set = 0;
5018
5019 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5020 if (unformat (i, "sw_if_index %d", &sw_if_index))
5021 sw_if_index_set = 1;
5022 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5023 sw_if_index_set = 1;
5024 else if (unformat (i, "vlan %d", &vlan_id))
5025 vlan_id_set = 1;
5026 else {
5027 clib_warning ("parse error '%U'", format_unformat_error, i);
5028 return -99;
5029 }
5030 }
5031
5032 if (sw_if_index_set == 0) {
5033 errmsg ("missing interface name or sw_if_index\n");
5034 return -99;
5035 }
5036
5037 if (vlan_id_set == 0) {
5038 errmsg ("missing vlan_id\n");
5039 return -99;
5040 }
5041 M(CREATE_VLAN_SUBIF, create_vlan_subif);
5042
5043 mp->sw_if_index = ntohl(sw_if_index);
5044 mp->vlan_id = ntohl(vlan_id);
5045
5046 S; W;
5047 /* NOTREACHED */
5048 return 0;
5049}
5050
5051#define foreach_create_subif_bit \
5052_(no_tags) \
5053_(one_tag) \
5054_(two_tags) \
5055_(dot1ad) \
5056_(exact_match) \
5057_(default_sub) \
5058_(outer_vlan_id_any) \
5059_(inner_vlan_id_any)
5060
5061static int api_create_subif (vat_main_t * vam)
5062{
5063 unformat_input_t * i = vam->input;
5064 vl_api_create_subif_t *mp;
5065 f64 timeout;
5066 u32 sw_if_index;
5067 u8 sw_if_index_set = 0;
5068 u32 sub_id;
5069 u8 sub_id_set = 0;
5070 u32 no_tags = 0;
5071 u32 one_tag = 0;
5072 u32 two_tags = 0;
5073 u32 dot1ad = 0;
5074 u32 exact_match = 0;
5075 u32 default_sub = 0;
5076 u32 outer_vlan_id_any = 0;
5077 u32 inner_vlan_id_any = 0;
5078 u32 tmp;
5079 u16 outer_vlan_id = 0;
5080 u16 inner_vlan_id = 0;
5081
5082 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5083 if (unformat (i, "sw_if_index %d", &sw_if_index))
5084 sw_if_index_set = 1;
5085 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5086 sw_if_index_set = 1;
5087 else if (unformat (i, "sub_id %d", &sub_id))
5088 sub_id_set = 1;
5089 else if (unformat (i, "outer_vlan_id %d", &tmp))
5090 outer_vlan_id = tmp;
5091 else if (unformat (i, "inner_vlan_id %d", &tmp))
5092 inner_vlan_id = tmp;
5093
5094#define _(a) else if (unformat (i, #a)) a = 1 ;
5095 foreach_create_subif_bit
5096#undef _
5097
5098 else {
5099 clib_warning ("parse error '%U'", format_unformat_error, i);
5100 return -99;
5101 }
5102 }
5103
5104 if (sw_if_index_set == 0) {
5105 errmsg ("missing interface name or sw_if_index\n");
5106 return -99;
5107 }
5108
5109 if (sub_id_set == 0) {
5110 errmsg ("missing sub_id\n");
5111 return -99;
5112 }
5113 M(CREATE_SUBIF, create_subif);
5114
5115 mp->sw_if_index = ntohl(sw_if_index);
5116 mp->sub_id = ntohl(sub_id);
5117
5118#define _(a) mp->a = a;
5119 foreach_create_subif_bit;
5120#undef _
5121
5122 mp->outer_vlan_id = ntohs (outer_vlan_id);
5123 mp->inner_vlan_id = ntohs (inner_vlan_id);
5124
5125 S; W;
5126 /* NOTREACHED */
5127 return 0;
5128}
5129
5130static int api_oam_add_del (vat_main_t * vam)
5131{
5132 unformat_input_t * i = vam->input;
5133 vl_api_oam_add_del_t *mp;
5134 f64 timeout;
5135 u32 vrf_id = 0;
5136 u8 is_add = 1;
5137 ip4_address_t src, dst;
5138 u8 src_set = 0;
5139 u8 dst_set = 0;
5140
5141 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5142 if (unformat (i, "vrf %d", &vrf_id))
5143 ;
5144 else if (unformat (i, "src %U", unformat_ip4_address, &src))
5145 src_set = 1;
5146 else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
5147 dst_set = 1;
5148 else if (unformat (i, "del"))
5149 is_add = 0;
5150 else {
5151 clib_warning ("parse error '%U'", format_unformat_error, i);
5152 return -99;
5153 }
5154 }
5155
5156 if (src_set == 0) {
5157 errmsg ("missing src addr\n");
5158 return -99;
5159 }
5160
5161 if (dst_set == 0) {
5162 errmsg ("missing dst addr\n");
5163 return -99;
5164 }
5165
5166 M(OAM_ADD_DEL, oam_add_del);
5167
5168 mp->vrf_id = ntohl(vrf_id);
5169 mp->is_add = is_add;
Damjan Marionf1213b82016-03-13 02:22:06 +01005170 clib_memcpy(mp->src_address, &src, sizeof (mp->src_address));
5171 clib_memcpy(mp->dst_address, &dst, sizeof (mp->dst_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005172
5173 S; W;
5174 /* NOTREACHED */
5175 return 0;
5176}
5177
5178static int api_reset_fib (vat_main_t * vam)
5179{
5180 unformat_input_t * i = vam->input;
5181 vl_api_reset_fib_t *mp;
5182 f64 timeout;
5183 u32 vrf_id = 0;
5184 u8 is_ipv6 = 0;
5185 u8 vrf_id_set = 0;
5186
5187 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5188 if (unformat (i, "vrf %d", &vrf_id))
5189 vrf_id_set = 1;
5190 else if (unformat (i, "ipv6"))
5191 is_ipv6 = 1;
5192 else {
5193 clib_warning ("parse error '%U'", format_unformat_error, i);
5194 return -99;
5195 }
5196 }
5197
5198 if (vrf_id_set == 0) {
5199 errmsg ("missing vrf id\n");
5200 return -99;
5201 }
5202
5203 M(RESET_FIB, reset_fib);
5204
5205 mp->vrf_id = ntohl(vrf_id);
5206 mp->is_ipv6 = is_ipv6;
5207
5208 S; W;
5209 /* NOTREACHED */
5210 return 0;
5211}
5212
5213static int api_dhcp_proxy_config (vat_main_t * vam)
5214{
5215 unformat_input_t * i = vam->input;
5216 vl_api_dhcp_proxy_config_t *mp;
5217 f64 timeout;
5218 u32 vrf_id = 0;
5219 u8 is_add = 1;
5220 u8 insert_cid = 1;
5221 u8 v4_address_set = 0;
5222 u8 v6_address_set = 0;
5223 ip4_address_t v4address;
5224 ip6_address_t v6address;
5225 u8 v4_src_address_set = 0;
5226 u8 v6_src_address_set = 0;
5227 ip4_address_t v4srcaddress;
5228 ip6_address_t v6srcaddress;
5229
5230 /* Parse args required to build the message */
5231 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5232 if (unformat (i, "del"))
5233 is_add = 0;
5234 else if (unformat (i, "vrf %d", &vrf_id))
5235 ;
5236 else if (unformat (i, "insert-cid %d", &insert_cid))
5237 ;
5238 else if (unformat (i, "svr %U",
5239 unformat_ip4_address, &v4address))
5240 v4_address_set = 1;
5241 else if (unformat (i, "svr %U",
5242 unformat_ip6_address, &v6address))
5243 v6_address_set = 1;
5244 else if (unformat (i, "src %U",
5245 unformat_ip4_address, &v4srcaddress))
5246 v4_src_address_set = 1;
5247 else if (unformat (i, "src %U",
5248 unformat_ip6_address, &v6srcaddress))
5249 v6_src_address_set = 1;
5250 else
5251 break;
5252 }
5253
5254 if (v4_address_set && v6_address_set) {
5255 errmsg ("both v4 and v6 server addresses set\n");
5256 return -99;
5257 }
5258 if (!v4_address_set && !v6_address_set) {
5259 errmsg ("no server addresses set\n");
5260 return -99;
5261 }
5262
5263 if (v4_src_address_set && v6_src_address_set) {
5264 errmsg ("both v4 and v6 src addresses set\n");
5265 return -99;
5266 }
5267 if (!v4_src_address_set && !v6_src_address_set) {
5268 errmsg ("no src addresses set\n");
5269 return -99;
5270 }
5271
5272 if (!(v4_src_address_set && v4_address_set) &&
5273 !(v6_src_address_set && v6_address_set)) {
5274 errmsg ("no matching server and src addresses set\n");
5275 return -99;
5276 }
5277
5278 /* Construct the API message */
5279 M(DHCP_PROXY_CONFIG, dhcp_proxy_config);
5280
5281 mp->insert_circuit_id = insert_cid;
5282 mp->is_add = is_add;
5283 mp->vrf_id = ntohl (vrf_id);
5284 if (v6_address_set) {
5285 mp->is_ipv6 = 1;
Damjan Marionf1213b82016-03-13 02:22:06 +01005286 clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
5287 clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005288 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01005289 clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
5290 clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005291 }
5292
5293 /* send it... */
5294 S;
5295
5296 /* Wait for a reply, return good/bad news */
5297 W;
5298 /* NOTREACHED */
5299 return 0;
5300}
5301
5302static int api_dhcp_proxy_config_2 (vat_main_t * vam)
5303{
5304 unformat_input_t * i = vam->input;
5305 vl_api_dhcp_proxy_config_2_t *mp;
5306 f64 timeout;
5307 u32 rx_vrf_id = 0;
5308 u32 server_vrf_id = 0;
5309 u8 is_add = 1;
5310 u8 insert_cid = 1;
5311 u8 v4_address_set = 0;
5312 u8 v6_address_set = 0;
5313 ip4_address_t v4address;
5314 ip6_address_t v6address;
5315 u8 v4_src_address_set = 0;
5316 u8 v6_src_address_set = 0;
5317 ip4_address_t v4srcaddress;
5318 ip6_address_t v6srcaddress;
5319
5320 /* Parse args required to build the message */
5321 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5322 if (unformat (i, "del"))
5323 is_add = 0;
5324 else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
5325 ;
5326 else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
5327 ;
5328 else if (unformat (i, "insert-cid %d", &insert_cid))
5329 ;
5330 else if (unformat (i, "svr %U",
5331 unformat_ip4_address, &v4address))
5332 v4_address_set = 1;
5333 else if (unformat (i, "svr %U",
5334 unformat_ip6_address, &v6address))
5335 v6_address_set = 1;
5336 else if (unformat (i, "src %U",
5337 unformat_ip4_address, &v4srcaddress))
5338 v4_src_address_set = 1;
5339 else if (unformat (i, "src %U",
5340 unformat_ip6_address, &v6srcaddress))
5341 v6_src_address_set = 1;
5342 else
5343 break;
5344 }
5345
5346 if (v4_address_set && v6_address_set) {
5347 errmsg ("both v4 and v6 server addresses set\n");
5348 return -99;
5349 }
5350 if (!v4_address_set && !v6_address_set) {
5351 errmsg ("no server addresses set\n");
5352 return -99;
5353 }
5354
5355 if (v4_src_address_set && v6_src_address_set) {
5356 errmsg ("both v4 and v6 src addresses set\n");
5357 return -99;
5358 }
5359 if (!v4_src_address_set && !v6_src_address_set) {
5360 errmsg ("no src addresses set\n");
5361 return -99;
5362 }
5363
5364 if (!(v4_src_address_set && v4_address_set) &&
5365 !(v6_src_address_set && v6_address_set)) {
5366 errmsg ("no matching server and src addresses set\n");
5367 return -99;
5368 }
5369
5370 /* Construct the API message */
5371 M(DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
5372
5373 mp->insert_circuit_id = insert_cid;
5374 mp->is_add = is_add;
5375 mp->rx_vrf_id = ntohl (rx_vrf_id);
5376 mp->server_vrf_id = ntohl (server_vrf_id);
5377 if (v6_address_set) {
5378 mp->is_ipv6 = 1;
Damjan Marionf1213b82016-03-13 02:22:06 +01005379 clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
5380 clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005381 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01005382 clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
5383 clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005384 }
5385
5386 /* send it... */
5387 S;
5388
5389 /* Wait for a reply, return good/bad news */
5390 W;
5391 /* NOTREACHED */
5392 return 0;
5393}
5394
5395static int api_dhcp_proxy_set_vss (vat_main_t * vam)
5396{
5397 unformat_input_t * i = vam->input;
5398 vl_api_dhcp_proxy_set_vss_t *mp;
5399 f64 timeout;
5400 u8 is_ipv6 = 0;
5401 u8 is_add = 1;
5402 u32 tbl_id;
5403 u8 tbl_id_set = 0;
5404 u32 oui;
5405 u8 oui_set = 0;
5406 u32 fib_id;
5407 u8 fib_id_set = 0;
5408
5409 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5410 if (unformat (i, "tbl_id %d", &tbl_id))
5411 tbl_id_set = 1;
5412 if (unformat (i, "fib_id %d", &fib_id))
5413 fib_id_set = 1;
5414 if (unformat (i, "oui %d", &oui))
5415 oui_set = 1;
5416 else if (unformat (i, "ipv6"))
5417 is_ipv6 = 1;
5418 else if (unformat (i, "del"))
5419 is_add = 0;
5420 else {
5421 clib_warning ("parse error '%U'", format_unformat_error, i);
5422 return -99;
5423 }
5424 }
5425
5426 if (tbl_id_set == 0) {
5427 errmsg ("missing tbl id\n");
5428 return -99;
5429 }
5430
5431 if (fib_id_set == 0) {
5432 errmsg ("missing fib id\n");
5433 return -99;
5434 }
5435 if (oui_set == 0) {
5436 errmsg ("missing oui\n");
5437 return -99;
5438 }
5439
5440 M(DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
5441 mp->tbl_id = ntohl(tbl_id);
5442 mp->fib_id = ntohl(fib_id);
5443 mp->oui = ntohl(oui);
5444 mp->is_ipv6 = is_ipv6;
5445 mp->is_add = is_add;
5446
5447 S; W;
5448 /* NOTREACHED */
5449 return 0;
5450}
5451
5452static int api_dhcp_client_config (vat_main_t * vam)
5453{
5454 unformat_input_t * i = vam->input;
5455 vl_api_dhcp_client_config_t *mp;
5456 f64 timeout;
5457 u32 sw_if_index;
5458 u8 sw_if_index_set = 0;
5459 u8 is_add = 1;
5460 u8 * hostname = 0;
5461 u8 disable_event = 0;
5462
5463 /* Parse args required to build the message */
5464 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5465 if (unformat (i, "del"))
5466 is_add = 0;
5467 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5468 sw_if_index_set = 1;
5469 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5470 sw_if_index_set = 1;
5471 else if (unformat (i, "hostname %s", &hostname))
5472 ;
5473 else if (unformat (i, "disable_event"))
5474 disable_event = 1;
5475 else
5476 break;
5477 }
5478
5479 if (sw_if_index_set == 0) {
5480 errmsg ("missing interface name or sw_if_index\n");
5481 return -99;
5482 }
5483
5484 if (vec_len (hostname) > 63) {
5485 errmsg ("hostname too long\n");
5486 }
5487 vec_add1 (hostname, 0);
5488
5489 /* Construct the API message */
5490 M(DHCP_CLIENT_CONFIG, dhcp_client_config);
5491
5492 mp->sw_if_index = ntohl (sw_if_index);
Damjan Marionf1213b82016-03-13 02:22:06 +01005493 clib_memcpy (mp->hostname, hostname, vec_len (hostname));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005494 vec_free (hostname);
5495 mp->is_add = is_add;
5496 mp->want_dhcp_event = disable_event ? 0 : 1;
5497 mp->pid = getpid();
5498
5499 /* send it... */
5500 S;
5501
5502 /* Wait for a reply, return good/bad news */
5503 W;
5504 /* NOTREACHED */
5505 return 0;
5506}
5507
5508static int api_set_ip_flow_hash (vat_main_t * vam)
5509{
5510 unformat_input_t * i = vam->input;
5511 vl_api_set_ip_flow_hash_t *mp;
5512 f64 timeout;
5513 u32 vrf_id = 0;
5514 u8 is_ipv6 = 0;
5515 u8 vrf_id_set = 0;
5516 u8 src = 0;
5517 u8 dst = 0;
5518 u8 sport = 0;
5519 u8 dport = 0;
5520 u8 proto = 0;
5521 u8 reverse = 0;
5522
5523 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5524 if (unformat (i, "vrf %d", &vrf_id))
5525 vrf_id_set = 1;
5526 else if (unformat (i, "ipv6"))
5527 is_ipv6 = 1;
5528 else if (unformat (i, "src"))
5529 src = 1;
5530 else if (unformat (i, "dst"))
5531 dst = 1;
5532 else if (unformat (i, "sport"))
5533 sport = 1;
5534 else if (unformat (i, "dport"))
5535 dport = 1;
5536 else if (unformat (i, "proto"))
5537 proto = 1;
5538 else if (unformat (i, "reverse"))
5539 reverse = 1;
5540
5541 else {
5542 clib_warning ("parse error '%U'", format_unformat_error, i);
5543 return -99;
5544 }
5545 }
5546
5547 if (vrf_id_set == 0) {
5548 errmsg ("missing vrf id\n");
5549 return -99;
5550 }
5551
5552 M(SET_IP_FLOW_HASH, set_ip_flow_hash);
5553 mp->src = src;
5554 mp->dst = dst;
5555 mp->sport = sport;
5556 mp->dport = dport;
5557 mp->proto = proto;
5558 mp->reverse = reverse;
5559 mp->vrf_id = ntohl(vrf_id);
5560 mp->is_ipv6 = is_ipv6;
5561
5562 S; W;
5563 /* NOTREACHED */
5564 return 0;
5565}
5566
5567static int api_sw_interface_ip6_enable_disable (vat_main_t * vam)
5568{
5569 unformat_input_t * i = vam->input;
5570 vl_api_sw_interface_ip6_enable_disable_t *mp;
5571 f64 timeout;
5572 u32 sw_if_index;
5573 u8 sw_if_index_set = 0;
5574 u8 enable = 0;
5575
5576 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5577 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5578 sw_if_index_set = 1;
5579 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5580 sw_if_index_set = 1;
5581 else if (unformat (i, "enable"))
5582 enable = 1;
5583 else if (unformat (i, "disable"))
5584 enable = 0;
5585 else {
5586 clib_warning ("parse error '%U'", format_unformat_error, i);
5587 return -99;
5588 }
5589 }
5590
5591 if (sw_if_index_set == 0) {
5592 errmsg ("missing interface name or sw_if_index\n");
5593 return -99;
5594 }
5595
5596 M(SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
5597
5598 mp->sw_if_index = ntohl(sw_if_index);
5599 mp->enable = enable;
5600
5601 S; W;
5602 /* NOTREACHED */
5603 return 0;
5604}
5605
5606static int api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
5607{
5608 unformat_input_t * i = vam->input;
5609 vl_api_sw_interface_ip6_set_link_local_address_t *mp;
5610 f64 timeout;
5611 u32 sw_if_index;
5612 u8 sw_if_index_set = 0;
5613 u32 address_length = 0;
5614 u8 v6_address_set = 0;
5615 ip6_address_t v6address;
5616
5617 /* Parse args required to build the message */
5618 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5619 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5620 sw_if_index_set = 1;
5621 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5622 sw_if_index_set = 1;
5623 else if (unformat (i, "%U/%d",
5624 unformat_ip6_address, &v6address,
5625 &address_length))
5626 v6_address_set = 1;
5627 else
5628 break;
5629 }
5630
5631 if (sw_if_index_set == 0) {
5632 errmsg ("missing interface name or sw_if_index\n");
5633 return -99;
5634 }
5635 if (!v6_address_set) {
5636 errmsg ("no address set\n");
5637 return -99;
5638 }
5639
5640 /* Construct the API message */
5641 M(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, \
5642 sw_interface_ip6_set_link_local_address);
5643
5644 mp->sw_if_index = ntohl (sw_if_index);
Damjan Marionf1213b82016-03-13 02:22:06 +01005645 clib_memcpy (mp->address, &v6address, sizeof (v6address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005646 mp->address_length = address_length;
5647
5648 /* send it... */
5649 S;
5650
5651 /* Wait for a reply, return good/bad news */
5652 W;
5653
5654 /* NOTREACHED */
5655 return 0;
5656}
5657
5658
5659static int api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
5660{
5661 unformat_input_t * i = vam->input;
5662 vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
5663 f64 timeout;
5664 u32 sw_if_index;
5665 u8 sw_if_index_set = 0;
5666 u32 address_length = 0;
5667 u8 v6_address_set = 0;
5668 ip6_address_t v6address;
5669 u8 use_default = 0;
5670 u8 no_advertise = 0;
5671 u8 off_link = 0;
5672 u8 no_autoconfig = 0;
5673 u8 no_onlink = 0;
5674 u8 is_no = 0;
5675 u32 val_lifetime = 0;
5676 u32 pref_lifetime = 0;
5677
5678 /* Parse args required to build the message */
5679 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5680 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5681 sw_if_index_set = 1;
5682 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5683 sw_if_index_set = 1;
5684 else if (unformat (i, "%U/%d",
5685 unformat_ip6_address, &v6address,
5686 &address_length))
5687 v6_address_set = 1;
5688 else if (unformat (i, "val_life %d", &val_lifetime))
5689 ;
5690 else if (unformat (i, "pref_life %d", &pref_lifetime))
5691 ;
5692 else if (unformat (i, "def"))
5693 use_default = 1;
5694 else if (unformat (i, "noadv"))
5695 no_advertise = 1;
5696 else if (unformat (i, "offl"))
5697 off_link = 1;
5698 else if (unformat (i, "noauto"))
5699 no_autoconfig = 1;
5700 else if (unformat (i, "nolink"))
5701 no_onlink = 1;
5702 else if (unformat (i, "isno"))
5703 is_no = 1;
5704 else {
5705 clib_warning ("parse error '%U'", format_unformat_error, i);
5706 return -99;
5707 }
5708 }
5709
5710 if (sw_if_index_set == 0) {
5711 errmsg ("missing interface name or sw_if_index\n");
5712 return -99;
5713 }
5714 if (!v6_address_set) {
5715 errmsg ("no address set\n");
5716 return -99;
5717 }
5718
5719 /* Construct the API message */
5720 M(SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
5721
5722 mp->sw_if_index = ntohl (sw_if_index);
Damjan Marionf1213b82016-03-13 02:22:06 +01005723 clib_memcpy (mp->address, &v6address, sizeof (v6address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005724 mp->address_length = address_length;
5725 mp->use_default = use_default;
5726 mp->no_advertise = no_advertise;
5727 mp->off_link = off_link;
5728 mp->no_autoconfig = no_autoconfig;
5729 mp->no_onlink = no_onlink;
5730 mp->is_no = is_no;
5731 mp->val_lifetime = ntohl(val_lifetime);
5732 mp->pref_lifetime = ntohl(pref_lifetime);
5733
5734 /* send it... */
5735 S;
5736
5737 /* Wait for a reply, return good/bad news */
5738 W;
5739
5740 /* NOTREACHED */
5741 return 0;
5742}
5743
5744static int api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
5745{
5746 unformat_input_t * i = vam->input;
5747 vl_api_sw_interface_ip6nd_ra_config_t *mp;
5748 f64 timeout;
5749 u32 sw_if_index;
5750 u8 sw_if_index_set = 0;
Chris Luke33879c92016-06-28 19:54:21 -04005751 u8 suppress = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -07005752 u8 managed = 0;
5753 u8 other = 0;
5754 u8 ll_option = 0;
5755 u8 send_unicast = 0;
5756 u8 cease = 0;
5757 u8 is_no = 0;
5758 u8 default_router = 0;
5759 u32 max_interval = 0;
5760 u32 min_interval = 0;
5761 u32 lifetime = 0;
5762 u32 initial_count = 0;
5763 u32 initial_interval = 0;
5764
5765
5766 /* Parse args required to build the message */
5767 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5768 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5769 sw_if_index_set = 1;
5770 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5771 sw_if_index_set = 1;
5772 else if (unformat (i, "maxint %d", &max_interval))
5773 ;
5774 else if (unformat (i, "minint %d", &min_interval))
5775 ;
5776 else if (unformat (i, "life %d", &lifetime))
5777 ;
5778 else if (unformat (i, "count %d", &initial_count))
5779 ;
5780 else if (unformat (i, "interval %d", &initial_interval))
5781 ;
Chris Luke33879c92016-06-28 19:54:21 -04005782 else if (unformat (i, "suppress") || unformat (i, "surpress"))
5783 suppress = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -07005784 else if (unformat (i, "managed"))
5785 managed = 1;
5786 else if (unformat (i, "other"))
5787 other = 1;
5788 else if (unformat (i, "ll"))
5789 ll_option = 1;
5790 else if (unformat (i, "send"))
5791 send_unicast = 1;
5792 else if (unformat (i, "cease"))
5793 cease = 1;
5794 else if (unformat (i, "isno"))
5795 is_no = 1;
5796 else if (unformat (i, "def"))
5797 default_router = 1;
5798 else {
5799 clib_warning ("parse error '%U'", format_unformat_error, i);
5800 return -99;
5801 }
5802 }
5803
5804 if (sw_if_index_set == 0) {
5805 errmsg ("missing interface name or sw_if_index\n");
5806 return -99;
5807 }
5808
5809 /* Construct the API message */
5810 M(SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
5811
5812 mp->sw_if_index = ntohl (sw_if_index);
5813 mp->max_interval = ntohl(max_interval);
5814 mp->min_interval = ntohl(min_interval);
5815 mp->lifetime = ntohl(lifetime);
5816 mp->initial_count = ntohl(initial_count);
5817 mp->initial_interval = ntohl(initial_interval);
Chris Luke33879c92016-06-28 19:54:21 -04005818 mp->suppress = suppress;
Ed Warnickecb9cada2015-12-08 15:45:58 -07005819 mp->managed = managed;
5820 mp->other = other;
5821 mp->ll_option = ll_option;
5822 mp->send_unicast = send_unicast;
5823 mp->cease = cease;
5824 mp->is_no = is_no;
5825 mp->default_router = default_router;
5826
5827 /* send it... */
5828 S;
5829
5830 /* Wait for a reply, return good/bad news */
5831 W;
5832
5833 /* NOTREACHED */
5834 return 0;
5835}
5836
5837static int api_set_arp_neighbor_limit (vat_main_t * vam)
5838{
5839 unformat_input_t * i = vam->input;
5840 vl_api_set_arp_neighbor_limit_t *mp;
5841 f64 timeout;
5842 u32 arp_nbr_limit;
5843 u8 limit_set = 0;
5844 u8 is_ipv6 = 0;
5845
5846 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5847 if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
5848 limit_set = 1;
5849 else if (unformat (i, "ipv6"))
5850 is_ipv6 = 1;
5851 else {
5852 clib_warning ("parse error '%U'", format_unformat_error, i);
5853 return -99;
5854 }
5855 }
5856
5857 if (limit_set == 0) {
5858 errmsg ("missing limit value\n");
5859 return -99;
5860 }
5861
5862 M(SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
5863
5864 mp->arp_neighbor_limit = ntohl(arp_nbr_limit);
5865 mp->is_ipv6 = is_ipv6;
5866
5867 S; W;
5868 /* NOTREACHED */
5869 return 0;
5870}
5871
5872static int api_l2_patch_add_del (vat_main_t * vam)
5873{
5874 unformat_input_t * i = vam->input;
5875 vl_api_l2_patch_add_del_t *mp;
5876 f64 timeout;
5877 u32 rx_sw_if_index;
5878 u8 rx_sw_if_index_set = 0;
5879 u32 tx_sw_if_index;
5880 u8 tx_sw_if_index_set = 0;
5881 u8 is_add = 1;
5882
5883 /* Parse args required to build the message */
5884 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5885 if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5886 rx_sw_if_index_set = 1;
5887 else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5888 tx_sw_if_index_set = 1;
5889 else if (unformat (i, "rx")) {
5890 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5891 if (unformat (i, "%U", unformat_sw_if_index, vam,
5892 &rx_sw_if_index))
5893 rx_sw_if_index_set = 1;
5894 } else
5895 break;
5896 } else if (unformat (i, "tx")) {
5897 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5898 if (unformat (i, "%U", unformat_sw_if_index, vam,
5899 &tx_sw_if_index))
5900 tx_sw_if_index_set = 1;
5901 } else
5902 break;
5903 } else if (unformat (i, "del"))
5904 is_add = 0;
5905 else
5906 break;
5907 }
5908
5909 if (rx_sw_if_index_set == 0) {
5910 errmsg ("missing rx interface name or rx_sw_if_index\n");
5911 return -99;
5912 }
5913
5914 if (tx_sw_if_index_set == 0) {
5915 errmsg ("missing tx interface name or tx_sw_if_index\n");
5916 return -99;
5917 }
5918
5919 M(L2_PATCH_ADD_DEL, l2_patch_add_del);
5920
5921 mp->rx_sw_if_index = ntohl(rx_sw_if_index);
5922 mp->tx_sw_if_index = ntohl(tx_sw_if_index);
5923 mp->is_add = is_add;
5924
5925 S; W;
5926 /* NOTREACHED */
5927 return 0;
5928}
Shwetha20a64f52016-03-25 10:55:01 +00005929static int api_trace_profile_add (vat_main_t *vam)
5930{
5931 unformat_input_t * input = vam->input;
5932 vl_api_trace_profile_add_t *mp;
5933 f64 timeout;
5934 u32 id = 0;
5935 u32 trace_option_elts = 0;
5936 u32 trace_type = 0, node_id = 0, app_data = 0, trace_tsp = 2;
5937 int has_pow_option = 0;
5938 int has_ppc_option = 0;
5939
5940 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5941 {
5942 if (unformat (input, "id %d trace-type 0x%x trace-elts %d "
5943 "trace-tsp %d node-id 0x%x app-data 0x%x",
5944 &id, &trace_type, &trace_option_elts, &trace_tsp,
5945 &node_id, &app_data))
5946 ;
5947 else if (unformat (input, "pow"))
5948 has_pow_option = 1;
5949 else if (unformat (input, "ppc encap"))
5950 has_ppc_option = PPC_ENCAP;
5951 else if (unformat (input, "ppc decap"))
5952 has_ppc_option = PPC_DECAP;
5953 else if (unformat (input, "ppc none"))
5954 has_ppc_option = PPC_NONE;
5955 else
5956 break;
5957 }
5958 M(TRACE_PROFILE_ADD, trace_profile_add);
5959 mp->id = htons(id);
5960 mp->trace_type = trace_type;
5961 mp->trace_num_elt = trace_option_elts;
5962 mp->trace_ppc = has_ppc_option;
5963 mp->trace_app_data = htonl(app_data);
5964 mp->pow_enable = has_pow_option;
5965 mp->trace_tsp = trace_tsp;
5966 mp->node_id = htonl(node_id);
5967
5968 S; W;
5969
5970 return(0);
5971
5972}
5973static int api_trace_profile_apply (vat_main_t *vam)
5974{
5975 unformat_input_t * input = vam->input;
5976 vl_api_trace_profile_apply_t *mp;
5977 f64 timeout;
5978 ip6_address_t addr;
5979 u32 mask_width = ~0;
5980 int is_add = 0;
5981 int is_pop = 0;
5982 int is_none = 0;
5983 u32 vrf_id = 0;
5984 u32 id = 0;
5985
5986 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5987 {
5988 if (unformat (input, "%U/%d",
5989 unformat_ip6_address, &addr, &mask_width))
5990 ;
5991 else if (unformat (input, "id %d", &id))
5992 ;
5993 else if (unformat (input, "vrf-id %d", &vrf_id))
5994 ;
5995 else if (unformat (input, "add"))
5996 is_add = 1;
5997 else if (unformat (input, "pop"))
5998 is_pop = 1;
5999 else if (unformat (input, "none"))
6000 is_none = 1;
6001 else
6002 break;
6003 }
Ed Warnickecb9cada2015-12-08 15:45:58 -07006004
Shwetha20a64f52016-03-25 10:55:01 +00006005 if ((is_add + is_pop + is_none) != 1) {
6006 errmsg("One of (add, pop, none) required");
6007 return -99;
6008 }
6009 if (mask_width == ~0) {
6010 errmsg("<address>/<mask-width> required");
6011 return -99;
6012 }
6013 M(TRACE_PROFILE_APPLY, trace_profile_apply);
Damjan Marionf1213b82016-03-13 02:22:06 +01006014 clib_memcpy(mp->dest_ipv6, &addr, sizeof(mp->dest_ipv6));
Shwetha20a64f52016-03-25 10:55:01 +00006015 mp->id = htons(id);
6016 mp->prefix_length = htonl(mask_width);
6017 mp->vrf_id = htonl(vrf_id);
6018 if (is_add)
6019 mp->trace_op = IOAM_HBYH_ADD;
6020 else if (is_pop)
6021 mp->trace_op = IOAM_HBYH_POP;
6022 else
6023 mp->trace_op = IOAM_HBYH_MOD;
6024
6025 if(is_none)
6026 mp->enable = 0;
6027 else
6028 mp->enable = 1;
6029
6030 S; W;
6031
6032 return 0;
6033}
6034
6035static int api_trace_profile_del (vat_main_t *vam)
6036{
6037 vl_api_trace_profile_del_t *mp;
6038 f64 timeout;
6039
6040 M(TRACE_PROFILE_DEL, trace_profile_del);
6041 S; W;
6042 return 0;
6043}
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07006044
Ed Warnickecb9cada2015-12-08 15:45:58 -07006045static int api_sr_tunnel_add_del (vat_main_t * vam)
6046{
6047 unformat_input_t * i = vam->input;
6048 vl_api_sr_tunnel_add_del_t *mp;
6049 f64 timeout;
6050 int is_del = 0;
6051 int pl_index;
6052 ip6_address_t src_address;
6053 int src_address_set = 0;
6054 ip6_address_t dst_address;
6055 u32 dst_mask_width;
6056 int dst_address_set = 0;
6057 u16 flags = 0;
6058 u32 rx_table_id = 0;
6059 u32 tx_table_id = 0;
6060 ip6_address_t * segments = 0;
6061 ip6_address_t * this_seg;
6062 ip6_address_t * tags = 0;
6063 ip6_address_t * this_tag;
6064 ip6_address_t next_address, tag;
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07006065 u8 * name = 0;
6066 u8 * policy_name = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -07006067
6068 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6069 {
6070 if (unformat (i, "del"))
6071 is_del = 1;
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07006072 else if (unformat (i, "name %s", &name))
6073 ;
6074 else if (unformat (i, "policy %s", &policy_name))
6075 ;
Ed Warnickecb9cada2015-12-08 15:45:58 -07006076 else if (unformat (i, "rx_fib_id %d", &rx_table_id))
6077 ;
6078 else if (unformat (i, "tx_fib_id %d", &tx_table_id))
6079 ;
6080 else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
6081 src_address_set = 1;
6082 else if (unformat (i, "dst %U/%d",
6083 unformat_ip6_address, &dst_address,
6084 &dst_mask_width))
6085 dst_address_set = 1;
6086 else if (unformat (i, "next %U", unformat_ip6_address,
6087 &next_address))
6088 {
6089 vec_add2 (segments, this_seg, 1);
Damjan Marionf1213b82016-03-13 02:22:06 +01006090 clib_memcpy (this_seg->as_u8, next_address.as_u8, sizeof (*this_seg));
Ed Warnickecb9cada2015-12-08 15:45:58 -07006091 }
6092 else if (unformat (i, "tag %U", unformat_ip6_address,
6093 &tag))
6094 {
6095 vec_add2 (tags, this_tag, 1);
Damjan Marionf1213b82016-03-13 02:22:06 +01006096 clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
Ed Warnickecb9cada2015-12-08 15:45:58 -07006097 }
6098 else if (unformat (i, "clean"))
6099 flags |= IP6_SR_HEADER_FLAG_CLEANUP;
6100 else if (unformat (i, "protected"))
6101 flags |= IP6_SR_HEADER_FLAG_PROTECTED;
6102 else if (unformat (i, "InPE %d", &pl_index))
6103 {
6104 if (pl_index <= 0 || pl_index > 4)
6105 {
6106 pl_index_range_error:
6107 errmsg ("pl index %d out of range\n", pl_index);
6108 return -99;
6109 }
6110 flags |= IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3*(pl_index - 1));
6111 }
6112 else if (unformat (i, "EgPE %d", &pl_index))
6113 {
6114 if (pl_index <= 0 || pl_index > 4)
6115 goto pl_index_range_error;
6116 flags |= IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3*(pl_index - 1));
6117 }
6118 else if (unformat (i, "OrgSrc %d", &pl_index))
6119 {
6120 if (pl_index <= 0 || pl_index > 4)
6121 goto pl_index_range_error;
6122 flags |= IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3*(pl_index - 1));
6123 }
6124 else
6125 break;
6126 }
6127
6128 if (!src_address_set)
6129 {
6130 errmsg ("src address required\n");
6131 return -99;
6132 }
6133
6134 if (!dst_address_set)
6135 {
6136 errmsg ("dst address required\n");
6137 return -99;
6138 }
6139
6140 if (!segments)
6141 {
6142 errmsg ("at least one sr segment required\n");
6143 return -99;
6144 }
6145
6146 M2(SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
6147 vec_len(segments) * sizeof (ip6_address_t)
6148 + vec_len(tags) * sizeof (ip6_address_t));
6149
Damjan Marionf1213b82016-03-13 02:22:06 +01006150 clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
6151 clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07006152 mp->dst_mask_width = dst_mask_width;
6153 mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
6154 mp->n_segments = vec_len (segments);
6155 mp->n_tags = vec_len (tags);
6156 mp->is_add = is_del == 0;
Damjan Marionf1213b82016-03-13 02:22:06 +01006157 clib_memcpy (mp->segs_and_tags, segments,
Ed Warnickecb9cada2015-12-08 15:45:58 -07006158 vec_len(segments)* sizeof (ip6_address_t));
Damjan Marionf1213b82016-03-13 02:22:06 +01006159 clib_memcpy (mp->segs_and_tags + vec_len(segments)*sizeof (ip6_address_t),
Ed Warnickecb9cada2015-12-08 15:45:58 -07006160 tags, vec_len(tags)* sizeof (ip6_address_t));
6161
6162 mp->outer_vrf_id = ntohl (rx_table_id);
6163 mp->inner_vrf_id = ntohl (tx_table_id);
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07006164 memcpy (mp->name, name, vec_len(name));
6165 memcpy (mp->policy_name, policy_name, vec_len(policy_name));
Ed Warnickecb9cada2015-12-08 15:45:58 -07006166
6167 vec_free (segments);
6168 vec_free (tags);
6169
6170 S; W;
6171 /* NOTREACHED */
6172}
6173
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07006174static int api_sr_policy_add_del (vat_main_t * vam)
6175{
6176 unformat_input_t * input = vam->input;
6177 vl_api_sr_policy_add_del_t *mp;
6178 f64 timeout;
6179 int is_del = 0;
6180 u8 * name = 0;
6181 u8 * tunnel_name = 0;
6182 u8 ** tunnel_names = 0;
6183
6184 int name_set = 0 ;
6185 int tunnel_set = 0;
6186 int j = 0;
6187 int tunnel_names_length = 1; // Init to 1 to offset the #tunnel_names counter byte
6188 int tun_name_len = 0; // Different naming convention used as confusing these would be "bad" (TM)
6189
6190 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
6191 {
6192 if (unformat (input, "del"))
6193 is_del = 1;
6194 else if (unformat (input, "name %s", &name))
6195 name_set = 1;
6196 else if (unformat (input, "tunnel %s", &tunnel_name))
6197 {
6198 if (tunnel_name)
6199 {
6200 vec_add1 (tunnel_names, tunnel_name);
6201 /* For serializer:
6202 - length = #bytes to store in serial vector
6203 - +1 = byte to store that length
6204 */
6205 tunnel_names_length += (vec_len (tunnel_name) + 1);
6206 tunnel_set = 1;
6207 tunnel_name = 0;
6208 }
6209 }
6210 else
6211 break;
6212 }
6213
6214 if (!name_set)
6215 {
6216 errmsg ("policy name required\n");
6217 return -99;
6218 }
6219
6220 if ((!tunnel_set) && (!is_del))
6221 {
6222 errmsg ("tunnel name required\n");
6223 return -99;
6224 }
6225
6226 M2(SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
6227
6228
6229
6230 mp->is_add = !is_del;
6231
6232 memcpy (mp->name, name, vec_len(name));
6233 // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
6234 u8 * serial_orig = 0;
6235 vec_validate (serial_orig, tunnel_names_length);
6236 *serial_orig = vec_len(tunnel_names); // Store the number of tunnels as length in first byte of serialized vector
6237 serial_orig += 1; // Move along one byte to store the length of first tunnel_name
6238
6239 for (j=0; j < vec_len(tunnel_names); j++)
6240 {
6241 tun_name_len = vec_len (tunnel_names[j]);
6242 *serial_orig = tun_name_len; // Store length of tunnel name in first byte of Length/Value pair
6243 serial_orig += 1; // Move along one byte to store the actual tunnel name
6244 memcpy (serial_orig, tunnel_names[j], tun_name_len);
6245 serial_orig += tun_name_len; // Advance past the copy
6246 }
6247 memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length); // Regress serial_orig to head then copy fwd
6248
6249 vec_free (tunnel_names);
6250 vec_free (tunnel_name);
6251
6252 S; W;
6253 /* NOTREACHED */
6254}
6255
6256static int api_sr_multicast_map_add_del (vat_main_t * vam)
6257{
6258 unformat_input_t * input = vam->input;
6259 vl_api_sr_multicast_map_add_del_t *mp;
6260 f64 timeout;
6261 int is_del = 0;
6262 ip6_address_t multicast_address;
6263 u8 * policy_name = 0;
6264 int multicast_address_set = 0;
6265
6266 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
6267 {
6268 if (unformat (input, "del"))
6269 is_del = 1;
6270 else if (unformat (input, "address %U", unformat_ip6_address, &multicast_address))
6271 multicast_address_set = 1;
6272 else if (unformat (input, "sr-policy %s", &policy_name))
6273 ;
6274 else
6275 break;
6276 }
6277
6278 if (!is_del && !policy_name)
6279 {
6280 errmsg ("sr-policy name required\n");
6281 return -99;
6282 }
6283
6284
6285 if (!multicast_address_set)
6286 {
6287 errmsg ("address required\n");
6288 return -99;
6289 }
6290
6291 M(SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
6292
6293 mp->is_add = !is_del;
6294 memcpy (mp->policy_name, policy_name, vec_len(policy_name));
6295 clib_memcpy (mp->multicast_address, &multicast_address, sizeof (mp->multicast_address));
6296
6297
6298 vec_free (policy_name);
6299
6300 S; W;
6301 /* NOTREACHED */
6302}
6303
Ed Warnickecb9cada2015-12-08 15:45:58 -07006304
6305#define foreach_ip4_proto_field \
6306_(src_address) \
6307_(dst_address) \
6308_(tos) \
6309_(length) \
6310_(fragment_id) \
6311_(ttl) \
6312_(protocol) \
6313_(checksum)
6314
6315uword unformat_ip4_mask (unformat_input_t * input, va_list * args)
6316{
6317 u8 ** maskp = va_arg (*args, u8 **);
6318 u8 * mask = 0;
6319 u8 found_something = 0;
6320 ip4_header_t * ip;
6321
6322#define _(a) u8 a=0;
6323 foreach_ip4_proto_field;
6324#undef _
6325 u8 version = 0;
6326 u8 hdr_length = 0;
6327
6328
6329 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
6330 {
6331 if (unformat (input, "version"))
6332 version = 1;
6333 else if (unformat (input, "hdr_length"))
6334 hdr_length = 1;
6335 else if (unformat (input, "src"))
6336 src_address = 1;
6337 else if (unformat (input, "dst"))
6338 dst_address = 1;
6339 else if (unformat (input, "proto"))
6340 protocol = 1;
6341
6342#define _(a) else if (unformat (input, #a)) a=1;
6343 foreach_ip4_proto_field
6344#undef _
6345 else
6346 break;
6347 }
6348
6349#define _(a) found_something += a;
6350 foreach_ip4_proto_field;
6351#undef _
6352
6353 if (found_something == 0)
6354 return 0;
6355
6356 vec_validate (mask, sizeof (*ip) - 1);
6357
6358 ip = (ip4_header_t *) mask;
6359
6360#define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
6361 foreach_ip4_proto_field;
6362#undef _
6363
6364 ip->ip_version_and_header_length = 0;
6365
6366 if (version)
6367 ip->ip_version_and_header_length |= 0xF0;
6368
6369 if (hdr_length)
6370 ip->ip_version_and_header_length |= 0x0F;
6371
6372 *maskp = mask;
6373 return 1;
6374}
6375
6376#define foreach_ip6_proto_field \
6377_(src_address) \
6378_(dst_address) \
6379_(payload_length) \
6380_(hop_limit) \
6381_(protocol)
6382
6383uword unformat_ip6_mask (unformat_input_t * input, va_list * args)
6384{
6385 u8 ** maskp = va_arg (*args, u8 **);
6386 u8 * mask = 0;
6387 u8 found_something = 0;
6388 ip6_header_t * ip;
6389 u32 ip_version_traffic_class_and_flow_label;
6390
6391#define _(a) u8 a=0;
6392 foreach_ip6_proto_field;
6393#undef _
6394 u8 version = 0;
6395 u8 traffic_class = 0;
6396 u8 flow_label = 0;
6397
6398 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
6399 {
6400 if (unformat (input, "version"))
6401 version = 1;
6402 else if (unformat (input, "traffic-class"))
6403 traffic_class = 1;
6404 else if (unformat (input, "flow-label"))
6405 flow_label = 1;
6406 else if (unformat (input, "src"))
6407 src_address = 1;
6408 else if (unformat (input, "dst"))
6409 dst_address = 1;
6410 else if (unformat (input, "proto"))
6411 protocol = 1;
6412
6413#define _(a) else if (unformat (input, #a)) a=1;
6414 foreach_ip6_proto_field
6415#undef _
6416 else
6417 break;
6418 }
6419
6420#define _(a) found_something += a;
6421 foreach_ip6_proto_field;
6422#undef _
6423
6424 if (found_something == 0)
6425 return 0;
6426
6427 vec_validate (mask, sizeof (*ip) - 1);
6428
6429 ip = (ip6_header_t *) mask;
6430
6431#define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
6432 foreach_ip6_proto_field;
6433#undef _
6434
6435 ip_version_traffic_class_and_flow_label = 0;
6436
6437 if (version)
6438 ip_version_traffic_class_and_flow_label |= 0xF0000000;
6439
6440 if (traffic_class)
6441 ip_version_traffic_class_and_flow_label |= 0x0FF00000;
6442
6443 if (flow_label)
6444 ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
6445
6446 ip->ip_version_traffic_class_and_flow_label =
6447 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
6448
6449 *maskp = mask;
6450 return 1;
6451}
6452
6453uword unformat_l3_mask (unformat_input_t * input, va_list * args)
6454{
6455 u8 ** maskp = va_arg (*args, u8 **);
6456
6457 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
6458 if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
6459 return 1;
6460 else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
6461 return 1;
6462 else
6463 break;
6464 }
6465 return 0;
6466}
6467
6468uword unformat_l2_mask (unformat_input_t * input, va_list * args)
6469{
6470 u8 ** maskp = va_arg (*args, u8 **);
6471 u8 * mask = 0;
6472 u8 src = 0;
6473 u8 dst = 0;
6474 u8 proto = 0;
6475 u8 tag1 = 0;
6476 u8 tag2 = 0;
6477 u8 ignore_tag1 = 0;
6478 u8 ignore_tag2 = 0;
6479 u8 cos1 = 0;
6480 u8 cos2 = 0;
6481 u8 dot1q = 0;
6482 u8 dot1ad = 0;
6483 int len = 14;
6484
6485 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
6486 if (unformat (input, "src"))
6487 src = 1;
6488 else if (unformat (input, "dst"))
6489 dst = 1;
6490 else if (unformat (input, "proto"))
6491 proto = 1;
6492 else if (unformat (input, "tag1"))
6493 tag1 = 1;
6494 else if (unformat (input, "tag2"))
6495 tag2 = 1;
6496 else if (unformat (input, "ignore-tag1"))
6497 ignore_tag1 = 1;
6498 else if (unformat (input, "ignore-tag2"))
6499 ignore_tag2 = 1;
6500 else if (unformat (input, "cos1"))
6501 cos1 = 1;
6502 else if (unformat (input, "cos2"))
6503 cos2 = 1;
6504 else if (unformat (input, "dot1q"))
6505 dot1q = 1;
6506 else if (unformat (input, "dot1ad"))
6507 dot1ad = 1;
6508 else
6509 break;
6510 }
6511 if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
6512 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
6513 return 0;
6514
6515 if (tag1 || ignore_tag1 || cos1 || dot1q)
6516 len = 18;
6517 if (tag2 || ignore_tag2 || cos2 || dot1ad)
6518 len = 22;
6519
6520 vec_validate (mask, len-1);
6521
6522 if (dst)
6523 memset (mask, 0xff, 6);
6524
6525 if (src)
6526 memset (mask + 6, 0xff, 6);
6527
6528 if (tag2 || dot1ad)
6529 {
6530 /* inner vlan tag */
6531 if (tag2)
6532 {
6533 mask[19] = 0xff;
6534 mask[18] = 0x0f;
6535 }
6536 if (cos2)
6537 mask[18] |= 0xe0;
6538 if (proto)
6539 mask[21] = mask [20] = 0xff;
6540 if (tag1)
6541 {
6542 mask [15] = 0xff;
6543 mask [14] = 0x0f;
6544 }
6545 if (cos1)
6546 mask[14] |= 0xe0;
6547 *maskp = mask;
6548 return 1;
6549 }
6550 if (tag1 | dot1q)
6551 {
6552 if (tag1)
6553 {
6554 mask [15] = 0xff;
6555 mask [14] = 0x0f;
6556 }
6557 if (cos1)
6558 mask[14] |= 0xe0;
6559 if (proto)
6560 mask[16] = mask [17] = 0xff;
6561
6562 *maskp = mask;
6563 return 1;
6564 }
6565 if (cos2)
6566 mask[18] |= 0xe0;
6567 if (cos1)
6568 mask[14] |= 0xe0;
6569 if (proto)
6570 mask[12] = mask [13] = 0xff;
6571
6572 *maskp = mask;
6573 return 1;
6574}
6575
6576uword unformat_classify_mask (unformat_input_t * input, va_list * args)
6577{
6578 u8 ** maskp = va_arg (*args, u8 **);
6579 u32 * skipp = va_arg (*args, u32 *);
6580 u32 * matchp = va_arg (*args, u32 *);
6581 u32 match;
6582 u8 * mask = 0;
6583 u8 * l2 = 0;
6584 u8 * l3 = 0;
6585 int i;
6586
6587 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
6588 if (unformat (input, "hex %U", unformat_hex_string, &mask))
6589 ;
6590 else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
6591 ;
6592 else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
6593 ;
6594 else
6595 break;
6596 }
6597
6598 if (mask || l2 || l3)
6599 {
6600 if (l2 || l3)
6601 {
6602 /* "With a free Ethernet header in every package" */
6603 if (l2 == 0)
6604 vec_validate (l2, 13);
6605 mask = l2;
6606 vec_append (mask, l3);
6607 vec_free (l3);
6608 }
6609
6610 /* Scan forward looking for the first significant mask octet */
6611 for (i = 0; i < vec_len (mask); i++)
6612 if (mask[i])
6613 break;
6614
6615 /* compute (skip, match) params */
6616 *skipp = i / sizeof(u32x4);
6617 vec_delete (mask, *skipp * sizeof(u32x4), 0);
6618
6619 /* Pad mask to an even multiple of the vector size */
6620 while (vec_len (mask) % sizeof (u32x4))
6621 vec_add1 (mask, 0);
6622
6623 match = vec_len (mask) / sizeof (u32x4);
6624
6625 for (i = match*sizeof(u32x4); i > 0; i-= sizeof(u32x4))
6626 {
6627 u64 *tmp = (u64 *)(mask + (i-sizeof(u32x4)));
6628 if (*tmp || *(tmp+1))
6629 break;
6630 match--;
6631 }
6632 if (match == 0)
6633 clib_warning ("BUG: match 0");
6634
6635 _vec_len (mask) = match * sizeof(u32x4);
6636
6637 *matchp = match;
6638 *maskp = mask;
6639
6640 return 1;
6641 }
6642
6643 return 0;
6644}
6645
6646#define foreach_l2_next \
6647_(drop, DROP) \
6648_(ethernet, ETHERNET_INPUT) \
6649_(ip4, IP4_INPUT) \
6650_(ip6, IP6_INPUT)
6651
6652uword unformat_l2_next_index (unformat_input_t * input, va_list * args)
6653{
6654 u32 * miss_next_indexp = va_arg (*args, u32 *);
6655 u32 next_index = 0;
6656 u32 tmp;
6657
6658#define _(n,N) \
6659 if (unformat (input, #n)) { next_index = L2_CLASSIFY_NEXT_##N; goto out;}
6660 foreach_l2_next;
6661#undef _
6662
6663 if (unformat (input, "%d", &tmp))
6664 {
6665 next_index = tmp;
6666 goto out;
6667 }
6668
6669 return 0;
6670
6671 out:
6672 *miss_next_indexp = next_index;
6673 return 1;
6674}
6675
6676#define foreach_ip_next \
6677_(miss, MISS) \
6678_(drop, DROP) \
6679_(local, LOCAL) \
6680_(rewrite, REWRITE)
6681
6682uword unformat_ip_next_index (unformat_input_t * input, va_list * args)
6683{
6684 u32 * miss_next_indexp = va_arg (*args, u32 *);
6685 u32 next_index = 0;
6686 u32 tmp;
6687
6688#define _(n,N) \
6689 if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
6690 foreach_ip_next;
6691#undef _
6692
6693 if (unformat (input, "%d", &tmp))
6694 {
6695 next_index = tmp;
6696 goto out;
6697 }
6698
6699 return 0;
6700
6701 out:
6702 *miss_next_indexp = next_index;
6703 return 1;
6704}
6705
6706#define foreach_acl_next \
6707_(deny, DENY)
6708
6709uword unformat_acl_next_index (unformat_input_t * input, va_list * args)
6710{
6711 u32 * miss_next_indexp = va_arg (*args, u32 *);
6712 u32 next_index = 0;
6713 u32 tmp;
6714
6715#define _(n,N) \
6716 if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
6717 foreach_acl_next;
6718#undef _
6719
6720 if (unformat (input, "permit"))
6721 {
6722 next_index = ~0;
6723 goto out;
6724 }
6725 else if (unformat (input, "%d", &tmp))
6726 {
6727 next_index = tmp;
6728 goto out;
6729 }
6730
6731 return 0;
6732
6733 out:
6734 *miss_next_indexp = next_index;
6735 return 1;
6736}
6737
6738static int api_classify_add_del_table (vat_main_t * vam)
6739{
6740 unformat_input_t * i = vam->input;
6741 vl_api_classify_add_del_table_t *mp;
6742
6743 u32 nbuckets = 2;
6744 u32 skip = ~0;
6745 u32 match = ~0;
6746 int is_add = 1;
6747 u32 table_index = ~0;
6748 u32 next_table_index = ~0;
6749 u32 miss_next_index = ~0;
6750 u32 memory_size = 32<<20;
6751 u8 * mask = 0;
6752 f64 timeout;
6753
6754 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6755 if (unformat (i, "del"))
6756 is_add = 0;
6757 else if (unformat (i, "buckets %d", &nbuckets))
6758 ;
6759 else if (unformat (i, "memory_size %d", &memory_size))
6760 ;
6761 else if (unformat (i, "skip %d", &skip))
6762 ;
6763 else if (unformat (i, "match %d", &match))
6764 ;
6765 else if (unformat (i, "table %d", &table_index))
6766 ;
6767 else if (unformat (i, "mask %U", unformat_classify_mask,
6768 &mask, &skip, &match))
6769 ;
6770 else if (unformat (i, "next-table %d", &next_table_index))
6771 ;
6772 else if (unformat (i, "miss-next %U", unformat_ip_next_index,
6773 &miss_next_index))
6774 ;
6775 else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
6776 &miss_next_index))
6777 ;
6778 else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
6779 &miss_next_index))
6780 ;
6781 else
6782 break;
6783 }
6784
6785 if (is_add && mask == 0) {
6786 errmsg ("Mask required\n");
6787 return -99;
6788 }
6789
6790 if (is_add && skip == ~0) {
6791 errmsg ("skip count required\n");
6792 return -99;
6793 }
6794
6795 if (is_add && match == ~0) {
6796 errmsg ("match count required\n");
6797 return -99;
6798 }
6799
6800 if (!is_add && table_index == ~0) {
6801 errmsg ("table index required for delete\n");
6802 return -99;
6803 }
6804
6805 M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table,
6806 vec_len(mask));
6807
6808 mp->is_add = is_add;
6809 mp->table_index = ntohl(table_index);
6810 mp->nbuckets = ntohl(nbuckets);
6811 mp->memory_size = ntohl(memory_size);
6812 mp->skip_n_vectors = ntohl(skip);
6813 mp->match_n_vectors = ntohl(match);
6814 mp->next_table_index = ntohl(next_table_index);
6815 mp->miss_next_index = ntohl(miss_next_index);
Damjan Marionf1213b82016-03-13 02:22:06 +01006816 clib_memcpy (mp->mask, mask, vec_len(mask));
Ed Warnickecb9cada2015-12-08 15:45:58 -07006817
6818 vec_free(mask);
6819
6820 S; W;
6821 /* NOTREACHED */
6822}
6823
6824uword unformat_ip4_match (unformat_input_t * input, va_list * args)
6825{
6826 u8 ** matchp = va_arg (*args, u8 **);
6827 u8 * match = 0;
6828 ip4_header_t * ip;
6829 int version = 0;
6830 u32 version_val;
6831 int hdr_length = 0;
6832 u32 hdr_length_val;
6833 int src = 0, dst = 0;
6834 ip4_address_t src_val, dst_val;
6835 int proto = 0;
6836 u32 proto_val;
6837 int tos = 0;
6838 u32 tos_val;
6839 int length = 0;
6840 u32 length_val;
6841 int fragment_id = 0;
6842 u32 fragment_id_val;
6843 int ttl = 0;
6844 int ttl_val;
6845 int checksum = 0;
6846 u32 checksum_val;
6847
6848 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
6849 {
6850 if (unformat (input, "version %d", &version_val))
6851 version = 1;
6852 else if (unformat (input, "hdr_length %d", &hdr_length_val))
6853 hdr_length = 1;
6854 else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
6855 src = 1;
6856 else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
6857 dst = 1;
6858 else if (unformat (input, "proto %d", &proto_val))
6859 proto = 1;
6860 else if (unformat (input, "tos %d", &tos_val))
6861 tos = 1;
6862 else if (unformat (input, "length %d", &length_val))
6863 length = 1;
6864 else if (unformat (input, "fragment_id %d", &fragment_id_val))
6865 fragment_id = 1;
6866 else if (unformat (input, "ttl %d", &ttl_val))
6867 ttl = 1;
6868 else if (unformat (input, "checksum %d", &checksum_val))
6869 checksum = 1;
6870 else
6871 break;
6872 }
6873
6874 if (version + hdr_length + src + dst + proto + tos + length + fragment_id
6875 + ttl + checksum == 0)
6876 return 0;
6877
6878 /*
6879 * Aligned because we use the real comparison functions
6880 */
6881 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof(u32x4));
6882
6883 ip = (ip4_header_t *) match;
6884
6885 /* These are realistically matched in practice */
6886 if (src)
6887 ip->src_address.as_u32 = src_val.as_u32;
6888
6889 if (dst)
6890 ip->dst_address.as_u32 = dst_val.as_u32;
6891
6892 if (proto)
6893 ip->protocol = proto_val;
6894
6895
6896 /* These are not, but they're included for completeness */
6897 if (version)
6898 ip->ip_version_and_header_length |= (version_val & 0xF)<<4;
6899
6900 if (hdr_length)
6901 ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
6902
6903 if (tos)
6904 ip->tos = tos_val;
6905
6906 if (length)
6907 ip->length = length_val;
6908
6909 if (ttl)
6910 ip->ttl = ttl_val;
6911
6912 if (checksum)
6913 ip->checksum = checksum_val;
6914
6915 *matchp = match;
6916 return 1;
6917}
6918
6919uword unformat_ip6_match (unformat_input_t * input, va_list * args)
6920{
6921 u8 ** matchp = va_arg (*args, u8 **);
6922 u8 * match = 0;
6923 ip6_header_t * ip;
6924 int version = 0;
6925 u32 version_val;
6926 u8 traffic_class;
6927 u32 traffic_class_val;
6928 u8 flow_label;
6929 u8 flow_label_val;
6930 int src = 0, dst = 0;
6931 ip6_address_t src_val, dst_val;
6932 int proto = 0;
6933 u32 proto_val;
6934 int payload_length = 0;
6935 u32 payload_length_val;
6936 int hop_limit = 0;
6937 int hop_limit_val;
6938 u32 ip_version_traffic_class_and_flow_label;
6939
6940 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
6941 {
6942 if (unformat (input, "version %d", &version_val))
6943 version = 1;
6944 else if (unformat (input, "traffic_class %d", &traffic_class_val))
6945 traffic_class = 1;
6946 else if (unformat (input, "flow_label %d", &flow_label_val))
6947 flow_label = 1;
6948 else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
6949 src = 1;
6950 else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
6951 dst = 1;
6952 else if (unformat (input, "proto %d", &proto_val))
6953 proto = 1;
6954 else if (unformat (input, "payload_length %d", &payload_length_val))
6955 payload_length = 1;
6956 else if (unformat (input, "hop_limit %d", &hop_limit_val))
6957 hop_limit = 1;
6958 else
6959 break;
6960 }
6961
6962 if (version + traffic_class + flow_label + src + dst + proto +
6963 payload_length + hop_limit == 0)
6964 return 0;
6965
6966 /*
6967 * Aligned because we use the real comparison functions
6968 */
6969 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof(u32x4));
6970
6971 ip = (ip6_header_t *) match;
6972
6973 if (src)
Damjan Marionf1213b82016-03-13 02:22:06 +01006974 clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07006975
6976 if (dst)
Damjan Marionf1213b82016-03-13 02:22:06 +01006977 clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07006978
6979 if (proto)
6980 ip->protocol = proto_val;
6981
6982 ip_version_traffic_class_and_flow_label = 0;
6983
6984 if (version)
6985 ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
6986
6987 if (traffic_class)
6988 ip_version_traffic_class_and_flow_label |= (traffic_class_val & 0xFF) << 20;
6989
6990 if (flow_label)
6991 ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
6992
6993 ip->ip_version_traffic_class_and_flow_label =
6994 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
6995
6996 if (payload_length)
6997 ip->payload_length = clib_host_to_net_u16 (payload_length_val);
6998
6999 if (hop_limit)
7000 ip->hop_limit = hop_limit_val;
7001
7002 *matchp = match;
7003 return 1;
7004}
7005
7006uword unformat_l3_match (unformat_input_t * input, va_list * args)
7007{
7008 u8 ** matchp = va_arg (*args, u8 **);
7009
7010 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
7011 if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
7012 return 1;
7013 else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
7014 return 1;
7015 else
7016 break;
7017 }
7018 return 0;
7019}
7020
7021uword unformat_vlan_tag (unformat_input_t * input, va_list * args)
7022{
7023 u8 * tagp = va_arg (*args, u8 *);
7024 u32 tag;
7025
7026 if (unformat(input, "%d", &tag))
7027 {
7028 tagp[0] = (tag>>8) & 0x0F;
7029 tagp[1] = tag & 0xFF;
7030 return 1;
7031 }
7032
7033 return 0;
7034}
7035
7036uword unformat_l2_match (unformat_input_t * input, va_list * args)
7037{
7038 u8 ** matchp = va_arg (*args, u8 **);
7039 u8 * match = 0;
7040 u8 src = 0;
7041 u8 src_val[6];
7042 u8 dst = 0;
7043 u8 dst_val[6];
7044 u8 proto = 0;
7045 u16 proto_val;
7046 u8 tag1 = 0;
7047 u8 tag1_val [2];
7048 u8 tag2 = 0;
7049 u8 tag2_val [2];
7050 int len = 14;
7051 u8 ignore_tag1 = 0;
7052 u8 ignore_tag2 = 0;
7053 u8 cos1 = 0;
7054 u8 cos2 = 0;
7055 u32 cos1_val = 0;
7056 u32 cos2_val = 0;
7057
7058 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
7059 if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
7060 src = 1;
7061 else if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
7062 dst = 1;
7063 else if (unformat (input, "proto %U",
7064 unformat_ethernet_type_host_byte_order, &proto_val))
7065 proto = 1;
7066 else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
7067 tag1 = 1;
7068 else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
7069 tag2 = 1;
7070 else if (unformat (input, "ignore-tag1"))
7071 ignore_tag1 = 1;
7072 else if (unformat (input, "ignore-tag2"))
7073 ignore_tag2 = 1;
7074 else if (unformat (input, "cos1 %d", &cos1_val))
7075 cos1 = 1;
7076 else if (unformat (input, "cos2 %d", &cos2_val))
7077 cos2 = 1;
7078 else
7079 break;
7080 }
7081 if ((src + dst + proto + tag1 + tag2 +
7082 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
7083 return 0;
7084
7085 if (tag1 || ignore_tag1 || cos1)
7086 len = 18;
7087 if (tag2 || ignore_tag2 || cos2)
7088 len = 22;
7089
7090 vec_validate_aligned (match, len-1, sizeof(u32x4));
7091
7092 if (dst)
Damjan Marionf1213b82016-03-13 02:22:06 +01007093 clib_memcpy (match, dst_val, 6);
Ed Warnickecb9cada2015-12-08 15:45:58 -07007094
7095 if (src)
Damjan Marionf1213b82016-03-13 02:22:06 +01007096 clib_memcpy (match + 6, src_val, 6);
Ed Warnickecb9cada2015-12-08 15:45:58 -07007097
7098 if (tag2)
7099 {
7100 /* inner vlan tag */
7101 match[19] = tag2_val[1];
7102 match[18] = tag2_val[0];
7103 if (cos2)
7104 match [18] |= (cos2_val & 0x7) << 5;
7105 if (proto)
7106 {
7107 match[21] = proto_val & 0xff;
7108 match[20] = proto_val >> 8;
7109 }
7110 if (tag1)
7111 {
7112 match [15] = tag1_val[1];
7113 match [14] = tag1_val[0];
7114 }
7115 if (cos1)
7116 match [14] |= (cos1_val & 0x7) << 5;
7117 *matchp = match;
7118 return 1;
7119 }
7120 if (tag1)
7121 {
7122 match [15] = tag1_val[1];
7123 match [14] = tag1_val[0];
7124 if (proto)
7125 {
7126 match[17] = proto_val & 0xff;
7127 match[16] = proto_val >> 8;
7128 }
7129 if (cos1)
7130 match [14] |= (cos1_val & 0x7) << 5;
7131
7132 *matchp = match;
7133 return 1;
7134 }
7135 if (cos2)
7136 match [18] |= (cos2_val & 0x7) << 5;
7137 if (cos1)
7138 match [14] |= (cos1_val & 0x7) << 5;
7139 if (proto)
7140 {
7141 match[13] = proto_val & 0xff;
7142 match[12] = proto_val >> 8;
7143 }
7144
7145 *matchp = match;
7146 return 1;
7147}
7148
7149
7150uword unformat_classify_match (unformat_input_t * input, va_list * args)
7151{
7152 u8 ** matchp = va_arg (*args, u8 **);
7153 u32 skip_n_vectors = va_arg (*args, u32);
7154 u32 match_n_vectors = va_arg (*args, u32);
7155
7156 u8 * match = 0;
7157 u8 * l2 = 0;
7158 u8 * l3 = 0;
7159
7160 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
7161 if (unformat (input, "hex %U", unformat_hex_string, &match))
7162 ;
7163 else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
7164 ;
7165 else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
7166 ;
7167 else
7168 break;
7169 }
7170
7171 if (match || l2 || l3)
7172 {
7173 if (l2 || l3)
7174 {
7175 /* "Win a free Ethernet header in every packet" */
7176 if (l2 == 0)
7177 vec_validate_aligned (l2, 13, sizeof(u32x4));
7178 match = l2;
7179 vec_append_aligned (match, l3, sizeof(u32x4));
7180 vec_free (l3);
7181 }
7182
7183 /* Make sure the vector is big enough even if key is all 0's */
7184 vec_validate_aligned
7185 (match, ((match_n_vectors + skip_n_vectors) * sizeof(u32x4)) - 1,
7186 sizeof(u32x4));
7187
7188 /* Set size, include skipped vectors*/
7189 _vec_len (match) = (match_n_vectors+skip_n_vectors) * sizeof(u32x4);
7190
7191 *matchp = match;
7192
7193 return 1;
7194 }
7195
7196 return 0;
7197}
7198
7199static int api_classify_add_del_session (vat_main_t * vam)
7200{
7201 unformat_input_t * i = vam->input;
7202 vl_api_classify_add_del_session_t *mp;
7203 int is_add = 1;
7204 u32 table_index = ~0;
7205 u32 hit_next_index = ~0;
7206 u32 opaque_index = ~0;
7207 u8 * match = 0;
7208 i32 advance = 0;
7209 f64 timeout;
7210 u32 skip_n_vectors = 0;
7211 u32 match_n_vectors = 0;
7212
7213 /*
7214 * Warning: you have to supply skip_n and match_n
7215 * because the API client cant simply look at the classify
7216 * table object.
7217 */
7218
7219 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7220 if (unformat (i, "del"))
7221 is_add = 0;
7222 else if (unformat (i, "hit-next %U", unformat_ip_next_index,
7223 &hit_next_index))
7224 ;
7225 else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
7226 &hit_next_index))
7227 ;
7228 else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
7229 &hit_next_index))
7230 ;
7231 else if (unformat (i, "opaque-index %d", &opaque_index))
7232 ;
7233 else if (unformat (i, "skip_n %d", &skip_n_vectors))
7234 ;
7235 else if (unformat (i, "match_n %d", &match_n_vectors))
7236 ;
7237 else if (unformat (i, "match %U", unformat_classify_match,
7238 &match, skip_n_vectors, match_n_vectors))
7239 ;
7240 else if (unformat (i, "advance %d", &advance))
7241 ;
7242 else if (unformat (i, "table-index %d", &table_index))
7243 ;
7244 else
7245 break;
7246 }
7247
7248 if (table_index == ~0) {
7249 errmsg ("Table index required\n");
7250 return -99;
7251 }
7252
7253 if (is_add && match == 0) {
7254 errmsg ("Match value required\n");
7255 return -99;
7256 }
7257
7258 M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session,
7259 vec_len(match));
7260
7261 mp->is_add = is_add;
7262 mp->table_index = ntohl(table_index);
7263 mp->hit_next_index = ntohl(hit_next_index);
7264 mp->opaque_index = ntohl(opaque_index);
7265 mp->advance = ntohl(advance);
Damjan Marionf1213b82016-03-13 02:22:06 +01007266 clib_memcpy (mp->match, match, vec_len(match));
Ed Warnickecb9cada2015-12-08 15:45:58 -07007267 vec_free(match);
7268
7269 S; W;
7270 /* NOTREACHED */
7271}
7272
7273static int api_classify_set_interface_ip_table (vat_main_t * vam)
7274{
7275 unformat_input_t * i = vam->input;
7276 vl_api_classify_set_interface_ip_table_t *mp;
7277 f64 timeout;
7278 u32 sw_if_index;
7279 int sw_if_index_set;
7280 u32 table_index = ~0;
7281 u8 is_ipv6 = 0;
7282
7283 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7284 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7285 sw_if_index_set = 1;
7286 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7287 sw_if_index_set = 1;
7288 else if (unformat (i, "table %d", &table_index))
7289 ;
7290 else {
7291 clib_warning ("parse error '%U'", format_unformat_error, i);
7292 return -99;
7293 }
7294 }
7295
7296 if (sw_if_index_set == 0) {
7297 errmsg ("missing interface name or sw_if_index\n");
7298 return -99;
7299 }
7300
7301
7302 M(CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
7303
7304 mp->sw_if_index = ntohl(sw_if_index);
7305 mp->table_index = ntohl(table_index);
7306 mp->is_ipv6 = is_ipv6;
7307
7308 S; W;
7309 /* NOTREACHED */
7310 return 0;
7311}
7312
7313static int api_classify_set_interface_l2_tables (vat_main_t * vam)
7314{
7315 unformat_input_t * i = vam->input;
7316 vl_api_classify_set_interface_l2_tables_t *mp;
7317 f64 timeout;
7318 u32 sw_if_index;
7319 int sw_if_index_set;
7320 u32 ip4_table_index = ~0;
7321 u32 ip6_table_index = ~0;
7322 u32 other_table_index = ~0;
7323
7324 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7325 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7326 sw_if_index_set = 1;
7327 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7328 sw_if_index_set = 1;
7329 else if (unformat (i, "ip4-table %d", &ip4_table_index))
7330 ;
7331 else if (unformat (i, "ip6-table %d", &ip6_table_index))
7332 ;
7333 else if (unformat (i, "other-table %d", &other_table_index))
7334 ;
7335 else {
7336 clib_warning ("parse error '%U'", format_unformat_error, i);
7337 return -99;
7338 }
7339 }
7340
7341 if (sw_if_index_set == 0) {
7342 errmsg ("missing interface name or sw_if_index\n");
7343 return -99;
7344 }
7345
7346
7347 M(CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
7348
7349 mp->sw_if_index = ntohl(sw_if_index);
7350 mp->ip4_table_index = ntohl(ip4_table_index);
7351 mp->ip6_table_index = ntohl(ip6_table_index);
7352 mp->other_table_index = ntohl(other_table_index);
7353
7354
7355 S; W;
7356 /* NOTREACHED */
7357 return 0;
7358}
7359
7360static int api_get_node_index (vat_main_t * vam)
7361{
7362 unformat_input_t * i = vam->input;
7363 vl_api_get_node_index_t * mp;
7364 f64 timeout;
7365 u8 * name = 0;
7366
7367 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7368 if (unformat (i, "node %s", &name))
7369 ;
7370 else
7371 break;
7372 }
7373 if (name == 0) {
7374 errmsg ("node name required\n");
7375 return -99;
7376 }
7377 if (vec_len (name) >= ARRAY_LEN(mp->node_name)) {
7378 errmsg ("node name too long, max %d\n", ARRAY_LEN(mp->node_name));
7379 return -99;
7380 }
7381
7382 M(GET_NODE_INDEX, get_node_index);
Damjan Marionf1213b82016-03-13 02:22:06 +01007383 clib_memcpy (mp->node_name, name, vec_len(name));
Ed Warnickecb9cada2015-12-08 15:45:58 -07007384 vec_free(name);
7385
7386 S; W;
7387 /* NOTREACHED */
7388 return 0;
7389}
7390
7391static int api_add_node_next (vat_main_t * vam)
7392{
7393 unformat_input_t * i = vam->input;
7394 vl_api_add_node_next_t * mp;
7395 f64 timeout;
7396 u8 * name = 0;
7397 u8 * next = 0;
7398
7399 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7400 if (unformat (i, "node %s", &name))
7401 ;
7402 else if (unformat (i, "next %s", &next))
7403 ;
7404 else
7405 break;
7406 }
7407 if (name == 0) {
7408 errmsg ("node name required\n");
7409 return -99;
7410 }
7411 if (vec_len (name) >= ARRAY_LEN(mp->node_name)) {
7412 errmsg ("node name too long, max %d\n", ARRAY_LEN(mp->node_name));
7413 return -99;
7414 }
7415 if (next == 0) {
7416 errmsg ("next node required\n");
7417 return -99;
7418 }
7419 if (vec_len (next) >= ARRAY_LEN(mp->next_name)) {
7420 errmsg ("next name too long, max %d\n", ARRAY_LEN(mp->next_name));
7421 return -99;
7422 }
7423
7424 M(ADD_NODE_NEXT, add_node_next);
Damjan Marionf1213b82016-03-13 02:22:06 +01007425 clib_memcpy (mp->node_name, name, vec_len(name));
7426 clib_memcpy (mp->next_name, next, vec_len(next));
Ed Warnickecb9cada2015-12-08 15:45:58 -07007427 vec_free(name);
7428 vec_free(next);
7429
7430 S; W;
7431 /* NOTREACHED */
7432 return 0;
7433}
7434
7435static int api_l2tpv3_create_tunnel (vat_main_t * vam)
7436{
7437 unformat_input_t * i = vam->input;
7438 ip6_address_t client_address, our_address;
7439 int client_address_set = 0;
7440 int our_address_set = 0;
7441 u32 local_session_id = 0;
7442 u32 remote_session_id = 0;
7443 u64 local_cookie = 0;
7444 u64 remote_cookie = 0;
7445 u8 l2_sublayer_present = 0;
7446 vl_api_l2tpv3_create_tunnel_t * mp;
7447 f64 timeout;
7448
7449 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7450 if (unformat (i, "client_address %U", unformat_ip6_address,
7451 &client_address))
7452 client_address_set = 1;
7453 else if (unformat (i, "our_address %U", unformat_ip6_address,
7454 &our_address))
7455 our_address_set = 1;
7456 else if (unformat (i, "local_session_id %d", &local_session_id))
7457 ;
7458 else if (unformat (i, "remote_session_id %d", &remote_session_id))
7459 ;
7460 else if (unformat (i, "local_cookie %lld", &local_cookie))
7461 ;
7462 else if (unformat (i, "remote_cookie %lld", &remote_cookie))
7463 ;
7464 else if (unformat (i, "l2-sublayer-present"))
7465 l2_sublayer_present = 1;
7466 else
7467 break;
7468 }
7469
7470 if (client_address_set == 0) {
7471 errmsg ("client_address required\n");
7472 return -99;
7473 }
7474
7475 if (our_address_set == 0) {
7476 errmsg ("our_address required\n");
7477 return -99;
7478 }
7479
7480 M(L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
7481
Damjan Marionf1213b82016-03-13 02:22:06 +01007482 clib_memcpy (mp->client_address, client_address.as_u8,
Ed Warnickecb9cada2015-12-08 15:45:58 -07007483 sizeof (mp->client_address));
7484
Damjan Marionf1213b82016-03-13 02:22:06 +01007485 clib_memcpy (mp->our_address, our_address.as_u8,
Ed Warnickecb9cada2015-12-08 15:45:58 -07007486 sizeof (mp->our_address));
7487
7488 mp->local_session_id = ntohl (local_session_id);
7489 mp->remote_session_id = ntohl (remote_session_id);
7490 mp->local_cookie = clib_host_to_net_u64 (local_cookie);
7491 mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
7492 mp->l2_sublayer_present = l2_sublayer_present;
7493 mp->is_ipv6 = 1;
7494
7495 S; W;
7496 /* NOTREACHED */
7497 return 0;
7498}
7499
7500static int api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
7501{
7502 unformat_input_t * i = vam->input;
7503 u32 sw_if_index;
7504 u8 sw_if_index_set = 0;
7505 u64 new_local_cookie = 0;
7506 u64 new_remote_cookie = 0;
7507 vl_api_l2tpv3_set_tunnel_cookies_t *mp;
7508 f64 timeout;
7509
7510 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7511 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7512 sw_if_index_set = 1;
7513 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7514 sw_if_index_set = 1;
7515 else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
7516 ;
7517 else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
7518 ;
7519 else
7520 break;
7521 }
7522
7523 if (sw_if_index_set == 0) {
7524 errmsg ("missing interface name or sw_if_index\n");
7525 return -99;
7526 }
7527
7528 M(L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
7529
7530 mp->sw_if_index = ntohl(sw_if_index);
7531 mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
7532 mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
7533
7534 S; W;
7535 /* NOTREACHED */
7536 return 0;
7537}
7538
7539static int api_l2tpv3_interface_enable_disable (vat_main_t * vam)
7540{
7541 unformat_input_t * i = vam->input;
7542 vl_api_l2tpv3_interface_enable_disable_t *mp;
7543 f64 timeout;
7544 u32 sw_if_index;
7545 u8 sw_if_index_set = 0;
7546 u8 enable_disable = 1;
7547
7548 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7549 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7550 sw_if_index_set = 1;
7551 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7552 sw_if_index_set = 1;
7553 else if (unformat (i, "enable"))
7554 enable_disable = 1;
7555 else if (unformat (i, "disable"))
7556 enable_disable = 0;
7557 else
7558 break;
7559 }
7560
7561 if (sw_if_index_set == 0) {
7562 errmsg ("missing interface name or sw_if_index\n");
7563 return -99;
7564 }
7565
7566 M(L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
7567
7568 mp->sw_if_index = ntohl(sw_if_index);
7569 mp->enable_disable = enable_disable;
7570
7571 S; W;
7572 /* NOTREACHED */
7573 return 0;
7574}
7575
7576static int api_l2tpv3_set_lookup_key (vat_main_t * vam)
7577{
7578 unformat_input_t * i = vam->input;
7579 vl_api_l2tpv3_set_lookup_key_t * mp;
7580 f64 timeout;
7581 u8 key = ~0;
7582
7583 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7584 if (unformat (i, "lookup_v6_src"))
7585 key = L2T_LOOKUP_SRC_ADDRESS;
7586 else if (unformat (i, "lookup_v6_dst"))
7587 key = L2T_LOOKUP_DST_ADDRESS;
7588 else if (unformat (i, "lookup_session_id"))
7589 key = L2T_LOOKUP_SESSION_ID;
7590 else
7591 break;
7592 }
7593
Damjan Marionfa693552016-04-26 19:30:36 +02007594 if (key == (u8) ~0) {
Ed Warnickecb9cada2015-12-08 15:45:58 -07007595 errmsg ("l2tp session lookup key unset\n");
7596 return -99;
7597 }
7598
7599 M(L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
7600
7601 mp->key = key;
7602
7603 S; W;
7604 /* NOTREACHED */
7605 return 0;
7606}
7607
7608static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
7609(vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
7610{
7611 vat_main_t * vam = &vat_main;
7612
7613 fformat(vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
7614 format_ip6_address, mp->our_address,
7615 format_ip6_address, mp->client_address,
7616 clib_net_to_host_u32(mp->sw_if_index));
7617
7618 fformat (vam->ofp, " local cookies %016llx %016llx remote cookie %016llx\n",
7619 clib_net_to_host_u64 (mp->local_cookie[0]),
7620 clib_net_to_host_u64 (mp->local_cookie[1]),
7621 clib_net_to_host_u64 (mp->remote_cookie));
7622
7623 fformat (vam->ofp, " local session-id %d remote session-id %d\n",
7624 clib_net_to_host_u32 (mp->local_session_id),
7625 clib_net_to_host_u32 (mp->remote_session_id));
7626
7627 fformat (vam->ofp, " l2 specific sublayer %s\n\n",
7628 mp->l2_sublayer_present ? "preset" : "absent");
7629
7630}
7631
7632static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
7633(vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
7634{
7635 vat_main_t * vam = &vat_main;
7636 vat_json_node_t *node = NULL;
7637 struct in6_addr addr;
7638
7639 if (VAT_JSON_ARRAY != vam->json_tree.type) {
7640 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
7641 vat_json_init_array(&vam->json_tree);
7642 }
7643 node = vat_json_array_add(&vam->json_tree);
7644
7645 vat_json_init_object(node);
7646
Damjan Marionf1213b82016-03-13 02:22:06 +01007647 clib_memcpy(&addr, mp->our_address, sizeof(addr));
Ed Warnickecb9cada2015-12-08 15:45:58 -07007648 vat_json_object_add_ip6(node, "our_address", addr);
Damjan Marionf1213b82016-03-13 02:22:06 +01007649 clib_memcpy(&addr, mp->client_address, sizeof(addr));
Ed Warnickecb9cada2015-12-08 15:45:58 -07007650 vat_json_object_add_ip6(node, "client_address", addr);
7651
7652 vat_json_node_t * lc = vat_json_object_add(node, "local_cookie");
7653 vat_json_init_array(lc);
7654 vat_json_array_add_uint(lc, clib_net_to_host_u64(mp->local_cookie[0]));
7655 vat_json_array_add_uint(lc, clib_net_to_host_u64(mp->local_cookie[1]));
7656 vat_json_object_add_uint(node, "remote_cookie", clib_net_to_host_u64(mp->remote_cookie));
7657
7658 printf("local id: %u", clib_net_to_host_u32(mp->local_session_id));
7659 vat_json_object_add_uint(node, "local_session_id", clib_net_to_host_u32(mp->local_session_id));
7660 vat_json_object_add_uint(node, "remote_session_id", clib_net_to_host_u32(mp->remote_session_id));
7661 vat_json_object_add_string_copy(node, "l2_sublayer", mp->l2_sublayer_present ?
7662 (u8*)"present" : (u8*)"absent");
7663}
7664
7665static int api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
7666{
7667 vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
7668 f64 timeout;
7669
7670 /* Get list of l2tpv3-tunnel interfaces */
7671 M(SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
7672 S;
7673
7674 /* Use a control ping for synchronization */
7675 {
7676 vl_api_control_ping_t * mp;
7677 M(CONTROL_PING, control_ping);
7678 S;
7679 }
7680 W;
7681}
7682
7683
7684static void vl_api_sw_interface_tap_details_t_handler
7685(vl_api_sw_interface_tap_details_t * mp)
7686{
7687 vat_main_t * vam = &vat_main;
7688
7689 fformat(vam->ofp, "%-16s %d\n",
7690 mp->dev_name,
7691 clib_net_to_host_u32(mp->sw_if_index));
7692}
7693
7694static void vl_api_sw_interface_tap_details_t_handler_json
7695(vl_api_sw_interface_tap_details_t * mp)
7696{
7697 vat_main_t * vam = &vat_main;
7698 vat_json_node_t *node = NULL;
7699
7700 if (VAT_JSON_ARRAY != vam->json_tree.type) {
7701 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
7702 vat_json_init_array(&vam->json_tree);
7703 }
7704 node = vat_json_array_add(&vam->json_tree);
7705
7706 vat_json_init_object(node);
7707 vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
7708 vat_json_object_add_string_copy(node, "dev_name", mp->dev_name);
7709}
7710
7711static int api_sw_interface_tap_dump (vat_main_t * vam)
7712{
7713 vl_api_sw_interface_tap_dump_t *mp;
7714 f64 timeout;
7715
7716 fformat(vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
7717 /* Get list of tap interfaces */
7718 M(SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
7719 S;
7720
7721 /* Use a control ping for synchronization */
7722 {
7723 vl_api_control_ping_t * mp;
7724 M(CONTROL_PING, control_ping);
7725 S;
7726 }
7727 W;
7728}
7729
7730static uword unformat_vxlan_decap_next
7731(unformat_input_t * input, va_list * args)
7732{
7733 u32 * result = va_arg (*args, u32 *);
7734 u32 tmp;
7735
7736 if (unformat (input, "drop"))
7737 *result = VXLAN_INPUT_NEXT_DROP;
7738 else if (unformat (input, "ip4"))
7739 *result = VXLAN_INPUT_NEXT_IP4_INPUT;
7740 else if (unformat (input, "ip6"))
7741 *result = VXLAN_INPUT_NEXT_IP6_INPUT;
7742 else if (unformat (input, "l2"))
7743 *result = VXLAN_INPUT_NEXT_L2_INPUT;
7744 else if (unformat (input, "%d", &tmp))
7745 *result = tmp;
7746 else
7747 return 0;
7748 return 1;
7749}
7750
7751static int api_vxlan_add_del_tunnel (vat_main_t * vam)
7752{
7753 unformat_input_t * line_input = vam->input;
7754 vl_api_vxlan_add_del_tunnel_t *mp;
7755 f64 timeout;
Chris Luke99cb3352016-04-26 10:49:53 -04007756 ip4_address_t src4, dst4;
7757 ip6_address_t src6, dst6;
Ed Warnickecb9cada2015-12-08 15:45:58 -07007758 u8 is_add = 1;
Chris Luke99cb3352016-04-26 10:49:53 -04007759 u8 ipv4_set = 0, ipv6_set = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -07007760 u8 src_set = 0;
7761 u8 dst_set = 0;
7762 u32 encap_vrf_id = 0;
7763 u32 decap_next_index = ~0;
7764 u32 vni = 0;
7765
7766 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
7767 if (unformat (line_input, "del"))
7768 is_add = 0;
7769 else if (unformat (line_input, "src %U",
Chris Luke99cb3352016-04-26 10:49:53 -04007770 unformat_ip4_address, &src4))
7771 {
7772 ipv4_set = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -07007773 src_set = 1;
Chris Luke99cb3352016-04-26 10:49:53 -04007774 }
Ed Warnickecb9cada2015-12-08 15:45:58 -07007775 else if (unformat (line_input, "dst %U",
Chris Luke99cb3352016-04-26 10:49:53 -04007776 unformat_ip4_address, &dst4))
7777 {
7778 ipv4_set = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -07007779 dst_set = 1;
Chris Luke99cb3352016-04-26 10:49:53 -04007780 }
7781 else if (unformat (line_input, "src %U",
7782 unformat_ip6_address, &src6))
7783 {
7784 ipv6_set = 1;
7785 src_set = 1;
7786 }
7787 else if (unformat (line_input, "dst %U",
7788 unformat_ip6_address, &dst6))
7789 {
7790 ipv6_set = 1;
7791 dst_set = 1;
7792 }
Ed Warnickecb9cada2015-12-08 15:45:58 -07007793 else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
7794 ;
7795 else if (unformat (line_input, "decap-next %U",
7796 unformat_vxlan_decap_next, &decap_next_index))
7797 ;
7798 else if (unformat (line_input, "vni %d", &vni))
7799 ;
7800 else {
7801 errmsg ("parse error '%U'\n", format_unformat_error, line_input);
7802 return -99;
7803 }
7804 }
7805
7806 if (src_set == 0) {
7807 errmsg ("tunnel src address not specified\n");
7808 return -99;
7809 }
7810 if (dst_set == 0) {
7811 errmsg ("tunnel dst address not specified\n");
7812 return -99;
7813 }
7814
Chris Luke99cb3352016-04-26 10:49:53 -04007815 if (ipv4_set && ipv6_set) {
7816 errmsg ("both IPv4 and IPv6 addresses specified");
7817 return -99;
7818 }
7819
Ed Warnickecb9cada2015-12-08 15:45:58 -07007820 if ((vni == 0) || (vni>>24)) {
7821 errmsg ("vni not specified or out of range\n");
7822 return -99;
7823 }
7824
7825 M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
Chris Luke99cb3352016-04-26 10:49:53 -04007826
7827 if (ipv6_set) {
Chris Luked686c632016-05-20 12:13:02 -04007828 clib_memcpy(&mp->src_address, &src6, sizeof(src6));
7829 clib_memcpy(&mp->dst_address, &dst6, sizeof(dst6));
Chris Luke99cb3352016-04-26 10:49:53 -04007830 } else {
7831 clib_memcpy(&mp->src_address, &src4, sizeof(src4));
7832 clib_memcpy(&mp->dst_address, &dst4, sizeof(dst4));
7833 }
Ed Warnickecb9cada2015-12-08 15:45:58 -07007834 mp->encap_vrf_id = ntohl(encap_vrf_id);
7835 mp->decap_next_index = ntohl(decap_next_index);
7836 mp->vni = ntohl(vni);
7837 mp->is_add = is_add;
Chris Luke99cb3352016-04-26 10:49:53 -04007838 mp->is_ipv6 = ipv6_set;
Ed Warnickecb9cada2015-12-08 15:45:58 -07007839
7840 S; W;
7841 /* NOTREACHED */
7842 return 0;
7843}
7844
Dave Wallace60231f32015-12-17 21:04:30 -05007845static void vl_api_vxlan_tunnel_details_t_handler
7846(vl_api_vxlan_tunnel_details_t * mp)
7847{
7848 vat_main_t * vam = &vat_main;
7849
Chris Luke99cb3352016-04-26 10:49:53 -04007850 fformat(vam->ofp, "%11d%24U%24U%14d%18d%13d\n",
Dave Wallace60231f32015-12-17 21:04:30 -05007851 ntohl(mp->sw_if_index),
Chris Luke99cb3352016-04-26 10:49:53 -04007852 format_ip46_address, &(mp->src_address[0]),
Damjan Marion86be4872016-05-24 23:19:11 +02007853 IP46_TYPE_ANY,
Chris Luke99cb3352016-04-26 10:49:53 -04007854 format_ip46_address, &(mp->dst_address[0]),
Damjan Marion86be4872016-05-24 23:19:11 +02007855 IP46_TYPE_ANY,
Dave Wallace60231f32015-12-17 21:04:30 -05007856 ntohl(mp->encap_vrf_id),
7857 ntohl(mp->decap_next_index),
7858 ntohl(mp->vni));
7859}
7860
7861static void vl_api_vxlan_tunnel_details_t_handler_json
7862(vl_api_vxlan_tunnel_details_t * mp)
7863{
7864 vat_main_t * vam = &vat_main;
7865 vat_json_node_t *node = NULL;
7866 struct in_addr ip4;
Chris Luke99cb3352016-04-26 10:49:53 -04007867 struct in6_addr ip6;
Dave Wallace60231f32015-12-17 21:04:30 -05007868
7869 if (VAT_JSON_ARRAY != vam->json_tree.type) {
7870 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
7871 vat_json_init_array(&vam->json_tree);
7872 }
7873 node = vat_json_array_add(&vam->json_tree);
7874
7875 vat_json_init_object(node);
7876 vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
Chris Luke99cb3352016-04-26 10:49:53 -04007877 if (mp->is_ipv6) {
7878 clib_memcpy(&ip6, &(mp->src_address[0]), sizeof(ip6));
7879 vat_json_object_add_ip6(node, "src_address", ip6);
7880 clib_memcpy(&ip6, &(mp->dst_address[0]), sizeof(ip6));
7881 vat_json_object_add_ip6(node, "dst_address", ip6);
7882 } else {
7883 clib_memcpy(&ip4, &(mp->src_address[0]), sizeof(ip4));
7884 vat_json_object_add_ip4(node, "src_address", ip4);
7885 clib_memcpy(&ip4, &(mp->dst_address[0]), sizeof(ip4));
7886 vat_json_object_add_ip4(node, "dst_address", ip4);
7887 }
Dave Wallace60231f32015-12-17 21:04:30 -05007888 vat_json_object_add_uint(node, "encap_vrf_id", ntohl(mp->encap_vrf_id));
7889 vat_json_object_add_uint(node, "decap_next_index", ntohl(mp->decap_next_index));
7890 vat_json_object_add_uint(node, "vni", ntohl(mp->vni));
Chris Luke99cb3352016-04-26 10:49:53 -04007891 vat_json_object_add_uint(node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
Dave Wallace60231f32015-12-17 21:04:30 -05007892}
7893
7894static int api_vxlan_tunnel_dump (vat_main_t * vam)
7895{
7896 unformat_input_t * i = vam->input;
7897 vl_api_vxlan_tunnel_dump_t *mp;
7898 f64 timeout;
7899 u32 sw_if_index;
7900 u8 sw_if_index_set = 0;
7901
7902 /* Parse args required to build the message */
7903 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7904 if (unformat (i, "sw_if_index %d", &sw_if_index))
7905 sw_if_index_set = 1;
7906 else
7907 break;
7908 }
7909
7910 if (sw_if_index_set == 0) {
7911 sw_if_index = ~0;
7912 }
7913
7914 if (!vam->json_output) {
Chris Luke99cb3352016-04-26 10:49:53 -04007915 fformat(vam->ofp, "%11s%24s%24s%14s%18s%13s\n",
Dave Wallace60231f32015-12-17 21:04:30 -05007916 "sw_if_index", "src_address", "dst_address",
7917 "encap_vrf_id", "decap_next_index", "vni");
7918 }
7919
Chris Luke99cb3352016-04-26 10:49:53 -04007920 /* Get list of vxlan-tunnel interfaces */
Dave Wallace60231f32015-12-17 21:04:30 -05007921 M(VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
7922
7923 mp->sw_if_index = htonl(sw_if_index);
7924
7925 S;
7926
7927 /* Use a control ping for synchronization */
7928 {
7929 vl_api_control_ping_t * mp;
7930 M(CONTROL_PING, control_ping);
7931 S;
7932 }
7933 W;
7934}
7935
Chris Luke27fe48f2016-04-28 13:44:38 -04007936static int api_gre_add_del_tunnel (vat_main_t * vam)
7937{
7938 unformat_input_t * line_input = vam->input;
7939 vl_api_gre_add_del_tunnel_t *mp;
7940 f64 timeout;
7941 ip4_address_t src4, dst4;
7942 u8 is_add = 1;
7943 u8 src_set = 0;
7944 u8 dst_set = 0;
7945 u32 outer_fib_id = 0;
7946
7947 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
7948 if (unformat (line_input, "del"))
7949 is_add = 0;
7950 else if (unformat (line_input, "src %U",
7951 unformat_ip4_address, &src4))
7952 src_set = 1;
7953 else if (unformat (line_input, "dst %U",
7954 unformat_ip4_address, &dst4))
7955 dst_set = 1;
7956 else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
7957 ;
7958 else {
7959 errmsg ("parse error '%U'\n", format_unformat_error, line_input);
7960 return -99;
7961 }
7962 }
7963
7964 if (src_set == 0) {
7965 errmsg ("tunnel src address not specified\n");
7966 return -99;
7967 }
7968 if (dst_set == 0) {
7969 errmsg ("tunnel dst address not specified\n");
7970 return -99;
7971 }
7972
7973
7974 M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
7975
7976 clib_memcpy(&mp->src_address, &src4, sizeof(src4));
7977 clib_memcpy(&mp->dst_address, &dst4, sizeof(dst4));
7978 mp->outer_table_id = ntohl(outer_fib_id);
7979 mp->is_add = is_add;
7980
7981 S; W;
7982 /* NOTREACHED */
7983 return 0;
7984}
7985
7986static void vl_api_gre_tunnel_details_t_handler
7987(vl_api_gre_tunnel_details_t * mp)
7988{
7989 vat_main_t * vam = &vat_main;
7990
7991 fformat(vam->ofp, "%11d%15U%15U%14d\n",
7992 ntohl(mp->sw_if_index),
7993 format_ip4_address, &mp->src_address,
7994 format_ip4_address, &mp->dst_address,
7995 ntohl(mp->outer_table_id));
7996}
7997
7998static void vl_api_gre_tunnel_details_t_handler_json
7999(vl_api_gre_tunnel_details_t * mp)
8000{
8001 vat_main_t * vam = &vat_main;
8002 vat_json_node_t *node = NULL;
8003 struct in_addr ip4;
8004
8005 if (VAT_JSON_ARRAY != vam->json_tree.type) {
8006 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
8007 vat_json_init_array(&vam->json_tree);
8008 }
8009 node = vat_json_array_add(&vam->json_tree);
8010
8011 vat_json_init_object(node);
8012 vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
8013 clib_memcpy(&ip4, &mp->src_address, sizeof(ip4));
8014 vat_json_object_add_ip4(node, "src_address", ip4);
8015 clib_memcpy(&ip4, &mp->dst_address, sizeof(ip4));
8016 vat_json_object_add_ip4(node, "dst_address", ip4);
8017 vat_json_object_add_uint(node, "outer_fib_id", ntohl(mp->outer_table_id));
8018}
8019
8020static int api_gre_tunnel_dump (vat_main_t * vam)
8021{
8022 unformat_input_t * i = vam->input;
8023 vl_api_gre_tunnel_dump_t *mp;
8024 f64 timeout;
8025 u32 sw_if_index;
8026 u8 sw_if_index_set = 0;
8027
8028 /* Parse args required to build the message */
8029 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8030 if (unformat (i, "sw_if_index %d", &sw_if_index))
8031 sw_if_index_set = 1;
8032 else
8033 break;
8034 }
8035
8036 if (sw_if_index_set == 0) {
8037 sw_if_index = ~0;
8038 }
8039
8040 if (!vam->json_output) {
8041 fformat(vam->ofp, "%11s%15s%15s%14s\n",
8042 "sw_if_index", "src_address", "dst_address",
8043 "outer_fib_id");
8044 }
8045
8046 /* Get list of gre-tunnel interfaces */
8047 M(GRE_TUNNEL_DUMP, gre_tunnel_dump);
8048
8049 mp->sw_if_index = htonl(sw_if_index);
8050
8051 S;
8052
8053 /* Use a control ping for synchronization */
8054 {
8055 vl_api_control_ping_t * mp;
8056 M(CONTROL_PING, control_ping);
8057 S;
8058 }
8059 W;
8060}
8061
Ed Warnickecb9cada2015-12-08 15:45:58 -07008062static int api_l2_fib_clear_table (vat_main_t * vam)
8063{
8064// unformat_input_t * i = vam->input;
8065 vl_api_l2_fib_clear_table_t *mp;
8066 f64 timeout;
8067
8068 M(L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
8069
8070 S; W;
8071 /* NOTREACHED */
8072 return 0;
8073}
8074
8075static int api_l2_interface_efp_filter (vat_main_t * vam)
8076{
8077 unformat_input_t * i = vam->input;
8078 vl_api_l2_interface_efp_filter_t *mp;
8079 f64 timeout;
8080 u32 sw_if_index;
8081 u8 enable = 1;
8082 u8 sw_if_index_set = 0;
8083
8084 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8085 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8086 sw_if_index_set = 1;
8087 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8088 sw_if_index_set = 1;
8089 else if (unformat (i, "enable"))
8090 enable = 1;
8091 else if (unformat (i, "disable"))
8092 enable = 0;
8093 else {
8094 clib_warning ("parse error '%U'", format_unformat_error, i);
8095 return -99;
8096 }
8097 }
8098
8099 if (sw_if_index_set == 0) {
8100 errmsg ("missing sw_if_index\n");
8101 return -99;
8102 }
8103
8104 M(L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
8105
8106 mp->sw_if_index = ntohl(sw_if_index);
8107 mp->enable_disable = enable;
8108
8109 S; W;
8110 /* NOTREACHED */
8111 return 0;
8112}
8113
8114#define foreach_vtr_op \
8115_("disable", L2_VTR_DISABLED) \
8116_("push-1", L2_VTR_PUSH_1) \
8117_("push-2", L2_VTR_PUSH_2) \
8118_("pop-1", L2_VTR_POP_1) \
8119_("pop-2", L2_VTR_POP_2) \
8120_("translate-1-1", L2_VTR_TRANSLATE_1_1) \
8121_("translate-1-2", L2_VTR_TRANSLATE_1_2) \
8122_("translate-2-1", L2_VTR_TRANSLATE_2_1) \
8123_("translate-2-2", L2_VTR_TRANSLATE_2_2)
8124
8125static int api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
8126{
8127 unformat_input_t * i = vam->input;
8128 vl_api_l2_interface_vlan_tag_rewrite_t *mp;
8129 f64 timeout;
8130 u32 sw_if_index;
8131 u8 sw_if_index_set = 0;
8132 u8 vtr_op_set = 0;
8133 u32 vtr_op = 0;
8134 u32 push_dot1q = 1;
8135 u32 tag1 = ~0;
8136 u32 tag2 = ~0;
8137
8138 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8139 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8140 sw_if_index_set = 1;
8141 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8142 sw_if_index_set = 1;
8143 else if (unformat (i, "vtr_op %d", &vtr_op))
8144 vtr_op_set = 1;
8145#define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
8146 foreach_vtr_op
8147#undef _
8148
8149 else if (unformat (i, "push_dot1q %d", &push_dot1q))
8150 ;
8151 else if (unformat (i, "tag1 %d", &tag1))
8152 ;
8153 else if (unformat (i, "tag2 %d", &tag2))
8154 ;
8155 else {
8156 clib_warning ("parse error '%U'", format_unformat_error, i);
8157 return -99;
8158 }
8159 }
8160
8161 if ((sw_if_index_set == 0)||(vtr_op_set == 0)) {
8162 errmsg ("missing vtr operation or sw_if_index\n");
8163 return -99;
8164 }
8165
8166 M(L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
8167
8168 mp->sw_if_index = ntohl(sw_if_index);
8169 mp->vtr_op = ntohl(vtr_op);
8170 mp->push_dot1q = ntohl(push_dot1q);
8171 mp->tag1 = ntohl(tag1);
8172 mp->tag2 = ntohl(tag2);
8173
8174 S; W;
8175 /* NOTREACHED */
8176 return 0;
8177}
8178
8179static int api_create_vhost_user_if (vat_main_t * vam)
8180{
8181 unformat_input_t * i = vam->input;
8182 vl_api_create_vhost_user_if_t *mp;
8183 f64 timeout;
8184 u8 * file_name;
8185 u8 is_server = 0;
8186 u8 file_name_set = 0;
8187 u32 custom_dev_instance = ~0;
Pierre Pfisteref65cb02016-02-19 13:52:44 +00008188 u8 hwaddr[6];
8189 u8 use_custom_mac = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -07008190
8191 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8192 if (unformat (i, "socket %s", &file_name)) {
8193 file_name_set = 1;
8194 }
8195 else if (unformat (i, "renumber %"PRIu32, &custom_dev_instance))
8196 ;
Pierre Pfisteref65cb02016-02-19 13:52:44 +00008197 else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
8198 use_custom_mac = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -07008199 else if (unformat (i, "server"))
8200 is_server = 1;
8201 else
8202 break;
8203 }
8204
8205 if (file_name_set == 0) {
8206 errmsg ("missing socket file name\n");
8207 return -99;
8208 }
8209
8210 if (vec_len (file_name) > 255) {
8211 errmsg ("socket file name too long\n");
8212 return -99;
8213 }
8214 vec_add1 (file_name, 0);
8215
8216 M(CREATE_VHOST_USER_IF, create_vhost_user_if);
8217
8218 mp->is_server = is_server;
Damjan Marionf1213b82016-03-13 02:22:06 +01008219 clib_memcpy(mp->sock_filename, file_name, vec_len(file_name));
Ed Warnickecb9cada2015-12-08 15:45:58 -07008220 vec_free(file_name);
8221 if (custom_dev_instance != ~0) {
8222 mp->renumber = 1;
8223 mp->custom_dev_instance = ntohl(custom_dev_instance);
8224 }
Pierre Pfisteref65cb02016-02-19 13:52:44 +00008225 mp->use_custom_mac = use_custom_mac;
Damjan Marionf1213b82016-03-13 02:22:06 +01008226 clib_memcpy(mp->mac_address, hwaddr, 6);
Ed Warnickecb9cada2015-12-08 15:45:58 -07008227
8228 S; W;
8229 /* NOTREACHED */
8230 return 0;
8231}
8232
8233static int api_modify_vhost_user_if (vat_main_t * vam)
8234{
8235 unformat_input_t * i = vam->input;
8236 vl_api_modify_vhost_user_if_t *mp;
8237 f64 timeout;
8238 u8 * file_name;
8239 u8 is_server = 0;
8240 u8 file_name_set = 0;
8241 u32 custom_dev_instance = ~0;
8242 u8 sw_if_index_set = 0;
8243 u32 sw_if_index = (u32)~0;
8244
8245 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8246 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8247 sw_if_index_set = 1;
8248 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8249 sw_if_index_set = 1;
8250 else if (unformat (i, "socket %s", &file_name)) {
8251 file_name_set = 1;
8252 }
8253 else if (unformat (i, "renumber %"PRIu32, &custom_dev_instance))
8254 ;
8255 else if (unformat (i, "server"))
8256 is_server = 1;
8257 else
8258 break;
8259 }
8260
8261 if (sw_if_index_set == 0) {
8262 errmsg ("missing sw_if_index or interface name\n");
8263 return -99;
8264 }
8265
8266 if (file_name_set == 0) {
8267 errmsg ("missing socket file name\n");
8268 return -99;
8269 }
8270
8271 if (vec_len (file_name) > 255) {
8272 errmsg ("socket file name too long\n");
8273 return -99;
8274 }
8275 vec_add1 (file_name, 0);
8276
8277 M(MODIFY_VHOST_USER_IF, modify_vhost_user_if);
8278
8279 mp->sw_if_index = ntohl(sw_if_index);
8280 mp->is_server = is_server;
Damjan Marionf1213b82016-03-13 02:22:06 +01008281 clib_memcpy(mp->sock_filename, file_name, vec_len(file_name));
Ed Warnickecb9cada2015-12-08 15:45:58 -07008282 vec_free(file_name);
8283 if (custom_dev_instance != ~0) {
8284 mp->renumber = 1;
8285 mp->custom_dev_instance = ntohl(custom_dev_instance);
8286 }
8287
8288 S; W;
8289 /* NOTREACHED */
8290 return 0;
8291}
8292
8293static int api_delete_vhost_user_if (vat_main_t * vam)
8294{
8295 unformat_input_t * i = vam->input;
8296 vl_api_delete_vhost_user_if_t *mp;
8297 f64 timeout;
8298 u32 sw_if_index = ~0;
8299 u8 sw_if_index_set = 0;
8300
8301 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8302 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8303 sw_if_index_set = 1;
8304 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8305 sw_if_index_set = 1;
8306 else
8307 break;
8308 }
8309
8310 if (sw_if_index_set == 0) {
8311 errmsg ("missing sw_if_index or interface name\n");
8312 return -99;
8313 }
8314
8315
8316 M(DELETE_VHOST_USER_IF, delete_vhost_user_if);
8317
8318 mp->sw_if_index = ntohl(sw_if_index);
8319
8320 S; W;
8321 /* NOTREACHED */
8322 return 0;
8323}
8324
8325static void vl_api_sw_interface_vhost_user_details_t_handler
8326(vl_api_sw_interface_vhost_user_details_t * mp)
8327{
8328 vat_main_t * vam = &vat_main;
8329
8330 fformat(vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
8331 (char *)mp->interface_name,
8332 ntohl(mp->sw_if_index), ntohl(mp->virtio_net_hdr_sz),
8333 clib_net_to_host_u64(mp->features), mp->is_server,
8334 ntohl(mp->num_regions), (char *)mp->sock_filename);
8335 fformat(vam->ofp, " Status: '%s'\n", strerror(ntohl(mp->sock_errno)));
8336}
8337
8338static void vl_api_sw_interface_vhost_user_details_t_handler_json
8339(vl_api_sw_interface_vhost_user_details_t * mp)
8340{
8341 vat_main_t * vam = &vat_main;
8342 vat_json_node_t *node = NULL;
8343
8344 if (VAT_JSON_ARRAY != vam->json_tree.type) {
8345 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
8346 vat_json_init_array(&vam->json_tree);
8347 }
8348 node = vat_json_array_add(&vam->json_tree);
8349
8350 vat_json_init_object(node);
8351 vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
8352 vat_json_object_add_string_copy(node, "interface_name", mp->interface_name);
8353 vat_json_object_add_uint(node, "virtio_net_hdr_sz", ntohl(mp->virtio_net_hdr_sz));
8354 vat_json_object_add_uint(node, "features", clib_net_to_host_u64(mp->features));
8355 vat_json_object_add_uint(node, "is_server", mp->is_server);
8356 vat_json_object_add_string_copy(node, "sock_filename", mp->sock_filename);
8357 vat_json_object_add_uint(node, "num_regions", ntohl(mp->num_regions));
8358 vat_json_object_add_uint(node, "sock_errno", ntohl(mp->sock_errno));
8359}
8360
8361static int api_sw_interface_vhost_user_dump (vat_main_t * vam)
8362{
8363 vl_api_sw_interface_vhost_user_dump_t *mp;
8364 f64 timeout;
8365 fformat(vam->ofp, "Interface name idx hdr_sz features server regions filename\n");
8366
8367 /* Get list of vhost-user interfaces */
8368 M(SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
8369 S;
8370
8371 /* Use a control ping for synchronization */
8372 {
8373 vl_api_control_ping_t * mp;
8374 M(CONTROL_PING, control_ping);
8375 S;
8376 }
8377 W;
8378}
8379
8380static int api_show_version (vat_main_t * vam)
8381{
8382 vl_api_show_version_t *mp;
8383 f64 timeout;
8384
8385 M(SHOW_VERSION, show_version);
8386
8387 S; W;
8388 /* NOTREACHED */
8389 return 0;
8390}
8391
Ed Warnickecb9cada2015-12-08 15:45:58 -07008392
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07008393static int api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
Ed Warnickecb9cada2015-12-08 15:45:58 -07008394{
8395 unformat_input_t * line_input = vam->input;
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07008396 vl_api_vxlan_gpe_add_del_tunnel_t *mp;
Ed Warnickecb9cada2015-12-08 15:45:58 -07008397 f64 timeout;
Hongjun Nidf921cc2016-05-25 01:16:19 +08008398 ip4_address_t local4, remote4;
8399 ip6_address_t local6, remote6;
Ed Warnickecb9cada2015-12-08 15:45:58 -07008400 u8 is_add = 1;
Hongjun Nidf921cc2016-05-25 01:16:19 +08008401 u8 ipv4_set = 0, ipv6_set = 0;
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07008402 u8 local_set = 0;
8403 u8 remote_set = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -07008404 u32 encap_vrf_id = 0;
8405 u32 decap_vrf_id = 0;
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07008406 u8 protocol = ~0;
Ed Warnickecb9cada2015-12-08 15:45:58 -07008407 u32 vni;
8408 u8 vni_set = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -07008409
8410 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
8411 if (unformat (line_input, "del"))
8412 is_add = 0;
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07008413 else if (unformat (line_input, "local %U",
Hongjun Nidf921cc2016-05-25 01:16:19 +08008414 unformat_ip4_address, &local4))
8415 {
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07008416 local_set = 1;
Hongjun Nidf921cc2016-05-25 01:16:19 +08008417 ipv4_set = 1;
8418 }
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07008419 else if (unformat (line_input, "remote %U",
Hongjun Nidf921cc2016-05-25 01:16:19 +08008420 unformat_ip4_address, &remote4))
8421 {
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07008422 remote_set = 1;
Hongjun Nidf921cc2016-05-25 01:16:19 +08008423 ipv4_set = 1;
8424 }
8425 else if (unformat (line_input, "local %U",
8426 unformat_ip6_address, &local6))
8427 {
8428 local_set = 1;
8429 ipv6_set = 1;
8430 }
8431 else if (unformat (line_input, "remote %U",
8432 unformat_ip6_address, &remote6))
8433 {
8434 remote_set = 1;
8435 ipv6_set = 1;
8436 }
Ed Warnickecb9cada2015-12-08 15:45:58 -07008437 else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
8438 ;
8439 else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
8440 ;
Ed Warnickecb9cada2015-12-08 15:45:58 -07008441 else if (unformat (line_input, "vni %d", &vni))
8442 vni_set = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -07008443 else if (unformat(line_input, "next-ip4"))
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07008444 protocol = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -07008445 else if (unformat(line_input, "next-ip6"))
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07008446 protocol = 2;
Ed Warnickecb9cada2015-12-08 15:45:58 -07008447 else if (unformat(line_input, "next-ethernet"))
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07008448 protocol = 3;
8449 else if (unformat(line_input, "next-nsh"))
8450 protocol = 4;
Ed Warnickecb9cada2015-12-08 15:45:58 -07008451 else {
8452 errmsg ("parse error '%U'\n", format_unformat_error, line_input);
8453 return -99;
8454 }
8455 }
8456
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07008457 if (local_set == 0) {
8458 errmsg ("tunnel local address not specified\n");
Ed Warnickecb9cada2015-12-08 15:45:58 -07008459 return -99;
8460 }
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07008461 if (remote_set == 0) {
8462 errmsg ("tunnel remote address not specified\n");
Ed Warnickecb9cada2015-12-08 15:45:58 -07008463 return -99;
8464 }
Hongjun Nidf921cc2016-05-25 01:16:19 +08008465 if (ipv4_set && ipv6_set) {
8466 errmsg ("both IPv4 and IPv6 addresses specified");
8467 return -99;
8468 }
Ed Warnickecb9cada2015-12-08 15:45:58 -07008469
Ed Warnickecb9cada2015-12-08 15:45:58 -07008470 if (vni_set == 0) {
8471 errmsg ("vni not specified\n");
8472 return -99;
8473 }
8474
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07008475 M(VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
Ed Warnickecb9cada2015-12-08 15:45:58 -07008476
Hongjun Nidf921cc2016-05-25 01:16:19 +08008477
8478 if (ipv6_set) {
8479 clib_memcpy(&mp->local, &local6, sizeof(local6));
8480 clib_memcpy(&mp->remote, &remote6, sizeof(remote6));
8481 } else {
8482 clib_memcpy(&mp->local, &local4, sizeof(local4));
8483 clib_memcpy(&mp->remote, &remote4, sizeof(remote4));
8484 }
8485
Ed Warnickecb9cada2015-12-08 15:45:58 -07008486 mp->encap_vrf_id = ntohl(encap_vrf_id);
8487 mp->decap_vrf_id = ntohl(decap_vrf_id);
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07008488 mp->protocol = ntohl(protocol);
Ed Warnickecb9cada2015-12-08 15:45:58 -07008489 mp->vni = ntohl(vni);
8490 mp->is_add = is_add;
Hongjun Nidf921cc2016-05-25 01:16:19 +08008491 mp->is_ipv6 = ipv6_set;
Ed Warnickecb9cada2015-12-08 15:45:58 -07008492
8493 S; W;
8494 /* NOTREACHED */
8495 return 0;
8496}
8497
Hongjun Ni0e06e2b2016-05-30 19:45:51 +08008498static void vl_api_vxlan_gpe_tunnel_details_t_handler
8499(vl_api_vxlan_gpe_tunnel_details_t * mp)
8500{
8501 vat_main_t * vam = &vat_main;
8502
8503 fformat(vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
8504 ntohl(mp->sw_if_index),
8505 format_ip46_address, &(mp->local[0]),
8506 format_ip46_address, &(mp->remote[0]),
8507 ntohl(mp->vni),
8508 ntohl(mp->protocol),
8509 ntohl(mp->encap_vrf_id),
8510 ntohl(mp->decap_vrf_id));
8511}
8512
8513static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
8514(vl_api_vxlan_gpe_tunnel_details_t * mp)
8515{
8516 vat_main_t * vam = &vat_main;
8517 vat_json_node_t *node = NULL;
8518 struct in_addr ip4;
8519 struct in6_addr ip6;
8520
8521 if (VAT_JSON_ARRAY != vam->json_tree.type) {
8522 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
8523 vat_json_init_array(&vam->json_tree);
8524 }
8525 node = vat_json_array_add(&vam->json_tree);
8526
8527 vat_json_init_object(node);
8528 vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
8529 if (mp->is_ipv6) {
8530 clib_memcpy(&ip6, &(mp->local[0]), sizeof(ip6));
8531 vat_json_object_add_ip6(node, "local", ip6);
8532 clib_memcpy(&ip6, &(mp->remote[0]), sizeof(ip6));
8533 vat_json_object_add_ip6(node, "remote", ip6);
8534 } else {
8535 clib_memcpy(&ip4, &(mp->local[0]), sizeof(ip4));
8536 vat_json_object_add_ip4(node, "local", ip4);
8537 clib_memcpy(&ip4, &(mp->remote[0]), sizeof(ip4));
8538 vat_json_object_add_ip4(node, "remote", ip4);
8539 }
8540 vat_json_object_add_uint(node, "vni", ntohl(mp->vni));
8541 vat_json_object_add_uint(node, "protocol", ntohl(mp->protocol));
8542 vat_json_object_add_uint(node, "encap_vrf_id", ntohl(mp->encap_vrf_id));
8543 vat_json_object_add_uint(node, "decap_vrf_id", ntohl(mp->decap_vrf_id));
8544 vat_json_object_add_uint(node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
8545}
8546
8547static int api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
8548{
8549 unformat_input_t * i = vam->input;
8550 vl_api_vxlan_gpe_tunnel_dump_t *mp;
8551 f64 timeout;
8552 u32 sw_if_index;
8553 u8 sw_if_index_set = 0;
8554
8555 /* Parse args required to build the message */
8556 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8557 if (unformat (i, "sw_if_index %d", &sw_if_index))
8558 sw_if_index_set = 1;
8559 else
8560 break;
8561 }
8562
8563 if (sw_if_index_set == 0) {
8564 sw_if_index = ~0;
8565 }
8566
8567 if (!vam->json_output) {
8568 fformat(vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
8569 "sw_if_index", "local", "remote", "vni",
8570 "protocol","encap_vrf_id", "decap_vrf_id");
8571 }
8572
8573 /* Get list of vxlan-tunnel interfaces */
8574 M(VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
8575
8576 mp->sw_if_index = htonl(sw_if_index);
8577
8578 S;
8579
8580 /* Use a control ping for synchronization */
8581 {
8582 vl_api_control_ping_t * mp;
8583 M(CONTROL_PING, control_ping);
8584 S;
8585 }
8586 W;
8587}
8588
Ed Warnickecb9cada2015-12-08 15:45:58 -07008589u8 * format_l2_fib_mac_address (u8 * s, va_list * args)
8590{
8591 u8 * a = va_arg (*args, u8 *);
8592
8593 return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
8594 a[2], a[3], a[4], a[5], a[6], a[7]);
8595}
8596
8597static void vl_api_l2_fib_table_entry_t_handler
8598(vl_api_l2_fib_table_entry_t * mp)
8599{
8600 vat_main_t * vam = &vat_main;
8601
8602 fformat(vam->ofp, "%3" PRIu32 " %U %3" PRIu32
8603 " %d %d %d\n",
8604 ntohl(mp->bd_id), format_l2_fib_mac_address, &mp->mac,
8605 ntohl(mp->sw_if_index), mp->static_mac, mp->filter_mac,
8606 mp->bvi_mac);
8607}
8608
8609static void vl_api_l2_fib_table_entry_t_handler_json
8610(vl_api_l2_fib_table_entry_t * mp)
8611{
8612 vat_main_t * vam = &vat_main;
8613 vat_json_node_t *node = NULL;
8614
8615 if (VAT_JSON_ARRAY != vam->json_tree.type) {
8616 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
8617 vat_json_init_array(&vam->json_tree);
8618 }
8619 node = vat_json_array_add(&vam->json_tree);
8620
8621 vat_json_init_object(node);
8622 vat_json_object_add_uint(node, "bd_id", ntohl(mp->bd_id));
8623 vat_json_object_add_uint(node, "mac", clib_net_to_host_u64(mp->mac));
8624 vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
8625 vat_json_object_add_uint(node, "static_mac", mp->static_mac);
8626 vat_json_object_add_uint(node, "filter_mac", mp->filter_mac);
8627 vat_json_object_add_uint(node, "bvi_mac", mp->bvi_mac);
8628}
8629
8630static int api_l2_fib_table_dump (vat_main_t * vam)
8631{
8632 unformat_input_t * i = vam->input;
8633 vl_api_l2_fib_table_dump_t *mp;
8634 f64 timeout;
8635 u32 bd_id;
8636 u8 bd_id_set = 0;
8637
8638 /* Parse args required to build the message */
8639 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8640 if (unformat (i, "bd_id %d", &bd_id))
8641 bd_id_set = 1;
8642 else
8643 break;
8644 }
8645
8646 if (bd_id_set == 0) {
8647 errmsg ("missing bridge domain\n");
8648 return -99;
8649 }
8650
8651 fformat(vam->ofp, "BD-ID Mac Address sw-ndx Static Filter BVI\n");
8652
8653 /* Get list of l2 fib entries */
8654 M(L2_FIB_TABLE_DUMP, l2_fib_table_dump);
8655
8656 mp->bd_id = ntohl(bd_id);
8657 S;
8658
8659 /* Use a control ping for synchronization */
8660 {
8661 vl_api_control_ping_t * mp;
8662 M(CONTROL_PING, control_ping);
8663 S;
8664 }
8665 W;
8666}
8667
8668
8669static int
8670api_interface_name_renumber (vat_main_t * vam)
8671{
8672 unformat_input_t * line_input = vam->input;
8673 vl_api_interface_name_renumber_t *mp;
8674 u32 sw_if_index = ~0;
8675 f64 timeout;
8676 u32 new_show_dev_instance = ~0;
8677
8678 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
8679 if (unformat (line_input, "%U", unformat_sw_if_index, vam,
8680 &sw_if_index))
8681 ;
8682 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
8683 ;
8684 else if (unformat (line_input, "new_show_dev_instance %d",
8685 &new_show_dev_instance))
8686 ;
8687 else
8688 break;
8689 }
8690
8691 if (sw_if_index == ~0) {
8692 errmsg ("missing interface name or sw_if_index\n");
8693 return -99;
8694 }
8695
8696 if (new_show_dev_instance == ~0) {
8697 errmsg ("missing new_show_dev_instance\n");
8698 return -99;
8699 }
8700
8701 M(INTERFACE_NAME_RENUMBER, interface_name_renumber);
8702
8703 mp->sw_if_index = ntohl (sw_if_index);
8704 mp->new_show_dev_instance = ntohl (new_show_dev_instance);
8705
8706 S; W;
8707}
8708
8709static int
8710api_want_ip4_arp_events (vat_main_t * vam)
8711{
8712 unformat_input_t * line_input = vam->input;
8713 vl_api_want_ip4_arp_events_t * mp;
8714 f64 timeout;
8715 ip4_address_t address;
8716 int address_set = 0;
8717 u32 enable_disable = 1;
8718
8719 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
8720 if (unformat (line_input, "address %U",
8721 unformat_ip4_address, &address))
8722 address_set = 1;
8723 else if (unformat (line_input, "del"))
8724 enable_disable = 0;
8725 else
8726 break;
8727 }
8728
8729 if (address_set == 0) {
8730 errmsg ("missing addresses\n");
8731 return -99;
8732 }
8733
8734 M(WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
8735 mp->enable_disable = enable_disable;
8736 mp->pid = getpid();
8737 mp->address = address.as_u32;
8738
8739 S; W;
8740}
8741
8742static int api_input_acl_set_interface (vat_main_t * vam)
8743{
8744 unformat_input_t * i = vam->input;
8745 vl_api_input_acl_set_interface_t *mp;
8746 f64 timeout;
8747 u32 sw_if_index;
8748 int sw_if_index_set;
8749 u32 ip4_table_index = ~0;
8750 u32 ip6_table_index = ~0;
8751 u32 l2_table_index = ~0;
8752 u8 is_add = 1;
8753
8754 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8755 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8756 sw_if_index_set = 1;
8757 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8758 sw_if_index_set = 1;
8759 else if (unformat (i, "del"))
8760 is_add = 0;
8761 else if (unformat (i, "ip4-table %d", &ip4_table_index))
8762 ;
8763 else if (unformat (i, "ip6-table %d", &ip6_table_index))
8764 ;
8765 else if (unformat (i, "l2-table %d", &l2_table_index))
8766 ;
8767 else {
8768 clib_warning ("parse error '%U'", format_unformat_error, i);
8769 return -99;
8770 }
8771 }
8772
8773 if (sw_if_index_set == 0) {
8774 errmsg ("missing interface name or sw_if_index\n");
8775 return -99;
8776 }
8777
8778 M(INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
8779
8780 mp->sw_if_index = ntohl(sw_if_index);
8781 mp->ip4_table_index = ntohl(ip4_table_index);
8782 mp->ip6_table_index = ntohl(ip6_table_index);
8783 mp->l2_table_index = ntohl(l2_table_index);
8784 mp->is_add = is_add;
8785
8786 S; W;
8787 /* NOTREACHED */
8788 return 0;
8789}
8790
8791static int
8792api_ip_address_dump (vat_main_t * vam)
8793{
8794 unformat_input_t * i = vam->input;
8795 vl_api_ip_address_dump_t * mp;
8796 u32 sw_if_index = ~0;
8797 u8 sw_if_index_set = 0;
8798 u8 ipv4_set = 0;
8799 u8 ipv6_set = 0;
8800 f64 timeout;
8801
8802 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8803 if (unformat (i, "sw_if_index %d", &sw_if_index))
8804 sw_if_index_set = 1;
8805 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8806 sw_if_index_set = 1;
8807 else if (unformat (i, "ipv4"))
8808 ipv4_set = 1;
8809 else if (unformat (i, "ipv6"))
8810 ipv6_set = 1;
8811 else
8812 break;
8813 }
8814
8815 if (ipv4_set && ipv6_set) {
8816 errmsg ("ipv4 and ipv6 flags cannot be both set\n");
8817 return -99;
8818 }
8819
8820 if ((!ipv4_set) && (!ipv6_set)) {
8821 errmsg ("no ipv4 nor ipv6 flag set\n");
8822 return -99;
8823 }
8824
8825 if (sw_if_index_set == 0) {
8826 errmsg ("missing interface name or sw_if_index\n");
8827 return -99;
8828 }
8829
8830 vam->current_sw_if_index = sw_if_index;
8831 vam->is_ipv6 = ipv6_set;
8832
8833 M(IP_ADDRESS_DUMP, ip_address_dump);
8834 mp->sw_if_index = ntohl(sw_if_index);
8835 mp->is_ipv6 = ipv6_set;
8836 S;
8837
8838 /* Use a control ping for synchronization */
8839 {
8840 vl_api_control_ping_t * mp;
8841 M(CONTROL_PING, control_ping);
8842 S;
8843 }
8844 W;
8845}
8846
8847static int
8848api_ip_dump (vat_main_t * vam)
8849{
8850 vl_api_ip_dump_t * mp;
8851 unformat_input_t * in = vam->input;
8852 int ipv4_set = 0;
8853 int ipv6_set = 0;
8854 int is_ipv6;
8855 f64 timeout;
8856 int i;
8857
8858 while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT) {
8859 if (unformat (in, "ipv4"))
8860 ipv4_set = 1;
8861 else if (unformat (in, "ipv6"))
8862 ipv6_set = 1;
8863 else
8864 break;
8865 }
8866
8867 if (ipv4_set && ipv6_set) {
8868 errmsg ("ipv4 and ipv6 flags cannot be both set\n");
8869 return -99;
8870 }
8871
8872 if ((!ipv4_set) && (!ipv6_set)) {
8873 errmsg ("no ipv4 nor ipv6 flag set\n");
8874 return -99;
8875 }
8876
8877 is_ipv6 = ipv6_set;
8878 vam->is_ipv6 = is_ipv6;
8879
8880 /* free old data */
8881 for (i = 0; i < vec_len(vam->ip_details_by_sw_if_index[is_ipv6]); i++) {
8882 vec_free(vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
8883 }
8884 vec_free(vam->ip_details_by_sw_if_index[is_ipv6]);
8885
8886 M(IP_DUMP, ip_dump);
8887 mp->is_ipv6 = ipv6_set;
8888 S;
8889
8890 /* Use a control ping for synchronization */
8891 {
8892 vl_api_control_ping_t * mp;
8893 M(CONTROL_PING, control_ping);
8894 S;
8895 }
8896 W;
8897}
8898
8899static int
8900api_ipsec_spd_add_del (vat_main_t * vam)
8901{
Dave Barachbfdedbd2016-01-20 09:11:55 -05008902#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -07008903 unformat_input_t * i = vam->input;
8904 vl_api_ipsec_spd_add_del_t *mp;
8905 f64 timeout;
8906 u32 spd_id = ~0;
8907 u8 is_add = 1;
8908
8909 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8910 if (unformat (i, "spd_id %d", &spd_id))
8911 ;
8912 else if (unformat (i, "del"))
8913 is_add = 0;
8914 else {
8915 clib_warning ("parse error '%U'", format_unformat_error, i);
8916 return -99;
8917 }
8918 }
8919 if (spd_id == ~0) {
8920 errmsg ("spd_id must be set\n");
8921 return -99;
8922 }
8923
8924 M(IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
8925
8926 mp->spd_id = ntohl(spd_id);
8927 mp->is_add = is_add;
8928
8929 S; W;
8930 /* NOTREACHED */
8931 return 0;
Dave Barachbfdedbd2016-01-20 09:11:55 -05008932#else
8933 clib_warning ("unsupported (no dpdk)");
8934 return -99;
8935#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -07008936}
8937
8938static int
8939api_ipsec_interface_add_del_spd (vat_main_t * vam)
8940{
Dave Barachbfdedbd2016-01-20 09:11:55 -05008941#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -07008942 unformat_input_t * i = vam->input;
8943 vl_api_ipsec_interface_add_del_spd_t *mp;
8944 f64 timeout;
8945 u32 sw_if_index;
8946 u8 sw_if_index_set = 0;
8947 u32 spd_id = (u32) ~0;
8948 u8 is_add = 1;
8949
8950 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8951 if (unformat (i, "del"))
8952 is_add = 0;
8953 else if (unformat (i, "spd_id %d", &spd_id))
8954 ;
8955 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8956 sw_if_index_set = 1;
8957 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8958 sw_if_index_set = 1;
8959 else {
8960 clib_warning ("parse error '%U'", format_unformat_error, i);
8961 return -99;
8962 }
8963
8964 }
8965
8966 if (spd_id == (u32) ~0) {
8967 errmsg ("spd_id must be set\n");
8968 return -99;
8969 }
8970
8971 if (sw_if_index_set == 0) {
8972 errmsg ("missing interface name or sw_if_index\n");
8973 return -99;
8974 }
8975
8976 M(IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
8977
8978 mp->spd_id = ntohl(spd_id);
8979 mp->sw_if_index = ntohl (sw_if_index);
8980 mp->is_add = is_add;
8981
8982 S; W;
8983 /* NOTREACHED */
8984 return 0;
Dave Barachbfdedbd2016-01-20 09:11:55 -05008985#else
8986 clib_warning ("unsupported (no dpdk)");
8987 return -99;
8988#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -07008989}
8990
8991static int
8992api_ipsec_spd_add_del_entry (vat_main_t * vam)
8993{
Dave Barachbfdedbd2016-01-20 09:11:55 -05008994#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -07008995 unformat_input_t * i = vam->input;
8996 vl_api_ipsec_spd_add_del_entry_t *mp;
8997 f64 timeout;
8998 u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
8999 u32 spd_id, sa_id, protocol = 0, policy = 0;
9000 i32 priority;
9001 u32 rport_start = 0, rport_stop = (u32) ~0;
9002 u32 lport_start = 0, lport_stop = (u32) ~0;
9003 ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
9004 ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
9005
9006 laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
9007 laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~0;
9008 laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
9009 laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
9010 laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~0;
9011 laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~0;
9012
9013 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9014 if (unformat (i, "del"))
9015 is_add = 0;
9016 if (unformat (i, "outbound"))
9017 is_outbound = 1;
9018 if (unformat (i, "inbound"))
9019 is_outbound = 0;
9020 else if (unformat (i, "spd_id %d", &spd_id))
9021 ;
9022 else if (unformat (i, "sa_id %d", &sa_id))
9023 ;
9024 else if (unformat (i, "priority %d", &priority))
9025 ;
9026 else if (unformat (i, "protocol %d", &protocol))
9027 ;
9028 else if (unformat (i, "lport_start %d", &lport_start))
9029 ;
9030 else if (unformat (i, "lport_stop %d", &lport_stop))
9031 ;
9032 else if (unformat (i, "rport_start %d", &rport_start))
9033 ;
9034 else if (unformat (i, "rport_stop %d", &rport_stop))
9035 ;
9036 else if (unformat (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
9037 {
9038 is_ipv6 = 0;
9039 is_ip_any =0;
9040 }
9041 else if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
9042 {
9043 is_ipv6 = 0;
9044 is_ip_any = 0;
9045 }
9046 else if (unformat (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
9047 {
9048 is_ipv6 = 0;
9049 is_ip_any = 0;
9050 }
9051 else if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
9052 {
9053 is_ipv6 = 0;
9054 is_ip_any = 0;
9055 }
9056 else if (unformat (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
9057 {
9058 is_ipv6 = 1;
9059 is_ip_any = 0;
9060 }
9061 else if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
9062 {
9063 is_ipv6 = 1;
9064 is_ip_any = 0;
9065 }
9066 else if (unformat (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
9067 {
9068 is_ipv6 = 1;
9069 is_ip_any = 0;
9070 }
9071 else if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
9072 {
9073 is_ipv6 = 1;
9074 is_ip_any = 0;
9075 }
9076 else if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
9077 {
9078 if (policy == IPSEC_POLICY_ACTION_RESOLVE) {
9079 clib_warning ("unsupported action: 'resolve'");
9080 return -99;
9081 }
9082 }
9083 else {
9084 clib_warning ("parse error '%U'", format_unformat_error, i);
9085 return -99;
9086 }
9087
9088 }
9089
9090 M(IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
9091
9092 mp->spd_id = ntohl(spd_id);
9093 mp->priority = ntohl(priority);
9094 mp->is_outbound = is_outbound;
9095
9096 mp->is_ipv6 = is_ipv6;
9097 if (is_ipv6 || is_ip_any) {
Damjan Marionf1213b82016-03-13 02:22:06 +01009098 clib_memcpy (mp->remote_address_start, &raddr6_start, sizeof(ip6_address_t));
9099 clib_memcpy (mp->remote_address_stop, &raddr6_stop, sizeof(ip6_address_t));
9100 clib_memcpy (mp->local_address_start, &laddr6_start, sizeof(ip6_address_t));
9101 clib_memcpy (mp->local_address_stop, &laddr6_stop, sizeof(ip6_address_t));
Ed Warnickecb9cada2015-12-08 15:45:58 -07009102 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01009103 clib_memcpy (mp->remote_address_start, &raddr4_start, sizeof(ip4_address_t));
9104 clib_memcpy (mp->remote_address_stop, &raddr4_stop, sizeof(ip4_address_t));
9105 clib_memcpy (mp->local_address_start, &laddr4_start, sizeof(ip4_address_t));
9106 clib_memcpy (mp->local_address_stop, &laddr4_stop, sizeof(ip4_address_t));
Ed Warnickecb9cada2015-12-08 15:45:58 -07009107 }
9108 mp->protocol = (u8) protocol;
9109 mp->local_port_start = ntohs((u16) lport_start);
9110 mp->local_port_stop = ntohs((u16) lport_stop);
9111 mp->remote_port_start = ntohs((u16) rport_start);
9112 mp->remote_port_stop = ntohs((u16) rport_stop);
9113 mp->policy = (u8) policy;
9114 mp->sa_id = ntohl(sa_id);
9115 mp->is_add = is_add;
9116 mp->is_ip_any = is_ip_any;
9117 S; W;
9118 /* NOTREACHED */
9119 return 0;
Dave Barachbfdedbd2016-01-20 09:11:55 -05009120#else
9121 clib_warning ("unsupported (no dpdk)");
9122 return -99;
9123#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -07009124}
9125
9126static int
9127api_ipsec_sad_add_del_entry (vat_main_t * vam)
9128{
Dave Barachbfdedbd2016-01-20 09:11:55 -05009129#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -07009130 unformat_input_t * i = vam->input;
9131 vl_api_ipsec_sad_add_del_entry_t *mp;
9132 f64 timeout;
9133 u32 sad_id, spi;
9134 u8 * ck, * ik;
9135 u8 is_add = 1;
9136
9137 u8 protocol = IPSEC_PROTOCOL_AH;
9138 u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
9139 u32 crypto_alg = 0, integ_alg = 0;
9140 ip4_address_t tun_src4;
9141 ip4_address_t tun_dst4;
9142 ip6_address_t tun_src6;
9143 ip6_address_t tun_dst6;
9144
9145 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9146 if (unformat (i, "del"))
9147 is_add = 0;
9148 else if (unformat (i, "sad_id %d", &sad_id))
9149 ;
9150 else if (unformat (i, "spi %d", &spi))
9151 ;
9152 else if (unformat (i, "esp"))
9153 protocol = IPSEC_PROTOCOL_ESP;
9154 else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4)) {
9155 is_tunnel = 1;
9156 is_tunnel_ipv6 = 0;
9157 }
9158 else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4)) {
9159 is_tunnel = 1;
9160 is_tunnel_ipv6 = 0;
9161 }
9162 else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6)) {
9163 is_tunnel = 1;
9164 is_tunnel_ipv6 = 1;
9165 }
9166 else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6)) {
9167 is_tunnel = 1;
9168 is_tunnel_ipv6 = 1;
9169 }
9170 else if (unformat (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg)) {
9171 if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
9172 crypto_alg > IPSEC_INTEG_ALG_SHA_512_256) {
9173 clib_warning ("unsupported crypto-alg: '%U'",
9174 format_ipsec_crypto_alg, crypto_alg);
9175 return -99;
9176 }
9177 }
9178 else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
9179 ;
9180 else if (unformat (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg)) {
9181 if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
9182 integ_alg > IPSEC_INTEG_ALG_SHA_512_256) {
9183 clib_warning ("unsupported integ-alg: '%U'",
9184 format_ipsec_integ_alg, integ_alg);
9185 return -99;
9186 }
9187 }
9188 else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
9189 ;
9190 else {
9191 clib_warning ("parse error '%U'", format_unformat_error, i);
9192 return -99;
9193 }
9194
9195 }
9196
9197 M(IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
9198
9199 mp->sad_id = ntohl(sad_id);
9200 mp->is_add = is_add;
9201 mp->protocol = protocol;
9202 mp->spi = ntohl(spi);
9203 mp->is_tunnel = is_tunnel;
9204 mp->is_tunnel_ipv6 = is_tunnel_ipv6;
9205 mp->crypto_algorithm = crypto_alg;
9206 mp->integrity_algorithm = integ_alg;
9207 mp->crypto_key_length = vec_len(ck);
9208 mp->integrity_key_length = vec_len(ik);
9209
9210 if (mp->crypto_key_length > sizeof(mp->crypto_key))
9211 mp->crypto_key_length = sizeof(mp->crypto_key);
9212
9213 if (mp->integrity_key_length > sizeof(mp->integrity_key))
9214 mp->integrity_key_length = sizeof(mp->integrity_key);
9215
Damjan Marionf1213b82016-03-13 02:22:06 +01009216 clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
9217 clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
Ed Warnickecb9cada2015-12-08 15:45:58 -07009218
9219 if (is_tunnel) {
9220 if (is_tunnel_ipv6) {
Damjan Marionf1213b82016-03-13 02:22:06 +01009221 clib_memcpy (mp->tunnel_src_address, &tun_src6, sizeof(ip6_address_t));
9222 clib_memcpy (mp->tunnel_dst_address, &tun_dst6, sizeof(ip6_address_t));
Ed Warnickecb9cada2015-12-08 15:45:58 -07009223 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01009224 clib_memcpy (mp->tunnel_src_address, &tun_src4, sizeof(ip4_address_t));
9225 clib_memcpy (mp->tunnel_dst_address, &tun_dst4, sizeof(ip4_address_t));
Ed Warnickecb9cada2015-12-08 15:45:58 -07009226 }
9227 }
9228
9229 S; W;
9230 /* NOTREACHED */
9231 return 0;
Dave Barachbfdedbd2016-01-20 09:11:55 -05009232#else
9233 clib_warning ("unsupported (no dpdk)");
9234 return -99;
9235#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -07009236}
9237
9238static int
9239api_ipsec_sa_set_key (vat_main_t * vam)
9240{
Dave Barachbfdedbd2016-01-20 09:11:55 -05009241#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -07009242 unformat_input_t * i = vam->input;
9243 vl_api_ipsec_sa_set_key_t *mp;
9244 f64 timeout;
9245 u32 sa_id;
9246 u8 * ck, * ik;
9247
9248 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9249 if (unformat (i, "sa_id %d", &sa_id))
9250 ;
9251 else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
9252 ;
9253 else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
9254 ;
9255 else {
9256 clib_warning ("parse error '%U'", format_unformat_error, i);
9257 return -99;
9258 }
9259 }
9260
9261 M(IPSEC_SA_SET_KEY, ipsec_set_sa_key);
9262
9263 mp->sa_id = ntohl(sa_id);
9264 mp->crypto_key_length = vec_len(ck);
9265 mp->integrity_key_length = vec_len(ik);
9266
9267 if (mp->crypto_key_length > sizeof(mp->crypto_key))
9268 mp->crypto_key_length = sizeof(mp->crypto_key);
9269
9270 if (mp->integrity_key_length > sizeof(mp->integrity_key))
9271 mp->integrity_key_length = sizeof(mp->integrity_key);
9272
Damjan Marionf1213b82016-03-13 02:22:06 +01009273 clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
9274 clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
Ed Warnickecb9cada2015-12-08 15:45:58 -07009275
9276 S; W;
9277 /* NOTREACHED */
9278 return 0;
Dave Barachbfdedbd2016-01-20 09:11:55 -05009279#else
9280 clib_warning ("unsupported (no dpdk)");
9281 return -99;
9282#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -07009283}
9284
Matus Fabiane5f42fe2016-04-08 11:18:08 +02009285static int
9286api_ikev2_profile_add_del (vat_main_t * vam)
9287{
9288#if DPDK > 0
9289 unformat_input_t * i = vam->input;
9290 vl_api_ikev2_profile_add_del_t * mp;
9291 f64 timeout;
9292 u8 is_add = 1;
9293 u8 * name = 0;
9294
9295 const char * valid_chars = "a-zA-Z0-9_";
9296
9297 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9298 if (unformat (i, "del"))
9299 is_add = 0;
9300 else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
9301 vec_add1 (name, 0);
9302 else {
9303 errmsg ("parse error '%U'", format_unformat_error, i);
9304 return -99;
9305 }
9306 }
9307
9308 if (!vec_len (name)) {
9309 errmsg ("profile name must be specified");
9310 return -99;
9311 }
9312
9313 if (vec_len (name) > 64) {
9314 errmsg ("profile name too long");
9315 return -99;
9316 }
9317
9318 M(IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
9319
Damjan Marionf1213b82016-03-13 02:22:06 +01009320 clib_memcpy(mp->name, name, vec_len (name));
Matus Fabiane5f42fe2016-04-08 11:18:08 +02009321 mp->is_add = is_add;
9322 vec_free (name);
9323
9324 S; W;
9325 /* NOTREACHED */
9326 return 0;
9327#else
9328 clib_warning ("unsupported (no dpdk)");
9329 return -99;
9330#endif
9331}
9332
9333static int
9334api_ikev2_profile_set_auth (vat_main_t * vam)
9335{
9336#if DPDK > 0
9337 unformat_input_t * i = vam->input;
9338 vl_api_ikev2_profile_set_auth_t * mp;
9339 f64 timeout;
9340 u8 * name = 0;
9341 u8 * data = 0;
9342 u32 auth_method = 0;
9343 u8 is_hex = 0;
9344
9345 const char * valid_chars = "a-zA-Z0-9_";
9346
9347 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9348 if (unformat (i, "name %U", unformat_token, valid_chars, &name))
9349 vec_add1 (name, 0);
9350 else if (unformat (i, "auth_method %U",
9351 unformat_ikev2_auth_method, &auth_method))
9352 ;
9353 else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
9354 is_hex = 1;
9355 else if (unformat (i, "auth_data %v", &data))
9356 ;
9357 else {
9358 errmsg ("parse error '%U'", format_unformat_error, i);
9359 return -99;
9360 }
9361 }
9362
9363 if (!vec_len (name)) {
9364 errmsg ("profile name must be specified");
9365 return -99;
9366 }
9367
9368 if (vec_len (name) > 64) {
9369 errmsg ("profile name too long");
9370 return -99;
9371 }
9372
9373 if (!vec_len(data)) {
9374 errmsg ("auth_data must be specified");
9375 return -99;
9376 }
9377
9378 if (!auth_method) {
9379 errmsg ("auth_method must be specified");
9380 return -99;
9381 }
9382
9383 M(IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
9384
9385 mp->is_hex = is_hex;
9386 mp->auth_method = (u8) auth_method;
9387 mp->data_len = vec_len (data);
Damjan Marionf1213b82016-03-13 02:22:06 +01009388 clib_memcpy (mp->name, name, vec_len (name));
9389 clib_memcpy (mp->data, data, vec_len (data));
Matus Fabiane5f42fe2016-04-08 11:18:08 +02009390 vec_free (name);
9391 vec_free (data);
9392
9393 S; W;
9394 /* NOTREACHED */
9395 return 0;
9396#else
9397 clib_warning ("unsupported (no dpdk)");
9398 return -99;
9399#endif
9400}
9401
9402static int
9403api_ikev2_profile_set_id (vat_main_t * vam)
9404{
9405#if DPDK > 0
9406 unformat_input_t * i = vam->input;
9407 vl_api_ikev2_profile_set_id_t * mp;
9408 f64 timeout;
9409 u8 * name = 0;
9410 u8 * data = 0;
9411 u8 is_local = 0;
9412 u32 id_type = 0;
9413 ip4_address_t ip4;
9414
9415 const char * valid_chars = "a-zA-Z0-9_";
9416
9417 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9418 if (unformat (i, "name %U", unformat_token, valid_chars, &name))
9419 vec_add1 (name, 0);
9420 else if (unformat (i, "id_type %U",
9421 unformat_ikev2_id_type, &id_type))
9422 ;
9423 else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
9424 {
9425 data = vec_new(u8, 4);
Damjan Marionf1213b82016-03-13 02:22:06 +01009426 clib_memcpy(data, ip4.as_u8, 4);
Matus Fabiane5f42fe2016-04-08 11:18:08 +02009427 }
9428 else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
9429 ;
9430 else if (unformat (i, "id_data %v", &data))
9431 ;
9432 else if (unformat (i, "local"))
9433 is_local = 1;
9434 else if (unformat (i, "remote"))
9435 is_local = 0;
9436 else {
9437 errmsg ("parse error '%U'", format_unformat_error, i);
9438 return -99;
9439 }
9440 }
9441
9442 if (!vec_len (name)) {
9443 errmsg ("profile name must be specified");
9444 return -99;
9445 }
9446
9447 if (vec_len (name) > 64) {
9448 errmsg ("profile name too long");
9449 return -99;
9450 }
9451
9452 if (!vec_len(data)) {
9453 errmsg ("id_data must be specified");
9454 return -99;
9455 }
9456
9457 if (!id_type) {
9458 errmsg ("id_type must be specified");
9459 return -99;
9460 }
9461
9462 M(IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
9463
9464 mp->is_local = is_local;
9465 mp->id_type = (u8) id_type;
9466 mp->data_len = vec_len (data);
Damjan Marionf1213b82016-03-13 02:22:06 +01009467 clib_memcpy (mp->name, name, vec_len (name));
9468 clib_memcpy (mp->data, data, vec_len (data));
Matus Fabiane5f42fe2016-04-08 11:18:08 +02009469 vec_free (name);
9470 vec_free (data);
9471
9472 S; W;
9473 /* NOTREACHED */
9474 return 0;
9475#else
9476 clib_warning ("unsupported (no dpdk)");
9477 return -99;
9478#endif
9479}
9480
9481static int
9482api_ikev2_profile_set_ts (vat_main_t * vam)
9483{
9484#if DPDK > 0
9485 unformat_input_t * i = vam->input;
9486 vl_api_ikev2_profile_set_ts_t * mp;
9487 f64 timeout;
9488 u8 * name = 0;
9489 u8 is_local = 0;
9490 u32 proto = 0, start_port = 0, end_port = (u32) ~0;
9491 ip4_address_t start_addr, end_addr;
9492
9493 const char * valid_chars = "a-zA-Z0-9_";
9494
9495 start_addr.as_u32 = 0;
9496 end_addr.as_u32 = (u32) ~0;
9497
9498 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9499 if (unformat (i, "name %U", unformat_token, valid_chars, &name))
9500 vec_add1 (name, 0);
9501 else if (unformat (i, "protocol %d", &proto))
9502 ;
9503 else if (unformat (i, "start_port %d", &start_port))
9504 ;
9505 else if (unformat (i, "end_port %d", &end_port))
9506 ;
9507 else if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
9508 ;
9509 else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
9510 ;
9511 else if (unformat (i, "local"))
9512 is_local = 1;
9513 else if (unformat (i, "remote"))
9514 is_local = 0;
9515 else {
9516 errmsg ("parse error '%U'", format_unformat_error, i);
9517 return -99;
9518 }
9519 }
9520
9521 if (!vec_len (name)) {
9522 errmsg ("profile name must be specified");
9523 return -99;
9524 }
9525
9526 if (vec_len (name) > 64) {
9527 errmsg ("profile name too long");
9528 return -99;
9529 }
9530
9531 M(IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
9532
9533 mp->is_local = is_local;
9534 mp->proto = (u8) proto;
9535 mp->start_port = (u16) start_port;
9536 mp->end_port = (u16) end_port;
9537 mp->start_addr = start_addr.as_u32;
9538 mp->end_addr = end_addr.as_u32;
Damjan Marionf1213b82016-03-13 02:22:06 +01009539 clib_memcpy (mp->name, name, vec_len (name));
Matus Fabiane5f42fe2016-04-08 11:18:08 +02009540 vec_free (name);
9541
9542 S; W;
9543 /* NOTREACHED */
9544 return 0;
9545#else
9546 clib_warning ("unsupported (no dpdk)");
9547 return -99;
9548#endif
9549}
9550
9551static int
9552api_ikev2_set_local_key (vat_main_t * vam)
9553{
9554#if DPDK > 0
9555 unformat_input_t * i = vam->input;
9556 vl_api_ikev2_set_local_key_t * mp;
9557 f64 timeout;
9558 u8 * file = 0;
9559
9560 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9561 if (unformat (i, "file %v", &file))
9562 vec_add1 (file, 0);
9563 else {
9564 errmsg ("parse error '%U'", format_unformat_error, i);
9565 return -99;
9566 }
9567 }
9568
9569 if (!vec_len (file)) {
9570 errmsg ("RSA key file must be specified");
9571 return -99;
9572 }
9573
9574 if (vec_len (file) > 256) {
9575 errmsg ("file name too long");
9576 return -99;
9577 }
9578
9579 M(IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
9580
Damjan Marionf1213b82016-03-13 02:22:06 +01009581 clib_memcpy (mp->key_file, file, vec_len (file));
Matus Fabiane5f42fe2016-04-08 11:18:08 +02009582 vec_free (file);
9583
9584 S; W;
9585 /* NOTREACHED */
9586 return 0;
9587#else
9588 clib_warning ("unsupported (no dpdk)");
9589 return -99;
9590#endif
9591}
9592
Ed Warnickecb9cada2015-12-08 15:45:58 -07009593/*
9594 * MAP
9595 */
9596static int api_map_add_domain (vat_main_t * vam)
9597{
9598 unformat_input_t *i = vam->input;
9599 vl_api_map_add_domain_t *mp;
9600 f64 timeout;
9601
9602 ip4_address_t ip4_prefix;
9603 ip6_address_t ip6_prefix;
9604 ip6_address_t ip6_src;
9605 u32 num_m_args = 0;
9606 u32 ip6_prefix_len, ip4_prefix_len, ea_bits_len, psid_offset,
9607 psid_length;
9608 u8 is_translation = 0;
9609 u32 mtu = 0;
9610 u8 ip6_src_len = 128;
9611
9612 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9613 if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
9614 &ip4_prefix, &ip4_prefix_len))
9615 num_m_args++;
9616 else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
9617 &ip6_prefix, &ip6_prefix_len))
9618 num_m_args++;
9619 else if (unformat (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src, &ip6_src_len))
9620 num_m_args++;
9621 else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
9622 num_m_args++;
9623 else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
9624 num_m_args++;
9625 else if (unformat (i, "psid-offset %d", &psid_offset))
9626 num_m_args++;
9627 else if (unformat (i, "psid-len %d", &psid_length))
9628 num_m_args++;
9629 else if (unformat (i, "mtu %d", &mtu))
9630 num_m_args++;
9631 else if (unformat (i, "map-t"))
9632 is_translation = 1;
9633 else {
9634 clib_warning ("parse error '%U'", format_unformat_error, i);
9635 return -99;
9636 }
9637 }
9638
9639 if (num_m_args != 6) {
9640 errmsg("mandatory argument(s) missing\n");
9641 return -99;
9642 }
9643
9644 /* Construct the API message */
9645 M(MAP_ADD_DOMAIN, map_add_domain);
9646
Damjan Marionf1213b82016-03-13 02:22:06 +01009647 clib_memcpy(mp->ip4_prefix, &ip4_prefix, sizeof(ip4_prefix));
Ed Warnickecb9cada2015-12-08 15:45:58 -07009648 mp->ip4_prefix_len = ip4_prefix_len;
9649
Damjan Marionf1213b82016-03-13 02:22:06 +01009650 clib_memcpy(mp->ip6_prefix, &ip6_prefix, sizeof(ip6_prefix));
Ed Warnickecb9cada2015-12-08 15:45:58 -07009651 mp->ip6_prefix_len = ip6_prefix_len;
9652
Damjan Marionf1213b82016-03-13 02:22:06 +01009653 clib_memcpy(mp->ip6_src, &ip6_src, sizeof(ip6_src));
Ed Warnickecb9cada2015-12-08 15:45:58 -07009654 mp->ip6_src_prefix_len = ip6_src_len;
9655
9656 mp->ea_bits_len = ea_bits_len;
9657 mp->psid_offset = psid_offset;
9658 mp->psid_length = psid_length;
9659 mp->is_translation = is_translation;
9660 mp->mtu = htons(mtu);
9661
9662 /* send it... */
9663 S;
9664
9665 /* Wait for a reply, return good/bad news */
9666 W;
9667}
9668
9669static int api_map_del_domain (vat_main_t * vam)
9670{
9671 unformat_input_t *i = vam->input;
9672 vl_api_map_del_domain_t *mp;
9673 f64 timeout;
9674
9675 u32 num_m_args = 0;
9676 u32 index;
9677
9678 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9679 if (unformat (i, "index %d", &index))
9680 num_m_args++;
9681 else {
9682 clib_warning ("parse error '%U'", format_unformat_error, i);
9683 return -99;
9684 }
9685 }
9686
9687 if (num_m_args != 1) {
9688 errmsg("mandatory argument(s) missing\n");
9689 return -99;
9690 }
9691
9692 /* Construct the API message */
9693 M(MAP_DEL_DOMAIN, map_del_domain);
9694
9695 mp->index = ntohl(index);
9696
9697 /* send it... */
9698 S;
9699
9700 /* Wait for a reply, return good/bad news */
9701 W;
9702}
9703
9704static int api_map_add_del_rule (vat_main_t * vam)
9705{
9706 unformat_input_t *i = vam->input;
9707 vl_api_map_add_del_rule_t *mp;
9708 f64 timeout;
9709 u8 is_add = 1;
9710 ip6_address_t ip6_dst;
9711 u32 num_m_args = 0, index, psid;
9712
9713 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9714 if (unformat (i, "index %d", &index))
9715 num_m_args++;
9716 else if (unformat (i, "psid %d", &psid))
9717 num_m_args++;
9718 else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
9719 num_m_args++;
9720 else if (unformat (i, "del")) {
9721 is_add = 0;
9722 } else {
9723 clib_warning ("parse error '%U'", format_unformat_error, i);
9724 return -99;
9725 }
9726 }
9727
9728 /* Construct the API message */
9729 M(MAP_ADD_DEL_RULE, map_add_del_rule);
9730
9731 mp->index = ntohl(index);
9732 mp->is_add = is_add;
Damjan Marionf1213b82016-03-13 02:22:06 +01009733 clib_memcpy(mp->ip6_dst, &ip6_dst, sizeof(ip6_dst));
Ed Warnickecb9cada2015-12-08 15:45:58 -07009734 mp->psid = ntohs(psid);
9735
9736 /* send it... */
9737 S;
9738
9739 /* Wait for a reply, return good/bad news */
9740 W;
9741}
9742
9743static int api_map_domain_dump (vat_main_t * vam)
9744{
9745 vl_api_map_domain_dump_t *mp;
9746 f64 timeout;
9747
9748 /* Construct the API message */
9749 M(MAP_DOMAIN_DUMP, map_domain_dump);
9750
9751 /* send it... */
9752 S;
9753
9754 /* Use a control ping for synchronization */
9755 {
9756 vl_api_control_ping_t * mp;
9757 M(CONTROL_PING, control_ping);
9758 S;
9759 }
9760 W;
9761}
9762
9763static int api_map_rule_dump (vat_main_t * vam)
9764{
9765 unformat_input_t *i = vam->input;
9766 vl_api_map_rule_dump_t *mp;
9767 f64 timeout;
9768 u32 domain_index = ~0;
9769
9770 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9771 if (unformat (i, "index %u", &domain_index))
9772 ;
9773 else
9774 break;
9775 }
9776
9777 if (domain_index == ~0) {
9778 clib_warning("parse error: domain index expected");
9779 return -99;
9780 }
9781
9782 /* Construct the API message */
9783 M(MAP_RULE_DUMP, map_rule_dump);
9784
9785 mp->domain_index = htonl(domain_index);
9786
9787 /* send it... */
9788 S;
9789
9790 /* Use a control ping for synchronization */
9791 {
9792 vl_api_control_ping_t * mp;
9793 M(CONTROL_PING, control_ping);
9794 S;
9795 }
9796 W;
9797}
9798
9799static void vl_api_map_add_domain_reply_t_handler
9800(vl_api_map_add_domain_reply_t * mp)
9801{
9802 vat_main_t * vam = &vat_main;
9803 i32 retval = ntohl(mp->retval);
9804
9805 if (vam->async_mode) {
9806 vam->async_errors += (retval < 0);
9807 } else {
9808 vam->retval = retval;
9809 vam->result_ready = 1;
9810 }
9811}
9812
9813static void vl_api_map_add_domain_reply_t_handler_json
9814(vl_api_map_add_domain_reply_t * mp)
9815{
9816 vat_main_t * vam = &vat_main;
9817 vat_json_node_t node;
9818
9819 vat_json_init_object(&node);
9820 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
9821 vat_json_object_add_uint(&node, "index", ntohl(mp->index));
9822
9823 vat_json_print(vam->ofp, &node);
9824 vat_json_free(&node);
9825
9826 vam->retval = ntohl(mp->retval);
9827 vam->result_ready = 1;
9828}
9829
9830static int
9831api_get_first_msg_id (vat_main_t * vam)
9832{
9833 vl_api_get_first_msg_id_t * mp;
9834 f64 timeout;
9835 unformat_input_t * i = vam->input;
9836 u8 * name;
9837 u8 name_set = 0;
9838
9839 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9840 if (unformat (i, "client %s", &name))
9841 name_set = 1;
9842 else
9843 break;
9844 }
9845
9846 if (name_set == 0) {
9847 errmsg ("missing client name\n");
9848 return -99;
9849 }
9850 vec_add1 (name, 0);
9851
9852 if (vec_len (name) > 63) {
9853 errmsg ("client name too long\n");
9854 return -99;
9855 }
9856
9857 M(GET_FIRST_MSG_ID, get_first_msg_id);
Damjan Marionf1213b82016-03-13 02:22:06 +01009858 clib_memcpy (mp->name, name, vec_len(name));
Ed Warnickecb9cada2015-12-08 15:45:58 -07009859 S; W;
9860 /* NOTREACHED */
9861 return 0;
9862}
9863
Dave Barachc07bf5d2016-02-17 17:52:26 -05009864static int api_cop_interface_enable_disable (vat_main_t * vam)
9865{
9866 unformat_input_t * line_input = vam->input;
9867 vl_api_cop_interface_enable_disable_t * mp;
9868 f64 timeout;
9869 u32 sw_if_index = ~0;
9870 u8 enable_disable = 1;
9871
9872 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
9873 if (unformat (line_input, "disable"))
9874 enable_disable = 0;
9875 if (unformat (line_input, "enable"))
9876 enable_disable = 1;
9877 else if (unformat (line_input, "%U", unformat_sw_if_index,
9878 vam, &sw_if_index))
9879 ;
9880 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
9881 ;
9882 else
9883 break;
9884 }
9885
9886 if (sw_if_index == ~0) {
9887 errmsg ("missing interface name or sw_if_index\n");
9888 return -99;
9889 }
9890
9891 /* Construct the API message */
9892 M(COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
9893 mp->sw_if_index = ntohl(sw_if_index);
9894 mp->enable_disable = enable_disable;
9895
9896 /* send it... */
9897 S;
9898 /* Wait for the reply */
9899 W;
9900}
9901
9902static int api_cop_whitelist_enable_disable (vat_main_t * vam)
9903{
9904 unformat_input_t * line_input = vam->input;
9905 vl_api_cop_whitelist_enable_disable_t * mp;
9906 f64 timeout;
9907 u32 sw_if_index = ~0;
9908 u8 ip4=0, ip6=0, default_cop=0;
9909 u32 fib_id;
9910
9911 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
9912 if (unformat (line_input, "ip4"))
9913 ip4 = 1;
9914 else if (unformat (line_input, "ip6"))
9915 ip6 = 1;
9916 else if (unformat (line_input, "default"))
9917 default_cop = 1;
9918 else if (unformat (line_input, "%U", unformat_sw_if_index,
9919 vam, &sw_if_index))
9920 ;
9921 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
9922 ;
9923 else if (unformat (line_input, "fib-id %d", &fib_id))
9924 ;
9925 else
9926 break;
9927 }
9928
9929 if (sw_if_index == ~0) {
9930 errmsg ("missing interface name or sw_if_index\n");
9931 return -99;
9932 }
9933
9934 /* Construct the API message */
9935 M(COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
9936 mp->sw_if_index = ntohl(sw_if_index);
9937 mp->fib_id = ntohl(fib_id);
9938 mp->ip4 = ip4;
9939 mp->ip6 = ip6;
9940 mp->default_cop = default_cop;
9941
9942 /* send it... */
9943 S;
9944 /* Wait for the reply */
9945 W;
9946}
9947
Dave Barachb44e9bc2016-02-19 09:06:23 -05009948static int api_get_node_graph (vat_main_t * vam)
9949{
9950 vl_api_get_node_graph_t * mp;
9951 f64 timeout;
9952
9953 M(GET_NODE_GRAPH, get_node_graph);
9954
9955 /* send it... */
9956 S;
9957 /* Wait for the reply */
9958 W;
9959}
9960
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02009961static int
9962api_lisp_add_del_locator_set(vat_main_t * vam)
9963{
9964 unformat_input_t * input = vam->input;
9965 vl_api_lisp_add_del_locator_set_t *mp;
9966 f64 timeout = ~0;
9967 u8 is_add = 1;
9968 u8 *locator_set_name = NULL;
9969 u8 locator_set_name_set = 0;
9970
9971 /* Parse args required to build the message */
9972 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
9973 if (unformat(input, "del")) {
9974 is_add = 0;
9975 } else if (unformat(input, "locator-set %s", &locator_set_name)) {
9976 locator_set_name_set = 1;
9977 } else
9978 break;
9979 }
9980
9981 if (locator_set_name_set == 0) {
9982 errmsg ("missing locator-set name");
9983 return -99;
9984 }
9985
9986 if (vec_len(locator_set_name) > 64) {
9987 errmsg ("locator-set name too long\n");
9988 vec_free(locator_set_name);
9989 return -99;
9990 }
9991 vec_add1(locator_set_name, 0);
9992
9993 /* Construct the API message */
9994 M(LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set);
9995
9996 mp->is_add = is_add;
Damjan Marionf1213b82016-03-13 02:22:06 +01009997 clib_memcpy(mp->locator_set_name, locator_set_name,
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02009998 vec_len(locator_set_name));
9999 vec_free(locator_set_name);
10000
10001 /* send it... */
10002 S;
10003
10004 /* Wait for a reply... */
10005 W;
10006
10007 /* NOTREACHED */
10008 return 0;
10009}
10010
10011static int
10012api_lisp_add_del_locator(vat_main_t * vam)
10013{
10014 unformat_input_t * input = vam->input;
10015 vl_api_lisp_add_del_locator_t *mp;
10016 f64 timeout = ~0;
10017 u32 tmp_if_index = ~0;
10018 u32 sw_if_index = ~0;
10019 u8 sw_if_index_set = 0;
10020 u8 sw_if_index_if_name_set = 0;
Filip Tehlarc4770ec2016-06-30 09:46:08 +020010021 u32 priority = ~0;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010022 u8 priority_set = 0;
Filip Tehlarc4770ec2016-06-30 09:46:08 +020010023 u32 weight = ~0;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010024 u8 weight_set = 0;
10025 u8 is_add = 1;
10026 u8 *locator_set_name = NULL;
10027 u8 locator_set_name_set = 0;
10028
10029 /* Parse args required to build the message */
10030 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
10031 if (unformat(input, "del")) {
10032 is_add = 0;
10033 } else if (unformat(input, "locator-set %s", &locator_set_name)) {
10034 locator_set_name_set = 1;
10035 } else if (unformat(input, "iface %U", unformat_sw_if_index, vam,
10036 &tmp_if_index)) {
10037 sw_if_index_if_name_set = 1;
10038 sw_if_index = tmp_if_index;
10039 } else if (unformat(input,"sw_if_index %d", &tmp_if_index)) {
10040 sw_if_index_set = 1;
10041 sw_if_index = tmp_if_index;
10042 } else if (unformat(input, "p %d", &priority)) {
10043 priority_set = 1;
10044 } else if (unformat(input, "w %d", &weight)) {
10045 weight_set = 1;
10046 } else
10047 break;
10048 }
10049
10050 if (locator_set_name_set == 0) {
10051 errmsg ("missing locator-set name");
10052 return -99;
10053 }
10054
10055 if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0) {
10056 errmsg ("missing sw_if_index");
10057 vec_free(locator_set_name);
10058 return -99;
10059 }
10060
10061 if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0) {
10062 errmsg ("cannot use both params interface name and sw_if_index");
10063 vec_free(locator_set_name);
10064 return -99;
10065 }
10066
10067 if (priority_set == 0) {
10068 errmsg ("missing locator-set priority\n");
10069 vec_free(locator_set_name);
10070 return -99;
10071 }
10072
10073 if (weight_set == 0) {
10074 errmsg ("missing locator-set weight\n");
10075 vec_free(locator_set_name);
10076 return -99;
10077 }
10078
10079 if (vec_len(locator_set_name) > 64) {
10080 errmsg ("locator-set name too long\n");
10081 vec_free(locator_set_name);
10082 return -99;
10083 }
10084 vec_add1(locator_set_name, 0);
10085
10086 /* Construct the API message */
10087 M(LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
10088
10089 mp->is_add = is_add;
10090 mp->sw_if_index = ntohl(sw_if_index);
10091 mp->priority = priority;
10092 mp->weight = weight;
Damjan Marionf1213b82016-03-13 02:22:06 +010010093 clib_memcpy(mp->locator_set_name, locator_set_name,
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010094 vec_len(locator_set_name));
10095 vec_free(locator_set_name);
10096
10097 /* send it... */
10098 S;
10099
10100 /* Wait for a reply... */
10101 W;
10102
10103 /* NOTREACHED */
10104 return 0;
10105}
10106
10107static int
10108api_lisp_add_del_local_eid(vat_main_t * vam)
10109{
10110 unformat_input_t * input = vam->input;
10111 vl_api_lisp_add_del_local_eid_t *mp;
10112 f64 timeout = ~0;
10113 u8 is_add = 1;
10114 u8 eidv4_set = 0;
10115 u8 eidv6_set = 0;
Filip Tehlar006eb262016-06-27 13:09:20 +020010116 u8 eid_type = (u8)~0;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010117 ip4_address_t eidv4;
10118 ip6_address_t eidv6;
Filip Tehlar006eb262016-06-27 13:09:20 +020010119 u8 mac[6] = {0};
Filip Tehlarc4770ec2016-06-30 09:46:08 +020010120 u32 tmp_eid_lenght = ~0;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010121 u8 eid_lenght = ~0;
10122 u8 *locator_set_name = NULL;
10123 u8 locator_set_name_set = 0;
Filip Tehlar324112f2016-06-02 16:07:38 +020010124 u32 vni = 0;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010125
10126 /* Parse args required to build the message */
10127 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
10128 if (unformat(input, "del")) {
10129 is_add = 0;
Filip Tehlar324112f2016-06-02 16:07:38 +020010130 } else if (unformat(input, "vni &d", &vni)) {
10131 ;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010132 } else if (unformat(input, "eid %U/%d", unformat_ip4_address,
10133 &eidv4, &tmp_eid_lenght)) {
10134 eid_lenght = tmp_eid_lenght;
10135 eidv4_set = 1;
Filip Tehlar006eb262016-06-27 13:09:20 +020010136 eid_type = 0; /* ipv4 type */
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010137 } else if (unformat(input, "eid %U/%d", unformat_ip6_address,
10138 &eidv6, &tmp_eid_lenght)) {
10139 eid_lenght = tmp_eid_lenght;
10140 eidv6_set = 1;
Filip Tehlar006eb262016-06-27 13:09:20 +020010141 eid_type = 1; /* ipv6 type */
10142 } else if (unformat(input, "eid %U", unformat_ethernet_address, mac)) {
10143 eid_type = 2; /* mac type */
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010144 } else if (unformat(input, "locator-set %s", &locator_set_name)) {
10145 locator_set_name_set = 1;
10146 } else
10147 break;
10148 }
10149
10150 if (locator_set_name_set == 0) {
10151 errmsg ("missing locator-set name\n");
10152 return -99;
10153 }
10154
Filip Tehlar006eb262016-06-27 13:09:20 +020010155 if ((u8)~0 == eid_type) {
10156 errmsg ("EID address not set!");
10157 vec_free(locator_set_name);
10158 return -99;
10159 }
10160
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010161 if (vec_len(locator_set_name) > 64) {
10162 errmsg ("locator-set name too long\n");
10163 vec_free(locator_set_name);
10164 return -99;
10165 }
10166 vec_add1(locator_set_name, 0);
10167
10168 if (eidv4_set && eidv6_set) {
10169 errmsg ("both eid v4 and v6 addresses set\n");
10170 vec_free(locator_set_name);
10171 return -99;
10172 }
10173
Andrej Kozemcak3e53fc52016-05-09 10:52:16 +020010174 if (eidv4_set && eid_lenght > 32) {
10175 errmsg ("eid prefix to big\n");
10176 vec_free(locator_set_name);
10177 return -99;
10178 }
10179
10180 if (eidv6_set && eid_lenght > 128) {
10181 errmsg ("eid prefix to big\n");
10182 vec_free(locator_set_name);
10183 return -99;
10184 }
10185
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010186 /* Construct the API message */
10187 M(LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
10188
10189 mp->is_add = is_add;
Filip Tehlar006eb262016-06-27 13:09:20 +020010190 switch (eid_type) {
10191 case 0: /* ipv4 */
10192 clib_memcpy (mp->eid, &eidv4, sizeof(eidv4));
10193 break;
10194 case 1: /* ipv6 */
10195 clib_memcpy (mp->eid, &eidv6, sizeof(eidv6));
10196 break;
10197 case 2: /* mac */
10198 clib_memcpy (mp->eid, mac, 6);
10199 break;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010200 }
Filip Tehlar006eb262016-06-27 13:09:20 +020010201 mp->eid_type = eid_type;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010202 mp->prefix_len = eid_lenght;
Filip Tehlar324112f2016-06-02 16:07:38 +020010203 mp->vni = clib_host_to_net_u32(vni);
Damjan Marionf1213b82016-03-13 02:22:06 +010010204 clib_memcpy(mp->locator_set_name, locator_set_name,
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010205 vec_len(locator_set_name));
10206 vec_free(locator_set_name);
10207
10208 /* send it... */
10209 S;
10210
10211 /* Wait for a reply... */
10212 W;
10213
10214 /* NOTREACHED */
10215 return 0;
10216}
10217
10218static int
10219api_lisp_gpe_add_del_fwd_entry(vat_main_t * vam)
10220{
10221 unformat_input_t * input = vam->input;
10222 vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
10223 f64 timeout = ~0;
10224 u8 is_add = 1;
10225 u8 eidv4_set = 0, slocv4_set = 0, dlocv4_set = 0;
10226 u8 eidv6_set = 0, slocv6_set = 0, dlocv6_set = 0;
10227 ip4_address_t eidv4, slocv4, dlocv4;
10228 ip6_address_t eidv6, slocv6, dlocv6;
Filip Tehlarc4770ec2016-06-30 09:46:08 +020010229 u32 tmp_eid_lenght = ~0;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010230 u8 eid_lenght = ~0;
10231
10232 /* Parse args required to build the message */
10233 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
10234 if (unformat(input, "del")) {
10235 is_add = 0;
10236 } else if (unformat(input, "eid %U/%d", unformat_ip4_address,
10237 &eidv4, &tmp_eid_lenght)) {
10238 eid_lenght = tmp_eid_lenght;
10239 eidv4_set = 1;
10240 } else if (unformat(input, "eid %U/%d", unformat_ip6_address,
10241 &eidv6, &tmp_eid_lenght)) {
10242 eid_lenght = tmp_eid_lenght;
10243 eidv6_set = 1;
10244 } else if (unformat(input, "sloc %U", unformat_ip4_address, &slocv4)) {
10245 slocv4_set = 1;
10246 } else if (unformat(input, "sloc %U", unformat_ip6_address, &slocv6)) {
10247 slocv6_set = 1;
10248 } else if (unformat(input, "dloc %U", unformat_ip4_address, &dlocv4)) {
10249 dlocv4_set = 1;
10250 } else if (unformat(input, "dloc %U", unformat_ip6_address, &dlocv6)) {
10251 dlocv6_set = 1;
10252 } else
10253 break;
10254 }
10255
10256 if (eidv4_set && eidv6_set) {
10257 errmsg ("both eid v4 and v6 addresses set\n");
10258 return -99;
10259 }
10260
10261 if (!eidv4_set && !eidv6_set) {
10262 errmsg ("eid addresses not set\n");
10263 return -99;
10264 }
10265
10266 if (slocv4_set && slocv6_set) {
10267 errmsg ("both source v4 and v6 addresses set\n");
10268 return -99;
10269 }
10270
10271 if (!slocv4_set && !slocv6_set) {
10272 errmsg ("source addresses not set\n");
10273 return -99;
10274 }
10275
10276 if (dlocv4_set && dlocv6_set) {
10277 errmsg ("both destination v4 and v6 addresses set\n");
10278 return -99;
10279 }
10280
10281 if (dlocv4_set && dlocv6_set) {
10282 errmsg ("destination addresses not set\n");
10283 return -99;
10284 }
10285
10286 if (!(slocv4_set == dlocv4_set && slocv6_set == dlocv6_set)) {
10287 errmsg ("mixing type of source and destination address\n");
10288 return -99;
10289 }
10290
10291 /* Construct the API message */
10292 M(LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
10293
10294 mp->is_add = is_add;
10295 if (eidv6_set) {
10296 mp->eid_is_ipv6 = 1;
Damjan Marionf1213b82016-03-13 02:22:06 +010010297 clib_memcpy(mp->eid_ip_address, &eidv6, sizeof(eidv6));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010298 } else {
10299 mp->eid_is_ipv6 = 0;
Damjan Marionf1213b82016-03-13 02:22:06 +010010300 clib_memcpy(mp->eid_ip_address, &eidv4, sizeof(eidv4));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010301 }
10302 mp->eid_prefix_len = eid_lenght;
10303 if (slocv6_set) {
10304 mp->address_is_ipv6 = 1;
Damjan Marionf1213b82016-03-13 02:22:06 +010010305 clib_memcpy(mp->source_ip_address, &slocv6, sizeof(slocv6));
10306 clib_memcpy(mp->destination_ip_address, &dlocv6, sizeof(dlocv6));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010307 } else {
10308 mp->address_is_ipv6 = 0;
Damjan Marionf1213b82016-03-13 02:22:06 +010010309 clib_memcpy(mp->source_ip_address, &slocv4, sizeof(slocv4));
10310 clib_memcpy(mp->destination_ip_address, &dlocv4, sizeof(dlocv4));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010311 }
10312
10313 /* send it... */
10314 S;
10315
10316 /* Wait for a reply... */
10317 W;
10318
10319 /* NOTREACHED */
10320 return 0;
10321}
10322
10323static int
10324api_lisp_add_del_map_resolver(vat_main_t * vam)
10325{
10326 unformat_input_t * input = vam->input;
10327 vl_api_lisp_add_del_map_resolver_t *mp;
10328 f64 timeout = ~0;
10329 u8 is_add = 1;
10330 u8 ipv4_set = 0;
10331 u8 ipv6_set = 0;
10332 ip4_address_t ipv4;
10333 ip6_address_t ipv6;
10334
10335 /* Parse args required to build the message */
10336 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
10337 if (unformat(input, "del")) {
10338 is_add = 0;
10339 } else if (unformat(input, "%U", unformat_ip4_address, &ipv4)) {
10340 ipv4_set = 1;
10341 } else if (unformat(input, "%U", unformat_ip6_address, &ipv6)) {
10342 ipv6_set = 1;
10343 } else
10344 break;
10345 }
10346
10347 if (ipv4_set && ipv6_set) {
10348 errmsg ("both eid v4 and v6 addresses set\n");
10349 return -99;
10350 }
10351
10352 if (!ipv4_set && !ipv6_set) {
10353 errmsg ("eid addresses not set\n");
10354 return -99;
10355 }
10356
10357 /* Construct the API message */
10358 M(LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
10359
10360 mp->is_add = is_add;
10361 if (ipv6_set) {
10362 mp->is_ipv6 = 1;
Damjan Marionf1213b82016-03-13 02:22:06 +010010363 clib_memcpy(mp->ip_address, &ipv6, sizeof(ipv6));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010364 } else {
10365 mp->is_ipv6 = 0;
Damjan Marionf1213b82016-03-13 02:22:06 +010010366 clib_memcpy(mp->ip_address, &ipv4, sizeof(ipv4));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010367 }
10368
10369 /* send it... */
10370 S;
10371
10372 /* Wait for a reply... */
10373 W;
10374
10375 /* NOTREACHED */
10376 return 0;
10377}
10378
10379static int
Florin Coras577c3552016-04-21 00:45:40 +020010380api_lisp_gpe_enable_disable (vat_main_t * vam)
10381{
10382 unformat_input_t * input = vam->input;
10383 vl_api_lisp_gpe_enable_disable_t *mp;
10384 f64 timeout = ~0;
10385 u8 is_set = 0;
10386 u8 is_en = 1;
10387
10388 /* Parse args required to build the message */
10389 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
10390 if (unformat(input, "enable")) {
10391 is_set = 1;
10392 is_en = 1;
10393 } else if (unformat(input, "disable")) {
10394 is_set = 1;
10395 is_en = 0;
10396 } else
10397 break;
10398 }
10399
10400 if (is_set == 0) {
10401 errmsg("Value not set\n");
10402 return -99;
10403 }
10404
10405 /* Construct the API message */
10406 M(LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
10407
10408 mp->is_en = is_en;
10409
10410 /* send it... */
10411 S;
10412
10413 /* Wait for a reply... */
10414 W;
10415
10416 /* NOTREACHED */
10417 return 0;
10418}
10419
10420static int
Filip Tehlar46d4e362016-05-09 09:39:26 +020010421api_lisp_enable_disable (vat_main_t * vam)
10422{
10423 unformat_input_t * input = vam->input;
10424 vl_api_lisp_enable_disable_t *mp;
10425 f64 timeout = ~0;
10426 u8 is_set = 0;
10427 u8 is_en = 0;
10428
10429 /* Parse args required to build the message */
10430 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10431 {
10432 if (unformat (input, "enable"))
10433 {
10434 is_set = 1;
10435 is_en = 1;
10436 }
10437 else if (unformat (input, "disable"))
10438 {
10439 is_set = 1;
10440 }
10441 else
10442 break;
10443 }
10444
10445 if (!is_set)
10446 {
10447 errmsg ("Value not set\n");
10448 return -99;
10449 }
10450
10451 /* Construct the API message */
10452 M(LISP_ENABLE_DISABLE, lisp_enable_disable);
10453
10454 mp->is_en = is_en;
10455
10456 /* send it... */
10457 S;
10458
10459 /* Wait for a reply... */
10460 W;
10461
10462 /* NOTREACHED */
10463 return 0;
10464}
10465
Filip Tehlar195bcee2016-05-13 17:37:35 +020010466/** Used for transferring locators via VPP API */
10467typedef CLIB_PACKED(struct
10468{
10469 u8 is_ip4; /**< is locator an IPv4 address? */
10470 u8 addr[16]; /**< IPv4/IPv6 address */
10471}) rloc_t;
10472
10473/**
Filip Tehlar53f09e32016-05-19 14:25:44 +020010474 * Enable/disable LISP proxy ITR.
10475 *
10476 * @param vam vpp API test context
10477 * @return return code
10478 */
10479static int
10480api_lisp_pitr_set_locator_set (vat_main_t * vam)
10481{
10482 f64 timeout = ~0;
10483 u8 ls_name_set = 0;
10484 unformat_input_t * input = vam->input;
10485 vl_api_lisp_pitr_set_locator_set_t * mp;
10486 u8 is_add = 1;
10487 u8 * ls_name = 0;
10488
10489 /* Parse args required to build the message */
10490 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10491 {
10492 if (unformat (input, "del"))
10493 is_add = 0;
10494 else if (unformat (input, "locator-set %s", &ls_name))
10495 ls_name_set = 1;
10496 else
10497 {
10498 errmsg ("parse error '%U'", format_unformat_error, input);
10499 return -99;
10500 }
10501 }
10502
10503 if (!ls_name_set)
10504 {
10505 errmsg ("locator-set name not set!");
10506 return -99;
10507 }
10508
10509 M(LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
10510
10511 mp->is_add = is_add;
10512 clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
10513 vec_free (ls_name);
10514
10515 /* send */
10516 S;
10517
10518 /* wait for reply */
10519 W;
10520
10521 /* notreached*/
10522 return 0;
10523}
10524
10525/**
Filip Tehlar324112f2016-06-02 16:07:38 +020010526 * Add/delete mapping between vni and vrf
10527 */
10528static int
10529api_lisp_eid_table_add_del_map (vat_main_t * vam)
10530{
10531 f64 timeout = ~0;
10532 unformat_input_t * input = vam->input;
10533 vl_api_lisp_eid_table_add_del_map_t *mp;
10534 u8 is_add = 1, vni_set = 0, vrf_set = 0;
10535 u32 vni, vrf;
10536
10537 /* Parse args required to build the message */
10538 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10539 {
10540 if (unformat (input, "del"))
10541 is_add = 0;
10542 else if (unformat(input, "vrf %d", &vrf))
10543 vrf_set = 1;
10544 else if (unformat(input, "vni %d", &vni))
10545 vni_set = 1;
10546 else
10547 break;
10548 }
10549
10550 if (!vni_set || !vrf_set)
10551 {
10552 errmsg ("missing arguments!");
10553 return -99;
10554 }
10555
10556 M(LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
10557
10558 mp->is_add = is_add;
10559 mp->vni = htonl (vni);
10560 mp->vrf = htonl (vrf);
10561
10562 /* send */
10563 S;
10564
10565 /* wait for reply */
10566 W;
10567
10568 /* notreached*/
10569 return 0;
10570}
10571
10572/**
Florin Corasf727db92016-06-23 15:01:58 +020010573 * Add/del remote mapping to/from LISP control plane
Filip Tehlar195bcee2016-05-13 17:37:35 +020010574 *
10575 * @param vam vpp API test context
10576 * @return return code
10577 */
10578static int
10579api_lisp_add_del_remote_mapping (vat_main_t * vam)
10580{
10581 unformat_input_t * input = vam->input;
10582 vl_api_lisp_add_del_remote_mapping_t *mp;
10583 f64 timeout = ~0;
10584 u32 vni = 0;
Filip Tehlar195bcee2016-05-13 17:37:35 +020010585 ip4_address_t seid4, deid4, rloc4;
10586 ip6_address_t seid6, deid6, rloc6;
Filip Tehlar006eb262016-06-27 13:09:20 +020010587 u8 deid_mac[6] = {0};
10588 u8 seid_mac[6] = {0};
10589 u8 deid_type, seid_type;
Filip Tehlar195bcee2016-05-13 17:37:35 +020010590 u32 seid_len = 0, deid_len = 0, len;
Filip Tehlar58f886a2016-05-30 15:57:40 +020010591 u8 is_add = 1, del_all = 0;
Filip Tehlar195bcee2016-05-13 17:37:35 +020010592 u32 action = ~0;
10593 rloc_t * rlocs = 0, rloc;
10594
Filip Tehlar006eb262016-06-27 13:09:20 +020010595 seid_type = deid_type = (u8)~0;
10596
Filip Tehlar195bcee2016-05-13 17:37:35 +020010597 /* Parse args required to build the message */
10598 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
Filip Tehlar58f886a2016-05-30 15:57:40 +020010599 if (unformat(input, "del-all")) {
10600 del_all = 1;
10601 } else if (unformat(input, "del")) {
Filip Tehlar195bcee2016-05-13 17:37:35 +020010602 is_add = 0;
10603 } else if (unformat(input, "add")) {
10604 is_add = 1;
10605 } else if (unformat(input, "deid %U/%d", unformat_ip4_address,
10606 &deid4, &len)) {
Filip Tehlar006eb262016-06-27 13:09:20 +020010607 deid_type = 0; /* ipv4 */
Filip Tehlar195bcee2016-05-13 17:37:35 +020010608 deid_len = len;
10609 } else if (unformat(input, "deid %U/%d", unformat_ip6_address,
10610 &deid6, &len)) {
Filip Tehlar006eb262016-06-27 13:09:20 +020010611 deid_type = 1; /* ipv6 */
Filip Tehlar195bcee2016-05-13 17:37:35 +020010612 deid_len = len;
Filip Tehlar006eb262016-06-27 13:09:20 +020010613 } else if (unformat(input, "deid %U", unformat_ethernet_address,
10614 deid_mac)) {
10615 deid_type = 2; /* mac */
Filip Tehlar195bcee2016-05-13 17:37:35 +020010616 } else if (unformat(input, "seid %U/%d", unformat_ip4_address,
10617 &seid4, &len)) {
Filip Tehlar006eb262016-06-27 13:09:20 +020010618 seid_type = 0; /* ipv4 */
Filip Tehlar195bcee2016-05-13 17:37:35 +020010619 seid_len = len;
10620 } else if (unformat(input, "seid %U/%d", unformat_ip6_address,
10621 &seid6, &len)) {
Filip Tehlar006eb262016-06-27 13:09:20 +020010622 seid_type = 1; /* ipv6 */
Filip Tehlar195bcee2016-05-13 17:37:35 +020010623 seid_len = len;
Filip Tehlar006eb262016-06-27 13:09:20 +020010624 } else if (unformat(input, "seid %U", unformat_ethernet_address,
10625 seid_mac)) {
10626 seid_type = 2; /* mac */
Filip Tehlar195bcee2016-05-13 17:37:35 +020010627 } else if (unformat(input, "vni %d", &vni)) {
10628 ;
10629 } else if (unformat(input, "rloc %U", unformat_ip4_address, &rloc4)) {
10630 rloc.is_ip4 = 1;
10631 clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
10632 vec_add1 (rlocs, rloc);
10633 } else if (unformat(input, "rloc %U", unformat_ip6_address, &rloc6)) {
10634 rloc.is_ip4 = 0;
10635 clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
10636 vec_add1 (rlocs, rloc);
10637 } else if (unformat(input, "action %d", &action)) {
10638 ;
10639 } else {
10640 clib_warning ("parse error '%U'", format_unformat_error, input);
10641 return -99;
10642 }
10643 }
10644
Filip Tehlar006eb262016-06-27 13:09:20 +020010645 if ((u8)~0 == deid_type) {
Filip Tehlar195bcee2016-05-13 17:37:35 +020010646 errmsg ("missing params!");
10647 return -99;
10648 }
10649
Filip Tehlar006eb262016-06-27 13:09:20 +020010650 if (seid_type != deid_type) {
10651 errmsg ("source and destination EIDs are of different types!");
Filip Tehlar195bcee2016-05-13 17:37:35 +020010652 return -99;
10653 }
10654
10655 if (is_add && (~0 == action)
10656 && 0 == vec_len (rlocs)) {
10657 errmsg ("no action set for negative map-reply!");
10658 return -99;
10659 }
10660
10661 M(LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping);
10662 mp->is_add = is_add;
10663 mp->vni = htonl (vni);
10664 mp->seid_len = seid_len;
10665 mp->action = (u8) action;
10666 mp->deid_len = deid_len;
Filip Tehlar58f886a2016-05-30 15:57:40 +020010667 mp->del_all = del_all;
Filip Tehlar006eb262016-06-27 13:09:20 +020010668 mp->eid_type = deid_type;
Filip Tehlar195bcee2016-05-13 17:37:35 +020010669
Filip Tehlar006eb262016-06-27 13:09:20 +020010670 switch (mp->eid_type) {
10671 case 0:
10672 clib_memcpy (mp->seid, &seid4, sizeof (seid4));
Filip Tehlar195bcee2016-05-13 17:37:35 +020010673 clib_memcpy (mp->deid, &deid4, sizeof (deid4));
Filip Tehlar006eb262016-06-27 13:09:20 +020010674 break;
10675 case 1:
10676 clib_memcpy (mp->seid, &seid6, sizeof (seid6));
Filip Tehlar195bcee2016-05-13 17:37:35 +020010677 clib_memcpy (mp->deid, &deid6, sizeof (deid6));
Filip Tehlar006eb262016-06-27 13:09:20 +020010678 break;
10679 case 2:
10680 clib_memcpy (mp->seid, seid_mac, 6);
10681 clib_memcpy (mp->deid, deid_mac, 6);
10682 break;
10683 default:
10684 errmsg ("unknown EID type %d!", mp->eid_type);
10685 return 0;
Filip Tehlar195bcee2016-05-13 17:37:35 +020010686 }
10687
10688 mp->rloc_num = vec_len (rlocs);
10689 clib_memcpy (mp->rlocs, rlocs, (sizeof (rloc_t) * vec_len (rlocs)));
10690 vec_free (rlocs);
10691
10692 /* send it... */
10693 S;
10694
10695 /* Wait for a reply... */
10696 W;
10697
10698 /* NOTREACHED */
10699 return 0;
10700}
10701
Florin Corasf727db92016-06-23 15:01:58 +020010702/**
10703 * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
10704 * forwarding entries in data-plane accordingly.
10705 *
10706 * @param vam vpp API test context
10707 * @return return code
10708 */
10709static int
10710api_lisp_add_del_adjacency (vat_main_t * vam)
10711{
10712 unformat_input_t * input = vam->input;
10713 vl_api_lisp_add_del_adjacency_t *mp;
10714 f64 timeout = ~0;
10715 u32 vni = 0;
10716 ip4_address_t seid4, deid4, rloc4;
10717 ip6_address_t seid6, deid6, rloc6;
10718 u8 deid_mac[6] = {0};
10719 u8 seid_mac[6] = {0};
10720 u8 deid_type, seid_type;
10721 u32 seid_len = 0, deid_len = 0, len;
10722 u8 is_add = 1;
10723 u32 action = ~0;
10724 rloc_t * rlocs = 0, rloc;
10725
10726 memset(mp, 0, sizeof(mp[0]));
10727 seid_type = deid_type = (u8)~0;
10728
10729 /* Parse args required to build the message */
10730 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
10731 if (unformat(input, "del")) {
10732 is_add = 0;
10733 } else if (unformat(input, "add")) {
10734 is_add = 1;
10735 } else if (unformat(input, "deid %U/%d", unformat_ip4_address,
10736 &deid4, &len)) {
10737 deid_type = 0; /* ipv4 */
10738 deid_len = len;
10739 } else if (unformat(input, "deid %U/%d", unformat_ip6_address,
10740 &deid6, &len)) {
10741 deid_type = 1; /* ipv6 */
10742 deid_len = len;
10743 } else if (unformat(input, "deid %U", unformat_ethernet_address,
10744 deid_mac)) {
10745 deid_type = 2; /* mac */
10746 } else if (unformat(input, "seid %U/%d", unformat_ip4_address,
10747 &seid4, &len)) {
10748 seid_type = 0; /* ipv4 */
10749 seid_len = len;
10750 } else if (unformat(input, "seid %U/%d", unformat_ip6_address,
10751 &seid6, &len)) {
10752 seid_type = 1; /* ipv6 */
10753 seid_len = len;
10754 } else if (unformat(input, "seid %U", unformat_ethernet_address,
10755 seid_mac)) {
10756 seid_type = 2; /* mac */
10757 } else if (unformat(input, "vni %d", &vni)) {
10758 ;
10759 } else if (unformat(input, "rloc %U", unformat_ip4_address, &rloc4)) {
10760 rloc.is_ip4 = 1;
10761 clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
10762 vec_add1 (rlocs, rloc);
10763 } else if (unformat(input, "rloc %U", unformat_ip6_address, &rloc6)) {
10764 rloc.is_ip4 = 0;
10765 clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
10766 vec_add1 (rlocs, rloc);
10767 } else if (unformat(input, "action %d", &action)) {
10768 ;
10769 } else {
10770 clib_warning ("parse error '%U'", format_unformat_error, input);
10771 return -99;
10772 }
10773 }
10774
10775 if ((u8)~0 == deid_type) {
10776 errmsg ("missing params!");
10777 return -99;
10778 }
10779
10780 if (seid_type != deid_type) {
10781 errmsg ("source and destination EIDs are of different types!");
10782 return -99;
10783 }
10784
10785 if (is_add && (~0 == action)
10786 && 0 == vec_len (rlocs)) {
10787 errmsg ("no action set for negative map-reply!");
10788 return -99;
10789 }
10790
10791 M(LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
10792 mp->is_add = is_add;
10793 mp->vni = htonl (vni);
10794 mp->seid_len = seid_len;
10795 mp->action = (u8) action;
10796 mp->deid_len = deid_len;
10797 mp->eid_type = deid_type;
10798
10799 switch (mp->eid_type) {
10800 case 0:
10801 clib_memcpy (mp->seid, &seid4, sizeof (seid4));
10802 clib_memcpy (mp->deid, &deid4, sizeof (deid4));
10803 break;
10804 case 1:
10805 clib_memcpy (mp->seid, &seid6, sizeof (seid6));
10806 clib_memcpy (mp->deid, &deid6, sizeof (deid6));
10807 break;
10808 case 2:
10809 clib_memcpy (mp->seid, seid_mac, 6);
10810 clib_memcpy (mp->deid, deid_mac, 6);
10811 break;
10812 default:
10813 errmsg ("unknown EID type %d!", mp->eid_type);
10814 return 0;
10815 }
10816
10817 mp->rloc_num = vec_len (rlocs);
10818 clib_memcpy (mp->rlocs, rlocs, (sizeof (rloc_t) * vec_len (rlocs)));
10819 vec_free (rlocs);
10820
10821 /* send it... */
10822 S;
10823
10824 /* Wait for a reply... */
10825 W;
10826
10827 /* NOTREACHED */
10828 return 0;
10829}
10830
Filip Tehlar46d4e362016-05-09 09:39:26 +020010831static int
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010832api_lisp_gpe_add_del_iface(vat_main_t * vam)
10833{
10834 unformat_input_t * input = vam->input;
10835 vl_api_lisp_gpe_add_del_iface_t *mp;
10836 f64 timeout = ~0;
10837 u8 is_set = 0;
Florin Coras577c3552016-04-21 00:45:40 +020010838 u8 is_add = 1;
10839 u32 table_id, vni;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010840
10841 /* Parse args required to build the message */
10842 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
10843 if (unformat(input, "up")) {
10844 is_set = 1;
10845 is_add = 1;
10846 } else if (unformat(input, "down")) {
10847 is_set = 1;
10848 is_add = 0;
Florin Coras577c3552016-04-21 00:45:40 +020010849 } else if (unformat(input, "table_id %d", &table_id)) {
10850 ;
10851 } else if (unformat(input, "vni %d", &vni)) {
10852 ;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010853 } else
10854 break;
10855 }
10856
10857 if (is_set == 0) {
10858 errmsg("Value not set\n");
10859 return -99;
10860 }
10861
10862 /* Construct the API message */
10863 M(LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
10864
10865 mp->is_add = is_add;
Florin Coras577c3552016-04-21 00:45:40 +020010866 mp->table_id = table_id;
10867 mp->vni = vni;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010868
10869 /* send it... */
10870 S;
10871
10872 /* Wait for a reply... */
10873 W;
10874
10875 /* NOTREACHED */
10876 return 0;
10877}
10878
Andrej Kozemcakb6e4d392016-06-14 13:55:57 +020010879/**
10880 * Add/del map request itr rlocs from LISP control plane and updates
10881 *
10882 * @param vam vpp API test context
10883 * @return return code
10884 */
10885static int
10886api_lisp_add_del_map_request_itr_rlocs(vat_main_t * vam)
10887{
10888 unformat_input_t * input = vam->input;
10889 vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
10890 f64 timeout = ~0;
10891 u8 *locator_set_name = 0;
10892 u8 locator_set_name_set = 0;
10893 u8 is_add = 1;
10894
10895 /* Parse args required to build the message */
10896 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
10897 if (unformat(input, "del")) {
10898 is_add = 0;
10899 } else if (unformat(input, "%_%v%_", &locator_set_name)) {
10900 locator_set_name_set = 1;
10901 } else {
10902 clib_warning ("parse error '%U'", format_unformat_error, input);
10903 return -99;
10904 }
10905 }
10906
10907 if (is_add && !locator_set_name_set) {
10908 errmsg ("itr-rloc is not set!");
10909 return -99;
10910 }
10911
10912 if (is_add && vec_len(locator_set_name) > 64) {
10913 errmsg ("itr-rloc locator-set name too long\n");
10914 vec_free(locator_set_name);
10915 return -99;
10916 }
10917
10918 M(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
10919 mp->is_add = is_add;
10920 if (is_add) {
10921 clib_memcpy (mp->locator_set_name , locator_set_name,
10922 vec_len(locator_set_name));
10923 } else {
10924 memset(mp->locator_set_name, 0, sizeof(mp->locator_set_name));
10925 }
10926 vec_free (locator_set_name);
10927
10928 /* send it... */
10929 S;
10930
10931 /* Wait for a reply... */
10932 W;
10933
10934 /* NOTREACHED */
10935 return 0;
10936}
10937
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010938static int
10939api_lisp_locator_set_dump(vat_main_t *vam)
10940{
10941 vl_api_lisp_locator_set_dump_t *mp;
10942 f64 timeout = ~0;
10943
10944 if (!vam->json_output) {
10945 fformat(vam->ofp, "%=20s%=16s%=16s%=16s\n",
10946 "Locator-set", "Locator", "Priority", "Weight");
10947 }
10948
10949 M(LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
10950 /* send it... */
10951 S;
10952
10953 /* Use a control ping for synchronization */
10954 {
10955 vl_api_control_ping_t * mp;
10956 M(CONTROL_PING, control_ping);
10957 S;
10958 }
10959 /* Wait for a reply... */
10960 W;
10961
10962 /* NOTREACHED */
10963 return 0;
10964}
10965
10966static int
10967api_lisp_local_eid_table_dump(vat_main_t *vam)
10968{
Filip Tehlar1b1ee4f2016-07-04 11:43:11 +020010969 unformat_input_t * i = vam->input;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010970 vl_api_lisp_local_eid_table_dump_t *mp;
10971 f64 timeout = ~0;
Filip Tehlar1b1ee4f2016-07-04 11:43:11 +020010972 struct in_addr ip4;
10973 struct in6_addr ip6;
10974 u8 mac[6];
10975 u8 eid_type = ~0, eid_set;
10976 u32 prefix_length = ~0, t, vni = 0;
10977
10978 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
10979 if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t)) {
10980 eid_set = 1;
10981 eid_type = 0;
10982 prefix_length = t;
10983 } else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t)) {
10984 eid_set = 1;
10985 eid_type = 1;
10986 prefix_length = t;
10987 } else if (unformat (i, "eid %U", unformat_ethernet_address, mac)) {
10988 eid_set = 1;
10989 eid_type = 2;
10990 } else if (unformat (i, "vni %d", &t))
10991 vni = t;
10992 else {
10993 errmsg ("parse error '%U'", format_unformat_error, i);
10994 return -99;
10995 }
10996 }
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010997
10998 if (!vam->json_output) {
10999 fformat(vam->ofp, "%=20s%=30s\n",
11000 "Locator-set", "Eid");
11001 }
11002
11003 M(LISP_LOCAL_EID_TABLE_DUMP, lisp_local_eid_table_dump);
Filip Tehlar1b1ee4f2016-07-04 11:43:11 +020011004
11005 if (eid_set) {
11006 mp->eid_set = 1;
11007 mp->vni = htonl (vni);
11008 mp->eid_type = eid_type;
11009 switch (eid_type) {
11010 case 0:
11011 mp->prefix_length = prefix_length;
11012 clib_memcpy (mp->eid, &ip4, sizeof (ip4));
11013 break;
11014 case 1:
11015 mp->prefix_length = prefix_length;
11016 clib_memcpy (mp->eid, &ip6, sizeof (ip6));
11017 break;
11018 case 2:
11019 clib_memcpy (mp->eid, mac, sizeof (mac));
11020 break;
11021 default:
11022 errmsg ("unknown EID type %d!", eid_type);
11023 return -99;
11024 }
11025 }
11026
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020011027 /* send it... */
11028 S;
11029
11030 /* Use a control ping for synchronization */
11031 {
11032 vl_api_control_ping_t * mp;
11033 M(CONTROL_PING, control_ping);
11034 S;
11035 }
11036 /* Wait for a reply... */
11037 W;
11038
11039 /* NOTREACHED */
11040 return 0;
11041}
11042
11043static int
11044api_lisp_gpe_tunnel_dump(vat_main_t *vam)
11045{
11046 vl_api_lisp_gpe_tunnel_dump_t *mp;
11047 f64 timeout = ~0;
11048
11049 if (!vam->json_output) {
11050 fformat(vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
11051 "%=16s%=16s%=16s%=16s%=16s\n",
11052 "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
11053 "Decap next", "Lisp version", "Flags", "Next protocol",
11054 "ver_res", "res", "iid");
11055 }
11056
11057 M(LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
11058 /* send it... */
11059 S;
11060
11061 /* Use a control ping for synchronization */
11062 {
11063 vl_api_control_ping_t * mp;
11064 M(CONTROL_PING, control_ping);
11065 S;
11066 }
11067 /* Wait for a reply... */
11068 W;
11069
11070 /* NOTREACHED */
11071 return 0;
11072}
11073
11074static int
11075api_lisp_map_resolver_dump(vat_main_t *vam)
11076{
11077 vl_api_lisp_map_resolver_dump_t *mp;
11078 f64 timeout = ~0;
11079
11080 if (!vam->json_output) {
11081 fformat(vam->ofp, "%=20s\n",
11082 "Map resolver");
11083 }
11084
11085 M(LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
11086 /* send it... */
11087 S;
11088
11089 /* Use a control ping for synchronization */
11090 {
11091 vl_api_control_ping_t * mp;
11092 M(CONTROL_PING, control_ping);
11093 S;
11094 }
11095 /* Wait for a reply... */
11096 W;
11097
11098 /* NOTREACHED */
11099 return 0;
11100}
11101
Andrej Kozemcaka9edd852016-05-02 12:14:33 +020011102static int
Filip Tehlar46d4e362016-05-09 09:39:26 +020011103api_lisp_enable_disable_status_dump(vat_main_t *vam)
Andrej Kozemcaka9edd852016-05-02 12:14:33 +020011104{
Filip Tehlar46d4e362016-05-09 09:39:26 +020011105 vl_api_lisp_enable_disable_status_dump_t *mp;
Andrej Kozemcaka9edd852016-05-02 12:14:33 +020011106 f64 timeout = ~0;
11107
11108 if (!vam->json_output) {
11109 fformat(vam->ofp, "%=20s\n",
Filip Tehlar46d4e362016-05-09 09:39:26 +020011110 "lisp status:");
Andrej Kozemcaka9edd852016-05-02 12:14:33 +020011111 }
11112
Filip Tehlar46d4e362016-05-09 09:39:26 +020011113 M(LISP_ENABLE_DISABLE_STATUS_DUMP,
11114 lisp_enable_disable_status_dump);
Andrej Kozemcaka9edd852016-05-02 12:14:33 +020011115 /* send it... */
11116 S;
11117
11118 /* Use a control ping for synchronization */
11119 {
11120 vl_api_control_ping_t * mp;
11121 M(CONTROL_PING, control_ping);
11122 S;
11123 }
11124 /* Wait for a reply... */
11125 W;
11126
11127 /* NOTREACHED */
11128 return 0;
11129}
11130
Matus Fabian8a95a482016-05-06 15:14:13 +020011131static int
Andrej Kozemcakb6e4d392016-06-14 13:55:57 +020011132api_lisp_get_map_request_itr_rlocs(vat_main_t *vam)
11133{
11134 vl_api_lisp_get_map_request_itr_rlocs_t *mp;
11135 f64 timeout = ~0;
11136
11137 if (!vam->json_output) {
11138 fformat(vam->ofp, "%=20s\n",
11139 "itr-rlocs:");
11140 }
11141
11142 M(LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
11143 /* send it... */
11144 S;
11145 /* Wait for a reply... */
11146 W;
11147
11148 /* NOTREACHED */
11149 return 0;
11150}
11151
11152static int
Matus Fabian8a95a482016-05-06 15:14:13 +020011153api_af_packet_create (vat_main_t * vam)
11154{
11155 unformat_input_t * i = vam->input;
11156 vl_api_af_packet_create_t * mp;
11157 f64 timeout;
11158 u8 * host_if_name = 0;
11159 u8 hw_addr[6];
11160 u8 random_hw_addr = 1;
11161
11162 memset (hw_addr, 0, sizeof (hw_addr));
11163
11164 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
11165 if (unformat (i, "name %s", &host_if_name))
11166 vec_add1 (host_if_name, 0);
11167 else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
11168 random_hw_addr = 0;
11169 else
11170 break;
11171 }
11172
11173 if (!vec_len (host_if_name)) {
11174 errmsg ("host-interface name must be specified");
11175 return -99;
11176 }
11177
11178 if (vec_len (host_if_name) > 64) {
11179 errmsg ("host-interface name too long");
11180 return -99;
11181 }
11182
11183 M(AF_PACKET_CREATE, af_packet_create);
11184
11185 clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
11186 clib_memcpy (mp->hw_addr, hw_addr, 6);
11187 mp->use_random_hw_addr = random_hw_addr;
11188 vec_free (host_if_name);
11189
Keith Burns (alagalah)802255c2016-06-13 16:56:04 -070011190 S; W2(fprintf(vam->ofp," new sw_if_index = %d ", vam->sw_if_index));
Matus Fabian8a95a482016-05-06 15:14:13 +020011191 /* NOTREACHED */
11192 return 0;
11193}
11194
11195static int
11196api_af_packet_delete (vat_main_t * vam)
11197{
11198 unformat_input_t * i = vam->input;
11199 vl_api_af_packet_delete_t * mp;
11200 f64 timeout;
11201 u8 * host_if_name = 0;
11202
11203 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
11204 if (unformat (i, "name %s", &host_if_name))
11205 vec_add1 (host_if_name, 0);
11206 else
11207 break;
11208 }
11209
11210 if (!vec_len (host_if_name)) {
11211 errmsg ("host-interface name must be specified");
11212 return -99;
11213 }
11214
11215 if (vec_len (host_if_name) > 64) {
11216 errmsg ("host-interface name too long");
11217 return -99;
11218 }
11219
11220 M(AF_PACKET_DELETE, af_packet_delete);
11221
11222 clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
11223 vec_free (host_if_name);
11224
11225 S; W;
11226 /* NOTREACHED */
11227 return 0;
11228}
11229
Matus Fabian65fcd4d2016-05-13 05:44:48 -070011230static int
11231api_policer_add_del (vat_main_t * vam)
11232{
11233 unformat_input_t * i = vam->input;
11234 vl_api_policer_add_del_t * mp;
11235 f64 timeout;
11236 u8 is_add = 1;
11237 u8 * name = 0;
11238 u32 cir = 0;
11239 u32 eir = 0;
11240 u64 cb = 0;
11241 u64 eb = 0;
11242 u8 rate_type = 0;
11243 u8 round_type = 0;
11244 u8 type = 0;
11245
11246 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
11247 if (unformat (i, "del"))
11248 is_add = 0;
11249 else if (unformat (i, "name %s", &name))
11250 vec_add1 (name, 0);
11251 else if (unformat (i, "cir %u", &cir))
11252 ;
11253 else if (unformat (i, "eir %u", &eir))
11254 ;
11255 else if (unformat (i, "cb %u", &cb))
11256 ;
11257 else if (unformat (i, "eb %u", &eb))
11258 ;
11259 else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
11260 &rate_type))
11261 ;
11262 else if (unformat (i, "round_type %U", unformat_policer_round_type,
11263 &round_type))
11264 ;
11265 else if (unformat (i, "type %U", unformat_policer_type, &type))
11266 ;
11267 else
11268 break;
11269 }
11270
11271 if (!vec_len (name)) {
11272 errmsg ("policer name must be specified");
11273 return -99;
11274 }
11275
11276 if (vec_len (name) > 64) {
11277 errmsg ("policer name too long");
11278 return -99;
11279 }
11280
11281 M(POLICER_ADD_DEL, policer_add_del);
11282
11283 clib_memcpy (mp->name, name, vec_len (name));
11284 vec_free (name);
11285 mp->is_add = is_add;
11286 mp->cir = cir;
11287 mp->eir = eir;
11288 mp->cb = cb;
11289 mp->eb = eb;
11290 mp->rate_type = rate_type;
11291 mp->round_type = round_type;
11292 mp->type = type;
11293
11294 S; W;
11295 /* NOTREACHED */
11296 return 0;
11297}
11298
Matus Fabian82e29c42016-05-11 04:49:46 -070011299static int
Matus Fabiane8554802016-05-18 23:40:37 -070011300api_policer_dump(vat_main_t *vam)
11301{
11302 unformat_input_t * i = vam->input;
11303 vl_api_policer_dump_t *mp;
11304 f64 timeout = ~0;
11305 u8 *match_name = 0;
11306 u8 match_name_valid = 0;
11307
11308 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
11309 if (unformat (i, "name %s", &match_name)) {
11310 vec_add1 (match_name, 0);
11311 match_name_valid = 1;
11312 } else
11313 break;
11314 }
11315
11316 M(POLICER_DUMP, policer_dump);
11317 mp->match_name_valid = match_name_valid;
11318 clib_memcpy (mp->match_name, match_name, vec_len (match_name));
11319 vec_free (match_name);
11320 /* send it... */
11321 S;
11322
11323 /* Use a control ping for synchronization */
11324 {
11325 vl_api_control_ping_t * mp;
11326 M(CONTROL_PING, control_ping);
11327 S;
11328 }
11329 /* Wait for a reply... */
11330 W;
11331
11332 /* NOTREACHED */
11333 return 0;
11334}
11335
11336static int
Matus Fabian82e29c42016-05-11 04:49:46 -070011337api_netmap_create (vat_main_t * vam)
11338{
11339 unformat_input_t * i = vam->input;
11340 vl_api_netmap_create_t * mp;
11341 f64 timeout;
11342 u8 * if_name = 0;
11343 u8 hw_addr[6];
11344 u8 random_hw_addr = 1;
11345 u8 is_pipe = 0;
11346 u8 is_master = 0;
11347
11348 memset (hw_addr, 0, sizeof (hw_addr));
11349
11350 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
11351 if (unformat (i, "name %s", &if_name))
11352 vec_add1 (if_name, 0);
11353 else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
11354 random_hw_addr = 0;
11355 else if (unformat (i, "pipe"))
11356 is_pipe = 1;
11357 else if (unformat (i, "master"))
11358 is_master = 1;
11359 else if (unformat (i, "slave"))
11360 is_master = 0;
11361 else
11362 break;
11363 }
11364
11365 if (!vec_len (if_name)) {
11366 errmsg ("interface name must be specified");
11367 return -99;
11368 }
11369
11370 if (vec_len (if_name) > 64) {
11371 errmsg ("interface name too long");
11372 return -99;
11373 }
11374
11375 M(NETMAP_CREATE, netmap_create);
11376
Dave Barach6f7b9922016-05-20 14:43:57 -040011377 clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
Matus Fabian82e29c42016-05-11 04:49:46 -070011378 clib_memcpy (mp->hw_addr, hw_addr, 6);
11379 mp->use_random_hw_addr = random_hw_addr;
11380 mp->is_pipe = is_pipe;
11381 mp->is_master = is_master;
11382 vec_free (if_name);
11383
11384 S; W;
11385 /* NOTREACHED */
11386 return 0;
11387}
11388
11389static int
11390api_netmap_delete (vat_main_t * vam)
11391{
11392 unformat_input_t * i = vam->input;
11393 vl_api_netmap_delete_t * mp;
11394 f64 timeout;
11395 u8 * if_name = 0;
11396
11397 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
11398 if (unformat (i, "name %s", &if_name))
11399 vec_add1 (if_name, 0);
11400 else
11401 break;
11402 }
11403
11404 if (!vec_len (if_name)) {
11405 errmsg ("interface name must be specified");
11406 return -99;
11407 }
11408
11409 if (vec_len (if_name) > 64) {
11410 errmsg ("interface name too long");
11411 return -99;
11412 }
11413
11414 M(NETMAP_DELETE, netmap_delete);
11415
Dave Barach6f7b9922016-05-20 14:43:57 -040011416 clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
Matus Fabian82e29c42016-05-11 04:49:46 -070011417 vec_free (if_name);
11418
11419 S; W;
11420 /* NOTREACHED */
11421 return 0;
11422}
11423
marek zavodsky2c21a9a2016-06-21 05:35:16 +020011424static void vl_api_mpls_gre_tunnel_details_t_handler
11425(vl_api_mpls_gre_tunnel_details_t * mp)
11426{
11427 vat_main_t * vam = &vat_main;
11428 i32 i;
11429 i32 len = ntohl(mp->nlabels);
11430
11431 if (mp->l2_only == 0) {
11432 fformat(vam->ofp, "[%d]: src %U, dst %U, adj %U/%d, labels ",
11433 ntohl(mp->tunnel_index),
11434 format_ip4_address, &mp->tunnel_src,
11435 format_ip4_address, &mp->tunnel_dst,
11436 format_ip4_address, &mp->intfc_address,
11437 ntohl(mp->mask_width));
11438 for (i = 0; i < len; i++) {
11439 fformat(vam->ofp, "%u ", ntohl(mp->labels[i]));
11440 }
11441 fformat(vam->ofp, "\n");
11442 fformat(vam->ofp, " inner fib index %d, outer fib index %d\n",
11443 ntohl(mp->inner_fib_index), ntohl(mp->outer_fib_index));
11444 } else {
11445 fformat(vam->ofp, "[%d]: src %U, dst %U, key %U, labels ",
11446 ntohl(mp->tunnel_index),
11447 format_ip4_address, &mp->tunnel_src,
11448 format_ip4_address, &mp->tunnel_dst,
11449 format_ip4_address, &mp->intfc_address);
11450 for (i = 0; i < len; i++) {
11451 fformat(vam->ofp, "%u ", ntohl(mp->labels[i]));
11452 }
11453 fformat(vam->ofp, "\n");
11454 fformat(vam->ofp, " l2 interface %d, outer fib index %d\n",
11455 ntohl(mp->hw_if_index), ntohl(mp->outer_fib_index));
11456 }
11457}
11458
11459static void vl_api_mpls_gre_tunnel_details_t_handler_json
11460(vl_api_mpls_gre_tunnel_details_t * mp)
11461{
11462 vat_main_t * vam = &vat_main;
11463 vat_json_node_t *node = NULL;
11464 struct in_addr ip4;
11465 i32 i;
11466 i32 len = ntohl(mp->nlabels);
11467
11468 if (VAT_JSON_ARRAY != vam->json_tree.type) {
11469 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
11470 vat_json_init_array(&vam->json_tree);
11471 }
11472 node = vat_json_array_add(&vam->json_tree);
11473
11474 vat_json_init_object(node);
11475 vat_json_object_add_uint(node, "tunnel_index", ntohl(mp->tunnel_index));
11476 clib_memcpy(&ip4, &(mp->intfc_address), sizeof(ip4));
11477 vat_json_object_add_ip4(node, "intfc_address", ip4);
11478 vat_json_object_add_uint(node, "inner_fib_index", ntohl(mp->inner_fib_index));
11479 vat_json_object_add_uint(node, "mask_width", ntohl(mp->mask_width));
11480 vat_json_object_add_uint(node, "encap_index", ntohl(mp->encap_index));
11481 vat_json_object_add_uint(node, "hw_if_index", ntohl(mp->hw_if_index));
11482 vat_json_object_add_uint(node, "l2_only", ntohl(mp->l2_only));
11483 clib_memcpy(&ip4, &(mp->tunnel_src), sizeof(ip4));
11484 vat_json_object_add_ip4(node, "tunnel_src", ip4);
11485 clib_memcpy(&ip4, &(mp->tunnel_dst), sizeof(ip4));
11486 vat_json_object_add_ip4(node, "tunnel_dst", ip4);
11487 vat_json_object_add_uint(node, "outer_fib_index", ntohl(mp->outer_fib_index));
11488 vat_json_object_add_uint(node, "label_count", len);
11489 for (i = 0; i < len; i++) {
11490 vat_json_object_add_uint(node, "label", ntohl(mp->labels[i]));
11491 }
11492}
11493
11494static int api_mpls_gre_tunnel_dump (vat_main_t * vam)
11495{
11496 vl_api_mpls_gre_tunnel_dump_t *mp;
11497 f64 timeout;
11498 i32 index = -1;
11499
11500 /* Parse args required to build the message */
11501 while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT) {
11502 if (!unformat (vam->input, "tunnel_index %d", &index)) {
11503 index = -1;
11504 break;
11505 }
11506 }
11507
11508 fformat(vam->ofp, " tunnel_index %d\n", index);
11509
11510 M(MPLS_GRE_TUNNEL_DUMP, mpls_gre_tunnel_dump);
11511 mp->tunnel_index = htonl(index);
11512 S;
11513
11514 /* Use a control ping for synchronization */
11515 {
11516 vl_api_control_ping_t * mp;
11517 M(CONTROL_PING, control_ping);
11518 S;
11519 }
11520 W;
11521}
11522
11523static void vl_api_mpls_eth_tunnel_details_t_handler
11524(vl_api_mpls_eth_tunnel_details_t * mp)
11525{
11526 vat_main_t * vam = &vat_main;
11527 i32 i;
11528 i32 len = ntohl(mp->nlabels);
11529
11530 fformat(vam->ofp, "[%d]: dst %U, adj %U/%d, labels ",
11531 ntohl(mp->tunnel_index),
11532 format_ethernet_address, &mp->tunnel_dst_mac,
11533 format_ip4_address, &mp->intfc_address,
11534 ntohl(mp->mask_width));
11535 for (i = 0; i < len; i++) {
11536 fformat(vam->ofp, "%u ", ntohl(mp->labels[i]));
11537 }
11538 fformat(vam->ofp, "\n");
11539 fformat(vam->ofp, " tx on %d, rx fib index %d\n",
11540 ntohl(mp->tx_sw_if_index),
11541 ntohl(mp->inner_fib_index));
11542}
11543
11544static void vl_api_mpls_eth_tunnel_details_t_handler_json
11545(vl_api_mpls_eth_tunnel_details_t * mp)
11546{
11547 vat_main_t * vam = &vat_main;
11548 vat_json_node_t *node = NULL;
11549 struct in_addr ip4;
11550 i32 i;
11551 i32 len = ntohl(mp->nlabels);
11552
11553 if (VAT_JSON_ARRAY != vam->json_tree.type) {
11554 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
11555 vat_json_init_array(&vam->json_tree);
11556 }
11557 node = vat_json_array_add(&vam->json_tree);
11558
11559 vat_json_init_object(node);
11560 vat_json_object_add_uint(node, "tunnel_index", ntohl(mp->tunnel_index));
11561 clib_memcpy(&ip4, &(mp->intfc_address), sizeof(ip4));
11562 vat_json_object_add_ip4(node, "intfc_address", ip4);
11563 vat_json_object_add_uint(node, "inner_fib_index", ntohl(mp->inner_fib_index));
11564 vat_json_object_add_uint(node, "mask_width", ntohl(mp->mask_width));
11565 vat_json_object_add_uint(node, "encap_index", ntohl(mp->encap_index));
11566 vat_json_object_add_uint(node, "hw_if_index", ntohl(mp->hw_if_index));
11567 vat_json_object_add_uint(node, "l2_only", ntohl(mp->l2_only));
11568 vat_json_object_add_string_copy(node, "tunnel_dst_mac",
11569 format(0, "%U", format_ethernet_address, &mp->tunnel_dst_mac));
11570 vat_json_object_add_uint(node, "tx_sw_if_index", ntohl(mp->tx_sw_if_index));
11571 vat_json_object_add_uint(node, "label_count", len);
11572 for (i = 0; i < len; i++) {
11573 vat_json_object_add_uint(node, "label", ntohl(mp->labels[i]));
11574 }
11575}
11576
11577static int api_mpls_eth_tunnel_dump (vat_main_t * vam)
11578{
11579 vl_api_mpls_eth_tunnel_dump_t *mp;
11580 f64 timeout;
11581 i32 index = -1;
11582
11583 /* Parse args required to build the message */
11584 while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT) {
11585 if (!unformat (vam->input, "tunnel_index %d", &index)) {
11586 index = -1;
11587 break;
11588 }
11589 }
11590
11591 fformat(vam->ofp, " tunnel_index %d\n", index);
11592
11593 M(MPLS_ETH_TUNNEL_DUMP, mpls_eth_tunnel_dump);
11594 mp->tunnel_index = htonl(index);
11595 S;
11596
11597 /* Use a control ping for synchronization */
11598 {
11599 vl_api_control_ping_t * mp;
11600 M(CONTROL_PING, control_ping);
11601 S;
11602 }
11603 W;
11604}
11605
11606static void vl_api_mpls_fib_encap_details_t_handler
11607(vl_api_mpls_fib_encap_details_t * mp)
11608{
11609 vat_main_t * vam = &vat_main;
11610 i32 i;
11611 i32 len = ntohl(mp->nlabels);
11612
11613 fformat(vam->ofp, "table %d, dest %U, label ",
11614 ntohl(mp->fib_index),
11615 format_ip4_address, &mp->dest,
11616 len);
11617 for (i = 0; i < len; i++) {
11618 fformat(vam->ofp, "%u ", ntohl(mp->labels[i]));
11619 }
11620 fformat(vam->ofp, "\n");
11621}
11622
11623static void vl_api_mpls_fib_encap_details_t_handler_json
11624(vl_api_mpls_fib_encap_details_t * mp)
11625{
11626 vat_main_t * vam = &vat_main;
11627 vat_json_node_t *node = NULL;
11628 i32 i;
11629 i32 len = ntohl(mp->nlabels);
11630 struct in_addr ip4;
11631
11632 if (VAT_JSON_ARRAY != vam->json_tree.type) {
11633 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
11634 vat_json_init_array(&vam->json_tree);
11635 }
11636 node = vat_json_array_add(&vam->json_tree);
11637
11638 vat_json_init_object(node);
11639 vat_json_object_add_uint(node, "table", ntohl(mp->fib_index));
11640 vat_json_object_add_uint(node, "entry_index", ntohl(mp->entry_index));
11641 clib_memcpy(&ip4, &(mp->dest), sizeof(ip4));
11642 vat_json_object_add_ip4(node, "dest", ip4);
11643 vat_json_object_add_uint(node, "s_bit", ntohl(mp->s_bit));
11644 vat_json_object_add_uint(node, "label_count", len);
11645 for (i = 0; i < len; i++) {
11646 vat_json_object_add_uint(node, "label", ntohl(mp->labels[i]));
11647 }
11648}
11649
11650static int api_mpls_fib_encap_dump (vat_main_t * vam)
11651{
11652 vl_api_mpls_fib_encap_dump_t *mp;
11653 f64 timeout;
11654
11655 M(MPLS_FIB_ENCAP_DUMP, mpls_fib_encap_dump);
11656 S;
11657
11658 /* Use a control ping for synchronization */
11659 {
11660 vl_api_control_ping_t * mp;
11661 M(CONTROL_PING, control_ping);
11662 S;
11663 }
11664 W;
11665}
11666
11667static void vl_api_mpls_fib_decap_details_t_handler
11668(vl_api_mpls_fib_decap_details_t * mp)
11669{
11670 vat_main_t * vam = &vat_main;
11671
11672 fformat(vam->ofp, "RX table %d, TX table/intfc %u, swif_tag '%s', label %u, s_bit %u\n",
11673 ntohl(mp->rx_table_id),
11674 ntohl(mp->tx_table_id),
11675 mp->swif_tag,
11676 ntohl(mp->label),
11677 ntohl(mp->s_bit));
11678}
11679
11680static void vl_api_mpls_fib_decap_details_t_handler_json
11681(vl_api_mpls_fib_decap_details_t * mp)
11682{
11683 vat_main_t * vam = &vat_main;
11684 vat_json_node_t *node = NULL;
11685 struct in_addr ip4;
11686
11687 if (VAT_JSON_ARRAY != vam->json_tree.type) {
11688 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
11689 vat_json_init_array(&vam->json_tree);
11690 }
11691 node = vat_json_array_add(&vam->json_tree);
11692
11693 vat_json_init_object(node);
11694 vat_json_object_add_uint(node, "table", ntohl(mp->fib_index));
11695 vat_json_object_add_uint(node, "entry_index", ntohl(mp->entry_index));
11696 clib_memcpy(&ip4, &(mp->dest), sizeof(ip4));
11697 vat_json_object_add_ip4(node, "dest", ip4);
11698 vat_json_object_add_uint(node, "s_bit", ntohl(mp->s_bit));
11699 vat_json_object_add_uint(node, "label", ntohl(mp->label));
11700 vat_json_object_add_uint(node, "rx_table_id", ntohl(mp->rx_table_id));
11701 vat_json_object_add_uint(node, "tx_table_id", ntohl(mp->tx_table_id));
11702 vat_json_object_add_string_copy(node, "swif_tag", mp->swif_tag);
11703}
11704
11705static int api_mpls_fib_decap_dump (vat_main_t * vam)
11706{
11707 vl_api_mpls_fib_decap_dump_t *mp;
11708 f64 timeout;
11709
11710 M(MPLS_FIB_DECAP_DUMP, mpls_fib_decap_dump);
11711 S;
11712
11713 /* Use a control ping for synchronization */
11714 {
11715 vl_api_control_ping_t * mp;
11716 M(CONTROL_PING, control_ping);
11717 S;
11718 }
11719 W;
11720}
11721
Pavel Kotucek20c90f72016-06-07 14:44:26 +020011722int api_classify_table_ids (vat_main_t *vam)
11723{
11724 vl_api_classify_table_ids_t *mp;
11725 f64 timeout;
11726
11727 /* Construct the API message */
11728 M(CLASSIFY_TABLE_IDS, classify_table_ids);
11729 mp->context = 0;
11730
11731 S; W;
11732 /* NOTREACHED */
11733 return 0;
11734}
11735
11736int api_classify_table_by_interface (vat_main_t *vam)
11737{
11738 unformat_input_t * input = vam->input;
11739 vl_api_classify_table_by_interface_t *mp;
11740 f64 timeout;
11741
11742 u32 sw_if_index = ~0;
11743 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
11744 if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
11745 ;
11746 else if (unformat (input, "sw_if_index %d", &sw_if_index))
11747 ;
11748 else
11749 break;
11750 }
11751 if (sw_if_index == ~0) {
11752 errmsg ("missing interface name or sw_if_index\n");
11753 return -99;
11754 }
11755
11756 /* Construct the API message */
11757 M(CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
11758 mp->context = 0;
11759 mp->sw_if_index = ntohl(sw_if_index);
11760
11761 S; W;
11762 /* NOTREACHED */
11763 return 0;
11764}
11765
11766int api_classify_table_info (vat_main_t *vam)
11767{
11768 unformat_input_t * input = vam->input;
11769 vl_api_classify_table_info_t *mp;
11770 f64 timeout;
11771
11772 u32 table_id = ~0;
11773 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
11774 if (unformat (input, "table_id %d", &table_id))
11775 ;
11776 else
11777 break;
11778 }
11779 if (table_id == ~0) {
11780 errmsg ("missing table id\n");
11781 return -99;
11782 }
11783
11784 /* Construct the API message */
11785 M(CLASSIFY_TABLE_INFO, classify_table_info);
11786 mp->context = 0;
11787 mp->table_id = ntohl(table_id);
11788
11789 S; W;
11790 /* NOTREACHED */
11791 return 0;
11792}
11793
11794int api_classify_session_dump (vat_main_t *vam)
11795{
11796 unformat_input_t * input = vam->input;
11797 vl_api_classify_session_dump_t *mp;
11798 f64 timeout;
11799
11800 u32 table_id = ~0;
11801 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
11802 if (unformat (input, "table_id %d", &table_id))
11803 ;
11804 else
11805 break;
11806 }
11807 if (table_id == ~0) {
11808 errmsg ("missing table id\n");
11809 return -99;
11810 }
11811
11812 /* Construct the API message */
11813 M(CLASSIFY_SESSION_DUMP, classify_session_dump);
11814 mp->context = 0;
11815 mp->table_id = ntohl(table_id);
11816 S;
11817
11818 /* Use a control ping for synchronization */
11819 {
11820 vl_api_control_ping_t * mp;
11821 M(CONTROL_PING, control_ping);
11822 S;
11823 }
11824 W;
11825 /* NOTREACHED */
11826 return 0;
11827}
11828
Ed Warnickecb9cada2015-12-08 15:45:58 -070011829static int q_or_quit (vat_main_t * vam)
11830{
11831 longjmp (vam->jump_buf, 1);
11832 return 0; /* not so much */
11833}
11834static int q (vat_main_t * vam) {return q_or_quit (vam);}
11835static int quit (vat_main_t * vam) {return q_or_quit (vam);}
11836
11837static int comment (vat_main_t * vam)
11838{
11839 return 0;
11840}
11841
Matus Fabiand2dc3df2015-12-14 10:31:33 -050011842static int cmd_cmp (void * a1, void * a2)
11843{
11844 u8 ** c1 = a1;
11845 u8 ** c2 = a2;
11846
11847 return strcmp ((char *)(c1[0]), (char *)(c2[0]));
11848}
11849
Ed Warnickecb9cada2015-12-08 15:45:58 -070011850static int help (vat_main_t * vam)
11851{
11852 u8 ** cmds = 0;
11853 u8 * name = 0;
11854 hash_pair_t * p;
11855 unformat_input_t * i = vam->input;
11856 int j;
11857
11858 if (unformat (i, "%s", &name)) {
11859 uword *hs;
11860
11861 vec_add1(name, 0);
11862
11863 hs = hash_get_mem (vam->help_by_name, name);
11864 if (hs)
11865 fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
11866 else
11867 fformat (vam->ofp, "No such msg / command '%s'\n", name);
11868 vec_free(name);
11869 return 0;
11870 }
11871
11872 fformat(vam->ofp, "Help is available for the following:\n");
11873
11874 hash_foreach_pair (p, vam->function_by_name,
11875 ({
11876 vec_add1 (cmds, (u8 *)(p->key));
11877 }));
11878
Matus Fabiand2dc3df2015-12-14 10:31:33 -050011879 vec_sort_with_function (cmds, cmd_cmp);
Ed Warnickecb9cada2015-12-08 15:45:58 -070011880
11881 for (j = 0; j < vec_len(cmds); j++)
11882 fformat (vam->ofp, "%s\n", cmds[j]);
11883
11884 vec_free (cmds);
11885 return 0;
11886}
11887
11888static int set (vat_main_t * vam)
11889{
11890 u8 * name = 0, * value = 0;
11891 unformat_input_t * i = vam->input;
11892
11893 if (unformat (i, "%s", &name)) {
11894 /* The input buffer is a vector, not a string. */
11895 value = vec_dup (i->buffer);
11896 vec_delete (value, i->index, 0);
11897 /* Almost certainly has a trailing newline */
11898 if (value[vec_len(value)-1] == '\n')
11899 value[vec_len(value)-1] = 0;
11900 /* Make sure it's a proper string, one way or the other */
11901 vec_add1 (value, 0);
11902 (void) clib_macro_set_value (&vam->macro_main,
11903 (char *)name, (char *)value);
11904 }
11905 else
11906 errmsg ("usage: set <name> <value>\n");
11907
11908 vec_free (name);
11909 vec_free (value);
11910 return 0;
11911}
11912
11913static int unset (vat_main_t * vam)
11914{
11915 u8 * name = 0;
11916
11917 if (unformat (vam->input, "%s", &name))
11918 if (clib_macro_unset (&vam->macro_main, (char *)name) == 1)
11919 errmsg ("unset: %s wasn't set\n", name);
11920 vec_free (name);
11921 return 0;
11922}
11923
11924typedef struct {
11925 u8 * name;
11926 u8 * value;
11927} macro_sort_t;
11928
11929
Matus Fabiand2dc3df2015-12-14 10:31:33 -050011930static int macro_sort_cmp (void * a1, void * a2)
11931{
11932 macro_sort_t * s1 = a1;
11933 macro_sort_t * s2 = a2;
11934
11935 return strcmp ((char *)(s1->name), (char *)(s2->name));
11936}
11937
Ed Warnickecb9cada2015-12-08 15:45:58 -070011938static int dump_macro_table (vat_main_t * vam)
11939{
11940 macro_sort_t * sort_me = 0, * sm;
11941 int i;
11942 hash_pair_t * p;
11943
11944 hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
11945 ({
11946 vec_add2 (sort_me, sm, 1);
11947 sm->name = (u8 *)(p->key);
11948 sm->value = (u8 *) (p->value[0]);
11949 }));
11950
Matus Fabiand2dc3df2015-12-14 10:31:33 -050011951 vec_sort_with_function (sort_me, macro_sort_cmp);
Ed Warnickecb9cada2015-12-08 15:45:58 -070011952
11953 if (vec_len(sort_me))
11954 fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
11955 else
11956 fformat (vam->ofp, "The macro table is empty...\n");
11957
11958 for (i = 0; i < vec_len (sort_me); i++)
11959 fformat (vam->ofp, "%-15s%s\n", sort_me[i].name,
11960 sort_me[i].value);
11961 return 0;
11962}
11963
Dave Barachb44e9bc2016-02-19 09:06:23 -050011964static int dump_node_table (vat_main_t * vam)
11965{
11966 int i, j;
11967 vlib_node_t * node, * next_node;
11968
11969 if (vec_len (vam->graph_nodes) == 0) {
11970 fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
11971 return 0;
11972 }
11973
11974 for (i = 0; i < vec_len (vam->graph_nodes); i++) {
11975 node = vam->graph_nodes[i];
11976 fformat (vam->ofp, "[%d] %s\n", i, node->name);
11977 for (j = 0; j < vec_len (node->next_nodes); j++) {
11978 if (node->next_nodes[j] != ~0) {
11979 next_node = vam->graph_nodes[node->next_nodes[j]];
11980 fformat (vam->ofp, " [%d] %s\n", j, next_node->name);
11981 }
11982 }
11983 }
11984 return 0;
11985}
11986
11987static int search_node_table (vat_main_t * vam)
11988{
11989 unformat_input_t * line_input = vam->input;
11990 u8 * node_to_find;
11991 int j;
11992 vlib_node_t * node, * next_node;
11993 uword * p;
11994
11995 if (vam->graph_node_index_by_name == 0) {
11996 fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
11997 return 0;
11998 }
11999
12000 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
12001 if (unformat (line_input, "%s", &node_to_find)) {
12002 vec_add1 (node_to_find, 0);
12003 p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
12004 if (p == 0) {
12005 fformat (vam->ofp, "%s not found...\n", node_to_find);
12006 goto out;
12007 }
12008 node = vam->graph_nodes[p[0]];
12009 fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
12010 for (j = 0; j < vec_len (node->next_nodes); j++) {
12011 if (node->next_nodes[j] != ~0) {
12012 next_node = vam->graph_nodes[node->next_nodes[j]];
12013 fformat (vam->ofp, " [%d] %s\n", j, next_node->name);
12014 }
12015 }
12016 }
12017
12018 else {
12019 clib_warning ("parse error '%U'", format_unformat_error,
12020 line_input);
12021 return -99;
12022 }
12023
12024 out:
12025 vec_free(node_to_find);
12026
12027 }
12028
12029 return 0;
12030}
12031
12032
Ed Warnickecb9cada2015-12-08 15:45:58 -070012033static int script (vat_main_t * vam)
12034{
12035 u8 * s = 0;
12036 char * save_current_file;
12037 unformat_input_t save_input;
12038 jmp_buf save_jump_buf;
12039 u32 save_line_number;
12040
12041 FILE * new_fp, * save_ifp;
12042
12043 if (unformat (vam->input, "%s", &s)) {
12044 new_fp = fopen ((char *)s, "r");
12045 if (new_fp == 0) {
12046 errmsg ("Couldn't open script file %s\n", s);
12047 vec_free (s);
12048 return -99;
12049 }
12050 } else {
12051 errmsg ("Missing script name\n");
12052 return -99;
12053 }
12054
Damjan Marionf1213b82016-03-13 02:22:06 +010012055 clib_memcpy (&save_input, &vam->input, sizeof (save_input));
12056 clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
Ed Warnickecb9cada2015-12-08 15:45:58 -070012057 save_ifp = vam->ifp;
12058 save_line_number = vam->input_line_number;
12059 save_current_file = (char *) vam->current_file;
12060
12061 vam->input_line_number = 0;
12062 vam->ifp = new_fp;
12063 vam->current_file = s;
12064 do_one_file (vam);
12065
Damjan Marionf1213b82016-03-13 02:22:06 +010012066 clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
12067 clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
Ed Warnickecb9cada2015-12-08 15:45:58 -070012068 vam->ifp = save_ifp;
12069 vam->input_line_number = save_line_number;
12070 vam->current_file = (u8 *) save_current_file;
12071 vec_free (s);
12072
12073 return 0;
12074}
12075
12076static int echo (vat_main_t * vam)
12077{
12078 fformat (vam->ofp, "%v", vam->input->buffer);
12079 return 0;
12080}
12081
12082/* List of API message constructors, CLI names map to api_xxx */
12083#define foreach_vpe_api_msg \
12084_(create_loopback,"[mac <mac-addr>]") \
12085_(sw_interface_dump,"") \
12086_(sw_interface_set_flags, \
12087 "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
12088_(sw_interface_add_del_address, \
12089 "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
12090_(sw_interface_set_table, \
12091 "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]") \
12092_(sw_interface_set_vpath, \
12093 "<intfc> | sw_if_index <id> enable | disable") \
12094_(sw_interface_set_l2_xconnect, \
12095 "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
12096 "enable | disable") \
12097_(sw_interface_set_l2_bridge, \
12098 "rx <intfc> | rx_sw_if_index <id> bd_id <bridge-domain-id>\n" \
12099 "[shg <split-horizon-group>] [bvi]\n" \
12100 "enable | disable") \
12101_(bridge_domain_add_del, \
12102 "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
12103_(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n") \
12104_(l2fib_add_del, \
12105 "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi]\n") \
12106_(l2_flags, \
12107 "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
12108_(bridge_flags, \
12109 "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
12110_(tap_connect, \
12111 "tapname <name> mac <mac-addr> | random-mac") \
12112_(tap_modify, \
12113 "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
12114_(tap_delete, \
12115 "<vpp-if-name> | sw_if_index <id>") \
12116_(sw_interface_tap_dump, "") \
12117_(ip_add_del_route, \
12118 "<addr>/<mask> via <addr> [vrf <n>]\n" \
12119 "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n" \
12120 "[weight <n>] [drop] [local] [classify <n>] [del]\n" \
12121 "[multipath] [count <n>]") \
12122_(proxy_arp_add_del, \
12123 "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]") \
12124_(proxy_arp_intfc_enable_disable, \
12125 "<intfc> | sw_if_index <id> enable | disable") \
12126_(mpls_add_del_encap, \
12127 "label <n> dst <ip4-addr> [vrf <n>] [del]") \
12128_(mpls_add_del_decap, \
12129 "label <n> [rx_vrf_id <n>] [tx_vrf_id] [s-bit-clear][del]") \
12130_(mpls_gre_add_del_tunnel, \
12131 "inner_vrf_id <n> outer_vrf_id <n> src <ip4-address> dst <ip4-address>\n" \
12132 "adj <ip4-address>/<mask-width> [del]") \
12133_(sw_interface_set_unnumbered, \
12134 "<intfc> | sw_if_index <id> unnum_if_index <id> [del]") \
12135_(ip_neighbor_add_del, \
12136 "<intfc> | sw_if_index <id> dst <ip46-address> mac <mac-addr>") \
12137_(reset_vrf, "vrf <id> [ipv6]") \
12138_(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>") \
12139_(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n" \
12140 "[outer_vlan_id <n>][inner_vlan_id <n>]\n" \
12141 "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n" \
12142 "[outer_vlan_id_any][inner_vlan_id_any]") \
12143_(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]") \
12144_(reset_fib, "vrf <n> [ipv6]") \
12145_(dhcp_proxy_config, \
12146 "svr <v46-address> src <v46-address>\n" \
12147 "insert-cid <n> [del]") \
12148_(dhcp_proxy_config_2, \
12149 "svr <v46-address> src <v46-address>\n" \
12150 "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]") \
12151_(dhcp_proxy_set_vss, \
12152 "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]") \
12153_(dhcp_client_config, \
12154 "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
12155_(set_ip_flow_hash, \
12156 "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]") \
12157_(sw_interface_ip6_enable_disable, \
12158 "<intfc> | sw_if_index <id> enable | disable") \
12159_(sw_interface_ip6_set_link_local_address, \
12160 "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>") \
12161_(sw_interface_ip6nd_ra_prefix, \
12162 "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n" \
12163 "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n" \
12164 "[nolink] [isno]") \
12165_(sw_interface_ip6nd_ra_config, \
12166 "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n" \
Chris Luke33879c92016-06-28 19:54:21 -040012167 "[life <n>] [count <n>] [interval <n>] [suppress]\n" \
Ed Warnickecb9cada2015-12-08 15:45:58 -070012168 "[managed] [other] [ll] [send] [cease] [isno] [def]") \
12169_(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]") \
12170_(l2_patch_add_del, \
12171 "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
12172 "enable | disable") \
12173_(mpls_ethernet_add_del_tunnel, \
12174 "tx <intfc> | tx_sw_if_index <n> dst <mac-addr>\n" \
12175 "adj <ip4-addr>/<mw> dst <mac-addr> [del]") \
12176_(mpls_ethernet_add_del_tunnel_2, \
12177 "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n" \
12178 "resolve-attempts <n> resolve-if-needed 0 | 1 [del]") \
12179_(sr_tunnel_add_del, \
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -070012180 "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n" \
12181 "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n" \
12182 "[policy <policy_name>]") \
12183_(sr_policy_add_del, \
12184 "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]") \
12185_(sr_multicast_map_add_del, \
12186 "address [ip6 multicast address] sr-policy [policy name] [del]") \
Ed Warnickecb9cada2015-12-08 15:45:58 -070012187_(classify_add_del_table, \
12188 "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n" \
12189 "[del] mask <mask-value>\n" \
12190 " [l2-miss-next | miss-next | acl-miss-next] <name|nn>") \
12191_(classify_add_del_session, \
12192 "[hit-next|l2-hit-next|acl-hit-next] <name|nn> table-index <nn>\n" \
12193 "skip_n <nn> match_n <nn> match [hex] [l2] [l3 [ip4|ip6]]") \
12194_(classify_set_interface_ip_table, \
12195 "<intfc> | sw_if_index <nn> table <nn>") \
12196_(classify_set_interface_l2_tables, \
12197 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
12198 " [other-table <nn>]") \
12199_(get_node_index, "node <node-name") \
12200_(add_node_next, "node <node-name> next <next-node-name>") \
12201_(l2tpv3_create_tunnel, \
12202 "client_address <ip6-addr> our_address <ip6-addr>\n" \
12203 "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
12204 "[remote_cookie <nn>]\n[l2-sublayer-preset]\n") \
12205_(l2tpv3_set_tunnel_cookies, \
12206 "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n" \
12207 "[new_remote_cookie <nn>]\n") \
12208_(l2tpv3_interface_enable_disable, \
12209 "<intfc> | sw_if_index <nn> enable | disable") \
12210_(l2tpv3_set_lookup_key, \
12211 "lookup_v6_src | lookup_v6_dst | lookup_session_id") \
12212_(sw_if_l2tpv3_tunnel_dump, "") \
12213_(vxlan_add_del_tunnel, \
Chris Luke404be662016-05-27 12:11:24 -040012214 "src <ip-addr> dst <ip-addr> vni <vni> [encap-vrf-id <nn>]\n" \
Ed Warnickecb9cada2015-12-08 15:45:58 -070012215 " [decap-next l2|ip4|ip6] [del]") \
Dave Wallace60231f32015-12-17 21:04:30 -050012216_(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
Chris Luke27fe48f2016-04-28 13:44:38 -040012217_(gre_add_del_tunnel, \
12218 "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [del]\n") \
12219_(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
Ed Warnickecb9cada2015-12-08 15:45:58 -070012220_(l2_fib_clear_table, "") \
12221_(l2_interface_efp_filter, "sw_if_index <nn> enable | disable") \
12222_(l2_interface_vlan_tag_rewrite, \
12223 "<intfc> | sw_if_index <nn> \n" \
12224 "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n" \
12225 "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>") \
12226_(create_vhost_user_if, \
Pierre Pfisteref65cb02016-02-19 13:52:44 +000012227 "socket <filename> [server] [renumber <dev_instance>] " \
12228 "[mac <mac_address>]") \
Ed Warnickecb9cada2015-12-08 15:45:58 -070012229_(modify_vhost_user_if, \
12230 "<intfc> | sw_if_index <nn> socket <filename>\n" \
12231 "[server] [renumber <dev_instance>]") \
12232_(delete_vhost_user_if, "<intfc> | sw_if_index <nn>") \
12233_(sw_interface_vhost_user_dump, "") \
12234_(show_version, "") \
Hongjun Ni0e06e2b2016-05-30 19:45:51 +080012235_(vxlan_gpe_add_del_tunnel, \
12236 "local <addr> remote <addr> vni <nn>\n" \
12237 "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]" \
12238 "[next-ethernet] [next-nsh]\n") \
12239_(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
Ed Warnickecb9cada2015-12-08 15:45:58 -070012240_(l2_fib_table_dump, "bd_id <bridge-domain-id>") \
Ed Warnickecb9cada2015-12-08 15:45:58 -070012241_(interface_name_renumber, \
12242 "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>") \
12243_(input_acl_set_interface, \
12244 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
12245 " [l2-table <nn>] [del]") \
12246_(want_ip4_arp_events, "address <ip4-address> [del]") \
12247_(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)") \
12248_(ip_dump, "ipv4 | ipv6") \
12249_(ipsec_spd_add_del, "spd_id <n> [del]") \
12250_(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n" \
12251 " spid_id <n> ") \
12252_(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n" \
12253 " crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n" \
12254 " integ_alg <alg> integ_key <hex>") \
12255_(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n" \
12256 " (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n" \
12257 " laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
12258 " [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
12259_(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>") \
Matus Fabiane5f42fe2016-04-08 11:18:08 +020012260_(ikev2_profile_add_del, "name <profile_name> [del]") \
12261_(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n" \
12262 "(auth_data 0x<data> | auth_data <data>)") \
12263_(ikev2_profile_set_id, "name <profile_name> id_type <type>\n" \
12264 "(id_data 0x<data> | id_data <data>) (local|remote)") \
12265_(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n" \
12266 "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
12267 "(local|remote)") \
12268_(ikev2_set_local_key, "file <absolute_file_path>") \
Ed Warnickecb9cada2015-12-08 15:45:58 -070012269_(delete_loopback,"sw_if_index <nn>") \
12270_(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
12271_(map_add_domain, \
12272 "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> " \
12273 "ip6-src <ip6addr> " \
12274 "ea-bits-len <n> psid-offset <n> psid-len <n>") \
12275_(map_del_domain, "index <n>") \
12276_(map_add_del_rule, \
12277 "index <n> psid <n> dst <ip6addr> [del]") \
12278_(map_domain_dump, "") \
12279_(map_rule_dump, "index <map-domain>") \
12280_(want_interface_events, "enable|disable") \
12281_(want_stats,"enable|disable") \
Dave Barachc07bf5d2016-02-17 17:52:26 -050012282_(get_first_msg_id, "client <name>") \
12283_(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
12284_(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n" \
Dave Barachb44e9bc2016-02-19 09:06:23 -050012285 "fib-id <nn> [ip4][ip6][default]") \
Pavel Kotucek00bbf272016-03-03 13:27:11 +010012286_(get_node_graph, " ") \
Shwetha20a64f52016-03-25 10:55:01 +000012287_(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>") \
12288_(trace_profile_add, "id <nn> trace-type <0x1f|0x3|0x9|0x11|0x19> " \
12289 "trace-elts <nn> trace-tsp <0|1|2|3> node-id <node id in hex> " \
12290 "app-data <app_data in hex> [pow] [ppc <encap|decap>]") \
12291_(trace_profile_apply, "id <nn> <ip6-address>/<width>" \
12292 " vrf_id <nn> add | pop | none") \
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020012293_(trace_profile_del, "") \
12294_(lisp_add_del_locator_set, "locator-set <locator_name> [del]") \
12295_(lisp_add_del_locator, "locator-set <locator_name> " \
12296 "iface <intf> | sw_if_index <sw_if_index> " \
12297 "p <priority> w <weight> [del]") \
12298_(lisp_add_del_local_eid, "<ipv4|ipv6>/<prefix> " \
12299 "locator-set <locator_name> [del]") \
12300_(lisp_gpe_add_del_fwd_entry, "eid <ip4|6-addr>/<prefix> " \
12301 "sloc <ip4/6-addr> dloc <ip4|6-addr> [del]") \
12302_(lisp_add_del_map_resolver, "<ip4|6-addr> [del]") \
Florin Coras577c3552016-04-21 00:45:40 +020012303_(lisp_gpe_enable_disable, "enable|disable") \
Filip Tehlar46d4e362016-05-09 09:39:26 +020012304_(lisp_enable_disable, "enable|disable") \
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020012305_(lisp_gpe_add_del_iface, "up|down") \
Florin Corasf727db92016-06-23 15:01:58 +020012306_(lisp_add_del_remote_mapping, "add|del vni <vni> deid <dest-eid> seid" \
Filip Tehlar195bcee2016-05-13 17:37:35 +020012307 " <src-eid> rloc <locator> " \
Florin Corasf727db92016-06-23 15:01:58 +020012308 "[rloc <loc> ... ] action <action>") \
12309_(lisp_add_del_adjacency, "add|del vni <vni> deid <dest-eid> seid" \
12310 " <src-eid> rloc <locator> " \
12311 "[rloc <loc> ... ] action <action>") \
Filip Tehlar53f09e32016-05-19 14:25:44 +020012312_(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del") \
Andrej Kozemcakb6e4d392016-06-14 13:55:57 +020012313_(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]") \
Filip Tehlar324112f2016-06-02 16:07:38 +020012314_(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>") \
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020012315_(lisp_locator_set_dump, "") \
12316_(lisp_local_eid_table_dump, "") \
12317_(lisp_gpe_tunnel_dump, "") \
Andrej Kozemcaka9edd852016-05-02 12:14:33 +020012318_(lisp_map_resolver_dump, "") \
Filip Tehlar46d4e362016-05-09 09:39:26 +020012319_(lisp_enable_disable_status_dump, "") \
Andrej Kozemcakb6e4d392016-06-14 13:55:57 +020012320_(lisp_get_map_request_itr_rlocs, "") \
Matus Fabian8a95a482016-05-06 15:14:13 +020012321_(af_packet_create, "name <host interface name> [hw_addr <mac>]") \
Matus Fabian65fcd4d2016-05-13 05:44:48 -070012322_(af_packet_delete, "name <host interface name>") \
Matus Fabian82e29c42016-05-11 04:49:46 -070012323_(policer_add_del, "name <policer name> <params> [del]") \
Matus Fabiane8554802016-05-18 23:40:37 -070012324_(policer_dump, "[name <policer name>]") \
Matus Fabian82e29c42016-05-11 04:49:46 -070012325_(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] " \
12326 "[master|slave]") \
marek zavodsky2c21a9a2016-06-21 05:35:16 +020012327_(netmap_delete, "name <interface name>") \
12328_(mpls_gre_tunnel_dump, "tunnel_index <tunnel-id>") \
12329_(mpls_eth_tunnel_dump, "tunnel_index <tunnel-id>") \
12330_(mpls_fib_encap_dump, "") \
Pavel Kotucek20c90f72016-06-07 14:44:26 +020012331_(mpls_fib_decap_dump, "") \
12332_(classify_table_ids, "") \
12333_(classify_table_by_interface, "sw_if_index <sw_if_index>") \
12334_(classify_table_info, "table_id <nn>") \
12335_(classify_session_dump, "table_id <nn>")
Ed Warnickecb9cada2015-12-08 15:45:58 -070012336
12337/* List of command functions, CLI names map directly to functions */
12338#define foreach_cli_function \
12339_(comment, "usage: comment <ignore-rest-of-line>") \
12340_(dump_interface_table, "usage: dump_interface_table") \
12341_(dump_sub_interface_table, "usage: dump_sub_interface_table") \
12342_(dump_ipv4_table, "usage: dump_ipv4_table") \
12343_(dump_ipv6_table, "usage: dump_ipv6_table") \
12344_(dump_stats_table, "usage: dump_stats_table") \
12345_(dump_macro_table, "usage: dump_macro_table ") \
Dave Barachb44e9bc2016-02-19 09:06:23 -050012346_(dump_node_table, "usage: dump_node_table") \
Ed Warnickecb9cada2015-12-08 15:45:58 -070012347_(echo, "usage: echo <message>") \
12348_(exec, "usage: exec <vpe-debug-CLI-command>") \
12349_(help, "usage: help") \
12350_(q, "usage: quit") \
12351_(quit, "usage: quit") \
Dave Barachb44e9bc2016-02-19 09:06:23 -050012352_(search_node_table, "usage: search_node_table <name>...") \
Ed Warnickecb9cada2015-12-08 15:45:58 -070012353_(set, "usage: set <variable-name> <value>") \
12354_(script, "usage: script <file-name>") \
12355_(unset, "usage: unset <variable-name>")
12356
12357#define _(N,n) \
12358 static void vl_api_##n##_t_handler_uni \
12359 (vl_api_##n##_t * mp) \
12360 { \
12361 vat_main_t * vam = &vat_main; \
12362 if (vam->json_output) { \
12363 vl_api_##n##_t_handler_json(mp); \
12364 } else { \
12365 vl_api_##n##_t_handler(mp); \
12366 } \
12367 }
12368foreach_vpe_api_reply_msg;
12369#undef _
12370
12371void vat_api_hookup (vat_main_t *vam)
12372{
12373#define _(N,n) \
12374 vl_msg_api_set_handlers(VL_API_##N, #n, \
12375 vl_api_##n##_t_handler_uni, \
12376 vl_noop_handler, \
12377 vl_api_##n##_t_endian, \
12378 vl_api_##n##_t_print, \
12379 sizeof(vl_api_##n##_t), 1);
12380 foreach_vpe_api_reply_msg;
12381#undef _
12382
12383 vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
12384
12385 vam->sw_if_index_by_interface_name =
12386 hash_create_string (0, sizeof (uword));
12387
12388 vam->function_by_name =
12389 hash_create_string (0, sizeof(uword));
12390
12391 vam->help_by_name =
12392 hash_create_string (0, sizeof(uword));
12393
12394 /* API messages we can send */
12395#define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
12396 foreach_vpe_api_msg;
12397#undef _
12398
12399 /* Help strings */
12400#define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
12401 foreach_vpe_api_msg;
12402#undef _
12403
12404 /* CLI functions */
12405#define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
12406 foreach_cli_function;
12407#undef _
12408
12409 /* Help strings */
12410#define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
12411 foreach_cli_function;
12412#undef _
12413}
12414
12415#undef vl_api_version
12416#define vl_api_version(n,v) static u32 vpe_api_version = v;
Dave Barachaa6920e2016-06-27 09:25:13 -040012417#include <vpp-api/vpe.api.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070012418#undef vl_api_version
12419
12420void vl_client_add_api_signatures (vl_api_memclnt_create_t *mp)
12421{
12422 /*
12423 * Send the main API signature in slot 0. This bit of code must
12424 * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
12425 */
12426 mp->api_versions[0] = clib_host_to_net_u32 (vpe_api_version);
12427}