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