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