blob: 086c888c465c6308375334652802e4060b69d510 [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
33#include <api/vpe_msg_enum.h>
34#include <vnet/l2/l2_classify.h>
35#include <vnet/l2/l2_vtr.h>
36#include <vnet/classify/input_acl.h>
Dave Barachbfdedbd2016-01-20 09:11:55 -050037#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -070038#include <vnet/ipsec/ipsec.h>
Matus Fabiane5f42fe2016-04-08 11:18:08 +020039#include <vnet/ipsec/ikev2.h>
Dave Barachbfdedbd2016-01-20 09:11:55 -050040#else
41#include <inttypes.h>
42#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -070043#include <vnet/map/map.h>
Dave Barachc07bf5d2016-02-17 17:52:26 -050044#include <vnet/cop/cop.h>
Shwetha20a64f52016-03-25 10:55:01 +000045#include <vnet/ip/ip6_hop_by_hop.h>
Matus Fabian65fcd4d2016-05-13 05:44:48 -070046#include <vnet/policer/xlate.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070047
48#include "vat/json_format.h"
49
50#define vl_typedefs /* define message structures */
51#include <api/vpe_all_api_h.h>
52#undef vl_typedefs
53
54/* declare message handlers for each api */
55
56#define vl_endianfun /* define message structures */
57#include <api/vpe_all_api_h.h>
58#undef vl_endianfun
59
60/* instantiate all the print functions we know about */
61#define vl_print(handle, ...)
62#define vl_printfun
63#include <api/vpe_all_api_h.h>
64#undef vl_printfun
65
66uword unformat_sw_if_index (unformat_input_t * input, va_list * args)
67{
68 vat_main_t * vam = va_arg (*args, vat_main_t *);
69 u32 * result = va_arg (*args, u32 *);
70 u8 * if_name;
71 uword * p;
72
73 if (!unformat (input, "%s", &if_name))
74 return 0;
75
76 p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
77 if (p == 0)
78 return 0;
79 *result = p[0];
80 return 1;
81}
82
83/* Parse an IP4 address %d.%d.%d.%d. */
84uword unformat_ip4_address (unformat_input_t * input, va_list * args)
85{
86 u8 * result = va_arg (*args, u8 *);
87 unsigned a[4];
88
89 if (! unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
90 return 0;
91
92 if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
93 return 0;
94
95 result[0] = a[0];
96 result[1] = a[1];
97 result[2] = a[2];
98 result[3] = a[3];
99
100 return 1;
101}
102
103
104uword
105unformat_ethernet_address (unformat_input_t * input, va_list * args)
106{
107 u8 * result = va_arg (*args, u8 *);
108 u32 i, a[6];
109
110 if (! unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
111 &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
112 return 0;
113
114 /* Check range. */
115 for (i = 0; i < 6; i++)
116 if (a[i] >= (1 << 8))
117 return 0;
118
119 for (i = 0; i < 6; i++)
120 result[i] = a[i];
121
122 return 1;
123}
124
125/* Returns ethernet type as an int in host byte order. */
126uword
127unformat_ethernet_type_host_byte_order (unformat_input_t * input,
128 va_list * args)
129{
130 u16 * result = va_arg (*args, u16 *);
131 int type;
132
133 /* Numeric type. */
134 if (unformat (input, "0x%x", &type)
135 || unformat (input, "%d", &type))
136 {
137 if (type >= (1 << 16))
138 return 0;
139 *result = type;
140 return 1;
141 }
142 return 0;
143}
144
145/* Parse an IP6 address. */
146uword unformat_ip6_address (unformat_input_t * input, va_list * args)
147{
148 ip6_address_t * result = va_arg (*args, ip6_address_t *);
149 u16 hex_quads[8];
150 uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
151 uword c, n_colon, double_colon_index;
152
153 n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
154 double_colon_index = ARRAY_LEN (hex_quads);
155 while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
156 {
157 hex_digit = 16;
158 if (c >= '0' && c <= '9')
159 hex_digit = c - '0';
160 else if (c >= 'a' && c <= 'f')
161 hex_digit = c + 10 - 'a';
162 else if (c >= 'A' && c <= 'F')
163 hex_digit = c + 10 - 'A';
164 else if (c == ':' && n_colon < 2)
165 n_colon++;
166 else
167 {
168 unformat_put_input (input);
169 break;
170 }
171
172 /* Too many hex quads. */
173 if (n_hex_quads >= ARRAY_LEN (hex_quads))
174 return 0;
175
176 if (hex_digit < 16)
177 {
178 hex_quad = (hex_quad << 4) | hex_digit;
179
180 /* Hex quad must fit in 16 bits. */
181 if (n_hex_digits >= 4)
182 return 0;
183
184 n_colon = 0;
185 n_hex_digits++;
186 }
187
188 /* Save position of :: */
189 if (n_colon == 2)
190 {
191 /* More than one :: ? */
192 if (double_colon_index < ARRAY_LEN (hex_quads))
193 return 0;
194 double_colon_index = n_hex_quads;
195 }
196
197 if (n_colon > 0 && n_hex_digits > 0)
198 {
199 hex_quads[n_hex_quads++] = hex_quad;
200 hex_quad = 0;
201 n_hex_digits = 0;
202 }
203 }
204
205 if (n_hex_digits > 0)
206 hex_quads[n_hex_quads++] = hex_quad;
207
208 {
209 word i;
210
211 /* Expand :: to appropriate number of zero hex quads. */
212 if (double_colon_index < ARRAY_LEN (hex_quads))
213 {
214 word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
215
216 for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
217 hex_quads[n_zero + i] = hex_quads[i];
218
219 for (i = 0; i < n_zero; i++)
220 hex_quads[double_colon_index + i] = 0;
221
222 n_hex_quads = ARRAY_LEN (hex_quads);
223 }
224
225 /* Too few hex quads given. */
226 if (n_hex_quads < ARRAY_LEN (hex_quads))
227 return 0;
228
229 for (i = 0; i < ARRAY_LEN (hex_quads); i++)
230 result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
231
232 return 1;
233 }
234}
235
236uword
237unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
238{
Dave Barachbfdedbd2016-01-20 09:11:55 -0500239#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -0700240 u32 * r = va_arg (*args, u32 *);
241
242 if (0) ;
243#define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
244 foreach_ipsec_policy_action
245#undef _
246 else
247 return 0;
248 return 1;
Dave Barachbfdedbd2016-01-20 09:11:55 -0500249#else
250 return 0;
251#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -0700252}
253
254uword
255unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
256{
Dave Barachbfdedbd2016-01-20 09:11:55 -0500257#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -0700258 u32 * r = va_arg (*args, u32 *);
259
260 if (0) ;
261#define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
262 foreach_ipsec_crypto_alg
263#undef _
264 else
265 return 0;
266 return 1;
Dave Barachbfdedbd2016-01-20 09:11:55 -0500267#else
268 return 0;
269#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -0700270}
271
272u8 *
273format_ipsec_crypto_alg (u8 * s, va_list * args)
274{
Dave Barachbfdedbd2016-01-20 09:11:55 -0500275#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -0700276 u32 i = va_arg (*args, u32);
277 u8 * t = 0;
278
279 switch (i)
280 {
281#define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
282 foreach_ipsec_crypto_alg
283#undef _
284 default:
285 return format (s, "unknown");
286 }
287 return format (s, "%s", t);
Dave Barachbfdedbd2016-01-20 09:11:55 -0500288#else
289 return format (s, "Unimplemented");
290#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -0700291}
292
293uword
294unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
295{
Dave Barachbfdedbd2016-01-20 09:11:55 -0500296#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -0700297 u32 * r = va_arg (*args, u32 *);
298
299 if (0) ;
300#define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
301 foreach_ipsec_integ_alg
302#undef _
303 else
304 return 0;
305 return 1;
Dave Barachbfdedbd2016-01-20 09:11:55 -0500306#else
307 return 0;
308#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -0700309}
310
311u8 *
312format_ipsec_integ_alg (u8 * s, va_list * args)
313{
Dave Barachbfdedbd2016-01-20 09:11:55 -0500314#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -0700315 u32 i = va_arg (*args, u32);
316 u8 * t = 0;
317
318 switch (i)
319 {
320#define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
321 foreach_ipsec_integ_alg
322#undef _
323 default:
324 return format (s, "unknown");
325 }
326 return format (s, "%s", t);
Dave Barachbfdedbd2016-01-20 09:11:55 -0500327#else
328 return format (s, "Unsupported");
329#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -0700330}
331
Matus Fabiane5f42fe2016-04-08 11:18:08 +0200332uword
333unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
334{
335#if DPDK > 0
336 u32 * r = va_arg (*args, u32 *);
337
338 if (0) ;
339#define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
340 foreach_ikev2_auth_method
341#undef _
342 else
343 return 0;
344 return 1;
345#else
346 return 0;
347#endif
348}
349
350uword
351unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
352{
353#if DPDK > 0
354 u32 * r = va_arg (*args, u32 *);
355
356 if (0) ;
357#define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
358 foreach_ikev2_id_type
359#undef _
360 else
361 return 0;
362 return 1;
363#else
364 return 0;
365#endif
366}
367
Matus Fabian65fcd4d2016-05-13 05:44:48 -0700368uword
369unformat_policer_rate_type (unformat_input_t * input, va_list * args)
370{
371 u8 * r = va_arg (*args, u8 *);
372
373 if (unformat (input, "kbps"))
374 *r = SSE2_QOS_RATE_KBPS;
375 else if (unformat(input, "pps"))
376 *r = SSE2_QOS_RATE_PPS;
377 else
378 return 0;
379 return 1;
380}
381
382uword
383unformat_policer_round_type (unformat_input_t * input, va_list * args)
384{
385 u8 * r = va_arg (*args, u8 *);
386
387 if (unformat(input, "closest"))
388 *r = SSE2_QOS_ROUND_TO_CLOSEST;
389 else if (unformat (input, "up"))
390 *r = SSE2_QOS_ROUND_TO_UP;
391 else if (unformat (input, "down"))
392 *r = SSE2_QOS_ROUND_TO_DOWN;
393 else
394 return 0;
395 return 1;
396}
397
398uword
399unformat_policer_type (unformat_input_t * input, va_list * args)
400{
401 u8 * r = va_arg (*args, u8 *);
402
403 if (unformat (input, "1r2c"))
404 *r = SSE2_QOS_POLICER_TYPE_1R2C;
405 else if (unformat (input, "1r3c"))
406 *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
407 else if (unformat (input, "2r3c-2698"))
408 *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
409 else if (unformat (input, "2r3c-4115"))
410 *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
411 else if (unformat (input, "2r3c-mef5cf1"))
412 *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
413 else
414 return 0;
415 return 1;
416}
417
Ed Warnickecb9cada2015-12-08 15:45:58 -0700418u8 * format_ip4_address (u8 * s, va_list * args)
419{
420 u8 * a = va_arg (*args, u8 *);
421 return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
422}
423
424u8 * format_ip6_address (u8 * s, va_list * args)
425{
426 ip6_address_t * a = va_arg (*args, ip6_address_t *);
427 u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
428
429 i_max_n_zero = ARRAY_LEN (a->as_u16);
430 max_n_zeros = 0;
431 i_first_zero = i_max_n_zero;
432 n_zeros = 0;
433 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
434 {
435 u32 is_zero = a->as_u16[i] == 0;
436 if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
437 {
438 i_first_zero = i;
439 n_zeros = 0;
440 }
441 n_zeros += is_zero;
442 if ((! is_zero && n_zeros > max_n_zeros)
443 || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
444 {
445 i_max_n_zero = i_first_zero;
446 max_n_zeros = n_zeros;
447 i_first_zero = ARRAY_LEN (a->as_u16);
448 n_zeros = 0;
449 }
450 }
451
452 last_double_colon = 0;
453 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
454 {
455 if (i == i_max_n_zero && max_n_zeros > 1)
456 {
457 s = format (s, "::");
458 i += max_n_zeros - 1;
459 last_double_colon = 1;
460 }
461 else
462 {
463 s = format (s, "%s%x",
464 (last_double_colon || i == 0) ? "" : ":",
465 clib_net_to_host_u16 (a->as_u16[i]));
466 last_double_colon = 0;
467 }
468 }
469
470 return s;
471}
472
Chris Luke99cb3352016-04-26 10:49:53 -0400473/* Format an IP46 address. */
474u8 * format_ip46_address (u8 * s, va_list * args)
475{
476 ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
Damjan Marion86be4872016-05-24 23:19:11 +0200477 ip46_type_t type = va_arg (*args, ip46_type_t);
478 int is_ip4 = 1;
479
480 switch (type)
481 {
482 case IP46_TYPE_ANY:
483 is_ip4 = ip46_address_is_ip4(ip46);
484 break;
485 case IP46_TYPE_IP4:
486 is_ip4 = 1;
487 break;
488 case IP46_TYPE_IP6:
489 is_ip4 = 0;
490 break;
491 }
492
493 return is_ip4 ?
Chris Luke99cb3352016-04-26 10:49:53 -0400494 format(s, "%U", format_ip4_address, &ip46->ip4):
495 format(s, "%U", format_ip6_address, &ip46->ip6);
496}
497
Ed Warnickecb9cada2015-12-08 15:45:58 -0700498u8 * format_ethernet_address (u8 * s, va_list * args)
499{
500 u8 * a = va_arg (*args, u8 *);
501
502 return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
503 a[0], a[1], a[2], a[3], a[4], a[5]);
504}
505
506void increment_v4_address (ip4_address_t * a)
507{
508 u32 v;
509
510 v = ntohl(a->as_u32) + 1;
511 a->as_u32 = ntohl(v);
512}
513
514void increment_v6_address (ip6_address_t * a)
515{
516 u64 v0, v1;
517
518 v0 = clib_net_to_host_u64 (a->as_u64[0]);
519 v1 = clib_net_to_host_u64 (a->as_u64[1]);
520
521 v1 += 1;
522 if (v1 == 0)
523 v0 += 1;
524 a->as_u64[0] = clib_net_to_host_u64 (v0);
525 a->as_u64[1] = clib_net_to_host_u64 (v1);
526}
527
528
529static void vl_api_create_loopback_reply_t_handler
530(vl_api_create_loopback_reply_t * mp)
531{
532 vat_main_t * vam = &vat_main;
533 i32 retval = ntohl(mp->retval);
534
535 vam->retval = retval;
536 vam->result_ready = 1;
537 vam->regenerate_interface_table = 1;
538}
539
540static void vl_api_create_loopback_reply_t_handler_json
541(vl_api_create_loopback_reply_t * mp)
542{
543 vat_main_t * vam = &vat_main;
544 vat_json_node_t node;
545
546 vat_json_init_object(&node);
547 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
548 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
549
550 vat_json_print(vam->ofp, &node);
551 vat_json_free(&node);
552
553 vam->retval = ntohl(mp->retval);
554 vam->result_ready = 1;
555}
556
557static void vl_api_create_vlan_subif_reply_t_handler
558(vl_api_create_vlan_subif_reply_t * mp)
559{
560 vat_main_t * vam = &vat_main;
561 i32 retval = ntohl(mp->retval);
562
563 vam->retval = retval;
564 vam->result_ready = 1;
565 vam->regenerate_interface_table = 1;
566}
567
568static void vl_api_create_vlan_subif_reply_t_handler_json
569(vl_api_create_vlan_subif_reply_t * mp)
570{
571 vat_main_t * vam = &vat_main;
572 vat_json_node_t node;
573
574 vat_json_init_object(&node);
575 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
576 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
577
578 vat_json_print(vam->ofp, &node);
579 vat_json_free(&node);
580
581 vam->retval = ntohl(mp->retval);
582 vam->result_ready = 1;
583}
584
585static void vl_api_create_subif_reply_t_handler
586(vl_api_create_subif_reply_t * mp)
587{
588 vat_main_t * vam = &vat_main;
589 i32 retval = ntohl(mp->retval);
590
591 vam->retval = retval;
592 vam->result_ready = 1;
593 vam->regenerate_interface_table = 1;
594}
595
596static void vl_api_create_subif_reply_t_handler_json
597(vl_api_create_subif_reply_t * mp)
598{
599 vat_main_t * vam = &vat_main;
600 vat_json_node_t node;
601
602 vat_json_init_object(&node);
603 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
604 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
605
606 vat_json_print(vam->ofp, &node);
607 vat_json_free(&node);
608
609 vam->retval = ntohl(mp->retval);
610 vam->result_ready = 1;
611}
612
613static void vl_api_interface_name_renumber_reply_t_handler
614(vl_api_interface_name_renumber_reply_t * mp)
615{
616 vat_main_t * vam = &vat_main;
617 i32 retval = ntohl(mp->retval);
618
619 vam->retval = retval;
620 vam->result_ready = 1;
621 vam->regenerate_interface_table = 1;
622}
623
624static void vl_api_interface_name_renumber_reply_t_handler_json
625(vl_api_interface_name_renumber_reply_t * mp)
626{
627 vat_main_t * vam = &vat_main;
628 vat_json_node_t node;
629
630 vat_json_init_object(&node);
631 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
632
633 vat_json_print(vam->ofp, &node);
634 vat_json_free(&node);
635
636 vam->retval = ntohl(mp->retval);
637 vam->result_ready = 1;
638}
639
640/*
641 * Special-case: build the interface table, maintain
642 * the next loopback sw_if_index vbl.
643 */
644static void vl_api_sw_interface_details_t_handler
645(vl_api_sw_interface_details_t * mp)
646{
647 vat_main_t * vam = &vat_main;
648 u8 * s = format (0, "%s%c", mp->interface_name, 0);
649
650 hash_set_mem (vam->sw_if_index_by_interface_name, s,
651 ntohl(mp->sw_if_index));
652
653 /* In sub interface case, fill the sub interface table entry */
654 if (mp->sw_if_index != mp->sup_sw_if_index) {
655 sw_interface_subif_t * sub = NULL;
656
657 vec_add2(vam->sw_if_subif_table, sub, 1);
658
659 vec_validate(sub->interface_name, strlen((char *)s) + 1);
660 strncpy((char *)sub->interface_name, (char *)s,
661 vec_len(sub->interface_name));
662 sub->sw_if_index = ntohl(mp->sw_if_index);
663 sub->sub_id = ntohl(mp->sub_id);
664
665 sub->sub_dot1ad = mp->sub_dot1ad;
666 sub->sub_number_of_tags = mp->sub_number_of_tags;
667 sub->sub_outer_vlan_id = ntohs(mp->sub_outer_vlan_id);
668 sub->sub_inner_vlan_id = ntohs(mp->sub_inner_vlan_id);
669 sub->sub_exact_match = mp->sub_exact_match;
670 sub->sub_default = mp->sub_default;
671 sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
672 sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
673
674 /* vlan tag rewrite */
675 sub->vtr_op = ntohl(mp->vtr_op);
676 sub->vtr_push_dot1q = ntohl(mp->vtr_push_dot1q);
677 sub->vtr_tag1 = ntohl(mp->vtr_tag1);
678 sub->vtr_tag2 = ntohl(mp->vtr_tag2);
679 }
680}
681
682static void vl_api_sw_interface_details_t_handler_json
683(vl_api_sw_interface_details_t * mp)
684{
685 vat_main_t * vam = &vat_main;
686 vat_json_node_t *node = NULL;
687
688 if (VAT_JSON_ARRAY != vam->json_tree.type) {
689 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
690 vat_json_init_array(&vam->json_tree);
691 }
692 node = vat_json_array_add(&vam->json_tree);
693
694 vat_json_init_object(node);
695 vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
696 vat_json_object_add_uint(node, "sup_sw_if_index", ntohl(mp->sup_sw_if_index));
697 vat_json_object_add_uint(node, "l2_address_length", ntohl(mp->l2_address_length));
698 vat_json_object_add_bytes(node, "l2_address", mp->l2_address, sizeof(mp->l2_address));
699 vat_json_object_add_string_copy(node, "interface_name", mp->interface_name);
700 vat_json_object_add_uint(node, "admin_up_down", mp->admin_up_down);
701 vat_json_object_add_uint(node, "link_up_down", mp->link_up_down);
702 vat_json_object_add_uint(node, "link_duplex", mp->link_duplex);
703 vat_json_object_add_uint(node, "link_speed", mp->link_speed);
Pavel84e4ffe2016-02-17 15:10:04 +0100704 vat_json_object_add_uint(node, "mtu", ntohs(mp->link_mtu));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700705 vat_json_object_add_uint(node, "sub_id", ntohl(mp->sub_id));
706 vat_json_object_add_uint(node, "sub_dot1ad", mp->sub_dot1ad);
707 vat_json_object_add_uint(node, "sub_number_of_tags", mp->sub_number_of_tags);
708 vat_json_object_add_uint(node, "sub_outer_vlan_id", ntohs(mp->sub_outer_vlan_id));
709 vat_json_object_add_uint(node, "sub_inner_vlan_id", ntohs(mp->sub_inner_vlan_id));
710 vat_json_object_add_uint(node, "sub_exact_match", mp->sub_exact_match);
711 vat_json_object_add_uint(node, "sub_default", mp->sub_default);
712 vat_json_object_add_uint(node, "sub_outer_vlan_id_any", mp->sub_outer_vlan_id_any);
713 vat_json_object_add_uint(node, "sub_inner_vlan_id_any", mp->sub_inner_vlan_id_any);
714 vat_json_object_add_uint(node, "vtr_op", ntohl(mp->vtr_op));
715 vat_json_object_add_uint(node, "vtr_push_dot1q", ntohl(mp->vtr_push_dot1q));
716 vat_json_object_add_uint(node, "vtr_tag1", ntohl(mp->vtr_tag1));
717 vat_json_object_add_uint(node, "vtr_tag2", ntohl(mp->vtr_tag2));
718}
719
720static void vl_api_sw_interface_set_flags_t_handler
721(vl_api_sw_interface_set_flags_t * mp)
722{
723 vat_main_t * vam = &vat_main;
724 if (vam->interface_event_display)
725 errmsg ("interface flags: sw_if_index %d %s %s\n",
726 ntohl(mp->sw_if_index),
727 mp->admin_up_down ? "admin-up" : "admin-down",
728 mp->link_up_down ? "link-up" : "link-down");
729}
730
731static void vl_api_sw_interface_set_flags_t_handler_json
732(vl_api_sw_interface_set_flags_t * mp)
733{
734 /* JSON output not supported */
735}
736
Pavel Kotucek00bbf272016-03-03 13:27:11 +0100737static void vl_api_cli_reply_t_handler
Ed Warnickecb9cada2015-12-08 15:45:58 -0700738(vl_api_cli_reply_t * mp)
739{
740 vat_main_t * vam = &vat_main;
741 i32 retval = ntohl(mp->retval);
742
743 vam->retval = retval;
744 vam->shmem_result = (u8 *) mp->reply_in_shmem;
745 vam->result_ready = 1;
746}
747
748static void vl_api_cli_reply_t_handler_json
749(vl_api_cli_reply_t * mp)
750{
751 vat_main_t * vam = &vat_main;
752 vat_json_node_t node;
Dave Barachb44e9bc2016-02-19 09:06:23 -0500753 api_main_t * am = &api_main;
754 void * oldheap;
755 u8 * reply;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700756
757 vat_json_init_object(&node);
758 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
Dave Barachb44e9bc2016-02-19 09:06:23 -0500759 vat_json_object_add_uint(&node, "reply_in_shmem",
760 ntohl(mp->reply_in_shmem));
761 /* Toss the shared-memory original... */
762 pthread_mutex_lock (&am->vlib_rp->mutex);
763 oldheap = svm_push_data_heap (am->vlib_rp);
764
765 reply = (u8 *)(mp->reply_in_shmem);
766 vec_free (reply);
767
768 svm_pop_heap (oldheap);
769 pthread_mutex_unlock (&am->vlib_rp->mutex);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700770
771 vat_json_print(vam->ofp, &node);
772 vat_json_free(&node);
773
774 vam->retval = ntohl(mp->retval);
775 vam->result_ready = 1;
776}
777
778static void vl_api_classify_add_del_table_reply_t_handler
779(vl_api_classify_add_del_table_reply_t * mp)
780{
781 vat_main_t * vam = &vat_main;
782 i32 retval = ntohl(mp->retval);
783 if (vam->async_mode) {
784 vam->async_errors += (retval < 0);
785 } else {
786 vam->retval = retval;
787 vam->result_ready = 1;
788 if (retval == 0 &&
789 ((mp->new_table_index != 0xFFFFFFFF) ||
790 (mp->skip_n_vectors != 0xFFFFFFFF) ||
791 (mp->match_n_vectors != 0xFFFFFFFF)))
792 /*
793 * Note: this is just barely thread-safe, depends on
794 * the main thread spinning waiting for an answer...
795 */
796 errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d\n",
797 ntohl(mp->new_table_index),
798 ntohl(mp->skip_n_vectors), ntohl(mp->match_n_vectors));
799 }
800}
801
802static void vl_api_classify_add_del_table_reply_t_handler_json
803(vl_api_classify_add_del_table_reply_t * mp)
804{
805 vat_main_t * vam = &vat_main;
806 vat_json_node_t node;
807
808 vat_json_init_object(&node);
809 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
810 vat_json_object_add_uint(&node, "new_table_index", ntohl(mp->new_table_index));
811 vat_json_object_add_uint(&node, "skip_n_vectors", ntohl(mp->skip_n_vectors));
812 vat_json_object_add_uint(&node, "match_n_vectors", ntohl(mp->match_n_vectors));
813
814 vat_json_print(vam->ofp, &node);
815 vat_json_free(&node);
816
817 vam->retval = ntohl(mp->retval);
818 vam->result_ready = 1;
819}
820
821static void vl_api_get_node_index_reply_t_handler
822(vl_api_get_node_index_reply_t * mp)
823{
824 vat_main_t * vam = &vat_main;
825 i32 retval = ntohl(mp->retval);
826 if (vam->async_mode) {
827 vam->async_errors += (retval < 0);
828 } else {
829 vam->retval = retval;
830 vam->result_ready = 1;
831 if (retval == 0)
832 errmsg ("node index %d\n", ntohl(mp->node_index));
833 }
834}
835
836static void vl_api_get_node_index_reply_t_handler_json
837(vl_api_get_node_index_reply_t * mp)
838{
839 vat_main_t * vam = &vat_main;
840 vat_json_node_t node;
841
842 vat_json_init_object(&node);
843 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
844 vat_json_object_add_uint(&node, "node_index", ntohl(mp->node_index));
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_add_node_next_reply_t_handler
854(vl_api_add_node_next_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;
862 vam->result_ready = 1;
863 if (retval == 0)
864 errmsg ("next index %d\n", ntohl(mp->next_index));
865 }
866}
867
868static void vl_api_add_node_next_reply_t_handler_json
869(vl_api_add_node_next_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, "next_index", ntohl(mp->next_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_mpls_gre_add_del_tunnel_reply_t_handler
886(vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
887{
888 vat_main_t * vam = &vat_main;
889 i32 retval = ntohl(mp->retval);
890 u32 sw_if_index = ntohl(mp->tunnel_sw_if_index);
891
892 if (retval >= 0 && sw_if_index != (u32)~0) {
893 errmsg ("tunnel_sw_if_index %d\n", sw_if_index);
894 }
895 vam->retval = retval;
896 vam->result_ready = 1;
897}
898
899static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler_json
900(vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
901{
902 vat_main_t * vam = &vat_main;
903 vat_json_node_t node;
904
905 vat_json_init_object(&node);
906 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
907 vat_json_object_add_uint(&node, "tunnel_sw_if_index", ntohl(mp->tunnel_sw_if_index));
908
909 vat_json_print(vam->ofp, &node);
910 vat_json_free(&node);
911
912 vam->retval = ntohl(mp->retval);
913 vam->result_ready = 1;
914}
915
Ed Warnickecb9cada2015-12-08 15:45:58 -0700916
Ed Warnickecb9cada2015-12-08 15:45:58 -0700917static void vl_api_show_version_reply_t_handler
918(vl_api_show_version_reply_t * mp)
919{
920 vat_main_t * vam = &vat_main;
921 i32 retval = ntohl(mp->retval);
922
923 if (retval >= 0) {
924 errmsg (" program: %s\n", mp->program);
Damjan Mariona0d4a1a2015-12-12 14:40:59 +0100925 errmsg (" version: %s\n", mp->version);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700926 errmsg (" build date: %s\n", mp->build_date);
927 errmsg ("build directory: %s\n", mp->build_directory);
928 }
929 vam->retval = retval;
930 vam->result_ready = 1;
931}
932
933static void vl_api_show_version_reply_t_handler_json
934(vl_api_show_version_reply_t * mp)
935{
936 vat_main_t * vam = &vat_main;
937 vat_json_node_t node;
938
939 vat_json_init_object(&node);
940 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
941 vat_json_object_add_string_copy(&node, "program", mp->program);
Damjan Mariona0d4a1a2015-12-12 14:40:59 +0100942 vat_json_object_add_string_copy(&node, "version", mp->version);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700943 vat_json_object_add_string_copy(&node, "build_date", mp->build_date);
944 vat_json_object_add_string_copy(&node, "build_directory", mp->build_directory);
945
946 vat_json_print(vam->ofp, &node);
947 vat_json_free(&node);
948
949 vam->retval = ntohl(mp->retval);
950 vam->result_ready = 1;
951}
952
953static void vl_api_ip4_arp_event_t_handler
954(vl_api_ip4_arp_event_t * mp)
955{
956 vat_main_t * vam = &vat_main;
957 errmsg ("arp event: address %U new mac %U sw_if_index %d\n",
958 format_ip4_address, &mp->address,
959 format_ethernet_address, mp->new_mac, mp->sw_if_index);
960}
961
962static void vl_api_ip4_arp_event_t_handler_json
963(vl_api_ip4_arp_event_t * mp)
964{
965 /* JSON output not supported */
966}
967
968/*
969 * Special-case: build the bridge domain table, maintain
970 * the next bd id vbl.
971 */
972static void vl_api_bridge_domain_details_t_handler
973(vl_api_bridge_domain_details_t * mp)
974{
975 vat_main_t * vam = &vat_main;
976 u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
977
978 fformat (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s\n",
979 " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
980
981 fformat (vam->ofp, "%3d %3d %3d %3d %3d %3d\n",
982 ntohl (mp->bd_id), mp->learn, mp->forward,
983 mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
984
985 if (n_sw_ifs)
986 fformat (vam->ofp, "\n\n%s %s %s\n", "sw_if_index", "SHG",
987 "Interface Name");
988}
989
990static void vl_api_bridge_domain_details_t_handler_json
991(vl_api_bridge_domain_details_t * mp)
992{
993 vat_main_t * vam = &vat_main;
994 vat_json_node_t *node, *array = NULL;
995
996 if (VAT_JSON_ARRAY != vam->json_tree.type) {
997 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
998 vat_json_init_array(&vam->json_tree);
999 }
1000 node = vat_json_array_add(&vam->json_tree);
1001
1002 vat_json_init_object(node);
1003 vat_json_object_add_uint(node, "bd_id", ntohl(mp->bd_id));
1004 vat_json_object_add_uint(node, "flood", mp->flood);
1005 vat_json_object_add_uint(node, "forward", mp->forward);
1006 vat_json_object_add_uint(node, "learn", mp->learn);
1007 vat_json_object_add_uint(node, "bvi_sw_if_index", ntohl(mp->bvi_sw_if_index));
1008 vat_json_object_add_uint(node, "n_sw_ifs", ntohl(mp->n_sw_ifs));
1009 array = vat_json_object_add(node, "sw_if");
1010 vat_json_init_array(array);
1011}
1012
1013/*
1014 * Special-case: build the bridge domain sw if table.
1015 */
1016static void vl_api_bridge_domain_sw_if_details_t_handler
1017(vl_api_bridge_domain_sw_if_details_t * mp)
1018{
1019 vat_main_t * vam = &vat_main;
1020 hash_pair_t * p;
1021 u8 * sw_if_name = 0;
1022 u32 sw_if_index;
1023
1024 sw_if_index = ntohl (mp->sw_if_index);
1025 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1026 ({
1027 if ((u32) p->value[0] == sw_if_index) {
1028 sw_if_name = (u8 *)(p->key);
1029 break;
1030 }
1031 }));
1032
1033 fformat (vam->ofp, "%7d %3d %s", sw_if_index,
1034 mp->shg, sw_if_name ? (char *)sw_if_name :
1035 "sw_if_index not found!");
1036}
1037
1038static void vl_api_bridge_domain_sw_if_details_t_handler_json
1039(vl_api_bridge_domain_sw_if_details_t * mp)
1040{
1041 vat_main_t * vam = &vat_main;
1042 vat_json_node_t *node = NULL;
1043 uword last_index = 0;
1044
1045 ASSERT(VAT_JSON_ARRAY == vam->json_tree.type);
1046 ASSERT(vec_len(vam->json_tree.array) >= 1);
1047 last_index = vec_len(vam->json_tree.array) - 1;
1048 node = &vam->json_tree.array[last_index];
1049 node = vat_json_object_get_element(node, "sw_if");
1050 ASSERT(NULL != node);
1051 node = vat_json_array_add(node);
1052
1053 vat_json_init_object(node);
1054 vat_json_object_add_uint(node, "bd_id", ntohl(mp->bd_id));
1055 vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
1056 vat_json_object_add_uint(node, "shg", mp->shg);
1057}
1058
1059static void vl_api_control_ping_reply_t_handler
1060(vl_api_control_ping_reply_t * mp)
1061{
1062 vat_main_t * vam = &vat_main;
1063 i32 retval = ntohl(mp->retval);
1064 if (vam->async_mode) {
1065 vam->async_errors += (retval < 0);
1066 } else {
1067 vam->retval = retval;
1068 vam->result_ready = 1;
1069 }
1070}
1071
1072static void vl_api_control_ping_reply_t_handler_json
1073(vl_api_control_ping_reply_t * mp)
1074{
1075 vat_main_t * vam = &vat_main;
1076 i32 retval = ntohl(mp->retval);
1077
1078 if (VAT_JSON_NONE != vam->json_tree.type) {
1079 vat_json_print(vam->ofp, &vam->json_tree);
1080 vat_json_free(&vam->json_tree);
1081 vam->json_tree.type = VAT_JSON_NONE;
1082 } else {
1083 /* just print [] */
1084 vat_json_init_array(&vam->json_tree);
1085 vat_json_print(vam->ofp, &vam->json_tree);
1086 vam->json_tree.type = VAT_JSON_NONE;
1087 }
1088
1089 vam->retval = retval;
1090 vam->result_ready = 1;
1091}
1092
1093static void vl_api_l2_flags_reply_t_handler
1094(vl_api_l2_flags_reply_t * mp)
1095{
1096 vat_main_t * vam = &vat_main;
1097 i32 retval = ntohl(mp->retval);
1098 if (vam->async_mode) {
1099 vam->async_errors += (retval < 0);
1100 } else {
1101 vam->retval = retval;
1102 vam->result_ready = 1;
1103 }
1104}
1105
1106static void vl_api_l2_flags_reply_t_handler_json
1107(vl_api_l2_flags_reply_t * mp)
1108{
1109 vat_main_t * vam = &vat_main;
1110 vat_json_node_t node;
1111
1112 vat_json_init_object(&node);
1113 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1114 vat_json_object_add_uint(&node, "resulting_feature_bitmap", ntohl(mp->resulting_feature_bitmap));
1115
1116 vat_json_print(vam->ofp, &node);
1117 vat_json_free(&node);
1118
1119 vam->retval = ntohl(mp->retval);
1120 vam->result_ready = 1;
1121}
1122
1123static void vl_api_bridge_flags_reply_t_handler
1124(vl_api_bridge_flags_reply_t * mp)
1125{
1126 vat_main_t * vam = &vat_main;
1127 i32 retval = ntohl(mp->retval);
1128 if (vam->async_mode) {
1129 vam->async_errors += (retval < 0);
1130 } else {
1131 vam->retval = retval;
1132 vam->result_ready = 1;
1133 }
1134}
1135
1136static void vl_api_bridge_flags_reply_t_handler_json
1137(vl_api_bridge_flags_reply_t * mp)
1138{
1139 vat_main_t * vam = &vat_main;
1140 vat_json_node_t node;
1141
1142 vat_json_init_object(&node);
1143 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1144 vat_json_object_add_uint(&node, "resulting_feature_bitmap", ntohl(mp->resulting_feature_bitmap));
1145
1146 vat_json_print(vam->ofp, &node);
1147 vat_json_free(&node);
1148
1149 vam->retval = ntohl(mp->retval);
1150 vam->result_ready = 1;
1151}
1152
1153static void vl_api_tap_connect_reply_t_handler
1154(vl_api_tap_connect_reply_t * mp)
1155{
1156 vat_main_t * vam = &vat_main;
1157 i32 retval = ntohl(mp->retval);
1158 if (vam->async_mode) {
1159 vam->async_errors += (retval < 0);
1160 } else {
1161 vam->retval = retval;
1162 vam->result_ready = 1;
1163 }
1164}
1165
1166static void vl_api_tap_connect_reply_t_handler_json
1167(vl_api_tap_connect_reply_t * mp)
1168{
1169 vat_main_t * vam = &vat_main;
1170 vat_json_node_t node;
1171
1172 vat_json_init_object(&node);
1173 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1174 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
1175
1176 vat_json_print(vam->ofp, &node);
1177 vat_json_free(&node);
1178
1179 vam->retval = ntohl(mp->retval);
1180 vam->result_ready = 1;
1181}
1182
1183static void vl_api_tap_modify_reply_t_handler
1184(vl_api_tap_modify_reply_t * mp)
1185{
1186 vat_main_t * vam = &vat_main;
1187 i32 retval = ntohl(mp->retval);
1188 if (vam->async_mode) {
1189 vam->async_errors += (retval < 0);
1190 } else {
1191 vam->retval = retval;
1192 vam->result_ready = 1;
1193 }
1194}
1195
1196static void vl_api_tap_modify_reply_t_handler_json
1197(vl_api_tap_modify_reply_t * mp)
1198{
1199 vat_main_t * vam = &vat_main;
1200 vat_json_node_t node;
1201
1202 vat_json_init_object(&node);
1203 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1204 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
1205
1206 vat_json_print(vam->ofp, &node);
1207 vat_json_free(&node);
1208
1209 vam->retval = ntohl(mp->retval);
1210 vam->result_ready = 1;
1211}
1212
1213static void vl_api_tap_delete_reply_t_handler
1214(vl_api_tap_delete_reply_t * mp)
1215{
1216 vat_main_t * vam = &vat_main;
1217 i32 retval = ntohl(mp->retval);
1218 if (vam->async_mode) {
1219 vam->async_errors += (retval < 0);
1220 } else {
1221 vam->retval = retval;
1222 vam->result_ready = 1;
1223 }
1224}
1225
1226static void vl_api_tap_delete_reply_t_handler_json
1227(vl_api_tap_delete_reply_t * mp)
1228{
1229 vat_main_t * vam = &vat_main;
1230 vat_json_node_t node;
1231
1232 vat_json_init_object(&node);
1233 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1234
1235 vat_json_print(vam->ofp, &node);
1236 vat_json_free(&node);
1237
1238 vam->retval = ntohl(mp->retval);
1239 vam->result_ready = 1;
1240}
1241
1242static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler
1243(vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1244{
1245 vat_main_t * vam = &vat_main;
1246 i32 retval = ntohl(mp->retval);
1247 if (vam->async_mode) {
1248 vam->async_errors += (retval < 0);
1249 } else {
1250 vam->retval = retval;
1251 vam->result_ready = 1;
1252 }
1253}
1254
1255static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler_json
1256(vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1257{
1258 vat_main_t * vam = &vat_main;
1259 vat_json_node_t node;
1260
1261 vat_json_init_object(&node);
1262 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1263 vat_json_object_add_uint(&node, "tunnel_sw_if_index", ntohl(mp->tunnel_sw_if_index));
1264
1265 vat_json_print(vam->ofp, &node);
1266 vat_json_free(&node);
1267
1268 vam->retval = ntohl(mp->retval);
1269 vam->result_ready = 1;
1270}
1271
1272static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1273(vl_api_l2tpv3_create_tunnel_reply_t * mp)
1274{
1275 vat_main_t * vam = &vat_main;
1276 i32 retval = ntohl(mp->retval);
1277 if (vam->async_mode) {
1278 vam->async_errors += (retval < 0);
1279 } else {
1280 vam->retval = retval;
1281 vam->result_ready = 1;
1282 }
1283}
1284
1285static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1286(vl_api_l2tpv3_create_tunnel_reply_t * mp)
1287{
1288 vat_main_t * vam = &vat_main;
1289 vat_json_node_t node;
1290
1291 vat_json_init_object(&node);
1292 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1293 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
1294
1295 vat_json_print(vam->ofp, &node);
1296 vat_json_free(&node);
1297
1298 vam->retval = ntohl(mp->retval);
1299 vam->result_ready = 1;
1300}
1301
1302static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1303(vl_api_vxlan_add_del_tunnel_reply_t * mp)
1304{
1305 vat_main_t * vam = &vat_main;
1306 i32 retval = ntohl(mp->retval);
1307 if (vam->async_mode) {
1308 vam->async_errors += (retval < 0);
1309 } else {
1310 vam->retval = retval;
1311 vam->result_ready = 1;
1312 }
1313}
1314
1315static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1316(vl_api_vxlan_add_del_tunnel_reply_t * mp)
1317{
1318 vat_main_t * vam = &vat_main;
1319 vat_json_node_t node;
1320
1321 vat_json_init_object(&node);
1322 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1323 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
1324
1325 vat_json_print(vam->ofp, &node);
1326 vat_json_free(&node);
1327
1328 vam->retval = ntohl(mp->retval);
1329 vam->result_ready = 1;
1330}
1331
Chris Luke27fe48f2016-04-28 13:44:38 -04001332static void vl_api_gre_add_del_tunnel_reply_t_handler
1333(vl_api_gre_add_del_tunnel_reply_t * mp)
1334{
1335 vat_main_t * vam = &vat_main;
1336 i32 retval = ntohl(mp->retval);
1337 if (vam->async_mode) {
1338 vam->async_errors += (retval < 0);
1339 } else {
1340 vam->retval = retval;
1341 vam->result_ready = 1;
1342 }
1343}
1344
1345static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1346(vl_api_gre_add_del_tunnel_reply_t * mp)
1347{
1348 vat_main_t * vam = &vat_main;
1349 vat_json_node_t node;
1350
1351 vat_json_init_object(&node);
1352 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1353 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
1354
1355 vat_json_print(vam->ofp, &node);
1356 vat_json_free(&node);
1357
1358 vam->retval = ntohl(mp->retval);
1359 vam->result_ready = 1;
1360}
1361
Ed Warnickecb9cada2015-12-08 15:45:58 -07001362static void vl_api_create_vhost_user_if_reply_t_handler
1363(vl_api_create_vhost_user_if_reply_t * mp)
1364{
1365 vat_main_t * vam = &vat_main;
1366 i32 retval = ntohl(mp->retval);
1367 if (vam->async_mode) {
1368 vam->async_errors += (retval < 0);
1369 } else {
1370 vam->retval = retval;
1371 vam->result_ready = 1;
1372 }
1373}
1374
1375static void vl_api_create_vhost_user_if_reply_t_handler_json
1376(vl_api_create_vhost_user_if_reply_t * mp)
1377{
1378 vat_main_t * vam = &vat_main;
1379 vat_json_node_t node;
1380
1381 vat_json_init_object(&node);
1382 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1383 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
1384
1385 vat_json_print(vam->ofp, &node);
1386 vat_json_free(&node);
1387
1388 vam->retval = ntohl(mp->retval);
1389 vam->result_ready = 1;
1390}
1391
1392static void vl_api_ip_address_details_t_handler
1393(vl_api_ip_address_details_t * mp)
1394{
1395 vat_main_t * vam = &vat_main;
1396 static ip_address_details_t empty_ip_address_details = {{0}};
1397 ip_address_details_t * address = NULL;
1398 ip_details_t * current_ip_details = NULL;
1399 ip_details_t * details = NULL;
1400
1401 details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1402
1403 if (!details || vam->current_sw_if_index >= vec_len(details)
1404 || !details[vam->current_sw_if_index].present) {
1405 errmsg ("ip address details arrived but not stored\n");
1406 errmsg ("ip_dump should be called first\n");
1407 return;
1408 }
1409
1410 current_ip_details = vec_elt_at_index(details,
1411 vam->current_sw_if_index);
1412
1413#define addresses (current_ip_details->addr)
1414
1415 vec_validate_init_empty(addresses, vec_len(addresses),
1416 empty_ip_address_details);
1417
1418 address = vec_elt_at_index(addresses, vec_len(addresses) - 1);
1419
Damjan Marionf1213b82016-03-13 02:22:06 +01001420 clib_memcpy(&address->ip, &mp->ip, sizeof(address->ip));
Ed Warnickecb9cada2015-12-08 15:45:58 -07001421 address->prefix_length = mp->prefix_length;
1422#undef addresses
1423}
1424
1425static void vl_api_ip_address_details_t_handler_json
1426(vl_api_ip_address_details_t * mp)
1427{
1428 vat_main_t * vam = &vat_main;
1429 vat_json_node_t *node = NULL;
1430 struct in6_addr ip6;
1431 struct in_addr ip4;
1432
1433 if (VAT_JSON_ARRAY != vam->json_tree.type) {
1434 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
1435 vat_json_init_array(&vam->json_tree);
1436 }
1437 node = vat_json_array_add(&vam->json_tree);
1438
1439 vat_json_init_object(node);
1440 if (vam->is_ipv6) {
Damjan Marionf1213b82016-03-13 02:22:06 +01001441 clib_memcpy(&ip6, mp->ip, sizeof(ip6));
Ed Warnickecb9cada2015-12-08 15:45:58 -07001442 vat_json_object_add_ip6(node, "ip", ip6);
1443 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01001444 clib_memcpy(&ip4, mp->ip, sizeof(ip4));
Ed Warnickecb9cada2015-12-08 15:45:58 -07001445 vat_json_object_add_ip4(node, "ip", ip4);
1446 }
1447 vat_json_object_add_uint(node, "prefix_length", mp->prefix_length);
1448}
1449
1450static void vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1451{
1452 vat_main_t * vam = &vat_main;
1453 static ip_details_t empty_ip_details = {0};
1454 ip_details_t * ip = NULL;
1455 u32 sw_if_index = ~0;
1456
1457 sw_if_index = ntohl(mp->sw_if_index);
1458
1459 vec_validate_init_empty(vam->ip_details_by_sw_if_index[vam->is_ipv6],
1460 sw_if_index, empty_ip_details);
1461
1462 ip = vec_elt_at_index(vam->ip_details_by_sw_if_index[vam->is_ipv6],
1463 sw_if_index);
1464
1465 ip->present = 1;
1466}
1467
1468static void vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1469{
1470 vat_main_t * vam = &vat_main;
1471
1472 if (VAT_JSON_ARRAY != vam->json_tree.type) {
1473 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
1474 vat_json_init_array(&vam->json_tree);
1475 }
1476 vat_json_array_add_uint(&vam->json_tree, clib_net_to_host_u32(mp->sw_if_index));
1477}
1478
1479static void vl_api_map_domain_details_t_handler_json
1480(vl_api_map_domain_details_t * mp)
1481{
1482 vat_json_node_t * node = NULL;
1483 vat_main_t * vam = &vat_main;
1484 struct in6_addr ip6;
1485 struct in_addr ip4;
1486
1487 if (VAT_JSON_ARRAY != vam->json_tree.type) {
1488 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
1489 vat_json_init_array(&vam->json_tree);
1490 }
1491
1492 node = vat_json_array_add(&vam->json_tree);
1493 vat_json_init_object(node);
1494
1495 vat_json_object_add_uint(node, "domain_index", clib_net_to_host_u32(mp->domain_index));
Damjan Marionf1213b82016-03-13 02:22:06 +01001496 clib_memcpy(&ip6, mp->ip6_prefix, sizeof(ip6));
Ed Warnickecb9cada2015-12-08 15:45:58 -07001497 vat_json_object_add_ip6(node, "ip6_prefix", ip6);
Damjan Marionf1213b82016-03-13 02:22:06 +01001498 clib_memcpy(&ip4, mp->ip4_prefix, sizeof(ip4));
Ed Warnickecb9cada2015-12-08 15:45:58 -07001499 vat_json_object_add_ip4(node, "ip4_prefix", ip4);
Damjan Marionf1213b82016-03-13 02:22:06 +01001500 clib_memcpy(&ip6, mp->ip6_src, sizeof(ip6));
Ed Warnickecb9cada2015-12-08 15:45:58 -07001501 vat_json_object_add_ip6(node, "ip6_src", ip6);
1502 vat_json_object_add_int(node, "ip6_prefix_len", mp->ip6_prefix_len);
1503 vat_json_object_add_int(node, "ip4_prefix_len", mp->ip4_prefix_len);
1504 vat_json_object_add_int(node, "ip6_src_len", mp->ip6_src_len);
1505 vat_json_object_add_int(node, "ea_bits_len", mp->ea_bits_len);
1506 vat_json_object_add_int(node, "psid_offset", mp->psid_offset);
1507 vat_json_object_add_int(node, "psid_length", mp->psid_length);
1508 vat_json_object_add_uint(node, "flags", mp->flags);
1509 vat_json_object_add_uint(node, "mtu", clib_net_to_host_u16(mp->mtu));
1510 vat_json_object_add_int(node, "is_translation", mp->is_translation);
1511}
1512
1513static void vl_api_map_domain_details_t_handler
1514(vl_api_map_domain_details_t * mp)
1515{
1516 vat_main_t * vam = &vat_main;
1517
1518 if (mp->is_translation) {
1519 fformat(vam->ofp, "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u\n",
1520 format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1521 format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1522 format_ip6_address, mp->ip6_src, mp->ip6_src_len, clib_net_to_host_u32(mp->domain_index));
1523 } else {
1524 fformat(vam->ofp, "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u\n",
1525 format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1526 format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1527 format_ip6_address, mp->ip6_src, clib_net_to_host_u32(mp->domain_index));
1528 }
1529 fformat(vam->ofp, " ea-len %d psid-offset %d psid-len %d mtu %d %s\n",
1530 mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu, mp->is_translation? "map-t":"");
1531}
1532
1533static void vl_api_map_rule_details_t_handler_json
1534(vl_api_map_rule_details_t * mp)
1535{
1536 struct in6_addr ip6;
1537 vat_json_node_t * node = NULL;
1538 vat_main_t * vam = &vat_main;
1539
1540 if (VAT_JSON_ARRAY != vam->json_tree.type) {
1541 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
1542 vat_json_init_array(&vam->json_tree);
1543 }
1544
1545 node = vat_json_array_add(&vam->json_tree);
1546 vat_json_init_object(node);
1547
1548 vat_json_object_add_uint(node, "psid", clib_net_to_host_u16(mp->psid));
Damjan Marionf1213b82016-03-13 02:22:06 +01001549 clib_memcpy(&ip6, mp->ip6_dst, sizeof(ip6));
Ed Warnickecb9cada2015-12-08 15:45:58 -07001550 vat_json_object_add_ip6(node, "ip6_dst", ip6);
1551}
1552
1553static void vl_api_map_rule_details_t_handler
1554(vl_api_map_rule_details_t * mp)
1555{
1556 vat_main_t * vam = &vat_main;
1557 fformat(vam->ofp, " %d (psid) %U (ip6-dst)\n", clib_net_to_host_u16(mp->psid),
1558 format_ip6_address, mp->ip6_dst);
1559}
1560
1561static void vl_api_dhcp_compl_event_t_handler
1562(vl_api_dhcp_compl_event_t * mp)
1563{
1564 vat_main_t * vam = &vat_main;
1565 errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1566 "router_addr %U host_mac %U\n",
1567 mp->pid, mp->is_ipv6 ? "ipv6":"ipv4", mp->hostname,
1568 format_ip4_address, &mp->host_address,
1569 format_ip4_address, &mp->router_address,
1570 format_ethernet_address, mp->host_mac);
1571}
1572
1573static void vl_api_dhcp_compl_event_t_handler_json
1574(vl_api_dhcp_compl_event_t * mp)
1575{
1576 /* JSON output not supported */
1577}
1578
1579static void set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1580 u32 counter)
1581{
1582 vat_main_t * vam = &vat_main;
1583 static u64 default_counter = 0;
1584
1585 vec_validate_init_empty(vam->simple_interface_counters, vnet_counter_type, NULL);
1586 vec_validate_init_empty(vam->simple_interface_counters[vnet_counter_type],
1587 sw_if_index, default_counter);
1588 vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1589}
1590
1591static void set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1592 interface_counter_t counter)
1593{
1594 vat_main_t * vam = &vat_main;
1595 static interface_counter_t default_counter = {0, };
1596
1597 vec_validate_init_empty(vam->combined_interface_counters, vnet_counter_type, NULL);
1598 vec_validate_init_empty(vam->combined_interface_counters[vnet_counter_type],
1599 sw_if_index, default_counter);
1600 vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1601}
1602
1603static void vl_api_vnet_interface_counters_t_handler
1604(vl_api_vnet_interface_counters_t *mp)
1605{
1606 /* not supported */
1607}
1608
1609static void vl_api_vnet_interface_counters_t_handler_json
1610(vl_api_vnet_interface_counters_t *mp)
1611{
1612 interface_counter_t counter;
1613 vlib_counter_t *v;
1614 u64 *v_packets;
1615 u64 packets;
1616 u32 count;
1617 u32 first_sw_if_index;
1618 int i;
1619
1620 count = ntohl(mp->count);
1621 first_sw_if_index = ntohl(mp->first_sw_if_index);
1622
1623 if (!mp->is_combined) {
1624 v_packets = (u64*)&mp->data;
1625 for (i = 0; i < count; i++) {
1626 packets = clib_net_to_host_u64(clib_mem_unaligned(v_packets, u64));
1627 set_simple_interface_counter(mp->vnet_counter_type,
1628 first_sw_if_index + i, packets);
1629 v_packets++;
1630 }
1631 } else {
1632 v = (vlib_counter_t*)&mp->data;
1633 for (i = 0; i < count; i++) {
1634 counter.packets = clib_net_to_host_u64(
1635 clib_mem_unaligned(&v->packets, u64));
1636 counter.bytes = clib_net_to_host_u64(
1637 clib_mem_unaligned(&v->bytes, u64));
1638 set_combined_interface_counter(mp->vnet_counter_type,
1639 first_sw_if_index + i, counter);
1640 v++;
1641 }
1642 }
1643}
1644
1645static u32 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1646{
1647 vat_main_t * vam = &vat_main;
1648 u32 i;
1649
1650 for (i = 0; i < vec_len(vam->ip4_fib_counters_vrf_id_by_index); i++) {
1651 if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id) {
1652 return i;
1653 }
1654 }
1655 return ~0;
1656}
1657
1658static u32 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1659{
1660 vat_main_t * vam = &vat_main;
1661 u32 i;
1662
1663 for (i = 0; i < vec_len(vam->ip6_fib_counters_vrf_id_by_index); i++) {
1664 if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id) {
1665 return i;
1666 }
1667 }
1668 return ~0;
1669}
1670
1671static void vl_api_vnet_ip4_fib_counters_t_handler
1672(vl_api_vnet_ip4_fib_counters_t *mp)
1673{
1674 /* not supported */
1675}
1676
1677static void vl_api_vnet_ip4_fib_counters_t_handler_json
1678(vl_api_vnet_ip4_fib_counters_t *mp)
1679{
1680 vat_main_t * vam = &vat_main;
1681 vl_api_ip4_fib_counter_t *v;
1682 ip4_fib_counter_t *counter;
1683 struct in_addr ip4;
1684 u32 vrf_id;
1685 u32 vrf_index;
1686 u32 count;
1687 int i;
1688
1689 vrf_id = ntohl(mp->vrf_id);
1690 vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id(vrf_id);
1691 if (~0 == vrf_index) {
1692 vrf_index = vec_len(vam->ip4_fib_counters_vrf_id_by_index);
1693 vec_validate(vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
1694 vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
1695 vec_validate(vam->ip4_fib_counters, vrf_index);
1696 vam->ip4_fib_counters[vrf_index] = NULL;
1697 }
1698
1699 vec_free(vam->ip4_fib_counters[vrf_index]);
1700 v = (vl_api_ip4_fib_counter_t*)&mp->c;
1701 count = ntohl(mp->count);
1702 for (i = 0; i < count; i++) {
1703 vec_validate(vam->ip4_fib_counters[vrf_index], i);
1704 counter = &vam->ip4_fib_counters[vrf_index][i];
Damjan Marionf1213b82016-03-13 02:22:06 +01001705 clib_memcpy(&ip4, &v->address, sizeof(ip4));
Ed Warnickecb9cada2015-12-08 15:45:58 -07001706 counter->address = ip4;
1707 counter->address_length = v->address_length;
1708 counter->packets = clib_net_to_host_u64(v->packets);
1709 counter->bytes = clib_net_to_host_u64(v->bytes);
1710 v++;
1711 }
1712}
1713
1714static void vl_api_vnet_ip6_fib_counters_t_handler
1715(vl_api_vnet_ip6_fib_counters_t *mp)
1716{
1717 /* not supported */
1718}
1719
1720static void vl_api_vnet_ip6_fib_counters_t_handler_json
1721(vl_api_vnet_ip6_fib_counters_t *mp)
1722{
1723 vat_main_t * vam = &vat_main;
1724 vl_api_ip6_fib_counter_t *v;
1725 ip6_fib_counter_t *counter;
1726 struct in6_addr ip6;
1727 u32 vrf_id;
1728 u32 vrf_index;
1729 u32 count;
1730 int i;
1731
1732 vrf_id = ntohl(mp->vrf_id);
1733 vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id(vrf_id);
1734 if (~0 == vrf_index) {
1735 vrf_index = vec_len(vam->ip6_fib_counters_vrf_id_by_index);
1736 vec_validate(vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
1737 vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
1738 vec_validate(vam->ip6_fib_counters, vrf_index);
1739 vam->ip6_fib_counters[vrf_index] = NULL;
1740 }
1741
1742 vec_free(vam->ip6_fib_counters[vrf_index]);
1743 v = (vl_api_ip6_fib_counter_t*)&mp->c;
1744 count = ntohl(mp->count);
1745 for (i = 0; i < count; i++) {
1746 vec_validate(vam->ip6_fib_counters[vrf_index], i);
1747 counter = &vam->ip6_fib_counters[vrf_index][i];
Damjan Marionf1213b82016-03-13 02:22:06 +01001748 clib_memcpy(&ip6, &v->address, sizeof(ip6));
Ed Warnickecb9cada2015-12-08 15:45:58 -07001749 counter->address = ip6;
1750 counter->address_length = v->address_length;
1751 counter->packets = clib_net_to_host_u64(v->packets);
1752 counter->bytes = clib_net_to_host_u64(v->bytes);
1753 v++;
1754 }
1755}
1756
1757static void vl_api_get_first_msg_id_reply_t_handler
1758(vl_api_get_first_msg_id_reply_t * mp)
1759{
1760 vat_main_t * vam = &vat_main;
1761 i32 retval = ntohl(mp->retval);
1762
1763 if (vam->async_mode) {
1764 vam->async_errors += (retval < 0);
1765 } else {
1766 vam->retval = retval;
1767 vam->result_ready = 1;
1768 }
1769 if (retval >= 0) {
1770 errmsg ("first message id %d\n", ntohs(mp->first_msg_id));
1771 }
1772}
1773
1774static void vl_api_get_first_msg_id_reply_t_handler_json
1775(vl_api_get_first_msg_id_reply_t * mp)
1776{
1777 vat_main_t * vam = &vat_main;
1778 vat_json_node_t node;
1779
1780 vat_json_init_object(&node);
1781 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1782 vat_json_object_add_uint(&node, "first_msg_id",
1783 (uint) ntohs(mp->first_msg_id));
1784
1785 vat_json_print(vam->ofp, &node);
1786 vat_json_free(&node);
1787
1788 vam->retval = ntohl(mp->retval);
1789 vam->result_ready = 1;
1790}
1791
Dave Barachb44e9bc2016-02-19 09:06:23 -05001792static void vl_api_get_node_graph_reply_t_handler
1793(vl_api_get_node_graph_reply_t * mp)
1794{
1795 vat_main_t * vam = &vat_main;
1796 api_main_t * am = &api_main;
1797 i32 retval = ntohl(mp->retval);
1798 u8 * pvt_copy, * reply;
1799 void * oldheap;
1800 vlib_node_t * node;
1801 int i;
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
1810 /* "Should never happen..." */
1811 if (retval != 0)
1812 return;
1813
1814 reply = (u8 *)(mp->reply_in_shmem);
1815 pvt_copy = vec_dup (reply);
1816
1817 /* Toss the shared-memory original... */
1818 pthread_mutex_lock (&am->vlib_rp->mutex);
1819 oldheap = svm_push_data_heap (am->vlib_rp);
1820
1821 vec_free (reply);
1822
1823 svm_pop_heap (oldheap);
1824 pthread_mutex_unlock (&am->vlib_rp->mutex);
1825
1826 if (vam->graph_nodes) {
1827 hash_free (vam->graph_node_index_by_name);
1828
1829 for (i = 0; i < vec_len (vam->graph_nodes); i++) {
1830 node = vam->graph_nodes[i];
1831 vec_free (node->name);
1832 vec_free (node->next_nodes);
1833 vec_free (node);
1834 }
1835 vec_free(vam->graph_nodes);
1836 }
1837
1838 vam->graph_node_index_by_name = hash_create_string (0, sizeof(uword));
1839 vam->graph_nodes = vlib_node_unserialize (pvt_copy);
1840 vec_free (pvt_copy);
1841
1842 for (i = 0; i < vec_len (vam->graph_nodes); i++) {
1843 node = vam->graph_nodes[i];
1844 hash_set_mem (vam->graph_node_index_by_name, node->name, i);
1845 }
1846}
1847
1848static void vl_api_get_node_graph_reply_t_handler_json
1849(vl_api_get_node_graph_reply_t * mp)
1850{
1851 vat_main_t * vam = &vat_main;
1852 api_main_t * am = &api_main;
1853 void * oldheap;
1854 vat_json_node_t node;
1855 u8 * reply;
1856
1857 /* $$$$ make this real? */
1858 vat_json_init_object(&node);
1859 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1860 vat_json_object_add_uint(&node, "reply_in_shmem", mp->reply_in_shmem);
1861
1862 reply = (u8 *)(mp->reply_in_shmem);
1863
1864 /* Toss the shared-memory original... */
1865 pthread_mutex_lock (&am->vlib_rp->mutex);
1866 oldheap = svm_push_data_heap (am->vlib_rp);
1867
1868 vec_free (reply);
1869
1870 svm_pop_heap (oldheap);
1871 pthread_mutex_unlock (&am->vlib_rp->mutex);
1872
1873 vat_json_print(vam->ofp, &node);
1874 vat_json_free(&node);
1875
1876 vam->retval = ntohl(mp->retval);
1877 vam->result_ready = 1;
1878}
1879
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02001880static void
1881vl_api_lisp_locator_set_details_t_handler (
1882 vl_api_lisp_locator_set_details_t *mp)
1883{
1884 vat_main_t *vam = &vat_main;
Andrej Kozemcak3e53fc52016-05-09 10:52:16 +02001885 u8 * tmp_str = NULL;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02001886
Andrej Kozemcak3e53fc52016-05-09 10:52:16 +02001887 if (mp->local) {
1888 fformat(vam->ofp, "%=20s%=16d%=16d%=16d\n",
1889 mp->locator_set_name,
1890 ntohl(mp->sw_if_index),
1891 mp->priority,
1892 mp->weight);
1893 } else {
1894 tmp_str = format(0,"%U/%d",
1895 mp->is_ipv6 ? format_ip6_address : format_ip4_address,
1896 mp->ip_address,
1897 mp->prefix_len);
1898
1899 fformat(vam->ofp, "%=20s%=16s%=16d%=16d\n",
1900 mp->locator_set_name,
1901 tmp_str,
1902 mp->priority,
1903 mp->weight);
1904 vec_free(tmp_str);
1905 }
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02001906}
1907
1908static void
1909vl_api_lisp_locator_set_details_t_handler_json (
1910 vl_api_lisp_locator_set_details_t *mp)
1911{
1912 vat_main_t *vam = &vat_main;
1913 vat_json_node_t *node = NULL;
Andrej Kozemcak3e53fc52016-05-09 10:52:16 +02001914 struct in6_addr ip6;
1915 struct in_addr ip4;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02001916
1917 if (VAT_JSON_ARRAY != vam->json_tree.type) {
1918 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
1919 vat_json_init_array(&vam->json_tree);
1920 }
1921 node = vat_json_array_add(&vam->json_tree);
1922
1923 vat_json_init_object(node);
1924 vat_json_object_add_string_copy(node, "locator-set", mp->locator_set_name);
Andrej Kozemcak3e53fc52016-05-09 10:52:16 +02001925 if (mp->local) {
1926 vat_json_object_add_uint(node, "locator", ntohl(mp->sw_if_index));
1927 } else {
1928 if (mp->is_ipv6) {
1929 clib_memcpy(&ip6, mp->ip_address, sizeof(ip6));
1930 vat_json_object_add_ip6(node, "locator", ip6);
1931 } else {
1932 clib_memcpy(&ip4, mp->ip_address, sizeof(ip4));
1933 vat_json_object_add_ip4(node, "locator", ip4);
1934 }
1935 vat_json_object_add_uint(node, "prefix-length", mp->prefix_len);
1936 }
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02001937 vat_json_object_add_uint(node, "priority", mp->priority);
1938 vat_json_object_add_uint(node, "weight", mp->weight);
1939}
1940
1941static void
1942vl_api_lisp_local_eid_table_details_t_handler (
1943 vl_api_lisp_local_eid_table_details_t *mp)
1944{
1945 vat_main_t *vam = &vat_main;
1946 u8 *prefix;
1947
1948 prefix = format(0, "%U/%d",
1949 mp->eid_is_ipv6 ? format_ip6_address : format_ip4_address,
1950 mp->eid_ip_address,
1951 mp->eid_prefix_len);
1952
1953 fformat(vam->ofp, "%=20s%=30s\n",
1954 mp->locator_set_name, prefix);
1955
1956 vec_free(prefix);
1957}
1958
1959static void
1960vl_api_lisp_local_eid_table_details_t_handler_json (
1961 vl_api_lisp_local_eid_table_details_t *mp)
1962{
1963 vat_main_t *vam = &vat_main;
1964 vat_json_node_t *node = NULL;
1965 struct in6_addr ip6;
1966 struct in_addr ip4;
1967
1968 if (VAT_JSON_ARRAY != vam->json_tree.type) {
1969 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
1970 vat_json_init_array(&vam->json_tree);
1971 }
1972 node = vat_json_array_add(&vam->json_tree);
1973
1974 vat_json_init_object(node);
1975 vat_json_object_add_string_copy(node, "locator-set", mp->locator_set_name);
1976 if (mp->eid_is_ipv6) {
Damjan Marionf1213b82016-03-13 02:22:06 +01001977 clib_memcpy(&ip6, mp->eid_ip_address, sizeof(ip6));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02001978 vat_json_object_add_ip6(node, "eid address", ip6);
1979 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01001980 clib_memcpy(&ip4, mp->eid_ip_address, sizeof(ip4));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02001981 vat_json_object_add_ip4(node, "eid address", ip4);
1982 }
1983 vat_json_object_add_uint(node, "eid prefix len", mp->eid_prefix_len);
1984}
1985
1986static u8 *
1987format_decap_next (u8 * s, va_list * args)
1988{
1989 u32 next_index = va_arg (*args, u32);
1990
1991 switch (next_index)
1992 {
1993 case LISP_GPE_INPUT_NEXT_DROP:
1994 return format (s, "drop");
1995 case LISP_GPE_INPUT_NEXT_IP4_INPUT:
1996 return format (s, "ip4");
1997 case LISP_GPE_INPUT_NEXT_IP6_INPUT:
1998 return format (s, "ip6");
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02001999 default:
2000 return format (s, "unknown %d", next_index);
2001 }
2002 return s;
2003}
2004
2005static void
2006vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *mp)
2007{
2008 vat_main_t *vam = &vat_main;
2009 u8 *iid_str;
2010 u8 *flag_str = NULL;
2011
2012 iid_str = format(0, "%d (0x%x)", ntohl(mp->iid), ntohl(mp->iid));
2013
2014#define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n);
2015 foreach_lisp_gpe_flag_bit;
2016#undef _
2017
2018 fformat(vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U"
2019 "%=16d%=16d%=16sd=16d%=16s%=16s\n",
2020 mp->tunnels,
2021 mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2022 mp->source_ip,
2023 mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2024 mp->destination_ip,
2025 ntohl(mp->encap_fib_id),
2026 ntohl(mp->decap_fib_id),
2027 format_decap_next, ntohl(mp->dcap_next),
2028 mp->ver_res >> 6,
2029 flag_str,
2030 mp->next_protocol,
2031 mp->ver_res,
2032 mp->res,
2033 iid_str);
2034
2035 vec_free(iid_str);
2036}
2037
2038static void
2039vl_api_lisp_gpe_tunnel_details_t_handler_json (
2040 vl_api_lisp_gpe_tunnel_details_t *mp)
2041{
2042 vat_main_t *vam = &vat_main;
2043 vat_json_node_t *node = NULL;
2044 struct in6_addr ip6;
2045 struct in_addr ip4;
2046 u8 *next_decap_str;
2047
2048 next_decap_str = format(0, "%U", format_decap_next, htonl(mp->dcap_next));
2049
2050 if (VAT_JSON_ARRAY != vam->json_tree.type) {
2051 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
2052 vat_json_init_array(&vam->json_tree);
2053 }
2054 node = vat_json_array_add(&vam->json_tree);
2055
2056 vat_json_init_object(node);
2057 vat_json_object_add_uint(node, "tunel", mp->tunnels);
2058 if (mp->is_ipv6) {
Damjan Marionf1213b82016-03-13 02:22:06 +01002059 clib_memcpy(&ip6, mp->source_ip, sizeof(ip6));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002060 vat_json_object_add_ip6(node, "source address", ip6);
Damjan Marionf1213b82016-03-13 02:22:06 +01002061 clib_memcpy(&ip6, mp->destination_ip, sizeof(ip6));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002062 vat_json_object_add_ip6(node, "destination address", ip6);
2063 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01002064 clib_memcpy(&ip4, mp->source_ip, sizeof(ip4));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002065 vat_json_object_add_ip4(node, "source address", ip4);
Damjan Marionf1213b82016-03-13 02:22:06 +01002066 clib_memcpy(&ip4, mp->destination_ip, sizeof(ip4));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002067 vat_json_object_add_ip4(node, "destination address", ip4);
2068 }
2069 vat_json_object_add_uint(node, "fib encap", ntohl(mp->encap_fib_id));
2070 vat_json_object_add_uint(node, "fib decap", ntohl(mp->decap_fib_id));
2071 vat_json_object_add_string_copy(node, "decap next", next_decap_str);
2072 vat_json_object_add_uint(node, "lisp version", mp->ver_res >> 6);
2073 vat_json_object_add_uint(node, "flags", mp->flags);
2074 vat_json_object_add_uint(node, "next protocol", mp->next_protocol);
2075 vat_json_object_add_uint(node, "ver_res", mp->ver_res);
2076 vat_json_object_add_uint(node, "res", mp->res);
2077 vat_json_object_add_uint(node, "iid", ntohl(mp->iid));
2078
2079 vec_free(next_decap_str);
2080}
2081
2082static void
2083vl_api_lisp_map_resolver_details_t_handler (
2084 vl_api_lisp_map_resolver_details_t *mp)
2085{
2086 vat_main_t *vam = &vat_main;
2087
2088 fformat(vam->ofp, "%=20U\n",
2089 mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2090 mp->ip_address);
2091}
2092
2093static void
2094vl_api_lisp_map_resolver_details_t_handler_json (
2095 vl_api_lisp_map_resolver_details_t *mp)
2096{
2097 vat_main_t *vam = &vat_main;
2098 vat_json_node_t *node = NULL;
2099 struct in6_addr ip6;
2100 struct in_addr ip4;
2101
2102 if (VAT_JSON_ARRAY != vam->json_tree.type) {
2103 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
2104 vat_json_init_array(&vam->json_tree);
2105 }
2106 node = vat_json_array_add(&vam->json_tree);
2107
2108 vat_json_init_object(node);
2109 if (mp->is_ipv6) {
Damjan Marionf1213b82016-03-13 02:22:06 +01002110 clib_memcpy(&ip6, mp->ip_address, sizeof(ip6));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002111 vat_json_object_add_ip6(node, "map resolver", ip6);
2112 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01002113 clib_memcpy(&ip4, mp->ip_address, sizeof(ip4));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002114 vat_json_object_add_ip4(node, "map resolver", ip4);
2115 }
2116}
2117
Andrej Kozemcaka9edd852016-05-02 12:14:33 +02002118static void
Filip Tehlar46d4e362016-05-09 09:39:26 +02002119vl_api_lisp_enable_disable_status_details_t_handler
2120(vl_api_lisp_enable_disable_status_details_t *mp)
Andrej Kozemcaka9edd852016-05-02 12:14:33 +02002121{
2122 vat_main_t *vam = &vat_main;
2123
Filip Tehlar46d4e362016-05-09 09:39:26 +02002124 fformat(vam->ofp, "feature: %s\ngpe: %s\n",
2125 mp->feature_status ? "enabled" : "disabled",
2126 mp->gpe_status ? "enabled" : "disabled");
Andrej Kozemcaka9edd852016-05-02 12:14:33 +02002127}
2128
2129static void
Filip Tehlar46d4e362016-05-09 09:39:26 +02002130vl_api_lisp_enable_disable_status_details_t_handler_json
2131(vl_api_lisp_enable_disable_status_details_t *mp)
Andrej Kozemcaka9edd852016-05-02 12:14:33 +02002132{
2133 vat_main_t *vam = &vat_main;
2134 vat_json_node_t *node = NULL;
Filip Tehlar46d4e362016-05-09 09:39:26 +02002135 u8 * gpe_status = NULL;
2136 u8 * feature_status = NULL;
Andrej Kozemcaka9edd852016-05-02 12:14:33 +02002137
Filip Tehlar46d4e362016-05-09 09:39:26 +02002138 gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2139 feature_status = format (0, "%s",
2140 mp->feature_status ? "enabled" : "disabled");
Filip Tehlar6f91cfe2016-06-06 13:13:16 +02002141 vec_add1 (gpe_status, 0);
2142 vec_add1 (feature_status, 0);
Andrej Kozemcaka9edd852016-05-02 12:14:33 +02002143
2144 if (VAT_JSON_ARRAY != vam->json_tree.type) {
2145 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
2146 vat_json_init_array(&vam->json_tree);
2147 }
2148 node = vat_json_array_add(&vam->json_tree);
2149
2150 vat_json_init_object(node);
Filip Tehlar46d4e362016-05-09 09:39:26 +02002151 vat_json_object_add_string_copy(node, "gpe_status", gpe_status);
2152 vat_json_object_add_string_copy(node, "feature_status", feature_status);
2153
2154 vec_free (gpe_status);
2155 vec_free (feature_status);
Andrej Kozemcaka9edd852016-05-02 12:14:33 +02002156}
2157
Matus Fabiane8554802016-05-18 23:40:37 -07002158static u8 * format_policer_type (u8 * s, va_list * va)
2159{
2160 u32 i = va_arg (*va, u32);
2161
2162 if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2163 s = format (s, "1r2c");
2164 else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2165 s = format (s, "1r3c");
2166 else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2167 s = format (s, "2r3c-2698");
2168 else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2169 s = format (s, "2r3c-4115");
2170 else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2171 s = format (s, "2r3c-mef5cf1");
2172 else
2173 s = format (s, "ILLEGAL");
2174 return s;
2175}
2176
2177static u8 * format_policer_rate_type (u8 * s, va_list * va)
2178{
2179 u32 i = va_arg (*va, u32);
2180
2181 if (i == SSE2_QOS_RATE_KBPS)
2182 s = format (s, "kbps");
2183 else if (i == SSE2_QOS_RATE_PPS)
2184 s = format(s, "pps");
2185 else
2186 s = format (s, "ILLEGAL");
2187 return s;
2188}
2189
2190static u8 * format_policer_round_type (u8 * s, va_list * va)
2191{
2192 u32 i = va_arg (*va, u32);
2193
2194 if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2195 s = format(s, "closest");
2196 else if (i == SSE2_QOS_ROUND_TO_UP)
2197 s = format (s, "up");
2198 else if (i == SSE2_QOS_ROUND_TO_DOWN)
2199 s = format (s, "down");
2200 else
2201 s = format (s, "ILLEGAL");
2202 return s;
2203}
2204
2205static void vl_api_policer_details_t_handler
2206(vl_api_policer_details_t * mp)
2207{
2208 vat_main_t * vam = &vat_main;
2209
2210 fformat (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2211 "rate type %U, round type %U, %s rate, %s color-aware, "
2212 "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2213 "cur bkt %u, ext lim %u, ext bkt %u, last update %llu\n",
2214 mp->name,
2215 format_policer_type, mp->type,
2216 ntohl(mp->cir),
2217 ntohl(mp->eir),
2218 ntohl(mp->cb),
2219 ntohl(mp->eb),
2220 format_policer_rate_type, mp->rate_type,
2221 format_policer_round_type, mp->round_type,
2222 mp->single_rate ? "single" : "dual",
2223 mp->color_aware ? "is" : "not",
2224 ntohl(mp->cir_tokens_per_period),
2225 ntohl(mp->pir_tokens_per_period),
2226 ntohl(mp->scale),
2227 ntohl(mp->current_limit),
2228 ntohl(mp->current_bucket),
2229 ntohl(mp->extended_limit),
2230 ntohl(mp->extended_bucket),
2231 clib_net_to_host_u64(mp->last_update_time));
2232}
2233
2234static void vl_api_policer_details_t_handler_json
2235(vl_api_policer_details_t * mp)
2236{
2237 vat_main_t * vam = &vat_main;
2238 vat_json_node_t *node;
2239 u8 *rate_type_str, *round_type_str, *type_str;
2240
2241 rate_type_str = format(0, "%U", format_policer_rate_type, mp->rate_type);
2242 round_type_str = format(0, "%U", format_policer_round_type, mp->round_type);
2243 type_str = format(0, "%U", format_policer_type, mp->type);
2244
2245 if (VAT_JSON_ARRAY != vam->json_tree.type) {
2246 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
2247 vat_json_init_array(&vam->json_tree);
2248 }
2249 node = vat_json_array_add(&vam->json_tree);
2250
2251 vat_json_init_object(node);
2252 vat_json_object_add_string_copy(node, "name", mp->name);
2253 vat_json_object_add_uint(node, "cir", ntohl(mp->cir));
2254 vat_json_object_add_uint(node, "eir", ntohl(mp->eir));
2255 vat_json_object_add_uint(node, "cb", ntohl(mp->cb));
2256 vat_json_object_add_uint(node, "eb", ntohl(mp->eb));
2257 vat_json_object_add_string_copy(node, "rate_type", rate_type_str);
2258 vat_json_object_add_string_copy(node, "round_type", round_type_str);
2259 vat_json_object_add_string_copy(node, "type", type_str);
2260 vat_json_object_add_uint(node, "single_rate", mp->single_rate);
2261 vat_json_object_add_uint(node, "color_aware", mp->color_aware);
2262 vat_json_object_add_uint(node, "scale", ntohl(mp->scale));
2263 vat_json_object_add_uint(node, "cir_tokens_per_period",
2264 ntohl(mp->cir_tokens_per_period));
2265 vat_json_object_add_uint(node, "eir_tokens_per_period",
2266 ntohl(mp->pir_tokens_per_period));
2267 vat_json_object_add_uint(node, "current_limit", ntohl(mp->current_limit));
2268 vat_json_object_add_uint(node, "current_bucket", ntohl(mp->current_bucket));
2269 vat_json_object_add_uint(node, "extended_limit", ntohl(mp->extended_limit));
2270 vat_json_object_add_uint(node, "extended_bucket",
2271 ntohl(mp->extended_bucket));
2272 vat_json_object_add_uint(node, "last_update_time",
2273 ntohl(mp->last_update_time));
2274
2275 vec_free(rate_type_str);
2276 vec_free(round_type_str);
2277 vec_free(type_str);
2278}
2279
2280
Ed Warnickecb9cada2015-12-08 15:45:58 -07002281#define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
2282#define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
2283#define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
2284#define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
2285
2286/*
2287 * Generate boilerplate reply handlers, which
2288 * dig the return value out of the xxx_reply_t API message,
2289 * stick it into vam->retval, and set vam->result_ready
2290 *
2291 * Could also do this by pointing N message decode slots at
2292 * a single function, but that could break in subtle ways.
2293 */
2294
2295#define foreach_standard_reply_retval_handler \
2296_(sw_interface_set_flags_reply) \
2297_(sw_interface_add_del_address_reply) \
2298_(sw_interface_set_table_reply) \
2299_(sw_interface_set_vpath_reply) \
2300_(sw_interface_set_l2_bridge_reply) \
2301_(bridge_domain_add_del_reply) \
2302_(sw_interface_set_l2_xconnect_reply) \
2303_(l2fib_add_del_reply) \
2304_(ip_add_del_route_reply) \
2305_(proxy_arp_add_del_reply) \
2306_(proxy_arp_intfc_enable_disable_reply) \
2307_(mpls_add_del_encap_reply) \
2308_(mpls_add_del_decap_reply) \
2309_(mpls_ethernet_add_del_tunnel_2_reply) \
2310_(sw_interface_set_unnumbered_reply) \
2311_(ip_neighbor_add_del_reply) \
2312_(reset_vrf_reply) \
2313_(oam_add_del_reply) \
2314_(reset_fib_reply) \
2315_(dhcp_proxy_config_reply) \
2316_(dhcp_proxy_config_2_reply) \
2317_(dhcp_proxy_set_vss_reply) \
2318_(dhcp_client_config_reply) \
2319_(set_ip_flow_hash_reply) \
2320_(sw_interface_ip6_enable_disable_reply) \
2321_(sw_interface_ip6_set_link_local_address_reply) \
2322_(sw_interface_ip6nd_ra_prefix_reply) \
2323_(sw_interface_ip6nd_ra_config_reply) \
2324_(set_arp_neighbor_limit_reply) \
2325_(l2_patch_add_del_reply) \
2326_(sr_tunnel_add_del_reply) \
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07002327_(sr_policy_add_del_reply) \
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07002328_(sr_multicast_map_add_del_reply) \
Ed Warnickecb9cada2015-12-08 15:45:58 -07002329_(classify_add_del_session_reply) \
2330_(classify_set_interface_ip_table_reply) \
2331_(classify_set_interface_l2_tables_reply) \
2332_(l2tpv3_set_tunnel_cookies_reply) \
2333_(l2tpv3_interface_enable_disable_reply) \
2334_(l2tpv3_set_lookup_key_reply) \
2335_(l2_fib_clear_table_reply) \
2336_(l2_interface_efp_filter_reply) \
2337_(l2_interface_vlan_tag_rewrite_reply) \
2338_(modify_vhost_user_if_reply) \
2339_(delete_vhost_user_if_reply) \
2340_(want_ip4_arp_events_reply) \
2341_(input_acl_set_interface_reply) \
2342_(ipsec_spd_add_del_reply) \
2343_(ipsec_interface_add_del_spd_reply) \
2344_(ipsec_spd_add_del_entry_reply) \
2345_(ipsec_sad_add_del_entry_reply) \
2346_(ipsec_sa_set_key_reply) \
Matus Fabiane5f42fe2016-04-08 11:18:08 +02002347_(ikev2_profile_add_del_reply) \
2348_(ikev2_profile_set_auth_reply) \
2349_(ikev2_profile_set_id_reply) \
2350_(ikev2_profile_set_ts_reply) \
2351_(ikev2_set_local_key_reply) \
Ed Warnickecb9cada2015-12-08 15:45:58 -07002352_(delete_loopback_reply) \
2353_(bd_ip_mac_add_del_reply) \
2354_(map_del_domain_reply) \
2355_(map_add_del_rule_reply) \
2356_(want_interface_events_reply) \
Dave Barachc07bf5d2016-02-17 17:52:26 -05002357_(want_stats_reply) \
2358_(cop_interface_enable_disable_reply) \
Pavel Kotucek00bbf272016-03-03 13:27:11 +01002359_(cop_whitelist_enable_disable_reply) \
Shwetha20a64f52016-03-25 10:55:01 +00002360_(sw_interface_clear_stats_reply) \
2361_(trace_profile_add_reply) \
2362_(trace_profile_apply_reply) \
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002363_(trace_profile_del_reply) \
2364_(lisp_add_del_locator_set_reply) \
2365_(lisp_add_del_locator_reply) \
2366_(lisp_add_del_local_eid_reply) \
2367_(lisp_gpe_add_del_fwd_entry_reply) \
2368_(lisp_add_del_map_resolver_reply) \
Florin Coras577c3552016-04-21 00:45:40 +02002369_(lisp_gpe_enable_disable_reply) \
Matus Fabian8a95a482016-05-06 15:14:13 +02002370_(lisp_gpe_add_del_iface_reply) \
Filip Tehlar46d4e362016-05-09 09:39:26 +02002371_(lisp_enable_disable_reply) \
Filip Tehlar53f09e32016-05-19 14:25:44 +02002372_(lisp_pitr_set_locator_set_reply) \
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07002373_(vxlan_gpe_add_del_tunnel_reply) \
Matus Fabian8a95a482016-05-06 15:14:13 +02002374_(af_packet_create_reply) \
Matus Fabian65fcd4d2016-05-13 05:44:48 -07002375_(af_packet_delete_reply) \
Matus Fabian82e29c42016-05-11 04:49:46 -07002376_(policer_add_del_reply) \
2377_(netmap_create_reply) \
2378_(netmap_delete_reply)
Ed Warnickecb9cada2015-12-08 15:45:58 -07002379
2380#define _(n) \
2381 static void vl_api_##n##_t_handler \
2382 (vl_api_##n##_t * mp) \
2383 { \
2384 vat_main_t * vam = &vat_main; \
2385 i32 retval = ntohl(mp->retval); \
2386 if (vam->async_mode) { \
2387 vam->async_errors += (retval < 0); \
2388 } else { \
2389 vam->retval = retval; \
2390 vam->result_ready = 1; \
2391 } \
2392 }
2393foreach_standard_reply_retval_handler;
2394#undef _
2395
2396#define _(n) \
2397 static void vl_api_##n##_t_handler_json \
2398 (vl_api_##n##_t * mp) \
2399 { \
2400 vat_main_t * vam = &vat_main; \
2401 vat_json_node_t node; \
2402 vat_json_init_object(&node); \
2403 vat_json_object_add_int(&node, "retval", ntohl(mp->retval)); \
2404 vat_json_print(vam->ofp, &node); \
2405 vam->retval = ntohl(mp->retval); \
2406 vam->result_ready = 1; \
2407 }
2408foreach_standard_reply_retval_handler;
2409#undef _
2410
2411/*
2412 * Table of message reply handlers, must include boilerplate handlers
2413 * we just generated
2414 */
2415
2416#define foreach_vpe_api_reply_msg \
2417_(CREATE_LOOPBACK_REPLY, create_loopback_reply) \
2418_(SW_INTERFACE_DETAILS, sw_interface_details) \
2419_(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags) \
2420_(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply) \
2421_(CONTROL_PING_REPLY, control_ping_reply) \
2422_(CLI_REPLY, cli_reply) \
2423_(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY, \
2424 sw_interface_add_del_address_reply) \
2425_(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply) \
2426_(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply) \
2427_(SW_INTERFACE_SET_L2_XCONNECT_REPLY, \
2428 sw_interface_set_l2_xconnect_reply) \
2429_(SW_INTERFACE_SET_L2_BRIDGE_REPLY, \
2430 sw_interface_set_l2_bridge_reply) \
2431_(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply) \
2432_(BRIDGE_DOMAIN_DETAILS, bridge_domain_details) \
2433_(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details) \
2434_(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply) \
2435_(L2_FLAGS_REPLY, l2_flags_reply) \
2436_(BRIDGE_FLAGS_REPLY, bridge_flags_reply) \
2437_(TAP_CONNECT_REPLY, tap_connect_reply) \
2438_(TAP_MODIFY_REPLY, tap_modify_reply) \
2439_(TAP_DELETE_REPLY, tap_delete_reply) \
2440_(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details) \
2441_(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply) \
2442_(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply) \
2443_(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY, \
2444 proxy_arp_intfc_enable_disable_reply) \
2445_(MPLS_ADD_DEL_ENCAP_REPLY, mpls_add_del_encap_reply) \
2446_(MPLS_ADD_DEL_DECAP_REPLY, mpls_add_del_decap_reply) \
2447_(MPLS_GRE_ADD_DEL_TUNNEL_REPLY, mpls_gre_add_del_tunnel_reply) \
2448_(MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY, \
2449 mpls_ethernet_add_del_tunnel_reply) \
2450_(MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY, \
2451 mpls_ethernet_add_del_tunnel_2_reply) \
2452_(SW_INTERFACE_SET_UNNUMBERED_REPLY, \
2453 sw_interface_set_unnumbered_reply) \
2454_(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply) \
2455_(RESET_VRF_REPLY, reset_vrf_reply) \
2456_(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply) \
2457_(CREATE_SUBIF_REPLY, create_subif_reply) \
2458_(OAM_ADD_DEL_REPLY, oam_add_del_reply) \
2459_(RESET_FIB_REPLY, reset_fib_reply) \
2460_(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply) \
2461_(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply) \
2462_(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply) \
2463_(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply) \
2464_(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply) \
2465_(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY, \
2466 sw_interface_ip6_enable_disable_reply) \
2467_(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY, \
2468 sw_interface_ip6_set_link_local_address_reply) \
2469_(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY, \
2470 sw_interface_ip6nd_ra_prefix_reply) \
2471_(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY, \
2472 sw_interface_ip6nd_ra_config_reply) \
2473_(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply) \
2474_(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply) \
2475_(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply) \
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07002476_(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply) \
2477_(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply) \
Ed Warnickecb9cada2015-12-08 15:45:58 -07002478_(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply) \
2479_(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply) \
2480_(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY, \
2481classify_set_interface_ip_table_reply) \
2482_(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY, \
2483 classify_set_interface_l2_tables_reply) \
2484_(GET_NODE_INDEX_REPLY, get_node_index_reply) \
2485_(ADD_NODE_NEXT_REPLY, add_node_next_reply) \
2486_(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply) \
2487_(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply) \
2488_(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY, \
2489 l2tpv3_interface_enable_disable_reply) \
2490_(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply) \
2491_(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details) \
2492_(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply) \
Dave Wallace60231f32015-12-17 21:04:30 -05002493_(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details) \
Chris Luke27fe48f2016-04-28 13:44:38 -04002494_(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply) \
2495_(GRE_TUNNEL_DETAILS, gre_tunnel_details) \
Ed Warnickecb9cada2015-12-08 15:45:58 -07002496_(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply) \
2497_(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply) \
2498_(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
2499_(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details) \
2500_(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply) \
2501_(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply) \
2502_(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply) \
2503_(SHOW_VERSION_REPLY, show_version_reply) \
Ed Warnickecb9cada2015-12-08 15:45:58 -07002504_(L2_FIB_TABLE_ENTRY, l2_fib_table_entry) \
Hongjun Ni0e06e2b2016-05-30 19:45:51 +08002505_(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply) \
2506_(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details) \
Ed Warnickecb9cada2015-12-08 15:45:58 -07002507_(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply) \
2508_(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply) \
2509_(IP4_ARP_EVENT, ip4_arp_event) \
2510_(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply) \
2511_(IP_ADDRESS_DETAILS, ip_address_details) \
2512_(IP_DETAILS, ip_details) \
2513_(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply) \
2514_(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
2515_(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply) \
2516_(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply) \
2517_(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply) \
Matus Fabiane5f42fe2016-04-08 11:18:08 +02002518_(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply) \
2519_(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply) \
2520_(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply) \
2521_(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply) \
2522_(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply) \
Ed Warnickecb9cada2015-12-08 15:45:58 -07002523_(DELETE_LOOPBACK_REPLY, delete_loopback_reply) \
2524_(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply) \
2525_(DHCP_COMPL_EVENT, dhcp_compl_event) \
2526_(VNET_INTERFACE_COUNTERS, vnet_interface_counters) \
2527_(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters) \
2528_(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters) \
2529_(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply) \
2530_(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply) \
Dave Barachc07bf5d2016-02-17 17:52:26 -05002531_(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply) \
Ed Warnickecb9cada2015-12-08 15:45:58 -07002532_(MAP_DOMAIN_DETAILS, map_domain_details) \
2533_(MAP_RULE_DETAILS, map_rule_details) \
2534_(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply) \
2535_(WANT_STATS_REPLY, want_stats_reply) \
Dave Barachc07bf5d2016-02-17 17:52:26 -05002536_(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply) \
2537_(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
Dave Barachb44e9bc2016-02-19 09:06:23 -05002538_(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
Pavel Kotucek00bbf272016-03-03 13:27:11 +01002539_(GET_NODE_GRAPH_REPLY, get_node_graph_reply) \
Shwetha20a64f52016-03-25 10:55:01 +00002540_(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply) \
2541_(TRACE_PROFILE_ADD_REPLY, trace_profile_add_reply) \
2542_(TRACE_PROFILE_APPLY_REPLY, trace_profile_apply_reply) \
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002543_(TRACE_PROFILE_DEL_REPLY, trace_profile_del_reply) \
2544_(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply) \
2545_(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply) \
2546_(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply) \
2547_(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply) \
2548_(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply) \
Florin Coras577c3552016-04-21 00:45:40 +02002549_(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply) \
Filip Tehlar46d4e362016-05-09 09:39:26 +02002550_(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply) \
Filip Tehlar53f09e32016-05-19 14:25:44 +02002551_(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply) \
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002552_(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply) \
2553_(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details) \
2554_(LISP_LOCAL_EID_TABLE_DETAILS, lisp_local_eid_table_details) \
2555_(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details) \
Andrej Kozemcaka9edd852016-05-02 12:14:33 +02002556_(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details) \
Filip Tehlar46d4e362016-05-09 09:39:26 +02002557_(LISP_ENABLE_DISABLE_STATUS_DETAILS, \
2558 lisp_enable_disable_status_details) \
Matus Fabian8a95a482016-05-06 15:14:13 +02002559_(AF_PACKET_CREATE_REPLY, af_packet_create_reply) \
Matus Fabian65fcd4d2016-05-13 05:44:48 -07002560_(AF_PACKET_DELETE_REPLY, af_packet_delete_reply) \
Matus Fabian82e29c42016-05-11 04:49:46 -07002561_(POLICER_ADD_DEL_REPLY, policer_add_del_reply) \
Matus Fabiane8554802016-05-18 23:40:37 -07002562_(POLICER_DETAILS, policer_details) \
Matus Fabian82e29c42016-05-11 04:49:46 -07002563_(NETMAP_CREATE_REPLY, netmap_create_reply) \
2564_(NETMAP_DELETE_REPLY, netmap_delete_reply)
Ed Warnickecb9cada2015-12-08 15:45:58 -07002565
2566/* M: construct, but don't yet send a message */
2567
2568#define M(T,t) \
2569do { \
2570 vam->result_ready = 0; \
2571 mp = vl_msg_api_alloc(sizeof(*mp)); \
2572 memset (mp, 0, sizeof (*mp)); \
2573 mp->_vl_msg_id = ntohs (VL_API_##T); \
2574 mp->client_index = vam->my_client_index; \
2575} while(0);
2576
2577#define M2(T,t,n) \
2578do { \
2579 vam->result_ready = 0; \
2580 mp = vl_msg_api_alloc(sizeof(*mp)+(n)); \
2581 memset (mp, 0, sizeof (*mp)); \
2582 mp->_vl_msg_id = ntohs (VL_API_##T); \
2583 mp->client_index = vam->my_client_index; \
2584} while(0);
2585
2586
2587/* S: send a message */
2588#define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
2589
2590/* W: wait for results, with timeout */
2591#define W \
2592do { \
2593 timeout = vat_time_now (vam) + 1.0; \
2594 \
2595 while (vat_time_now (vam) < timeout) { \
2596 if (vam->result_ready == 1) { \
2597 return (vam->retval); \
2598 } \
2599 } \
2600 return -99; \
2601} while(0);
2602
2603typedef struct {
2604 u8 * name;
2605 u32 value;
2606} name_sort_t;
2607
2608
2609#define STR_VTR_OP_CASE(op) \
2610 case L2_VTR_ ## op: \
2611 return "" # op;
2612
2613static const char *str_vtr_op(u32 vtr_op)
2614{
2615 switch(vtr_op) {
2616 STR_VTR_OP_CASE(DISABLED);
2617 STR_VTR_OP_CASE(PUSH_1);
2618 STR_VTR_OP_CASE(PUSH_2);
2619 STR_VTR_OP_CASE(POP_1);
2620 STR_VTR_OP_CASE(POP_2);
2621 STR_VTR_OP_CASE(TRANSLATE_1_1);
2622 STR_VTR_OP_CASE(TRANSLATE_1_2);
2623 STR_VTR_OP_CASE(TRANSLATE_2_1);
2624 STR_VTR_OP_CASE(TRANSLATE_2_2);
2625 }
2626
2627 return "UNKNOWN";
2628}
2629
2630static int dump_sub_interface_table (vat_main_t * vam)
2631{
2632 const sw_interface_subif_t * sub = NULL;
2633
2634 if (vam->json_output) {
2635 clib_warning ("JSON output supported only for VPE API calls and dump_stats_table");
2636 return -99;
2637 }
2638
2639 fformat (vam->ofp,
2640 "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
2641 "Interface", "sw_if_index",
2642 "sub id", "dot1ad", "tags", "outer id",
2643 "inner id", "exact", "default",
2644 "outer any", "inner any");
2645
2646 vec_foreach (sub, vam->sw_if_subif_table) {
2647 fformat (vam->ofp,
2648 "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
2649 sub->interface_name,
2650 sub->sw_if_index,
2651 sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
2652 sub->sub_number_of_tags, sub->sub_outer_vlan_id,
2653 sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
2654 sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
2655 if (sub->vtr_op != L2_VTR_DISABLED) {
2656 fformat (vam->ofp,
2657 " vlan-tag-rewrite - op: %-14s [ dot1q: %d "
2658 "tag1: %d tag2: %d ]\n",
2659 str_vtr_op(sub->vtr_op), sub->vtr_push_dot1q,
2660 sub->vtr_tag1, sub->vtr_tag2);
2661 }
2662 }
2663
2664 return 0;
2665}
2666
Matus Fabiand2dc3df2015-12-14 10:31:33 -05002667static int name_sort_cmp (void * a1, void * a2)
2668{
2669 name_sort_t * n1 = a1;
2670 name_sort_t * n2 = a2;
2671
2672 return strcmp ((char *)n1->name, (char *)n2->name);
2673}
2674
Ed Warnickecb9cada2015-12-08 15:45:58 -07002675static int dump_interface_table (vat_main_t * vam)
2676{
2677 hash_pair_t * p;
2678 name_sort_t * nses = 0, * ns;
2679
2680 if (vam->json_output) {
2681 clib_warning ("JSON output supported only for VPE API calls and dump_stats_table");
2682 return -99;
2683 }
2684
2685 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
2686 ({
2687 vec_add2 (nses, ns, 1);
2688 ns->name = (u8 *)(p->key);
2689 ns->value = (u32) p->value[0];
2690 }));
2691
Matus Fabiand2dc3df2015-12-14 10:31:33 -05002692 vec_sort_with_function (nses, name_sort_cmp);
Ed Warnickecb9cada2015-12-08 15:45:58 -07002693
2694 fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
2695 vec_foreach (ns, nses) {
2696 fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
2697 }
2698 vec_free (nses);
2699 return 0;
2700}
2701
2702static int dump_ip_table (vat_main_t * vam, int is_ipv6)
2703{
2704 const ip_details_t * det = NULL;
2705 const ip_address_details_t * address = NULL;
2706 u32 i = ~0;
2707
2708 fformat (vam->ofp,
2709 "%-12s\n",
2710 "sw_if_index");
2711
Damjan Marionfa693552016-04-26 19:30:36 +02002712 if (0 == vam) {
Ed Warnickecb9cada2015-12-08 15:45:58 -07002713 return 0;
2714 }
2715
2716 vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6]) {
2717 i++;
2718 if (!det->present) {
2719 continue;
2720 }
2721 fformat (vam->ofp,
2722 "%-12d\n",
2723 i);
2724 fformat (vam->ofp,
2725 " %-30s%-13s\n",
2726 "Address", "Prefix length");
2727 if (!det->addr) {
2728 continue;
2729 }
2730 vec_foreach (address, det->addr) {
2731 fformat (vam->ofp,
2732 " %-30U%-13d\n",
2733 is_ipv6 ? format_ip6_address : format_ip4_address,
2734 address->ip,
2735 address->prefix_length);
2736 }
2737 }
2738
2739 return 0;
2740}
2741
2742static int dump_ipv4_table (vat_main_t * vam)
2743{
2744 if (vam->json_output) {
2745 clib_warning ("JSON output supported only for VPE API calls and dump_stats_table");
2746 return -99;
2747 }
2748
2749 return dump_ip_table (vam, 0);
2750}
2751
2752static int dump_ipv6_table (vat_main_t * vam)
2753{
2754 if (vam->json_output) {
2755 clib_warning ("JSON output supported only for VPE API calls and dump_stats_table");
2756 return -99;
2757 }
2758
2759 return dump_ip_table (vam, 1);
2760}
2761
2762static char* counter_type_to_str (u8 counter_type, u8 is_combined)
2763{
2764 if (!is_combined) {
2765 switch(counter_type) {
2766 case VNET_INTERFACE_COUNTER_DROP:
2767 return "drop";
2768 case VNET_INTERFACE_COUNTER_PUNT:
2769 return "punt";
2770 case VNET_INTERFACE_COUNTER_IP4:
2771 return "ip4";
2772 case VNET_INTERFACE_COUNTER_IP6:
2773 return "ip6";
2774 case VNET_INTERFACE_COUNTER_RX_NO_BUF:
2775 return "rx-no-buf";
2776 case VNET_INTERFACE_COUNTER_RX_MISS:
2777 return "rx-miss";
2778 case VNET_INTERFACE_COUNTER_RX_ERROR:
2779 return "rx-error";
2780 case VNET_INTERFACE_COUNTER_TX_ERROR:
2781 return "tx-error";
2782 default:
2783 return "INVALID-COUNTER-TYPE";
2784 }
2785 } else {
2786 switch(counter_type) {
2787 case VNET_INTERFACE_COUNTER_RX:
2788 return "rx";
2789 case VNET_INTERFACE_COUNTER_TX:
2790 return "tx";
2791 default:
2792 return "INVALID-COUNTER-TYPE";
2793 }
2794 }
2795}
2796
2797static int dump_stats_table (vat_main_t * vam)
2798{
2799 vat_json_node_t node;
2800 vat_json_node_t *msg_array;
2801 vat_json_node_t *msg;
2802 vat_json_node_t *counter_array;
2803 vat_json_node_t *counter;
2804 interface_counter_t c;
2805 u64 packets;
2806 ip4_fib_counter_t *c4;
2807 ip6_fib_counter_t *c6;
2808 int i, j;
2809
2810 if (!vam->json_output) {
2811 clib_warning ("dump_stats_table supported only in JSON format");
2812 return -99;
2813 }
2814
2815 vat_json_init_object(&node);
2816
2817 /* interface counters */
2818 msg_array = vat_json_object_add(&node, "interface_counters");
2819 vat_json_init_array(msg_array);
2820 for (i = 0; i < vec_len(vam->simple_interface_counters); i++) {
2821 msg = vat_json_array_add(msg_array);
2822 vat_json_init_object(msg);
2823 vat_json_object_add_string_copy(msg, "vnet_counter_type",
2824 (u8*)counter_type_to_str(i, 0));
2825 vat_json_object_add_int(msg, "is_combined", 0);
2826 counter_array = vat_json_object_add(msg, "data");
2827 vat_json_init_array(counter_array);
2828 for (j = 0; j < vec_len(vam->simple_interface_counters[i]); j++) {
2829 packets = vam->simple_interface_counters[i][j];
2830 vat_json_array_add_uint(counter_array, packets);
2831 }
2832 }
2833 for (i = 0; i < vec_len(vam->combined_interface_counters); i++) {
2834 msg = vat_json_array_add(msg_array);
2835 vat_json_init_object(msg);
2836 vat_json_object_add_string_copy(msg, "vnet_counter_type",
2837 (u8*)counter_type_to_str(i, 1));
2838 vat_json_object_add_int(msg, "is_combined", 1);
2839 counter_array = vat_json_object_add(msg, "data");
2840 vat_json_init_array(counter_array);
2841 for (j = 0; j < vec_len(vam->combined_interface_counters[i]); j++) {
2842 c = vam->combined_interface_counters[i][j];
2843 counter = vat_json_array_add(counter_array);
2844 vat_json_init_object(counter);
2845 vat_json_object_add_uint(counter, "packets", c.packets);
2846 vat_json_object_add_uint(counter, "bytes", c.bytes);
2847 }
2848 }
2849
2850 /* ip4 fib counters */
2851 msg_array = vat_json_object_add(&node, "ip4_fib_counters");
2852 vat_json_init_array(msg_array);
2853 for (i = 0; i < vec_len(vam->ip4_fib_counters); i++) {
2854 msg = vat_json_array_add(msg_array);
2855 vat_json_init_object(msg);
2856 vat_json_object_add_uint(msg, "vrf_id", vam->ip4_fib_counters_vrf_id_by_index[i]);
2857 counter_array = vat_json_object_add(msg, "c");
2858 vat_json_init_array(counter_array);
2859 for (j = 0; j < vec_len(vam->ip4_fib_counters[i]); j++) {
2860 counter = vat_json_array_add(counter_array);
2861 vat_json_init_object(counter);
2862 c4 = &vam->ip4_fib_counters[i][j];
2863 vat_json_object_add_ip4(counter, "address", c4->address);
2864 vat_json_object_add_uint(counter, "address_length", c4->address_length);
2865 vat_json_object_add_uint(counter, "packets", c4->packets);
2866 vat_json_object_add_uint(counter, "bytes", c4->bytes);
2867 }
2868 }
2869
2870 /* ip6 fib counters */
2871 msg_array = vat_json_object_add(&node, "ip6_fib_counters");
2872 vat_json_init_array(msg_array);
2873 for (i = 0; i < vec_len(vam->ip6_fib_counters); i++) {
2874 msg = vat_json_array_add(msg_array);
2875 vat_json_init_object(msg);
2876 vat_json_object_add_uint(msg, "vrf_id", vam->ip6_fib_counters_vrf_id_by_index[i]);
2877 counter_array = vat_json_object_add(msg, "c");
2878 vat_json_init_array(counter_array);
2879 for (j = 0; j < vec_len(vam->ip6_fib_counters[i]); j++) {
2880 counter = vat_json_array_add(counter_array);
2881 vat_json_init_object(counter);
2882 c6 = &vam->ip6_fib_counters[i][j];
2883 vat_json_object_add_ip6(counter, "address", c6->address);
2884 vat_json_object_add_uint(counter, "address_length", c6->address_length);
2885 vat_json_object_add_uint(counter, "packets", c6->packets);
2886 vat_json_object_add_uint(counter, "bytes", c6->bytes);
2887 }
2888 }
2889
2890 vat_json_print(vam->ofp, &node);
2891 vat_json_free(&node);
2892
2893 return 0;
2894}
2895
2896int exec (vat_main_t * vam)
2897{
2898 api_main_t * am = &api_main;
2899 vl_api_cli_request_t *mp;
2900 f64 timeout;
2901 void * oldheap;
2902 u8 * cmd = 0;
2903 unformat_input_t * i = vam->input;
2904
2905 if (vec_len(i->buffer) == 0)
2906 return -1;
2907
2908 if (vam->exec_mode == 0 && unformat (i, "mode")) {
2909 vam->exec_mode = 1;
2910 return 0;
2911 }
2912 if (vam->exec_mode == 1 &&
2913 (unformat (i, "exit") || unformat (i, "quit"))) {
2914 vam->exec_mode = 0;
2915 return 0;
2916 }
2917
2918
2919 M(CLI_REQUEST, cli_request);
2920
2921 /*
2922 * Copy cmd into shared memory.
2923 * In order for the CLI command to work, it
2924 * must be a vector ending in \n, not a C-string ending
2925 * in \n\0.
2926 */
2927 pthread_mutex_lock (&am->vlib_rp->mutex);
2928 oldheap = svm_push_data_heap (am->vlib_rp);
2929
2930 vec_validate (cmd, vec_len(vam->input->buffer)-1);
Damjan Marionf1213b82016-03-13 02:22:06 +01002931 clib_memcpy (cmd, vam->input->buffer, vec_len(vam->input->buffer));
Ed Warnickecb9cada2015-12-08 15:45:58 -07002932
2933 svm_pop_heap (oldheap);
2934 pthread_mutex_unlock (&am->vlib_rp->mutex);
2935
2936 mp->cmd_in_shmem = (u64) cmd;
2937 S;
2938 timeout = vat_time_now (vam) + 10.0;
2939
2940 while (vat_time_now (vam) < timeout) {
2941 if (vam->result_ready == 1) {
2942 u8 * free_me;
Pavel Kotucek060c6fc2016-02-24 15:52:42 +01002943 if (vam->shmem_result != NULL)
2944 fformat (vam->ofp, "%s", vam->shmem_result);
Ed Warnickecb9cada2015-12-08 15:45:58 -07002945 pthread_mutex_lock (&am->vlib_rp->mutex);
2946 oldheap = svm_push_data_heap (am->vlib_rp);
2947
2948 free_me = (u8 *)vam->shmem_result;
2949 vec_free (free_me);
2950
2951 svm_pop_heap (oldheap);
2952 pthread_mutex_unlock (&am->vlib_rp->mutex);
2953 return 0;
2954 }
2955 }
2956 return -99;
2957}
2958
2959static int api_create_loopback (vat_main_t * vam)
2960{
2961 unformat_input_t * i = vam->input;
2962 vl_api_create_loopback_t *mp;
2963 f64 timeout;
2964 u8 mac_address[6];
2965 u8 mac_set = 0;
2966
2967 memset (mac_address, 0, sizeof (mac_address));
2968
2969 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2970 {
2971 if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
2972 mac_set = 1;
2973 else
2974 break;
2975 }
2976
2977 /* Construct the API message */
2978 M(CREATE_LOOPBACK, create_loopback);
2979 if (mac_set)
Damjan Marionf1213b82016-03-13 02:22:06 +01002980 clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07002981
2982 S; W;
2983}
2984
2985static int api_delete_loopback (vat_main_t * vam)
2986{
2987 unformat_input_t * i = vam->input;
2988 vl_api_delete_loopback_t *mp;
2989 f64 timeout;
2990 u32 sw_if_index = ~0;
2991
2992 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2993 {
2994 if (unformat (i, "sw_if_index %d", &sw_if_index))
2995 ;
2996 else
2997 break;
2998 }
2999
3000 if (sw_if_index == ~0)
3001 {
3002 errmsg ("missing sw_if_index\n");
3003 return -99;
3004 }
3005
3006 /* Construct the API message */
3007 M(DELETE_LOOPBACK, delete_loopback);
3008 mp->sw_if_index = ntohl (sw_if_index);
3009
3010 S; W;
3011}
3012
3013static int api_want_stats (vat_main_t * vam)
3014{
3015 unformat_input_t * i = vam->input;
3016 vl_api_want_stats_t * mp;
3017 f64 timeout;
3018 int enable = -1;
3019
3020 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3021 {
3022 if (unformat (i, "enable"))
3023 enable = 1;
3024 else if (unformat (i, "disable"))
3025 enable = 0;
3026 else
3027 break;
3028 }
3029
3030 if (enable == -1)
3031 {
3032 errmsg ("missing enable|disable\n");
3033 return -99;
3034 }
3035
3036 M(WANT_STATS, want_stats);
3037 mp->enable_disable = enable;
3038
3039 S; W;
3040}
3041
3042static int api_want_interface_events (vat_main_t * vam)
3043{
3044 unformat_input_t * i = vam->input;
3045 vl_api_want_interface_events_t * mp;
3046 f64 timeout;
3047 int enable = -1;
3048
3049 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3050 {
3051 if (unformat (i, "enable"))
3052 enable = 1;
3053 else if (unformat (i, "disable"))
3054 enable = 0;
3055 else
3056 break;
3057 }
3058
3059 if (enable == -1)
3060 {
3061 errmsg ("missing enable|disable\n");
3062 return -99;
3063 }
3064
3065 M(WANT_INTERFACE_EVENTS, want_interface_events);
3066 mp->enable_disable = enable;
3067
3068 vam->interface_event_display = enable;
3069
3070 S; W;
3071}
3072
3073
3074/* Note: non-static, called once to set up the initial intfc table */
3075int api_sw_interface_dump (vat_main_t * vam)
3076{
3077 vl_api_sw_interface_dump_t *mp;
3078 f64 timeout;
3079 hash_pair_t * p;
3080 name_sort_t * nses = 0, * ns;
3081 sw_interface_subif_t * sub = NULL;
3082
3083 /* Toss the old name table */
3084 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3085 ({
3086 vec_add2 (nses, ns, 1);
3087 ns->name = (u8 *)(p->key);
3088 ns->value = (u32) p->value[0];
3089 }));
3090
3091 hash_free (vam->sw_if_index_by_interface_name);
3092
3093 vec_foreach (ns, nses)
3094 vec_free (ns->name);
3095
3096 vec_free (nses);
3097
3098 vec_foreach (sub, vam->sw_if_subif_table) {
3099 vec_free (sub->interface_name);
3100 }
3101 vec_free (vam->sw_if_subif_table);
3102
3103 /* recreate the interface name hash table */
3104 vam->sw_if_index_by_interface_name
3105 = hash_create_string (0, sizeof(uword));
3106
3107 /* Get list of ethernets */
3108 M(SW_INTERFACE_DUMP, sw_interface_dump);
3109 mp->name_filter_valid = 1;
Damjan Marionfa693552016-04-26 19:30:36 +02003110 strncpy ((char *) mp->name_filter, "Ether", sizeof(mp->name_filter)-1);
Ed Warnickecb9cada2015-12-08 15:45:58 -07003111 S;
3112
3113 /* and local / loopback interfaces */
3114 M(SW_INTERFACE_DUMP, sw_interface_dump);
3115 mp->name_filter_valid = 1;
Damjan Marionfa693552016-04-26 19:30:36 +02003116 strncpy ((char *) mp->name_filter, "lo", sizeof(mp->name_filter)-1);
Ed Warnickecb9cada2015-12-08 15:45:58 -07003117 S;
3118
Hongjun Nic4248792016-06-08 01:07:12 +08003119
3120 /* and vxlan-gpe tunnel interfaces */
3121 M(SW_INTERFACE_DUMP, sw_interface_dump);
3122 mp->name_filter_valid = 1;
3123 strncpy ((char *) mp->name_filter, "vxlan_gpe", sizeof(mp->name_filter)-1);
3124 S;
3125
Ed Warnickecb9cada2015-12-08 15:45:58 -07003126 /* and vxlan tunnel interfaces */
3127 M(SW_INTERFACE_DUMP, sw_interface_dump);
3128 mp->name_filter_valid = 1;
Damjan Marionfa693552016-04-26 19:30:36 +02003129 strncpy ((char *) mp->name_filter, "vxlan", sizeof(mp->name_filter)-1);
Ed Warnickecb9cada2015-12-08 15:45:58 -07003130 S;
3131
Damjan Marionb02e49c2016-03-31 17:44:25 +02003132 /* and host (af_packet) interfaces */
3133 M(SW_INTERFACE_DUMP, sw_interface_dump);
3134 mp->name_filter_valid = 1;
Damjan Marionfa693552016-04-26 19:30:36 +02003135 strncpy ((char *) mp->name_filter, "host", sizeof(mp->name_filter)-1);
Damjan Marionb02e49c2016-03-31 17:44:25 +02003136 S;
3137
Ed Warnickecb9cada2015-12-08 15:45:58 -07003138 /* and l2tpv3 tunnel interfaces */
3139 M(SW_INTERFACE_DUMP, sw_interface_dump);
3140 mp->name_filter_valid = 1;
Damjan Marionfa693552016-04-26 19:30:36 +02003141 strncpy ((char *) mp->name_filter, "l2tpv3_tunnel", sizeof(mp->name_filter)-1);
Ed Warnickecb9cada2015-12-08 15:45:58 -07003142 S;
3143
Chris Lukea6116ef2016-05-06 10:12:30 -04003144 /* and GRE tunnel interfaces */
3145 M(SW_INTERFACE_DUMP, sw_interface_dump);
3146 mp->name_filter_valid = 1;
3147 strncpy ((char *) mp->name_filter, "gre", sizeof(mp->name_filter)-1);
3148 S;
3149
Ed Warnickecb9cada2015-12-08 15:45:58 -07003150 /* Use a control ping for synchronization */
3151 {
3152 vl_api_control_ping_t * mp;
3153 M(CONTROL_PING, control_ping);
3154 S;
3155 }
3156 W;
3157}
3158
3159static int api_sw_interface_set_flags (vat_main_t * vam)
3160{
3161 unformat_input_t * i = vam->input;
3162 vl_api_sw_interface_set_flags_t *mp;
3163 f64 timeout;
3164 u32 sw_if_index;
3165 u8 sw_if_index_set = 0;
3166 u8 admin_up = 0, link_up = 0;
3167
3168 /* Parse args required to build the message */
3169 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3170 if (unformat (i, "admin-up"))
3171 admin_up = 1;
3172 else if (unformat (i, "admin-down"))
3173 admin_up = 0;
3174 else if (unformat (i, "link-up"))
3175 link_up = 1;
3176 else if (unformat (i, "link-down"))
3177 link_up = 0;
3178 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3179 sw_if_index_set = 1;
3180 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3181 sw_if_index_set = 1;
3182 else
3183 break;
3184 }
3185
3186 if (sw_if_index_set == 0) {
3187 errmsg ("missing interface name or sw_if_index\n");
3188 return -99;
3189 }
3190
3191 /* Construct the API message */
3192 M(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
3193 mp->sw_if_index = ntohl (sw_if_index);
3194 mp->admin_up_down = admin_up;
3195 mp->link_up_down = link_up;
3196
3197 /* send it... */
3198 S;
3199
3200 /* Wait for a reply, return the good/bad news... */
3201 W;
3202}
3203
Pavel Kotucek00bbf272016-03-03 13:27:11 +01003204static int api_sw_interface_clear_stats (vat_main_t * vam)
3205{
3206 unformat_input_t * i = vam->input;
3207 vl_api_sw_interface_clear_stats_t *mp;
3208 f64 timeout;
3209 u32 sw_if_index;
3210 u8 sw_if_index_set = 0;
3211
3212 /* Parse args required to build the message */
3213 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3214 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3215 sw_if_index_set = 1;
3216 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3217 sw_if_index_set = 1;
3218 else
3219 break;
3220 }
3221
3222 /* Construct the API message */
3223 M(SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
3224
3225 if (sw_if_index_set == 1)
3226 mp->sw_if_index = ntohl (sw_if_index);
3227 else
3228 mp->sw_if_index = ~0;
3229
3230 /* send it... */
3231 S;
3232
3233 /* Wait for a reply, return the good/bad news... */
3234 W;
3235}
3236
Ed Warnickecb9cada2015-12-08 15:45:58 -07003237static int api_sw_interface_add_del_address (vat_main_t * vam)
3238{
3239 unformat_input_t * i = vam->input;
3240 vl_api_sw_interface_add_del_address_t *mp;
3241 f64 timeout;
3242 u32 sw_if_index;
3243 u8 sw_if_index_set = 0;
3244 u8 is_add = 1, del_all = 0;
3245 u32 address_length = 0;
3246 u8 v4_address_set = 0;
3247 u8 v6_address_set = 0;
3248 ip4_address_t v4address;
3249 ip6_address_t v6address;
3250
3251 /* Parse args required to build the message */
3252 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3253 if (unformat (i, "del-all"))
3254 del_all = 1;
3255 else if (unformat (i, "del"))
3256 is_add = 0;
3257 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3258 sw_if_index_set = 1;
3259 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3260 sw_if_index_set = 1;
3261 else if (unformat (i, "%U/%d",
3262 unformat_ip4_address, &v4address,
3263 &address_length))
3264 v4_address_set = 1;
3265 else if (unformat (i, "%U/%d",
3266 unformat_ip6_address, &v6address,
3267 &address_length))
3268 v6_address_set = 1;
3269 else
3270 break;
3271 }
3272
3273 if (sw_if_index_set == 0) {
3274 errmsg ("missing interface name or sw_if_index\n");
3275 return -99;
3276 }
3277 if (v4_address_set && v6_address_set) {
3278 errmsg ("both v4 and v6 addresses set\n");
3279 return -99;
3280 }
3281 if (!v4_address_set && !v6_address_set && !del_all) {
3282 errmsg ("no addresses set\n");
3283 return -99;
3284 }
3285
3286 /* Construct the API message */
3287 M(SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
3288
3289 mp->sw_if_index = ntohl (sw_if_index);
3290 mp->is_add = is_add;
3291 mp->del_all = del_all;
3292 if (v6_address_set) {
3293 mp->is_ipv6 = 1;
Damjan Marionf1213b82016-03-13 02:22:06 +01003294 clib_memcpy (mp->address, &v6address, sizeof (v6address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07003295 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01003296 clib_memcpy (mp->address, &v4address, sizeof (v4address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07003297 }
3298 mp->address_length = address_length;
3299
3300 /* send it... */
3301 S;
3302
3303 /* Wait for a reply, return good/bad news */
3304 W;
3305}
3306
3307static int api_sw_interface_set_table (vat_main_t * vam)
3308{
3309 unformat_input_t * i = vam->input;
3310 vl_api_sw_interface_set_table_t *mp;
3311 f64 timeout;
3312 u32 sw_if_index, vrf_id = 0;
3313 u8 sw_if_index_set = 0;
3314 u8 is_ipv6 = 0;
3315
3316 /* Parse args required to build the message */
3317 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3318 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3319 sw_if_index_set = 1;
3320 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3321 sw_if_index_set = 1;
3322 else if (unformat (i, "vrf %d", &vrf_id))
3323 ;
3324 else if (unformat (i, "ipv6"))
3325 is_ipv6 = 1;
3326 else
3327 break;
3328 }
3329
3330 if (sw_if_index_set == 0) {
3331 errmsg ("missing interface name or sw_if_index\n");
3332 return -99;
3333 }
3334
3335 /* Construct the API message */
3336 M(SW_INTERFACE_SET_TABLE, sw_interface_set_table);
3337
3338 mp->sw_if_index = ntohl (sw_if_index);
3339 mp->is_ipv6 = is_ipv6;
3340 mp->vrf_id = ntohl (vrf_id);
3341
3342 /* send it... */
3343 S;
3344
3345 /* Wait for a reply... */
3346 W;
3347}
3348
3349static int api_sw_interface_set_vpath (vat_main_t * vam)
3350{
3351 unformat_input_t * i = vam->input;
3352 vl_api_sw_interface_set_vpath_t *mp;
3353 f64 timeout;
3354 u32 sw_if_index = 0;
3355 u8 sw_if_index_set = 0;
3356 u8 is_enable = 0;
3357
3358 /* Parse args required to build the message */
3359 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3360 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3361 sw_if_index_set = 1;
3362 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3363 sw_if_index_set = 1;
3364 else if (unformat (i, "enable"))
3365 is_enable = 1;
3366 else if (unformat (i, "disable"))
3367 is_enable = 0;
3368 else
3369 break;
3370 }
3371
3372 if (sw_if_index_set == 0) {
3373 errmsg ("missing interface name or sw_if_index\n");
3374 return -99;
3375 }
3376
3377 /* Construct the API message */
3378 M(SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
3379
3380 mp->sw_if_index = ntohl (sw_if_index);
3381 mp->enable = is_enable;
3382
3383 /* send it... */
3384 S;
3385
3386 /* Wait for a reply... */
3387 W;
3388}
3389
3390static int api_sw_interface_set_l2_xconnect (vat_main_t * vam)
3391{
3392 unformat_input_t * i = vam->input;
3393 vl_api_sw_interface_set_l2_xconnect_t *mp;
3394 f64 timeout;
3395 u32 rx_sw_if_index;
3396 u8 rx_sw_if_index_set = 0;
3397 u32 tx_sw_if_index;
3398 u8 tx_sw_if_index_set = 0;
3399 u8 enable = 1;
3400
3401 /* Parse args required to build the message */
3402 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3403 if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
3404 rx_sw_if_index_set = 1;
3405 else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
3406 tx_sw_if_index_set = 1;
3407 else if (unformat (i, "rx")) {
3408 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3409 if (unformat (i, "%U", unformat_sw_if_index, vam,
3410 &rx_sw_if_index))
3411 rx_sw_if_index_set = 1;
3412 } else
3413 break;
3414 } else if (unformat (i, "tx")) {
3415 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3416 if (unformat (i, "%U", unformat_sw_if_index, vam,
3417 &tx_sw_if_index))
3418 tx_sw_if_index_set = 1;
3419 } else
3420 break;
3421 } else if (unformat (i, "enable"))
3422 enable = 1;
3423 else if (unformat (i, "disable"))
3424 enable = 0;
3425 else
3426 break;
3427 }
3428
3429 if (rx_sw_if_index_set == 0) {
3430 errmsg ("missing rx interface name or rx_sw_if_index\n");
3431 return -99;
3432 }
3433
3434 if (enable && (tx_sw_if_index_set == 0)) {
3435 errmsg ("missing tx interface name or tx_sw_if_index\n");
3436 return -99;
3437 }
3438
3439 M(SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
3440
3441 mp->rx_sw_if_index = ntohl(rx_sw_if_index);
3442 mp->tx_sw_if_index = ntohl(tx_sw_if_index);
3443 mp->enable = enable;
3444
3445 S; W;
3446 /* NOTREACHED */
3447 return 0;
3448}
3449
3450static int api_sw_interface_set_l2_bridge (vat_main_t * vam)
3451{
3452 unformat_input_t * i = vam->input;
3453 vl_api_sw_interface_set_l2_bridge_t *mp;
3454 f64 timeout;
3455 u32 rx_sw_if_index;
3456 u8 rx_sw_if_index_set = 0;
3457 u32 bd_id;
3458 u8 bd_id_set = 0;
3459 u8 bvi = 0;
3460 u32 shg = 0;
3461 u8 enable = 1;
3462
3463 /* Parse args required to build the message */
3464 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3465 if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
3466 rx_sw_if_index_set = 1;
3467 else if (unformat (i, "bd_id %d", &bd_id))
3468 bd_id_set = 1;
3469 else if (unformat (i, "%U", unformat_sw_if_index, vam,
3470 &rx_sw_if_index))
3471 rx_sw_if_index_set = 1;
3472 else if (unformat (i, "shg %d", &shg))
3473 ;
3474 else if (unformat (i, "bvi"))
3475 bvi = 1;
3476 else if (unformat (i, "enable"))
3477 enable = 1;
3478 else if (unformat (i, "disable"))
3479 enable = 0;
3480 else
3481 break;
3482 }
3483
3484 if (rx_sw_if_index_set == 0) {
3485 errmsg ("missing rx interface name or sw_if_index\n");
3486 return -99;
3487 }
3488
3489 if (enable && (bd_id_set == 0)) {
3490 errmsg ("missing bridge domain\n");
3491 return -99;
3492 }
3493
3494 M(SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
3495
3496 mp->rx_sw_if_index = ntohl(rx_sw_if_index);
3497 mp->bd_id = ntohl(bd_id);
3498 mp->shg = (u8)shg;
3499 mp->bvi = bvi;
3500 mp->enable = enable;
3501
3502 S; W;
3503 /* NOTREACHED */
3504 return 0;
3505}
3506
3507static int api_bridge_domain_dump (vat_main_t * vam)
3508{
3509 unformat_input_t * i = vam->input;
3510 vl_api_bridge_domain_dump_t *mp;
3511 f64 timeout;
3512 u32 bd_id = ~0;
3513
3514 /* Parse args required to build the message */
3515 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3516 if (unformat (i, "bd_id %d", &bd_id))
3517 ;
3518 else
3519 break;
3520 }
3521
3522 M(BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
3523 mp->bd_id = ntohl(bd_id);
3524 S;
3525
3526 /* Use a control ping for synchronization */
3527 {
3528 vl_api_control_ping_t * mp;
3529 M(CONTROL_PING, control_ping);
3530 S;
3531 }
3532
3533 W;
3534 /* NOTREACHED */
3535 return 0;
3536}
3537
3538static int api_bridge_domain_add_del (vat_main_t * vam)
3539{
3540 unformat_input_t * i = vam->input;
3541 vl_api_bridge_domain_add_del_t *mp;
3542 f64 timeout;
3543 u32 bd_id = ~0;
3544 u8 is_add = 1;
3545 u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
3546
3547 /* Parse args required to build the message */
3548 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3549 if (unformat (i, "bd_id %d", &bd_id))
3550 ;
3551 else if (unformat (i, "flood %d", &flood))
3552 ;
3553 else if (unformat (i, "uu-flood %d", &uu_flood))
3554 ;
3555 else if (unformat (i, "forward %d", &forward))
3556 ;
3557 else if (unformat (i, "learn %d", &learn))
3558 ;
3559 else if (unformat (i, "arp-term %d", &arp_term))
3560 ;
3561 else if (unformat (i, "del")) {
3562 is_add = 0;
3563 flood = uu_flood = forward = learn = 0;
3564 }
3565 else
3566 break;
3567 }
3568
3569 if (bd_id == ~0) {
3570 errmsg ("missing bridge domain\n");
3571 return -99;
3572 }
3573
3574 M(BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
3575
3576 mp->bd_id = ntohl(bd_id);
3577 mp->flood = flood;
3578 mp->uu_flood = uu_flood;
3579 mp->forward = forward;
3580 mp->learn = learn;
3581 mp->arp_term = arp_term;
3582 mp->is_add = is_add;
3583
3584 S; W;
3585 /* NOTREACHED */
3586 return 0;
3587}
3588
3589static int api_l2fib_add_del (vat_main_t * vam)
3590{
3591 unformat_input_t * i = vam->input;
3592 vl_api_l2fib_add_del_t *mp;
3593 f64 timeout;
3594 u64 mac = 0;
3595 u8 mac_set = 0;
3596 u32 bd_id;
3597 u8 bd_id_set = 0;
3598 u32 sw_if_index;
3599 u8 sw_if_index_set = 0;
3600 u8 is_add = 1;
3601 u8 static_mac = 0;
3602 u8 filter_mac = 0;
3603
3604 /* Parse args required to build the message */
3605 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3606 if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
3607 mac_set = 1;
3608 else if (unformat (i, "bd_id %d", &bd_id))
3609 bd_id_set = 1;
3610 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3611 sw_if_index_set = 1;
3612 else if (unformat (i, "sw_if")) {
3613 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3614 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3615 sw_if_index_set = 1;
3616 } else
3617 break;
3618 } else if (unformat (i, "static"))
3619 static_mac = 1;
3620 else if (unformat (i, "filter")) {
3621 filter_mac = 1;
3622 static_mac = 1;
3623 } else if (unformat (i, "del"))
3624 is_add = 0;
3625 else
3626 break;
3627 }
3628
3629 if (mac_set == 0) {
3630 errmsg ("missing mac address\n");
3631 return -99;
3632 }
3633
3634 if (bd_id_set == 0) {
3635 errmsg ("missing bridge domain\n");
3636 return -99;
3637 }
3638
3639 if (is_add && (sw_if_index_set == 0)) {
3640 errmsg ("missing interface name or sw_if_index\n");
3641 return -99;
3642 }
3643
3644 M(L2FIB_ADD_DEL, l2fib_add_del);
3645
3646 mp->mac = mac;
3647 mp->bd_id = ntohl(bd_id);
3648 mp->is_add = is_add;
3649
3650 if (is_add) {
3651 mp->sw_if_index = ntohl(sw_if_index);
3652 mp->static_mac = static_mac;
3653 mp->filter_mac = filter_mac;
3654 }
3655
3656 S; W;
3657 /* NOTREACHED */
3658 return 0;
3659}
3660
3661static int api_l2_flags (vat_main_t * vam)
3662{
3663 unformat_input_t * i = vam->input;
3664 vl_api_l2_flags_t *mp;
3665 f64 timeout;
3666 u32 sw_if_index;
3667 u32 feature_bitmap = 0;
3668 u8 sw_if_index_set = 0;
3669
3670 /* Parse args required to build the message */
3671 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3672 if (unformat (i, "sw_if_index %d", &sw_if_index))
3673 sw_if_index_set = 1;
3674 else if (unformat (i, "sw_if")) {
3675 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3676 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3677 sw_if_index_set = 1;
3678 } else
3679 break;
3680 } else if (unformat (i, "learn"))
3681 feature_bitmap |= L2INPUT_FEAT_LEARN;
3682 else if (unformat (i, "forward"))
3683 feature_bitmap |= L2INPUT_FEAT_FWD;
3684 else if (unformat (i, "flood"))
3685 feature_bitmap |= L2INPUT_FEAT_FLOOD;
3686 else if (unformat (i, "uu-flood"))
3687 feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
3688 else
3689 break;
3690 }
3691
3692 if (sw_if_index_set == 0) {
3693 errmsg ("missing interface name or sw_if_index\n");
3694 return -99;
3695 }
3696
3697 M(L2_FLAGS, l2_flags);
3698
3699 mp->sw_if_index = ntohl(sw_if_index);
3700 mp->feature_bitmap = ntohl(feature_bitmap);
3701
3702 S; W;
3703 /* NOTREACHED */
3704 return 0;
3705}
3706
3707static int api_bridge_flags (vat_main_t * vam)
3708{
3709 unformat_input_t * i = vam->input;
3710 vl_api_bridge_flags_t *mp;
3711 f64 timeout;
3712 u32 bd_id;
3713 u8 bd_id_set = 0;
3714 u8 is_set = 1;
3715 u32 flags = 0;
3716
3717 /* Parse args required to build the message */
3718 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3719 if (unformat (i, "bd_id %d", &bd_id))
3720 bd_id_set = 1;
3721 else if (unformat (i, "learn"))
3722 flags |= L2_LEARN;
3723 else if (unformat (i, "forward"))
3724 flags |= L2_FWD;
3725 else if (unformat (i, "flood"))
3726 flags |= L2_FLOOD;
3727 else if (unformat (i, "uu-flood"))
3728 flags |= L2_UU_FLOOD;
3729 else if (unformat (i, "arp-term"))
3730 flags |= L2_ARP_TERM;
3731 else if (unformat (i, "off"))
3732 is_set = 0;
3733 else if (unformat (i, "disable"))
3734 is_set = 0;
3735 else
3736 break;
3737 }
3738
3739 if (bd_id_set == 0) {
3740 errmsg ("missing bridge domain\n");
3741 return -99;
3742 }
3743
3744 M(BRIDGE_FLAGS, bridge_flags);
3745
3746 mp->bd_id = ntohl(bd_id);
3747 mp->feature_bitmap = ntohl(flags);
3748 mp->is_set = is_set;
3749
3750 S; W;
3751 /* NOTREACHED */
3752 return 0;
3753}
3754
3755static int api_bd_ip_mac_add_del (vat_main_t * vam)
3756{
3757 unformat_input_t * i = vam->input;
3758 vl_api_bd_ip_mac_add_del_t *mp;
3759 f64 timeout;
3760 u32 bd_id;
3761 u8 is_ipv6 = 0;
3762 u8 is_add = 1;
3763 u8 bd_id_set = 0;
3764 u8 ip_set = 0;
3765 u8 mac_set = 0;
3766 ip4_address_t v4addr;
3767 ip6_address_t v6addr;
3768 u8 macaddr[6];
3769
3770
3771 /* Parse args required to build the message */
3772 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3773 if (unformat (i, "bd_id %d", &bd_id)) {
3774 bd_id_set++;
3775 } else if (unformat (i, "%U", unformat_ip4_address, &v4addr)) {
3776 ip_set++;
3777 } else if (unformat (i, "%U", unformat_ip6_address, &v6addr)) {
3778 ip_set++;
3779 is_ipv6++;
3780 } else if (unformat (i, "%U", unformat_ethernet_address, macaddr)) {
3781 mac_set++;
3782 } else if (unformat (i, "del"))
3783 is_add = 0;
3784 else
3785 break;
3786 }
3787
3788 if (bd_id_set == 0) {
3789 errmsg ("missing bridge domain\n");
3790 return -99;
3791 } else if (ip_set == 0) {
3792 errmsg ("missing IP address\n");
3793 return -99;
3794 } else if (mac_set == 0) {
3795 errmsg ("missing MAC address\n");
3796 return -99;
3797 }
3798
3799 M(BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
3800
3801 mp->bd_id = ntohl(bd_id);
3802 mp->is_ipv6 = is_ipv6;
3803 mp->is_add = is_add;
3804 if (is_ipv6)
Damjan Marionf1213b82016-03-13 02:22:06 +01003805 clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
3806 else clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
3807 clib_memcpy (mp->mac_address, macaddr, 6);
Ed Warnickecb9cada2015-12-08 15:45:58 -07003808 S; W;
3809 /* NOTREACHED */
3810 return 0;
3811}
3812
3813static int api_tap_connect (vat_main_t * vam)
3814{
3815 unformat_input_t * i = vam->input;
3816 vl_api_tap_connect_t *mp;
3817 f64 timeout;
3818 u8 mac_address[6];
3819 u8 random_mac = 1;
3820 u8 name_set = 0;
3821 u8 * tap_name;
3822
3823 memset (mac_address, 0, sizeof (mac_address));
3824
3825 /* Parse args required to build the message */
3826 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3827 if (unformat (i, "mac %U", unformat_ethernet_address, mac_address)) {
3828 random_mac = 0;
3829 }
3830 else if (unformat (i, "random-mac"))
3831 random_mac = 1;
3832 else if (unformat (i, "tapname %s", &tap_name))
3833 name_set = 1;
3834 else
3835 break;
3836 }
3837
3838 if (name_set == 0) {
3839 errmsg ("missing tap name\n");
3840 return -99;
3841 }
3842 if (vec_len (tap_name) > 63) {
3843 errmsg ("tap name too long\n");
3844 }
3845 vec_add1 (tap_name, 0);
3846
3847 /* Construct the API message */
3848 M(TAP_CONNECT, tap_connect);
3849
3850 mp->use_random_mac = random_mac;
Damjan Marionf1213b82016-03-13 02:22:06 +01003851 clib_memcpy (mp->mac_address, mac_address, 6);
3852 clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
Ed Warnickecb9cada2015-12-08 15:45:58 -07003853 vec_free (tap_name);
3854
3855 /* send it... */
3856 S;
3857
3858 /* Wait for a reply... */
3859 W;
3860}
3861
3862static int api_tap_modify (vat_main_t * vam)
3863{
3864 unformat_input_t * i = vam->input;
3865 vl_api_tap_modify_t *mp;
3866 f64 timeout;
3867 u8 mac_address[6];
3868 u8 random_mac = 1;
3869 u8 name_set = 0;
3870 u8 * tap_name;
3871 u32 sw_if_index = ~0;
3872 u8 sw_if_index_set = 0;
3873
3874 memset (mac_address, 0, sizeof (mac_address));
3875
3876 /* Parse args required to build the message */
3877 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3878 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3879 sw_if_index_set = 1;
3880 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3881 sw_if_index_set = 1;
3882 else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address)) {
3883 random_mac = 0;
3884 }
3885 else if (unformat (i, "random-mac"))
3886 random_mac = 1;
3887 else if (unformat (i, "tapname %s", &tap_name))
3888 name_set = 1;
3889 else
3890 break;
3891 }
3892
3893 if (sw_if_index_set == 0) {
3894 errmsg ("missing vpp interface name");
3895 return -99;
3896 }
3897 if (name_set == 0) {
3898 errmsg ("missing tap name\n");
3899 return -99;
3900 }
3901 if (vec_len (tap_name) > 63) {
3902 errmsg ("tap name too long\n");
3903 }
3904 vec_add1 (tap_name, 0);
3905
3906 /* Construct the API message */
3907 M(TAP_MODIFY, tap_modify);
3908
3909 mp->use_random_mac = random_mac;
3910 mp->sw_if_index = ntohl(sw_if_index);
Damjan Marionf1213b82016-03-13 02:22:06 +01003911 clib_memcpy (mp->mac_address, mac_address, 6);
3912 clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
Ed Warnickecb9cada2015-12-08 15:45:58 -07003913 vec_free (tap_name);
3914
3915 /* send it... */
3916 S;
3917
3918 /* Wait for a reply... */
3919 W;
3920}
3921
3922static int api_tap_delete (vat_main_t * vam)
3923{
3924 unformat_input_t * i = vam->input;
3925 vl_api_tap_delete_t *mp;
3926 f64 timeout;
3927 u32 sw_if_index = ~0;
3928 u8 sw_if_index_set = 0;
3929
3930 /* Parse args required to build the message */
3931 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3932 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3933 sw_if_index_set = 1;
3934 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3935 sw_if_index_set = 1;
3936 else
3937 break;
3938 }
3939
3940 if (sw_if_index_set == 0) {
3941 errmsg ("missing vpp interface name");
3942 return -99;
3943 }
3944
3945 /* Construct the API message */
3946 M(TAP_DELETE, tap_delete);
3947
3948 mp->sw_if_index = ntohl(sw_if_index);
3949
3950 /* send it... */
3951 S;
3952
3953 /* Wait for a reply... */
3954 W;
3955}
3956
3957static int api_ip_add_del_route (vat_main_t * vam)
3958{
3959 unformat_input_t * i = vam->input;
3960 vl_api_ip_add_del_route_t *mp;
3961 f64 timeout;
3962 u32 sw_if_index = 0, vrf_id = 0;
3963 u8 sw_if_index_set = 0;
3964 u8 is_ipv6 = 0;
3965 u8 is_local = 0, is_drop = 0;
3966 u8 create_vrf_if_needed = 0;
3967 u8 is_add = 1;
3968 u8 next_hop_weight = 1;
3969 u8 not_last = 0;
3970 u8 is_multipath = 0;
3971 u8 address_set = 0;
3972 u8 address_length_set = 0;
3973 u32 lookup_in_vrf = 0;
3974 u32 resolve_attempts = 0;
3975 u32 dst_address_length = 0;
3976 u8 next_hop_set = 0;
3977 ip4_address_t v4_dst_address, v4_next_hop_address;
3978 ip6_address_t v6_dst_address, v6_next_hop_address;
3979 int count = 1;
3980 int j;
3981 f64 before = 0;
3982 u32 random_add_del = 0;
3983 u32 * random_vector = 0;
3984 uword * random_hash;
3985 u32 random_seed = 0xdeaddabe;
3986 u32 classify_table_index = ~0;
3987 u8 is_classify = 0;
3988
3989 /* Parse args required to build the message */
3990 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3991 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3992 sw_if_index_set = 1;
3993 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3994 sw_if_index_set = 1;
3995 else if (unformat (i, "%U", unformat_ip4_address,
3996 &v4_dst_address)) {
3997 address_set = 1;
3998 is_ipv6 = 0;
3999 }
4000 else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address)) {
4001 address_set = 1;
4002 is_ipv6 = 1;
4003 }
4004 else if (unformat (i, "/%d", &dst_address_length)) {
4005 address_length_set = 1;
4006 }
4007
4008 else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
4009 &v4_next_hop_address)) {
4010 next_hop_set = 1;
4011 }
4012 else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
4013 &v6_next_hop_address)) {
4014 next_hop_set = 1;
4015 }
4016 else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
4017 ;
4018 else if (unformat (i, "weight %d", &next_hop_weight))
4019 ;
4020 else if (unformat (i, "drop")) {
4021 is_drop = 1;
4022 } else if (unformat (i, "local")) {
4023 is_local = 1;
4024 } else if (unformat (i, "classify %d", &classify_table_index)) {
4025 is_classify = 1;
4026 } else if (unformat (i, "del"))
4027 is_add = 0;
4028 else if (unformat (i, "add"))
4029 is_add = 1;
4030 else if (unformat (i, "not-last"))
4031 not_last = 1;
4032 else if (unformat (i, "multipath"))
4033 is_multipath = 1;
4034 else if (unformat (i, "vrf %d", &vrf_id))
4035 ;
4036 else if (unformat (i, "create-vrf"))
4037 create_vrf_if_needed = 1;
4038 else if (unformat (i, "count %d", &count))
4039 ;
4040 else if (unformat (i, "lookup-in-vrf %d", &lookup_in_vrf))
4041 ;
4042 else if (unformat (i, "random"))
4043 random_add_del = 1;
4044 else if (unformat (i, "seed %d", &random_seed))
4045 ;
4046 else {
4047 clib_warning ("parse error '%U'", format_unformat_error, i);
4048 return -99;
4049 }
4050 }
4051
4052 if (resolve_attempts > 0 && sw_if_index_set == 0) {
4053 errmsg ("ARP resolution needs explicit interface or sw_if_index\n");
4054 return -99;
4055 }
4056
4057 if (!next_hop_set && !is_drop && !is_local && !is_classify) {
4058 errmsg ("next hop / local / drop / classify not set\n");
4059 return -99;
4060 }
4061
4062 if (address_set == 0) {
4063 errmsg ("missing addresses\n");
4064 return -99;
4065 }
4066
4067 if (address_length_set == 0) {
4068 errmsg ("missing address length\n");
4069 return -99;
4070 }
4071
4072 /* Generate a pile of unique, random routes */
4073 if (random_add_del) {
4074 u32 this_random_address;
4075 random_hash = hash_create (count, sizeof(uword));
4076
4077 hash_set (random_hash, v4_next_hop_address.as_u32, 1);
4078 for (j = 0; j <= count; j++) {
4079 do {
4080 this_random_address = random_u32 (&random_seed);
4081 this_random_address =
4082 clib_host_to_net_u32 (this_random_address);
4083 } while (hash_get (random_hash, this_random_address));
4084 vec_add1 (random_vector, this_random_address);
4085 hash_set (random_hash, this_random_address, 1);
4086 }
4087 hash_free (random_hash);
4088 v4_dst_address.as_u32 = random_vector[0];
4089 }
4090
4091 if (count > 1) {
4092 /* Turn on async mode */
4093 vam->async_mode = 1;
4094 vam->async_errors = 0;
4095 before = vat_time_now(vam);
4096 }
4097
4098 for (j = 0; j < count; j++) {
4099 /* Construct the API message */
4100 M(IP_ADD_DEL_ROUTE, ip_add_del_route);
4101
4102 mp->next_hop_sw_if_index = ntohl (sw_if_index);
4103 mp->vrf_id = ntohl (vrf_id);
4104 if (resolve_attempts > 0) {
4105 mp->resolve_attempts = ntohl (resolve_attempts);
4106 mp->resolve_if_needed = 1;
4107 }
4108 mp->create_vrf_if_needed = create_vrf_if_needed;
4109
4110 mp->is_add = is_add;
4111 mp->is_drop = is_drop;
4112 mp->is_ipv6 = is_ipv6;
4113 mp->is_local = is_local;
4114 mp->is_classify = is_classify;
4115 mp->is_multipath = is_multipath;
4116 mp->not_last = not_last;
4117 mp->next_hop_weight = next_hop_weight;
4118 mp->dst_address_length = dst_address_length;
4119 mp->lookup_in_vrf = ntohl(lookup_in_vrf);
4120 mp->classify_table_index = ntohl(classify_table_index);
4121
4122 if (is_ipv6){
Damjan Marionf1213b82016-03-13 02:22:06 +01004123 clib_memcpy (mp->dst_address, &v6_dst_address, sizeof (v6_dst_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004124 if (next_hop_set)
Damjan Marionf1213b82016-03-13 02:22:06 +01004125 clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
Ed Warnickecb9cada2015-12-08 15:45:58 -07004126 sizeof (v6_next_hop_address));
4127 increment_v6_address (&v6_dst_address);
4128 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01004129 clib_memcpy (mp->dst_address, &v4_dst_address, sizeof (v4_dst_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004130 if (next_hop_set)
Damjan Marionf1213b82016-03-13 02:22:06 +01004131 clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
Ed Warnickecb9cada2015-12-08 15:45:58 -07004132 sizeof (v4_next_hop_address));
4133 if (random_add_del)
4134 v4_dst_address.as_u32 = random_vector[j+1];
4135 else
4136 increment_v4_address (&v4_dst_address);
4137 }
4138 /* send it... */
4139 S;
4140 }
4141
4142 /* When testing multiple add/del ops, use a control-ping to sync */
4143 if (count > 1) {
4144 vl_api_control_ping_t * mp;
4145 f64 after;
4146
4147 /* Shut off async mode */
4148 vam->async_mode = 0;
4149
4150 M(CONTROL_PING, control_ping);
4151 S;
4152
4153 timeout = vat_time_now(vam) + 1.0;
4154 while (vat_time_now (vam) < timeout)
4155 if (vam->result_ready == 1)
4156 goto out;
4157 vam->retval = -99;
4158
4159 out:
4160 if (vam->retval == -99)
4161 errmsg ("timeout\n");
4162
4163 if (vam->async_errors > 0) {
4164 errmsg ("%d asynchronous errors\n", vam->async_errors);
4165 vam->retval = -98;
4166 }
4167 vam->async_errors = 0;
4168 after = vat_time_now(vam);
4169
4170 fformat(vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
4171 count, after - before, count / (after - before));
4172 } else {
4173 /* Wait for a reply... */
4174 W;
4175 }
4176
4177 /* Return the good/bad news */
4178 return (vam->retval);
4179}
4180
4181static int api_proxy_arp_add_del (vat_main_t * vam)
4182{
4183 unformat_input_t * i = vam->input;
4184 vl_api_proxy_arp_add_del_t *mp;
4185 f64 timeout;
4186 u32 vrf_id = 0;
4187 u8 is_add = 1;
4188 ip4_address_t lo, hi;
4189 u8 range_set = 0;
4190
4191 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4192 if (unformat (i, "vrf %d", &vrf_id))
4193 ;
4194 else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
4195 unformat_ip4_address, &hi))
4196 range_set = 1;
4197 else if (unformat (i, "del"))
4198 is_add = 0;
4199 else {
4200 clib_warning ("parse error '%U'", format_unformat_error, i);
4201 return -99;
4202 }
4203 }
4204
4205 if (range_set == 0) {
4206 errmsg ("address range not set\n");
4207 return -99;
4208 }
4209
4210 M(PROXY_ARP_ADD_DEL, proxy_arp_add_del);
4211
4212 mp->vrf_id = ntohl(vrf_id);
4213 mp->is_add = is_add;
Damjan Marionf1213b82016-03-13 02:22:06 +01004214 clib_memcpy(mp->low_address, &lo, sizeof (mp->low_address));
4215 clib_memcpy(mp->hi_address, &hi, sizeof (mp->hi_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004216
4217 S; W;
4218 /* NOTREACHED */
4219 return 0;
4220}
4221
4222static int api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
4223{
4224 unformat_input_t * i = vam->input;
4225 vl_api_proxy_arp_intfc_enable_disable_t *mp;
4226 f64 timeout;
4227 u32 sw_if_index;
4228 u8 enable = 1;
4229 u8 sw_if_index_set = 0;
4230
4231 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4232 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4233 sw_if_index_set = 1;
4234 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4235 sw_if_index_set = 1;
4236 else if (unformat (i, "enable"))
4237 enable = 1;
4238 else if (unformat (i, "disable"))
4239 enable = 0;
4240 else {
4241 clib_warning ("parse error '%U'", format_unformat_error, i);
4242 return -99;
4243 }
4244 }
4245
4246 if (sw_if_index_set == 0) {
4247 errmsg ("missing interface name or sw_if_index\n");
4248 return -99;
4249 }
4250
4251 M(PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
4252
4253 mp->sw_if_index = ntohl(sw_if_index);
4254 mp->enable_disable = enable;
4255
4256 S; W;
4257 /* NOTREACHED */
4258 return 0;
4259}
4260
4261static int api_mpls_add_del_decap (vat_main_t * vam)
4262{
4263 unformat_input_t * i = vam->input;
4264 vl_api_mpls_add_del_decap_t *mp;
4265 f64 timeout;
4266 u32 rx_vrf_id = 0;
4267 u32 tx_vrf_id = 0;
4268 u32 label = 0;
4269 u8 is_add = 1;
4270 u8 s_bit = 1;
4271 u32 next_index = 1;
4272
4273 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4274 if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
4275 ;
4276 else if (unformat (i, "tx_vrf_id %d", &tx_vrf_id))
4277 ;
4278 else if (unformat (i, "label %d", &label))
4279 ;
4280 else if (unformat (i, "next-index %d", &next_index))
4281 ;
4282 else if (unformat (i, "del"))
4283 is_add = 0;
4284 else if (unformat (i, "s-bit-clear"))
4285 s_bit = 0;
4286 else {
4287 clib_warning ("parse error '%U'", format_unformat_error, i);
4288 return -99;
4289 }
4290 }
4291
4292 M(MPLS_ADD_DEL_DECAP, mpls_add_del_decap);
4293
4294 mp->rx_vrf_id = ntohl(rx_vrf_id);
4295 mp->tx_vrf_id = ntohl(tx_vrf_id);
4296 mp->label = ntohl(label);
4297 mp->next_index = ntohl(next_index);
4298 mp->s_bit = s_bit;
4299 mp->is_add = is_add;
4300
4301 S; W;
4302 /* NOTREACHED */
4303 return 0;
4304}
4305
4306static int api_mpls_add_del_encap (vat_main_t * vam)
4307{
4308 unformat_input_t * i = vam->input;
4309 vl_api_mpls_add_del_encap_t *mp;
4310 f64 timeout;
4311 u32 vrf_id = 0;
4312 u32 *labels = 0;
4313 u32 label;
4314 ip4_address_t dst_address;
4315 u8 is_add = 1;
4316
4317 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4318 if (unformat (i, "vrf %d", &vrf_id))
4319 ;
4320 else if (unformat (i, "label %d", &label))
4321 vec_add1 (labels, ntohl(label));
4322 else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
4323 ;
4324 else if (unformat (i, "del"))
4325 is_add = 0;
4326 else {
4327 clib_warning ("parse error '%U'", format_unformat_error, i);
4328 return -99;
4329 }
4330 }
4331
4332 if (vec_len (labels) == 0) {
4333 errmsg ("missing encap label stack\n");
4334 return -99;
4335 }
4336
4337 M2(MPLS_ADD_DEL_ENCAP, mpls_add_del_encap,
4338 sizeof (u32) * vec_len (labels));
4339
4340 mp->vrf_id = ntohl(vrf_id);
Damjan Marionf1213b82016-03-13 02:22:06 +01004341 clib_memcpy(mp->dst_address, &dst_address, sizeof (dst_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004342 mp->is_add = is_add;
4343 mp->nlabels = vec_len (labels);
Damjan Marionf1213b82016-03-13 02:22:06 +01004344 clib_memcpy(mp->labels, labels, sizeof(u32)*mp->nlabels);
Ed Warnickecb9cada2015-12-08 15:45:58 -07004345
4346 vec_free(labels);
4347
4348 S; W;
4349 /* NOTREACHED */
4350 return 0;
4351}
4352
4353static int api_mpls_gre_add_del_tunnel (vat_main_t * vam)
4354{
4355 unformat_input_t * i = vam->input;
4356 vl_api_mpls_gre_add_del_tunnel_t *mp;
4357 f64 timeout;
4358 u32 inner_vrf_id = 0;
4359 u32 outer_vrf_id = 0;
4360 ip4_address_t src_address;
4361 ip4_address_t dst_address;
4362 ip4_address_t intfc_address;
4363 u32 tmp;
4364 u8 intfc_address_length = 0;
4365 u8 is_add = 1;
4366 u8 l2_only = 0;
4367
4368 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4369 if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
4370 ;
4371 else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
4372 ;
4373 else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
4374 ;
4375 else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
4376 ;
4377 else if (unformat (i, "adj %U/%d", unformat_ip4_address,
4378 &intfc_address, &tmp))
4379 intfc_address_length = tmp;
4380 else if (unformat (i, "l2-only"))
4381 l2_only = 1;
4382 else if (unformat (i, "del"))
4383 is_add = 0;
4384 else {
4385 clib_warning ("parse error '%U'", format_unformat_error, i);
4386 return -99;
4387 }
4388 }
4389
4390 M(MPLS_GRE_ADD_DEL_TUNNEL, mpls_gre_add_del_tunnel);
4391
4392 mp->inner_vrf_id = ntohl(inner_vrf_id);
4393 mp->outer_vrf_id = ntohl(outer_vrf_id);
Damjan Marionf1213b82016-03-13 02:22:06 +01004394 clib_memcpy(mp->src_address, &src_address, sizeof (src_address));
4395 clib_memcpy(mp->dst_address, &dst_address, sizeof (dst_address));
4396 clib_memcpy(mp->intfc_address, &intfc_address, sizeof (intfc_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004397 mp->intfc_address_length = intfc_address_length;
4398 mp->l2_only = l2_only;
4399 mp->is_add = is_add;
4400
4401 S; W;
4402 /* NOTREACHED */
4403 return 0;
4404}
4405
4406static int api_mpls_ethernet_add_del_tunnel (vat_main_t * vam)
4407{
4408 unformat_input_t * i = vam->input;
4409 vl_api_mpls_ethernet_add_del_tunnel_t *mp;
4410 f64 timeout;
4411 u32 inner_vrf_id = 0;
4412 ip4_address_t intfc_address;
4413 u8 dst_mac_address[6];
4414 int dst_set = 1;
4415 u32 tmp;
4416 u8 intfc_address_length = 0;
4417 u8 is_add = 1;
4418 u8 l2_only = 0;
4419 u32 tx_sw_if_index;
4420 int tx_sw_if_index_set = 0;
4421
4422 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4423 if (unformat (i, "vrf %d", &inner_vrf_id))
4424 ;
4425 else if (unformat (i, "adj %U/%d", unformat_ip4_address,
4426 &intfc_address, &tmp))
4427 intfc_address_length = tmp;
4428 else if (unformat (i, "%U",
4429 unformat_sw_if_index, vam, &tx_sw_if_index))
4430 tx_sw_if_index_set = 1;
4431 else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
4432 tx_sw_if_index_set = 1;
4433 else if (unformat (i, "dst %U", unformat_ethernet_address,
4434 dst_mac_address))
4435 dst_set = 1;
4436 else if (unformat (i, "l2-only"))
4437 l2_only = 1;
4438 else if (unformat (i, "del"))
4439 is_add = 0;
4440 else {
4441 clib_warning ("parse error '%U'", format_unformat_error, i);
4442 return -99;
4443 }
4444 }
4445
4446 if (!dst_set) {
4447 errmsg ("dst (mac address) not set\n");
4448 return -99;
4449 }
4450 if (!tx_sw_if_index_set) {
4451 errmsg ("tx-intfc not set\n");
4452 return -99;
4453 }
4454
4455 M(MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel);
4456
4457 mp->vrf_id = ntohl(inner_vrf_id);
Damjan Marionf1213b82016-03-13 02:22:06 +01004458 clib_memcpy (mp->adj_address, &intfc_address, sizeof (intfc_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004459 mp->adj_address_length = intfc_address_length;
Damjan Marionf1213b82016-03-13 02:22:06 +01004460 clib_memcpy (mp->dst_mac_address, dst_mac_address, sizeof (dst_mac_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004461 mp->tx_sw_if_index = ntohl(tx_sw_if_index);
4462 mp->l2_only = l2_only;
4463 mp->is_add = is_add;
4464
4465 S; W;
4466 /* NOTREACHED */
4467 return 0;
4468}
4469
4470static int api_mpls_ethernet_add_del_tunnel_2 (vat_main_t * vam)
4471{
4472 unformat_input_t * i = vam->input;
4473 vl_api_mpls_ethernet_add_del_tunnel_2_t *mp;
4474 f64 timeout;
4475 u32 inner_vrf_id = 0;
4476 u32 outer_vrf_id = 0;
4477 ip4_address_t adj_address;
4478 int adj_address_set = 0;
4479 ip4_address_t next_hop_address;
4480 int next_hop_address_set = 0;
4481 u32 tmp;
4482 u8 adj_address_length = 0;
4483 u8 l2_only = 0;
4484 u8 is_add = 1;
4485 u32 resolve_attempts = 5;
4486 u8 resolve_if_needed = 1;
4487
4488 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4489 if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
4490 ;
4491 else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
4492 ;
4493 else if (unformat (i, "adj %U/%d", unformat_ip4_address,
4494 &adj_address, &tmp)) {
4495 adj_address_length = tmp;
4496 adj_address_set = 1;
4497 }
4498 else if (unformat (i, "next-hop %U", unformat_ip4_address,
4499 &next_hop_address))
4500 next_hop_address_set = 1;
4501 else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
4502 ;
4503 else if (unformat (i, "resolve-if-needed %d", &tmp))
4504 resolve_if_needed = tmp;
4505 else if (unformat (i, "l2-only"))
4506 l2_only = 1;
4507 else if (unformat (i, "del"))
4508 is_add = 0;
4509 else {
4510 clib_warning ("parse error '%U'", format_unformat_error, i);
4511 return -99;
4512 }
4513 }
4514
4515 if (!adj_address_set) {
4516 errmsg ("adjacency address/mask not set\n");
4517 return -99;
4518 }
4519 if (!next_hop_address_set) {
4520 errmsg ("ip4 next hop address (in outer fib) not set\n");
4521 return -99;
4522 }
4523
4524 M(MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2);
4525
4526 mp->inner_vrf_id = ntohl(inner_vrf_id);
4527 mp->outer_vrf_id = ntohl(outer_vrf_id);
4528 mp->resolve_attempts = ntohl(resolve_attempts);
4529 mp->resolve_if_needed = resolve_if_needed;
4530 mp->is_add = is_add;
4531 mp->l2_only = l2_only;
Damjan Marionf1213b82016-03-13 02:22:06 +01004532 clib_memcpy (mp->adj_address, &adj_address, sizeof (adj_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004533 mp->adj_address_length = adj_address_length;
Damjan Marionf1213b82016-03-13 02:22:06 +01004534 clib_memcpy (mp->next_hop_ip4_address_in_outer_vrf, &next_hop_address,
Ed Warnickecb9cada2015-12-08 15:45:58 -07004535 sizeof (next_hop_address));
4536
4537 S; W;
4538 /* NOTREACHED */
4539 return 0;
4540}
4541
4542static int api_sw_interface_set_unnumbered (vat_main_t * vam)
4543{
4544 unformat_input_t * i = vam->input;
4545 vl_api_sw_interface_set_unnumbered_t *mp;
4546 f64 timeout;
4547 u32 sw_if_index;
4548 u32 unnum_sw_index;
4549 u8 is_add = 1;
4550 u8 sw_if_index_set = 0;
4551
4552 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4553 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4554 sw_if_index_set = 1;
4555 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4556 sw_if_index_set = 1;
4557 else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
4558 ;
4559 else if (unformat (i, "del"))
4560 is_add = 0;
4561 else {
4562 clib_warning ("parse error '%U'", format_unformat_error, i);
4563 return -99;
4564 }
4565 }
4566
4567 if (sw_if_index_set == 0) {
4568 errmsg ("missing interface name or sw_if_index\n");
4569 return -99;
4570 }
4571
4572 M(SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
4573
4574 mp->sw_if_index = ntohl(sw_if_index);
4575 mp->unnumbered_sw_if_index = ntohl(unnum_sw_index);
4576 mp->is_add = is_add;
4577
4578 S; W;
4579 /* NOTREACHED */
4580 return 0;
4581}
4582
4583static int api_ip_neighbor_add_del (vat_main_t * vam)
4584{
4585 unformat_input_t * i = vam->input;
4586 vl_api_ip_neighbor_add_del_t *mp;
4587 f64 timeout;
4588 u32 sw_if_index;
4589 u8 sw_if_index_set = 0;
4590 u32 vrf_id = 0;
4591 u8 is_add = 1;
4592 u8 is_static = 0;
4593 u8 mac_address[6];
4594 u8 mac_set = 0;
4595 u8 v4_address_set = 0;
4596 u8 v6_address_set = 0;
4597 ip4_address_t v4address;
4598 ip6_address_t v6address;
4599
4600 memset (mac_address, 0, sizeof (mac_address));
4601
4602 /* Parse args required to build the message */
4603 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4604 if (unformat (i, "mac %U", unformat_ethernet_address, mac_address)) {
4605 mac_set = 1;
4606 }
4607 else if (unformat (i, "del"))
4608 is_add = 0;
4609 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4610 sw_if_index_set = 1;
4611 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4612 sw_if_index_set = 1;
4613 else if (unformat (i, "is_static"))
4614 is_static = 1;
4615 else if (unformat (i, "vrf %d", &vrf_id))
4616 ;
4617 else if (unformat (i, "dst %U",
4618 unformat_ip4_address, &v4address))
4619 v4_address_set = 1;
4620 else if (unformat (i, "dst %U",
4621 unformat_ip6_address, &v6address))
4622 v6_address_set = 1;
4623 else {
4624 clib_warning ("parse error '%U'", format_unformat_error, i);
4625 return -99;
4626 }
4627 }
4628
4629 if (sw_if_index_set == 0) {
4630 errmsg ("missing interface name or sw_if_index\n");
4631 return -99;
4632 }
4633 if (v4_address_set && v6_address_set) {
4634 errmsg ("both v4 and v6 addresses set\n");
4635 return -99;
4636 }
4637 if (!v4_address_set && !v6_address_set) {
4638 errmsg ("no addresses set\n");
4639 return -99;
4640 }
4641
4642 /* Construct the API message */
4643 M(IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
4644
4645 mp->sw_if_index = ntohl (sw_if_index);
4646 mp->is_add = is_add;
4647 mp->vrf_id = ntohl (vrf_id);
4648 mp->is_static = is_static;
4649 if (mac_set)
Damjan Marionf1213b82016-03-13 02:22:06 +01004650 clib_memcpy (mp->mac_address, mac_address, 6);
Ed Warnickecb9cada2015-12-08 15:45:58 -07004651 if (v6_address_set) {
4652 mp->is_ipv6 = 1;
Damjan Marionf1213b82016-03-13 02:22:06 +01004653 clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004654 } else {
4655 /* mp->is_ipv6 = 0; via memset in M macro above */
Damjan Marionf1213b82016-03-13 02:22:06 +01004656 clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004657 }
4658
4659 /* send it... */
4660 S;
4661
4662 /* Wait for a reply, return good/bad news */
4663 W;
4664
4665 /* NOTREACHED */
4666 return 0;
4667}
4668
4669static int api_reset_vrf (vat_main_t * vam)
4670{
4671 unformat_input_t * i = vam->input;
4672 vl_api_reset_vrf_t *mp;
4673 f64 timeout;
4674 u32 vrf_id = 0;
4675 u8 is_ipv6 = 0;
4676 u8 vrf_id_set = 0;
4677
4678 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4679 if (unformat (i, "vrf %d", &vrf_id))
4680 vrf_id_set = 1;
4681 else if (unformat (i, "ipv6"))
4682 is_ipv6 = 1;
4683 else {
4684 clib_warning ("parse error '%U'", format_unformat_error, i);
4685 return -99;
4686 }
4687 }
4688
4689 if (vrf_id_set == 0) {
4690 errmsg ("missing vrf id\n");
4691 return -99;
4692 }
4693
4694 M(RESET_VRF, reset_vrf);
4695
4696 mp->vrf_id = ntohl(vrf_id);
4697 mp->is_ipv6 = is_ipv6;
4698
4699 S; W;
4700 /* NOTREACHED */
4701 return 0;
4702}
4703
4704static int api_create_vlan_subif (vat_main_t * vam)
4705{
4706 unformat_input_t * i = vam->input;
4707 vl_api_create_vlan_subif_t *mp;
4708 f64 timeout;
4709 u32 sw_if_index;
4710 u8 sw_if_index_set = 0;
4711 u32 vlan_id;
4712 u8 vlan_id_set = 0;
4713
4714 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4715 if (unformat (i, "sw_if_index %d", &sw_if_index))
4716 sw_if_index_set = 1;
4717 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4718 sw_if_index_set = 1;
4719 else if (unformat (i, "vlan %d", &vlan_id))
4720 vlan_id_set = 1;
4721 else {
4722 clib_warning ("parse error '%U'", format_unformat_error, i);
4723 return -99;
4724 }
4725 }
4726
4727 if (sw_if_index_set == 0) {
4728 errmsg ("missing interface name or sw_if_index\n");
4729 return -99;
4730 }
4731
4732 if (vlan_id_set == 0) {
4733 errmsg ("missing vlan_id\n");
4734 return -99;
4735 }
4736 M(CREATE_VLAN_SUBIF, create_vlan_subif);
4737
4738 mp->sw_if_index = ntohl(sw_if_index);
4739 mp->vlan_id = ntohl(vlan_id);
4740
4741 S; W;
4742 /* NOTREACHED */
4743 return 0;
4744}
4745
4746#define foreach_create_subif_bit \
4747_(no_tags) \
4748_(one_tag) \
4749_(two_tags) \
4750_(dot1ad) \
4751_(exact_match) \
4752_(default_sub) \
4753_(outer_vlan_id_any) \
4754_(inner_vlan_id_any)
4755
4756static int api_create_subif (vat_main_t * vam)
4757{
4758 unformat_input_t * i = vam->input;
4759 vl_api_create_subif_t *mp;
4760 f64 timeout;
4761 u32 sw_if_index;
4762 u8 sw_if_index_set = 0;
4763 u32 sub_id;
4764 u8 sub_id_set = 0;
4765 u32 no_tags = 0;
4766 u32 one_tag = 0;
4767 u32 two_tags = 0;
4768 u32 dot1ad = 0;
4769 u32 exact_match = 0;
4770 u32 default_sub = 0;
4771 u32 outer_vlan_id_any = 0;
4772 u32 inner_vlan_id_any = 0;
4773 u32 tmp;
4774 u16 outer_vlan_id = 0;
4775 u16 inner_vlan_id = 0;
4776
4777 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4778 if (unformat (i, "sw_if_index %d", &sw_if_index))
4779 sw_if_index_set = 1;
4780 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4781 sw_if_index_set = 1;
4782 else if (unformat (i, "sub_id %d", &sub_id))
4783 sub_id_set = 1;
4784 else if (unformat (i, "outer_vlan_id %d", &tmp))
4785 outer_vlan_id = tmp;
4786 else if (unformat (i, "inner_vlan_id %d", &tmp))
4787 inner_vlan_id = tmp;
4788
4789#define _(a) else if (unformat (i, #a)) a = 1 ;
4790 foreach_create_subif_bit
4791#undef _
4792
4793 else {
4794 clib_warning ("parse error '%U'", format_unformat_error, i);
4795 return -99;
4796 }
4797 }
4798
4799 if (sw_if_index_set == 0) {
4800 errmsg ("missing interface name or sw_if_index\n");
4801 return -99;
4802 }
4803
4804 if (sub_id_set == 0) {
4805 errmsg ("missing sub_id\n");
4806 return -99;
4807 }
4808 M(CREATE_SUBIF, create_subif);
4809
4810 mp->sw_if_index = ntohl(sw_if_index);
4811 mp->sub_id = ntohl(sub_id);
4812
4813#define _(a) mp->a = a;
4814 foreach_create_subif_bit;
4815#undef _
4816
4817 mp->outer_vlan_id = ntohs (outer_vlan_id);
4818 mp->inner_vlan_id = ntohs (inner_vlan_id);
4819
4820 S; W;
4821 /* NOTREACHED */
4822 return 0;
4823}
4824
4825static int api_oam_add_del (vat_main_t * vam)
4826{
4827 unformat_input_t * i = vam->input;
4828 vl_api_oam_add_del_t *mp;
4829 f64 timeout;
4830 u32 vrf_id = 0;
4831 u8 is_add = 1;
4832 ip4_address_t src, dst;
4833 u8 src_set = 0;
4834 u8 dst_set = 0;
4835
4836 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4837 if (unformat (i, "vrf %d", &vrf_id))
4838 ;
4839 else if (unformat (i, "src %U", unformat_ip4_address, &src))
4840 src_set = 1;
4841 else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
4842 dst_set = 1;
4843 else if (unformat (i, "del"))
4844 is_add = 0;
4845 else {
4846 clib_warning ("parse error '%U'", format_unformat_error, i);
4847 return -99;
4848 }
4849 }
4850
4851 if (src_set == 0) {
4852 errmsg ("missing src addr\n");
4853 return -99;
4854 }
4855
4856 if (dst_set == 0) {
4857 errmsg ("missing dst addr\n");
4858 return -99;
4859 }
4860
4861 M(OAM_ADD_DEL, oam_add_del);
4862
4863 mp->vrf_id = ntohl(vrf_id);
4864 mp->is_add = is_add;
Damjan Marionf1213b82016-03-13 02:22:06 +01004865 clib_memcpy(mp->src_address, &src, sizeof (mp->src_address));
4866 clib_memcpy(mp->dst_address, &dst, sizeof (mp->dst_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004867
4868 S; W;
4869 /* NOTREACHED */
4870 return 0;
4871}
4872
4873static int api_reset_fib (vat_main_t * vam)
4874{
4875 unformat_input_t * i = vam->input;
4876 vl_api_reset_fib_t *mp;
4877 f64 timeout;
4878 u32 vrf_id = 0;
4879 u8 is_ipv6 = 0;
4880 u8 vrf_id_set = 0;
4881
4882 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4883 if (unformat (i, "vrf %d", &vrf_id))
4884 vrf_id_set = 1;
4885 else if (unformat (i, "ipv6"))
4886 is_ipv6 = 1;
4887 else {
4888 clib_warning ("parse error '%U'", format_unformat_error, i);
4889 return -99;
4890 }
4891 }
4892
4893 if (vrf_id_set == 0) {
4894 errmsg ("missing vrf id\n");
4895 return -99;
4896 }
4897
4898 M(RESET_FIB, reset_fib);
4899
4900 mp->vrf_id = ntohl(vrf_id);
4901 mp->is_ipv6 = is_ipv6;
4902
4903 S; W;
4904 /* NOTREACHED */
4905 return 0;
4906}
4907
4908static int api_dhcp_proxy_config (vat_main_t * vam)
4909{
4910 unformat_input_t * i = vam->input;
4911 vl_api_dhcp_proxy_config_t *mp;
4912 f64 timeout;
4913 u32 vrf_id = 0;
4914 u8 is_add = 1;
4915 u8 insert_cid = 1;
4916 u8 v4_address_set = 0;
4917 u8 v6_address_set = 0;
4918 ip4_address_t v4address;
4919 ip6_address_t v6address;
4920 u8 v4_src_address_set = 0;
4921 u8 v6_src_address_set = 0;
4922 ip4_address_t v4srcaddress;
4923 ip6_address_t v6srcaddress;
4924
4925 /* Parse args required to build the message */
4926 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4927 if (unformat (i, "del"))
4928 is_add = 0;
4929 else if (unformat (i, "vrf %d", &vrf_id))
4930 ;
4931 else if (unformat (i, "insert-cid %d", &insert_cid))
4932 ;
4933 else if (unformat (i, "svr %U",
4934 unformat_ip4_address, &v4address))
4935 v4_address_set = 1;
4936 else if (unformat (i, "svr %U",
4937 unformat_ip6_address, &v6address))
4938 v6_address_set = 1;
4939 else if (unformat (i, "src %U",
4940 unformat_ip4_address, &v4srcaddress))
4941 v4_src_address_set = 1;
4942 else if (unformat (i, "src %U",
4943 unformat_ip6_address, &v6srcaddress))
4944 v6_src_address_set = 1;
4945 else
4946 break;
4947 }
4948
4949 if (v4_address_set && v6_address_set) {
4950 errmsg ("both v4 and v6 server addresses set\n");
4951 return -99;
4952 }
4953 if (!v4_address_set && !v6_address_set) {
4954 errmsg ("no server addresses set\n");
4955 return -99;
4956 }
4957
4958 if (v4_src_address_set && v6_src_address_set) {
4959 errmsg ("both v4 and v6 src addresses set\n");
4960 return -99;
4961 }
4962 if (!v4_src_address_set && !v6_src_address_set) {
4963 errmsg ("no src addresses set\n");
4964 return -99;
4965 }
4966
4967 if (!(v4_src_address_set && v4_address_set) &&
4968 !(v6_src_address_set && v6_address_set)) {
4969 errmsg ("no matching server and src addresses set\n");
4970 return -99;
4971 }
4972
4973 /* Construct the API message */
4974 M(DHCP_PROXY_CONFIG, dhcp_proxy_config);
4975
4976 mp->insert_circuit_id = insert_cid;
4977 mp->is_add = is_add;
4978 mp->vrf_id = ntohl (vrf_id);
4979 if (v6_address_set) {
4980 mp->is_ipv6 = 1;
Damjan Marionf1213b82016-03-13 02:22:06 +01004981 clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
4982 clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004983 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01004984 clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
4985 clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004986 }
4987
4988 /* send it... */
4989 S;
4990
4991 /* Wait for a reply, return good/bad news */
4992 W;
4993 /* NOTREACHED */
4994 return 0;
4995}
4996
4997static int api_dhcp_proxy_config_2 (vat_main_t * vam)
4998{
4999 unformat_input_t * i = vam->input;
5000 vl_api_dhcp_proxy_config_2_t *mp;
5001 f64 timeout;
5002 u32 rx_vrf_id = 0;
5003 u32 server_vrf_id = 0;
5004 u8 is_add = 1;
5005 u8 insert_cid = 1;
5006 u8 v4_address_set = 0;
5007 u8 v6_address_set = 0;
5008 ip4_address_t v4address;
5009 ip6_address_t v6address;
5010 u8 v4_src_address_set = 0;
5011 u8 v6_src_address_set = 0;
5012 ip4_address_t v4srcaddress;
5013 ip6_address_t v6srcaddress;
5014
5015 /* Parse args required to build the message */
5016 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5017 if (unformat (i, "del"))
5018 is_add = 0;
5019 else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
5020 ;
5021 else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
5022 ;
5023 else if (unformat (i, "insert-cid %d", &insert_cid))
5024 ;
5025 else if (unformat (i, "svr %U",
5026 unformat_ip4_address, &v4address))
5027 v4_address_set = 1;
5028 else if (unformat (i, "svr %U",
5029 unformat_ip6_address, &v6address))
5030 v6_address_set = 1;
5031 else if (unformat (i, "src %U",
5032 unformat_ip4_address, &v4srcaddress))
5033 v4_src_address_set = 1;
5034 else if (unformat (i, "src %U",
5035 unformat_ip6_address, &v6srcaddress))
5036 v6_src_address_set = 1;
5037 else
5038 break;
5039 }
5040
5041 if (v4_address_set && v6_address_set) {
5042 errmsg ("both v4 and v6 server addresses set\n");
5043 return -99;
5044 }
5045 if (!v4_address_set && !v6_address_set) {
5046 errmsg ("no server addresses set\n");
5047 return -99;
5048 }
5049
5050 if (v4_src_address_set && v6_src_address_set) {
5051 errmsg ("both v4 and v6 src addresses set\n");
5052 return -99;
5053 }
5054 if (!v4_src_address_set && !v6_src_address_set) {
5055 errmsg ("no src addresses set\n");
5056 return -99;
5057 }
5058
5059 if (!(v4_src_address_set && v4_address_set) &&
5060 !(v6_src_address_set && v6_address_set)) {
5061 errmsg ("no matching server and src addresses set\n");
5062 return -99;
5063 }
5064
5065 /* Construct the API message */
5066 M(DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
5067
5068 mp->insert_circuit_id = insert_cid;
5069 mp->is_add = is_add;
5070 mp->rx_vrf_id = ntohl (rx_vrf_id);
5071 mp->server_vrf_id = ntohl (server_vrf_id);
5072 if (v6_address_set) {
5073 mp->is_ipv6 = 1;
Damjan Marionf1213b82016-03-13 02:22:06 +01005074 clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
5075 clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005076 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01005077 clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
5078 clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005079 }
5080
5081 /* send it... */
5082 S;
5083
5084 /* Wait for a reply, return good/bad news */
5085 W;
5086 /* NOTREACHED */
5087 return 0;
5088}
5089
5090static int api_dhcp_proxy_set_vss (vat_main_t * vam)
5091{
5092 unformat_input_t * i = vam->input;
5093 vl_api_dhcp_proxy_set_vss_t *mp;
5094 f64 timeout;
5095 u8 is_ipv6 = 0;
5096 u8 is_add = 1;
5097 u32 tbl_id;
5098 u8 tbl_id_set = 0;
5099 u32 oui;
5100 u8 oui_set = 0;
5101 u32 fib_id;
5102 u8 fib_id_set = 0;
5103
5104 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5105 if (unformat (i, "tbl_id %d", &tbl_id))
5106 tbl_id_set = 1;
5107 if (unformat (i, "fib_id %d", &fib_id))
5108 fib_id_set = 1;
5109 if (unformat (i, "oui %d", &oui))
5110 oui_set = 1;
5111 else if (unformat (i, "ipv6"))
5112 is_ipv6 = 1;
5113 else if (unformat (i, "del"))
5114 is_add = 0;
5115 else {
5116 clib_warning ("parse error '%U'", format_unformat_error, i);
5117 return -99;
5118 }
5119 }
5120
5121 if (tbl_id_set == 0) {
5122 errmsg ("missing tbl id\n");
5123 return -99;
5124 }
5125
5126 if (fib_id_set == 0) {
5127 errmsg ("missing fib id\n");
5128 return -99;
5129 }
5130 if (oui_set == 0) {
5131 errmsg ("missing oui\n");
5132 return -99;
5133 }
5134
5135 M(DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
5136 mp->tbl_id = ntohl(tbl_id);
5137 mp->fib_id = ntohl(fib_id);
5138 mp->oui = ntohl(oui);
5139 mp->is_ipv6 = is_ipv6;
5140 mp->is_add = is_add;
5141
5142 S; W;
5143 /* NOTREACHED */
5144 return 0;
5145}
5146
5147static int api_dhcp_client_config (vat_main_t * vam)
5148{
5149 unformat_input_t * i = vam->input;
5150 vl_api_dhcp_client_config_t *mp;
5151 f64 timeout;
5152 u32 sw_if_index;
5153 u8 sw_if_index_set = 0;
5154 u8 is_add = 1;
5155 u8 * hostname = 0;
5156 u8 disable_event = 0;
5157
5158 /* Parse args required to build the message */
5159 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5160 if (unformat (i, "del"))
5161 is_add = 0;
5162 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5163 sw_if_index_set = 1;
5164 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5165 sw_if_index_set = 1;
5166 else if (unformat (i, "hostname %s", &hostname))
5167 ;
5168 else if (unformat (i, "disable_event"))
5169 disable_event = 1;
5170 else
5171 break;
5172 }
5173
5174 if (sw_if_index_set == 0) {
5175 errmsg ("missing interface name or sw_if_index\n");
5176 return -99;
5177 }
5178
5179 if (vec_len (hostname) > 63) {
5180 errmsg ("hostname too long\n");
5181 }
5182 vec_add1 (hostname, 0);
5183
5184 /* Construct the API message */
5185 M(DHCP_CLIENT_CONFIG, dhcp_client_config);
5186
5187 mp->sw_if_index = ntohl (sw_if_index);
Damjan Marionf1213b82016-03-13 02:22:06 +01005188 clib_memcpy (mp->hostname, hostname, vec_len (hostname));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005189 vec_free (hostname);
5190 mp->is_add = is_add;
5191 mp->want_dhcp_event = disable_event ? 0 : 1;
5192 mp->pid = getpid();
5193
5194 /* send it... */
5195 S;
5196
5197 /* Wait for a reply, return good/bad news */
5198 W;
5199 /* NOTREACHED */
5200 return 0;
5201}
5202
5203static int api_set_ip_flow_hash (vat_main_t * vam)
5204{
5205 unformat_input_t * i = vam->input;
5206 vl_api_set_ip_flow_hash_t *mp;
5207 f64 timeout;
5208 u32 vrf_id = 0;
5209 u8 is_ipv6 = 0;
5210 u8 vrf_id_set = 0;
5211 u8 src = 0;
5212 u8 dst = 0;
5213 u8 sport = 0;
5214 u8 dport = 0;
5215 u8 proto = 0;
5216 u8 reverse = 0;
5217
5218 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5219 if (unformat (i, "vrf %d", &vrf_id))
5220 vrf_id_set = 1;
5221 else if (unformat (i, "ipv6"))
5222 is_ipv6 = 1;
5223 else if (unformat (i, "src"))
5224 src = 1;
5225 else if (unformat (i, "dst"))
5226 dst = 1;
5227 else if (unformat (i, "sport"))
5228 sport = 1;
5229 else if (unformat (i, "dport"))
5230 dport = 1;
5231 else if (unformat (i, "proto"))
5232 proto = 1;
5233 else if (unformat (i, "reverse"))
5234 reverse = 1;
5235
5236 else {
5237 clib_warning ("parse error '%U'", format_unformat_error, i);
5238 return -99;
5239 }
5240 }
5241
5242 if (vrf_id_set == 0) {
5243 errmsg ("missing vrf id\n");
5244 return -99;
5245 }
5246
5247 M(SET_IP_FLOW_HASH, set_ip_flow_hash);
5248 mp->src = src;
5249 mp->dst = dst;
5250 mp->sport = sport;
5251 mp->dport = dport;
5252 mp->proto = proto;
5253 mp->reverse = reverse;
5254 mp->vrf_id = ntohl(vrf_id);
5255 mp->is_ipv6 = is_ipv6;
5256
5257 S; W;
5258 /* NOTREACHED */
5259 return 0;
5260}
5261
5262static int api_sw_interface_ip6_enable_disable (vat_main_t * vam)
5263{
5264 unformat_input_t * i = vam->input;
5265 vl_api_sw_interface_ip6_enable_disable_t *mp;
5266 f64 timeout;
5267 u32 sw_if_index;
5268 u8 sw_if_index_set = 0;
5269 u8 enable = 0;
5270
5271 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5272 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5273 sw_if_index_set = 1;
5274 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5275 sw_if_index_set = 1;
5276 else if (unformat (i, "enable"))
5277 enable = 1;
5278 else if (unformat (i, "disable"))
5279 enable = 0;
5280 else {
5281 clib_warning ("parse error '%U'", format_unformat_error, i);
5282 return -99;
5283 }
5284 }
5285
5286 if (sw_if_index_set == 0) {
5287 errmsg ("missing interface name or sw_if_index\n");
5288 return -99;
5289 }
5290
5291 M(SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
5292
5293 mp->sw_if_index = ntohl(sw_if_index);
5294 mp->enable = enable;
5295
5296 S; W;
5297 /* NOTREACHED */
5298 return 0;
5299}
5300
5301static int api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
5302{
5303 unformat_input_t * i = vam->input;
5304 vl_api_sw_interface_ip6_set_link_local_address_t *mp;
5305 f64 timeout;
5306 u32 sw_if_index;
5307 u8 sw_if_index_set = 0;
5308 u32 address_length = 0;
5309 u8 v6_address_set = 0;
5310 ip6_address_t v6address;
5311
5312 /* Parse args required to build the message */
5313 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5314 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5315 sw_if_index_set = 1;
5316 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5317 sw_if_index_set = 1;
5318 else if (unformat (i, "%U/%d",
5319 unformat_ip6_address, &v6address,
5320 &address_length))
5321 v6_address_set = 1;
5322 else
5323 break;
5324 }
5325
5326 if (sw_if_index_set == 0) {
5327 errmsg ("missing interface name or sw_if_index\n");
5328 return -99;
5329 }
5330 if (!v6_address_set) {
5331 errmsg ("no address set\n");
5332 return -99;
5333 }
5334
5335 /* Construct the API message */
5336 M(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, \
5337 sw_interface_ip6_set_link_local_address);
5338
5339 mp->sw_if_index = ntohl (sw_if_index);
Damjan Marionf1213b82016-03-13 02:22:06 +01005340 clib_memcpy (mp->address, &v6address, sizeof (v6address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005341 mp->address_length = address_length;
5342
5343 /* send it... */
5344 S;
5345
5346 /* Wait for a reply, return good/bad news */
5347 W;
5348
5349 /* NOTREACHED */
5350 return 0;
5351}
5352
5353
5354static int api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
5355{
5356 unformat_input_t * i = vam->input;
5357 vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
5358 f64 timeout;
5359 u32 sw_if_index;
5360 u8 sw_if_index_set = 0;
5361 u32 address_length = 0;
5362 u8 v6_address_set = 0;
5363 ip6_address_t v6address;
5364 u8 use_default = 0;
5365 u8 no_advertise = 0;
5366 u8 off_link = 0;
5367 u8 no_autoconfig = 0;
5368 u8 no_onlink = 0;
5369 u8 is_no = 0;
5370 u32 val_lifetime = 0;
5371 u32 pref_lifetime = 0;
5372
5373 /* Parse args required to build the message */
5374 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5375 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5376 sw_if_index_set = 1;
5377 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5378 sw_if_index_set = 1;
5379 else if (unformat (i, "%U/%d",
5380 unformat_ip6_address, &v6address,
5381 &address_length))
5382 v6_address_set = 1;
5383 else if (unformat (i, "val_life %d", &val_lifetime))
5384 ;
5385 else if (unformat (i, "pref_life %d", &pref_lifetime))
5386 ;
5387 else if (unformat (i, "def"))
5388 use_default = 1;
5389 else if (unformat (i, "noadv"))
5390 no_advertise = 1;
5391 else if (unformat (i, "offl"))
5392 off_link = 1;
5393 else if (unformat (i, "noauto"))
5394 no_autoconfig = 1;
5395 else if (unformat (i, "nolink"))
5396 no_onlink = 1;
5397 else if (unformat (i, "isno"))
5398 is_no = 1;
5399 else {
5400 clib_warning ("parse error '%U'", format_unformat_error, i);
5401 return -99;
5402 }
5403 }
5404
5405 if (sw_if_index_set == 0) {
5406 errmsg ("missing interface name or sw_if_index\n");
5407 return -99;
5408 }
5409 if (!v6_address_set) {
5410 errmsg ("no address set\n");
5411 return -99;
5412 }
5413
5414 /* Construct the API message */
5415 M(SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
5416
5417 mp->sw_if_index = ntohl (sw_if_index);
Damjan Marionf1213b82016-03-13 02:22:06 +01005418 clib_memcpy (mp->address, &v6address, sizeof (v6address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005419 mp->address_length = address_length;
5420 mp->use_default = use_default;
5421 mp->no_advertise = no_advertise;
5422 mp->off_link = off_link;
5423 mp->no_autoconfig = no_autoconfig;
5424 mp->no_onlink = no_onlink;
5425 mp->is_no = is_no;
5426 mp->val_lifetime = ntohl(val_lifetime);
5427 mp->pref_lifetime = ntohl(pref_lifetime);
5428
5429 /* send it... */
5430 S;
5431
5432 /* Wait for a reply, return good/bad news */
5433 W;
5434
5435 /* NOTREACHED */
5436 return 0;
5437}
5438
5439static int api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
5440{
5441 unformat_input_t * i = vam->input;
5442 vl_api_sw_interface_ip6nd_ra_config_t *mp;
5443 f64 timeout;
5444 u32 sw_if_index;
5445 u8 sw_if_index_set = 0;
5446 u8 surpress = 0;
5447 u8 managed = 0;
5448 u8 other = 0;
5449 u8 ll_option = 0;
5450 u8 send_unicast = 0;
5451 u8 cease = 0;
5452 u8 is_no = 0;
5453 u8 default_router = 0;
5454 u32 max_interval = 0;
5455 u32 min_interval = 0;
5456 u32 lifetime = 0;
5457 u32 initial_count = 0;
5458 u32 initial_interval = 0;
5459
5460
5461 /* Parse args required to build the message */
5462 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5463 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5464 sw_if_index_set = 1;
5465 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5466 sw_if_index_set = 1;
5467 else if (unformat (i, "maxint %d", &max_interval))
5468 ;
5469 else if (unformat (i, "minint %d", &min_interval))
5470 ;
5471 else if (unformat (i, "life %d", &lifetime))
5472 ;
5473 else if (unformat (i, "count %d", &initial_count))
5474 ;
5475 else if (unformat (i, "interval %d", &initial_interval))
5476 ;
5477 else if (unformat (i, "surpress"))
5478 surpress = 1;
5479 else if (unformat (i, "managed"))
5480 managed = 1;
5481 else if (unformat (i, "other"))
5482 other = 1;
5483 else if (unformat (i, "ll"))
5484 ll_option = 1;
5485 else if (unformat (i, "send"))
5486 send_unicast = 1;
5487 else if (unformat (i, "cease"))
5488 cease = 1;
5489 else if (unformat (i, "isno"))
5490 is_no = 1;
5491 else if (unformat (i, "def"))
5492 default_router = 1;
5493 else {
5494 clib_warning ("parse error '%U'", format_unformat_error, i);
5495 return -99;
5496 }
5497 }
5498
5499 if (sw_if_index_set == 0) {
5500 errmsg ("missing interface name or sw_if_index\n");
5501 return -99;
5502 }
5503
5504 /* Construct the API message */
5505 M(SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
5506
5507 mp->sw_if_index = ntohl (sw_if_index);
5508 mp->max_interval = ntohl(max_interval);
5509 mp->min_interval = ntohl(min_interval);
5510 mp->lifetime = ntohl(lifetime);
5511 mp->initial_count = ntohl(initial_count);
5512 mp->initial_interval = ntohl(initial_interval);
5513 mp->surpress = surpress;
5514 mp->managed = managed;
5515 mp->other = other;
5516 mp->ll_option = ll_option;
5517 mp->send_unicast = send_unicast;
5518 mp->cease = cease;
5519 mp->is_no = is_no;
5520 mp->default_router = default_router;
5521
5522 /* send it... */
5523 S;
5524
5525 /* Wait for a reply, return good/bad news */
5526 W;
5527
5528 /* NOTREACHED */
5529 return 0;
5530}
5531
5532static int api_set_arp_neighbor_limit (vat_main_t * vam)
5533{
5534 unformat_input_t * i = vam->input;
5535 vl_api_set_arp_neighbor_limit_t *mp;
5536 f64 timeout;
5537 u32 arp_nbr_limit;
5538 u8 limit_set = 0;
5539 u8 is_ipv6 = 0;
5540
5541 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5542 if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
5543 limit_set = 1;
5544 else if (unformat (i, "ipv6"))
5545 is_ipv6 = 1;
5546 else {
5547 clib_warning ("parse error '%U'", format_unformat_error, i);
5548 return -99;
5549 }
5550 }
5551
5552 if (limit_set == 0) {
5553 errmsg ("missing limit value\n");
5554 return -99;
5555 }
5556
5557 M(SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
5558
5559 mp->arp_neighbor_limit = ntohl(arp_nbr_limit);
5560 mp->is_ipv6 = is_ipv6;
5561
5562 S; W;
5563 /* NOTREACHED */
5564 return 0;
5565}
5566
5567static int api_l2_patch_add_del (vat_main_t * vam)
5568{
5569 unformat_input_t * i = vam->input;
5570 vl_api_l2_patch_add_del_t *mp;
5571 f64 timeout;
5572 u32 rx_sw_if_index;
5573 u8 rx_sw_if_index_set = 0;
5574 u32 tx_sw_if_index;
5575 u8 tx_sw_if_index_set = 0;
5576 u8 is_add = 1;
5577
5578 /* Parse args required to build the message */
5579 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5580 if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5581 rx_sw_if_index_set = 1;
5582 else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5583 tx_sw_if_index_set = 1;
5584 else if (unformat (i, "rx")) {
5585 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5586 if (unformat (i, "%U", unformat_sw_if_index, vam,
5587 &rx_sw_if_index))
5588 rx_sw_if_index_set = 1;
5589 } else
5590 break;
5591 } else if (unformat (i, "tx")) {
5592 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5593 if (unformat (i, "%U", unformat_sw_if_index, vam,
5594 &tx_sw_if_index))
5595 tx_sw_if_index_set = 1;
5596 } else
5597 break;
5598 } else if (unformat (i, "del"))
5599 is_add = 0;
5600 else
5601 break;
5602 }
5603
5604 if (rx_sw_if_index_set == 0) {
5605 errmsg ("missing rx interface name or rx_sw_if_index\n");
5606 return -99;
5607 }
5608
5609 if (tx_sw_if_index_set == 0) {
5610 errmsg ("missing tx interface name or tx_sw_if_index\n");
5611 return -99;
5612 }
5613
5614 M(L2_PATCH_ADD_DEL, l2_patch_add_del);
5615
5616 mp->rx_sw_if_index = ntohl(rx_sw_if_index);
5617 mp->tx_sw_if_index = ntohl(tx_sw_if_index);
5618 mp->is_add = is_add;
5619
5620 S; W;
5621 /* NOTREACHED */
5622 return 0;
5623}
Shwetha20a64f52016-03-25 10:55:01 +00005624static int api_trace_profile_add (vat_main_t *vam)
5625{
5626 unformat_input_t * input = vam->input;
5627 vl_api_trace_profile_add_t *mp;
5628 f64 timeout;
5629 u32 id = 0;
5630 u32 trace_option_elts = 0;
5631 u32 trace_type = 0, node_id = 0, app_data = 0, trace_tsp = 2;
5632 int has_pow_option = 0;
5633 int has_ppc_option = 0;
5634
5635 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5636 {
5637 if (unformat (input, "id %d trace-type 0x%x trace-elts %d "
5638 "trace-tsp %d node-id 0x%x app-data 0x%x",
5639 &id, &trace_type, &trace_option_elts, &trace_tsp,
5640 &node_id, &app_data))
5641 ;
5642 else if (unformat (input, "pow"))
5643 has_pow_option = 1;
5644 else if (unformat (input, "ppc encap"))
5645 has_ppc_option = PPC_ENCAP;
5646 else if (unformat (input, "ppc decap"))
5647 has_ppc_option = PPC_DECAP;
5648 else if (unformat (input, "ppc none"))
5649 has_ppc_option = PPC_NONE;
5650 else
5651 break;
5652 }
5653 M(TRACE_PROFILE_ADD, trace_profile_add);
5654 mp->id = htons(id);
5655 mp->trace_type = trace_type;
5656 mp->trace_num_elt = trace_option_elts;
5657 mp->trace_ppc = has_ppc_option;
5658 mp->trace_app_data = htonl(app_data);
5659 mp->pow_enable = has_pow_option;
5660 mp->trace_tsp = trace_tsp;
5661 mp->node_id = htonl(node_id);
5662
5663 S; W;
5664
5665 return(0);
5666
5667}
5668static int api_trace_profile_apply (vat_main_t *vam)
5669{
5670 unformat_input_t * input = vam->input;
5671 vl_api_trace_profile_apply_t *mp;
5672 f64 timeout;
5673 ip6_address_t addr;
5674 u32 mask_width = ~0;
5675 int is_add = 0;
5676 int is_pop = 0;
5677 int is_none = 0;
5678 u32 vrf_id = 0;
5679 u32 id = 0;
5680
5681 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5682 {
5683 if (unformat (input, "%U/%d",
5684 unformat_ip6_address, &addr, &mask_width))
5685 ;
5686 else if (unformat (input, "id %d", &id))
5687 ;
5688 else if (unformat (input, "vrf-id %d", &vrf_id))
5689 ;
5690 else if (unformat (input, "add"))
5691 is_add = 1;
5692 else if (unformat (input, "pop"))
5693 is_pop = 1;
5694 else if (unformat (input, "none"))
5695 is_none = 1;
5696 else
5697 break;
5698 }
Ed Warnickecb9cada2015-12-08 15:45:58 -07005699
Shwetha20a64f52016-03-25 10:55:01 +00005700 if ((is_add + is_pop + is_none) != 1) {
5701 errmsg("One of (add, pop, none) required");
5702 return -99;
5703 }
5704 if (mask_width == ~0) {
5705 errmsg("<address>/<mask-width> required");
5706 return -99;
5707 }
5708 M(TRACE_PROFILE_APPLY, trace_profile_apply);
Damjan Marionf1213b82016-03-13 02:22:06 +01005709 clib_memcpy(mp->dest_ipv6, &addr, sizeof(mp->dest_ipv6));
Shwetha20a64f52016-03-25 10:55:01 +00005710 mp->id = htons(id);
5711 mp->prefix_length = htonl(mask_width);
5712 mp->vrf_id = htonl(vrf_id);
5713 if (is_add)
5714 mp->trace_op = IOAM_HBYH_ADD;
5715 else if (is_pop)
5716 mp->trace_op = IOAM_HBYH_POP;
5717 else
5718 mp->trace_op = IOAM_HBYH_MOD;
5719
5720 if(is_none)
5721 mp->enable = 0;
5722 else
5723 mp->enable = 1;
5724
5725 S; W;
5726
5727 return 0;
5728}
5729
5730static int api_trace_profile_del (vat_main_t *vam)
5731{
5732 vl_api_trace_profile_del_t *mp;
5733 f64 timeout;
5734
5735 M(TRACE_PROFILE_DEL, trace_profile_del);
5736 S; W;
5737 return 0;
5738}
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07005739
Ed Warnickecb9cada2015-12-08 15:45:58 -07005740static int api_sr_tunnel_add_del (vat_main_t * vam)
5741{
5742 unformat_input_t * i = vam->input;
5743 vl_api_sr_tunnel_add_del_t *mp;
5744 f64 timeout;
5745 int is_del = 0;
5746 int pl_index;
5747 ip6_address_t src_address;
5748 int src_address_set = 0;
5749 ip6_address_t dst_address;
5750 u32 dst_mask_width;
5751 int dst_address_set = 0;
5752 u16 flags = 0;
5753 u32 rx_table_id = 0;
5754 u32 tx_table_id = 0;
5755 ip6_address_t * segments = 0;
5756 ip6_address_t * this_seg;
5757 ip6_address_t * tags = 0;
5758 ip6_address_t * this_tag;
5759 ip6_address_t next_address, tag;
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07005760 u8 * name = 0;
5761 u8 * policy_name = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -07005762
5763 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5764 {
5765 if (unformat (i, "del"))
5766 is_del = 1;
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07005767 else if (unformat (i, "name %s", &name))
5768 ;
5769 else if (unformat (i, "policy %s", &policy_name))
5770 ;
Ed Warnickecb9cada2015-12-08 15:45:58 -07005771 else if (unformat (i, "rx_fib_id %d", &rx_table_id))
5772 ;
5773 else if (unformat (i, "tx_fib_id %d", &tx_table_id))
5774 ;
5775 else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
5776 src_address_set = 1;
5777 else if (unformat (i, "dst %U/%d",
5778 unformat_ip6_address, &dst_address,
5779 &dst_mask_width))
5780 dst_address_set = 1;
5781 else if (unformat (i, "next %U", unformat_ip6_address,
5782 &next_address))
5783 {
5784 vec_add2 (segments, this_seg, 1);
Damjan Marionf1213b82016-03-13 02:22:06 +01005785 clib_memcpy (this_seg->as_u8, next_address.as_u8, sizeof (*this_seg));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005786 }
5787 else if (unformat (i, "tag %U", unformat_ip6_address,
5788 &tag))
5789 {
5790 vec_add2 (tags, this_tag, 1);
Damjan Marionf1213b82016-03-13 02:22:06 +01005791 clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005792 }
5793 else if (unformat (i, "clean"))
5794 flags |= IP6_SR_HEADER_FLAG_CLEANUP;
5795 else if (unformat (i, "protected"))
5796 flags |= IP6_SR_HEADER_FLAG_PROTECTED;
5797 else if (unformat (i, "InPE %d", &pl_index))
5798 {
5799 if (pl_index <= 0 || pl_index > 4)
5800 {
5801 pl_index_range_error:
5802 errmsg ("pl index %d out of range\n", pl_index);
5803 return -99;
5804 }
5805 flags |= IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3*(pl_index - 1));
5806 }
5807 else if (unformat (i, "EgPE %d", &pl_index))
5808 {
5809 if (pl_index <= 0 || pl_index > 4)
5810 goto pl_index_range_error;
5811 flags |= IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3*(pl_index - 1));
5812 }
5813 else if (unformat (i, "OrgSrc %d", &pl_index))
5814 {
5815 if (pl_index <= 0 || pl_index > 4)
5816 goto pl_index_range_error;
5817 flags |= IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3*(pl_index - 1));
5818 }
5819 else
5820 break;
5821 }
5822
5823 if (!src_address_set)
5824 {
5825 errmsg ("src address required\n");
5826 return -99;
5827 }
5828
5829 if (!dst_address_set)
5830 {
5831 errmsg ("dst address required\n");
5832 return -99;
5833 }
5834
5835 if (!segments)
5836 {
5837 errmsg ("at least one sr segment required\n");
5838 return -99;
5839 }
5840
5841 M2(SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
5842 vec_len(segments) * sizeof (ip6_address_t)
5843 + vec_len(tags) * sizeof (ip6_address_t));
5844
Damjan Marionf1213b82016-03-13 02:22:06 +01005845 clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
5846 clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005847 mp->dst_mask_width = dst_mask_width;
5848 mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
5849 mp->n_segments = vec_len (segments);
5850 mp->n_tags = vec_len (tags);
5851 mp->is_add = is_del == 0;
Damjan Marionf1213b82016-03-13 02:22:06 +01005852 clib_memcpy (mp->segs_and_tags, segments,
Ed Warnickecb9cada2015-12-08 15:45:58 -07005853 vec_len(segments)* sizeof (ip6_address_t));
Damjan Marionf1213b82016-03-13 02:22:06 +01005854 clib_memcpy (mp->segs_and_tags + vec_len(segments)*sizeof (ip6_address_t),
Ed Warnickecb9cada2015-12-08 15:45:58 -07005855 tags, vec_len(tags)* sizeof (ip6_address_t));
5856
5857 mp->outer_vrf_id = ntohl (rx_table_id);
5858 mp->inner_vrf_id = ntohl (tx_table_id);
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07005859 memcpy (mp->name, name, vec_len(name));
5860 memcpy (mp->policy_name, policy_name, vec_len(policy_name));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005861
5862 vec_free (segments);
5863 vec_free (tags);
5864
5865 S; W;
5866 /* NOTREACHED */
5867}
5868
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07005869static int api_sr_policy_add_del (vat_main_t * vam)
5870{
5871 unformat_input_t * input = vam->input;
5872 vl_api_sr_policy_add_del_t *mp;
5873 f64 timeout;
5874 int is_del = 0;
5875 u8 * name = 0;
5876 u8 * tunnel_name = 0;
5877 u8 ** tunnel_names = 0;
5878
5879 int name_set = 0 ;
5880 int tunnel_set = 0;
5881 int j = 0;
5882 int tunnel_names_length = 1; // Init to 1 to offset the #tunnel_names counter byte
5883 int tun_name_len = 0; // Different naming convention used as confusing these would be "bad" (TM)
5884
5885 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5886 {
5887 if (unformat (input, "del"))
5888 is_del = 1;
5889 else if (unformat (input, "name %s", &name))
5890 name_set = 1;
5891 else if (unformat (input, "tunnel %s", &tunnel_name))
5892 {
5893 if (tunnel_name)
5894 {
5895 vec_add1 (tunnel_names, tunnel_name);
5896 /* For serializer:
5897 - length = #bytes to store in serial vector
5898 - +1 = byte to store that length
5899 */
5900 tunnel_names_length += (vec_len (tunnel_name) + 1);
5901 tunnel_set = 1;
5902 tunnel_name = 0;
5903 }
5904 }
5905 else
5906 break;
5907 }
5908
5909 if (!name_set)
5910 {
5911 errmsg ("policy name required\n");
5912 return -99;
5913 }
5914
5915 if ((!tunnel_set) && (!is_del))
5916 {
5917 errmsg ("tunnel name required\n");
5918 return -99;
5919 }
5920
5921 M2(SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
5922
5923
5924
5925 mp->is_add = !is_del;
5926
5927 memcpy (mp->name, name, vec_len(name));
5928 // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
5929 u8 * serial_orig = 0;
5930 vec_validate (serial_orig, tunnel_names_length);
5931 *serial_orig = vec_len(tunnel_names); // Store the number of tunnels as length in first byte of serialized vector
5932 serial_orig += 1; // Move along one byte to store the length of first tunnel_name
5933
5934 for (j=0; j < vec_len(tunnel_names); j++)
5935 {
5936 tun_name_len = vec_len (tunnel_names[j]);
5937 *serial_orig = tun_name_len; // Store length of tunnel name in first byte of Length/Value pair
5938 serial_orig += 1; // Move along one byte to store the actual tunnel name
5939 memcpy (serial_orig, tunnel_names[j], tun_name_len);
5940 serial_orig += tun_name_len; // Advance past the copy
5941 }
5942 memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length); // Regress serial_orig to head then copy fwd
5943
5944 vec_free (tunnel_names);
5945 vec_free (tunnel_name);
5946
5947 S; W;
5948 /* NOTREACHED */
5949}
5950
5951static int api_sr_multicast_map_add_del (vat_main_t * vam)
5952{
5953 unformat_input_t * input = vam->input;
5954 vl_api_sr_multicast_map_add_del_t *mp;
5955 f64 timeout;
5956 int is_del = 0;
5957 ip6_address_t multicast_address;
5958 u8 * policy_name = 0;
5959 int multicast_address_set = 0;
5960
5961 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5962 {
5963 if (unformat (input, "del"))
5964 is_del = 1;
5965 else if (unformat (input, "address %U", unformat_ip6_address, &multicast_address))
5966 multicast_address_set = 1;
5967 else if (unformat (input, "sr-policy %s", &policy_name))
5968 ;
5969 else
5970 break;
5971 }
5972
5973 if (!is_del && !policy_name)
5974 {
5975 errmsg ("sr-policy name required\n");
5976 return -99;
5977 }
5978
5979
5980 if (!multicast_address_set)
5981 {
5982 errmsg ("address required\n");
5983 return -99;
5984 }
5985
5986 M(SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
5987
5988 mp->is_add = !is_del;
5989 memcpy (mp->policy_name, policy_name, vec_len(policy_name));
5990 clib_memcpy (mp->multicast_address, &multicast_address, sizeof (mp->multicast_address));
5991
5992
5993 vec_free (policy_name);
5994
5995 S; W;
5996 /* NOTREACHED */
5997}
5998
Ed Warnickecb9cada2015-12-08 15:45:58 -07005999
6000#define foreach_ip4_proto_field \
6001_(src_address) \
6002_(dst_address) \
6003_(tos) \
6004_(length) \
6005_(fragment_id) \
6006_(ttl) \
6007_(protocol) \
6008_(checksum)
6009
6010uword unformat_ip4_mask (unformat_input_t * input, va_list * args)
6011{
6012 u8 ** maskp = va_arg (*args, u8 **);
6013 u8 * mask = 0;
6014 u8 found_something = 0;
6015 ip4_header_t * ip;
6016
6017#define _(a) u8 a=0;
6018 foreach_ip4_proto_field;
6019#undef _
6020 u8 version = 0;
6021 u8 hdr_length = 0;
6022
6023
6024 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
6025 {
6026 if (unformat (input, "version"))
6027 version = 1;
6028 else if (unformat (input, "hdr_length"))
6029 hdr_length = 1;
6030 else if (unformat (input, "src"))
6031 src_address = 1;
6032 else if (unformat (input, "dst"))
6033 dst_address = 1;
6034 else if (unformat (input, "proto"))
6035 protocol = 1;
6036
6037#define _(a) else if (unformat (input, #a)) a=1;
6038 foreach_ip4_proto_field
6039#undef _
6040 else
6041 break;
6042 }
6043
6044#define _(a) found_something += a;
6045 foreach_ip4_proto_field;
6046#undef _
6047
6048 if (found_something == 0)
6049 return 0;
6050
6051 vec_validate (mask, sizeof (*ip) - 1);
6052
6053 ip = (ip4_header_t *) mask;
6054
6055#define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
6056 foreach_ip4_proto_field;
6057#undef _
6058
6059 ip->ip_version_and_header_length = 0;
6060
6061 if (version)
6062 ip->ip_version_and_header_length |= 0xF0;
6063
6064 if (hdr_length)
6065 ip->ip_version_and_header_length |= 0x0F;
6066
6067 *maskp = mask;
6068 return 1;
6069}
6070
6071#define foreach_ip6_proto_field \
6072_(src_address) \
6073_(dst_address) \
6074_(payload_length) \
6075_(hop_limit) \
6076_(protocol)
6077
6078uword unformat_ip6_mask (unformat_input_t * input, va_list * args)
6079{
6080 u8 ** maskp = va_arg (*args, u8 **);
6081 u8 * mask = 0;
6082 u8 found_something = 0;
6083 ip6_header_t * ip;
6084 u32 ip_version_traffic_class_and_flow_label;
6085
6086#define _(a) u8 a=0;
6087 foreach_ip6_proto_field;
6088#undef _
6089 u8 version = 0;
6090 u8 traffic_class = 0;
6091 u8 flow_label = 0;
6092
6093 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
6094 {
6095 if (unformat (input, "version"))
6096 version = 1;
6097 else if (unformat (input, "traffic-class"))
6098 traffic_class = 1;
6099 else if (unformat (input, "flow-label"))
6100 flow_label = 1;
6101 else if (unformat (input, "src"))
6102 src_address = 1;
6103 else if (unformat (input, "dst"))
6104 dst_address = 1;
6105 else if (unformat (input, "proto"))
6106 protocol = 1;
6107
6108#define _(a) else if (unformat (input, #a)) a=1;
6109 foreach_ip6_proto_field
6110#undef _
6111 else
6112 break;
6113 }
6114
6115#define _(a) found_something += a;
6116 foreach_ip6_proto_field;
6117#undef _
6118
6119 if (found_something == 0)
6120 return 0;
6121
6122 vec_validate (mask, sizeof (*ip) - 1);
6123
6124 ip = (ip6_header_t *) mask;
6125
6126#define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
6127 foreach_ip6_proto_field;
6128#undef _
6129
6130 ip_version_traffic_class_and_flow_label = 0;
6131
6132 if (version)
6133 ip_version_traffic_class_and_flow_label |= 0xF0000000;
6134
6135 if (traffic_class)
6136 ip_version_traffic_class_and_flow_label |= 0x0FF00000;
6137
6138 if (flow_label)
6139 ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
6140
6141 ip->ip_version_traffic_class_and_flow_label =
6142 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
6143
6144 *maskp = mask;
6145 return 1;
6146}
6147
6148uword unformat_l3_mask (unformat_input_t * input, va_list * args)
6149{
6150 u8 ** maskp = va_arg (*args, u8 **);
6151
6152 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
6153 if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
6154 return 1;
6155 else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
6156 return 1;
6157 else
6158 break;
6159 }
6160 return 0;
6161}
6162
6163uword unformat_l2_mask (unformat_input_t * input, va_list * args)
6164{
6165 u8 ** maskp = va_arg (*args, u8 **);
6166 u8 * mask = 0;
6167 u8 src = 0;
6168 u8 dst = 0;
6169 u8 proto = 0;
6170 u8 tag1 = 0;
6171 u8 tag2 = 0;
6172 u8 ignore_tag1 = 0;
6173 u8 ignore_tag2 = 0;
6174 u8 cos1 = 0;
6175 u8 cos2 = 0;
6176 u8 dot1q = 0;
6177 u8 dot1ad = 0;
6178 int len = 14;
6179
6180 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
6181 if (unformat (input, "src"))
6182 src = 1;
6183 else if (unformat (input, "dst"))
6184 dst = 1;
6185 else if (unformat (input, "proto"))
6186 proto = 1;
6187 else if (unformat (input, "tag1"))
6188 tag1 = 1;
6189 else if (unformat (input, "tag2"))
6190 tag2 = 1;
6191 else if (unformat (input, "ignore-tag1"))
6192 ignore_tag1 = 1;
6193 else if (unformat (input, "ignore-tag2"))
6194 ignore_tag2 = 1;
6195 else if (unformat (input, "cos1"))
6196 cos1 = 1;
6197 else if (unformat (input, "cos2"))
6198 cos2 = 1;
6199 else if (unformat (input, "dot1q"))
6200 dot1q = 1;
6201 else if (unformat (input, "dot1ad"))
6202 dot1ad = 1;
6203 else
6204 break;
6205 }
6206 if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
6207 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
6208 return 0;
6209
6210 if (tag1 || ignore_tag1 || cos1 || dot1q)
6211 len = 18;
6212 if (tag2 || ignore_tag2 || cos2 || dot1ad)
6213 len = 22;
6214
6215 vec_validate (mask, len-1);
6216
6217 if (dst)
6218 memset (mask, 0xff, 6);
6219
6220 if (src)
6221 memset (mask + 6, 0xff, 6);
6222
6223 if (tag2 || dot1ad)
6224 {
6225 /* inner vlan tag */
6226 if (tag2)
6227 {
6228 mask[19] = 0xff;
6229 mask[18] = 0x0f;
6230 }
6231 if (cos2)
6232 mask[18] |= 0xe0;
6233 if (proto)
6234 mask[21] = mask [20] = 0xff;
6235 if (tag1)
6236 {
6237 mask [15] = 0xff;
6238 mask [14] = 0x0f;
6239 }
6240 if (cos1)
6241 mask[14] |= 0xe0;
6242 *maskp = mask;
6243 return 1;
6244 }
6245 if (tag1 | dot1q)
6246 {
6247 if (tag1)
6248 {
6249 mask [15] = 0xff;
6250 mask [14] = 0x0f;
6251 }
6252 if (cos1)
6253 mask[14] |= 0xe0;
6254 if (proto)
6255 mask[16] = mask [17] = 0xff;
6256
6257 *maskp = mask;
6258 return 1;
6259 }
6260 if (cos2)
6261 mask[18] |= 0xe0;
6262 if (cos1)
6263 mask[14] |= 0xe0;
6264 if (proto)
6265 mask[12] = mask [13] = 0xff;
6266
6267 *maskp = mask;
6268 return 1;
6269}
6270
6271uword unformat_classify_mask (unformat_input_t * input, va_list * args)
6272{
6273 u8 ** maskp = va_arg (*args, u8 **);
6274 u32 * skipp = va_arg (*args, u32 *);
6275 u32 * matchp = va_arg (*args, u32 *);
6276 u32 match;
6277 u8 * mask = 0;
6278 u8 * l2 = 0;
6279 u8 * l3 = 0;
6280 int i;
6281
6282 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
6283 if (unformat (input, "hex %U", unformat_hex_string, &mask))
6284 ;
6285 else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
6286 ;
6287 else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
6288 ;
6289 else
6290 break;
6291 }
6292
6293 if (mask || l2 || l3)
6294 {
6295 if (l2 || l3)
6296 {
6297 /* "With a free Ethernet header in every package" */
6298 if (l2 == 0)
6299 vec_validate (l2, 13);
6300 mask = l2;
6301 vec_append (mask, l3);
6302 vec_free (l3);
6303 }
6304
6305 /* Scan forward looking for the first significant mask octet */
6306 for (i = 0; i < vec_len (mask); i++)
6307 if (mask[i])
6308 break;
6309
6310 /* compute (skip, match) params */
6311 *skipp = i / sizeof(u32x4);
6312 vec_delete (mask, *skipp * sizeof(u32x4), 0);
6313
6314 /* Pad mask to an even multiple of the vector size */
6315 while (vec_len (mask) % sizeof (u32x4))
6316 vec_add1 (mask, 0);
6317
6318 match = vec_len (mask) / sizeof (u32x4);
6319
6320 for (i = match*sizeof(u32x4); i > 0; i-= sizeof(u32x4))
6321 {
6322 u64 *tmp = (u64 *)(mask + (i-sizeof(u32x4)));
6323 if (*tmp || *(tmp+1))
6324 break;
6325 match--;
6326 }
6327 if (match == 0)
6328 clib_warning ("BUG: match 0");
6329
6330 _vec_len (mask) = match * sizeof(u32x4);
6331
6332 *matchp = match;
6333 *maskp = mask;
6334
6335 return 1;
6336 }
6337
6338 return 0;
6339}
6340
6341#define foreach_l2_next \
6342_(drop, DROP) \
6343_(ethernet, ETHERNET_INPUT) \
6344_(ip4, IP4_INPUT) \
6345_(ip6, IP6_INPUT)
6346
6347uword unformat_l2_next_index (unformat_input_t * input, va_list * args)
6348{
6349 u32 * miss_next_indexp = va_arg (*args, u32 *);
6350 u32 next_index = 0;
6351 u32 tmp;
6352
6353#define _(n,N) \
6354 if (unformat (input, #n)) { next_index = L2_CLASSIFY_NEXT_##N; goto out;}
6355 foreach_l2_next;
6356#undef _
6357
6358 if (unformat (input, "%d", &tmp))
6359 {
6360 next_index = tmp;
6361 goto out;
6362 }
6363
6364 return 0;
6365
6366 out:
6367 *miss_next_indexp = next_index;
6368 return 1;
6369}
6370
6371#define foreach_ip_next \
6372_(miss, MISS) \
6373_(drop, DROP) \
6374_(local, LOCAL) \
6375_(rewrite, REWRITE)
6376
6377uword unformat_ip_next_index (unformat_input_t * input, va_list * args)
6378{
6379 u32 * miss_next_indexp = va_arg (*args, u32 *);
6380 u32 next_index = 0;
6381 u32 tmp;
6382
6383#define _(n,N) \
6384 if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
6385 foreach_ip_next;
6386#undef _
6387
6388 if (unformat (input, "%d", &tmp))
6389 {
6390 next_index = tmp;
6391 goto out;
6392 }
6393
6394 return 0;
6395
6396 out:
6397 *miss_next_indexp = next_index;
6398 return 1;
6399}
6400
6401#define foreach_acl_next \
6402_(deny, DENY)
6403
6404uword unformat_acl_next_index (unformat_input_t * input, va_list * args)
6405{
6406 u32 * miss_next_indexp = va_arg (*args, u32 *);
6407 u32 next_index = 0;
6408 u32 tmp;
6409
6410#define _(n,N) \
6411 if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
6412 foreach_acl_next;
6413#undef _
6414
6415 if (unformat (input, "permit"))
6416 {
6417 next_index = ~0;
6418 goto out;
6419 }
6420 else if (unformat (input, "%d", &tmp))
6421 {
6422 next_index = tmp;
6423 goto out;
6424 }
6425
6426 return 0;
6427
6428 out:
6429 *miss_next_indexp = next_index;
6430 return 1;
6431}
6432
6433static int api_classify_add_del_table (vat_main_t * vam)
6434{
6435 unformat_input_t * i = vam->input;
6436 vl_api_classify_add_del_table_t *mp;
6437
6438 u32 nbuckets = 2;
6439 u32 skip = ~0;
6440 u32 match = ~0;
6441 int is_add = 1;
6442 u32 table_index = ~0;
6443 u32 next_table_index = ~0;
6444 u32 miss_next_index = ~0;
6445 u32 memory_size = 32<<20;
6446 u8 * mask = 0;
6447 f64 timeout;
6448
6449 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6450 if (unformat (i, "del"))
6451 is_add = 0;
6452 else if (unformat (i, "buckets %d", &nbuckets))
6453 ;
6454 else if (unformat (i, "memory_size %d", &memory_size))
6455 ;
6456 else if (unformat (i, "skip %d", &skip))
6457 ;
6458 else if (unformat (i, "match %d", &match))
6459 ;
6460 else if (unformat (i, "table %d", &table_index))
6461 ;
6462 else if (unformat (i, "mask %U", unformat_classify_mask,
6463 &mask, &skip, &match))
6464 ;
6465 else if (unformat (i, "next-table %d", &next_table_index))
6466 ;
6467 else if (unformat (i, "miss-next %U", unformat_ip_next_index,
6468 &miss_next_index))
6469 ;
6470 else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
6471 &miss_next_index))
6472 ;
6473 else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
6474 &miss_next_index))
6475 ;
6476 else
6477 break;
6478 }
6479
6480 if (is_add && mask == 0) {
6481 errmsg ("Mask required\n");
6482 return -99;
6483 }
6484
6485 if (is_add && skip == ~0) {
6486 errmsg ("skip count required\n");
6487 return -99;
6488 }
6489
6490 if (is_add && match == ~0) {
6491 errmsg ("match count required\n");
6492 return -99;
6493 }
6494
6495 if (!is_add && table_index == ~0) {
6496 errmsg ("table index required for delete\n");
6497 return -99;
6498 }
6499
6500 M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table,
6501 vec_len(mask));
6502
6503 mp->is_add = is_add;
6504 mp->table_index = ntohl(table_index);
6505 mp->nbuckets = ntohl(nbuckets);
6506 mp->memory_size = ntohl(memory_size);
6507 mp->skip_n_vectors = ntohl(skip);
6508 mp->match_n_vectors = ntohl(match);
6509 mp->next_table_index = ntohl(next_table_index);
6510 mp->miss_next_index = ntohl(miss_next_index);
Damjan Marionf1213b82016-03-13 02:22:06 +01006511 clib_memcpy (mp->mask, mask, vec_len(mask));
Ed Warnickecb9cada2015-12-08 15:45:58 -07006512
6513 vec_free(mask);
6514
6515 S; W;
6516 /* NOTREACHED */
6517}
6518
6519uword unformat_ip4_match (unformat_input_t * input, va_list * args)
6520{
6521 u8 ** matchp = va_arg (*args, u8 **);
6522 u8 * match = 0;
6523 ip4_header_t * ip;
6524 int version = 0;
6525 u32 version_val;
6526 int hdr_length = 0;
6527 u32 hdr_length_val;
6528 int src = 0, dst = 0;
6529 ip4_address_t src_val, dst_val;
6530 int proto = 0;
6531 u32 proto_val;
6532 int tos = 0;
6533 u32 tos_val;
6534 int length = 0;
6535 u32 length_val;
6536 int fragment_id = 0;
6537 u32 fragment_id_val;
6538 int ttl = 0;
6539 int ttl_val;
6540 int checksum = 0;
6541 u32 checksum_val;
6542
6543 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
6544 {
6545 if (unformat (input, "version %d", &version_val))
6546 version = 1;
6547 else if (unformat (input, "hdr_length %d", &hdr_length_val))
6548 hdr_length = 1;
6549 else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
6550 src = 1;
6551 else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
6552 dst = 1;
6553 else if (unformat (input, "proto %d", &proto_val))
6554 proto = 1;
6555 else if (unformat (input, "tos %d", &tos_val))
6556 tos = 1;
6557 else if (unformat (input, "length %d", &length_val))
6558 length = 1;
6559 else if (unformat (input, "fragment_id %d", &fragment_id_val))
6560 fragment_id = 1;
6561 else if (unformat (input, "ttl %d", &ttl_val))
6562 ttl = 1;
6563 else if (unformat (input, "checksum %d", &checksum_val))
6564 checksum = 1;
6565 else
6566 break;
6567 }
6568
6569 if (version + hdr_length + src + dst + proto + tos + length + fragment_id
6570 + ttl + checksum == 0)
6571 return 0;
6572
6573 /*
6574 * Aligned because we use the real comparison functions
6575 */
6576 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof(u32x4));
6577
6578 ip = (ip4_header_t *) match;
6579
6580 /* These are realistically matched in practice */
6581 if (src)
6582 ip->src_address.as_u32 = src_val.as_u32;
6583
6584 if (dst)
6585 ip->dst_address.as_u32 = dst_val.as_u32;
6586
6587 if (proto)
6588 ip->protocol = proto_val;
6589
6590
6591 /* These are not, but they're included for completeness */
6592 if (version)
6593 ip->ip_version_and_header_length |= (version_val & 0xF)<<4;
6594
6595 if (hdr_length)
6596 ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
6597
6598 if (tos)
6599 ip->tos = tos_val;
6600
6601 if (length)
6602 ip->length = length_val;
6603
6604 if (ttl)
6605 ip->ttl = ttl_val;
6606
6607 if (checksum)
6608 ip->checksum = checksum_val;
6609
6610 *matchp = match;
6611 return 1;
6612}
6613
6614uword unformat_ip6_match (unformat_input_t * input, va_list * args)
6615{
6616 u8 ** matchp = va_arg (*args, u8 **);
6617 u8 * match = 0;
6618 ip6_header_t * ip;
6619 int version = 0;
6620 u32 version_val;
6621 u8 traffic_class;
6622 u32 traffic_class_val;
6623 u8 flow_label;
6624 u8 flow_label_val;
6625 int src = 0, dst = 0;
6626 ip6_address_t src_val, dst_val;
6627 int proto = 0;
6628 u32 proto_val;
6629 int payload_length = 0;
6630 u32 payload_length_val;
6631 int hop_limit = 0;
6632 int hop_limit_val;
6633 u32 ip_version_traffic_class_and_flow_label;
6634
6635 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
6636 {
6637 if (unformat (input, "version %d", &version_val))
6638 version = 1;
6639 else if (unformat (input, "traffic_class %d", &traffic_class_val))
6640 traffic_class = 1;
6641 else if (unformat (input, "flow_label %d", &flow_label_val))
6642 flow_label = 1;
6643 else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
6644 src = 1;
6645 else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
6646 dst = 1;
6647 else if (unformat (input, "proto %d", &proto_val))
6648 proto = 1;
6649 else if (unformat (input, "payload_length %d", &payload_length_val))
6650 payload_length = 1;
6651 else if (unformat (input, "hop_limit %d", &hop_limit_val))
6652 hop_limit = 1;
6653 else
6654 break;
6655 }
6656
6657 if (version + traffic_class + flow_label + src + dst + proto +
6658 payload_length + hop_limit == 0)
6659 return 0;
6660
6661 /*
6662 * Aligned because we use the real comparison functions
6663 */
6664 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof(u32x4));
6665
6666 ip = (ip6_header_t *) match;
6667
6668 if (src)
Damjan Marionf1213b82016-03-13 02:22:06 +01006669 clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07006670
6671 if (dst)
Damjan Marionf1213b82016-03-13 02:22:06 +01006672 clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07006673
6674 if (proto)
6675 ip->protocol = proto_val;
6676
6677 ip_version_traffic_class_and_flow_label = 0;
6678
6679 if (version)
6680 ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
6681
6682 if (traffic_class)
6683 ip_version_traffic_class_and_flow_label |= (traffic_class_val & 0xFF) << 20;
6684
6685 if (flow_label)
6686 ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
6687
6688 ip->ip_version_traffic_class_and_flow_label =
6689 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
6690
6691 if (payload_length)
6692 ip->payload_length = clib_host_to_net_u16 (payload_length_val);
6693
6694 if (hop_limit)
6695 ip->hop_limit = hop_limit_val;
6696
6697 *matchp = match;
6698 return 1;
6699}
6700
6701uword unformat_l3_match (unformat_input_t * input, va_list * args)
6702{
6703 u8 ** matchp = va_arg (*args, u8 **);
6704
6705 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
6706 if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
6707 return 1;
6708 else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
6709 return 1;
6710 else
6711 break;
6712 }
6713 return 0;
6714}
6715
6716uword unformat_vlan_tag (unformat_input_t * input, va_list * args)
6717{
6718 u8 * tagp = va_arg (*args, u8 *);
6719 u32 tag;
6720
6721 if (unformat(input, "%d", &tag))
6722 {
6723 tagp[0] = (tag>>8) & 0x0F;
6724 tagp[1] = tag & 0xFF;
6725 return 1;
6726 }
6727
6728 return 0;
6729}
6730
6731uword unformat_l2_match (unformat_input_t * input, va_list * args)
6732{
6733 u8 ** matchp = va_arg (*args, u8 **);
6734 u8 * match = 0;
6735 u8 src = 0;
6736 u8 src_val[6];
6737 u8 dst = 0;
6738 u8 dst_val[6];
6739 u8 proto = 0;
6740 u16 proto_val;
6741 u8 tag1 = 0;
6742 u8 tag1_val [2];
6743 u8 tag2 = 0;
6744 u8 tag2_val [2];
6745 int len = 14;
6746 u8 ignore_tag1 = 0;
6747 u8 ignore_tag2 = 0;
6748 u8 cos1 = 0;
6749 u8 cos2 = 0;
6750 u32 cos1_val = 0;
6751 u32 cos2_val = 0;
6752
6753 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
6754 if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
6755 src = 1;
6756 else if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
6757 dst = 1;
6758 else if (unformat (input, "proto %U",
6759 unformat_ethernet_type_host_byte_order, &proto_val))
6760 proto = 1;
6761 else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
6762 tag1 = 1;
6763 else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
6764 tag2 = 1;
6765 else if (unformat (input, "ignore-tag1"))
6766 ignore_tag1 = 1;
6767 else if (unformat (input, "ignore-tag2"))
6768 ignore_tag2 = 1;
6769 else if (unformat (input, "cos1 %d", &cos1_val))
6770 cos1 = 1;
6771 else if (unformat (input, "cos2 %d", &cos2_val))
6772 cos2 = 1;
6773 else
6774 break;
6775 }
6776 if ((src + dst + proto + tag1 + tag2 +
6777 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
6778 return 0;
6779
6780 if (tag1 || ignore_tag1 || cos1)
6781 len = 18;
6782 if (tag2 || ignore_tag2 || cos2)
6783 len = 22;
6784
6785 vec_validate_aligned (match, len-1, sizeof(u32x4));
6786
6787 if (dst)
Damjan Marionf1213b82016-03-13 02:22:06 +01006788 clib_memcpy (match, dst_val, 6);
Ed Warnickecb9cada2015-12-08 15:45:58 -07006789
6790 if (src)
Damjan Marionf1213b82016-03-13 02:22:06 +01006791 clib_memcpy (match + 6, src_val, 6);
Ed Warnickecb9cada2015-12-08 15:45:58 -07006792
6793 if (tag2)
6794 {
6795 /* inner vlan tag */
6796 match[19] = tag2_val[1];
6797 match[18] = tag2_val[0];
6798 if (cos2)
6799 match [18] |= (cos2_val & 0x7) << 5;
6800 if (proto)
6801 {
6802 match[21] = proto_val & 0xff;
6803 match[20] = proto_val >> 8;
6804 }
6805 if (tag1)
6806 {
6807 match [15] = tag1_val[1];
6808 match [14] = tag1_val[0];
6809 }
6810 if (cos1)
6811 match [14] |= (cos1_val & 0x7) << 5;
6812 *matchp = match;
6813 return 1;
6814 }
6815 if (tag1)
6816 {
6817 match [15] = tag1_val[1];
6818 match [14] = tag1_val[0];
6819 if (proto)
6820 {
6821 match[17] = proto_val & 0xff;
6822 match[16] = proto_val >> 8;
6823 }
6824 if (cos1)
6825 match [14] |= (cos1_val & 0x7) << 5;
6826
6827 *matchp = match;
6828 return 1;
6829 }
6830 if (cos2)
6831 match [18] |= (cos2_val & 0x7) << 5;
6832 if (cos1)
6833 match [14] |= (cos1_val & 0x7) << 5;
6834 if (proto)
6835 {
6836 match[13] = proto_val & 0xff;
6837 match[12] = proto_val >> 8;
6838 }
6839
6840 *matchp = match;
6841 return 1;
6842}
6843
6844
6845uword unformat_classify_match (unformat_input_t * input, va_list * args)
6846{
6847 u8 ** matchp = va_arg (*args, u8 **);
6848 u32 skip_n_vectors = va_arg (*args, u32);
6849 u32 match_n_vectors = va_arg (*args, u32);
6850
6851 u8 * match = 0;
6852 u8 * l2 = 0;
6853 u8 * l3 = 0;
6854
6855 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
6856 if (unformat (input, "hex %U", unformat_hex_string, &match))
6857 ;
6858 else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
6859 ;
6860 else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
6861 ;
6862 else
6863 break;
6864 }
6865
6866 if (match || l2 || l3)
6867 {
6868 if (l2 || l3)
6869 {
6870 /* "Win a free Ethernet header in every packet" */
6871 if (l2 == 0)
6872 vec_validate_aligned (l2, 13, sizeof(u32x4));
6873 match = l2;
6874 vec_append_aligned (match, l3, sizeof(u32x4));
6875 vec_free (l3);
6876 }
6877
6878 /* Make sure the vector is big enough even if key is all 0's */
6879 vec_validate_aligned
6880 (match, ((match_n_vectors + skip_n_vectors) * sizeof(u32x4)) - 1,
6881 sizeof(u32x4));
6882
6883 /* Set size, include skipped vectors*/
6884 _vec_len (match) = (match_n_vectors+skip_n_vectors) * sizeof(u32x4);
6885
6886 *matchp = match;
6887
6888 return 1;
6889 }
6890
6891 return 0;
6892}
6893
6894static int api_classify_add_del_session (vat_main_t * vam)
6895{
6896 unformat_input_t * i = vam->input;
6897 vl_api_classify_add_del_session_t *mp;
6898 int is_add = 1;
6899 u32 table_index = ~0;
6900 u32 hit_next_index = ~0;
6901 u32 opaque_index = ~0;
6902 u8 * match = 0;
6903 i32 advance = 0;
6904 f64 timeout;
6905 u32 skip_n_vectors = 0;
6906 u32 match_n_vectors = 0;
6907
6908 /*
6909 * Warning: you have to supply skip_n and match_n
6910 * because the API client cant simply look at the classify
6911 * table object.
6912 */
6913
6914 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6915 if (unformat (i, "del"))
6916 is_add = 0;
6917 else if (unformat (i, "hit-next %U", unformat_ip_next_index,
6918 &hit_next_index))
6919 ;
6920 else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
6921 &hit_next_index))
6922 ;
6923 else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
6924 &hit_next_index))
6925 ;
6926 else if (unformat (i, "opaque-index %d", &opaque_index))
6927 ;
6928 else if (unformat (i, "skip_n %d", &skip_n_vectors))
6929 ;
6930 else if (unformat (i, "match_n %d", &match_n_vectors))
6931 ;
6932 else if (unformat (i, "match %U", unformat_classify_match,
6933 &match, skip_n_vectors, match_n_vectors))
6934 ;
6935 else if (unformat (i, "advance %d", &advance))
6936 ;
6937 else if (unformat (i, "table-index %d", &table_index))
6938 ;
6939 else
6940 break;
6941 }
6942
6943 if (table_index == ~0) {
6944 errmsg ("Table index required\n");
6945 return -99;
6946 }
6947
6948 if (is_add && match == 0) {
6949 errmsg ("Match value required\n");
6950 return -99;
6951 }
6952
6953 M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session,
6954 vec_len(match));
6955
6956 mp->is_add = is_add;
6957 mp->table_index = ntohl(table_index);
6958 mp->hit_next_index = ntohl(hit_next_index);
6959 mp->opaque_index = ntohl(opaque_index);
6960 mp->advance = ntohl(advance);
Damjan Marionf1213b82016-03-13 02:22:06 +01006961 clib_memcpy (mp->match, match, vec_len(match));
Ed Warnickecb9cada2015-12-08 15:45:58 -07006962 vec_free(match);
6963
6964 S; W;
6965 /* NOTREACHED */
6966}
6967
6968static int api_classify_set_interface_ip_table (vat_main_t * vam)
6969{
6970 unformat_input_t * i = vam->input;
6971 vl_api_classify_set_interface_ip_table_t *mp;
6972 f64 timeout;
6973 u32 sw_if_index;
6974 int sw_if_index_set;
6975 u32 table_index = ~0;
6976 u8 is_ipv6 = 0;
6977
6978 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6979 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6980 sw_if_index_set = 1;
6981 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6982 sw_if_index_set = 1;
6983 else if (unformat (i, "table %d", &table_index))
6984 ;
6985 else {
6986 clib_warning ("parse error '%U'", format_unformat_error, i);
6987 return -99;
6988 }
6989 }
6990
6991 if (sw_if_index_set == 0) {
6992 errmsg ("missing interface name or sw_if_index\n");
6993 return -99;
6994 }
6995
6996
6997 M(CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
6998
6999 mp->sw_if_index = ntohl(sw_if_index);
7000 mp->table_index = ntohl(table_index);
7001 mp->is_ipv6 = is_ipv6;
7002
7003 S; W;
7004 /* NOTREACHED */
7005 return 0;
7006}
7007
7008static int api_classify_set_interface_l2_tables (vat_main_t * vam)
7009{
7010 unformat_input_t * i = vam->input;
7011 vl_api_classify_set_interface_l2_tables_t *mp;
7012 f64 timeout;
7013 u32 sw_if_index;
7014 int sw_if_index_set;
7015 u32 ip4_table_index = ~0;
7016 u32 ip6_table_index = ~0;
7017 u32 other_table_index = ~0;
7018
7019 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7020 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7021 sw_if_index_set = 1;
7022 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7023 sw_if_index_set = 1;
7024 else if (unformat (i, "ip4-table %d", &ip4_table_index))
7025 ;
7026 else if (unformat (i, "ip6-table %d", &ip6_table_index))
7027 ;
7028 else if (unformat (i, "other-table %d", &other_table_index))
7029 ;
7030 else {
7031 clib_warning ("parse error '%U'", format_unformat_error, i);
7032 return -99;
7033 }
7034 }
7035
7036 if (sw_if_index_set == 0) {
7037 errmsg ("missing interface name or sw_if_index\n");
7038 return -99;
7039 }
7040
7041
7042 M(CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
7043
7044 mp->sw_if_index = ntohl(sw_if_index);
7045 mp->ip4_table_index = ntohl(ip4_table_index);
7046 mp->ip6_table_index = ntohl(ip6_table_index);
7047 mp->other_table_index = ntohl(other_table_index);
7048
7049
7050 S; W;
7051 /* NOTREACHED */
7052 return 0;
7053}
7054
7055static int api_get_node_index (vat_main_t * vam)
7056{
7057 unformat_input_t * i = vam->input;
7058 vl_api_get_node_index_t * mp;
7059 f64 timeout;
7060 u8 * name = 0;
7061
7062 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7063 if (unformat (i, "node %s", &name))
7064 ;
7065 else
7066 break;
7067 }
7068 if (name == 0) {
7069 errmsg ("node name required\n");
7070 return -99;
7071 }
7072 if (vec_len (name) >= ARRAY_LEN(mp->node_name)) {
7073 errmsg ("node name too long, max %d\n", ARRAY_LEN(mp->node_name));
7074 return -99;
7075 }
7076
7077 M(GET_NODE_INDEX, get_node_index);
Damjan Marionf1213b82016-03-13 02:22:06 +01007078 clib_memcpy (mp->node_name, name, vec_len(name));
Ed Warnickecb9cada2015-12-08 15:45:58 -07007079 vec_free(name);
7080
7081 S; W;
7082 /* NOTREACHED */
7083 return 0;
7084}
7085
7086static int api_add_node_next (vat_main_t * vam)
7087{
7088 unformat_input_t * i = vam->input;
7089 vl_api_add_node_next_t * mp;
7090 f64 timeout;
7091 u8 * name = 0;
7092 u8 * next = 0;
7093
7094 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7095 if (unformat (i, "node %s", &name))
7096 ;
7097 else if (unformat (i, "next %s", &next))
7098 ;
7099 else
7100 break;
7101 }
7102 if (name == 0) {
7103 errmsg ("node name required\n");
7104 return -99;
7105 }
7106 if (vec_len (name) >= ARRAY_LEN(mp->node_name)) {
7107 errmsg ("node name too long, max %d\n", ARRAY_LEN(mp->node_name));
7108 return -99;
7109 }
7110 if (next == 0) {
7111 errmsg ("next node required\n");
7112 return -99;
7113 }
7114 if (vec_len (next) >= ARRAY_LEN(mp->next_name)) {
7115 errmsg ("next name too long, max %d\n", ARRAY_LEN(mp->next_name));
7116 return -99;
7117 }
7118
7119 M(ADD_NODE_NEXT, add_node_next);
Damjan Marionf1213b82016-03-13 02:22:06 +01007120 clib_memcpy (mp->node_name, name, vec_len(name));
7121 clib_memcpy (mp->next_name, next, vec_len(next));
Ed Warnickecb9cada2015-12-08 15:45:58 -07007122 vec_free(name);
7123 vec_free(next);
7124
7125 S; W;
7126 /* NOTREACHED */
7127 return 0;
7128}
7129
7130static int api_l2tpv3_create_tunnel (vat_main_t * vam)
7131{
7132 unformat_input_t * i = vam->input;
7133 ip6_address_t client_address, our_address;
7134 int client_address_set = 0;
7135 int our_address_set = 0;
7136 u32 local_session_id = 0;
7137 u32 remote_session_id = 0;
7138 u64 local_cookie = 0;
7139 u64 remote_cookie = 0;
7140 u8 l2_sublayer_present = 0;
7141 vl_api_l2tpv3_create_tunnel_t * mp;
7142 f64 timeout;
7143
7144 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7145 if (unformat (i, "client_address %U", unformat_ip6_address,
7146 &client_address))
7147 client_address_set = 1;
7148 else if (unformat (i, "our_address %U", unformat_ip6_address,
7149 &our_address))
7150 our_address_set = 1;
7151 else if (unformat (i, "local_session_id %d", &local_session_id))
7152 ;
7153 else if (unformat (i, "remote_session_id %d", &remote_session_id))
7154 ;
7155 else if (unformat (i, "local_cookie %lld", &local_cookie))
7156 ;
7157 else if (unformat (i, "remote_cookie %lld", &remote_cookie))
7158 ;
7159 else if (unformat (i, "l2-sublayer-present"))
7160 l2_sublayer_present = 1;
7161 else
7162 break;
7163 }
7164
7165 if (client_address_set == 0) {
7166 errmsg ("client_address required\n");
7167 return -99;
7168 }
7169
7170 if (our_address_set == 0) {
7171 errmsg ("our_address required\n");
7172 return -99;
7173 }
7174
7175 M(L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
7176
Damjan Marionf1213b82016-03-13 02:22:06 +01007177 clib_memcpy (mp->client_address, client_address.as_u8,
Ed Warnickecb9cada2015-12-08 15:45:58 -07007178 sizeof (mp->client_address));
7179
Damjan Marionf1213b82016-03-13 02:22:06 +01007180 clib_memcpy (mp->our_address, our_address.as_u8,
Ed Warnickecb9cada2015-12-08 15:45:58 -07007181 sizeof (mp->our_address));
7182
7183 mp->local_session_id = ntohl (local_session_id);
7184 mp->remote_session_id = ntohl (remote_session_id);
7185 mp->local_cookie = clib_host_to_net_u64 (local_cookie);
7186 mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
7187 mp->l2_sublayer_present = l2_sublayer_present;
7188 mp->is_ipv6 = 1;
7189
7190 S; W;
7191 /* NOTREACHED */
7192 return 0;
7193}
7194
7195static int api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
7196{
7197 unformat_input_t * i = vam->input;
7198 u32 sw_if_index;
7199 u8 sw_if_index_set = 0;
7200 u64 new_local_cookie = 0;
7201 u64 new_remote_cookie = 0;
7202 vl_api_l2tpv3_set_tunnel_cookies_t *mp;
7203 f64 timeout;
7204
7205 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7206 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7207 sw_if_index_set = 1;
7208 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7209 sw_if_index_set = 1;
7210 else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
7211 ;
7212 else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
7213 ;
7214 else
7215 break;
7216 }
7217
7218 if (sw_if_index_set == 0) {
7219 errmsg ("missing interface name or sw_if_index\n");
7220 return -99;
7221 }
7222
7223 M(L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
7224
7225 mp->sw_if_index = ntohl(sw_if_index);
7226 mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
7227 mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
7228
7229 S; W;
7230 /* NOTREACHED */
7231 return 0;
7232}
7233
7234static int api_l2tpv3_interface_enable_disable (vat_main_t * vam)
7235{
7236 unformat_input_t * i = vam->input;
7237 vl_api_l2tpv3_interface_enable_disable_t *mp;
7238 f64 timeout;
7239 u32 sw_if_index;
7240 u8 sw_if_index_set = 0;
7241 u8 enable_disable = 1;
7242
7243 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7244 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7245 sw_if_index_set = 1;
7246 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7247 sw_if_index_set = 1;
7248 else if (unformat (i, "enable"))
7249 enable_disable = 1;
7250 else if (unformat (i, "disable"))
7251 enable_disable = 0;
7252 else
7253 break;
7254 }
7255
7256 if (sw_if_index_set == 0) {
7257 errmsg ("missing interface name or sw_if_index\n");
7258 return -99;
7259 }
7260
7261 M(L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
7262
7263 mp->sw_if_index = ntohl(sw_if_index);
7264 mp->enable_disable = enable_disable;
7265
7266 S; W;
7267 /* NOTREACHED */
7268 return 0;
7269}
7270
7271static int api_l2tpv3_set_lookup_key (vat_main_t * vam)
7272{
7273 unformat_input_t * i = vam->input;
7274 vl_api_l2tpv3_set_lookup_key_t * mp;
7275 f64 timeout;
7276 u8 key = ~0;
7277
7278 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7279 if (unformat (i, "lookup_v6_src"))
7280 key = L2T_LOOKUP_SRC_ADDRESS;
7281 else if (unformat (i, "lookup_v6_dst"))
7282 key = L2T_LOOKUP_DST_ADDRESS;
7283 else if (unformat (i, "lookup_session_id"))
7284 key = L2T_LOOKUP_SESSION_ID;
7285 else
7286 break;
7287 }
7288
Damjan Marionfa693552016-04-26 19:30:36 +02007289 if (key == (u8) ~0) {
Ed Warnickecb9cada2015-12-08 15:45:58 -07007290 errmsg ("l2tp session lookup key unset\n");
7291 return -99;
7292 }
7293
7294 M(L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
7295
7296 mp->key = key;
7297
7298 S; W;
7299 /* NOTREACHED */
7300 return 0;
7301}
7302
7303static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
7304(vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
7305{
7306 vat_main_t * vam = &vat_main;
7307
7308 fformat(vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
7309 format_ip6_address, mp->our_address,
7310 format_ip6_address, mp->client_address,
7311 clib_net_to_host_u32(mp->sw_if_index));
7312
7313 fformat (vam->ofp, " local cookies %016llx %016llx remote cookie %016llx\n",
7314 clib_net_to_host_u64 (mp->local_cookie[0]),
7315 clib_net_to_host_u64 (mp->local_cookie[1]),
7316 clib_net_to_host_u64 (mp->remote_cookie));
7317
7318 fformat (vam->ofp, " local session-id %d remote session-id %d\n",
7319 clib_net_to_host_u32 (mp->local_session_id),
7320 clib_net_to_host_u32 (mp->remote_session_id));
7321
7322 fformat (vam->ofp, " l2 specific sublayer %s\n\n",
7323 mp->l2_sublayer_present ? "preset" : "absent");
7324
7325}
7326
7327static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
7328(vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
7329{
7330 vat_main_t * vam = &vat_main;
7331 vat_json_node_t *node = NULL;
7332 struct in6_addr addr;
7333
7334 if (VAT_JSON_ARRAY != vam->json_tree.type) {
7335 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
7336 vat_json_init_array(&vam->json_tree);
7337 }
7338 node = vat_json_array_add(&vam->json_tree);
7339
7340 vat_json_init_object(node);
7341
Damjan Marionf1213b82016-03-13 02:22:06 +01007342 clib_memcpy(&addr, mp->our_address, sizeof(addr));
Ed Warnickecb9cada2015-12-08 15:45:58 -07007343 vat_json_object_add_ip6(node, "our_address", addr);
Damjan Marionf1213b82016-03-13 02:22:06 +01007344 clib_memcpy(&addr, mp->client_address, sizeof(addr));
Ed Warnickecb9cada2015-12-08 15:45:58 -07007345 vat_json_object_add_ip6(node, "client_address", addr);
7346
7347 vat_json_node_t * lc = vat_json_object_add(node, "local_cookie");
7348 vat_json_init_array(lc);
7349 vat_json_array_add_uint(lc, clib_net_to_host_u64(mp->local_cookie[0]));
7350 vat_json_array_add_uint(lc, clib_net_to_host_u64(mp->local_cookie[1]));
7351 vat_json_object_add_uint(node, "remote_cookie", clib_net_to_host_u64(mp->remote_cookie));
7352
7353 printf("local id: %u", clib_net_to_host_u32(mp->local_session_id));
7354 vat_json_object_add_uint(node, "local_session_id", clib_net_to_host_u32(mp->local_session_id));
7355 vat_json_object_add_uint(node, "remote_session_id", clib_net_to_host_u32(mp->remote_session_id));
7356 vat_json_object_add_string_copy(node, "l2_sublayer", mp->l2_sublayer_present ?
7357 (u8*)"present" : (u8*)"absent");
7358}
7359
7360static int api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
7361{
7362 vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
7363 f64 timeout;
7364
7365 /* Get list of l2tpv3-tunnel interfaces */
7366 M(SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
7367 S;
7368
7369 /* Use a control ping for synchronization */
7370 {
7371 vl_api_control_ping_t * mp;
7372 M(CONTROL_PING, control_ping);
7373 S;
7374 }
7375 W;
7376}
7377
7378
7379static void vl_api_sw_interface_tap_details_t_handler
7380(vl_api_sw_interface_tap_details_t * mp)
7381{
7382 vat_main_t * vam = &vat_main;
7383
7384 fformat(vam->ofp, "%-16s %d\n",
7385 mp->dev_name,
7386 clib_net_to_host_u32(mp->sw_if_index));
7387}
7388
7389static void vl_api_sw_interface_tap_details_t_handler_json
7390(vl_api_sw_interface_tap_details_t * mp)
7391{
7392 vat_main_t * vam = &vat_main;
7393 vat_json_node_t *node = NULL;
7394
7395 if (VAT_JSON_ARRAY != vam->json_tree.type) {
7396 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
7397 vat_json_init_array(&vam->json_tree);
7398 }
7399 node = vat_json_array_add(&vam->json_tree);
7400
7401 vat_json_init_object(node);
7402 vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
7403 vat_json_object_add_string_copy(node, "dev_name", mp->dev_name);
7404}
7405
7406static int api_sw_interface_tap_dump (vat_main_t * vam)
7407{
7408 vl_api_sw_interface_tap_dump_t *mp;
7409 f64 timeout;
7410
7411 fformat(vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
7412 /* Get list of tap interfaces */
7413 M(SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
7414 S;
7415
7416 /* Use a control ping for synchronization */
7417 {
7418 vl_api_control_ping_t * mp;
7419 M(CONTROL_PING, control_ping);
7420 S;
7421 }
7422 W;
7423}
7424
7425static uword unformat_vxlan_decap_next
7426(unformat_input_t * input, va_list * args)
7427{
7428 u32 * result = va_arg (*args, u32 *);
7429 u32 tmp;
7430
7431 if (unformat (input, "drop"))
7432 *result = VXLAN_INPUT_NEXT_DROP;
7433 else if (unformat (input, "ip4"))
7434 *result = VXLAN_INPUT_NEXT_IP4_INPUT;
7435 else if (unformat (input, "ip6"))
7436 *result = VXLAN_INPUT_NEXT_IP6_INPUT;
7437 else if (unformat (input, "l2"))
7438 *result = VXLAN_INPUT_NEXT_L2_INPUT;
7439 else if (unformat (input, "%d", &tmp))
7440 *result = tmp;
7441 else
7442 return 0;
7443 return 1;
7444}
7445
7446static int api_vxlan_add_del_tunnel (vat_main_t * vam)
7447{
7448 unformat_input_t * line_input = vam->input;
7449 vl_api_vxlan_add_del_tunnel_t *mp;
7450 f64 timeout;
Chris Luke99cb3352016-04-26 10:49:53 -04007451 ip4_address_t src4, dst4;
7452 ip6_address_t src6, dst6;
Ed Warnickecb9cada2015-12-08 15:45:58 -07007453 u8 is_add = 1;
Chris Luke99cb3352016-04-26 10:49:53 -04007454 u8 ipv4_set = 0, ipv6_set = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -07007455 u8 src_set = 0;
7456 u8 dst_set = 0;
7457 u32 encap_vrf_id = 0;
7458 u32 decap_next_index = ~0;
7459 u32 vni = 0;
7460
7461 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
7462 if (unformat (line_input, "del"))
7463 is_add = 0;
7464 else if (unformat (line_input, "src %U",
Chris Luke99cb3352016-04-26 10:49:53 -04007465 unformat_ip4_address, &src4))
7466 {
7467 ipv4_set = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -07007468 src_set = 1;
Chris Luke99cb3352016-04-26 10:49:53 -04007469 }
Ed Warnickecb9cada2015-12-08 15:45:58 -07007470 else if (unformat (line_input, "dst %U",
Chris Luke99cb3352016-04-26 10:49:53 -04007471 unformat_ip4_address, &dst4))
7472 {
7473 ipv4_set = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -07007474 dst_set = 1;
Chris Luke99cb3352016-04-26 10:49:53 -04007475 }
7476 else if (unformat (line_input, "src %U",
7477 unformat_ip6_address, &src6))
7478 {
7479 ipv6_set = 1;
7480 src_set = 1;
7481 }
7482 else if (unformat (line_input, "dst %U",
7483 unformat_ip6_address, &dst6))
7484 {
7485 ipv6_set = 1;
7486 dst_set = 1;
7487 }
Ed Warnickecb9cada2015-12-08 15:45:58 -07007488 else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
7489 ;
7490 else if (unformat (line_input, "decap-next %U",
7491 unformat_vxlan_decap_next, &decap_next_index))
7492 ;
7493 else if (unformat (line_input, "vni %d", &vni))
7494 ;
7495 else {
7496 errmsg ("parse error '%U'\n", format_unformat_error, line_input);
7497 return -99;
7498 }
7499 }
7500
7501 if (src_set == 0) {
7502 errmsg ("tunnel src address not specified\n");
7503 return -99;
7504 }
7505 if (dst_set == 0) {
7506 errmsg ("tunnel dst address not specified\n");
7507 return -99;
7508 }
7509
Chris Luke99cb3352016-04-26 10:49:53 -04007510 if (ipv4_set && ipv6_set) {
7511 errmsg ("both IPv4 and IPv6 addresses specified");
7512 return -99;
7513 }
7514
Ed Warnickecb9cada2015-12-08 15:45:58 -07007515 if ((vni == 0) || (vni>>24)) {
7516 errmsg ("vni not specified or out of range\n");
7517 return -99;
7518 }
7519
7520 M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
Chris Luke99cb3352016-04-26 10:49:53 -04007521
7522 if (ipv6_set) {
Chris Luked686c632016-05-20 12:13:02 -04007523 clib_memcpy(&mp->src_address, &src6, sizeof(src6));
7524 clib_memcpy(&mp->dst_address, &dst6, sizeof(dst6));
Chris Luke99cb3352016-04-26 10:49:53 -04007525 } else {
7526 clib_memcpy(&mp->src_address, &src4, sizeof(src4));
7527 clib_memcpy(&mp->dst_address, &dst4, sizeof(dst4));
7528 }
Ed Warnickecb9cada2015-12-08 15:45:58 -07007529 mp->encap_vrf_id = ntohl(encap_vrf_id);
7530 mp->decap_next_index = ntohl(decap_next_index);
7531 mp->vni = ntohl(vni);
7532 mp->is_add = is_add;
Chris Luke99cb3352016-04-26 10:49:53 -04007533 mp->is_ipv6 = ipv6_set;
Ed Warnickecb9cada2015-12-08 15:45:58 -07007534
7535 S; W;
7536 /* NOTREACHED */
7537 return 0;
7538}
7539
Dave Wallace60231f32015-12-17 21:04:30 -05007540static void vl_api_vxlan_tunnel_details_t_handler
7541(vl_api_vxlan_tunnel_details_t * mp)
7542{
7543 vat_main_t * vam = &vat_main;
7544
Chris Luke99cb3352016-04-26 10:49:53 -04007545 fformat(vam->ofp, "%11d%24U%24U%14d%18d%13d\n",
Dave Wallace60231f32015-12-17 21:04:30 -05007546 ntohl(mp->sw_if_index),
Chris Luke99cb3352016-04-26 10:49:53 -04007547 format_ip46_address, &(mp->src_address[0]),
Damjan Marion86be4872016-05-24 23:19:11 +02007548 IP46_TYPE_ANY,
Chris Luke99cb3352016-04-26 10:49:53 -04007549 format_ip46_address, &(mp->dst_address[0]),
Damjan Marion86be4872016-05-24 23:19:11 +02007550 IP46_TYPE_ANY,
Dave Wallace60231f32015-12-17 21:04:30 -05007551 ntohl(mp->encap_vrf_id),
7552 ntohl(mp->decap_next_index),
7553 ntohl(mp->vni));
7554}
7555
7556static void vl_api_vxlan_tunnel_details_t_handler_json
7557(vl_api_vxlan_tunnel_details_t * mp)
7558{
7559 vat_main_t * vam = &vat_main;
7560 vat_json_node_t *node = NULL;
7561 struct in_addr ip4;
Chris Luke99cb3352016-04-26 10:49:53 -04007562 struct in6_addr ip6;
Dave Wallace60231f32015-12-17 21:04:30 -05007563
7564 if (VAT_JSON_ARRAY != vam->json_tree.type) {
7565 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
7566 vat_json_init_array(&vam->json_tree);
7567 }
7568 node = vat_json_array_add(&vam->json_tree);
7569
7570 vat_json_init_object(node);
7571 vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
Chris Luke99cb3352016-04-26 10:49:53 -04007572 if (mp->is_ipv6) {
7573 clib_memcpy(&ip6, &(mp->src_address[0]), sizeof(ip6));
7574 vat_json_object_add_ip6(node, "src_address", ip6);
7575 clib_memcpy(&ip6, &(mp->dst_address[0]), sizeof(ip6));
7576 vat_json_object_add_ip6(node, "dst_address", ip6);
7577 } else {
7578 clib_memcpy(&ip4, &(mp->src_address[0]), sizeof(ip4));
7579 vat_json_object_add_ip4(node, "src_address", ip4);
7580 clib_memcpy(&ip4, &(mp->dst_address[0]), sizeof(ip4));
7581 vat_json_object_add_ip4(node, "dst_address", ip4);
7582 }
Dave Wallace60231f32015-12-17 21:04:30 -05007583 vat_json_object_add_uint(node, "encap_vrf_id", ntohl(mp->encap_vrf_id));
7584 vat_json_object_add_uint(node, "decap_next_index", ntohl(mp->decap_next_index));
7585 vat_json_object_add_uint(node, "vni", ntohl(mp->vni));
Chris Luke99cb3352016-04-26 10:49:53 -04007586 vat_json_object_add_uint(node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
Dave Wallace60231f32015-12-17 21:04:30 -05007587}
7588
7589static int api_vxlan_tunnel_dump (vat_main_t * vam)
7590{
7591 unformat_input_t * i = vam->input;
7592 vl_api_vxlan_tunnel_dump_t *mp;
7593 f64 timeout;
7594 u32 sw_if_index;
7595 u8 sw_if_index_set = 0;
7596
7597 /* Parse args required to build the message */
7598 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7599 if (unformat (i, "sw_if_index %d", &sw_if_index))
7600 sw_if_index_set = 1;
7601 else
7602 break;
7603 }
7604
7605 if (sw_if_index_set == 0) {
7606 sw_if_index = ~0;
7607 }
7608
7609 if (!vam->json_output) {
Chris Luke99cb3352016-04-26 10:49:53 -04007610 fformat(vam->ofp, "%11s%24s%24s%14s%18s%13s\n",
Dave Wallace60231f32015-12-17 21:04:30 -05007611 "sw_if_index", "src_address", "dst_address",
7612 "encap_vrf_id", "decap_next_index", "vni");
7613 }
7614
Chris Luke99cb3352016-04-26 10:49:53 -04007615 /* Get list of vxlan-tunnel interfaces */
Dave Wallace60231f32015-12-17 21:04:30 -05007616 M(VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
7617
7618 mp->sw_if_index = htonl(sw_if_index);
7619
7620 S;
7621
7622 /* Use a control ping for synchronization */
7623 {
7624 vl_api_control_ping_t * mp;
7625 M(CONTROL_PING, control_ping);
7626 S;
7627 }
7628 W;
7629}
7630
Chris Luke27fe48f2016-04-28 13:44:38 -04007631static int api_gre_add_del_tunnel (vat_main_t * vam)
7632{
7633 unformat_input_t * line_input = vam->input;
7634 vl_api_gre_add_del_tunnel_t *mp;
7635 f64 timeout;
7636 ip4_address_t src4, dst4;
7637 u8 is_add = 1;
7638 u8 src_set = 0;
7639 u8 dst_set = 0;
7640 u32 outer_fib_id = 0;
7641
7642 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
7643 if (unformat (line_input, "del"))
7644 is_add = 0;
7645 else if (unformat (line_input, "src %U",
7646 unformat_ip4_address, &src4))
7647 src_set = 1;
7648 else if (unformat (line_input, "dst %U",
7649 unformat_ip4_address, &dst4))
7650 dst_set = 1;
7651 else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
7652 ;
7653 else {
7654 errmsg ("parse error '%U'\n", format_unformat_error, line_input);
7655 return -99;
7656 }
7657 }
7658
7659 if (src_set == 0) {
7660 errmsg ("tunnel src address not specified\n");
7661 return -99;
7662 }
7663 if (dst_set == 0) {
7664 errmsg ("tunnel dst address not specified\n");
7665 return -99;
7666 }
7667
7668
7669 M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
7670
7671 clib_memcpy(&mp->src_address, &src4, sizeof(src4));
7672 clib_memcpy(&mp->dst_address, &dst4, sizeof(dst4));
7673 mp->outer_table_id = ntohl(outer_fib_id);
7674 mp->is_add = is_add;
7675
7676 S; W;
7677 /* NOTREACHED */
7678 return 0;
7679}
7680
7681static void vl_api_gre_tunnel_details_t_handler
7682(vl_api_gre_tunnel_details_t * mp)
7683{
7684 vat_main_t * vam = &vat_main;
7685
7686 fformat(vam->ofp, "%11d%15U%15U%14d\n",
7687 ntohl(mp->sw_if_index),
7688 format_ip4_address, &mp->src_address,
7689 format_ip4_address, &mp->dst_address,
7690 ntohl(mp->outer_table_id));
7691}
7692
7693static void vl_api_gre_tunnel_details_t_handler_json
7694(vl_api_gre_tunnel_details_t * mp)
7695{
7696 vat_main_t * vam = &vat_main;
7697 vat_json_node_t *node = NULL;
7698 struct in_addr ip4;
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 clib_memcpy(&ip4, &mp->src_address, sizeof(ip4));
7709 vat_json_object_add_ip4(node, "src_address", ip4);
7710 clib_memcpy(&ip4, &mp->dst_address, sizeof(ip4));
7711 vat_json_object_add_ip4(node, "dst_address", ip4);
7712 vat_json_object_add_uint(node, "outer_fib_id", ntohl(mp->outer_table_id));
7713}
7714
7715static int api_gre_tunnel_dump (vat_main_t * vam)
7716{
7717 unformat_input_t * i = vam->input;
7718 vl_api_gre_tunnel_dump_t *mp;
7719 f64 timeout;
7720 u32 sw_if_index;
7721 u8 sw_if_index_set = 0;
7722
7723 /* Parse args required to build the message */
7724 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7725 if (unformat (i, "sw_if_index %d", &sw_if_index))
7726 sw_if_index_set = 1;
7727 else
7728 break;
7729 }
7730
7731 if (sw_if_index_set == 0) {
7732 sw_if_index = ~0;
7733 }
7734
7735 if (!vam->json_output) {
7736 fformat(vam->ofp, "%11s%15s%15s%14s\n",
7737 "sw_if_index", "src_address", "dst_address",
7738 "outer_fib_id");
7739 }
7740
7741 /* Get list of gre-tunnel interfaces */
7742 M(GRE_TUNNEL_DUMP, gre_tunnel_dump);
7743
7744 mp->sw_if_index = htonl(sw_if_index);
7745
7746 S;
7747
7748 /* Use a control ping for synchronization */
7749 {
7750 vl_api_control_ping_t * mp;
7751 M(CONTROL_PING, control_ping);
7752 S;
7753 }
7754 W;
7755}
7756
Ed Warnickecb9cada2015-12-08 15:45:58 -07007757static int api_l2_fib_clear_table (vat_main_t * vam)
7758{
7759// unformat_input_t * i = vam->input;
7760 vl_api_l2_fib_clear_table_t *mp;
7761 f64 timeout;
7762
7763 M(L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
7764
7765 S; W;
7766 /* NOTREACHED */
7767 return 0;
7768}
7769
7770static int api_l2_interface_efp_filter (vat_main_t * vam)
7771{
7772 unformat_input_t * i = vam->input;
7773 vl_api_l2_interface_efp_filter_t *mp;
7774 f64 timeout;
7775 u32 sw_if_index;
7776 u8 enable = 1;
7777 u8 sw_if_index_set = 0;
7778
7779 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7780 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7781 sw_if_index_set = 1;
7782 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7783 sw_if_index_set = 1;
7784 else if (unformat (i, "enable"))
7785 enable = 1;
7786 else if (unformat (i, "disable"))
7787 enable = 0;
7788 else {
7789 clib_warning ("parse error '%U'", format_unformat_error, i);
7790 return -99;
7791 }
7792 }
7793
7794 if (sw_if_index_set == 0) {
7795 errmsg ("missing sw_if_index\n");
7796 return -99;
7797 }
7798
7799 M(L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
7800
7801 mp->sw_if_index = ntohl(sw_if_index);
7802 mp->enable_disable = enable;
7803
7804 S; W;
7805 /* NOTREACHED */
7806 return 0;
7807}
7808
7809#define foreach_vtr_op \
7810_("disable", L2_VTR_DISABLED) \
7811_("push-1", L2_VTR_PUSH_1) \
7812_("push-2", L2_VTR_PUSH_2) \
7813_("pop-1", L2_VTR_POP_1) \
7814_("pop-2", L2_VTR_POP_2) \
7815_("translate-1-1", L2_VTR_TRANSLATE_1_1) \
7816_("translate-1-2", L2_VTR_TRANSLATE_1_2) \
7817_("translate-2-1", L2_VTR_TRANSLATE_2_1) \
7818_("translate-2-2", L2_VTR_TRANSLATE_2_2)
7819
7820static int api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
7821{
7822 unformat_input_t * i = vam->input;
7823 vl_api_l2_interface_vlan_tag_rewrite_t *mp;
7824 f64 timeout;
7825 u32 sw_if_index;
7826 u8 sw_if_index_set = 0;
7827 u8 vtr_op_set = 0;
7828 u32 vtr_op = 0;
7829 u32 push_dot1q = 1;
7830 u32 tag1 = ~0;
7831 u32 tag2 = ~0;
7832
7833 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7834 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7835 sw_if_index_set = 1;
7836 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7837 sw_if_index_set = 1;
7838 else if (unformat (i, "vtr_op %d", &vtr_op))
7839 vtr_op_set = 1;
7840#define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
7841 foreach_vtr_op
7842#undef _
7843
7844 else if (unformat (i, "push_dot1q %d", &push_dot1q))
7845 ;
7846 else if (unformat (i, "tag1 %d", &tag1))
7847 ;
7848 else if (unformat (i, "tag2 %d", &tag2))
7849 ;
7850 else {
7851 clib_warning ("parse error '%U'", format_unformat_error, i);
7852 return -99;
7853 }
7854 }
7855
7856 if ((sw_if_index_set == 0)||(vtr_op_set == 0)) {
7857 errmsg ("missing vtr operation or sw_if_index\n");
7858 return -99;
7859 }
7860
7861 M(L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
7862
7863 mp->sw_if_index = ntohl(sw_if_index);
7864 mp->vtr_op = ntohl(vtr_op);
7865 mp->push_dot1q = ntohl(push_dot1q);
7866 mp->tag1 = ntohl(tag1);
7867 mp->tag2 = ntohl(tag2);
7868
7869 S; W;
7870 /* NOTREACHED */
7871 return 0;
7872}
7873
7874static int api_create_vhost_user_if (vat_main_t * vam)
7875{
7876 unformat_input_t * i = vam->input;
7877 vl_api_create_vhost_user_if_t *mp;
7878 f64 timeout;
7879 u8 * file_name;
7880 u8 is_server = 0;
7881 u8 file_name_set = 0;
7882 u32 custom_dev_instance = ~0;
Pierre Pfisteref65cb02016-02-19 13:52:44 +00007883 u8 hwaddr[6];
7884 u8 use_custom_mac = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -07007885
7886 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7887 if (unformat (i, "socket %s", &file_name)) {
7888 file_name_set = 1;
7889 }
7890 else if (unformat (i, "renumber %"PRIu32, &custom_dev_instance))
7891 ;
Pierre Pfisteref65cb02016-02-19 13:52:44 +00007892 else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
7893 use_custom_mac = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -07007894 else if (unformat (i, "server"))
7895 is_server = 1;
7896 else
7897 break;
7898 }
7899
7900 if (file_name_set == 0) {
7901 errmsg ("missing socket file name\n");
7902 return -99;
7903 }
7904
7905 if (vec_len (file_name) > 255) {
7906 errmsg ("socket file name too long\n");
7907 return -99;
7908 }
7909 vec_add1 (file_name, 0);
7910
7911 M(CREATE_VHOST_USER_IF, create_vhost_user_if);
7912
7913 mp->is_server = is_server;
Damjan Marionf1213b82016-03-13 02:22:06 +01007914 clib_memcpy(mp->sock_filename, file_name, vec_len(file_name));
Ed Warnickecb9cada2015-12-08 15:45:58 -07007915 vec_free(file_name);
7916 if (custom_dev_instance != ~0) {
7917 mp->renumber = 1;
7918 mp->custom_dev_instance = ntohl(custom_dev_instance);
7919 }
Pierre Pfisteref65cb02016-02-19 13:52:44 +00007920 mp->use_custom_mac = use_custom_mac;
Damjan Marionf1213b82016-03-13 02:22:06 +01007921 clib_memcpy(mp->mac_address, hwaddr, 6);
Ed Warnickecb9cada2015-12-08 15:45:58 -07007922
7923 S; W;
7924 /* NOTREACHED */
7925 return 0;
7926}
7927
7928static int api_modify_vhost_user_if (vat_main_t * vam)
7929{
7930 unformat_input_t * i = vam->input;
7931 vl_api_modify_vhost_user_if_t *mp;
7932 f64 timeout;
7933 u8 * file_name;
7934 u8 is_server = 0;
7935 u8 file_name_set = 0;
7936 u32 custom_dev_instance = ~0;
7937 u8 sw_if_index_set = 0;
7938 u32 sw_if_index = (u32)~0;
7939
7940 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7941 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7942 sw_if_index_set = 1;
7943 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7944 sw_if_index_set = 1;
7945 else if (unformat (i, "socket %s", &file_name)) {
7946 file_name_set = 1;
7947 }
7948 else if (unformat (i, "renumber %"PRIu32, &custom_dev_instance))
7949 ;
7950 else if (unformat (i, "server"))
7951 is_server = 1;
7952 else
7953 break;
7954 }
7955
7956 if (sw_if_index_set == 0) {
7957 errmsg ("missing sw_if_index or interface name\n");
7958 return -99;
7959 }
7960
7961 if (file_name_set == 0) {
7962 errmsg ("missing socket file name\n");
7963 return -99;
7964 }
7965
7966 if (vec_len (file_name) > 255) {
7967 errmsg ("socket file name too long\n");
7968 return -99;
7969 }
7970 vec_add1 (file_name, 0);
7971
7972 M(MODIFY_VHOST_USER_IF, modify_vhost_user_if);
7973
7974 mp->sw_if_index = ntohl(sw_if_index);
7975 mp->is_server = is_server;
Damjan Marionf1213b82016-03-13 02:22:06 +01007976 clib_memcpy(mp->sock_filename, file_name, vec_len(file_name));
Ed Warnickecb9cada2015-12-08 15:45:58 -07007977 vec_free(file_name);
7978 if (custom_dev_instance != ~0) {
7979 mp->renumber = 1;
7980 mp->custom_dev_instance = ntohl(custom_dev_instance);
7981 }
7982
7983 S; W;
7984 /* NOTREACHED */
7985 return 0;
7986}
7987
7988static int api_delete_vhost_user_if (vat_main_t * vam)
7989{
7990 unformat_input_t * i = vam->input;
7991 vl_api_delete_vhost_user_if_t *mp;
7992 f64 timeout;
7993 u32 sw_if_index = ~0;
7994 u8 sw_if_index_set = 0;
7995
7996 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7997 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7998 sw_if_index_set = 1;
7999 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8000 sw_if_index_set = 1;
8001 else
8002 break;
8003 }
8004
8005 if (sw_if_index_set == 0) {
8006 errmsg ("missing sw_if_index or interface name\n");
8007 return -99;
8008 }
8009
8010
8011 M(DELETE_VHOST_USER_IF, delete_vhost_user_if);
8012
8013 mp->sw_if_index = ntohl(sw_if_index);
8014
8015 S; W;
8016 /* NOTREACHED */
8017 return 0;
8018}
8019
8020static void vl_api_sw_interface_vhost_user_details_t_handler
8021(vl_api_sw_interface_vhost_user_details_t * mp)
8022{
8023 vat_main_t * vam = &vat_main;
8024
8025 fformat(vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
8026 (char *)mp->interface_name,
8027 ntohl(mp->sw_if_index), ntohl(mp->virtio_net_hdr_sz),
8028 clib_net_to_host_u64(mp->features), mp->is_server,
8029 ntohl(mp->num_regions), (char *)mp->sock_filename);
8030 fformat(vam->ofp, " Status: '%s'\n", strerror(ntohl(mp->sock_errno)));
8031}
8032
8033static void vl_api_sw_interface_vhost_user_details_t_handler_json
8034(vl_api_sw_interface_vhost_user_details_t * mp)
8035{
8036 vat_main_t * vam = &vat_main;
8037 vat_json_node_t *node = NULL;
8038
8039 if (VAT_JSON_ARRAY != vam->json_tree.type) {
8040 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
8041 vat_json_init_array(&vam->json_tree);
8042 }
8043 node = vat_json_array_add(&vam->json_tree);
8044
8045 vat_json_init_object(node);
8046 vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
8047 vat_json_object_add_string_copy(node, "interface_name", mp->interface_name);
8048 vat_json_object_add_uint(node, "virtio_net_hdr_sz", ntohl(mp->virtio_net_hdr_sz));
8049 vat_json_object_add_uint(node, "features", clib_net_to_host_u64(mp->features));
8050 vat_json_object_add_uint(node, "is_server", mp->is_server);
8051 vat_json_object_add_string_copy(node, "sock_filename", mp->sock_filename);
8052 vat_json_object_add_uint(node, "num_regions", ntohl(mp->num_regions));
8053 vat_json_object_add_uint(node, "sock_errno", ntohl(mp->sock_errno));
8054}
8055
8056static int api_sw_interface_vhost_user_dump (vat_main_t * vam)
8057{
8058 vl_api_sw_interface_vhost_user_dump_t *mp;
8059 f64 timeout;
8060 fformat(vam->ofp, "Interface name idx hdr_sz features server regions filename\n");
8061
8062 /* Get list of vhost-user interfaces */
8063 M(SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
8064 S;
8065
8066 /* Use a control ping for synchronization */
8067 {
8068 vl_api_control_ping_t * mp;
8069 M(CONTROL_PING, control_ping);
8070 S;
8071 }
8072 W;
8073}
8074
8075static int api_show_version (vat_main_t * vam)
8076{
8077 vl_api_show_version_t *mp;
8078 f64 timeout;
8079
8080 M(SHOW_VERSION, show_version);
8081
8082 S; W;
8083 /* NOTREACHED */
8084 return 0;
8085}
8086
Ed Warnickecb9cada2015-12-08 15:45:58 -07008087
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07008088static int api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
Ed Warnickecb9cada2015-12-08 15:45:58 -07008089{
8090 unformat_input_t * line_input = vam->input;
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07008091 vl_api_vxlan_gpe_add_del_tunnel_t *mp;
Ed Warnickecb9cada2015-12-08 15:45:58 -07008092 f64 timeout;
Hongjun Nidf921cc2016-05-25 01:16:19 +08008093 ip4_address_t local4, remote4;
8094 ip6_address_t local6, remote6;
Ed Warnickecb9cada2015-12-08 15:45:58 -07008095 u8 is_add = 1;
Hongjun Nidf921cc2016-05-25 01:16:19 +08008096 u8 ipv4_set = 0, ipv6_set = 0;
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07008097 u8 local_set = 0;
8098 u8 remote_set = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -07008099 u32 encap_vrf_id = 0;
8100 u32 decap_vrf_id = 0;
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07008101 u8 protocol = ~0;
Ed Warnickecb9cada2015-12-08 15:45:58 -07008102 u32 vni;
8103 u8 vni_set = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -07008104
8105 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
8106 if (unformat (line_input, "del"))
8107 is_add = 0;
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07008108 else if (unformat (line_input, "local %U",
Hongjun Nidf921cc2016-05-25 01:16:19 +08008109 unformat_ip4_address, &local4))
8110 {
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07008111 local_set = 1;
Hongjun Nidf921cc2016-05-25 01:16:19 +08008112 ipv4_set = 1;
8113 }
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07008114 else if (unformat (line_input, "remote %U",
Hongjun Nidf921cc2016-05-25 01:16:19 +08008115 unformat_ip4_address, &remote4))
8116 {
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07008117 remote_set = 1;
Hongjun Nidf921cc2016-05-25 01:16:19 +08008118 ipv4_set = 1;
8119 }
8120 else if (unformat (line_input, "local %U",
8121 unformat_ip6_address, &local6))
8122 {
8123 local_set = 1;
8124 ipv6_set = 1;
8125 }
8126 else if (unformat (line_input, "remote %U",
8127 unformat_ip6_address, &remote6))
8128 {
8129 remote_set = 1;
8130 ipv6_set = 1;
8131 }
Ed Warnickecb9cada2015-12-08 15:45:58 -07008132 else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
8133 ;
8134 else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
8135 ;
Ed Warnickecb9cada2015-12-08 15:45:58 -07008136 else if (unformat (line_input, "vni %d", &vni))
8137 vni_set = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -07008138 else if (unformat(line_input, "next-ip4"))
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07008139 protocol = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -07008140 else if (unformat(line_input, "next-ip6"))
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07008141 protocol = 2;
Ed Warnickecb9cada2015-12-08 15:45:58 -07008142 else if (unformat(line_input, "next-ethernet"))
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07008143 protocol = 3;
8144 else if (unformat(line_input, "next-nsh"))
8145 protocol = 4;
Ed Warnickecb9cada2015-12-08 15:45:58 -07008146 else {
8147 errmsg ("parse error '%U'\n", format_unformat_error, line_input);
8148 return -99;
8149 }
8150 }
8151
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07008152 if (local_set == 0) {
8153 errmsg ("tunnel local address not specified\n");
Ed Warnickecb9cada2015-12-08 15:45:58 -07008154 return -99;
8155 }
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07008156 if (remote_set == 0) {
8157 errmsg ("tunnel remote address not specified\n");
Ed Warnickecb9cada2015-12-08 15:45:58 -07008158 return -99;
8159 }
Hongjun Nidf921cc2016-05-25 01:16:19 +08008160 if (ipv4_set && ipv6_set) {
8161 errmsg ("both IPv4 and IPv6 addresses specified");
8162 return -99;
8163 }
Ed Warnickecb9cada2015-12-08 15:45:58 -07008164
Ed Warnickecb9cada2015-12-08 15:45:58 -07008165 if (vni_set == 0) {
8166 errmsg ("vni not specified\n");
8167 return -99;
8168 }
8169
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07008170 M(VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
Ed Warnickecb9cada2015-12-08 15:45:58 -07008171
Hongjun Nidf921cc2016-05-25 01:16:19 +08008172
8173 if (ipv6_set) {
8174 clib_memcpy(&mp->local, &local6, sizeof(local6));
8175 clib_memcpy(&mp->remote, &remote6, sizeof(remote6));
8176 } else {
8177 clib_memcpy(&mp->local, &local4, sizeof(local4));
8178 clib_memcpy(&mp->remote, &remote4, sizeof(remote4));
8179 }
8180
Ed Warnickecb9cada2015-12-08 15:45:58 -07008181 mp->encap_vrf_id = ntohl(encap_vrf_id);
8182 mp->decap_vrf_id = ntohl(decap_vrf_id);
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07008183 mp->protocol = ntohl(protocol);
Ed Warnickecb9cada2015-12-08 15:45:58 -07008184 mp->vni = ntohl(vni);
8185 mp->is_add = is_add;
Hongjun Nidf921cc2016-05-25 01:16:19 +08008186 mp->is_ipv6 = ipv6_set;
Ed Warnickecb9cada2015-12-08 15:45:58 -07008187
8188 S; W;
8189 /* NOTREACHED */
8190 return 0;
8191}
8192
Hongjun Ni0e06e2b2016-05-30 19:45:51 +08008193static void vl_api_vxlan_gpe_tunnel_details_t_handler
8194(vl_api_vxlan_gpe_tunnel_details_t * mp)
8195{
8196 vat_main_t * vam = &vat_main;
8197
8198 fformat(vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
8199 ntohl(mp->sw_if_index),
8200 format_ip46_address, &(mp->local[0]),
8201 format_ip46_address, &(mp->remote[0]),
8202 ntohl(mp->vni),
8203 ntohl(mp->protocol),
8204 ntohl(mp->encap_vrf_id),
8205 ntohl(mp->decap_vrf_id));
8206}
8207
8208static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
8209(vl_api_vxlan_gpe_tunnel_details_t * mp)
8210{
8211 vat_main_t * vam = &vat_main;
8212 vat_json_node_t *node = NULL;
8213 struct in_addr ip4;
8214 struct in6_addr ip6;
8215
8216 if (VAT_JSON_ARRAY != vam->json_tree.type) {
8217 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
8218 vat_json_init_array(&vam->json_tree);
8219 }
8220 node = vat_json_array_add(&vam->json_tree);
8221
8222 vat_json_init_object(node);
8223 vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
8224 if (mp->is_ipv6) {
8225 clib_memcpy(&ip6, &(mp->local[0]), sizeof(ip6));
8226 vat_json_object_add_ip6(node, "local", ip6);
8227 clib_memcpy(&ip6, &(mp->remote[0]), sizeof(ip6));
8228 vat_json_object_add_ip6(node, "remote", ip6);
8229 } else {
8230 clib_memcpy(&ip4, &(mp->local[0]), sizeof(ip4));
8231 vat_json_object_add_ip4(node, "local", ip4);
8232 clib_memcpy(&ip4, &(mp->remote[0]), sizeof(ip4));
8233 vat_json_object_add_ip4(node, "remote", ip4);
8234 }
8235 vat_json_object_add_uint(node, "vni", ntohl(mp->vni));
8236 vat_json_object_add_uint(node, "protocol", ntohl(mp->protocol));
8237 vat_json_object_add_uint(node, "encap_vrf_id", ntohl(mp->encap_vrf_id));
8238 vat_json_object_add_uint(node, "decap_vrf_id", ntohl(mp->decap_vrf_id));
8239 vat_json_object_add_uint(node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
8240}
8241
8242static int api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
8243{
8244 unformat_input_t * i = vam->input;
8245 vl_api_vxlan_gpe_tunnel_dump_t *mp;
8246 f64 timeout;
8247 u32 sw_if_index;
8248 u8 sw_if_index_set = 0;
8249
8250 /* Parse args required to build the message */
8251 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8252 if (unformat (i, "sw_if_index %d", &sw_if_index))
8253 sw_if_index_set = 1;
8254 else
8255 break;
8256 }
8257
8258 if (sw_if_index_set == 0) {
8259 sw_if_index = ~0;
8260 }
8261
8262 if (!vam->json_output) {
8263 fformat(vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
8264 "sw_if_index", "local", "remote", "vni",
8265 "protocol","encap_vrf_id", "decap_vrf_id");
8266 }
8267
8268 /* Get list of vxlan-tunnel interfaces */
8269 M(VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
8270
8271 mp->sw_if_index = htonl(sw_if_index);
8272
8273 S;
8274
8275 /* Use a control ping for synchronization */
8276 {
8277 vl_api_control_ping_t * mp;
8278 M(CONTROL_PING, control_ping);
8279 S;
8280 }
8281 W;
8282}
8283
Ed Warnickecb9cada2015-12-08 15:45:58 -07008284u8 * format_l2_fib_mac_address (u8 * s, va_list * args)
8285{
8286 u8 * a = va_arg (*args, u8 *);
8287
8288 return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
8289 a[2], a[3], a[4], a[5], a[6], a[7]);
8290}
8291
8292static void vl_api_l2_fib_table_entry_t_handler
8293(vl_api_l2_fib_table_entry_t * mp)
8294{
8295 vat_main_t * vam = &vat_main;
8296
8297 fformat(vam->ofp, "%3" PRIu32 " %U %3" PRIu32
8298 " %d %d %d\n",
8299 ntohl(mp->bd_id), format_l2_fib_mac_address, &mp->mac,
8300 ntohl(mp->sw_if_index), mp->static_mac, mp->filter_mac,
8301 mp->bvi_mac);
8302}
8303
8304static void vl_api_l2_fib_table_entry_t_handler_json
8305(vl_api_l2_fib_table_entry_t * mp)
8306{
8307 vat_main_t * vam = &vat_main;
8308 vat_json_node_t *node = NULL;
8309
8310 if (VAT_JSON_ARRAY != vam->json_tree.type) {
8311 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
8312 vat_json_init_array(&vam->json_tree);
8313 }
8314 node = vat_json_array_add(&vam->json_tree);
8315
8316 vat_json_init_object(node);
8317 vat_json_object_add_uint(node, "bd_id", ntohl(mp->bd_id));
8318 vat_json_object_add_uint(node, "mac", clib_net_to_host_u64(mp->mac));
8319 vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
8320 vat_json_object_add_uint(node, "static_mac", mp->static_mac);
8321 vat_json_object_add_uint(node, "filter_mac", mp->filter_mac);
8322 vat_json_object_add_uint(node, "bvi_mac", mp->bvi_mac);
8323}
8324
8325static int api_l2_fib_table_dump (vat_main_t * vam)
8326{
8327 unformat_input_t * i = vam->input;
8328 vl_api_l2_fib_table_dump_t *mp;
8329 f64 timeout;
8330 u32 bd_id;
8331 u8 bd_id_set = 0;
8332
8333 /* Parse args required to build the message */
8334 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8335 if (unformat (i, "bd_id %d", &bd_id))
8336 bd_id_set = 1;
8337 else
8338 break;
8339 }
8340
8341 if (bd_id_set == 0) {
8342 errmsg ("missing bridge domain\n");
8343 return -99;
8344 }
8345
8346 fformat(vam->ofp, "BD-ID Mac Address sw-ndx Static Filter BVI\n");
8347
8348 /* Get list of l2 fib entries */
8349 M(L2_FIB_TABLE_DUMP, l2_fib_table_dump);
8350
8351 mp->bd_id = ntohl(bd_id);
8352 S;
8353
8354 /* Use a control ping for synchronization */
8355 {
8356 vl_api_control_ping_t * mp;
8357 M(CONTROL_PING, control_ping);
8358 S;
8359 }
8360 W;
8361}
8362
8363
8364static int
8365api_interface_name_renumber (vat_main_t * vam)
8366{
8367 unformat_input_t * line_input = vam->input;
8368 vl_api_interface_name_renumber_t *mp;
8369 u32 sw_if_index = ~0;
8370 f64 timeout;
8371 u32 new_show_dev_instance = ~0;
8372
8373 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
8374 if (unformat (line_input, "%U", unformat_sw_if_index, vam,
8375 &sw_if_index))
8376 ;
8377 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
8378 ;
8379 else if (unformat (line_input, "new_show_dev_instance %d",
8380 &new_show_dev_instance))
8381 ;
8382 else
8383 break;
8384 }
8385
8386 if (sw_if_index == ~0) {
8387 errmsg ("missing interface name or sw_if_index\n");
8388 return -99;
8389 }
8390
8391 if (new_show_dev_instance == ~0) {
8392 errmsg ("missing new_show_dev_instance\n");
8393 return -99;
8394 }
8395
8396 M(INTERFACE_NAME_RENUMBER, interface_name_renumber);
8397
8398 mp->sw_if_index = ntohl (sw_if_index);
8399 mp->new_show_dev_instance = ntohl (new_show_dev_instance);
8400
8401 S; W;
8402}
8403
8404static int
8405api_want_ip4_arp_events (vat_main_t * vam)
8406{
8407 unformat_input_t * line_input = vam->input;
8408 vl_api_want_ip4_arp_events_t * mp;
8409 f64 timeout;
8410 ip4_address_t address;
8411 int address_set = 0;
8412 u32 enable_disable = 1;
8413
8414 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
8415 if (unformat (line_input, "address %U",
8416 unformat_ip4_address, &address))
8417 address_set = 1;
8418 else if (unformat (line_input, "del"))
8419 enable_disable = 0;
8420 else
8421 break;
8422 }
8423
8424 if (address_set == 0) {
8425 errmsg ("missing addresses\n");
8426 return -99;
8427 }
8428
8429 M(WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
8430 mp->enable_disable = enable_disable;
8431 mp->pid = getpid();
8432 mp->address = address.as_u32;
8433
8434 S; W;
8435}
8436
8437static int api_input_acl_set_interface (vat_main_t * vam)
8438{
8439 unformat_input_t * i = vam->input;
8440 vl_api_input_acl_set_interface_t *mp;
8441 f64 timeout;
8442 u32 sw_if_index;
8443 int sw_if_index_set;
8444 u32 ip4_table_index = ~0;
8445 u32 ip6_table_index = ~0;
8446 u32 l2_table_index = ~0;
8447 u8 is_add = 1;
8448
8449 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8450 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8451 sw_if_index_set = 1;
8452 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8453 sw_if_index_set = 1;
8454 else if (unformat (i, "del"))
8455 is_add = 0;
8456 else if (unformat (i, "ip4-table %d", &ip4_table_index))
8457 ;
8458 else if (unformat (i, "ip6-table %d", &ip6_table_index))
8459 ;
8460 else if (unformat (i, "l2-table %d", &l2_table_index))
8461 ;
8462 else {
8463 clib_warning ("parse error '%U'", format_unformat_error, i);
8464 return -99;
8465 }
8466 }
8467
8468 if (sw_if_index_set == 0) {
8469 errmsg ("missing interface name or sw_if_index\n");
8470 return -99;
8471 }
8472
8473 M(INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
8474
8475 mp->sw_if_index = ntohl(sw_if_index);
8476 mp->ip4_table_index = ntohl(ip4_table_index);
8477 mp->ip6_table_index = ntohl(ip6_table_index);
8478 mp->l2_table_index = ntohl(l2_table_index);
8479 mp->is_add = is_add;
8480
8481 S; W;
8482 /* NOTREACHED */
8483 return 0;
8484}
8485
8486static int
8487api_ip_address_dump (vat_main_t * vam)
8488{
8489 unformat_input_t * i = vam->input;
8490 vl_api_ip_address_dump_t * mp;
8491 u32 sw_if_index = ~0;
8492 u8 sw_if_index_set = 0;
8493 u8 ipv4_set = 0;
8494 u8 ipv6_set = 0;
8495 f64 timeout;
8496
8497 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8498 if (unformat (i, "sw_if_index %d", &sw_if_index))
8499 sw_if_index_set = 1;
8500 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8501 sw_if_index_set = 1;
8502 else if (unformat (i, "ipv4"))
8503 ipv4_set = 1;
8504 else if (unformat (i, "ipv6"))
8505 ipv6_set = 1;
8506 else
8507 break;
8508 }
8509
8510 if (ipv4_set && ipv6_set) {
8511 errmsg ("ipv4 and ipv6 flags cannot be both set\n");
8512 return -99;
8513 }
8514
8515 if ((!ipv4_set) && (!ipv6_set)) {
8516 errmsg ("no ipv4 nor ipv6 flag set\n");
8517 return -99;
8518 }
8519
8520 if (sw_if_index_set == 0) {
8521 errmsg ("missing interface name or sw_if_index\n");
8522 return -99;
8523 }
8524
8525 vam->current_sw_if_index = sw_if_index;
8526 vam->is_ipv6 = ipv6_set;
8527
8528 M(IP_ADDRESS_DUMP, ip_address_dump);
8529 mp->sw_if_index = ntohl(sw_if_index);
8530 mp->is_ipv6 = ipv6_set;
8531 S;
8532
8533 /* Use a control ping for synchronization */
8534 {
8535 vl_api_control_ping_t * mp;
8536 M(CONTROL_PING, control_ping);
8537 S;
8538 }
8539 W;
8540}
8541
8542static int
8543api_ip_dump (vat_main_t * vam)
8544{
8545 vl_api_ip_dump_t * mp;
8546 unformat_input_t * in = vam->input;
8547 int ipv4_set = 0;
8548 int ipv6_set = 0;
8549 int is_ipv6;
8550 f64 timeout;
8551 int i;
8552
8553 while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT) {
8554 if (unformat (in, "ipv4"))
8555 ipv4_set = 1;
8556 else if (unformat (in, "ipv6"))
8557 ipv6_set = 1;
8558 else
8559 break;
8560 }
8561
8562 if (ipv4_set && ipv6_set) {
8563 errmsg ("ipv4 and ipv6 flags cannot be both set\n");
8564 return -99;
8565 }
8566
8567 if ((!ipv4_set) && (!ipv6_set)) {
8568 errmsg ("no ipv4 nor ipv6 flag set\n");
8569 return -99;
8570 }
8571
8572 is_ipv6 = ipv6_set;
8573 vam->is_ipv6 = is_ipv6;
8574
8575 /* free old data */
8576 for (i = 0; i < vec_len(vam->ip_details_by_sw_if_index[is_ipv6]); i++) {
8577 vec_free(vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
8578 }
8579 vec_free(vam->ip_details_by_sw_if_index[is_ipv6]);
8580
8581 M(IP_DUMP, ip_dump);
8582 mp->is_ipv6 = ipv6_set;
8583 S;
8584
8585 /* Use a control ping for synchronization */
8586 {
8587 vl_api_control_ping_t * mp;
8588 M(CONTROL_PING, control_ping);
8589 S;
8590 }
8591 W;
8592}
8593
8594static int
8595api_ipsec_spd_add_del (vat_main_t * vam)
8596{
Dave Barachbfdedbd2016-01-20 09:11:55 -05008597#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -07008598 unformat_input_t * i = vam->input;
8599 vl_api_ipsec_spd_add_del_t *mp;
8600 f64 timeout;
8601 u32 spd_id = ~0;
8602 u8 is_add = 1;
8603
8604 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8605 if (unformat (i, "spd_id %d", &spd_id))
8606 ;
8607 else if (unformat (i, "del"))
8608 is_add = 0;
8609 else {
8610 clib_warning ("parse error '%U'", format_unformat_error, i);
8611 return -99;
8612 }
8613 }
8614 if (spd_id == ~0) {
8615 errmsg ("spd_id must be set\n");
8616 return -99;
8617 }
8618
8619 M(IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
8620
8621 mp->spd_id = ntohl(spd_id);
8622 mp->is_add = is_add;
8623
8624 S; W;
8625 /* NOTREACHED */
8626 return 0;
Dave Barachbfdedbd2016-01-20 09:11:55 -05008627#else
8628 clib_warning ("unsupported (no dpdk)");
8629 return -99;
8630#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -07008631}
8632
8633static int
8634api_ipsec_interface_add_del_spd (vat_main_t * vam)
8635{
Dave Barachbfdedbd2016-01-20 09:11:55 -05008636#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -07008637 unformat_input_t * i = vam->input;
8638 vl_api_ipsec_interface_add_del_spd_t *mp;
8639 f64 timeout;
8640 u32 sw_if_index;
8641 u8 sw_if_index_set = 0;
8642 u32 spd_id = (u32) ~0;
8643 u8 is_add = 1;
8644
8645 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8646 if (unformat (i, "del"))
8647 is_add = 0;
8648 else if (unformat (i, "spd_id %d", &spd_id))
8649 ;
8650 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8651 sw_if_index_set = 1;
8652 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8653 sw_if_index_set = 1;
8654 else {
8655 clib_warning ("parse error '%U'", format_unformat_error, i);
8656 return -99;
8657 }
8658
8659 }
8660
8661 if (spd_id == (u32) ~0) {
8662 errmsg ("spd_id must be set\n");
8663 return -99;
8664 }
8665
8666 if (sw_if_index_set == 0) {
8667 errmsg ("missing interface name or sw_if_index\n");
8668 return -99;
8669 }
8670
8671 M(IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
8672
8673 mp->spd_id = ntohl(spd_id);
8674 mp->sw_if_index = ntohl (sw_if_index);
8675 mp->is_add = is_add;
8676
8677 S; W;
8678 /* NOTREACHED */
8679 return 0;
Dave Barachbfdedbd2016-01-20 09:11:55 -05008680#else
8681 clib_warning ("unsupported (no dpdk)");
8682 return -99;
8683#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -07008684}
8685
8686static int
8687api_ipsec_spd_add_del_entry (vat_main_t * vam)
8688{
Dave Barachbfdedbd2016-01-20 09:11:55 -05008689#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -07008690 unformat_input_t * i = vam->input;
8691 vl_api_ipsec_spd_add_del_entry_t *mp;
8692 f64 timeout;
8693 u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
8694 u32 spd_id, sa_id, protocol = 0, policy = 0;
8695 i32 priority;
8696 u32 rport_start = 0, rport_stop = (u32) ~0;
8697 u32 lport_start = 0, lport_stop = (u32) ~0;
8698 ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
8699 ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
8700
8701 laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
8702 laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~0;
8703 laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
8704 laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
8705 laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~0;
8706 laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~0;
8707
8708 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8709 if (unformat (i, "del"))
8710 is_add = 0;
8711 if (unformat (i, "outbound"))
8712 is_outbound = 1;
8713 if (unformat (i, "inbound"))
8714 is_outbound = 0;
8715 else if (unformat (i, "spd_id %d", &spd_id))
8716 ;
8717 else if (unformat (i, "sa_id %d", &sa_id))
8718 ;
8719 else if (unformat (i, "priority %d", &priority))
8720 ;
8721 else if (unformat (i, "protocol %d", &protocol))
8722 ;
8723 else if (unformat (i, "lport_start %d", &lport_start))
8724 ;
8725 else if (unformat (i, "lport_stop %d", &lport_stop))
8726 ;
8727 else if (unformat (i, "rport_start %d", &rport_start))
8728 ;
8729 else if (unformat (i, "rport_stop %d", &rport_stop))
8730 ;
8731 else if (unformat (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
8732 {
8733 is_ipv6 = 0;
8734 is_ip_any =0;
8735 }
8736 else if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
8737 {
8738 is_ipv6 = 0;
8739 is_ip_any = 0;
8740 }
8741 else if (unformat (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
8742 {
8743 is_ipv6 = 0;
8744 is_ip_any = 0;
8745 }
8746 else if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
8747 {
8748 is_ipv6 = 0;
8749 is_ip_any = 0;
8750 }
8751 else if (unformat (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
8752 {
8753 is_ipv6 = 1;
8754 is_ip_any = 0;
8755 }
8756 else if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
8757 {
8758 is_ipv6 = 1;
8759 is_ip_any = 0;
8760 }
8761 else if (unformat (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
8762 {
8763 is_ipv6 = 1;
8764 is_ip_any = 0;
8765 }
8766 else if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
8767 {
8768 is_ipv6 = 1;
8769 is_ip_any = 0;
8770 }
8771 else if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
8772 {
8773 if (policy == IPSEC_POLICY_ACTION_RESOLVE) {
8774 clib_warning ("unsupported action: 'resolve'");
8775 return -99;
8776 }
8777 }
8778 else {
8779 clib_warning ("parse error '%U'", format_unformat_error, i);
8780 return -99;
8781 }
8782
8783 }
8784
8785 M(IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
8786
8787 mp->spd_id = ntohl(spd_id);
8788 mp->priority = ntohl(priority);
8789 mp->is_outbound = is_outbound;
8790
8791 mp->is_ipv6 = is_ipv6;
8792 if (is_ipv6 || is_ip_any) {
Damjan Marionf1213b82016-03-13 02:22:06 +01008793 clib_memcpy (mp->remote_address_start, &raddr6_start, sizeof(ip6_address_t));
8794 clib_memcpy (mp->remote_address_stop, &raddr6_stop, sizeof(ip6_address_t));
8795 clib_memcpy (mp->local_address_start, &laddr6_start, sizeof(ip6_address_t));
8796 clib_memcpy (mp->local_address_stop, &laddr6_stop, sizeof(ip6_address_t));
Ed Warnickecb9cada2015-12-08 15:45:58 -07008797 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01008798 clib_memcpy (mp->remote_address_start, &raddr4_start, sizeof(ip4_address_t));
8799 clib_memcpy (mp->remote_address_stop, &raddr4_stop, sizeof(ip4_address_t));
8800 clib_memcpy (mp->local_address_start, &laddr4_start, sizeof(ip4_address_t));
8801 clib_memcpy (mp->local_address_stop, &laddr4_stop, sizeof(ip4_address_t));
Ed Warnickecb9cada2015-12-08 15:45:58 -07008802 }
8803 mp->protocol = (u8) protocol;
8804 mp->local_port_start = ntohs((u16) lport_start);
8805 mp->local_port_stop = ntohs((u16) lport_stop);
8806 mp->remote_port_start = ntohs((u16) rport_start);
8807 mp->remote_port_stop = ntohs((u16) rport_stop);
8808 mp->policy = (u8) policy;
8809 mp->sa_id = ntohl(sa_id);
8810 mp->is_add = is_add;
8811 mp->is_ip_any = is_ip_any;
8812 S; W;
8813 /* NOTREACHED */
8814 return 0;
Dave Barachbfdedbd2016-01-20 09:11:55 -05008815#else
8816 clib_warning ("unsupported (no dpdk)");
8817 return -99;
8818#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -07008819}
8820
8821static int
8822api_ipsec_sad_add_del_entry (vat_main_t * vam)
8823{
Dave Barachbfdedbd2016-01-20 09:11:55 -05008824#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -07008825 unformat_input_t * i = vam->input;
8826 vl_api_ipsec_sad_add_del_entry_t *mp;
8827 f64 timeout;
8828 u32 sad_id, spi;
8829 u8 * ck, * ik;
8830 u8 is_add = 1;
8831
8832 u8 protocol = IPSEC_PROTOCOL_AH;
8833 u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
8834 u32 crypto_alg = 0, integ_alg = 0;
8835 ip4_address_t tun_src4;
8836 ip4_address_t tun_dst4;
8837 ip6_address_t tun_src6;
8838 ip6_address_t tun_dst6;
8839
8840 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8841 if (unformat (i, "del"))
8842 is_add = 0;
8843 else if (unformat (i, "sad_id %d", &sad_id))
8844 ;
8845 else if (unformat (i, "spi %d", &spi))
8846 ;
8847 else if (unformat (i, "esp"))
8848 protocol = IPSEC_PROTOCOL_ESP;
8849 else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4)) {
8850 is_tunnel = 1;
8851 is_tunnel_ipv6 = 0;
8852 }
8853 else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4)) {
8854 is_tunnel = 1;
8855 is_tunnel_ipv6 = 0;
8856 }
8857 else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6)) {
8858 is_tunnel = 1;
8859 is_tunnel_ipv6 = 1;
8860 }
8861 else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6)) {
8862 is_tunnel = 1;
8863 is_tunnel_ipv6 = 1;
8864 }
8865 else if (unformat (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg)) {
8866 if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
8867 crypto_alg > IPSEC_INTEG_ALG_SHA_512_256) {
8868 clib_warning ("unsupported crypto-alg: '%U'",
8869 format_ipsec_crypto_alg, crypto_alg);
8870 return -99;
8871 }
8872 }
8873 else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
8874 ;
8875 else if (unformat (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg)) {
8876 if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
8877 integ_alg > IPSEC_INTEG_ALG_SHA_512_256) {
8878 clib_warning ("unsupported integ-alg: '%U'",
8879 format_ipsec_integ_alg, integ_alg);
8880 return -99;
8881 }
8882 }
8883 else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
8884 ;
8885 else {
8886 clib_warning ("parse error '%U'", format_unformat_error, i);
8887 return -99;
8888 }
8889
8890 }
8891
8892 M(IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
8893
8894 mp->sad_id = ntohl(sad_id);
8895 mp->is_add = is_add;
8896 mp->protocol = protocol;
8897 mp->spi = ntohl(spi);
8898 mp->is_tunnel = is_tunnel;
8899 mp->is_tunnel_ipv6 = is_tunnel_ipv6;
8900 mp->crypto_algorithm = crypto_alg;
8901 mp->integrity_algorithm = integ_alg;
8902 mp->crypto_key_length = vec_len(ck);
8903 mp->integrity_key_length = vec_len(ik);
8904
8905 if (mp->crypto_key_length > sizeof(mp->crypto_key))
8906 mp->crypto_key_length = sizeof(mp->crypto_key);
8907
8908 if (mp->integrity_key_length > sizeof(mp->integrity_key))
8909 mp->integrity_key_length = sizeof(mp->integrity_key);
8910
Damjan Marionf1213b82016-03-13 02:22:06 +01008911 clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
8912 clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
Ed Warnickecb9cada2015-12-08 15:45:58 -07008913
8914 if (is_tunnel) {
8915 if (is_tunnel_ipv6) {
Damjan Marionf1213b82016-03-13 02:22:06 +01008916 clib_memcpy (mp->tunnel_src_address, &tun_src6, sizeof(ip6_address_t));
8917 clib_memcpy (mp->tunnel_dst_address, &tun_dst6, sizeof(ip6_address_t));
Ed Warnickecb9cada2015-12-08 15:45:58 -07008918 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01008919 clib_memcpy (mp->tunnel_src_address, &tun_src4, sizeof(ip4_address_t));
8920 clib_memcpy (mp->tunnel_dst_address, &tun_dst4, sizeof(ip4_address_t));
Ed Warnickecb9cada2015-12-08 15:45:58 -07008921 }
8922 }
8923
8924 S; W;
8925 /* NOTREACHED */
8926 return 0;
Dave Barachbfdedbd2016-01-20 09:11:55 -05008927#else
8928 clib_warning ("unsupported (no dpdk)");
8929 return -99;
8930#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -07008931}
8932
8933static int
8934api_ipsec_sa_set_key (vat_main_t * vam)
8935{
Dave Barachbfdedbd2016-01-20 09:11:55 -05008936#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -07008937 unformat_input_t * i = vam->input;
8938 vl_api_ipsec_sa_set_key_t *mp;
8939 f64 timeout;
8940 u32 sa_id;
8941 u8 * ck, * ik;
8942
8943 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8944 if (unformat (i, "sa_id %d", &sa_id))
8945 ;
8946 else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
8947 ;
8948 else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
8949 ;
8950 else {
8951 clib_warning ("parse error '%U'", format_unformat_error, i);
8952 return -99;
8953 }
8954 }
8955
8956 M(IPSEC_SA_SET_KEY, ipsec_set_sa_key);
8957
8958 mp->sa_id = ntohl(sa_id);
8959 mp->crypto_key_length = vec_len(ck);
8960 mp->integrity_key_length = vec_len(ik);
8961
8962 if (mp->crypto_key_length > sizeof(mp->crypto_key))
8963 mp->crypto_key_length = sizeof(mp->crypto_key);
8964
8965 if (mp->integrity_key_length > sizeof(mp->integrity_key))
8966 mp->integrity_key_length = sizeof(mp->integrity_key);
8967
Damjan Marionf1213b82016-03-13 02:22:06 +01008968 clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
8969 clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
Ed Warnickecb9cada2015-12-08 15:45:58 -07008970
8971 S; W;
8972 /* NOTREACHED */
8973 return 0;
Dave Barachbfdedbd2016-01-20 09:11:55 -05008974#else
8975 clib_warning ("unsupported (no dpdk)");
8976 return -99;
8977#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -07008978}
8979
Matus Fabiane5f42fe2016-04-08 11:18:08 +02008980static int
8981api_ikev2_profile_add_del (vat_main_t * vam)
8982{
8983#if DPDK > 0
8984 unformat_input_t * i = vam->input;
8985 vl_api_ikev2_profile_add_del_t * mp;
8986 f64 timeout;
8987 u8 is_add = 1;
8988 u8 * name = 0;
8989
8990 const char * valid_chars = "a-zA-Z0-9_";
8991
8992 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8993 if (unformat (i, "del"))
8994 is_add = 0;
8995 else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
8996 vec_add1 (name, 0);
8997 else {
8998 errmsg ("parse error '%U'", format_unformat_error, i);
8999 return -99;
9000 }
9001 }
9002
9003 if (!vec_len (name)) {
9004 errmsg ("profile name must be specified");
9005 return -99;
9006 }
9007
9008 if (vec_len (name) > 64) {
9009 errmsg ("profile name too long");
9010 return -99;
9011 }
9012
9013 M(IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
9014
Damjan Marionf1213b82016-03-13 02:22:06 +01009015 clib_memcpy(mp->name, name, vec_len (name));
Matus Fabiane5f42fe2016-04-08 11:18:08 +02009016 mp->is_add = is_add;
9017 vec_free (name);
9018
9019 S; W;
9020 /* NOTREACHED */
9021 return 0;
9022#else
9023 clib_warning ("unsupported (no dpdk)");
9024 return -99;
9025#endif
9026}
9027
9028static int
9029api_ikev2_profile_set_auth (vat_main_t * vam)
9030{
9031#if DPDK > 0
9032 unformat_input_t * i = vam->input;
9033 vl_api_ikev2_profile_set_auth_t * mp;
9034 f64 timeout;
9035 u8 * name = 0;
9036 u8 * data = 0;
9037 u32 auth_method = 0;
9038 u8 is_hex = 0;
9039
9040 const char * valid_chars = "a-zA-Z0-9_";
9041
9042 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9043 if (unformat (i, "name %U", unformat_token, valid_chars, &name))
9044 vec_add1 (name, 0);
9045 else if (unformat (i, "auth_method %U",
9046 unformat_ikev2_auth_method, &auth_method))
9047 ;
9048 else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
9049 is_hex = 1;
9050 else if (unformat (i, "auth_data %v", &data))
9051 ;
9052 else {
9053 errmsg ("parse error '%U'", format_unformat_error, i);
9054 return -99;
9055 }
9056 }
9057
9058 if (!vec_len (name)) {
9059 errmsg ("profile name must be specified");
9060 return -99;
9061 }
9062
9063 if (vec_len (name) > 64) {
9064 errmsg ("profile name too long");
9065 return -99;
9066 }
9067
9068 if (!vec_len(data)) {
9069 errmsg ("auth_data must be specified");
9070 return -99;
9071 }
9072
9073 if (!auth_method) {
9074 errmsg ("auth_method must be specified");
9075 return -99;
9076 }
9077
9078 M(IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
9079
9080 mp->is_hex = is_hex;
9081 mp->auth_method = (u8) auth_method;
9082 mp->data_len = vec_len (data);
Damjan Marionf1213b82016-03-13 02:22:06 +01009083 clib_memcpy (mp->name, name, vec_len (name));
9084 clib_memcpy (mp->data, data, vec_len (data));
Matus Fabiane5f42fe2016-04-08 11:18:08 +02009085 vec_free (name);
9086 vec_free (data);
9087
9088 S; W;
9089 /* NOTREACHED */
9090 return 0;
9091#else
9092 clib_warning ("unsupported (no dpdk)");
9093 return -99;
9094#endif
9095}
9096
9097static int
9098api_ikev2_profile_set_id (vat_main_t * vam)
9099{
9100#if DPDK > 0
9101 unformat_input_t * i = vam->input;
9102 vl_api_ikev2_profile_set_id_t * mp;
9103 f64 timeout;
9104 u8 * name = 0;
9105 u8 * data = 0;
9106 u8 is_local = 0;
9107 u32 id_type = 0;
9108 ip4_address_t ip4;
9109
9110 const char * valid_chars = "a-zA-Z0-9_";
9111
9112 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9113 if (unformat (i, "name %U", unformat_token, valid_chars, &name))
9114 vec_add1 (name, 0);
9115 else if (unformat (i, "id_type %U",
9116 unformat_ikev2_id_type, &id_type))
9117 ;
9118 else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
9119 {
9120 data = vec_new(u8, 4);
Damjan Marionf1213b82016-03-13 02:22:06 +01009121 clib_memcpy(data, ip4.as_u8, 4);
Matus Fabiane5f42fe2016-04-08 11:18:08 +02009122 }
9123 else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
9124 ;
9125 else if (unformat (i, "id_data %v", &data))
9126 ;
9127 else if (unformat (i, "local"))
9128 is_local = 1;
9129 else if (unformat (i, "remote"))
9130 is_local = 0;
9131 else {
9132 errmsg ("parse error '%U'", format_unformat_error, i);
9133 return -99;
9134 }
9135 }
9136
9137 if (!vec_len (name)) {
9138 errmsg ("profile name must be specified");
9139 return -99;
9140 }
9141
9142 if (vec_len (name) > 64) {
9143 errmsg ("profile name too long");
9144 return -99;
9145 }
9146
9147 if (!vec_len(data)) {
9148 errmsg ("id_data must be specified");
9149 return -99;
9150 }
9151
9152 if (!id_type) {
9153 errmsg ("id_type must be specified");
9154 return -99;
9155 }
9156
9157 M(IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
9158
9159 mp->is_local = is_local;
9160 mp->id_type = (u8) id_type;
9161 mp->data_len = vec_len (data);
Damjan Marionf1213b82016-03-13 02:22:06 +01009162 clib_memcpy (mp->name, name, vec_len (name));
9163 clib_memcpy (mp->data, data, vec_len (data));
Matus Fabiane5f42fe2016-04-08 11:18:08 +02009164 vec_free (name);
9165 vec_free (data);
9166
9167 S; W;
9168 /* NOTREACHED */
9169 return 0;
9170#else
9171 clib_warning ("unsupported (no dpdk)");
9172 return -99;
9173#endif
9174}
9175
9176static int
9177api_ikev2_profile_set_ts (vat_main_t * vam)
9178{
9179#if DPDK > 0
9180 unformat_input_t * i = vam->input;
9181 vl_api_ikev2_profile_set_ts_t * mp;
9182 f64 timeout;
9183 u8 * name = 0;
9184 u8 is_local = 0;
9185 u32 proto = 0, start_port = 0, end_port = (u32) ~0;
9186 ip4_address_t start_addr, end_addr;
9187
9188 const char * valid_chars = "a-zA-Z0-9_";
9189
9190 start_addr.as_u32 = 0;
9191 end_addr.as_u32 = (u32) ~0;
9192
9193 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9194 if (unformat (i, "name %U", unformat_token, valid_chars, &name))
9195 vec_add1 (name, 0);
9196 else if (unformat (i, "protocol %d", &proto))
9197 ;
9198 else if (unformat (i, "start_port %d", &start_port))
9199 ;
9200 else if (unformat (i, "end_port %d", &end_port))
9201 ;
9202 else if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
9203 ;
9204 else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
9205 ;
9206 else if (unformat (i, "local"))
9207 is_local = 1;
9208 else if (unformat (i, "remote"))
9209 is_local = 0;
9210 else {
9211 errmsg ("parse error '%U'", format_unformat_error, i);
9212 return -99;
9213 }
9214 }
9215
9216 if (!vec_len (name)) {
9217 errmsg ("profile name must be specified");
9218 return -99;
9219 }
9220
9221 if (vec_len (name) > 64) {
9222 errmsg ("profile name too long");
9223 return -99;
9224 }
9225
9226 M(IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
9227
9228 mp->is_local = is_local;
9229 mp->proto = (u8) proto;
9230 mp->start_port = (u16) start_port;
9231 mp->end_port = (u16) end_port;
9232 mp->start_addr = start_addr.as_u32;
9233 mp->end_addr = end_addr.as_u32;
Damjan Marionf1213b82016-03-13 02:22:06 +01009234 clib_memcpy (mp->name, name, vec_len (name));
Matus Fabiane5f42fe2016-04-08 11:18:08 +02009235 vec_free (name);
9236
9237 S; W;
9238 /* NOTREACHED */
9239 return 0;
9240#else
9241 clib_warning ("unsupported (no dpdk)");
9242 return -99;
9243#endif
9244}
9245
9246static int
9247api_ikev2_set_local_key (vat_main_t * vam)
9248{
9249#if DPDK > 0
9250 unformat_input_t * i = vam->input;
9251 vl_api_ikev2_set_local_key_t * mp;
9252 f64 timeout;
9253 u8 * file = 0;
9254
9255 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9256 if (unformat (i, "file %v", &file))
9257 vec_add1 (file, 0);
9258 else {
9259 errmsg ("parse error '%U'", format_unformat_error, i);
9260 return -99;
9261 }
9262 }
9263
9264 if (!vec_len (file)) {
9265 errmsg ("RSA key file must be specified");
9266 return -99;
9267 }
9268
9269 if (vec_len (file) > 256) {
9270 errmsg ("file name too long");
9271 return -99;
9272 }
9273
9274 M(IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
9275
Damjan Marionf1213b82016-03-13 02:22:06 +01009276 clib_memcpy (mp->key_file, file, vec_len (file));
Matus Fabiane5f42fe2016-04-08 11:18:08 +02009277 vec_free (file);
9278
9279 S; W;
9280 /* NOTREACHED */
9281 return 0;
9282#else
9283 clib_warning ("unsupported (no dpdk)");
9284 return -99;
9285#endif
9286}
9287
Ed Warnickecb9cada2015-12-08 15:45:58 -07009288/*
9289 * MAP
9290 */
9291static int api_map_add_domain (vat_main_t * vam)
9292{
9293 unformat_input_t *i = vam->input;
9294 vl_api_map_add_domain_t *mp;
9295 f64 timeout;
9296
9297 ip4_address_t ip4_prefix;
9298 ip6_address_t ip6_prefix;
9299 ip6_address_t ip6_src;
9300 u32 num_m_args = 0;
9301 u32 ip6_prefix_len, ip4_prefix_len, ea_bits_len, psid_offset,
9302 psid_length;
9303 u8 is_translation = 0;
9304 u32 mtu = 0;
9305 u8 ip6_src_len = 128;
9306
9307 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9308 if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
9309 &ip4_prefix, &ip4_prefix_len))
9310 num_m_args++;
9311 else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
9312 &ip6_prefix, &ip6_prefix_len))
9313 num_m_args++;
9314 else if (unformat (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src, &ip6_src_len))
9315 num_m_args++;
9316 else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
9317 num_m_args++;
9318 else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
9319 num_m_args++;
9320 else if (unformat (i, "psid-offset %d", &psid_offset))
9321 num_m_args++;
9322 else if (unformat (i, "psid-len %d", &psid_length))
9323 num_m_args++;
9324 else if (unformat (i, "mtu %d", &mtu))
9325 num_m_args++;
9326 else if (unformat (i, "map-t"))
9327 is_translation = 1;
9328 else {
9329 clib_warning ("parse error '%U'", format_unformat_error, i);
9330 return -99;
9331 }
9332 }
9333
9334 if (num_m_args != 6) {
9335 errmsg("mandatory argument(s) missing\n");
9336 return -99;
9337 }
9338
9339 /* Construct the API message */
9340 M(MAP_ADD_DOMAIN, map_add_domain);
9341
Damjan Marionf1213b82016-03-13 02:22:06 +01009342 clib_memcpy(mp->ip4_prefix, &ip4_prefix, sizeof(ip4_prefix));
Ed Warnickecb9cada2015-12-08 15:45:58 -07009343 mp->ip4_prefix_len = ip4_prefix_len;
9344
Damjan Marionf1213b82016-03-13 02:22:06 +01009345 clib_memcpy(mp->ip6_prefix, &ip6_prefix, sizeof(ip6_prefix));
Ed Warnickecb9cada2015-12-08 15:45:58 -07009346 mp->ip6_prefix_len = ip6_prefix_len;
9347
Damjan Marionf1213b82016-03-13 02:22:06 +01009348 clib_memcpy(mp->ip6_src, &ip6_src, sizeof(ip6_src));
Ed Warnickecb9cada2015-12-08 15:45:58 -07009349 mp->ip6_src_prefix_len = ip6_src_len;
9350
9351 mp->ea_bits_len = ea_bits_len;
9352 mp->psid_offset = psid_offset;
9353 mp->psid_length = psid_length;
9354 mp->is_translation = is_translation;
9355 mp->mtu = htons(mtu);
9356
9357 /* send it... */
9358 S;
9359
9360 /* Wait for a reply, return good/bad news */
9361 W;
9362}
9363
9364static int api_map_del_domain (vat_main_t * vam)
9365{
9366 unformat_input_t *i = vam->input;
9367 vl_api_map_del_domain_t *mp;
9368 f64 timeout;
9369
9370 u32 num_m_args = 0;
9371 u32 index;
9372
9373 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9374 if (unformat (i, "index %d", &index))
9375 num_m_args++;
9376 else {
9377 clib_warning ("parse error '%U'", format_unformat_error, i);
9378 return -99;
9379 }
9380 }
9381
9382 if (num_m_args != 1) {
9383 errmsg("mandatory argument(s) missing\n");
9384 return -99;
9385 }
9386
9387 /* Construct the API message */
9388 M(MAP_DEL_DOMAIN, map_del_domain);
9389
9390 mp->index = ntohl(index);
9391
9392 /* send it... */
9393 S;
9394
9395 /* Wait for a reply, return good/bad news */
9396 W;
9397}
9398
9399static int api_map_add_del_rule (vat_main_t * vam)
9400{
9401 unformat_input_t *i = vam->input;
9402 vl_api_map_add_del_rule_t *mp;
9403 f64 timeout;
9404 u8 is_add = 1;
9405 ip6_address_t ip6_dst;
9406 u32 num_m_args = 0, index, psid;
9407
9408 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9409 if (unformat (i, "index %d", &index))
9410 num_m_args++;
9411 else if (unformat (i, "psid %d", &psid))
9412 num_m_args++;
9413 else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
9414 num_m_args++;
9415 else if (unformat (i, "del")) {
9416 is_add = 0;
9417 } else {
9418 clib_warning ("parse error '%U'", format_unformat_error, i);
9419 return -99;
9420 }
9421 }
9422
9423 /* Construct the API message */
9424 M(MAP_ADD_DEL_RULE, map_add_del_rule);
9425
9426 mp->index = ntohl(index);
9427 mp->is_add = is_add;
Damjan Marionf1213b82016-03-13 02:22:06 +01009428 clib_memcpy(mp->ip6_dst, &ip6_dst, sizeof(ip6_dst));
Ed Warnickecb9cada2015-12-08 15:45:58 -07009429 mp->psid = ntohs(psid);
9430
9431 /* send it... */
9432 S;
9433
9434 /* Wait for a reply, return good/bad news */
9435 W;
9436}
9437
9438static int api_map_domain_dump (vat_main_t * vam)
9439{
9440 vl_api_map_domain_dump_t *mp;
9441 f64 timeout;
9442
9443 /* Construct the API message */
9444 M(MAP_DOMAIN_DUMP, map_domain_dump);
9445
9446 /* send it... */
9447 S;
9448
9449 /* Use a control ping for synchronization */
9450 {
9451 vl_api_control_ping_t * mp;
9452 M(CONTROL_PING, control_ping);
9453 S;
9454 }
9455 W;
9456}
9457
9458static int api_map_rule_dump (vat_main_t * vam)
9459{
9460 unformat_input_t *i = vam->input;
9461 vl_api_map_rule_dump_t *mp;
9462 f64 timeout;
9463 u32 domain_index = ~0;
9464
9465 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9466 if (unformat (i, "index %u", &domain_index))
9467 ;
9468 else
9469 break;
9470 }
9471
9472 if (domain_index == ~0) {
9473 clib_warning("parse error: domain index expected");
9474 return -99;
9475 }
9476
9477 /* Construct the API message */
9478 M(MAP_RULE_DUMP, map_rule_dump);
9479
9480 mp->domain_index = htonl(domain_index);
9481
9482 /* send it... */
9483 S;
9484
9485 /* Use a control ping for synchronization */
9486 {
9487 vl_api_control_ping_t * mp;
9488 M(CONTROL_PING, control_ping);
9489 S;
9490 }
9491 W;
9492}
9493
9494static void vl_api_map_add_domain_reply_t_handler
9495(vl_api_map_add_domain_reply_t * mp)
9496{
9497 vat_main_t * vam = &vat_main;
9498 i32 retval = ntohl(mp->retval);
9499
9500 if (vam->async_mode) {
9501 vam->async_errors += (retval < 0);
9502 } else {
9503 vam->retval = retval;
9504 vam->result_ready = 1;
9505 }
9506}
9507
9508static void vl_api_map_add_domain_reply_t_handler_json
9509(vl_api_map_add_domain_reply_t * mp)
9510{
9511 vat_main_t * vam = &vat_main;
9512 vat_json_node_t node;
9513
9514 vat_json_init_object(&node);
9515 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
9516 vat_json_object_add_uint(&node, "index", ntohl(mp->index));
9517
9518 vat_json_print(vam->ofp, &node);
9519 vat_json_free(&node);
9520
9521 vam->retval = ntohl(mp->retval);
9522 vam->result_ready = 1;
9523}
9524
9525static int
9526api_get_first_msg_id (vat_main_t * vam)
9527{
9528 vl_api_get_first_msg_id_t * mp;
9529 f64 timeout;
9530 unformat_input_t * i = vam->input;
9531 u8 * name;
9532 u8 name_set = 0;
9533
9534 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9535 if (unformat (i, "client %s", &name))
9536 name_set = 1;
9537 else
9538 break;
9539 }
9540
9541 if (name_set == 0) {
9542 errmsg ("missing client name\n");
9543 return -99;
9544 }
9545 vec_add1 (name, 0);
9546
9547 if (vec_len (name) > 63) {
9548 errmsg ("client name too long\n");
9549 return -99;
9550 }
9551
9552 M(GET_FIRST_MSG_ID, get_first_msg_id);
Damjan Marionf1213b82016-03-13 02:22:06 +01009553 clib_memcpy (mp->name, name, vec_len(name));
Ed Warnickecb9cada2015-12-08 15:45:58 -07009554 S; W;
9555 /* NOTREACHED */
9556 return 0;
9557}
9558
Dave Barachc07bf5d2016-02-17 17:52:26 -05009559static int api_cop_interface_enable_disable (vat_main_t * vam)
9560{
9561 unformat_input_t * line_input = vam->input;
9562 vl_api_cop_interface_enable_disable_t * mp;
9563 f64 timeout;
9564 u32 sw_if_index = ~0;
9565 u8 enable_disable = 1;
9566
9567 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
9568 if (unformat (line_input, "disable"))
9569 enable_disable = 0;
9570 if (unformat (line_input, "enable"))
9571 enable_disable = 1;
9572 else if (unformat (line_input, "%U", unformat_sw_if_index,
9573 vam, &sw_if_index))
9574 ;
9575 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
9576 ;
9577 else
9578 break;
9579 }
9580
9581 if (sw_if_index == ~0) {
9582 errmsg ("missing interface name or sw_if_index\n");
9583 return -99;
9584 }
9585
9586 /* Construct the API message */
9587 M(COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
9588 mp->sw_if_index = ntohl(sw_if_index);
9589 mp->enable_disable = enable_disable;
9590
9591 /* send it... */
9592 S;
9593 /* Wait for the reply */
9594 W;
9595}
9596
9597static int api_cop_whitelist_enable_disable (vat_main_t * vam)
9598{
9599 unformat_input_t * line_input = vam->input;
9600 vl_api_cop_whitelist_enable_disable_t * mp;
9601 f64 timeout;
9602 u32 sw_if_index = ~0;
9603 u8 ip4=0, ip6=0, default_cop=0;
9604 u32 fib_id;
9605
9606 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
9607 if (unformat (line_input, "ip4"))
9608 ip4 = 1;
9609 else if (unformat (line_input, "ip6"))
9610 ip6 = 1;
9611 else if (unformat (line_input, "default"))
9612 default_cop = 1;
9613 else if (unformat (line_input, "%U", unformat_sw_if_index,
9614 vam, &sw_if_index))
9615 ;
9616 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
9617 ;
9618 else if (unformat (line_input, "fib-id %d", &fib_id))
9619 ;
9620 else
9621 break;
9622 }
9623
9624 if (sw_if_index == ~0) {
9625 errmsg ("missing interface name or sw_if_index\n");
9626 return -99;
9627 }
9628
9629 /* Construct the API message */
9630 M(COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
9631 mp->sw_if_index = ntohl(sw_if_index);
9632 mp->fib_id = ntohl(fib_id);
9633 mp->ip4 = ip4;
9634 mp->ip6 = ip6;
9635 mp->default_cop = default_cop;
9636
9637 /* send it... */
9638 S;
9639 /* Wait for the reply */
9640 W;
9641}
9642
Dave Barachb44e9bc2016-02-19 09:06:23 -05009643static int api_get_node_graph (vat_main_t * vam)
9644{
9645 vl_api_get_node_graph_t * mp;
9646 f64 timeout;
9647
9648 M(GET_NODE_GRAPH, get_node_graph);
9649
9650 /* send it... */
9651 S;
9652 /* Wait for the reply */
9653 W;
9654}
9655
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02009656static int
9657api_lisp_add_del_locator_set(vat_main_t * vam)
9658{
9659 unformat_input_t * input = vam->input;
9660 vl_api_lisp_add_del_locator_set_t *mp;
9661 f64 timeout = ~0;
9662 u8 is_add = 1;
9663 u8 *locator_set_name = NULL;
9664 u8 locator_set_name_set = 0;
9665
9666 /* Parse args required to build the message */
9667 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
9668 if (unformat(input, "del")) {
9669 is_add = 0;
9670 } else if (unformat(input, "locator-set %s", &locator_set_name)) {
9671 locator_set_name_set = 1;
9672 } else
9673 break;
9674 }
9675
9676 if (locator_set_name_set == 0) {
9677 errmsg ("missing locator-set name");
9678 return -99;
9679 }
9680
9681 if (vec_len(locator_set_name) > 64) {
9682 errmsg ("locator-set name too long\n");
9683 vec_free(locator_set_name);
9684 return -99;
9685 }
9686 vec_add1(locator_set_name, 0);
9687
9688 /* Construct the API message */
9689 M(LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set);
9690
9691 mp->is_add = is_add;
Damjan Marionf1213b82016-03-13 02:22:06 +01009692 clib_memcpy(mp->locator_set_name, locator_set_name,
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02009693 vec_len(locator_set_name));
9694 vec_free(locator_set_name);
9695
9696 /* send it... */
9697 S;
9698
9699 /* Wait for a reply... */
9700 W;
9701
9702 /* NOTREACHED */
9703 return 0;
9704}
9705
9706static int
9707api_lisp_add_del_locator(vat_main_t * vam)
9708{
9709 unformat_input_t * input = vam->input;
9710 vl_api_lisp_add_del_locator_t *mp;
9711 f64 timeout = ~0;
9712 u32 tmp_if_index = ~0;
9713 u32 sw_if_index = ~0;
9714 u8 sw_if_index_set = 0;
9715 u8 sw_if_index_if_name_set = 0;
9716 u8 priority = ~0;
9717 u8 priority_set = 0;
9718 u8 weight = ~0;
9719 u8 weight_set = 0;
9720 u8 is_add = 1;
9721 u8 *locator_set_name = NULL;
9722 u8 locator_set_name_set = 0;
9723
9724 /* Parse args required to build the message */
9725 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
9726 if (unformat(input, "del")) {
9727 is_add = 0;
9728 } else if (unformat(input, "locator-set %s", &locator_set_name)) {
9729 locator_set_name_set = 1;
9730 } else if (unformat(input, "iface %U", unformat_sw_if_index, vam,
9731 &tmp_if_index)) {
9732 sw_if_index_if_name_set = 1;
9733 sw_if_index = tmp_if_index;
9734 } else if (unformat(input,"sw_if_index %d", &tmp_if_index)) {
9735 sw_if_index_set = 1;
9736 sw_if_index = tmp_if_index;
9737 } else if (unformat(input, "p %d", &priority)) {
9738 priority_set = 1;
9739 } else if (unformat(input, "w %d", &weight)) {
9740 weight_set = 1;
9741 } else
9742 break;
9743 }
9744
9745 if (locator_set_name_set == 0) {
9746 errmsg ("missing locator-set name");
9747 return -99;
9748 }
9749
9750 if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0) {
9751 errmsg ("missing sw_if_index");
9752 vec_free(locator_set_name);
9753 return -99;
9754 }
9755
9756 if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0) {
9757 errmsg ("cannot use both params interface name and sw_if_index");
9758 vec_free(locator_set_name);
9759 return -99;
9760 }
9761
9762 if (priority_set == 0) {
9763 errmsg ("missing locator-set priority\n");
9764 vec_free(locator_set_name);
9765 return -99;
9766 }
9767
9768 if (weight_set == 0) {
9769 errmsg ("missing locator-set weight\n");
9770 vec_free(locator_set_name);
9771 return -99;
9772 }
9773
9774 if (vec_len(locator_set_name) > 64) {
9775 errmsg ("locator-set name too long\n");
9776 vec_free(locator_set_name);
9777 return -99;
9778 }
9779 vec_add1(locator_set_name, 0);
9780
9781 /* Construct the API message */
9782 M(LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
9783
9784 mp->is_add = is_add;
9785 mp->sw_if_index = ntohl(sw_if_index);
9786 mp->priority = priority;
9787 mp->weight = weight;
Damjan Marionf1213b82016-03-13 02:22:06 +01009788 clib_memcpy(mp->locator_set_name, locator_set_name,
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02009789 vec_len(locator_set_name));
9790 vec_free(locator_set_name);
9791
9792 /* send it... */
9793 S;
9794
9795 /* Wait for a reply... */
9796 W;
9797
9798 /* NOTREACHED */
9799 return 0;
9800}
9801
9802static int
9803api_lisp_add_del_local_eid(vat_main_t * vam)
9804{
9805 unformat_input_t * input = vam->input;
9806 vl_api_lisp_add_del_local_eid_t *mp;
9807 f64 timeout = ~0;
9808 u8 is_add = 1;
9809 u8 eidv4_set = 0;
9810 u8 eidv6_set = 0;
9811 ip4_address_t eidv4;
9812 ip6_address_t eidv6;
9813 u8 tmp_eid_lenght = ~0;
9814 u8 eid_lenght = ~0;
9815 u8 *locator_set_name = NULL;
9816 u8 locator_set_name_set = 0;
9817
9818 /* Parse args required to build the message */
9819 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
9820 if (unformat(input, "del")) {
9821 is_add = 0;
9822 } else if (unformat(input, "eid %U/%d", unformat_ip4_address,
9823 &eidv4, &tmp_eid_lenght)) {
9824 eid_lenght = tmp_eid_lenght;
9825 eidv4_set = 1;
9826 } else if (unformat(input, "eid %U/%d", unformat_ip6_address,
9827 &eidv6, &tmp_eid_lenght)) {
9828 eid_lenght = tmp_eid_lenght;
9829 eidv6_set = 1;
9830 } else if (unformat(input, "locator-set %s", &locator_set_name)) {
9831 locator_set_name_set = 1;
9832 } else
9833 break;
9834 }
9835
9836 if (locator_set_name_set == 0) {
9837 errmsg ("missing locator-set name\n");
9838 return -99;
9839 }
9840
9841 if (vec_len(locator_set_name) > 64) {
9842 errmsg ("locator-set name too long\n");
9843 vec_free(locator_set_name);
9844 return -99;
9845 }
9846 vec_add1(locator_set_name, 0);
9847
9848 if (eidv4_set && eidv6_set) {
9849 errmsg ("both eid v4 and v6 addresses set\n");
9850 vec_free(locator_set_name);
9851 return -99;
9852 }
9853
9854 if (!eidv4_set && !eidv6_set) {
9855 errmsg ("eid addresses not set\n");
9856 vec_free(locator_set_name);
9857 return -99;
9858 }
9859
Andrej Kozemcak3e53fc52016-05-09 10:52:16 +02009860 if (eidv4_set && eid_lenght > 32) {
9861 errmsg ("eid prefix to big\n");
9862 vec_free(locator_set_name);
9863 return -99;
9864 }
9865
9866 if (eidv6_set && eid_lenght > 128) {
9867 errmsg ("eid prefix to big\n");
9868 vec_free(locator_set_name);
9869 return -99;
9870 }
9871
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02009872 /* Construct the API message */
9873 M(LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
9874
9875 mp->is_add = is_add;
9876 if (eidv6_set) {
9877 mp->is_ipv6 = 1;
Damjan Marionf1213b82016-03-13 02:22:06 +01009878 clib_memcpy(mp->ip_address, &eidv6, sizeof(eidv6));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02009879 } else {
9880 mp->is_ipv6 = 0;
Damjan Marionf1213b82016-03-13 02:22:06 +01009881 clib_memcpy(mp->ip_address, &eidv4, sizeof(eidv4));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02009882 }
9883 mp->prefix_len = eid_lenght;
Damjan Marionf1213b82016-03-13 02:22:06 +01009884 clib_memcpy(mp->locator_set_name, locator_set_name,
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02009885 vec_len(locator_set_name));
9886 vec_free(locator_set_name);
9887
9888 /* send it... */
9889 S;
9890
9891 /* Wait for a reply... */
9892 W;
9893
9894 /* NOTREACHED */
9895 return 0;
9896}
9897
9898static int
9899api_lisp_gpe_add_del_fwd_entry(vat_main_t * vam)
9900{
9901 unformat_input_t * input = vam->input;
9902 vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
9903 f64 timeout = ~0;
9904 u8 is_add = 1;
9905 u8 eidv4_set = 0, slocv4_set = 0, dlocv4_set = 0;
9906 u8 eidv6_set = 0, slocv6_set = 0, dlocv6_set = 0;
9907 ip4_address_t eidv4, slocv4, dlocv4;
9908 ip6_address_t eidv6, slocv6, dlocv6;
9909 u8 tmp_eid_lenght = ~0;
9910 u8 eid_lenght = ~0;
9911
9912 /* Parse args required to build the message */
9913 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
9914 if (unformat(input, "del")) {
9915 is_add = 0;
9916 } else if (unformat(input, "eid %U/%d", unformat_ip4_address,
9917 &eidv4, &tmp_eid_lenght)) {
9918 eid_lenght = tmp_eid_lenght;
9919 eidv4_set = 1;
9920 } else if (unformat(input, "eid %U/%d", unformat_ip6_address,
9921 &eidv6, &tmp_eid_lenght)) {
9922 eid_lenght = tmp_eid_lenght;
9923 eidv6_set = 1;
9924 } else if (unformat(input, "sloc %U", unformat_ip4_address, &slocv4)) {
9925 slocv4_set = 1;
9926 } else if (unformat(input, "sloc %U", unformat_ip6_address, &slocv6)) {
9927 slocv6_set = 1;
9928 } else if (unformat(input, "dloc %U", unformat_ip4_address, &dlocv4)) {
9929 dlocv4_set = 1;
9930 } else if (unformat(input, "dloc %U", unformat_ip6_address, &dlocv6)) {
9931 dlocv6_set = 1;
9932 } else
9933 break;
9934 }
9935
9936 if (eidv4_set && eidv6_set) {
9937 errmsg ("both eid v4 and v6 addresses set\n");
9938 return -99;
9939 }
9940
9941 if (!eidv4_set && !eidv6_set) {
9942 errmsg ("eid addresses not set\n");
9943 return -99;
9944 }
9945
9946 if (slocv4_set && slocv6_set) {
9947 errmsg ("both source v4 and v6 addresses set\n");
9948 return -99;
9949 }
9950
9951 if (!slocv4_set && !slocv6_set) {
9952 errmsg ("source addresses not set\n");
9953 return -99;
9954 }
9955
9956 if (dlocv4_set && dlocv6_set) {
9957 errmsg ("both destination v4 and v6 addresses set\n");
9958 return -99;
9959 }
9960
9961 if (dlocv4_set && dlocv6_set) {
9962 errmsg ("destination addresses not set\n");
9963 return -99;
9964 }
9965
9966 if (!(slocv4_set == dlocv4_set && slocv6_set == dlocv6_set)) {
9967 errmsg ("mixing type of source and destination address\n");
9968 return -99;
9969 }
9970
9971 /* Construct the API message */
9972 M(LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
9973
9974 mp->is_add = is_add;
9975 if (eidv6_set) {
9976 mp->eid_is_ipv6 = 1;
Damjan Marionf1213b82016-03-13 02:22:06 +01009977 clib_memcpy(mp->eid_ip_address, &eidv6, sizeof(eidv6));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02009978 } else {
9979 mp->eid_is_ipv6 = 0;
Damjan Marionf1213b82016-03-13 02:22:06 +01009980 clib_memcpy(mp->eid_ip_address, &eidv4, sizeof(eidv4));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02009981 }
9982 mp->eid_prefix_len = eid_lenght;
9983 if (slocv6_set) {
9984 mp->address_is_ipv6 = 1;
Damjan Marionf1213b82016-03-13 02:22:06 +01009985 clib_memcpy(mp->source_ip_address, &slocv6, sizeof(slocv6));
9986 clib_memcpy(mp->destination_ip_address, &dlocv6, sizeof(dlocv6));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02009987 } else {
9988 mp->address_is_ipv6 = 0;
Damjan Marionf1213b82016-03-13 02:22:06 +01009989 clib_memcpy(mp->source_ip_address, &slocv4, sizeof(slocv4));
9990 clib_memcpy(mp->destination_ip_address, &dlocv4, sizeof(dlocv4));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02009991 }
9992
9993 /* send it... */
9994 S;
9995
9996 /* Wait for a reply... */
9997 W;
9998
9999 /* NOTREACHED */
10000 return 0;
10001}
10002
10003static int
10004api_lisp_add_del_map_resolver(vat_main_t * vam)
10005{
10006 unformat_input_t * input = vam->input;
10007 vl_api_lisp_add_del_map_resolver_t *mp;
10008 f64 timeout = ~0;
10009 u8 is_add = 1;
10010 u8 ipv4_set = 0;
10011 u8 ipv6_set = 0;
10012 ip4_address_t ipv4;
10013 ip6_address_t ipv6;
10014
10015 /* Parse args required to build the message */
10016 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
10017 if (unformat(input, "del")) {
10018 is_add = 0;
10019 } else if (unformat(input, "%U", unformat_ip4_address, &ipv4)) {
10020 ipv4_set = 1;
10021 } else if (unformat(input, "%U", unformat_ip6_address, &ipv6)) {
10022 ipv6_set = 1;
10023 } else
10024 break;
10025 }
10026
10027 if (ipv4_set && ipv6_set) {
10028 errmsg ("both eid v4 and v6 addresses set\n");
10029 return -99;
10030 }
10031
10032 if (!ipv4_set && !ipv6_set) {
10033 errmsg ("eid addresses not set\n");
10034 return -99;
10035 }
10036
10037 /* Construct the API message */
10038 M(LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
10039
10040 mp->is_add = is_add;
10041 if (ipv6_set) {
10042 mp->is_ipv6 = 1;
Damjan Marionf1213b82016-03-13 02:22:06 +010010043 clib_memcpy(mp->ip_address, &ipv6, sizeof(ipv6));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010044 } else {
10045 mp->is_ipv6 = 0;
Damjan Marionf1213b82016-03-13 02:22:06 +010010046 clib_memcpy(mp->ip_address, &ipv4, sizeof(ipv4));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010047 }
10048
10049 /* send it... */
10050 S;
10051
10052 /* Wait for a reply... */
10053 W;
10054
10055 /* NOTREACHED */
10056 return 0;
10057}
10058
10059static int
Florin Coras577c3552016-04-21 00:45:40 +020010060api_lisp_gpe_enable_disable (vat_main_t * vam)
10061{
10062 unformat_input_t * input = vam->input;
10063 vl_api_lisp_gpe_enable_disable_t *mp;
10064 f64 timeout = ~0;
10065 u8 is_set = 0;
10066 u8 is_en = 1;
10067
10068 /* Parse args required to build the message */
10069 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
10070 if (unformat(input, "enable")) {
10071 is_set = 1;
10072 is_en = 1;
10073 } else if (unformat(input, "disable")) {
10074 is_set = 1;
10075 is_en = 0;
10076 } else
10077 break;
10078 }
10079
10080 if (is_set == 0) {
10081 errmsg("Value not set\n");
10082 return -99;
10083 }
10084
10085 /* Construct the API message */
10086 M(LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
10087
10088 mp->is_en = is_en;
10089
10090 /* send it... */
10091 S;
10092
10093 /* Wait for a reply... */
10094 W;
10095
10096 /* NOTREACHED */
10097 return 0;
10098}
10099
10100static int
Filip Tehlar46d4e362016-05-09 09:39:26 +020010101api_lisp_enable_disable (vat_main_t * vam)
10102{
10103 unformat_input_t * input = vam->input;
10104 vl_api_lisp_enable_disable_t *mp;
10105 f64 timeout = ~0;
10106 u8 is_set = 0;
10107 u8 is_en = 0;
10108
10109 /* Parse args required to build the message */
10110 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10111 {
10112 if (unformat (input, "enable"))
10113 {
10114 is_set = 1;
10115 is_en = 1;
10116 }
10117 else if (unformat (input, "disable"))
10118 {
10119 is_set = 1;
10120 }
10121 else
10122 break;
10123 }
10124
10125 if (!is_set)
10126 {
10127 errmsg ("Value not set\n");
10128 return -99;
10129 }
10130
10131 /* Construct the API message */
10132 M(LISP_ENABLE_DISABLE, lisp_enable_disable);
10133
10134 mp->is_en = is_en;
10135
10136 /* send it... */
10137 S;
10138
10139 /* Wait for a reply... */
10140 W;
10141
10142 /* NOTREACHED */
10143 return 0;
10144}
10145
Filip Tehlar195bcee2016-05-13 17:37:35 +020010146/** Used for transferring locators via VPP API */
10147typedef CLIB_PACKED(struct
10148{
10149 u8 is_ip4; /**< is locator an IPv4 address? */
10150 u8 addr[16]; /**< IPv4/IPv6 address */
10151}) rloc_t;
10152
10153/**
Filip Tehlar53f09e32016-05-19 14:25:44 +020010154 * Enable/disable LISP proxy ITR.
10155 *
10156 * @param vam vpp API test context
10157 * @return return code
10158 */
10159static int
10160api_lisp_pitr_set_locator_set (vat_main_t * vam)
10161{
10162 f64 timeout = ~0;
10163 u8 ls_name_set = 0;
10164 unformat_input_t * input = vam->input;
10165 vl_api_lisp_pitr_set_locator_set_t * mp;
10166 u8 is_add = 1;
10167 u8 * ls_name = 0;
10168
10169 /* Parse args required to build the message */
10170 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10171 {
10172 if (unformat (input, "del"))
10173 is_add = 0;
10174 else if (unformat (input, "locator-set %s", &ls_name))
10175 ls_name_set = 1;
10176 else
10177 {
10178 errmsg ("parse error '%U'", format_unformat_error, input);
10179 return -99;
10180 }
10181 }
10182
10183 if (!ls_name_set)
10184 {
10185 errmsg ("locator-set name not set!");
10186 return -99;
10187 }
10188
10189 M(LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
10190
10191 mp->is_add = is_add;
10192 clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
10193 vec_free (ls_name);
10194
10195 /* send */
10196 S;
10197
10198 /* wait for reply */
10199 W;
10200
10201 /* notreached*/
10202 return 0;
10203}
10204
10205/**
Filip Tehlar195bcee2016-05-13 17:37:35 +020010206 * Add/del remote mapping from LISP control plane and updates
10207 * forwarding entries in data-plane accordingly.
10208 *
10209 * @param vam vpp API test context
10210 * @return return code
10211 */
10212static int
10213api_lisp_add_del_remote_mapping (vat_main_t * vam)
10214{
10215 unformat_input_t * input = vam->input;
10216 vl_api_lisp_add_del_remote_mapping_t *mp;
10217 f64 timeout = ~0;
10218 u32 vni = 0;
10219 u8 seid_set = 0, deid_set = 0;
10220 ip4_address_t seid4, deid4, rloc4;
10221 ip6_address_t seid6, deid6, rloc6;
10222 u32 seid_len = 0, deid_len = 0, len;
10223 u8 deid_is_ip4 = 0, seid_is_ip4 = 0;
Filip Tehlar58f886a2016-05-30 15:57:40 +020010224 u8 is_add = 1, del_all = 0;
Filip Tehlar195bcee2016-05-13 17:37:35 +020010225 u32 action = ~0;
10226 rloc_t * rlocs = 0, rloc;
10227
10228 /* Parse args required to build the message */
10229 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
Filip Tehlar58f886a2016-05-30 15:57:40 +020010230 if (unformat(input, "del-all")) {
10231 del_all = 1;
10232 } else if (unformat(input, "del")) {
Filip Tehlar195bcee2016-05-13 17:37:35 +020010233 is_add = 0;
10234 } else if (unformat(input, "add")) {
10235 is_add = 1;
10236 } else if (unformat(input, "deid %U/%d", unformat_ip4_address,
10237 &deid4, &len)) {
10238 deid_set = 1;
10239 deid_is_ip4 = 1;
10240 deid_len = len;
10241 } else if (unformat(input, "deid %U/%d", unformat_ip6_address,
10242 &deid6, &len)) {
10243 deid_set = 1;
10244 deid_is_ip4 = 0;
10245 deid_len = len;
10246 } else if (unformat(input, "seid %U/%d", unformat_ip4_address,
10247 &seid4, &len)) {
10248 seid_set = 1;
10249 seid_is_ip4 = 1;
10250 seid_len = len;
10251 } else if (unformat(input, "seid %U/%d", unformat_ip6_address,
10252 &seid6, &len)) {
10253 seid_set = 1;
10254 seid_is_ip4 = 0;
10255 seid_len = len;
10256 } else if (unformat(input, "vni %d", &vni)) {
10257 ;
10258 } else if (unformat(input, "rloc %U", unformat_ip4_address, &rloc4)) {
10259 rloc.is_ip4 = 1;
10260 clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
10261 vec_add1 (rlocs, rloc);
10262 } else if (unformat(input, "rloc %U", unformat_ip6_address, &rloc6)) {
10263 rloc.is_ip4 = 0;
10264 clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
10265 vec_add1 (rlocs, rloc);
10266 } else if (unformat(input, "action %d", &action)) {
10267 ;
10268 } else {
10269 clib_warning ("parse error '%U'", format_unformat_error, input);
10270 return -99;
10271 }
10272 }
10273
10274 if (!seid_set || !deid_set) {
10275 errmsg ("missing params!");
10276 return -99;
10277 }
10278
10279 if (seid_is_ip4 != deid_is_ip4) {
10280 errmsg ("source and destination EIDs are not in " "same IP family!");
10281 return -99;
10282 }
10283
10284 if (is_add && (~0 == action)
10285 && 0 == vec_len (rlocs)) {
10286 errmsg ("no action set for negative map-reply!");
10287 return -99;
10288 }
10289
10290 M(LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping);
10291 mp->is_add = is_add;
10292 mp->vni = htonl (vni);
10293 mp->seid_len = seid_len;
10294 mp->action = (u8) action;
10295 mp->deid_len = deid_len;
Filip Tehlar58f886a2016-05-30 15:57:40 +020010296 mp->del_all = del_all;
Filip Tehlar195bcee2016-05-13 17:37:35 +020010297 if (seid_is_ip4) {
10298 mp->eid_is_ip4 = 1;
10299 clib_memcpy (mp->seid, &seid4, sizeof (seid4));
10300 } else {
10301 mp->eid_is_ip4 = 0;
10302 clib_memcpy (mp->seid, &seid6, sizeof (seid6));
10303 }
10304
10305 if (deid_is_ip4) {
10306 mp->eid_is_ip4 = 1;
10307 clib_memcpy (mp->deid, &deid4, sizeof (deid4));
10308 } else {
10309 mp->eid_is_ip4 = 0;
10310 clib_memcpy (mp->deid, &deid6, sizeof (deid6));
10311 }
10312
10313 mp->rloc_num = vec_len (rlocs);
10314 clib_memcpy (mp->rlocs, rlocs, (sizeof (rloc_t) * vec_len (rlocs)));
10315 vec_free (rlocs);
10316
10317 /* send it... */
10318 S;
10319
10320 /* Wait for a reply... */
10321 W;
10322
10323 /* NOTREACHED */
10324 return 0;
10325}
10326
Filip Tehlar46d4e362016-05-09 09:39:26 +020010327static int
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010328api_lisp_gpe_add_del_iface(vat_main_t * vam)
10329{
10330 unformat_input_t * input = vam->input;
10331 vl_api_lisp_gpe_add_del_iface_t *mp;
10332 f64 timeout = ~0;
10333 u8 is_set = 0;
Florin Coras577c3552016-04-21 00:45:40 +020010334 u8 is_add = 1;
10335 u32 table_id, vni;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010336
10337 /* Parse args required to build the message */
10338 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
10339 if (unformat(input, "up")) {
10340 is_set = 1;
10341 is_add = 1;
10342 } else if (unformat(input, "down")) {
10343 is_set = 1;
10344 is_add = 0;
Florin Coras577c3552016-04-21 00:45:40 +020010345 } else if (unformat(input, "table_id %d", &table_id)) {
10346 ;
10347 } else if (unformat(input, "vni %d", &vni)) {
10348 ;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010349 } else
10350 break;
10351 }
10352
10353 if (is_set == 0) {
10354 errmsg("Value not set\n");
10355 return -99;
10356 }
10357
10358 /* Construct the API message */
10359 M(LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
10360
10361 mp->is_add = is_add;
Florin Coras577c3552016-04-21 00:45:40 +020010362 mp->table_id = table_id;
10363 mp->vni = vni;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010364
10365 /* send it... */
10366 S;
10367
10368 /* Wait for a reply... */
10369 W;
10370
10371 /* NOTREACHED */
10372 return 0;
10373}
10374
10375static int
10376api_lisp_locator_set_dump(vat_main_t *vam)
10377{
10378 vl_api_lisp_locator_set_dump_t *mp;
10379 f64 timeout = ~0;
10380
10381 if (!vam->json_output) {
10382 fformat(vam->ofp, "%=20s%=16s%=16s%=16s\n",
10383 "Locator-set", "Locator", "Priority", "Weight");
10384 }
10385
10386 M(LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
10387 /* send it... */
10388 S;
10389
10390 /* Use a control ping for synchronization */
10391 {
10392 vl_api_control_ping_t * mp;
10393 M(CONTROL_PING, control_ping);
10394 S;
10395 }
10396 /* Wait for a reply... */
10397 W;
10398
10399 /* NOTREACHED */
10400 return 0;
10401}
10402
10403static int
10404api_lisp_local_eid_table_dump(vat_main_t *vam)
10405{
10406 vl_api_lisp_local_eid_table_dump_t *mp;
10407 f64 timeout = ~0;
10408
10409 if (!vam->json_output) {
10410 fformat(vam->ofp, "%=20s%=30s\n",
10411 "Locator-set", "Eid");
10412 }
10413
10414 M(LISP_LOCAL_EID_TABLE_DUMP, lisp_local_eid_table_dump);
10415 /* send it... */
10416 S;
10417
10418 /* Use a control ping for synchronization */
10419 {
10420 vl_api_control_ping_t * mp;
10421 M(CONTROL_PING, control_ping);
10422 S;
10423 }
10424 /* Wait for a reply... */
10425 W;
10426
10427 /* NOTREACHED */
10428 return 0;
10429}
10430
10431static int
10432api_lisp_gpe_tunnel_dump(vat_main_t *vam)
10433{
10434 vl_api_lisp_gpe_tunnel_dump_t *mp;
10435 f64 timeout = ~0;
10436
10437 if (!vam->json_output) {
10438 fformat(vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
10439 "%=16s%=16s%=16s%=16s%=16s\n",
10440 "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
10441 "Decap next", "Lisp version", "Flags", "Next protocol",
10442 "ver_res", "res", "iid");
10443 }
10444
10445 M(LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
10446 /* send it... */
10447 S;
10448
10449 /* Use a control ping for synchronization */
10450 {
10451 vl_api_control_ping_t * mp;
10452 M(CONTROL_PING, control_ping);
10453 S;
10454 }
10455 /* Wait for a reply... */
10456 W;
10457
10458 /* NOTREACHED */
10459 return 0;
10460}
10461
10462static int
10463api_lisp_map_resolver_dump(vat_main_t *vam)
10464{
10465 vl_api_lisp_map_resolver_dump_t *mp;
10466 f64 timeout = ~0;
10467
10468 if (!vam->json_output) {
10469 fformat(vam->ofp, "%=20s\n",
10470 "Map resolver");
10471 }
10472
10473 M(LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
10474 /* send it... */
10475 S;
10476
10477 /* Use a control ping for synchronization */
10478 {
10479 vl_api_control_ping_t * mp;
10480 M(CONTROL_PING, control_ping);
10481 S;
10482 }
10483 /* Wait for a reply... */
10484 W;
10485
10486 /* NOTREACHED */
10487 return 0;
10488}
10489
Andrej Kozemcaka9edd852016-05-02 12:14:33 +020010490static int
Filip Tehlar46d4e362016-05-09 09:39:26 +020010491api_lisp_enable_disable_status_dump(vat_main_t *vam)
Andrej Kozemcaka9edd852016-05-02 12:14:33 +020010492{
Filip Tehlar46d4e362016-05-09 09:39:26 +020010493 vl_api_lisp_enable_disable_status_dump_t *mp;
Andrej Kozemcaka9edd852016-05-02 12:14:33 +020010494 f64 timeout = ~0;
10495
10496 if (!vam->json_output) {
10497 fformat(vam->ofp, "%=20s\n",
Filip Tehlar46d4e362016-05-09 09:39:26 +020010498 "lisp status:");
Andrej Kozemcaka9edd852016-05-02 12:14:33 +020010499 }
10500
Filip Tehlar46d4e362016-05-09 09:39:26 +020010501 M(LISP_ENABLE_DISABLE_STATUS_DUMP,
10502 lisp_enable_disable_status_dump);
Andrej Kozemcaka9edd852016-05-02 12:14:33 +020010503 /* send it... */
10504 S;
10505
10506 /* Use a control ping for synchronization */
10507 {
10508 vl_api_control_ping_t * mp;
10509 M(CONTROL_PING, control_ping);
10510 S;
10511 }
10512 /* Wait for a reply... */
10513 W;
10514
10515 /* NOTREACHED */
10516 return 0;
10517}
10518
Matus Fabian8a95a482016-05-06 15:14:13 +020010519static int
10520api_af_packet_create (vat_main_t * vam)
10521{
10522 unformat_input_t * i = vam->input;
10523 vl_api_af_packet_create_t * mp;
10524 f64 timeout;
10525 u8 * host_if_name = 0;
10526 u8 hw_addr[6];
10527 u8 random_hw_addr = 1;
10528
10529 memset (hw_addr, 0, sizeof (hw_addr));
10530
10531 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
10532 if (unformat (i, "name %s", &host_if_name))
10533 vec_add1 (host_if_name, 0);
10534 else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
10535 random_hw_addr = 0;
10536 else
10537 break;
10538 }
10539
10540 if (!vec_len (host_if_name)) {
10541 errmsg ("host-interface name must be specified");
10542 return -99;
10543 }
10544
10545 if (vec_len (host_if_name) > 64) {
10546 errmsg ("host-interface name too long");
10547 return -99;
10548 }
10549
10550 M(AF_PACKET_CREATE, af_packet_create);
10551
10552 clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
10553 clib_memcpy (mp->hw_addr, hw_addr, 6);
10554 mp->use_random_hw_addr = random_hw_addr;
10555 vec_free (host_if_name);
10556
10557 S; W;
10558 /* NOTREACHED */
10559 return 0;
10560}
10561
10562static int
10563api_af_packet_delete (vat_main_t * vam)
10564{
10565 unformat_input_t * i = vam->input;
10566 vl_api_af_packet_delete_t * mp;
10567 f64 timeout;
10568 u8 * host_if_name = 0;
10569
10570 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
10571 if (unformat (i, "name %s", &host_if_name))
10572 vec_add1 (host_if_name, 0);
10573 else
10574 break;
10575 }
10576
10577 if (!vec_len (host_if_name)) {
10578 errmsg ("host-interface name must be specified");
10579 return -99;
10580 }
10581
10582 if (vec_len (host_if_name) > 64) {
10583 errmsg ("host-interface name too long");
10584 return -99;
10585 }
10586
10587 M(AF_PACKET_DELETE, af_packet_delete);
10588
10589 clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
10590 vec_free (host_if_name);
10591
10592 S; W;
10593 /* NOTREACHED */
10594 return 0;
10595}
10596
Matus Fabian65fcd4d2016-05-13 05:44:48 -070010597static int
10598api_policer_add_del (vat_main_t * vam)
10599{
10600 unformat_input_t * i = vam->input;
10601 vl_api_policer_add_del_t * mp;
10602 f64 timeout;
10603 u8 is_add = 1;
10604 u8 * name = 0;
10605 u32 cir = 0;
10606 u32 eir = 0;
10607 u64 cb = 0;
10608 u64 eb = 0;
10609 u8 rate_type = 0;
10610 u8 round_type = 0;
10611 u8 type = 0;
10612
10613 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
10614 if (unformat (i, "del"))
10615 is_add = 0;
10616 else if (unformat (i, "name %s", &name))
10617 vec_add1 (name, 0);
10618 else if (unformat (i, "cir %u", &cir))
10619 ;
10620 else if (unformat (i, "eir %u", &eir))
10621 ;
10622 else if (unformat (i, "cb %u", &cb))
10623 ;
10624 else if (unformat (i, "eb %u", &eb))
10625 ;
10626 else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
10627 &rate_type))
10628 ;
10629 else if (unformat (i, "round_type %U", unformat_policer_round_type,
10630 &round_type))
10631 ;
10632 else if (unformat (i, "type %U", unformat_policer_type, &type))
10633 ;
10634 else
10635 break;
10636 }
10637
10638 if (!vec_len (name)) {
10639 errmsg ("policer name must be specified");
10640 return -99;
10641 }
10642
10643 if (vec_len (name) > 64) {
10644 errmsg ("policer name too long");
10645 return -99;
10646 }
10647
10648 M(POLICER_ADD_DEL, policer_add_del);
10649
10650 clib_memcpy (mp->name, name, vec_len (name));
10651 vec_free (name);
10652 mp->is_add = is_add;
10653 mp->cir = cir;
10654 mp->eir = eir;
10655 mp->cb = cb;
10656 mp->eb = eb;
10657 mp->rate_type = rate_type;
10658 mp->round_type = round_type;
10659 mp->type = type;
10660
10661 S; W;
10662 /* NOTREACHED */
10663 return 0;
10664}
10665
Matus Fabian82e29c42016-05-11 04:49:46 -070010666static int
Matus Fabiane8554802016-05-18 23:40:37 -070010667api_policer_dump(vat_main_t *vam)
10668{
10669 unformat_input_t * i = vam->input;
10670 vl_api_policer_dump_t *mp;
10671 f64 timeout = ~0;
10672 u8 *match_name = 0;
10673 u8 match_name_valid = 0;
10674
10675 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
10676 if (unformat (i, "name %s", &match_name)) {
10677 vec_add1 (match_name, 0);
10678 match_name_valid = 1;
10679 } else
10680 break;
10681 }
10682
10683 M(POLICER_DUMP, policer_dump);
10684 mp->match_name_valid = match_name_valid;
10685 clib_memcpy (mp->match_name, match_name, vec_len (match_name));
10686 vec_free (match_name);
10687 /* send it... */
10688 S;
10689
10690 /* Use a control ping for synchronization */
10691 {
10692 vl_api_control_ping_t * mp;
10693 M(CONTROL_PING, control_ping);
10694 S;
10695 }
10696 /* Wait for a reply... */
10697 W;
10698
10699 /* NOTREACHED */
10700 return 0;
10701}
10702
10703static int
Matus Fabian82e29c42016-05-11 04:49:46 -070010704api_netmap_create (vat_main_t * vam)
10705{
10706 unformat_input_t * i = vam->input;
10707 vl_api_netmap_create_t * mp;
10708 f64 timeout;
10709 u8 * if_name = 0;
10710 u8 hw_addr[6];
10711 u8 random_hw_addr = 1;
10712 u8 is_pipe = 0;
10713 u8 is_master = 0;
10714
10715 memset (hw_addr, 0, sizeof (hw_addr));
10716
10717 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
10718 if (unformat (i, "name %s", &if_name))
10719 vec_add1 (if_name, 0);
10720 else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
10721 random_hw_addr = 0;
10722 else if (unformat (i, "pipe"))
10723 is_pipe = 1;
10724 else if (unformat (i, "master"))
10725 is_master = 1;
10726 else if (unformat (i, "slave"))
10727 is_master = 0;
10728 else
10729 break;
10730 }
10731
10732 if (!vec_len (if_name)) {
10733 errmsg ("interface name must be specified");
10734 return -99;
10735 }
10736
10737 if (vec_len (if_name) > 64) {
10738 errmsg ("interface name too long");
10739 return -99;
10740 }
10741
10742 M(NETMAP_CREATE, netmap_create);
10743
Dave Barach6f7b9922016-05-20 14:43:57 -040010744 clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
Matus Fabian82e29c42016-05-11 04:49:46 -070010745 clib_memcpy (mp->hw_addr, hw_addr, 6);
10746 mp->use_random_hw_addr = random_hw_addr;
10747 mp->is_pipe = is_pipe;
10748 mp->is_master = is_master;
10749 vec_free (if_name);
10750
10751 S; W;
10752 /* NOTREACHED */
10753 return 0;
10754}
10755
10756static int
10757api_netmap_delete (vat_main_t * vam)
10758{
10759 unformat_input_t * i = vam->input;
10760 vl_api_netmap_delete_t * mp;
10761 f64 timeout;
10762 u8 * if_name = 0;
10763
10764 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
10765 if (unformat (i, "name %s", &if_name))
10766 vec_add1 (if_name, 0);
10767 else
10768 break;
10769 }
10770
10771 if (!vec_len (if_name)) {
10772 errmsg ("interface name must be specified");
10773 return -99;
10774 }
10775
10776 if (vec_len (if_name) > 64) {
10777 errmsg ("interface name too long");
10778 return -99;
10779 }
10780
10781 M(NETMAP_DELETE, netmap_delete);
10782
Dave Barach6f7b9922016-05-20 14:43:57 -040010783 clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
Matus Fabian82e29c42016-05-11 04:49:46 -070010784 vec_free (if_name);
10785
10786 S; W;
10787 /* NOTREACHED */
10788 return 0;
10789}
10790
Ed Warnickecb9cada2015-12-08 15:45:58 -070010791static int q_or_quit (vat_main_t * vam)
10792{
10793 longjmp (vam->jump_buf, 1);
10794 return 0; /* not so much */
10795}
10796static int q (vat_main_t * vam) {return q_or_quit (vam);}
10797static int quit (vat_main_t * vam) {return q_or_quit (vam);}
10798
10799static int comment (vat_main_t * vam)
10800{
10801 return 0;
10802}
10803
Matus Fabiand2dc3df2015-12-14 10:31:33 -050010804static int cmd_cmp (void * a1, void * a2)
10805{
10806 u8 ** c1 = a1;
10807 u8 ** c2 = a2;
10808
10809 return strcmp ((char *)(c1[0]), (char *)(c2[0]));
10810}
10811
Ed Warnickecb9cada2015-12-08 15:45:58 -070010812static int help (vat_main_t * vam)
10813{
10814 u8 ** cmds = 0;
10815 u8 * name = 0;
10816 hash_pair_t * p;
10817 unformat_input_t * i = vam->input;
10818 int j;
10819
10820 if (unformat (i, "%s", &name)) {
10821 uword *hs;
10822
10823 vec_add1(name, 0);
10824
10825 hs = hash_get_mem (vam->help_by_name, name);
10826 if (hs)
10827 fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
10828 else
10829 fformat (vam->ofp, "No such msg / command '%s'\n", name);
10830 vec_free(name);
10831 return 0;
10832 }
10833
10834 fformat(vam->ofp, "Help is available for the following:\n");
10835
10836 hash_foreach_pair (p, vam->function_by_name,
10837 ({
10838 vec_add1 (cmds, (u8 *)(p->key));
10839 }));
10840
Matus Fabiand2dc3df2015-12-14 10:31:33 -050010841 vec_sort_with_function (cmds, cmd_cmp);
Ed Warnickecb9cada2015-12-08 15:45:58 -070010842
10843 for (j = 0; j < vec_len(cmds); j++)
10844 fformat (vam->ofp, "%s\n", cmds[j]);
10845
10846 vec_free (cmds);
10847 return 0;
10848}
10849
10850static int set (vat_main_t * vam)
10851{
10852 u8 * name = 0, * value = 0;
10853 unformat_input_t * i = vam->input;
10854
10855 if (unformat (i, "%s", &name)) {
10856 /* The input buffer is a vector, not a string. */
10857 value = vec_dup (i->buffer);
10858 vec_delete (value, i->index, 0);
10859 /* Almost certainly has a trailing newline */
10860 if (value[vec_len(value)-1] == '\n')
10861 value[vec_len(value)-1] = 0;
10862 /* Make sure it's a proper string, one way or the other */
10863 vec_add1 (value, 0);
10864 (void) clib_macro_set_value (&vam->macro_main,
10865 (char *)name, (char *)value);
10866 }
10867 else
10868 errmsg ("usage: set <name> <value>\n");
10869
10870 vec_free (name);
10871 vec_free (value);
10872 return 0;
10873}
10874
10875static int unset (vat_main_t * vam)
10876{
10877 u8 * name = 0;
10878
10879 if (unformat (vam->input, "%s", &name))
10880 if (clib_macro_unset (&vam->macro_main, (char *)name) == 1)
10881 errmsg ("unset: %s wasn't set\n", name);
10882 vec_free (name);
10883 return 0;
10884}
10885
10886typedef struct {
10887 u8 * name;
10888 u8 * value;
10889} macro_sort_t;
10890
10891
Matus Fabiand2dc3df2015-12-14 10:31:33 -050010892static int macro_sort_cmp (void * a1, void * a2)
10893{
10894 macro_sort_t * s1 = a1;
10895 macro_sort_t * s2 = a2;
10896
10897 return strcmp ((char *)(s1->name), (char *)(s2->name));
10898}
10899
Ed Warnickecb9cada2015-12-08 15:45:58 -070010900static int dump_macro_table (vat_main_t * vam)
10901{
10902 macro_sort_t * sort_me = 0, * sm;
10903 int i;
10904 hash_pair_t * p;
10905
10906 hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
10907 ({
10908 vec_add2 (sort_me, sm, 1);
10909 sm->name = (u8 *)(p->key);
10910 sm->value = (u8 *) (p->value[0]);
10911 }));
10912
Matus Fabiand2dc3df2015-12-14 10:31:33 -050010913 vec_sort_with_function (sort_me, macro_sort_cmp);
Ed Warnickecb9cada2015-12-08 15:45:58 -070010914
10915 if (vec_len(sort_me))
10916 fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
10917 else
10918 fformat (vam->ofp, "The macro table is empty...\n");
10919
10920 for (i = 0; i < vec_len (sort_me); i++)
10921 fformat (vam->ofp, "%-15s%s\n", sort_me[i].name,
10922 sort_me[i].value);
10923 return 0;
10924}
10925
Dave Barachb44e9bc2016-02-19 09:06:23 -050010926static int dump_node_table (vat_main_t * vam)
10927{
10928 int i, j;
10929 vlib_node_t * node, * next_node;
10930
10931 if (vec_len (vam->graph_nodes) == 0) {
10932 fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
10933 return 0;
10934 }
10935
10936 for (i = 0; i < vec_len (vam->graph_nodes); i++) {
10937 node = vam->graph_nodes[i];
10938 fformat (vam->ofp, "[%d] %s\n", i, node->name);
10939 for (j = 0; j < vec_len (node->next_nodes); j++) {
10940 if (node->next_nodes[j] != ~0) {
10941 next_node = vam->graph_nodes[node->next_nodes[j]];
10942 fformat (vam->ofp, " [%d] %s\n", j, next_node->name);
10943 }
10944 }
10945 }
10946 return 0;
10947}
10948
10949static int search_node_table (vat_main_t * vam)
10950{
10951 unformat_input_t * line_input = vam->input;
10952 u8 * node_to_find;
10953 int j;
10954 vlib_node_t * node, * next_node;
10955 uword * p;
10956
10957 if (vam->graph_node_index_by_name == 0) {
10958 fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
10959 return 0;
10960 }
10961
10962 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
10963 if (unformat (line_input, "%s", &node_to_find)) {
10964 vec_add1 (node_to_find, 0);
10965 p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
10966 if (p == 0) {
10967 fformat (vam->ofp, "%s not found...\n", node_to_find);
10968 goto out;
10969 }
10970 node = vam->graph_nodes[p[0]];
10971 fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
10972 for (j = 0; j < vec_len (node->next_nodes); j++) {
10973 if (node->next_nodes[j] != ~0) {
10974 next_node = vam->graph_nodes[node->next_nodes[j]];
10975 fformat (vam->ofp, " [%d] %s\n", j, next_node->name);
10976 }
10977 }
10978 }
10979
10980 else {
10981 clib_warning ("parse error '%U'", format_unformat_error,
10982 line_input);
10983 return -99;
10984 }
10985
10986 out:
10987 vec_free(node_to_find);
10988
10989 }
10990
10991 return 0;
10992}
10993
10994
Ed Warnickecb9cada2015-12-08 15:45:58 -070010995static int script (vat_main_t * vam)
10996{
10997 u8 * s = 0;
10998 char * save_current_file;
10999 unformat_input_t save_input;
11000 jmp_buf save_jump_buf;
11001 u32 save_line_number;
11002
11003 FILE * new_fp, * save_ifp;
11004
11005 if (unformat (vam->input, "%s", &s)) {
11006 new_fp = fopen ((char *)s, "r");
11007 if (new_fp == 0) {
11008 errmsg ("Couldn't open script file %s\n", s);
11009 vec_free (s);
11010 return -99;
11011 }
11012 } else {
11013 errmsg ("Missing script name\n");
11014 return -99;
11015 }
11016
Damjan Marionf1213b82016-03-13 02:22:06 +010011017 clib_memcpy (&save_input, &vam->input, sizeof (save_input));
11018 clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
Ed Warnickecb9cada2015-12-08 15:45:58 -070011019 save_ifp = vam->ifp;
11020 save_line_number = vam->input_line_number;
11021 save_current_file = (char *) vam->current_file;
11022
11023 vam->input_line_number = 0;
11024 vam->ifp = new_fp;
11025 vam->current_file = s;
11026 do_one_file (vam);
11027
Damjan Marionf1213b82016-03-13 02:22:06 +010011028 clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
11029 clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
Ed Warnickecb9cada2015-12-08 15:45:58 -070011030 vam->ifp = save_ifp;
11031 vam->input_line_number = save_line_number;
11032 vam->current_file = (u8 *) save_current_file;
11033 vec_free (s);
11034
11035 return 0;
11036}
11037
11038static int echo (vat_main_t * vam)
11039{
11040 fformat (vam->ofp, "%v", vam->input->buffer);
11041 return 0;
11042}
11043
11044/* List of API message constructors, CLI names map to api_xxx */
11045#define foreach_vpe_api_msg \
11046_(create_loopback,"[mac <mac-addr>]") \
11047_(sw_interface_dump,"") \
11048_(sw_interface_set_flags, \
11049 "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
11050_(sw_interface_add_del_address, \
11051 "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
11052_(sw_interface_set_table, \
11053 "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]") \
11054_(sw_interface_set_vpath, \
11055 "<intfc> | sw_if_index <id> enable | disable") \
11056_(sw_interface_set_l2_xconnect, \
11057 "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
11058 "enable | disable") \
11059_(sw_interface_set_l2_bridge, \
11060 "rx <intfc> | rx_sw_if_index <id> bd_id <bridge-domain-id>\n" \
11061 "[shg <split-horizon-group>] [bvi]\n" \
11062 "enable | disable") \
11063_(bridge_domain_add_del, \
11064 "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
11065_(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n") \
11066_(l2fib_add_del, \
11067 "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi]\n") \
11068_(l2_flags, \
11069 "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
11070_(bridge_flags, \
11071 "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
11072_(tap_connect, \
11073 "tapname <name> mac <mac-addr> | random-mac") \
11074_(tap_modify, \
11075 "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
11076_(tap_delete, \
11077 "<vpp-if-name> | sw_if_index <id>") \
11078_(sw_interface_tap_dump, "") \
11079_(ip_add_del_route, \
11080 "<addr>/<mask> via <addr> [vrf <n>]\n" \
11081 "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n" \
11082 "[weight <n>] [drop] [local] [classify <n>] [del]\n" \
11083 "[multipath] [count <n>]") \
11084_(proxy_arp_add_del, \
11085 "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]") \
11086_(proxy_arp_intfc_enable_disable, \
11087 "<intfc> | sw_if_index <id> enable | disable") \
11088_(mpls_add_del_encap, \
11089 "label <n> dst <ip4-addr> [vrf <n>] [del]") \
11090_(mpls_add_del_decap, \
11091 "label <n> [rx_vrf_id <n>] [tx_vrf_id] [s-bit-clear][del]") \
11092_(mpls_gre_add_del_tunnel, \
11093 "inner_vrf_id <n> outer_vrf_id <n> src <ip4-address> dst <ip4-address>\n" \
11094 "adj <ip4-address>/<mask-width> [del]") \
11095_(sw_interface_set_unnumbered, \
11096 "<intfc> | sw_if_index <id> unnum_if_index <id> [del]") \
11097_(ip_neighbor_add_del, \
11098 "<intfc> | sw_if_index <id> dst <ip46-address> mac <mac-addr>") \
11099_(reset_vrf, "vrf <id> [ipv6]") \
11100_(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>") \
11101_(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n" \
11102 "[outer_vlan_id <n>][inner_vlan_id <n>]\n" \
11103 "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n" \
11104 "[outer_vlan_id_any][inner_vlan_id_any]") \
11105_(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]") \
11106_(reset_fib, "vrf <n> [ipv6]") \
11107_(dhcp_proxy_config, \
11108 "svr <v46-address> src <v46-address>\n" \
11109 "insert-cid <n> [del]") \
11110_(dhcp_proxy_config_2, \
11111 "svr <v46-address> src <v46-address>\n" \
11112 "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]") \
11113_(dhcp_proxy_set_vss, \
11114 "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]") \
11115_(dhcp_client_config, \
11116 "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
11117_(set_ip_flow_hash, \
11118 "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]") \
11119_(sw_interface_ip6_enable_disable, \
11120 "<intfc> | sw_if_index <id> enable | disable") \
11121_(sw_interface_ip6_set_link_local_address, \
11122 "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>") \
11123_(sw_interface_ip6nd_ra_prefix, \
11124 "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n" \
11125 "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n" \
11126 "[nolink] [isno]") \
11127_(sw_interface_ip6nd_ra_config, \
11128 "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n" \
11129 "[life <n>] [count <n>] [interval <n>] [surpress]\n" \
11130 "[managed] [other] [ll] [send] [cease] [isno] [def]") \
11131_(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]") \
11132_(l2_patch_add_del, \
11133 "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
11134 "enable | disable") \
11135_(mpls_ethernet_add_del_tunnel, \
11136 "tx <intfc> | tx_sw_if_index <n> dst <mac-addr>\n" \
11137 "adj <ip4-addr>/<mw> dst <mac-addr> [del]") \
11138_(mpls_ethernet_add_del_tunnel_2, \
11139 "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n" \
11140 "resolve-attempts <n> resolve-if-needed 0 | 1 [del]") \
11141_(sr_tunnel_add_del, \
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -070011142 "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n" \
11143 "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n" \
11144 "[policy <policy_name>]") \
11145_(sr_policy_add_del, \
11146 "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]") \
11147_(sr_multicast_map_add_del, \
11148 "address [ip6 multicast address] sr-policy [policy name] [del]") \
Ed Warnickecb9cada2015-12-08 15:45:58 -070011149_(classify_add_del_table, \
11150 "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n" \
11151 "[del] mask <mask-value>\n" \
11152 " [l2-miss-next | miss-next | acl-miss-next] <name|nn>") \
11153_(classify_add_del_session, \
11154 "[hit-next|l2-hit-next|acl-hit-next] <name|nn> table-index <nn>\n" \
11155 "skip_n <nn> match_n <nn> match [hex] [l2] [l3 [ip4|ip6]]") \
11156_(classify_set_interface_ip_table, \
11157 "<intfc> | sw_if_index <nn> table <nn>") \
11158_(classify_set_interface_l2_tables, \
11159 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
11160 " [other-table <nn>]") \
11161_(get_node_index, "node <node-name") \
11162_(add_node_next, "node <node-name> next <next-node-name>") \
11163_(l2tpv3_create_tunnel, \
11164 "client_address <ip6-addr> our_address <ip6-addr>\n" \
11165 "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
11166 "[remote_cookie <nn>]\n[l2-sublayer-preset]\n") \
11167_(l2tpv3_set_tunnel_cookies, \
11168 "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n" \
11169 "[new_remote_cookie <nn>]\n") \
11170_(l2tpv3_interface_enable_disable, \
11171 "<intfc> | sw_if_index <nn> enable | disable") \
11172_(l2tpv3_set_lookup_key, \
11173 "lookup_v6_src | lookup_v6_dst | lookup_session_id") \
11174_(sw_if_l2tpv3_tunnel_dump, "") \
11175_(vxlan_add_del_tunnel, \
Chris Luke404be662016-05-27 12:11:24 -040011176 "src <ip-addr> dst <ip-addr> vni <vni> [encap-vrf-id <nn>]\n" \
Ed Warnickecb9cada2015-12-08 15:45:58 -070011177 " [decap-next l2|ip4|ip6] [del]") \
Dave Wallace60231f32015-12-17 21:04:30 -050011178_(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
Chris Luke27fe48f2016-04-28 13:44:38 -040011179_(gre_add_del_tunnel, \
11180 "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [del]\n") \
11181_(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
Ed Warnickecb9cada2015-12-08 15:45:58 -070011182_(l2_fib_clear_table, "") \
11183_(l2_interface_efp_filter, "sw_if_index <nn> enable | disable") \
11184_(l2_interface_vlan_tag_rewrite, \
11185 "<intfc> | sw_if_index <nn> \n" \
11186 "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n" \
11187 "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>") \
11188_(create_vhost_user_if, \
Pierre Pfisteref65cb02016-02-19 13:52:44 +000011189 "socket <filename> [server] [renumber <dev_instance>] " \
11190 "[mac <mac_address>]") \
Ed Warnickecb9cada2015-12-08 15:45:58 -070011191_(modify_vhost_user_if, \
11192 "<intfc> | sw_if_index <nn> socket <filename>\n" \
11193 "[server] [renumber <dev_instance>]") \
11194_(delete_vhost_user_if, "<intfc> | sw_if_index <nn>") \
11195_(sw_interface_vhost_user_dump, "") \
11196_(show_version, "") \
Hongjun Ni0e06e2b2016-05-30 19:45:51 +080011197_(vxlan_gpe_add_del_tunnel, \
11198 "local <addr> remote <addr> vni <nn>\n" \
11199 "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]" \
11200 "[next-ethernet] [next-nsh]\n") \
11201_(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
Ed Warnickecb9cada2015-12-08 15:45:58 -070011202_(l2_fib_table_dump, "bd_id <bridge-domain-id>") \
Ed Warnickecb9cada2015-12-08 15:45:58 -070011203_(interface_name_renumber, \
11204 "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>") \
11205_(input_acl_set_interface, \
11206 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
11207 " [l2-table <nn>] [del]") \
11208_(want_ip4_arp_events, "address <ip4-address> [del]") \
11209_(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)") \
11210_(ip_dump, "ipv4 | ipv6") \
11211_(ipsec_spd_add_del, "spd_id <n> [del]") \
11212_(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n" \
11213 " spid_id <n> ") \
11214_(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n" \
11215 " crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n" \
11216 " integ_alg <alg> integ_key <hex>") \
11217_(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n" \
11218 " (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n" \
11219 " laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
11220 " [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
11221_(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>") \
Matus Fabiane5f42fe2016-04-08 11:18:08 +020011222_(ikev2_profile_add_del, "name <profile_name> [del]") \
11223_(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n" \
11224 "(auth_data 0x<data> | auth_data <data>)") \
11225_(ikev2_profile_set_id, "name <profile_name> id_type <type>\n" \
11226 "(id_data 0x<data> | id_data <data>) (local|remote)") \
11227_(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n" \
11228 "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
11229 "(local|remote)") \
11230_(ikev2_set_local_key, "file <absolute_file_path>") \
Ed Warnickecb9cada2015-12-08 15:45:58 -070011231_(delete_loopback,"sw_if_index <nn>") \
11232_(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
11233_(map_add_domain, \
11234 "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> " \
11235 "ip6-src <ip6addr> " \
11236 "ea-bits-len <n> psid-offset <n> psid-len <n>") \
11237_(map_del_domain, "index <n>") \
11238_(map_add_del_rule, \
11239 "index <n> psid <n> dst <ip6addr> [del]") \
11240_(map_domain_dump, "") \
11241_(map_rule_dump, "index <map-domain>") \
11242_(want_interface_events, "enable|disable") \
11243_(want_stats,"enable|disable") \
Dave Barachc07bf5d2016-02-17 17:52:26 -050011244_(get_first_msg_id, "client <name>") \
11245_(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
11246_(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n" \
Dave Barachb44e9bc2016-02-19 09:06:23 -050011247 "fib-id <nn> [ip4][ip6][default]") \
Pavel Kotucek00bbf272016-03-03 13:27:11 +010011248_(get_node_graph, " ") \
Shwetha20a64f52016-03-25 10:55:01 +000011249_(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>") \
11250_(trace_profile_add, "id <nn> trace-type <0x1f|0x3|0x9|0x11|0x19> " \
11251 "trace-elts <nn> trace-tsp <0|1|2|3> node-id <node id in hex> " \
11252 "app-data <app_data in hex> [pow] [ppc <encap|decap>]") \
11253_(trace_profile_apply, "id <nn> <ip6-address>/<width>" \
11254 " vrf_id <nn> add | pop | none") \
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020011255_(trace_profile_del, "") \
11256_(lisp_add_del_locator_set, "locator-set <locator_name> [del]") \
11257_(lisp_add_del_locator, "locator-set <locator_name> " \
11258 "iface <intf> | sw_if_index <sw_if_index> " \
11259 "p <priority> w <weight> [del]") \
11260_(lisp_add_del_local_eid, "<ipv4|ipv6>/<prefix> " \
11261 "locator-set <locator_name> [del]") \
11262_(lisp_gpe_add_del_fwd_entry, "eid <ip4|6-addr>/<prefix> " \
11263 "sloc <ip4/6-addr> dloc <ip4|6-addr> [del]") \
11264_(lisp_add_del_map_resolver, "<ip4|6-addr> [del]") \
Florin Coras577c3552016-04-21 00:45:40 +020011265_(lisp_gpe_enable_disable, "enable|disable") \
Filip Tehlar46d4e362016-05-09 09:39:26 +020011266_(lisp_enable_disable, "enable|disable") \
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020011267_(lisp_gpe_add_del_iface, "up|down") \
Filip Tehlar53f09e32016-05-19 14:25:44 +020011268_(lisp_add_del_remote_mapping, "add|del vni <vni> table-id <id> " \
11269 "deid <dest-eid> seid" \
Filip Tehlar195bcee2016-05-13 17:37:35 +020011270 " <src-eid> rloc <locator> " \
11271 "[rloc <loc> ... ]") \
Filip Tehlar53f09e32016-05-19 14:25:44 +020011272_(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del") \
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020011273_(lisp_locator_set_dump, "") \
11274_(lisp_local_eid_table_dump, "") \
11275_(lisp_gpe_tunnel_dump, "") \
Andrej Kozemcaka9edd852016-05-02 12:14:33 +020011276_(lisp_map_resolver_dump, "") \
Filip Tehlar46d4e362016-05-09 09:39:26 +020011277_(lisp_enable_disable_status_dump, "") \
Matus Fabian8a95a482016-05-06 15:14:13 +020011278_(af_packet_create, "name <host interface name> [hw_addr <mac>]") \
Matus Fabian65fcd4d2016-05-13 05:44:48 -070011279_(af_packet_delete, "name <host interface name>") \
Matus Fabian82e29c42016-05-11 04:49:46 -070011280_(policer_add_del, "name <policer name> <params> [del]") \
Matus Fabiane8554802016-05-18 23:40:37 -070011281_(policer_dump, "[name <policer name>]") \
Matus Fabian82e29c42016-05-11 04:49:46 -070011282_(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] " \
11283 "[master|slave]") \
11284_(netmap_delete, "name <interface name>")
Ed Warnickecb9cada2015-12-08 15:45:58 -070011285
11286/* List of command functions, CLI names map directly to functions */
11287#define foreach_cli_function \
11288_(comment, "usage: comment <ignore-rest-of-line>") \
11289_(dump_interface_table, "usage: dump_interface_table") \
11290_(dump_sub_interface_table, "usage: dump_sub_interface_table") \
11291_(dump_ipv4_table, "usage: dump_ipv4_table") \
11292_(dump_ipv6_table, "usage: dump_ipv6_table") \
11293_(dump_stats_table, "usage: dump_stats_table") \
11294_(dump_macro_table, "usage: dump_macro_table ") \
Dave Barachb44e9bc2016-02-19 09:06:23 -050011295_(dump_node_table, "usage: dump_node_table") \
Ed Warnickecb9cada2015-12-08 15:45:58 -070011296_(echo, "usage: echo <message>") \
11297_(exec, "usage: exec <vpe-debug-CLI-command>") \
11298_(help, "usage: help") \
11299_(q, "usage: quit") \
11300_(quit, "usage: quit") \
Dave Barachb44e9bc2016-02-19 09:06:23 -050011301_(search_node_table, "usage: search_node_table <name>...") \
Ed Warnickecb9cada2015-12-08 15:45:58 -070011302_(set, "usage: set <variable-name> <value>") \
11303_(script, "usage: script <file-name>") \
11304_(unset, "usage: unset <variable-name>")
11305
11306#define _(N,n) \
11307 static void vl_api_##n##_t_handler_uni \
11308 (vl_api_##n##_t * mp) \
11309 { \
11310 vat_main_t * vam = &vat_main; \
11311 if (vam->json_output) { \
11312 vl_api_##n##_t_handler_json(mp); \
11313 } else { \
11314 vl_api_##n##_t_handler(mp); \
11315 } \
11316 }
11317foreach_vpe_api_reply_msg;
11318#undef _
11319
11320void vat_api_hookup (vat_main_t *vam)
11321{
11322#define _(N,n) \
11323 vl_msg_api_set_handlers(VL_API_##N, #n, \
11324 vl_api_##n##_t_handler_uni, \
11325 vl_noop_handler, \
11326 vl_api_##n##_t_endian, \
11327 vl_api_##n##_t_print, \
11328 sizeof(vl_api_##n##_t), 1);
11329 foreach_vpe_api_reply_msg;
11330#undef _
11331
11332 vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
11333
11334 vam->sw_if_index_by_interface_name =
11335 hash_create_string (0, sizeof (uword));
11336
11337 vam->function_by_name =
11338 hash_create_string (0, sizeof(uword));
11339
11340 vam->help_by_name =
11341 hash_create_string (0, sizeof(uword));
11342
11343 /* API messages we can send */
11344#define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
11345 foreach_vpe_api_msg;
11346#undef _
11347
11348 /* Help strings */
11349#define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
11350 foreach_vpe_api_msg;
11351#undef _
11352
11353 /* CLI functions */
11354#define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
11355 foreach_cli_function;
11356#undef _
11357
11358 /* Help strings */
11359#define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
11360 foreach_cli_function;
11361#undef _
11362}
11363
11364#undef vl_api_version
11365#define vl_api_version(n,v) static u32 vpe_api_version = v;
11366#include <api/vpe.api.h>
11367#undef vl_api_version
11368
11369void vl_client_add_api_signatures (vl_api_memclnt_create_t *mp)
11370{
11371 /*
11372 * Send the main API signature in slot 0. This bit of code must
11373 * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
11374 */
11375 mp->api_versions[0] = clib_host_to_net_u32 (vpe_api_version);
11376}