blob: 051f95f9470ad8c594260079693196c0aa2d3dc6 [file] [log] [blame]
Ed Warnickecb9cada2015-12-08 15:45:58 -07001/*
2 *------------------------------------------------------------------
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08003 * api_format.c
4 *
Ed Warnickecb9cada2015-12-08 15:45:58 -07005 * 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
Hongjun Ni11bfc2f2016-07-22 18:19:19 +080016 * limitations under the License.
Ed Warnickecb9cada2015-12-08 15:45:58 -070017 *------------------------------------------------------------------
18 */
19
20#include <vat/vat.h>
21#include <vlibapi/api.h>
22#include <vlibmemory/api.h>
23#include <vlibsocket/api.h>
24#include <vnet/ip/ip.h>
25#include <vnet/sr/sr_packet.h>
26#include <vnet/l2/l2_input.h>
27#include <vnet/l2tp/l2tp.h>
28#include <vnet/vxlan/vxlan.h>
Chris Luke27fe48f2016-04-28 13:44:38 -040029#include <vnet/gre/gre.h>
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -070030#include <vnet/vxlan-gpe/vxlan_gpe.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070031#include <vnet/lisp-gpe/lisp_gpe.h>
32
Dave Barachaa6920e2016-06-27 09:25:13 -040033#include <vpp-api/vpe_msg_enum.h>
Hongjun Ni11bfc2f2016-07-22 18:19:19 +080034#include <vnet/l2/l2_classify.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070035#include <vnet/l2/l2_vtr.h>
36#include <vnet/classify/input_acl.h>
Matus Fabian70e6a8d2016-06-20 08:10:42 -070037#include <vnet/classify/policer_classify.h>
marek zavodsky2c21a9a2016-06-21 05:35:16 +020038#include <vnet/mpls-gre/mpls.h>
Dave Barachbfdedbd2016-01-20 09:11:55 -050039#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -070040#include <vnet/ipsec/ipsec.h>
Matus Fabiane5f42fe2016-04-08 11:18:08 +020041#include <vnet/ipsec/ikev2.h>
Dave Barachbfdedbd2016-01-20 09:11:55 -050042#else
43#include <inttypes.h>
44#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -070045#include <vnet/map/map.h>
Dave Barachc07bf5d2016-02-17 17:52:26 -050046#include <vnet/cop/cop.h>
Shwetha20a64f52016-03-25 10:55:01 +000047#include <vnet/ip/ip6_hop_by_hop.h>
Dave Barach6f9bca22016-04-30 10:25:32 -040048#include <vnet/ip/ip_source_and_port_range_check.h>
Matus Fabian65fcd4d2016-05-13 05:44:48 -070049#include <vnet/policer/xlate.h>
Matus Fabian4ac74c92016-05-31 07:33:29 -070050#include <vnet/policer/policer.h>
Matus Fabian70e6a8d2016-06-20 08:10:42 -070051#include <vnet/policer/police.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070052
53#include "vat/json_format.h"
54
Pavel Kotucek9e6ed6e2016-07-12 10:18:26 +020055#include <sys/stat.h>
56
Ed Warnickecb9cada2015-12-08 15:45:58 -070057#define vl_typedefs /* define message structures */
Hongjun Ni11bfc2f2016-07-22 18:19:19 +080058#include <vpp-api/vpe_all_api_h.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070059#undef vl_typedefs
60
61/* declare message handlers for each api */
62
63#define vl_endianfun /* define message structures */
Hongjun Ni11bfc2f2016-07-22 18:19:19 +080064#include <vpp-api/vpe_all_api_h.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070065#undef vl_endianfun
66
67/* instantiate all the print functions we know about */
68#define vl_print(handle, ...)
69#define vl_printfun
Dave Barachaa6920e2016-06-27 09:25:13 -040070#include <vpp-api/vpe_all_api_h.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070071#undef vl_printfun
72
73uword unformat_sw_if_index (unformat_input_t * input, va_list * args)
74{
75 vat_main_t * vam = va_arg (*args, vat_main_t *);
76 u32 * result = va_arg (*args, u32 *);
77 u8 * if_name;
78 uword * p;
79
80 if (!unformat (input, "%s", &if_name))
81 return 0;
82
83 p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
84 if (p == 0)
85 return 0;
86 *result = p[0];
87 return 1;
88}
89
90/* Parse an IP4 address %d.%d.%d.%d. */
91uword unformat_ip4_address (unformat_input_t * input, va_list * args)
92{
93 u8 * result = va_arg (*args, u8 *);
94 unsigned a[4];
95
96 if (! unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
97 return 0;
98
99 if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
100 return 0;
101
102 result[0] = a[0];
103 result[1] = a[1];
104 result[2] = a[2];
105 result[3] = a[3];
106
107 return 1;
108}
109
110
111uword
112unformat_ethernet_address (unformat_input_t * input, va_list * args)
113{
114 u8 * result = va_arg (*args, u8 *);
115 u32 i, a[6];
116
117 if (! unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
118 &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
119 return 0;
120
121 /* Check range. */
122 for (i = 0; i < 6; i++)
123 if (a[i] >= (1 << 8))
124 return 0;
125
126 for (i = 0; i < 6; i++)
127 result[i] = a[i];
128
129 return 1;
130}
131
132/* Returns ethernet type as an int in host byte order. */
133uword
134unformat_ethernet_type_host_byte_order (unformat_input_t * input,
135 va_list * args)
136{
137 u16 * result = va_arg (*args, u16 *);
138 int type;
139
140 /* Numeric type. */
141 if (unformat (input, "0x%x", &type)
142 || unformat (input, "%d", &type))
143 {
144 if (type >= (1 << 16))
145 return 0;
146 *result = type;
147 return 1;
148 }
149 return 0;
150}
151
152/* Parse an IP6 address. */
153uword unformat_ip6_address (unformat_input_t * input, va_list * args)
154{
155 ip6_address_t * result = va_arg (*args, ip6_address_t *);
156 u16 hex_quads[8];
157 uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
158 uword c, n_colon, double_colon_index;
159
160 n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
161 double_colon_index = ARRAY_LEN (hex_quads);
162 while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
163 {
164 hex_digit = 16;
165 if (c >= '0' && c <= '9')
166 hex_digit = c - '0';
167 else if (c >= 'a' && c <= 'f')
168 hex_digit = c + 10 - 'a';
169 else if (c >= 'A' && c <= 'F')
170 hex_digit = c + 10 - 'A';
171 else if (c == ':' && n_colon < 2)
172 n_colon++;
173 else
174 {
175 unformat_put_input (input);
176 break;
177 }
178
179 /* Too many hex quads. */
180 if (n_hex_quads >= ARRAY_LEN (hex_quads))
181 return 0;
182
183 if (hex_digit < 16)
184 {
185 hex_quad = (hex_quad << 4) | hex_digit;
186
187 /* Hex quad must fit in 16 bits. */
188 if (n_hex_digits >= 4)
189 return 0;
190
191 n_colon = 0;
192 n_hex_digits++;
193 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +0800194
Ed Warnickecb9cada2015-12-08 15:45:58 -0700195 /* Save position of :: */
196 if (n_colon == 2)
197 {
198 /* More than one :: ? */
199 if (double_colon_index < ARRAY_LEN (hex_quads))
200 return 0;
201 double_colon_index = n_hex_quads;
202 }
203
204 if (n_colon > 0 && n_hex_digits > 0)
205 {
206 hex_quads[n_hex_quads++] = hex_quad;
207 hex_quad = 0;
208 n_hex_digits = 0;
209 }
210 }
211
212 if (n_hex_digits > 0)
213 hex_quads[n_hex_quads++] = hex_quad;
214
215 {
216 word i;
217
218 /* Expand :: to appropriate number of zero hex quads. */
219 if (double_colon_index < ARRAY_LEN (hex_quads))
220 {
221 word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
222
223 for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
224 hex_quads[n_zero + i] = hex_quads[i];
225
226 for (i = 0; i < n_zero; i++)
227 hex_quads[double_colon_index + i] = 0;
228
229 n_hex_quads = ARRAY_LEN (hex_quads);
230 }
231
232 /* Too few hex quads given. */
233 if (n_hex_quads < ARRAY_LEN (hex_quads))
234 return 0;
235
236 for (i = 0; i < ARRAY_LEN (hex_quads); i++)
237 result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
238
239 return 1;
240 }
241}
242
243uword
244unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
245{
Dave Barachbfdedbd2016-01-20 09:11:55 -0500246#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -0700247 u32 * r = va_arg (*args, u32 *);
248
249 if (0) ;
250#define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
251 foreach_ipsec_policy_action
252#undef _
253 else
254 return 0;
255 return 1;
Dave Barachbfdedbd2016-01-20 09:11:55 -0500256#else
257 return 0;
258#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -0700259}
260
261uword
262unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
263{
Dave Barachbfdedbd2016-01-20 09:11:55 -0500264#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -0700265 u32 * r = va_arg (*args, u32 *);
266
267 if (0) ;
268#define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
269 foreach_ipsec_crypto_alg
270#undef _
271 else
272 return 0;
273 return 1;
Dave Barachbfdedbd2016-01-20 09:11:55 -0500274#else
275 return 0;
276#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -0700277}
278
279u8 *
280format_ipsec_crypto_alg (u8 * s, va_list * args)
281{
Dave Barachbfdedbd2016-01-20 09:11:55 -0500282#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -0700283 u32 i = va_arg (*args, u32);
284 u8 * t = 0;
285
286 switch (i)
287 {
288#define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
289 foreach_ipsec_crypto_alg
290#undef _
291 default:
292 return format (s, "unknown");
293 }
294 return format (s, "%s", t);
Dave Barachbfdedbd2016-01-20 09:11:55 -0500295#else
296 return format (s, "Unimplemented");
297#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -0700298}
299
300uword
301unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
302{
Dave Barachbfdedbd2016-01-20 09:11:55 -0500303#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -0700304 u32 * r = va_arg (*args, u32 *);
305
306 if (0) ;
307#define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
308 foreach_ipsec_integ_alg
309#undef _
310 else
311 return 0;
312 return 1;
Dave Barachbfdedbd2016-01-20 09:11:55 -0500313#else
314 return 0;
315#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -0700316}
317
318u8 *
319format_ipsec_integ_alg (u8 * s, va_list * args)
320{
Dave Barachbfdedbd2016-01-20 09:11:55 -0500321#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -0700322 u32 i = va_arg (*args, u32);
323 u8 * t = 0;
324
325 switch (i)
326 {
327#define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
328 foreach_ipsec_integ_alg
329#undef _
330 default:
331 return format (s, "unknown");
332 }
333 return format (s, "%s", t);
Dave Barachbfdedbd2016-01-20 09:11:55 -0500334#else
335 return format (s, "Unsupported");
336#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -0700337}
338
Matus Fabiane5f42fe2016-04-08 11:18:08 +0200339uword
340unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
341{
342#if DPDK > 0
343 u32 * r = va_arg (*args, u32 *);
344
345 if (0) ;
346#define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
347 foreach_ikev2_auth_method
348#undef _
349 else
350 return 0;
351 return 1;
352#else
353 return 0;
354#endif
355}
356
357uword
358unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
359{
360#if DPDK > 0
361 u32 * r = va_arg (*args, u32 *);
362
363 if (0) ;
364#define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
365 foreach_ikev2_id_type
366#undef _
367 else
368 return 0;
369 return 1;
370#else
371 return 0;
372#endif
373}
374
Matus Fabian65fcd4d2016-05-13 05:44:48 -0700375uword
376unformat_policer_rate_type (unformat_input_t * input, va_list * args)
377{
378 u8 * r = va_arg (*args, u8 *);
379
380 if (unformat (input, "kbps"))
381 *r = SSE2_QOS_RATE_KBPS;
382 else if (unformat(input, "pps"))
383 *r = SSE2_QOS_RATE_PPS;
384 else
385 return 0;
386 return 1;
387}
388
389uword
390unformat_policer_round_type (unformat_input_t * input, va_list * args)
391{
392 u8 * r = va_arg (*args, u8 *);
393
394 if (unformat(input, "closest"))
395 *r = SSE2_QOS_ROUND_TO_CLOSEST;
396 else if (unformat (input, "up"))
397 *r = SSE2_QOS_ROUND_TO_UP;
398 else if (unformat (input, "down"))
399 *r = SSE2_QOS_ROUND_TO_DOWN;
400 else
401 return 0;
402 return 1;
403}
404
405uword
406unformat_policer_type (unformat_input_t * input, va_list * args)
407{
408 u8 * r = va_arg (*args, u8 *);
409
410 if (unformat (input, "1r2c"))
411 *r = SSE2_QOS_POLICER_TYPE_1R2C;
412 else if (unformat (input, "1r3c"))
413 *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
414 else if (unformat (input, "2r3c-2698"))
415 *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
416 else if (unformat (input, "2r3c-4115"))
417 *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
418 else if (unformat (input, "2r3c-mef5cf1"))
419 *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
420 else
421 return 0;
422 return 1;
423}
424
Matus Fabian4ac74c92016-05-31 07:33:29 -0700425uword
426unformat_dscp (unformat_input_t * input, va_list * va)
427{
428 u8 * r = va_arg (*va, u8 *);
429
430 if (0) ;
431#define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
432 foreach_vnet_dscp
433#undef _
434 else
435 return 0;
436 return 1;
437}
438
439uword
440unformat_policer_action_type (unformat_input_t * input, va_list * va)
441{
442 sse2_qos_pol_action_params_st * a
443 = va_arg (*va, sse2_qos_pol_action_params_st *);
444
445 if (unformat (input, "drop"))
446 a->action_type = SSE2_QOS_ACTION_DROP;
447 else if (unformat (input, "transmit"))
448 a->action_type = SSE2_QOS_ACTION_TRANSMIT;
449 else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
450 a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
451 else
452 return 0;
453 return 1;
454}
455
Matus Fabian70e6a8d2016-06-20 08:10:42 -0700456uword
457unformat_classify_table_type (unformat_input_t * input, va_list * va)
458{
459 u32 * r = va_arg (*va, u32 *);
460 u32 tid;
461
462 if (unformat (input, "ip4"))
463 tid = POLICER_CLASSIFY_TABLE_IP4;
464 else if (unformat (input, "ip6"))
465 tid = POLICER_CLASSIFY_TABLE_IP6;
466 else if (unformat (input, "l2"))
467 tid = POLICER_CLASSIFY_TABLE_L2;
468 else
469 return 0;
470
471 *r = tid;
472 return 1;
473}
474
Ed Warnickecb9cada2015-12-08 15:45:58 -0700475u8 * format_ip4_address (u8 * s, va_list * args)
476{
477 u8 * a = va_arg (*args, u8 *);
478 return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
479}
480
481u8 * format_ip6_address (u8 * s, va_list * args)
482{
483 ip6_address_t * a = va_arg (*args, ip6_address_t *);
484 u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
485
486 i_max_n_zero = ARRAY_LEN (a->as_u16);
487 max_n_zeros = 0;
488 i_first_zero = i_max_n_zero;
489 n_zeros = 0;
490 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
491 {
492 u32 is_zero = a->as_u16[i] == 0;
493 if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
494 {
495 i_first_zero = i;
496 n_zeros = 0;
497 }
498 n_zeros += is_zero;
499 if ((! is_zero && n_zeros > max_n_zeros)
500 || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
501 {
502 i_max_n_zero = i_first_zero;
503 max_n_zeros = n_zeros;
504 i_first_zero = ARRAY_LEN (a->as_u16);
505 n_zeros = 0;
506 }
507 }
508
509 last_double_colon = 0;
510 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
511 {
512 if (i == i_max_n_zero && max_n_zeros > 1)
513 {
514 s = format (s, "::");
515 i += max_n_zeros - 1;
516 last_double_colon = 1;
517 }
518 else
519 {
520 s = format (s, "%s%x",
521 (last_double_colon || i == 0) ? "" : ":",
522 clib_net_to_host_u16 (a->as_u16[i]));
523 last_double_colon = 0;
524 }
525 }
526
527 return s;
528}
529
Chris Luke99cb3352016-04-26 10:49:53 -0400530/* Format an IP46 address. */
531u8 * format_ip46_address (u8 * s, va_list * args)
532{
533 ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
Damjan Marion86be4872016-05-24 23:19:11 +0200534 ip46_type_t type = va_arg (*args, ip46_type_t);
535 int is_ip4 = 1;
536
537 switch (type)
538 {
539 case IP46_TYPE_ANY:
540 is_ip4 = ip46_address_is_ip4(ip46);
541 break;
542 case IP46_TYPE_IP4:
543 is_ip4 = 1;
544 break;
545 case IP46_TYPE_IP6:
546 is_ip4 = 0;
547 break;
548 }
549
550 return is_ip4 ?
Chris Luke99cb3352016-04-26 10:49:53 -0400551 format(s, "%U", format_ip4_address, &ip46->ip4):
552 format(s, "%U", format_ip6_address, &ip46->ip6);
553}
554
Ed Warnickecb9cada2015-12-08 15:45:58 -0700555u8 * format_ethernet_address (u8 * s, va_list * args)
556{
557 u8 * a = va_arg (*args, u8 *);
558
559 return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
560 a[0], a[1], a[2], a[3], a[4], a[5]);
561}
562
563void increment_v4_address (ip4_address_t * a)
564{
565 u32 v;
566
567 v = ntohl(a->as_u32) + 1;
568 a->as_u32 = ntohl(v);
569}
570
571void increment_v6_address (ip6_address_t * a)
572{
573 u64 v0, v1;
574
575 v0 = clib_net_to_host_u64 (a->as_u64[0]);
576 v1 = clib_net_to_host_u64 (a->as_u64[1]);
577
578 v1 += 1;
579 if (v1 == 0)
580 v0 += 1;
581 a->as_u64[0] = clib_net_to_host_u64 (v0);
582 a->as_u64[1] = clib_net_to_host_u64 (v1);
583}
584
Dave Barach41da02d2016-07-11 16:48:42 -0700585void increment_mac_address (u64 *mac)
586{
587 u64 tmp = *mac;
588
589 tmp = clib_net_to_host_u64(tmp);
590 tmp += 1<<16; /* skip unused (least significant) octets */
591 tmp = clib_host_to_net_u64 (tmp);
592 *mac = tmp;
593}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700594
Hongjun Ni11bfc2f2016-07-22 18:19:19 +0800595static void vl_api_create_loopback_reply_t_handler
Ed Warnickecb9cada2015-12-08 15:45:58 -0700596(vl_api_create_loopback_reply_t * mp)
597{
598 vat_main_t * vam = &vat_main;
599 i32 retval = ntohl(mp->retval);
600
601 vam->retval = retval;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700602 vam->regenerate_interface_table = 1;
Keith Burns (alagalah)802255c2016-06-13 16:56:04 -0700603 vam->sw_if_index = ntohl (mp->sw_if_index);
604 vam->result_ready = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700605}
606
607static void vl_api_create_loopback_reply_t_handler_json
608(vl_api_create_loopback_reply_t * mp)
609{
610 vat_main_t * vam = &vat_main;
611 vat_json_node_t node;
612
613 vat_json_init_object(&node);
614 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
615 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
616
617 vat_json_print(vam->ofp, &node);
618 vat_json_free(&node);
Keith Burns (alagalah)802255c2016-06-13 16:56:04 -0700619 vam->retval = ntohl(mp->retval);
620 vam->result_ready = 1;
621}
622
Hongjun Ni11bfc2f2016-07-22 18:19:19 +0800623static void vl_api_af_packet_create_reply_t_handler
Keith Burns (alagalah)802255c2016-06-13 16:56:04 -0700624(vl_api_af_packet_create_reply_t * mp)
625{
626 vat_main_t * vam = &vat_main;
627 i32 retval = ntohl(mp->retval);
628
629 vam->retval = retval;
630 vam->regenerate_interface_table = 1;
631 vam->sw_if_index = ntohl (mp->sw_if_index);
632 vam->result_ready = 1;
633}
634
635static void vl_api_af_packet_create_reply_t_handler_json
636(vl_api_af_packet_create_reply_t * mp)
637{
638 vat_main_t * vam = &vat_main;
639 vat_json_node_t node;
640
641 vat_json_init_object(&node);
642 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
643 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
644
645 vat_json_print(vam->ofp, &node);
646 vat_json_free(&node);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700647
648 vam->retval = ntohl(mp->retval);
649 vam->result_ready = 1;
650}
651
Hongjun Ni11bfc2f2016-07-22 18:19:19 +0800652static void vl_api_create_vlan_subif_reply_t_handler
Ed Warnickecb9cada2015-12-08 15:45:58 -0700653(vl_api_create_vlan_subif_reply_t * mp)
654{
655 vat_main_t * vam = &vat_main;
656 i32 retval = ntohl(mp->retval);
657
658 vam->retval = retval;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700659 vam->regenerate_interface_table = 1;
Keith Burns (alagalah)802255c2016-06-13 16:56:04 -0700660 vam->sw_if_index = ntohl (mp->sw_if_index);
661 vam->result_ready = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700662}
663
664static void vl_api_create_vlan_subif_reply_t_handler_json
665(vl_api_create_vlan_subif_reply_t * mp)
666{
667 vat_main_t * vam = &vat_main;
668 vat_json_node_t node;
669
670 vat_json_init_object(&node);
671 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
672 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
673
674 vat_json_print(vam->ofp, &node);
675 vat_json_free(&node);
676
677 vam->retval = ntohl(mp->retval);
678 vam->result_ready = 1;
679}
680
Hongjun Ni11bfc2f2016-07-22 18:19:19 +0800681static void vl_api_create_subif_reply_t_handler
Ed Warnickecb9cada2015-12-08 15:45:58 -0700682(vl_api_create_subif_reply_t * mp)
683{
684 vat_main_t * vam = &vat_main;
685 i32 retval = ntohl(mp->retval);
686
687 vam->retval = retval;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700688 vam->regenerate_interface_table = 1;
Keith Burns (alagalah)802255c2016-06-13 16:56:04 -0700689 vam->sw_if_index = ntohl (mp->sw_if_index);
690 vam->result_ready = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700691}
692
693static void vl_api_create_subif_reply_t_handler_json
694(vl_api_create_subif_reply_t * mp)
695{
696 vat_main_t * vam = &vat_main;
697 vat_json_node_t node;
698
699 vat_json_init_object(&node);
700 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
701 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
702
703 vat_json_print(vam->ofp, &node);
704 vat_json_free(&node);
705
706 vam->retval = ntohl(mp->retval);
707 vam->result_ready = 1;
708}
709
Hongjun Ni11bfc2f2016-07-22 18:19:19 +0800710static void vl_api_interface_name_renumber_reply_t_handler
Ed Warnickecb9cada2015-12-08 15:45:58 -0700711(vl_api_interface_name_renumber_reply_t * mp)
712{
713 vat_main_t * vam = &vat_main;
714 i32 retval = ntohl(mp->retval);
715
716 vam->retval = retval;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700717 vam->regenerate_interface_table = 1;
Keith Burns (alagalah)802255c2016-06-13 16:56:04 -0700718 vam->result_ready = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700719}
720
721static void vl_api_interface_name_renumber_reply_t_handler_json
722(vl_api_interface_name_renumber_reply_t * mp)
723{
724 vat_main_t * vam = &vat_main;
725 vat_json_node_t node;
726
727 vat_json_init_object(&node);
728 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
729
730 vat_json_print(vam->ofp, &node);
731 vat_json_free(&node);
732
733 vam->retval = ntohl(mp->retval);
734 vam->result_ready = 1;
735}
736
Hongjun Ni11bfc2f2016-07-22 18:19:19 +0800737/*
Ed Warnickecb9cada2015-12-08 15:45:58 -0700738 * Special-case: build the interface table, maintain
739 * the next loopback sw_if_index vbl.
740 */
741static void vl_api_sw_interface_details_t_handler
742(vl_api_sw_interface_details_t * mp)
743{
744 vat_main_t * vam = &vat_main;
745 u8 * s = format (0, "%s%c", mp->interface_name, 0);
746
Hongjun Ni11bfc2f2016-07-22 18:19:19 +0800747 hash_set_mem (vam->sw_if_index_by_interface_name, s,
Ed Warnickecb9cada2015-12-08 15:45:58 -0700748 ntohl(mp->sw_if_index));
749
750 /* In sub interface case, fill the sub interface table entry */
751 if (mp->sw_if_index != mp->sup_sw_if_index) {
752 sw_interface_subif_t * sub = NULL;
753
754 vec_add2(vam->sw_if_subif_table, sub, 1);
755
756 vec_validate(sub->interface_name, strlen((char *)s) + 1);
757 strncpy((char *)sub->interface_name, (char *)s,
758 vec_len(sub->interface_name));
759 sub->sw_if_index = ntohl(mp->sw_if_index);
760 sub->sub_id = ntohl(mp->sub_id);
761
762 sub->sub_dot1ad = mp->sub_dot1ad;
763 sub->sub_number_of_tags = mp->sub_number_of_tags;
764 sub->sub_outer_vlan_id = ntohs(mp->sub_outer_vlan_id);
765 sub->sub_inner_vlan_id = ntohs(mp->sub_inner_vlan_id);
766 sub->sub_exact_match = mp->sub_exact_match;
767 sub->sub_default = mp->sub_default;
768 sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
769 sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
770
771 /* vlan tag rewrite */
772 sub->vtr_op = ntohl(mp->vtr_op);
773 sub->vtr_push_dot1q = ntohl(mp->vtr_push_dot1q);
774 sub->vtr_tag1 = ntohl(mp->vtr_tag1);
775 sub->vtr_tag2 = ntohl(mp->vtr_tag2);
776 }
777}
778
779static void vl_api_sw_interface_details_t_handler_json
780(vl_api_sw_interface_details_t * mp)
781{
782 vat_main_t * vam = &vat_main;
783 vat_json_node_t *node = NULL;
784
785 if (VAT_JSON_ARRAY != vam->json_tree.type) {
786 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
787 vat_json_init_array(&vam->json_tree);
788 }
789 node = vat_json_array_add(&vam->json_tree);
790
791 vat_json_init_object(node);
792 vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
793 vat_json_object_add_uint(node, "sup_sw_if_index", ntohl(mp->sup_sw_if_index));
794 vat_json_object_add_uint(node, "l2_address_length", ntohl(mp->l2_address_length));
795 vat_json_object_add_bytes(node, "l2_address", mp->l2_address, sizeof(mp->l2_address));
796 vat_json_object_add_string_copy(node, "interface_name", mp->interface_name);
797 vat_json_object_add_uint(node, "admin_up_down", mp->admin_up_down);
798 vat_json_object_add_uint(node, "link_up_down", mp->link_up_down);
799 vat_json_object_add_uint(node, "link_duplex", mp->link_duplex);
800 vat_json_object_add_uint(node, "link_speed", mp->link_speed);
Pavel84e4ffe2016-02-17 15:10:04 +0100801 vat_json_object_add_uint(node, "mtu", ntohs(mp->link_mtu));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700802 vat_json_object_add_uint(node, "sub_id", ntohl(mp->sub_id));
803 vat_json_object_add_uint(node, "sub_dot1ad", mp->sub_dot1ad);
804 vat_json_object_add_uint(node, "sub_number_of_tags", mp->sub_number_of_tags);
805 vat_json_object_add_uint(node, "sub_outer_vlan_id", ntohs(mp->sub_outer_vlan_id));
806 vat_json_object_add_uint(node, "sub_inner_vlan_id", ntohs(mp->sub_inner_vlan_id));
807 vat_json_object_add_uint(node, "sub_exact_match", mp->sub_exact_match);
808 vat_json_object_add_uint(node, "sub_default", mp->sub_default);
809 vat_json_object_add_uint(node, "sub_outer_vlan_id_any", mp->sub_outer_vlan_id_any);
810 vat_json_object_add_uint(node, "sub_inner_vlan_id_any", mp->sub_inner_vlan_id_any);
811 vat_json_object_add_uint(node, "vtr_op", ntohl(mp->vtr_op));
812 vat_json_object_add_uint(node, "vtr_push_dot1q", ntohl(mp->vtr_push_dot1q));
813 vat_json_object_add_uint(node, "vtr_tag1", ntohl(mp->vtr_tag1));
814 vat_json_object_add_uint(node, "vtr_tag2", ntohl(mp->vtr_tag2));
815}
816
817static void vl_api_sw_interface_set_flags_t_handler
818(vl_api_sw_interface_set_flags_t * mp)
819{
820 vat_main_t * vam = &vat_main;
821 if (vam->interface_event_display)
822 errmsg ("interface flags: sw_if_index %d %s %s\n",
823 ntohl(mp->sw_if_index),
824 mp->admin_up_down ? "admin-up" : "admin-down",
825 mp->link_up_down ? "link-up" : "link-down");
826}
827
828static void vl_api_sw_interface_set_flags_t_handler_json
829(vl_api_sw_interface_set_flags_t * mp)
830{
831 /* JSON output not supported */
832}
833
Pavel Kotucek00bbf272016-03-03 13:27:11 +0100834static void vl_api_cli_reply_t_handler
Ed Warnickecb9cada2015-12-08 15:45:58 -0700835(vl_api_cli_reply_t * mp)
836{
837 vat_main_t * vam = &vat_main;
838 i32 retval = ntohl(mp->retval);
839
840 vam->retval = retval;
841 vam->shmem_result = (u8 *) mp->reply_in_shmem;
842 vam->result_ready = 1;
843}
844
845static void vl_api_cli_reply_t_handler_json
846(vl_api_cli_reply_t * mp)
847{
848 vat_main_t * vam = &vat_main;
849 vat_json_node_t node;
Dave Barachb44e9bc2016-02-19 09:06:23 -0500850 api_main_t * am = &api_main;
851 void * oldheap;
852 u8 * reply;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700853
854 vat_json_init_object(&node);
855 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
Hongjun Ni11bfc2f2016-07-22 18:19:19 +0800856 vat_json_object_add_uint(&node, "reply_in_shmem",
Dave Barachb44e9bc2016-02-19 09:06:23 -0500857 ntohl(mp->reply_in_shmem));
858 /* Toss the shared-memory original... */
859 pthread_mutex_lock (&am->vlib_rp->mutex);
860 oldheap = svm_push_data_heap (am->vlib_rp);
861
862 reply = (u8 *)(mp->reply_in_shmem);
863 vec_free (reply);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +0800864
Dave Barachb44e9bc2016-02-19 09:06:23 -0500865 svm_pop_heap (oldheap);
866 pthread_mutex_unlock (&am->vlib_rp->mutex);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700867
868 vat_json_print(vam->ofp, &node);
869 vat_json_free(&node);
870
871 vam->retval = ntohl(mp->retval);
872 vam->result_ready = 1;
873}
874
875static void vl_api_classify_add_del_table_reply_t_handler
876(vl_api_classify_add_del_table_reply_t * mp)
877{
878 vat_main_t * vam = &vat_main;
879 i32 retval = ntohl(mp->retval);
880 if (vam->async_mode) {
881 vam->async_errors += (retval < 0);
882 } else {
883 vam->retval = retval;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +0800884 if (retval == 0 &&
Ed Warnickecb9cada2015-12-08 15:45:58 -0700885 ((mp->new_table_index != 0xFFFFFFFF) ||
886 (mp->skip_n_vectors != 0xFFFFFFFF) ||
887 (mp->match_n_vectors != 0xFFFFFFFF)))
Hongjun Ni11bfc2f2016-07-22 18:19:19 +0800888 /*
Ed Warnickecb9cada2015-12-08 15:45:58 -0700889 * Note: this is just barely thread-safe, depends on
890 * the main thread spinning waiting for an answer...
891 */
892 errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d\n",
893 ntohl(mp->new_table_index),
894 ntohl(mp->skip_n_vectors), ntohl(mp->match_n_vectors));
Keith Burns (alagalah)802255c2016-06-13 16:56:04 -0700895 vam->result_ready = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700896 }
897}
898
899static void vl_api_classify_add_del_table_reply_t_handler_json
900(vl_api_classify_add_del_table_reply_t * mp)
901{
902 vat_main_t * vam = &vat_main;
903 vat_json_node_t node;
904
905 vat_json_init_object(&node);
906 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
907 vat_json_object_add_uint(&node, "new_table_index", ntohl(mp->new_table_index));
908 vat_json_object_add_uint(&node, "skip_n_vectors", ntohl(mp->skip_n_vectors));
909 vat_json_object_add_uint(&node, "match_n_vectors", ntohl(mp->match_n_vectors));
910
911 vat_json_print(vam->ofp, &node);
912 vat_json_free(&node);
913
914 vam->retval = ntohl(mp->retval);
915 vam->result_ready = 1;
916}
917
918static void vl_api_get_node_index_reply_t_handler
919(vl_api_get_node_index_reply_t * mp)
920{
921 vat_main_t * vam = &vat_main;
922 i32 retval = ntohl(mp->retval);
923 if (vam->async_mode) {
924 vam->async_errors += (retval < 0);
925 } else {
926 vam->retval = retval;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700927 if (retval == 0)
928 errmsg ("node index %d\n", ntohl(mp->node_index));
Keith Burns (alagalah)802255c2016-06-13 16:56:04 -0700929 vam->result_ready = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700930 }
931}
932
933static void vl_api_get_node_index_reply_t_handler_json
934(vl_api_get_node_index_reply_t * mp)
935{
936 vat_main_t * vam = &vat_main;
937 vat_json_node_t node;
938
939 vat_json_init_object(&node);
940 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
941 vat_json_object_add_uint(&node, "node_index", ntohl(mp->node_index));
942
943 vat_json_print(vam->ofp, &node);
944 vat_json_free(&node);
945
946 vam->retval = ntohl(mp->retval);
947 vam->result_ready = 1;
948}
949
Keith Burns (alagalah)c61080e2016-07-19 14:47:43 -0700950static void vl_api_get_next_index_reply_t_handler
951(vl_api_get_next_index_reply_t * mp)
952{
953 vat_main_t * vam = &vat_main;
954 i32 retval = ntohl(mp->retval);
955 if (vam->async_mode) {
956 vam->async_errors += (retval < 0);
957 } else {
958 vam->retval = retval;
959 if (retval == 0)
960 errmsg ("next node index %d\n", ntohl(mp->next_index));
961 vam->result_ready = 1;
962 }
963}
964
965static void vl_api_get_next_index_reply_t_handler_json
966(vl_api_get_next_index_reply_t * mp)
967{
968 vat_main_t * vam = &vat_main;
969 vat_json_node_t node;
970
971 vat_json_init_object(&node);
972 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
973 vat_json_object_add_uint(&node, "next_index", ntohl(mp->next_index));
974
975 vat_json_print(vam->ofp, &node);
976 vat_json_free(&node);
977
978 vam->retval = ntohl(mp->retval);
979 vam->result_ready = 1;
980}
981
Ed Warnickecb9cada2015-12-08 15:45:58 -0700982static void vl_api_add_node_next_reply_t_handler
983(vl_api_add_node_next_reply_t * mp)
984{
985 vat_main_t * vam = &vat_main;
986 i32 retval = ntohl(mp->retval);
987 if (vam->async_mode) {
988 vam->async_errors += (retval < 0);
989 } else {
990 vam->retval = retval;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700991 if (retval == 0)
992 errmsg ("next index %d\n", ntohl(mp->next_index));
Keith Burns (alagalah)802255c2016-06-13 16:56:04 -0700993 vam->result_ready = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700994 }
995}
996
997static void vl_api_add_node_next_reply_t_handler_json
998(vl_api_add_node_next_reply_t * mp)
999{
1000 vat_main_t * vam = &vat_main;
1001 vat_json_node_t node;
1002
1003 vat_json_init_object(&node);
1004 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1005 vat_json_object_add_uint(&node, "next_index", ntohl(mp->next_index));
1006
1007 vat_json_print(vam->ofp, &node);
1008 vat_json_free(&node);
1009
1010 vam->retval = ntohl(mp->retval);
1011 vam->result_ready = 1;
1012}
1013
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08001014static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler
Ed Warnickecb9cada2015-12-08 15:45:58 -07001015(vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
1016{
1017 vat_main_t * vam = &vat_main;
1018 i32 retval = ntohl(mp->retval);
1019 u32 sw_if_index = ntohl(mp->tunnel_sw_if_index);
1020
1021 if (retval >= 0 && sw_if_index != (u32)~0) {
1022 errmsg ("tunnel_sw_if_index %d\n", sw_if_index);
1023 }
1024 vam->retval = retval;
1025 vam->result_ready = 1;
1026}
1027
1028static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler_json
1029(vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
1030{
1031 vat_main_t * vam = &vat_main;
1032 vat_json_node_t node;
1033
1034 vat_json_init_object(&node);
1035 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1036 vat_json_object_add_uint(&node, "tunnel_sw_if_index", ntohl(mp->tunnel_sw_if_index));
1037
1038 vat_json_print(vam->ofp, &node);
1039 vat_json_free(&node);
1040
1041 vam->retval = ntohl(mp->retval);
1042 vam->result_ready = 1;
1043}
1044
Ed Warnickecb9cada2015-12-08 15:45:58 -07001045
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08001046static void vl_api_show_version_reply_t_handler
Ed Warnickecb9cada2015-12-08 15:45:58 -07001047(vl_api_show_version_reply_t * mp)
1048{
1049 vat_main_t * vam = &vat_main;
1050 i32 retval = ntohl(mp->retval);
1051
1052 if (retval >= 0) {
1053 errmsg (" program: %s\n", mp->program);
Damjan Mariona0d4a1a2015-12-12 14:40:59 +01001054 errmsg (" version: %s\n", mp->version);
Ed Warnickecb9cada2015-12-08 15:45:58 -07001055 errmsg (" build date: %s\n", mp->build_date);
1056 errmsg ("build directory: %s\n", mp->build_directory);
1057 }
1058 vam->retval = retval;
1059 vam->result_ready = 1;
1060}
1061
1062static void vl_api_show_version_reply_t_handler_json
1063(vl_api_show_version_reply_t * mp)
1064{
1065 vat_main_t * vam = &vat_main;
1066 vat_json_node_t node;
1067
1068 vat_json_init_object(&node);
1069 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1070 vat_json_object_add_string_copy(&node, "program", mp->program);
Damjan Mariona0d4a1a2015-12-12 14:40:59 +01001071 vat_json_object_add_string_copy(&node, "version", mp->version);
Ed Warnickecb9cada2015-12-08 15:45:58 -07001072 vat_json_object_add_string_copy(&node, "build_date", mp->build_date);
1073 vat_json_object_add_string_copy(&node, "build_directory", mp->build_directory);
1074
1075 vat_json_print(vam->ofp, &node);
1076 vat_json_free(&node);
1077
1078 vam->retval = ntohl(mp->retval);
1079 vam->result_ready = 1;
1080}
1081
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08001082static void vl_api_ip4_arp_event_t_handler
Ed Warnickecb9cada2015-12-08 15:45:58 -07001083(vl_api_ip4_arp_event_t * mp)
1084{
1085 vat_main_t * vam = &vat_main;
1086 errmsg ("arp event: address %U new mac %U sw_if_index %d\n",
1087 format_ip4_address, &mp->address,
1088 format_ethernet_address, mp->new_mac, mp->sw_if_index);
1089}
1090
1091static void vl_api_ip4_arp_event_t_handler_json
1092(vl_api_ip4_arp_event_t * mp)
1093{
1094 /* JSON output not supported */
1095}
1096
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08001097/*
Ed Warnickecb9cada2015-12-08 15:45:58 -07001098 * Special-case: build the bridge domain table, maintain
1099 * the next bd id vbl.
1100 */
1101static void vl_api_bridge_domain_details_t_handler
1102(vl_api_bridge_domain_details_t * mp)
1103{
1104 vat_main_t * vam = &vat_main;
1105 u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1106
1107 fformat (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s\n",
1108 " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1109
1110 fformat (vam->ofp, "%3d %3d %3d %3d %3d %3d\n",
1111 ntohl (mp->bd_id), mp->learn, mp->forward,
1112 mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1113
1114 if (n_sw_ifs)
1115 fformat (vam->ofp, "\n\n%s %s %s\n", "sw_if_index", "SHG",
1116 "Interface Name");
1117}
1118
1119static void vl_api_bridge_domain_details_t_handler_json
1120(vl_api_bridge_domain_details_t * mp)
1121{
1122 vat_main_t * vam = &vat_main;
1123 vat_json_node_t *node, *array = NULL;
1124
1125 if (VAT_JSON_ARRAY != vam->json_tree.type) {
1126 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
1127 vat_json_init_array(&vam->json_tree);
1128 }
1129 node = vat_json_array_add(&vam->json_tree);
1130
1131 vat_json_init_object(node);
1132 vat_json_object_add_uint(node, "bd_id", ntohl(mp->bd_id));
1133 vat_json_object_add_uint(node, "flood", mp->flood);
1134 vat_json_object_add_uint(node, "forward", mp->forward);
1135 vat_json_object_add_uint(node, "learn", mp->learn);
1136 vat_json_object_add_uint(node, "bvi_sw_if_index", ntohl(mp->bvi_sw_if_index));
1137 vat_json_object_add_uint(node, "n_sw_ifs", ntohl(mp->n_sw_ifs));
1138 array = vat_json_object_add(node, "sw_if");
1139 vat_json_init_array(array);
1140}
1141
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08001142/*
Ed Warnickecb9cada2015-12-08 15:45:58 -07001143 * Special-case: build the bridge domain sw if table.
1144 */
1145static void vl_api_bridge_domain_sw_if_details_t_handler
1146(vl_api_bridge_domain_sw_if_details_t * mp)
1147{
1148 vat_main_t * vam = &vat_main;
1149 hash_pair_t * p;
1150 u8 * sw_if_name = 0;
1151 u32 sw_if_index;
1152
1153 sw_if_index = ntohl (mp->sw_if_index);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08001154 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
Ed Warnickecb9cada2015-12-08 15:45:58 -07001155 ({
1156 if ((u32) p->value[0] == sw_if_index) {
1157 sw_if_name = (u8 *)(p->key);
1158 break;
1159 }
1160 }));
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08001161
1162 fformat (vam->ofp, "%7d %3d %s", sw_if_index,
1163 mp->shg, sw_if_name ? (char *)sw_if_name :
Ed Warnickecb9cada2015-12-08 15:45:58 -07001164 "sw_if_index not found!");
1165}
1166
1167static void vl_api_bridge_domain_sw_if_details_t_handler_json
1168(vl_api_bridge_domain_sw_if_details_t * mp)
1169{
1170 vat_main_t * vam = &vat_main;
1171 vat_json_node_t *node = NULL;
1172 uword last_index = 0;
1173
1174 ASSERT(VAT_JSON_ARRAY == vam->json_tree.type);
1175 ASSERT(vec_len(vam->json_tree.array) >= 1);
1176 last_index = vec_len(vam->json_tree.array) - 1;
1177 node = &vam->json_tree.array[last_index];
1178 node = vat_json_object_get_element(node, "sw_if");
1179 ASSERT(NULL != node);
1180 node = vat_json_array_add(node);
1181
1182 vat_json_init_object(node);
1183 vat_json_object_add_uint(node, "bd_id", ntohl(mp->bd_id));
1184 vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
1185 vat_json_object_add_uint(node, "shg", mp->shg);
1186}
1187
1188static void vl_api_control_ping_reply_t_handler
1189(vl_api_control_ping_reply_t * mp)
1190{
1191 vat_main_t * vam = &vat_main;
1192 i32 retval = ntohl(mp->retval);
1193 if (vam->async_mode) {
1194 vam->async_errors += (retval < 0);
1195 } else {
1196 vam->retval = retval;
1197 vam->result_ready = 1;
1198 }
1199}
1200
1201static void vl_api_control_ping_reply_t_handler_json
1202(vl_api_control_ping_reply_t * mp)
1203{
1204 vat_main_t * vam = &vat_main;
1205 i32 retval = ntohl(mp->retval);
1206
1207 if (VAT_JSON_NONE != vam->json_tree.type) {
1208 vat_json_print(vam->ofp, &vam->json_tree);
1209 vat_json_free(&vam->json_tree);
1210 vam->json_tree.type = VAT_JSON_NONE;
1211 } else {
1212 /* just print [] */
1213 vat_json_init_array(&vam->json_tree);
1214 vat_json_print(vam->ofp, &vam->json_tree);
1215 vam->json_tree.type = VAT_JSON_NONE;
1216 }
1217
1218 vam->retval = retval;
1219 vam->result_ready = 1;
1220}
1221
Andrej Kozemcakd9831182016-06-20 08:47:57 +02001222static void vl_api_noprint_control_ping_reply_t_handler
1223(vl_api_noprint_control_ping_reply_t * mp)
1224{
1225 vat_main_t * vam = &vat_main;
1226 i32 retval = ntohl(mp->retval);
1227 if (vam->async_mode) {
1228 vam->async_errors += (retval < 0);
1229 } else {
1230 vam->retval = retval;
1231 vam->result_ready = 1;
1232 }
1233}
1234
1235static void vl_api_noprint_control_ping_reply_t_handler_json
1236(vl_api_noprint_control_ping_reply_t * mp)
1237{
1238 vat_main_t * vam = &vat_main;
1239 i32 retval = ntohl(mp->retval);
1240
1241 if (vam->noprint_msg) {
1242 vam->retval = retval;
1243 vam->result_ready = 1;
1244 return;
1245 }
1246
1247 if (VAT_JSON_NONE != vam->json_tree.type) {
1248 vat_json_print(vam->ofp, &vam->json_tree);
1249 vat_json_free(&vam->json_tree);
1250 vam->json_tree.type = VAT_JSON_NONE;
1251 } else {
1252 /* just print [] */
1253 vat_json_init_array(&vam->json_tree);
1254 vat_json_print(vam->ofp, &vam->json_tree);
1255 vam->json_tree.type = VAT_JSON_NONE;
1256 }
1257
1258 vam->retval = retval;
1259 vam->result_ready = 1;
1260}
1261
Ed Warnickecb9cada2015-12-08 15:45:58 -07001262static void vl_api_l2_flags_reply_t_handler
1263(vl_api_l2_flags_reply_t * mp)
1264{
1265 vat_main_t * vam = &vat_main;
1266 i32 retval = ntohl(mp->retval);
1267 if (vam->async_mode) {
1268 vam->async_errors += (retval < 0);
1269 } else {
1270 vam->retval = retval;
1271 vam->result_ready = 1;
1272 }
1273}
1274
1275static void vl_api_l2_flags_reply_t_handler_json
1276(vl_api_l2_flags_reply_t * mp)
1277{
1278 vat_main_t * vam = &vat_main;
1279 vat_json_node_t node;
1280
1281 vat_json_init_object(&node);
1282 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1283 vat_json_object_add_uint(&node, "resulting_feature_bitmap", ntohl(mp->resulting_feature_bitmap));
1284
1285 vat_json_print(vam->ofp, &node);
1286 vat_json_free(&node);
1287
1288 vam->retval = ntohl(mp->retval);
1289 vam->result_ready = 1;
1290}
1291
1292static void vl_api_bridge_flags_reply_t_handler
1293(vl_api_bridge_flags_reply_t * mp)
1294{
1295 vat_main_t * vam = &vat_main;
1296 i32 retval = ntohl(mp->retval);
1297 if (vam->async_mode) {
1298 vam->async_errors += (retval < 0);
1299 } else {
1300 vam->retval = retval;
1301 vam->result_ready = 1;
1302 }
1303}
1304
1305static void vl_api_bridge_flags_reply_t_handler_json
1306(vl_api_bridge_flags_reply_t * mp)
1307{
1308 vat_main_t * vam = &vat_main;
1309 vat_json_node_t node;
1310
1311 vat_json_init_object(&node);
1312 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1313 vat_json_object_add_uint(&node, "resulting_feature_bitmap", ntohl(mp->resulting_feature_bitmap));
1314
1315 vat_json_print(vam->ofp, &node);
1316 vat_json_free(&node);
1317
1318 vam->retval = ntohl(mp->retval);
1319 vam->result_ready = 1;
1320}
1321
1322static void vl_api_tap_connect_reply_t_handler
1323(vl_api_tap_connect_reply_t * mp)
1324{
1325 vat_main_t * vam = &vat_main;
1326 i32 retval = ntohl(mp->retval);
1327 if (vam->async_mode) {
1328 vam->async_errors += (retval < 0);
1329 } else {
1330 vam->retval = retval;
Keith Burns (alagalah)802255c2016-06-13 16:56:04 -07001331 vam->sw_if_index = ntohl (mp->sw_if_index);
1332 vam->result_ready = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -07001333 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08001334
Ed Warnickecb9cada2015-12-08 15:45:58 -07001335}
1336
1337static void vl_api_tap_connect_reply_t_handler_json
1338(vl_api_tap_connect_reply_t * mp)
1339{
1340 vat_main_t * vam = &vat_main;
1341 vat_json_node_t node;
1342
1343 vat_json_init_object(&node);
1344 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1345 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
1346
1347 vat_json_print(vam->ofp, &node);
1348 vat_json_free(&node);
1349
1350 vam->retval = ntohl(mp->retval);
1351 vam->result_ready = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08001352
Ed Warnickecb9cada2015-12-08 15:45:58 -07001353}
1354
1355static void vl_api_tap_modify_reply_t_handler
1356(vl_api_tap_modify_reply_t * mp)
1357{
1358 vat_main_t * vam = &vat_main;
1359 i32 retval = ntohl(mp->retval);
1360 if (vam->async_mode) {
1361 vam->async_errors += (retval < 0);
1362 } else {
1363 vam->retval = retval;
Keith Burns (alagalah)802255c2016-06-13 16:56:04 -07001364 vam->sw_if_index = ntohl (mp->sw_if_index);
Ed Warnickecb9cada2015-12-08 15:45:58 -07001365 vam->result_ready = 1;
1366 }
1367}
1368
1369static void vl_api_tap_modify_reply_t_handler_json
1370(vl_api_tap_modify_reply_t * mp)
1371{
1372 vat_main_t * vam = &vat_main;
1373 vat_json_node_t node;
1374
1375 vat_json_init_object(&node);
1376 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1377 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
1378
1379 vat_json_print(vam->ofp, &node);
1380 vat_json_free(&node);
1381
1382 vam->retval = ntohl(mp->retval);
1383 vam->result_ready = 1;
1384}
1385
1386static void vl_api_tap_delete_reply_t_handler
1387(vl_api_tap_delete_reply_t * mp)
1388{
1389 vat_main_t * vam = &vat_main;
1390 i32 retval = ntohl(mp->retval);
1391 if (vam->async_mode) {
1392 vam->async_errors += (retval < 0);
1393 } else {
1394 vam->retval = retval;
1395 vam->result_ready = 1;
1396 }
1397}
1398
1399static void vl_api_tap_delete_reply_t_handler_json
1400(vl_api_tap_delete_reply_t * mp)
1401{
1402 vat_main_t * vam = &vat_main;
1403 vat_json_node_t node;
1404
1405 vat_json_init_object(&node);
1406 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1407
1408 vat_json_print(vam->ofp, &node);
1409 vat_json_free(&node);
1410
1411 vam->retval = ntohl(mp->retval);
1412 vam->result_ready = 1;
1413}
1414
1415static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler
1416(vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1417{
1418 vat_main_t * vam = &vat_main;
1419 i32 retval = ntohl(mp->retval);
1420 if (vam->async_mode) {
1421 vam->async_errors += (retval < 0);
1422 } else {
1423 vam->retval = retval;
1424 vam->result_ready = 1;
1425 }
1426}
1427
1428static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler_json
1429(vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1430{
1431 vat_main_t * vam = &vat_main;
1432 vat_json_node_t node;
1433
1434 vat_json_init_object(&node);
1435 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1436 vat_json_object_add_uint(&node, "tunnel_sw_if_index", ntohl(mp->tunnel_sw_if_index));
1437
1438 vat_json_print(vam->ofp, &node);
1439 vat_json_free(&node);
1440
1441 vam->retval = ntohl(mp->retval);
1442 vam->result_ready = 1;
1443}
1444
1445static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1446(vl_api_l2tpv3_create_tunnel_reply_t * mp)
1447{
1448 vat_main_t * vam = &vat_main;
1449 i32 retval = ntohl(mp->retval);
1450 if (vam->async_mode) {
1451 vam->async_errors += (retval < 0);
1452 } else {
1453 vam->retval = retval;
Keith Burns (alagalah)802255c2016-06-13 16:56:04 -07001454 vam->sw_if_index = ntohl (mp->sw_if_index);
Ed Warnickecb9cada2015-12-08 15:45:58 -07001455 vam->result_ready = 1;
1456 }
1457}
1458
1459static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1460(vl_api_l2tpv3_create_tunnel_reply_t * mp)
1461{
1462 vat_main_t * vam = &vat_main;
1463 vat_json_node_t node;
1464
1465 vat_json_init_object(&node);
1466 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1467 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
1468
1469 vat_json_print(vam->ofp, &node);
1470 vat_json_free(&node);
1471
1472 vam->retval = ntohl(mp->retval);
1473 vam->result_ready = 1;
1474}
1475
1476static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1477(vl_api_vxlan_add_del_tunnel_reply_t * mp)
1478{
1479 vat_main_t * vam = &vat_main;
1480 i32 retval = ntohl(mp->retval);
1481 if (vam->async_mode) {
1482 vam->async_errors += (retval < 0);
1483 } else {
1484 vam->retval = retval;
Keith Burns (alagalah)802255c2016-06-13 16:56:04 -07001485 vam->sw_if_index = ntohl (mp->sw_if_index);
Ed Warnickecb9cada2015-12-08 15:45:58 -07001486 vam->result_ready = 1;
1487 }
1488}
1489
1490static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1491(vl_api_vxlan_add_del_tunnel_reply_t * mp)
1492{
1493 vat_main_t * vam = &vat_main;
1494 vat_json_node_t node;
1495
1496 vat_json_init_object(&node);
1497 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1498 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
1499
1500 vat_json_print(vam->ofp, &node);
1501 vat_json_free(&node);
1502
1503 vam->retval = ntohl(mp->retval);
1504 vam->result_ready = 1;
1505}
1506
Chris Luke27fe48f2016-04-28 13:44:38 -04001507static void vl_api_gre_add_del_tunnel_reply_t_handler
1508(vl_api_gre_add_del_tunnel_reply_t * mp)
1509{
1510 vat_main_t * vam = &vat_main;
1511 i32 retval = ntohl(mp->retval);
1512 if (vam->async_mode) {
1513 vam->async_errors += (retval < 0);
1514 } else {
1515 vam->retval = retval;
Keith Burns (alagalah)802255c2016-06-13 16:56:04 -07001516 vam->sw_if_index = ntohl (mp->sw_if_index);
Chris Luke27fe48f2016-04-28 13:44:38 -04001517 vam->result_ready = 1;
1518 }
1519}
1520
1521static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1522(vl_api_gre_add_del_tunnel_reply_t * mp)
1523{
1524 vat_main_t * vam = &vat_main;
1525 vat_json_node_t node;
1526
1527 vat_json_init_object(&node);
1528 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1529 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
1530
1531 vat_json_print(vam->ofp, &node);
1532 vat_json_free(&node);
1533
1534 vam->retval = ntohl(mp->retval);
1535 vam->result_ready = 1;
1536}
1537
Ed Warnickecb9cada2015-12-08 15:45:58 -07001538static void vl_api_create_vhost_user_if_reply_t_handler
1539(vl_api_create_vhost_user_if_reply_t * mp)
1540{
1541 vat_main_t * vam = &vat_main;
1542 i32 retval = ntohl(mp->retval);
1543 if (vam->async_mode) {
1544 vam->async_errors += (retval < 0);
1545 } else {
1546 vam->retval = retval;
Keith Burns (alagalah)802255c2016-06-13 16:56:04 -07001547 vam->sw_if_index = ntohl (mp->sw_if_index);
Ed Warnickecb9cada2015-12-08 15:45:58 -07001548 vam->result_ready = 1;
1549 }
1550}
1551
1552static void vl_api_create_vhost_user_if_reply_t_handler_json
1553(vl_api_create_vhost_user_if_reply_t * mp)
1554{
1555 vat_main_t * vam = &vat_main;
1556 vat_json_node_t node;
1557
1558 vat_json_init_object(&node);
1559 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1560 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
1561
1562 vat_json_print(vam->ofp, &node);
1563 vat_json_free(&node);
1564
1565 vam->retval = ntohl(mp->retval);
1566 vam->result_ready = 1;
1567}
1568
1569static void vl_api_ip_address_details_t_handler
1570(vl_api_ip_address_details_t * mp)
1571{
1572 vat_main_t * vam = &vat_main;
1573 static ip_address_details_t empty_ip_address_details = {{0}};
1574 ip_address_details_t * address = NULL;
1575 ip_details_t * current_ip_details = NULL;
1576 ip_details_t * details = NULL;
1577
1578 details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1579
1580 if (!details || vam->current_sw_if_index >= vec_len(details)
1581 || !details[vam->current_sw_if_index].present) {
1582 errmsg ("ip address details arrived but not stored\n");
1583 errmsg ("ip_dump should be called first\n");
1584 return;
1585 }
1586
1587 current_ip_details = vec_elt_at_index(details,
1588 vam->current_sw_if_index);
1589
1590#define addresses (current_ip_details->addr)
1591
1592 vec_validate_init_empty(addresses, vec_len(addresses),
1593 empty_ip_address_details);
1594
1595 address = vec_elt_at_index(addresses, vec_len(addresses) - 1);
1596
Damjan Marionf1213b82016-03-13 02:22:06 +01001597 clib_memcpy(&address->ip, &mp->ip, sizeof(address->ip));
Ed Warnickecb9cada2015-12-08 15:45:58 -07001598 address->prefix_length = mp->prefix_length;
1599#undef addresses
1600}
1601
1602static void vl_api_ip_address_details_t_handler_json
1603(vl_api_ip_address_details_t * mp)
1604{
1605 vat_main_t * vam = &vat_main;
1606 vat_json_node_t *node = NULL;
1607 struct in6_addr ip6;
1608 struct in_addr ip4;
1609
1610 if (VAT_JSON_ARRAY != vam->json_tree.type) {
1611 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
1612 vat_json_init_array(&vam->json_tree);
1613 }
1614 node = vat_json_array_add(&vam->json_tree);
1615
1616 vat_json_init_object(node);
1617 if (vam->is_ipv6) {
Damjan Marionf1213b82016-03-13 02:22:06 +01001618 clib_memcpy(&ip6, mp->ip, sizeof(ip6));
Ed Warnickecb9cada2015-12-08 15:45:58 -07001619 vat_json_object_add_ip6(node, "ip", ip6);
1620 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01001621 clib_memcpy(&ip4, mp->ip, sizeof(ip4));
Ed Warnickecb9cada2015-12-08 15:45:58 -07001622 vat_json_object_add_ip4(node, "ip", ip4);
1623 }
1624 vat_json_object_add_uint(node, "prefix_length", mp->prefix_length);
1625}
1626
1627static void vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1628{
1629 vat_main_t * vam = &vat_main;
1630 static ip_details_t empty_ip_details = {0};
1631 ip_details_t * ip = NULL;
1632 u32 sw_if_index = ~0;
1633
1634 sw_if_index = ntohl(mp->sw_if_index);
1635
1636 vec_validate_init_empty(vam->ip_details_by_sw_if_index[vam->is_ipv6],
1637 sw_if_index, empty_ip_details);
1638
1639 ip = vec_elt_at_index(vam->ip_details_by_sw_if_index[vam->is_ipv6],
1640 sw_if_index);
1641
1642 ip->present = 1;
1643}
1644
1645static void vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1646{
1647 vat_main_t * vam = &vat_main;
1648
1649 if (VAT_JSON_ARRAY != vam->json_tree.type) {
1650 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
1651 vat_json_init_array(&vam->json_tree);
1652 }
1653 vat_json_array_add_uint(&vam->json_tree, clib_net_to_host_u32(mp->sw_if_index));
1654}
1655
1656static void vl_api_map_domain_details_t_handler_json
1657(vl_api_map_domain_details_t * mp)
1658{
1659 vat_json_node_t * node = NULL;
1660 vat_main_t * vam = &vat_main;
1661 struct in6_addr ip6;
1662 struct in_addr ip4;
1663
1664 if (VAT_JSON_ARRAY != vam->json_tree.type) {
1665 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
1666 vat_json_init_array(&vam->json_tree);
1667 }
1668
1669 node = vat_json_array_add(&vam->json_tree);
1670 vat_json_init_object(node);
1671
1672 vat_json_object_add_uint(node, "domain_index", clib_net_to_host_u32(mp->domain_index));
Damjan Marionf1213b82016-03-13 02:22:06 +01001673 clib_memcpy(&ip6, mp->ip6_prefix, sizeof(ip6));
Ed Warnickecb9cada2015-12-08 15:45:58 -07001674 vat_json_object_add_ip6(node, "ip6_prefix", ip6);
Damjan Marionf1213b82016-03-13 02:22:06 +01001675 clib_memcpy(&ip4, mp->ip4_prefix, sizeof(ip4));
Ed Warnickecb9cada2015-12-08 15:45:58 -07001676 vat_json_object_add_ip4(node, "ip4_prefix", ip4);
Damjan Marionf1213b82016-03-13 02:22:06 +01001677 clib_memcpy(&ip6, mp->ip6_src, sizeof(ip6));
Ed Warnickecb9cada2015-12-08 15:45:58 -07001678 vat_json_object_add_ip6(node, "ip6_src", ip6);
1679 vat_json_object_add_int(node, "ip6_prefix_len", mp->ip6_prefix_len);
1680 vat_json_object_add_int(node, "ip4_prefix_len", mp->ip4_prefix_len);
1681 vat_json_object_add_int(node, "ip6_src_len", mp->ip6_src_len);
1682 vat_json_object_add_int(node, "ea_bits_len", mp->ea_bits_len);
1683 vat_json_object_add_int(node, "psid_offset", mp->psid_offset);
1684 vat_json_object_add_int(node, "psid_length", mp->psid_length);
1685 vat_json_object_add_uint(node, "flags", mp->flags);
1686 vat_json_object_add_uint(node, "mtu", clib_net_to_host_u16(mp->mtu));
1687 vat_json_object_add_int(node, "is_translation", mp->is_translation);
1688}
1689
1690static void vl_api_map_domain_details_t_handler
1691(vl_api_map_domain_details_t * mp)
1692{
1693 vat_main_t * vam = &vat_main;
1694
1695 if (mp->is_translation) {
1696 fformat(vam->ofp, "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u\n",
1697 format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1698 format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1699 format_ip6_address, mp->ip6_src, mp->ip6_src_len, clib_net_to_host_u32(mp->domain_index));
1700 } else {
1701 fformat(vam->ofp, "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u\n",
1702 format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1703 format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1704 format_ip6_address, mp->ip6_src, clib_net_to_host_u32(mp->domain_index));
1705 }
1706 fformat(vam->ofp, " ea-len %d psid-offset %d psid-len %d mtu %d %s\n",
1707 mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu, mp->is_translation? "map-t":"");
1708}
1709
1710static void vl_api_map_rule_details_t_handler_json
1711(vl_api_map_rule_details_t * mp)
1712{
1713 struct in6_addr ip6;
1714 vat_json_node_t * node = NULL;
1715 vat_main_t * vam = &vat_main;
1716
1717 if (VAT_JSON_ARRAY != vam->json_tree.type) {
1718 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
1719 vat_json_init_array(&vam->json_tree);
1720 }
1721
1722 node = vat_json_array_add(&vam->json_tree);
1723 vat_json_init_object(node);
1724
1725 vat_json_object_add_uint(node, "psid", clib_net_to_host_u16(mp->psid));
Damjan Marionf1213b82016-03-13 02:22:06 +01001726 clib_memcpy(&ip6, mp->ip6_dst, sizeof(ip6));
Ed Warnickecb9cada2015-12-08 15:45:58 -07001727 vat_json_object_add_ip6(node, "ip6_dst", ip6);
1728}
1729
1730static void vl_api_map_rule_details_t_handler
1731(vl_api_map_rule_details_t * mp)
1732{
1733 vat_main_t * vam = &vat_main;
1734 fformat(vam->ofp, " %d (psid) %U (ip6-dst)\n", clib_net_to_host_u16(mp->psid),
1735 format_ip6_address, mp->ip6_dst);
1736}
1737
1738static void vl_api_dhcp_compl_event_t_handler
1739(vl_api_dhcp_compl_event_t * mp)
1740{
1741 vat_main_t * vam = &vat_main;
1742 errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1743 "router_addr %U host_mac %U\n",
1744 mp->pid, mp->is_ipv6 ? "ipv6":"ipv4", mp->hostname,
1745 format_ip4_address, &mp->host_address,
1746 format_ip4_address, &mp->router_address,
1747 format_ethernet_address, mp->host_mac);
1748}
1749
1750static void vl_api_dhcp_compl_event_t_handler_json
1751(vl_api_dhcp_compl_event_t * mp)
1752{
1753 /* JSON output not supported */
1754}
1755
1756static void set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1757 u32 counter)
1758{
1759 vat_main_t * vam = &vat_main;
1760 static u64 default_counter = 0;
1761
1762 vec_validate_init_empty(vam->simple_interface_counters, vnet_counter_type, NULL);
1763 vec_validate_init_empty(vam->simple_interface_counters[vnet_counter_type],
1764 sw_if_index, default_counter);
1765 vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1766}
1767
1768static void set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1769 interface_counter_t counter)
1770{
1771 vat_main_t * vam = &vat_main;
1772 static interface_counter_t default_counter = {0, };
1773
1774 vec_validate_init_empty(vam->combined_interface_counters, vnet_counter_type, NULL);
1775 vec_validate_init_empty(vam->combined_interface_counters[vnet_counter_type],
1776 sw_if_index, default_counter);
1777 vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1778}
1779
1780static void vl_api_vnet_interface_counters_t_handler
1781(vl_api_vnet_interface_counters_t *mp)
1782{
1783 /* not supported */
1784}
1785
1786static void vl_api_vnet_interface_counters_t_handler_json
1787(vl_api_vnet_interface_counters_t *mp)
1788{
1789 interface_counter_t counter;
1790 vlib_counter_t *v;
1791 u64 *v_packets;
1792 u64 packets;
1793 u32 count;
1794 u32 first_sw_if_index;
1795 int i;
1796
1797 count = ntohl(mp->count);
1798 first_sw_if_index = ntohl(mp->first_sw_if_index);
1799
1800 if (!mp->is_combined) {
1801 v_packets = (u64*)&mp->data;
1802 for (i = 0; i < count; i++) {
1803 packets = clib_net_to_host_u64(clib_mem_unaligned(v_packets, u64));
1804 set_simple_interface_counter(mp->vnet_counter_type,
1805 first_sw_if_index + i, packets);
1806 v_packets++;
1807 }
1808 } else {
1809 v = (vlib_counter_t*)&mp->data;
1810 for (i = 0; i < count; i++) {
1811 counter.packets = clib_net_to_host_u64(
1812 clib_mem_unaligned(&v->packets, u64));
1813 counter.bytes = clib_net_to_host_u64(
1814 clib_mem_unaligned(&v->bytes, u64));
1815 set_combined_interface_counter(mp->vnet_counter_type,
1816 first_sw_if_index + i, counter);
1817 v++;
1818 }
1819 }
1820}
1821
1822static u32 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1823{
1824 vat_main_t * vam = &vat_main;
1825 u32 i;
1826
1827 for (i = 0; i < vec_len(vam->ip4_fib_counters_vrf_id_by_index); i++) {
1828 if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id) {
1829 return i;
1830 }
1831 }
1832 return ~0;
1833}
1834
1835static u32 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1836{
1837 vat_main_t * vam = &vat_main;
1838 u32 i;
1839
1840 for (i = 0; i < vec_len(vam->ip6_fib_counters_vrf_id_by_index); i++) {
1841 if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id) {
1842 return i;
1843 }
1844 }
1845 return ~0;
1846}
1847
1848static void vl_api_vnet_ip4_fib_counters_t_handler
1849(vl_api_vnet_ip4_fib_counters_t *mp)
1850{
1851 /* not supported */
1852}
1853
1854static void vl_api_vnet_ip4_fib_counters_t_handler_json
1855(vl_api_vnet_ip4_fib_counters_t *mp)
1856{
1857 vat_main_t * vam = &vat_main;
1858 vl_api_ip4_fib_counter_t *v;
1859 ip4_fib_counter_t *counter;
1860 struct in_addr ip4;
1861 u32 vrf_id;
1862 u32 vrf_index;
1863 u32 count;
1864 int i;
1865
1866 vrf_id = ntohl(mp->vrf_id);
1867 vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id(vrf_id);
1868 if (~0 == vrf_index) {
1869 vrf_index = vec_len(vam->ip4_fib_counters_vrf_id_by_index);
1870 vec_validate(vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
1871 vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
1872 vec_validate(vam->ip4_fib_counters, vrf_index);
1873 vam->ip4_fib_counters[vrf_index] = NULL;
1874 }
1875
1876 vec_free(vam->ip4_fib_counters[vrf_index]);
1877 v = (vl_api_ip4_fib_counter_t*)&mp->c;
1878 count = ntohl(mp->count);
1879 for (i = 0; i < count; i++) {
1880 vec_validate(vam->ip4_fib_counters[vrf_index], i);
1881 counter = &vam->ip4_fib_counters[vrf_index][i];
Damjan Marionf1213b82016-03-13 02:22:06 +01001882 clib_memcpy(&ip4, &v->address, sizeof(ip4));
Ed Warnickecb9cada2015-12-08 15:45:58 -07001883 counter->address = ip4;
1884 counter->address_length = v->address_length;
1885 counter->packets = clib_net_to_host_u64(v->packets);
1886 counter->bytes = clib_net_to_host_u64(v->bytes);
1887 v++;
1888 }
1889}
1890
1891static void vl_api_vnet_ip6_fib_counters_t_handler
1892(vl_api_vnet_ip6_fib_counters_t *mp)
1893{
1894 /* not supported */
1895}
1896
1897static void vl_api_vnet_ip6_fib_counters_t_handler_json
1898(vl_api_vnet_ip6_fib_counters_t *mp)
1899{
1900 vat_main_t * vam = &vat_main;
1901 vl_api_ip6_fib_counter_t *v;
1902 ip6_fib_counter_t *counter;
1903 struct in6_addr ip6;
1904 u32 vrf_id;
1905 u32 vrf_index;
1906 u32 count;
1907 int i;
1908
1909 vrf_id = ntohl(mp->vrf_id);
1910 vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id(vrf_id);
1911 if (~0 == vrf_index) {
1912 vrf_index = vec_len(vam->ip6_fib_counters_vrf_id_by_index);
1913 vec_validate(vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
1914 vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
1915 vec_validate(vam->ip6_fib_counters, vrf_index);
1916 vam->ip6_fib_counters[vrf_index] = NULL;
1917 }
1918
1919 vec_free(vam->ip6_fib_counters[vrf_index]);
1920 v = (vl_api_ip6_fib_counter_t*)&mp->c;
1921 count = ntohl(mp->count);
1922 for (i = 0; i < count; i++) {
1923 vec_validate(vam->ip6_fib_counters[vrf_index], i);
1924 counter = &vam->ip6_fib_counters[vrf_index][i];
Damjan Marionf1213b82016-03-13 02:22:06 +01001925 clib_memcpy(&ip6, &v->address, sizeof(ip6));
Ed Warnickecb9cada2015-12-08 15:45:58 -07001926 counter->address = ip6;
1927 counter->address_length = v->address_length;
1928 counter->packets = clib_net_to_host_u64(v->packets);
1929 counter->bytes = clib_net_to_host_u64(v->bytes);
1930 v++;
1931 }
1932}
1933
1934static void vl_api_get_first_msg_id_reply_t_handler
1935(vl_api_get_first_msg_id_reply_t * mp)
1936{
1937 vat_main_t * vam = &vat_main;
1938 i32 retval = ntohl(mp->retval);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08001939
Ed Warnickecb9cada2015-12-08 15:45:58 -07001940 if (vam->async_mode) {
1941 vam->async_errors += (retval < 0);
1942 } else {
1943 vam->retval = retval;
1944 vam->result_ready = 1;
1945 }
1946 if (retval >= 0) {
1947 errmsg ("first message id %d\n", ntohs(mp->first_msg_id));
1948 }
1949}
1950
1951static void vl_api_get_first_msg_id_reply_t_handler_json
1952(vl_api_get_first_msg_id_reply_t * mp)
1953{
1954 vat_main_t * vam = &vat_main;
1955 vat_json_node_t node;
1956
1957 vat_json_init_object(&node);
1958 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08001959 vat_json_object_add_uint(&node, "first_msg_id",
Ed Warnickecb9cada2015-12-08 15:45:58 -07001960 (uint) ntohs(mp->first_msg_id));
1961
1962 vat_json_print(vam->ofp, &node);
1963 vat_json_free(&node);
1964
1965 vam->retval = ntohl(mp->retval);
1966 vam->result_ready = 1;
1967}
1968
Dave Barachb44e9bc2016-02-19 09:06:23 -05001969static void vl_api_get_node_graph_reply_t_handler
1970(vl_api_get_node_graph_reply_t * mp)
1971{
1972 vat_main_t * vam = &vat_main;
1973 api_main_t * am = &api_main;
1974 i32 retval = ntohl(mp->retval);
1975 u8 * pvt_copy, * reply;
1976 void * oldheap;
1977 vlib_node_t * node;
1978 int i;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08001979
Dave Barachb44e9bc2016-02-19 09:06:23 -05001980 if (vam->async_mode) {
1981 vam->async_errors += (retval < 0);
1982 } else {
1983 vam->retval = retval;
1984 vam->result_ready = 1;
1985 }
1986
1987 /* "Should never happen..." */
1988 if (retval != 0)
1989 return;
1990
1991 reply = (u8 *)(mp->reply_in_shmem);
1992 pvt_copy = vec_dup (reply);
1993
1994 /* Toss the shared-memory original... */
1995 pthread_mutex_lock (&am->vlib_rp->mutex);
1996 oldheap = svm_push_data_heap (am->vlib_rp);
1997
1998 vec_free (reply);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08001999
Dave Barachb44e9bc2016-02-19 09:06:23 -05002000 svm_pop_heap (oldheap);
2001 pthread_mutex_unlock (&am->vlib_rp->mutex);
2002
2003 if (vam->graph_nodes) {
2004 hash_free (vam->graph_node_index_by_name);
2005
2006 for (i = 0; i < vec_len (vam->graph_nodes); i++) {
2007 node = vam->graph_nodes[i];
2008 vec_free (node->name);
2009 vec_free (node->next_nodes);
2010 vec_free (node);
2011 }
2012 vec_free(vam->graph_nodes);
2013 }
2014
2015 vam->graph_node_index_by_name = hash_create_string (0, sizeof(uword));
2016 vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2017 vec_free (pvt_copy);
2018
2019 for (i = 0; i < vec_len (vam->graph_nodes); i++) {
2020 node = vam->graph_nodes[i];
2021 hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2022 }
2023}
2024
2025static void vl_api_get_node_graph_reply_t_handler_json
2026(vl_api_get_node_graph_reply_t * mp)
2027{
2028 vat_main_t * vam = &vat_main;
2029 api_main_t * am = &api_main;
2030 void * oldheap;
2031 vat_json_node_t node;
2032 u8 * reply;
2033
2034 /* $$$$ make this real? */
2035 vat_json_init_object(&node);
2036 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
2037 vat_json_object_add_uint(&node, "reply_in_shmem", mp->reply_in_shmem);
2038
2039 reply = (u8 *)(mp->reply_in_shmem);
2040
2041 /* Toss the shared-memory original... */
2042 pthread_mutex_lock (&am->vlib_rp->mutex);
2043 oldheap = svm_push_data_heap (am->vlib_rp);
2044
2045 vec_free (reply);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08002046
Dave Barachb44e9bc2016-02-19 09:06:23 -05002047 svm_pop_heap (oldheap);
2048 pthread_mutex_unlock (&am->vlib_rp->mutex);
2049
2050 vat_json_print(vam->ofp, &node);
2051 vat_json_free(&node);
2052
2053 vam->retval = ntohl(mp->retval);
2054 vam->result_ready = 1;
2055}
2056
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002057static void
Andrej Kozemcakd9831182016-06-20 08:47:57 +02002058vl_api_lisp_locator_details_t_handler (
2059 vl_api_lisp_locator_details_t *mp)
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002060{
2061 vat_main_t *vam = &vat_main;
Andrej Kozemcakd9831182016-06-20 08:47:57 +02002062 locator_msg_t loc;
2063 u8 * tmp_str = 0;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002064
Andrej Kozemcakd9831182016-06-20 08:47:57 +02002065 memset(&loc, 0, sizeof(loc));
2066 if (vam->noprint_msg) {
2067 loc.local = mp->local;
2068 loc.priority = mp->priority;
2069 loc.weight = mp->weight;
2070 if (loc.local) {
2071 loc.sw_if_index = ntohl(mp->sw_if_index);
2072 } else {
2073 loc.is_ipv6 = mp->is_ipv6;
2074 clib_memcpy(loc.ip_address, mp->ip_address, sizeof(loc.ip_address));
2075 }
2076 vec_add1(vam->locator_msg, loc);
Andrej Kozemcak3e53fc52016-05-09 10:52:16 +02002077 } else {
Andrej Kozemcakd9831182016-06-20 08:47:57 +02002078 if (mp->local) {
2079 tmp_str = format(tmp_str, "%=16d%=16d%=16d\n",
2080 ntohl(mp->sw_if_index),
2081 mp->priority,
2082 mp->weight);
2083 } else {
2084 tmp_str = format(tmp_str, "%=16U%=16d%=16d\n",
2085 mp->is_ipv6 ? format_ip6_address :
2086 format_ip4_address,
2087 mp->ip_address,
2088 mp->priority,
2089 mp->weight);
2090 }
Andrej Kozemcak3e53fc52016-05-09 10:52:16 +02002091
Andrej Kozemcakd9831182016-06-20 08:47:57 +02002092 fformat(vam->ofp, "%s", tmp_str);
2093
Andrej Kozemcak3e53fc52016-05-09 10:52:16 +02002094 vec_free(tmp_str);
2095 }
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002096}
2097
2098static void
Andrej Kozemcakd9831182016-06-20 08:47:57 +02002099vl_api_lisp_locator_details_t_handler_json (
2100 vl_api_lisp_locator_details_t *mp)
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002101{
2102 vat_main_t *vam = &vat_main;
2103 vat_json_node_t *node = NULL;
Andrej Kozemcakd9831182016-06-20 08:47:57 +02002104 locator_msg_t loc;
Andrej Kozemcak3e53fc52016-05-09 10:52:16 +02002105 struct in6_addr ip6;
2106 struct in_addr ip4;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002107
Andrej Kozemcakd9831182016-06-20 08:47:57 +02002108 memset(&loc, 0, sizeof(loc));
2109 if (vam->noprint_msg) {
2110 loc.local = mp->local;
2111 loc.priority = mp->priority;
2112 loc.weight = mp->weight;
2113 if (loc.local) {
2114 loc.sw_if_index = ntohl(mp->sw_if_index);
2115 } else {
2116 loc.is_ipv6 = mp->is_ipv6;
2117 clib_memcpy(loc.ip_address, mp->ip_address, sizeof(loc.ip_address));
2118 }
2119 vec_add1(vam->locator_msg, loc);
2120 return;
2121 }
2122
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002123 if (VAT_JSON_ARRAY != vam->json_tree.type) {
2124 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
2125 vat_json_init_array(&vam->json_tree);
2126 }
2127 node = vat_json_array_add(&vam->json_tree);
2128
2129 vat_json_init_object(node);
Andrej Kozemcakd9831182016-06-20 08:47:57 +02002130
Andrej Kozemcak3e53fc52016-05-09 10:52:16 +02002131 if (mp->local) {
Andrej Kozemcakd9831182016-06-20 08:47:57 +02002132 vat_json_object_add_uint(node, "locator_index", ntohl(mp->sw_if_index));
Andrej Kozemcak3e53fc52016-05-09 10:52:16 +02002133 } else {
Andrej Kozemcakd9831182016-06-20 08:47:57 +02002134 if (mp->is_ipv6) {
2135 clib_memcpy(&ip6, mp->ip_address, sizeof(ip6));
2136 vat_json_object_add_ip6(node, "locator", ip6);
2137 } else {
2138 clib_memcpy(&ip4, mp->ip_address, sizeof(ip4));
2139 vat_json_object_add_ip4(node, "locator", ip4);
2140 }
Andrej Kozemcak3e53fc52016-05-09 10:52:16 +02002141 }
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002142 vat_json_object_add_uint(node, "priority", mp->priority);
2143 vat_json_object_add_uint(node, "weight", mp->weight);
2144}
2145
2146static void
Andrej Kozemcakd9831182016-06-20 08:47:57 +02002147vl_api_lisp_locator_set_details_t_handler (
2148 vl_api_lisp_locator_set_details_t *mp)
2149{
2150 vat_main_t *vam = &vat_main;
2151 locator_set_msg_t ls;
2152
2153 ls.locator_set_index = ntohl(mp->locator_set_index);
2154 ls.locator_set_name = format(0, "%s", mp->locator_set_name);
2155 vec_add1(vam->locator_set_msg, ls);
2156}
2157
2158static void
2159vl_api_lisp_locator_set_details_t_handler_json (
2160 vl_api_lisp_locator_set_details_t *mp)
2161{
2162 vat_main_t *vam = &vat_main;
2163 locator_set_msg_t ls;
2164
2165 ls.locator_set_index = ntohl(mp->locator_set_index);
2166 ls.locator_set_name = format(0, "%s", mp->locator_set_name);
2167 vec_add1(vam->locator_set_msg, ls);
2168}
2169
2170static void
Andrej Kozemcak6cc6f912016-07-13 13:01:01 +02002171vl_api_lisp_eid_table_details_t_handler (
2172 vl_api_lisp_eid_table_details_t * mp)
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002173{
2174 vat_main_t *vam = &vat_main;
Andrej Kozemcak6cc6f912016-07-13 13:01:01 +02002175 eid_table_t eid_table;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002176
Andrej Kozemcak6cc6f912016-07-13 13:01:01 +02002177 memset(&eid_table, 0, sizeof(eid_table));
2178 eid_table.is_local = mp->is_local;
2179 eid_table.locator_set_index = mp->locator_set_index;
2180 eid_table.eid_type = mp->eid_type;
2181 eid_table.vni = mp->vni;
2182 eid_table.eid_prefix_len = mp->eid_prefix_len;
2183 eid_table.ttl = mp->ttl;
2184 eid_table.authoritative = mp->authoritative;
2185 clib_memcpy(eid_table.eid, mp->eid, sizeof(eid_table.eid));
2186 vec_add1(vam->eid_tables, eid_table);
2187}
Filip Tehlar006eb262016-06-27 13:09:20 +02002188
Andrej Kozemcak6cc6f912016-07-13 13:01:01 +02002189static void
2190vl_api_lisp_eid_table_details_t_handler_json (
2191 vl_api_lisp_eid_table_details_t * mp)
2192{
2193 vat_main_t *vam = &vat_main;
2194 eid_table_t eid_table;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002195
Andrej Kozemcak6cc6f912016-07-13 13:01:01 +02002196 memset(&eid_table, 0, sizeof(eid_table));
2197 eid_table.is_local = mp->is_local;
2198 eid_table.locator_set_index = mp->locator_set_index;
2199 eid_table.eid_type = mp->eid_type;
2200 eid_table.vni = mp->vni;
2201 eid_table.eid_prefix_len = mp->eid_prefix_len;
2202 eid_table.ttl = mp->ttl;
2203 eid_table.authoritative = mp->authoritative;
2204 clib_memcpy(eid_table.eid, mp->eid, sizeof(eid_table.eid));
2205 vec_add1(vam->eid_tables, eid_table);
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002206}
2207
2208static void
Filip Tehlar2f653d02016-07-13 13:17:15 +02002209vl_api_lisp_eid_table_map_details_t_handler (
2210 vl_api_lisp_eid_table_map_details_t *mp)
2211{
2212 vat_main_t *vam = &vat_main;
2213
2214 u8 * line = format(0, "%=10d%=10d",
2215 clib_net_to_host_u32 (mp->vni),
2216 clib_net_to_host_u32 (mp->vrf));
2217 fformat(vam->ofp, "%v\n", line);
2218 vec_free(line);
2219}
2220
2221static void
2222vl_api_lisp_eid_table_map_details_t_handler_json (
2223 vl_api_lisp_eid_table_map_details_t *mp)
2224{
2225 vat_main_t *vam = &vat_main;
2226 vat_json_node_t *node = NULL;
2227
2228 if (VAT_JSON_ARRAY != vam->json_tree.type) {
2229 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
2230 vat_json_init_array(&vam->json_tree);
2231 }
2232 node = vat_json_array_add(&vam->json_tree);
2233 vat_json_init_object(node);
2234 vat_json_object_add_uint(node, "vrf", clib_net_to_host_u32 (mp->vrf));
2235 vat_json_object_add_uint(node, "vni", clib_net_to_host_u32 (mp->vni));
2236}
2237
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002238
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002239
2240static u8 *
2241format_decap_next (u8 * s, va_list * args)
2242{
2243 u32 next_index = va_arg (*args, u32);
2244
2245 switch (next_index)
2246 {
2247 case LISP_GPE_INPUT_NEXT_DROP:
2248 return format (s, "drop");
2249 case LISP_GPE_INPUT_NEXT_IP4_INPUT:
2250 return format (s, "ip4");
2251 case LISP_GPE_INPUT_NEXT_IP6_INPUT:
2252 return format (s, "ip6");
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002253 default:
2254 return format (s, "unknown %d", next_index);
2255 }
2256 return s;
2257}
2258
2259static void
2260vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *mp)
2261{
2262 vat_main_t *vam = &vat_main;
2263 u8 *iid_str;
2264 u8 *flag_str = NULL;
2265
2266 iid_str = format(0, "%d (0x%x)", ntohl(mp->iid), ntohl(mp->iid));
2267
2268#define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n);
2269 foreach_lisp_gpe_flag_bit;
2270#undef _
2271
2272 fformat(vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U"
2273 "%=16d%=16d%=16sd=16d%=16s%=16s\n",
2274 mp->tunnels,
2275 mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2276 mp->source_ip,
2277 mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2278 mp->destination_ip,
2279 ntohl(mp->encap_fib_id),
2280 ntohl(mp->decap_fib_id),
2281 format_decap_next, ntohl(mp->dcap_next),
2282 mp->ver_res >> 6,
2283 flag_str,
2284 mp->next_protocol,
2285 mp->ver_res,
2286 mp->res,
2287 iid_str);
2288
2289 vec_free(iid_str);
2290}
2291
2292static void
2293vl_api_lisp_gpe_tunnel_details_t_handler_json (
2294 vl_api_lisp_gpe_tunnel_details_t *mp)
2295{
2296 vat_main_t *vam = &vat_main;
2297 vat_json_node_t *node = NULL;
2298 struct in6_addr ip6;
2299 struct in_addr ip4;
2300 u8 *next_decap_str;
2301
2302 next_decap_str = format(0, "%U", format_decap_next, htonl(mp->dcap_next));
2303
2304 if (VAT_JSON_ARRAY != vam->json_tree.type) {
2305 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
2306 vat_json_init_array(&vam->json_tree);
2307 }
2308 node = vat_json_array_add(&vam->json_tree);
2309
2310 vat_json_init_object(node);
2311 vat_json_object_add_uint(node, "tunel", mp->tunnels);
2312 if (mp->is_ipv6) {
Damjan Marionf1213b82016-03-13 02:22:06 +01002313 clib_memcpy(&ip6, mp->source_ip, sizeof(ip6));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002314 vat_json_object_add_ip6(node, "source address", ip6);
Damjan Marionf1213b82016-03-13 02:22:06 +01002315 clib_memcpy(&ip6, mp->destination_ip, sizeof(ip6));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002316 vat_json_object_add_ip6(node, "destination address", ip6);
2317 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01002318 clib_memcpy(&ip4, mp->source_ip, sizeof(ip4));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002319 vat_json_object_add_ip4(node, "source address", ip4);
Damjan Marionf1213b82016-03-13 02:22:06 +01002320 clib_memcpy(&ip4, mp->destination_ip, sizeof(ip4));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002321 vat_json_object_add_ip4(node, "destination address", ip4);
2322 }
2323 vat_json_object_add_uint(node, "fib encap", ntohl(mp->encap_fib_id));
2324 vat_json_object_add_uint(node, "fib decap", ntohl(mp->decap_fib_id));
2325 vat_json_object_add_string_copy(node, "decap next", next_decap_str);
2326 vat_json_object_add_uint(node, "lisp version", mp->ver_res >> 6);
2327 vat_json_object_add_uint(node, "flags", mp->flags);
2328 vat_json_object_add_uint(node, "next protocol", mp->next_protocol);
2329 vat_json_object_add_uint(node, "ver_res", mp->ver_res);
2330 vat_json_object_add_uint(node, "res", mp->res);
2331 vat_json_object_add_uint(node, "iid", ntohl(mp->iid));
2332
2333 vec_free(next_decap_str);
2334}
2335
2336static void
2337vl_api_lisp_map_resolver_details_t_handler (
2338 vl_api_lisp_map_resolver_details_t *mp)
2339{
2340 vat_main_t *vam = &vat_main;
2341
2342 fformat(vam->ofp, "%=20U\n",
2343 mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2344 mp->ip_address);
2345}
2346
2347static void
2348vl_api_lisp_map_resolver_details_t_handler_json (
2349 vl_api_lisp_map_resolver_details_t *mp)
2350{
2351 vat_main_t *vam = &vat_main;
2352 vat_json_node_t *node = NULL;
2353 struct in6_addr ip6;
2354 struct in_addr ip4;
2355
2356 if (VAT_JSON_ARRAY != vam->json_tree.type) {
2357 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
2358 vat_json_init_array(&vam->json_tree);
2359 }
2360 node = vat_json_array_add(&vam->json_tree);
2361
2362 vat_json_init_object(node);
2363 if (mp->is_ipv6) {
Damjan Marionf1213b82016-03-13 02:22:06 +01002364 clib_memcpy(&ip6, mp->ip_address, sizeof(ip6));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002365 vat_json_object_add_ip6(node, "map resolver", ip6);
2366 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01002367 clib_memcpy(&ip4, mp->ip_address, sizeof(ip4));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002368 vat_json_object_add_ip4(node, "map resolver", ip4);
2369 }
2370}
2371
Andrej Kozemcaka9edd852016-05-02 12:14:33 +02002372static void
Andrej Kozemcakd9831182016-06-20 08:47:57 +02002373vl_api_show_lisp_status_reply_t_handler
2374(vl_api_show_lisp_status_reply_t * mp)
Andrej Kozemcaka9edd852016-05-02 12:14:33 +02002375{
2376 vat_main_t *vam = &vat_main;
Andrej Kozemcakd9831182016-06-20 08:47:57 +02002377 i32 retval = ntohl(mp->retval);
Andrej Kozemcaka9edd852016-05-02 12:14:33 +02002378
Andrej Kozemcakd9831182016-06-20 08:47:57 +02002379 if (0 <= retval) {
2380 fformat(vam->ofp, "feature: %s\ngpe: %s\n",
2381 mp->feature_status ? "enabled" : "disabled",
2382 mp->gpe_status ? "enabled" : "disabled");
2383 }
2384
2385 vam->retval = retval;
2386 vam->result_ready = 1;
Andrej Kozemcaka9edd852016-05-02 12:14:33 +02002387}
2388
2389static void
Andrej Kozemcakd9831182016-06-20 08:47:57 +02002390vl_api_show_lisp_status_reply_t_handler_json
2391(vl_api_show_lisp_status_reply_t *mp)
Andrej Kozemcaka9edd852016-05-02 12:14:33 +02002392{
2393 vat_main_t *vam = &vat_main;
Andrej Kozemcakd9831182016-06-20 08:47:57 +02002394 vat_json_node_t node;
Filip Tehlar46d4e362016-05-09 09:39:26 +02002395 u8 * gpe_status = NULL;
2396 u8 * feature_status = NULL;
Andrej Kozemcaka9edd852016-05-02 12:14:33 +02002397
Filip Tehlar46d4e362016-05-09 09:39:26 +02002398 gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2399 feature_status = format (0, "%s",
2400 mp->feature_status ? "enabled" : "disabled");
Filip Tehlar6f91cfe2016-06-06 13:13:16 +02002401 vec_add1 (gpe_status, 0);
2402 vec_add1 (feature_status, 0);
Andrej Kozemcaka9edd852016-05-02 12:14:33 +02002403
Andrej Kozemcakd9831182016-06-20 08:47:57 +02002404 vat_json_init_object(&node);
2405 vat_json_object_add_string_copy(&node, "gpe_status", gpe_status);
2406 vat_json_object_add_string_copy(&node, "feature_status", feature_status);
Filip Tehlar46d4e362016-05-09 09:39:26 +02002407
2408 vec_free (gpe_status);
2409 vec_free (feature_status);
Andrej Kozemcakd9831182016-06-20 08:47:57 +02002410
2411 vat_json_print(vam->ofp, &node);
2412 vat_json_free(&node);
2413
2414 vam->retval = ntohl(mp->retval);
2415 vam->result_ready = 1;
Andrej Kozemcaka9edd852016-05-02 12:14:33 +02002416}
2417
Andrej Kozemcakb6e4d392016-06-14 13:55:57 +02002418static void
2419vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler (
2420 vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2421{
2422 vat_main_t * vam = &vat_main;
2423 i32 retval = ntohl(mp->retval);
2424
2425 if (retval >= 0) {
2426 fformat(vam->ofp, "%=20s\n",
2427 mp->locator_set_name);
2428 }
2429
2430 vam->retval = retval;
2431 vam->result_ready = 1;
2432}
2433
2434static void
2435vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json (
2436 vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2437{
2438 vat_main_t * vam = &vat_main;
2439 vat_json_node_t * node = NULL;
2440
2441 if (VAT_JSON_ARRAY != vam->json_tree.type) {
2442 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
2443 vat_json_init_array(&vam->json_tree);
2444 }
2445 node = vat_json_array_add(&vam->json_tree);
2446
2447 vat_json_init_object(node);
2448 vat_json_object_add_string_copy(node, "itr-rlocs", mp->locator_set_name);
2449
2450 vat_json_print(vam->ofp, node);
2451 vat_json_free(node);
2452
2453 vam->retval = ntohl(mp->retval);
2454 vam->result_ready = 1;
2455}
2456
Andrej Kozemcak914f91b2016-07-18 13:55:37 +02002457static void
2458vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2459{
2460 vat_main_t *vam = &vat_main;
2461 i32 retval = ntohl(mp->retval);
2462
2463 if (0 <= retval) {
2464 fformat(vam->ofp, "%-20s%-16s\n",
2465 mp->status ? "enabled" : "disabled",
2466 mp->status ? (char *) mp->locator_set_name : "");
2467 }
2468
2469 vam->retval = retval;
2470 vam->result_ready = 1;
2471}
2472
2473static void
2474vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t * mp)
2475{
2476 vat_main_t *vam = &vat_main;
2477 vat_json_node_t node;
2478 u8 * status = 0;
2479
2480 status = format (0, "%s", mp->status ? "enabled" : "disabled");
2481 vec_add1 (status, 0);
2482
2483 vat_json_init_object(&node);
2484 vat_json_object_add_string_copy(&node, "status", status);
2485 if (mp->status) {
2486 vat_json_object_add_string_copy(&node, "locator_set", mp->locator_set_name);
2487 }
2488
2489 vec_free (status);
2490
2491 vat_json_print(vam->ofp, &node);
2492 vat_json_free(&node);
2493
2494 vam->retval = ntohl(mp->retval);
2495 vam->result_ready = 1;
2496}
2497
Matus Fabiane8554802016-05-18 23:40:37 -07002498static u8 * format_policer_type (u8 * s, va_list * va)
2499{
2500 u32 i = va_arg (*va, u32);
2501
2502 if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2503 s = format (s, "1r2c");
2504 else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2505 s = format (s, "1r3c");
2506 else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2507 s = format (s, "2r3c-2698");
2508 else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2509 s = format (s, "2r3c-4115");
2510 else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2511 s = format (s, "2r3c-mef5cf1");
2512 else
2513 s = format (s, "ILLEGAL");
2514 return s;
2515}
2516
2517static u8 * format_policer_rate_type (u8 * s, va_list * va)
2518{
2519 u32 i = va_arg (*va, u32);
2520
2521 if (i == SSE2_QOS_RATE_KBPS)
2522 s = format (s, "kbps");
2523 else if (i == SSE2_QOS_RATE_PPS)
2524 s = format(s, "pps");
2525 else
2526 s = format (s, "ILLEGAL");
2527 return s;
2528}
2529
2530static u8 * format_policer_round_type (u8 * s, va_list * va)
2531{
2532 u32 i = va_arg (*va, u32);
2533
2534 if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2535 s = format(s, "closest");
2536 else if (i == SSE2_QOS_ROUND_TO_UP)
2537 s = format (s, "up");
2538 else if (i == SSE2_QOS_ROUND_TO_DOWN)
2539 s = format (s, "down");
2540 else
2541 s = format (s, "ILLEGAL");
2542 return s;
2543}
2544
Matus Fabian4ac74c92016-05-31 07:33:29 -07002545static u8 * format_policer_action_type (u8 * s, va_list * va)
2546{
2547 u32 i = va_arg (*va, u32);
2548
2549 if (i == SSE2_QOS_ACTION_DROP)
2550 s = format (s, "drop");
2551 else if (i == SSE2_QOS_ACTION_TRANSMIT)
2552 s = format (s, "transmit");
2553 else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2554 s = format (s, "mark-and-transmit");
2555 else
2556 s = format (s, "ILLEGAL");
2557 return s;
2558}
2559
2560static u8 * format_dscp (u8 * s, va_list * va)
2561{
2562 u32 i = va_arg (*va, u32);
2563 char * t = 0;
2564
2565 switch (i) {
2566 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
2567 foreach_vnet_dscp
2568 #undef _
2569 default:
2570 return format (s, "ILLEGAL");
2571 }
2572 s = format (s, "%s", t);
2573 return s;
2574}
2575
Matus Fabiane8554802016-05-18 23:40:37 -07002576static void vl_api_policer_details_t_handler
2577(vl_api_policer_details_t * mp)
2578{
2579 vat_main_t * vam = &vat_main;
Matus Fabian4ac74c92016-05-31 07:33:29 -07002580 u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2581
2582 if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2583 conform_dscp_str = format(0, "%U", format_dscp, mp->conform_dscp);
2584 else
2585 conform_dscp_str = format(0, "");
2586
2587 if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2588 exceed_dscp_str = format(0, "%U", format_dscp, mp->exceed_dscp);
2589 else
2590 exceed_dscp_str = format(0, "");
2591
2592 if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2593 violate_dscp_str = format(0, "%U", format_dscp, mp->violate_dscp);
2594 else
2595 violate_dscp_str = format(0, "");
Matus Fabiane8554802016-05-18 23:40:37 -07002596
2597 fformat (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2598 "rate type %U, round type %U, %s rate, %s color-aware, "
2599 "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
Matus Fabian4ac74c92016-05-31 07:33:29 -07002600 "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
2601 "conform action %U%s, exceed action %U%s, violate action %U%s\n",
Matus Fabiane8554802016-05-18 23:40:37 -07002602 mp->name,
2603 format_policer_type, mp->type,
2604 ntohl(mp->cir),
2605 ntohl(mp->eir),
Matus Fabian70e6a8d2016-06-20 08:10:42 -07002606 clib_net_to_host_u64(mp->cb),
2607 clib_net_to_host_u64(mp->eb),
Matus Fabiane8554802016-05-18 23:40:37 -07002608 format_policer_rate_type, mp->rate_type,
2609 format_policer_round_type, mp->round_type,
2610 mp->single_rate ? "single" : "dual",
2611 mp->color_aware ? "is" : "not",
2612 ntohl(mp->cir_tokens_per_period),
2613 ntohl(mp->pir_tokens_per_period),
2614 ntohl(mp->scale),
2615 ntohl(mp->current_limit),
2616 ntohl(mp->current_bucket),
2617 ntohl(mp->extended_limit),
2618 ntohl(mp->extended_bucket),
Matus Fabian4ac74c92016-05-31 07:33:29 -07002619 clib_net_to_host_u64(mp->last_update_time),
2620 format_policer_action_type, mp->conform_action_type,
2621 conform_dscp_str,
2622 format_policer_action_type, mp->exceed_action_type,
2623 exceed_dscp_str,
2624 format_policer_action_type, mp->violate_action_type,
2625 violate_dscp_str);
2626
2627 vec_free(conform_dscp_str);
2628 vec_free(exceed_dscp_str);
2629 vec_free(violate_dscp_str);
Matus Fabiane8554802016-05-18 23:40:37 -07002630}
2631
2632static void vl_api_policer_details_t_handler_json
2633(vl_api_policer_details_t * mp)
2634{
2635 vat_main_t * vam = &vat_main;
2636 vat_json_node_t *node;
2637 u8 *rate_type_str, *round_type_str, *type_str;
Matus Fabian4ac74c92016-05-31 07:33:29 -07002638 u8 *conform_action_str, *exceed_action_str, *violate_action_str;
Matus Fabiane8554802016-05-18 23:40:37 -07002639
2640 rate_type_str = format(0, "%U", format_policer_rate_type, mp->rate_type);
2641 round_type_str = format(0, "%U", format_policer_round_type, mp->round_type);
2642 type_str = format(0, "%U", format_policer_type, mp->type);
Matus Fabian4ac74c92016-05-31 07:33:29 -07002643 conform_action_str = format(0, "%U", format_policer_action_type,
2644 mp->conform_action_type);
2645 exceed_action_str = format(0, "%U", format_policer_action_type,
2646 mp->exceed_action_type);
2647 violate_action_str = format(0, "%U", format_policer_action_type,
2648 mp->violate_action_type);
Matus Fabiane8554802016-05-18 23:40:37 -07002649
2650 if (VAT_JSON_ARRAY != vam->json_tree.type) {
2651 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
2652 vat_json_init_array(&vam->json_tree);
2653 }
2654 node = vat_json_array_add(&vam->json_tree);
2655
2656 vat_json_init_object(node);
2657 vat_json_object_add_string_copy(node, "name", mp->name);
2658 vat_json_object_add_uint(node, "cir", ntohl(mp->cir));
2659 vat_json_object_add_uint(node, "eir", ntohl(mp->eir));
2660 vat_json_object_add_uint(node, "cb", ntohl(mp->cb));
2661 vat_json_object_add_uint(node, "eb", ntohl(mp->eb));
2662 vat_json_object_add_string_copy(node, "rate_type", rate_type_str);
2663 vat_json_object_add_string_copy(node, "round_type", round_type_str);
2664 vat_json_object_add_string_copy(node, "type", type_str);
2665 vat_json_object_add_uint(node, "single_rate", mp->single_rate);
2666 vat_json_object_add_uint(node, "color_aware", mp->color_aware);
2667 vat_json_object_add_uint(node, "scale", ntohl(mp->scale));
2668 vat_json_object_add_uint(node, "cir_tokens_per_period",
2669 ntohl(mp->cir_tokens_per_period));
2670 vat_json_object_add_uint(node, "eir_tokens_per_period",
2671 ntohl(mp->pir_tokens_per_period));
2672 vat_json_object_add_uint(node, "current_limit", ntohl(mp->current_limit));
2673 vat_json_object_add_uint(node, "current_bucket", ntohl(mp->current_bucket));
2674 vat_json_object_add_uint(node, "extended_limit", ntohl(mp->extended_limit));
2675 vat_json_object_add_uint(node, "extended_bucket",
2676 ntohl(mp->extended_bucket));
2677 vat_json_object_add_uint(node, "last_update_time",
2678 ntohl(mp->last_update_time));
Matus Fabian4ac74c92016-05-31 07:33:29 -07002679 vat_json_object_add_string_copy(node, "conform_action", conform_action_str);
2680 if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT) {
2681 u8 *dscp_str = format(0, "%U", format_dscp, mp->conform_dscp);
2682 vat_json_object_add_string_copy(node, "conform_dscp", dscp_str);
2683 vec_free(dscp_str);
2684 }
2685 vat_json_object_add_string_copy(node, "exceed_action", exceed_action_str);
2686 if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT) {
2687 u8 *dscp_str = format(0, "%U", format_dscp, mp->exceed_dscp);
2688 vat_json_object_add_string_copy(node, "exceed_dscp", dscp_str);
2689 vec_free(dscp_str);
2690 }
2691 vat_json_object_add_string_copy(node, "violate_action", violate_action_str);
2692 if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT) {
2693 u8 *dscp_str = format(0, "%U", format_dscp, mp->violate_dscp);
2694 vat_json_object_add_string_copy(node, "violate_dscp", dscp_str);
2695 vec_free(dscp_str);
2696 }
Matus Fabiane8554802016-05-18 23:40:37 -07002697
2698 vec_free(rate_type_str);
2699 vec_free(round_type_str);
2700 vec_free(type_str);
Matus Fabian4ac74c92016-05-31 07:33:29 -07002701 vec_free(conform_action_str);
2702 vec_free(exceed_action_str);
2703 vec_free(violate_action_str);
Matus Fabiane8554802016-05-18 23:40:37 -07002704}
2705
Pavel Kotucek20c90f72016-06-07 14:44:26 +02002706static void vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t * mp)
2707{
2708 vat_main_t * vam = &vat_main;
2709 int i, count = ntohl(mp->count);
2710
2711 if (count>0)
2712 fformat (vam->ofp, "classify table ids (%d) : ", count);
2713 for (i = 0; i < count; i++)
2714 {
2715 fformat (vam->ofp, "%d", ntohl(mp->ids[i]));
2716 fformat (vam->ofp, (i<count-1)?",":"\n");
2717 }
2718 vam->retval = ntohl(mp->retval);
2719 vam->result_ready = 1;
2720}
2721
2722static void vl_api_classify_table_ids_reply_t_handler_json (vl_api_classify_table_ids_reply_t * mp)
2723{
2724 vat_main_t * vam = &vat_main;
2725 int i, count = ntohl(mp->count);
2726
2727 if (count>0) {
2728 vat_json_node_t node;
2729
2730 vat_json_init_object(&node);
2731 for (i = 0; i < count; i++)
2732 {
2733 vat_json_object_add_uint(&node, "table_id", ntohl(mp->ids[i]));
2734 }
2735 vat_json_print(vam->ofp, &node);
2736 vat_json_free(&node);
2737 }
2738 vam->retval = ntohl(mp->retval);
2739 vam->result_ready = 1;
2740}
2741
2742static void vl_api_classify_table_by_interface_reply_t_handler (vl_api_classify_table_by_interface_reply_t * mp)
2743{
2744 vat_main_t * vam = &vat_main;
2745 u32 table_id;
2746
2747 table_id = ntohl(mp->l2_table_id);
2748 if (table_id != ~0)
2749 fformat (vam->ofp, "l2 table id : %d\n", table_id);
2750 else
2751 fformat (vam->ofp, "l2 table id : No input ACL tables configured\n");
2752 table_id = ntohl(mp->ip4_table_id);
2753 if (table_id != ~0)
2754 fformat (vam->ofp, "ip4 table id : %d\n", table_id);
2755 else
2756 fformat (vam->ofp, "ip4 table id : No input ACL tables configured\n");
2757 table_id = ntohl(mp->ip6_table_id);
2758 if (table_id != ~0)
2759 fformat (vam->ofp, "ip6 table id : %d\n", table_id);
2760 else
2761 fformat (vam->ofp, "ip6 table id : No input ACL tables configured\n");
2762 vam->retval = ntohl(mp->retval);
2763 vam->result_ready = 1;
2764}
2765
2766static void vl_api_classify_table_by_interface_reply_t_handler_json (vl_api_classify_table_by_interface_reply_t * mp)
2767{
2768 vat_main_t * vam = &vat_main;
2769 vat_json_node_t node;
2770
2771 vat_json_init_object(&node);
2772
2773 vat_json_object_add_int(&node, "l2_table_id", ntohl(mp->l2_table_id));
2774 vat_json_object_add_int(&node, "ip4_table_id", ntohl(mp->ip4_table_id));
2775 vat_json_object_add_int(&node, "ip6_table_id", ntohl(mp->ip6_table_id));
2776
2777 vat_json_print(vam->ofp, &node);
2778 vat_json_free(&node);
2779
2780 vam->retval = ntohl(mp->retval);
2781 vam->result_ready = 1;
2782}
2783
Matus Fabian70e6a8d2016-06-20 08:10:42 -07002784static void vl_api_policer_add_del_reply_t_handler
2785(vl_api_policer_add_del_reply_t * mp)
2786{
2787 vat_main_t * vam = &vat_main;
2788 i32 retval = ntohl(mp->retval);
2789 if (vam->async_mode) {
2790 vam->async_errors += (retval < 0);
2791 } else {
2792 vam->retval = retval;
2793 vam->result_ready = 1;
2794 if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
2795 /*
2796 * Note: this is just barely thread-safe, depends on
2797 * the main thread spinning waiting for an answer...
2798 */
2799 errmsg ("policer index %d\n", ntohl(mp->policer_index));
2800 }
2801}
2802
2803static void vl_api_policer_add_del_reply_t_handler_json
2804(vl_api_policer_add_del_reply_t * mp)
2805{
2806 vat_main_t * vam = &vat_main;
2807 vat_json_node_t node;
2808
2809 vat_json_init_object(&node);
2810 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
2811 vat_json_object_add_uint(&node, "policer_index", ntohl(mp->policer_index));
2812
2813 vat_json_print(vam->ofp, &node);
2814 vat_json_free(&node);
2815
2816 vam->retval = ntohl(mp->retval);
2817 vam->result_ready = 1;
2818}
2819
Pavel Kotucek20c90f72016-06-07 14:44:26 +02002820/* Format hex dump. */
2821u8 * format_hex_bytes (u8 * s, va_list * va)
2822{
2823 u8 * bytes = va_arg (*va, u8 *);
2824 int n_bytes = va_arg (*va, int);
2825 uword i;
2826
2827 /* Print short or long form depending on byte count. */
2828 uword short_form = n_bytes <= 32;
2829 uword indent = format_get_indent (s);
2830
2831 if (n_bytes == 0)
2832 return s;
2833
2834 for (i = 0; i < n_bytes; i++)
2835 {
2836 if (! short_form && (i % 32) == 0)
2837 s = format (s, "%08x: ", i);
2838 s = format (s, "%02x", bytes[i]);
2839 if (! short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
2840 s = format (s, "\n%U", format_white_space, indent);
2841 }
2842
2843 return s;
2844}
2845
2846static void vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t * mp)
2847{
2848 vat_main_t * vam = &vat_main;
2849 i32 retval = ntohl(mp->retval);
2850 if (retval == 0) {
2851 fformat (vam->ofp, "classify table info :\n");
2852 fformat (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d\n", ntohl(mp->active_sessions), ntohl(mp->next_table_index), ntohl(mp->miss_next_index));
2853 fformat (vam->ofp, "nbuckets: %d skip: %d match: %d\n", ntohl(mp->nbuckets), ntohl(mp->skip_n_vectors), ntohl(mp->match_n_vectors));
2854 fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->mask, ntohl(mp->mask_length));
2855 }
2856 vam->retval = retval;
2857 vam->result_ready = 1;
2858}
2859
2860static void vl_api_classify_table_info_reply_t_handler_json (vl_api_classify_table_info_reply_t * mp)
2861{
2862 vat_main_t * vam = &vat_main;
2863 vat_json_node_t node;
2864
2865 i32 retval = ntohl(mp->retval);
2866 if (retval == 0) {
2867 vat_json_init_object(&node);
2868
2869 vat_json_object_add_int(&node, "sessions", ntohl(mp->active_sessions));
2870 vat_json_object_add_int(&node, "nexttbl", ntohl(mp->next_table_index));
2871 vat_json_object_add_int(&node, "nextnode", ntohl(mp->miss_next_index));
2872 vat_json_object_add_int(&node, "nbuckets", ntohl(mp->nbuckets));
2873 vat_json_object_add_int(&node, "skip", ntohl(mp->skip_n_vectors));
2874 vat_json_object_add_int(&node, "match", ntohl(mp->match_n_vectors));
2875 u8 * s = format (0, "%U%c",format_hex_bytes, mp->mask, ntohl(mp->mask_length), 0);
2876 vat_json_object_add_string_copy(&node, "mask", s);
2877
2878 vat_json_print(vam->ofp, &node);
2879 vat_json_free(&node);
2880 }
2881 vam->retval = ntohl(mp->retval);
2882 vam->result_ready = 1;
2883}
2884
2885static void vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t * mp)
2886{
2887 vat_main_t * vam = &vat_main;
2888
2889 fformat (vam->ofp, "next_index: %d advance: %d opaque: %d ", ntohl(mp->hit_next_index), ntohl(mp->advance), ntohl(mp->opaque_index));
2890 fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->match, ntohl(mp->match_length));
2891}
2892
2893static void vl_api_classify_session_details_t_handler_json (vl_api_classify_session_details_t * mp)
2894{
2895 vat_main_t * vam = &vat_main;
2896 vat_json_node_t *node = NULL;
2897
2898 if (VAT_JSON_ARRAY != vam->json_tree.type) {
2899 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
2900 vat_json_init_array(&vam->json_tree);
2901 }
2902 node = vat_json_array_add(&vam->json_tree);
2903
2904 vat_json_init_object(node);
2905 vat_json_object_add_int(node, "next_index", ntohl(mp->hit_next_index));
2906 vat_json_object_add_int(node, "advance", ntohl(mp->advance));
2907 vat_json_object_add_int(node, "opaque", ntohl(mp->opaque_index));
2908 u8 * s = format (0, "%U%c",format_hex_bytes, mp->match, ntohl(mp->match_length), 0);
2909 vat_json_object_add_string_copy(node, "match", s);
2910}
Matus Fabiane8554802016-05-18 23:40:37 -07002911
Pavel Kotucek9e6ed6e2016-07-12 10:18:26 +02002912static void vl_api_pg_create_interface_reply_t_handler
2913(vl_api_pg_create_interface_reply_t * mp)
2914{
2915 vat_main_t * vam = &vat_main;
2916
2917 vam->retval = ntohl(mp->retval);
2918 vam->result_ready = 1;
2919}
2920
2921static void vl_api_pg_create_interface_reply_t_handler_json
2922(vl_api_pg_create_interface_reply_t * mp)
2923{
2924 vat_main_t * vam = &vat_main;
2925 vat_json_node_t node;
2926
2927 i32 retval = ntohl(mp->retval);
2928 if (retval == 0) {
2929 vat_json_init_object(&node);
2930
2931 vat_json_object_add_int(&node, "sw_if_index", ntohl(mp->sw_if_index));
2932
2933 vat_json_print(vam->ofp, &node);
2934 vat_json_free(&node);
2935 }
2936 vam->retval = ntohl(mp->retval);
2937 vam->result_ready = 1;
2938}
2939
Matus Fabian70e6a8d2016-06-20 08:10:42 -07002940static void vl_api_policer_classify_details_t_handler
2941(vl_api_policer_classify_details_t * mp)
2942{
2943 vat_main_t * vam = &vat_main;
2944
2945 fformat (vam->ofp, "%10d%20d\n", ntohl(mp->sw_if_index),
2946 ntohl(mp->table_index));
2947}
2948
2949static void vl_api_policer_classify_details_t_handler_json
2950(vl_api_policer_classify_details_t * mp)
2951{
2952 vat_main_t * vam = &vat_main;
2953 vat_json_node_t * node;
2954
2955 if (VAT_JSON_ARRAY != vam->json_tree.type) {
2956 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
2957 vat_json_init_array(&vam->json_tree);
2958 }
2959 node = vat_json_array_add(&vam->json_tree);
2960
2961 vat_json_init_object(node);
2962 vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
2963 vat_json_object_add_uint(node, "table_index", ntohl(mp->table_index));
2964}
2965
2966
Ed Warnickecb9cada2015-12-08 15:45:58 -07002967#define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
2968#define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
2969#define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
2970#define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
2971
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08002972/*
Pavel Kotucek9e6ed6e2016-07-12 10:18:26 +02002973 * Generate boilerplate reply handlers, which
Ed Warnickecb9cada2015-12-08 15:45:58 -07002974 * dig the return value out of the xxx_reply_t API message,
2975 * stick it into vam->retval, and set vam->result_ready
2976 *
2977 * Could also do this by pointing N message decode slots at
2978 * a single function, but that could break in subtle ways.
2979 */
2980
2981#define foreach_standard_reply_retval_handler \
2982_(sw_interface_set_flags_reply) \
2983_(sw_interface_add_del_address_reply) \
2984_(sw_interface_set_table_reply) \
2985_(sw_interface_set_vpath_reply) \
2986_(sw_interface_set_l2_bridge_reply) \
2987_(bridge_domain_add_del_reply) \
2988_(sw_interface_set_l2_xconnect_reply) \
2989_(l2fib_add_del_reply) \
2990_(ip_add_del_route_reply) \
2991_(proxy_arp_add_del_reply) \
2992_(proxy_arp_intfc_enable_disable_reply) \
2993_(mpls_add_del_encap_reply) \
2994_(mpls_add_del_decap_reply) \
2995_(mpls_ethernet_add_del_tunnel_2_reply) \
2996_(sw_interface_set_unnumbered_reply) \
2997_(ip_neighbor_add_del_reply) \
2998_(reset_vrf_reply) \
2999_(oam_add_del_reply) \
3000_(reset_fib_reply) \
3001_(dhcp_proxy_config_reply) \
3002_(dhcp_proxy_config_2_reply) \
3003_(dhcp_proxy_set_vss_reply) \
3004_(dhcp_client_config_reply) \
3005_(set_ip_flow_hash_reply) \
3006_(sw_interface_ip6_enable_disable_reply) \
3007_(sw_interface_ip6_set_link_local_address_reply) \
3008_(sw_interface_ip6nd_ra_prefix_reply) \
3009_(sw_interface_ip6nd_ra_config_reply) \
3010_(set_arp_neighbor_limit_reply) \
3011_(l2_patch_add_del_reply) \
3012_(sr_tunnel_add_del_reply) \
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07003013_(sr_policy_add_del_reply) \
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07003014_(sr_multicast_map_add_del_reply) \
Ed Warnickecb9cada2015-12-08 15:45:58 -07003015_(classify_add_del_session_reply) \
3016_(classify_set_interface_ip_table_reply) \
3017_(classify_set_interface_l2_tables_reply) \
3018_(l2tpv3_set_tunnel_cookies_reply) \
3019_(l2tpv3_interface_enable_disable_reply) \
3020_(l2tpv3_set_lookup_key_reply) \
3021_(l2_fib_clear_table_reply) \
3022_(l2_interface_efp_filter_reply) \
3023_(l2_interface_vlan_tag_rewrite_reply) \
3024_(modify_vhost_user_if_reply) \
3025_(delete_vhost_user_if_reply) \
3026_(want_ip4_arp_events_reply) \
3027_(input_acl_set_interface_reply) \
3028_(ipsec_spd_add_del_reply) \
3029_(ipsec_interface_add_del_spd_reply) \
3030_(ipsec_spd_add_del_entry_reply) \
3031_(ipsec_sad_add_del_entry_reply) \
3032_(ipsec_sa_set_key_reply) \
Matus Fabiane5f42fe2016-04-08 11:18:08 +02003033_(ikev2_profile_add_del_reply) \
3034_(ikev2_profile_set_auth_reply) \
3035_(ikev2_profile_set_id_reply) \
3036_(ikev2_profile_set_ts_reply) \
3037_(ikev2_set_local_key_reply) \
Ed Warnickecb9cada2015-12-08 15:45:58 -07003038_(delete_loopback_reply) \
3039_(bd_ip_mac_add_del_reply) \
3040_(map_del_domain_reply) \
3041_(map_add_del_rule_reply) \
3042_(want_interface_events_reply) \
Dave Barachc07bf5d2016-02-17 17:52:26 -05003043_(want_stats_reply) \
3044_(cop_interface_enable_disable_reply) \
Pavel Kotucek00bbf272016-03-03 13:27:11 +01003045_(cop_whitelist_enable_disable_reply) \
Shwetha20a64f52016-03-25 10:55:01 +00003046_(sw_interface_clear_stats_reply) \
3047_(trace_profile_add_reply) \
3048_(trace_profile_apply_reply) \
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02003049_(trace_profile_del_reply) \
3050_(lisp_add_del_locator_set_reply) \
3051_(lisp_add_del_locator_reply) \
3052_(lisp_add_del_local_eid_reply) \
Florin Corasf727db92016-06-23 15:01:58 +02003053_(lisp_add_del_remote_mapping_reply) \
3054_(lisp_add_del_adjacency_reply) \
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02003055_(lisp_gpe_add_del_fwd_entry_reply) \
3056_(lisp_add_del_map_resolver_reply) \
Florin Coras577c3552016-04-21 00:45:40 +02003057_(lisp_gpe_enable_disable_reply) \
Matus Fabian8a95a482016-05-06 15:14:13 +02003058_(lisp_gpe_add_del_iface_reply) \
Filip Tehlar46d4e362016-05-09 09:39:26 +02003059_(lisp_enable_disable_reply) \
Filip Tehlar53f09e32016-05-19 14:25:44 +02003060_(lisp_pitr_set_locator_set_reply) \
Andrej Kozemcakb6e4d392016-06-14 13:55:57 +02003061_(lisp_add_del_map_request_itr_rlocs_reply) \
Filip Tehlar324112f2016-06-02 16:07:38 +02003062_(lisp_eid_table_add_del_map_reply) \
Dave Barach6f9bca22016-04-30 10:25:32 -04003063_(vxlan_gpe_add_del_tunnel_reply) \
Matus Fabian65fcd4d2016-05-13 05:44:48 -07003064_(af_packet_delete_reply) \
Matus Fabian70e6a8d2016-06-20 08:10:42 -07003065_(policer_classify_set_interface_reply) \
Matus Fabian82e29c42016-05-11 04:49:46 -07003066_(netmap_create_reply) \
Juraj Slobodaac645ad2016-07-07 00:18:57 -07003067_(netmap_delete_reply) \
Pavel Kotucek9e6ed6e2016-07-12 10:18:26 +02003068_(ipfix_enable_reply) \
3069_(pg_capture_reply) \
Dave Barach6f9bca22016-04-30 10:25:32 -04003070_(pg_enable_disable_reply) \
3071_(ip_source_and_port_range_check_add_del_reply) \
3072_(ip_source_and_port_range_check_interface_add_del_reply)
Ed Warnickecb9cada2015-12-08 15:45:58 -07003073
3074#define _(n) \
3075 static void vl_api_##n##_t_handler \
3076 (vl_api_##n##_t * mp) \
3077 { \
3078 vat_main_t * vam = &vat_main; \
3079 i32 retval = ntohl(mp->retval); \
3080 if (vam->async_mode) { \
3081 vam->async_errors += (retval < 0); \
3082 } else { \
3083 vam->retval = retval; \
3084 vam->result_ready = 1; \
3085 } \
3086 }
3087foreach_standard_reply_retval_handler;
3088#undef _
3089
3090#define _(n) \
3091 static void vl_api_##n##_t_handler_json \
3092 (vl_api_##n##_t * mp) \
3093 { \
3094 vat_main_t * vam = &vat_main; \
3095 vat_json_node_t node; \
3096 vat_json_init_object(&node); \
3097 vat_json_object_add_int(&node, "retval", ntohl(mp->retval)); \
3098 vat_json_print(vam->ofp, &node); \
3099 vam->retval = ntohl(mp->retval); \
3100 vam->result_ready = 1; \
3101 }
3102foreach_standard_reply_retval_handler;
3103#undef _
3104
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08003105/*
Ed Warnickecb9cada2015-12-08 15:45:58 -07003106 * Table of message reply handlers, must include boilerplate handlers
3107 * we just generated
3108 */
3109
3110#define foreach_vpe_api_reply_msg \
3111_(CREATE_LOOPBACK_REPLY, create_loopback_reply) \
3112_(SW_INTERFACE_DETAILS, sw_interface_details) \
3113_(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags) \
3114_(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply) \
3115_(CONTROL_PING_REPLY, control_ping_reply) \
Andrej Kozemcakd9831182016-06-20 08:47:57 +02003116_(NOPRINT_CONTROL_PING_REPLY, noprint_control_ping_reply) \
Ed Warnickecb9cada2015-12-08 15:45:58 -07003117_(CLI_REPLY, cli_reply) \
3118_(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY, \
3119 sw_interface_add_del_address_reply) \
3120_(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply) \
3121_(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply) \
3122_(SW_INTERFACE_SET_L2_XCONNECT_REPLY, \
3123 sw_interface_set_l2_xconnect_reply) \
3124_(SW_INTERFACE_SET_L2_BRIDGE_REPLY, \
3125 sw_interface_set_l2_bridge_reply) \
3126_(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply) \
3127_(BRIDGE_DOMAIN_DETAILS, bridge_domain_details) \
3128_(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details) \
3129_(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply) \
3130_(L2_FLAGS_REPLY, l2_flags_reply) \
3131_(BRIDGE_FLAGS_REPLY, bridge_flags_reply) \
3132_(TAP_CONNECT_REPLY, tap_connect_reply) \
3133_(TAP_MODIFY_REPLY, tap_modify_reply) \
3134_(TAP_DELETE_REPLY, tap_delete_reply) \
3135_(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details) \
3136_(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply) \
3137_(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply) \
3138_(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY, \
3139 proxy_arp_intfc_enable_disable_reply) \
3140_(MPLS_ADD_DEL_ENCAP_REPLY, mpls_add_del_encap_reply) \
3141_(MPLS_ADD_DEL_DECAP_REPLY, mpls_add_del_decap_reply) \
3142_(MPLS_GRE_ADD_DEL_TUNNEL_REPLY, mpls_gre_add_del_tunnel_reply) \
3143_(MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY, \
3144 mpls_ethernet_add_del_tunnel_reply) \
3145_(MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY, \
3146 mpls_ethernet_add_del_tunnel_2_reply) \
3147_(SW_INTERFACE_SET_UNNUMBERED_REPLY, \
3148 sw_interface_set_unnumbered_reply) \
3149_(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply) \
3150_(RESET_VRF_REPLY, reset_vrf_reply) \
3151_(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply) \
3152_(CREATE_SUBIF_REPLY, create_subif_reply) \
3153_(OAM_ADD_DEL_REPLY, oam_add_del_reply) \
3154_(RESET_FIB_REPLY, reset_fib_reply) \
3155_(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply) \
3156_(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply) \
3157_(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply) \
3158_(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply) \
3159_(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply) \
3160_(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY, \
3161 sw_interface_ip6_enable_disable_reply) \
3162_(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY, \
3163 sw_interface_ip6_set_link_local_address_reply) \
3164_(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY, \
3165 sw_interface_ip6nd_ra_prefix_reply) \
3166_(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY, \
3167 sw_interface_ip6nd_ra_config_reply) \
3168_(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply) \
3169_(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply) \
3170_(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply) \
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07003171_(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply) \
3172_(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply) \
Ed Warnickecb9cada2015-12-08 15:45:58 -07003173_(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply) \
3174_(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply) \
3175_(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY, \
3176classify_set_interface_ip_table_reply) \
3177_(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY, \
3178 classify_set_interface_l2_tables_reply) \
3179_(GET_NODE_INDEX_REPLY, get_node_index_reply) \
3180_(ADD_NODE_NEXT_REPLY, add_node_next_reply) \
3181_(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply) \
3182_(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply) \
3183_(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY, \
3184 l2tpv3_interface_enable_disable_reply) \
3185_(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply) \
3186_(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details) \
3187_(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply) \
Dave Wallace60231f32015-12-17 21:04:30 -05003188_(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details) \
Chris Luke27fe48f2016-04-28 13:44:38 -04003189_(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply) \
3190_(GRE_TUNNEL_DETAILS, gre_tunnel_details) \
Ed Warnickecb9cada2015-12-08 15:45:58 -07003191_(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply) \
3192_(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply) \
3193_(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3194_(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details) \
3195_(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply) \
3196_(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply) \
3197_(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply) \
3198_(SHOW_VERSION_REPLY, show_version_reply) \
Ed Warnickecb9cada2015-12-08 15:45:58 -07003199_(L2_FIB_TABLE_ENTRY, l2_fib_table_entry) \
Hongjun Ni0e06e2b2016-05-30 19:45:51 +08003200_(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply) \
3201_(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details) \
Ed Warnickecb9cada2015-12-08 15:45:58 -07003202_(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply) \
3203_(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply) \
3204_(IP4_ARP_EVENT, ip4_arp_event) \
3205_(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply) \
3206_(IP_ADDRESS_DETAILS, ip_address_details) \
3207_(IP_DETAILS, ip_details) \
3208_(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply) \
3209_(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3210_(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply) \
3211_(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply) \
3212_(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply) \
Matus Fabiane5f42fe2016-04-08 11:18:08 +02003213_(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply) \
3214_(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply) \
3215_(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply) \
3216_(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply) \
3217_(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply) \
Ed Warnickecb9cada2015-12-08 15:45:58 -07003218_(DELETE_LOOPBACK_REPLY, delete_loopback_reply) \
3219_(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply) \
3220_(DHCP_COMPL_EVENT, dhcp_compl_event) \
3221_(VNET_INTERFACE_COUNTERS, vnet_interface_counters) \
3222_(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters) \
3223_(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters) \
3224_(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply) \
3225_(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply) \
Dave Barachc07bf5d2016-02-17 17:52:26 -05003226_(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply) \
Ed Warnickecb9cada2015-12-08 15:45:58 -07003227_(MAP_DOMAIN_DETAILS, map_domain_details) \
3228_(MAP_RULE_DETAILS, map_rule_details) \
3229_(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply) \
3230_(WANT_STATS_REPLY, want_stats_reply) \
Dave Barachc07bf5d2016-02-17 17:52:26 -05003231_(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply) \
3232_(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
Dave Barachb44e9bc2016-02-19 09:06:23 -05003233_(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
Pavel Kotucek00bbf272016-03-03 13:27:11 +01003234_(GET_NODE_GRAPH_REPLY, get_node_graph_reply) \
Shwetha20a64f52016-03-25 10:55:01 +00003235_(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply) \
3236_(TRACE_PROFILE_ADD_REPLY, trace_profile_add_reply) \
3237_(TRACE_PROFILE_APPLY_REPLY, trace_profile_apply_reply) \
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02003238_(TRACE_PROFILE_DEL_REPLY, trace_profile_del_reply) \
3239_(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply) \
3240_(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply) \
3241_(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply) \
Florin Corasf727db92016-06-23 15:01:58 +02003242_(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3243_(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply) \
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02003244_(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply) \
3245_(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply) \
Florin Coras577c3552016-04-21 00:45:40 +02003246_(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply) \
Filip Tehlar46d4e362016-05-09 09:39:26 +02003247_(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply) \
Filip Tehlar53f09e32016-05-19 14:25:44 +02003248_(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply) \
Filip Tehlar324112f2016-06-02 16:07:38 +02003249_(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply) \
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02003250_(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply) \
3251_(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details) \
Andrej Kozemcakd9831182016-06-20 08:47:57 +02003252_(LISP_LOCATOR_DETAILS, lisp_locator_details) \
Andrej Kozemcak6cc6f912016-07-13 13:01:01 +02003253_(LISP_EID_TABLE_DETAILS, lisp_eid_table_details) \
Filip Tehlar2f653d02016-07-13 13:17:15 +02003254_(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details) \
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02003255_(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details) \
Andrej Kozemcaka9edd852016-05-02 12:14:33 +02003256_(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details) \
Andrej Kozemcakd9831182016-06-20 08:47:57 +02003257_(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply) \
Andrej Kozemcakb6e4d392016-06-14 13:55:57 +02003258_(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY, \
3259 lisp_add_del_map_request_itr_rlocs_reply) \
3260_(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY, \
3261 lisp_get_map_request_itr_rlocs_reply) \
Andrej Kozemcak914f91b2016-07-18 13:55:37 +02003262_(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply) \
Matus Fabian8a95a482016-05-06 15:14:13 +02003263_(AF_PACKET_CREATE_REPLY, af_packet_create_reply) \
Matus Fabian65fcd4d2016-05-13 05:44:48 -07003264_(AF_PACKET_DELETE_REPLY, af_packet_delete_reply) \
Matus Fabian82e29c42016-05-11 04:49:46 -07003265_(POLICER_ADD_DEL_REPLY, policer_add_del_reply) \
Matus Fabiane8554802016-05-18 23:40:37 -07003266_(POLICER_DETAILS, policer_details) \
Matus Fabian70e6a8d2016-06-20 08:10:42 -07003267_(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3268_(POLICER_CLASSIFY_DETAILS, policer_classify_details) \
Matus Fabian82e29c42016-05-11 04:49:46 -07003269_(NETMAP_CREATE_REPLY, netmap_create_reply) \
marek zavodsky2c21a9a2016-06-21 05:35:16 +02003270_(NETMAP_DELETE_REPLY, netmap_delete_reply) \
3271_(MPLS_GRE_TUNNEL_DETAILS, mpls_gre_tunnel_details) \
3272_(MPLS_ETH_TUNNEL_DETAILS, mpls_eth_tunnel_details) \
3273_(MPLS_FIB_ENCAP_DETAILS, mpls_fib_encap_details) \
Pavel Kotucek20c90f72016-06-07 14:44:26 +02003274_(MPLS_FIB_DECAP_DETAILS, mpls_fib_decap_details) \
3275_(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply) \
3276_(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3277_(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply) \
Juraj Slobodaac645ad2016-07-07 00:18:57 -07003278_(CLASSIFY_SESSION_DETAILS, classify_session_details) \
3279_(IPFIX_ENABLE_REPLY, ipfix_enable_reply) \
Keith Burns (alagalah)c61080e2016-07-19 14:47:43 -07003280_(IPFIX_DETAILS, ipfix_details) \
Pavel Kotucek9e6ed6e2016-07-12 10:18:26 +02003281_(GET_NEXT_INDEX_REPLY, get_next_index_reply) \
3282_(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply) \
3283_(PG_CAPTURE_REPLY, pg_capture_reply) \
Dave Barach6f9bca22016-04-30 10:25:32 -04003284_(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply) \
3285_(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY, \
3286 ip_source_and_port_range_check_add_del_reply) \
3287_(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY, \
3288 ip_source_and_port_range_check_interface_add_del_reply)
Ed Warnickecb9cada2015-12-08 15:45:58 -07003289
3290/* M: construct, but don't yet send a message */
3291
3292#define M(T,t) \
3293do { \
3294 vam->result_ready = 0; \
3295 mp = vl_msg_api_alloc(sizeof(*mp)); \
3296 memset (mp, 0, sizeof (*mp)); \
3297 mp->_vl_msg_id = ntohs (VL_API_##T); \
3298 mp->client_index = vam->my_client_index; \
3299} while(0);
3300
3301#define M2(T,t,n) \
3302do { \
3303 vam->result_ready = 0; \
3304 mp = vl_msg_api_alloc(sizeof(*mp)+(n)); \
3305 memset (mp, 0, sizeof (*mp)); \
3306 mp->_vl_msg_id = ntohs (VL_API_##T); \
3307 mp->client_index = vam->my_client_index; \
3308} while(0);
3309
3310
3311/* S: send a message */
3312#define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3313
3314/* W: wait for results, with timeout */
3315#define W \
3316do { \
3317 timeout = vat_time_now (vam) + 1.0; \
3318 \
3319 while (vat_time_now (vam) < timeout) { \
3320 if (vam->result_ready == 1) { \
3321 return (vam->retval); \
3322 } \
3323 } \
3324 return -99; \
3325} while(0);
3326
Keith Burns (alagalah)802255c2016-06-13 16:56:04 -07003327/* W2: wait for results, with timeout */
3328#define W2(body) \
3329do { \
3330 timeout = vat_time_now (vam) + 1.0; \
3331 \
3332 while (vat_time_now (vam) < timeout) { \
3333 if (vam->result_ready == 1) { \
3334 (body); \
3335 return (vam->retval); \
3336 } \
3337 } \
3338 return -99; \
3339} while(0);
3340
Andrej Kozemcakd9831182016-06-20 08:47:57 +02003341/* W_L: wait for results, with timeout */
3342#define W_L(body) \
3343do { \
3344 timeout = vat_time_now (vam) + 1.0; \
3345 \
3346 while (vat_time_now (vam) < timeout) { \
3347 if (vam->result_ready == 1) { \
3348 (body); \
3349 return (vam->retval); \
3350 } \
3351 } \
3352 vam->noprint_msg = 0; \
3353 return -99; \
3354} while(0);
3355
Ed Warnickecb9cada2015-12-08 15:45:58 -07003356typedef struct {
3357 u8 * name;
3358 u32 value;
3359} name_sort_t;
3360
3361
3362#define STR_VTR_OP_CASE(op) \
3363 case L2_VTR_ ## op: \
3364 return "" # op;
3365
3366static const char *str_vtr_op(u32 vtr_op)
3367{
3368 switch(vtr_op) {
3369 STR_VTR_OP_CASE(DISABLED);
3370 STR_VTR_OP_CASE(PUSH_1);
3371 STR_VTR_OP_CASE(PUSH_2);
3372 STR_VTR_OP_CASE(POP_1);
3373 STR_VTR_OP_CASE(POP_2);
3374 STR_VTR_OP_CASE(TRANSLATE_1_1);
3375 STR_VTR_OP_CASE(TRANSLATE_1_2);
3376 STR_VTR_OP_CASE(TRANSLATE_2_1);
3377 STR_VTR_OP_CASE(TRANSLATE_2_2);
3378 }
3379
3380 return "UNKNOWN";
3381}
3382
3383static int dump_sub_interface_table (vat_main_t * vam)
3384{
3385 const sw_interface_subif_t * sub = NULL;
3386
3387 if (vam->json_output) {
3388 clib_warning ("JSON output supported only for VPE API calls and dump_stats_table");
3389 return -99;
3390 }
3391
3392 fformat (vam->ofp,
3393 "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
3394 "Interface", "sw_if_index",
3395 "sub id", "dot1ad", "tags", "outer id",
3396 "inner id", "exact", "default",
3397 "outer any", "inner any");
3398
3399 vec_foreach (sub, vam->sw_if_subif_table) {
3400 fformat (vam->ofp,
3401 "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
3402 sub->interface_name,
3403 sub->sw_if_index,
3404 sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3405 sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3406 sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3407 sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3408 if (sub->vtr_op != L2_VTR_DISABLED) {
3409 fformat (vam->ofp,
3410 " vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3411 "tag1: %d tag2: %d ]\n",
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08003412 str_vtr_op(sub->vtr_op), sub->vtr_push_dot1q,
Ed Warnickecb9cada2015-12-08 15:45:58 -07003413 sub->vtr_tag1, sub->vtr_tag2);
3414 }
3415 }
3416
3417 return 0;
3418}
3419
Matus Fabiand2dc3df2015-12-14 10:31:33 -05003420static int name_sort_cmp (void * a1, void * a2)
3421{
3422 name_sort_t * n1 = a1;
3423 name_sort_t * n2 = a2;
3424
3425 return strcmp ((char *)n1->name, (char *)n2->name);
3426}
3427
Ed Warnickecb9cada2015-12-08 15:45:58 -07003428static int dump_interface_table (vat_main_t * vam)
3429{
3430 hash_pair_t * p;
3431 name_sort_t * nses = 0, * ns;
3432
3433 if (vam->json_output) {
3434 clib_warning ("JSON output supported only for VPE API calls and dump_stats_table");
3435 return -99;
3436 }
3437
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08003438 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
Ed Warnickecb9cada2015-12-08 15:45:58 -07003439 ({
3440 vec_add2 (nses, ns, 1);
3441 ns->name = (u8 *)(p->key);
3442 ns->value = (u32) p->value[0];
3443 }));
3444
Matus Fabiand2dc3df2015-12-14 10:31:33 -05003445 vec_sort_with_function (nses, name_sort_cmp);
Ed Warnickecb9cada2015-12-08 15:45:58 -07003446
3447 fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
3448 vec_foreach (ns, nses) {
3449 fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
3450 }
3451 vec_free (nses);
3452 return 0;
3453}
3454
3455static int dump_ip_table (vat_main_t * vam, int is_ipv6)
3456{
3457 const ip_details_t * det = NULL;
3458 const ip_address_details_t * address = NULL;
3459 u32 i = ~0;
3460
3461 fformat (vam->ofp,
3462 "%-12s\n",
3463 "sw_if_index");
3464
Damjan Marionfa693552016-04-26 19:30:36 +02003465 if (0 == vam) {
Ed Warnickecb9cada2015-12-08 15:45:58 -07003466 return 0;
3467 }
3468
3469 vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6]) {
3470 i++;
3471 if (!det->present) {
3472 continue;
3473 }
3474 fformat (vam->ofp,
3475 "%-12d\n",
3476 i);
3477 fformat (vam->ofp,
3478 " %-30s%-13s\n",
3479 "Address", "Prefix length");
3480 if (!det->addr) {
3481 continue;
3482 }
3483 vec_foreach (address, det->addr) {
3484 fformat (vam->ofp,
3485 " %-30U%-13d\n",
3486 is_ipv6 ? format_ip6_address : format_ip4_address,
3487 address->ip,
3488 address->prefix_length);
3489 }
3490 }
3491
3492 return 0;
3493}
3494
3495static int dump_ipv4_table (vat_main_t * vam)
3496{
3497 if (vam->json_output) {
3498 clib_warning ("JSON output supported only for VPE API calls and dump_stats_table");
3499 return -99;
3500 }
3501
3502 return dump_ip_table (vam, 0);
3503}
3504
3505static int dump_ipv6_table (vat_main_t * vam)
3506{
3507 if (vam->json_output) {
3508 clib_warning ("JSON output supported only for VPE API calls and dump_stats_table");
3509 return -99;
3510 }
3511
3512 return dump_ip_table (vam, 1);
3513}
3514
3515static char* counter_type_to_str (u8 counter_type, u8 is_combined)
3516{
3517 if (!is_combined) {
3518 switch(counter_type) {
3519 case VNET_INTERFACE_COUNTER_DROP:
3520 return "drop";
3521 case VNET_INTERFACE_COUNTER_PUNT:
3522 return "punt";
3523 case VNET_INTERFACE_COUNTER_IP4:
3524 return "ip4";
3525 case VNET_INTERFACE_COUNTER_IP6:
3526 return "ip6";
3527 case VNET_INTERFACE_COUNTER_RX_NO_BUF:
3528 return "rx-no-buf";
3529 case VNET_INTERFACE_COUNTER_RX_MISS:
3530 return "rx-miss";
3531 case VNET_INTERFACE_COUNTER_RX_ERROR:
3532 return "rx-error";
3533 case VNET_INTERFACE_COUNTER_TX_ERROR:
3534 return "tx-error";
3535 default:
3536 return "INVALID-COUNTER-TYPE";
3537 }
3538 } else {
3539 switch(counter_type) {
3540 case VNET_INTERFACE_COUNTER_RX:
3541 return "rx";
3542 case VNET_INTERFACE_COUNTER_TX:
3543 return "tx";
3544 default:
3545 return "INVALID-COUNTER-TYPE";
3546 }
3547 }
3548}
3549
3550static int dump_stats_table (vat_main_t * vam)
3551{
3552 vat_json_node_t node;
3553 vat_json_node_t *msg_array;
3554 vat_json_node_t *msg;
3555 vat_json_node_t *counter_array;
3556 vat_json_node_t *counter;
3557 interface_counter_t c;
3558 u64 packets;
3559 ip4_fib_counter_t *c4;
3560 ip6_fib_counter_t *c6;
3561 int i, j;
3562
3563 if (!vam->json_output) {
3564 clib_warning ("dump_stats_table supported only in JSON format");
3565 return -99;
3566 }
3567
3568 vat_json_init_object(&node);
3569
3570 /* interface counters */
3571 msg_array = vat_json_object_add(&node, "interface_counters");
3572 vat_json_init_array(msg_array);
3573 for (i = 0; i < vec_len(vam->simple_interface_counters); i++) {
3574 msg = vat_json_array_add(msg_array);
3575 vat_json_init_object(msg);
3576 vat_json_object_add_string_copy(msg, "vnet_counter_type",
3577 (u8*)counter_type_to_str(i, 0));
3578 vat_json_object_add_int(msg, "is_combined", 0);
3579 counter_array = vat_json_object_add(msg, "data");
3580 vat_json_init_array(counter_array);
3581 for (j = 0; j < vec_len(vam->simple_interface_counters[i]); j++) {
3582 packets = vam->simple_interface_counters[i][j];
3583 vat_json_array_add_uint(counter_array, packets);
3584 }
3585 }
3586 for (i = 0; i < vec_len(vam->combined_interface_counters); i++) {
3587 msg = vat_json_array_add(msg_array);
3588 vat_json_init_object(msg);
3589 vat_json_object_add_string_copy(msg, "vnet_counter_type",
3590 (u8*)counter_type_to_str(i, 1));
3591 vat_json_object_add_int(msg, "is_combined", 1);
3592 counter_array = vat_json_object_add(msg, "data");
3593 vat_json_init_array(counter_array);
3594 for (j = 0; j < vec_len(vam->combined_interface_counters[i]); j++) {
3595 c = vam->combined_interface_counters[i][j];
3596 counter = vat_json_array_add(counter_array);
3597 vat_json_init_object(counter);
3598 vat_json_object_add_uint(counter, "packets", c.packets);
3599 vat_json_object_add_uint(counter, "bytes", c.bytes);
3600 }
3601 }
3602
3603 /* ip4 fib counters */
3604 msg_array = vat_json_object_add(&node, "ip4_fib_counters");
3605 vat_json_init_array(msg_array);
3606 for (i = 0; i < vec_len(vam->ip4_fib_counters); i++) {
3607 msg = vat_json_array_add(msg_array);
3608 vat_json_init_object(msg);
3609 vat_json_object_add_uint(msg, "vrf_id", vam->ip4_fib_counters_vrf_id_by_index[i]);
3610 counter_array = vat_json_object_add(msg, "c");
3611 vat_json_init_array(counter_array);
3612 for (j = 0; j < vec_len(vam->ip4_fib_counters[i]); j++) {
3613 counter = vat_json_array_add(counter_array);
3614 vat_json_init_object(counter);
3615 c4 = &vam->ip4_fib_counters[i][j];
3616 vat_json_object_add_ip4(counter, "address", c4->address);
3617 vat_json_object_add_uint(counter, "address_length", c4->address_length);
3618 vat_json_object_add_uint(counter, "packets", c4->packets);
3619 vat_json_object_add_uint(counter, "bytes", c4->bytes);
3620 }
3621 }
3622
3623 /* ip6 fib counters */
3624 msg_array = vat_json_object_add(&node, "ip6_fib_counters");
3625 vat_json_init_array(msg_array);
3626 for (i = 0; i < vec_len(vam->ip6_fib_counters); i++) {
3627 msg = vat_json_array_add(msg_array);
3628 vat_json_init_object(msg);
3629 vat_json_object_add_uint(msg, "vrf_id", vam->ip6_fib_counters_vrf_id_by_index[i]);
3630 counter_array = vat_json_object_add(msg, "c");
3631 vat_json_init_array(counter_array);
3632 for (j = 0; j < vec_len(vam->ip6_fib_counters[i]); j++) {
3633 counter = vat_json_array_add(counter_array);
3634 vat_json_init_object(counter);
3635 c6 = &vam->ip6_fib_counters[i][j];
3636 vat_json_object_add_ip6(counter, "address", c6->address);
3637 vat_json_object_add_uint(counter, "address_length", c6->address_length);
3638 vat_json_object_add_uint(counter, "packets", c6->packets);
3639 vat_json_object_add_uint(counter, "bytes", c6->bytes);
3640 }
3641 }
3642
3643 vat_json_print(vam->ofp, &node);
3644 vat_json_free(&node);
3645
3646 return 0;
3647}
3648
3649int exec (vat_main_t * vam)
3650{
3651 api_main_t * am = &api_main;
3652 vl_api_cli_request_t *mp;
3653 f64 timeout;
3654 void * oldheap;
3655 u8 * cmd = 0;
3656 unformat_input_t * i = vam->input;
3657
3658 if (vec_len(i->buffer) == 0)
3659 return -1;
3660
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08003661 if (vam->exec_mode == 0 && unformat (i, "mode")) {
Ed Warnickecb9cada2015-12-08 15:45:58 -07003662 vam->exec_mode = 1;
3663 return 0;
3664 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08003665 if (vam->exec_mode == 1 &&
Ed Warnickecb9cada2015-12-08 15:45:58 -07003666 (unformat (i, "exit") || unformat (i, "quit"))) {
3667 vam->exec_mode = 0;
3668 return 0;
3669 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08003670
Ed Warnickecb9cada2015-12-08 15:45:58 -07003671
3672 M(CLI_REQUEST, cli_request);
3673
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08003674 /*
Ed Warnickecb9cada2015-12-08 15:45:58 -07003675 * Copy cmd into shared memory.
3676 * In order for the CLI command to work, it
3677 * must be a vector ending in \n, not a C-string ending
3678 * in \n\0.
3679 */
3680 pthread_mutex_lock (&am->vlib_rp->mutex);
3681 oldheap = svm_push_data_heap (am->vlib_rp);
3682
3683 vec_validate (cmd, vec_len(vam->input->buffer)-1);
Damjan Marionf1213b82016-03-13 02:22:06 +01003684 clib_memcpy (cmd, vam->input->buffer, vec_len(vam->input->buffer));
Ed Warnickecb9cada2015-12-08 15:45:58 -07003685
3686 svm_pop_heap (oldheap);
3687 pthread_mutex_unlock (&am->vlib_rp->mutex);
3688
3689 mp->cmd_in_shmem = (u64) cmd;
3690 S;
3691 timeout = vat_time_now (vam) + 10.0;
3692
3693 while (vat_time_now (vam) < timeout) {
3694 if (vam->result_ready == 1) {
3695 u8 * free_me;
Pavel Kotucek060c6fc2016-02-24 15:52:42 +01003696 if (vam->shmem_result != NULL)
3697 fformat (vam->ofp, "%s", vam->shmem_result);
Ed Warnickecb9cada2015-12-08 15:45:58 -07003698 pthread_mutex_lock (&am->vlib_rp->mutex);
3699 oldheap = svm_push_data_heap (am->vlib_rp);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08003700
Ed Warnickecb9cada2015-12-08 15:45:58 -07003701 free_me = (u8 *)vam->shmem_result;
3702 vec_free (free_me);
3703
3704 svm_pop_heap (oldheap);
3705 pthread_mutex_unlock (&am->vlib_rp->mutex);
3706 return 0;
3707 }
3708 }
3709 return -99;
3710}
3711
3712static int api_create_loopback (vat_main_t * vam)
3713{
3714 unformat_input_t * i = vam->input;
3715 vl_api_create_loopback_t *mp;
3716 f64 timeout;
3717 u8 mac_address[6];
3718 u8 mac_set = 0;
3719
3720 memset (mac_address, 0, sizeof (mac_address));
3721
3722 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3723 {
3724 if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
3725 mac_set = 1;
3726 else
3727 break;
3728 }
3729
3730 /* Construct the API message */
3731 M(CREATE_LOOPBACK, create_loopback);
3732 if (mac_set)
Damjan Marionf1213b82016-03-13 02:22:06 +01003733 clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07003734
3735 S; W;
3736}
3737
3738static int api_delete_loopback (vat_main_t * vam)
3739{
3740 unformat_input_t * i = vam->input;
3741 vl_api_delete_loopback_t *mp;
3742 f64 timeout;
3743 u32 sw_if_index = ~0;
3744
3745 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3746 {
3747 if (unformat (i, "sw_if_index %d", &sw_if_index))
3748 ;
3749 else
3750 break;
3751 }
3752
3753 if (sw_if_index == ~0)
3754 {
3755 errmsg ("missing sw_if_index\n");
3756 return -99;
3757 }
3758
3759 /* Construct the API message */
3760 M(DELETE_LOOPBACK, delete_loopback);
3761 mp->sw_if_index = ntohl (sw_if_index);
3762
3763 S; W;
3764}
3765
3766static int api_want_stats (vat_main_t * vam)
3767{
3768 unformat_input_t * i = vam->input;
3769 vl_api_want_stats_t * mp;
3770 f64 timeout;
3771 int enable = -1;
3772
3773 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3774 {
3775 if (unformat (i, "enable"))
3776 enable = 1;
3777 else if (unformat (i, "disable"))
3778 enable = 0;
3779 else
3780 break;
3781 }
3782
3783 if (enable == -1)
3784 {
3785 errmsg ("missing enable|disable\n");
3786 return -99;
3787 }
3788
3789 M(WANT_STATS, want_stats);
3790 mp->enable_disable = enable;
3791
3792 S; W;
3793}
3794
3795static int api_want_interface_events (vat_main_t * vam)
3796{
3797 unformat_input_t * i = vam->input;
3798 vl_api_want_interface_events_t * mp;
3799 f64 timeout;
3800 int enable = -1;
3801
3802 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3803 {
3804 if (unformat (i, "enable"))
3805 enable = 1;
3806 else if (unformat (i, "disable"))
3807 enable = 0;
3808 else
3809 break;
3810 }
3811
3812 if (enable == -1)
3813 {
3814 errmsg ("missing enable|disable\n");
3815 return -99;
3816 }
3817
3818 M(WANT_INTERFACE_EVENTS, want_interface_events);
3819 mp->enable_disable = enable;
3820
3821 vam->interface_event_display = enable;
3822
3823 S; W;
3824}
3825
3826
3827/* Note: non-static, called once to set up the initial intfc table */
3828int api_sw_interface_dump (vat_main_t * vam)
3829{
3830 vl_api_sw_interface_dump_t *mp;
3831 f64 timeout;
3832 hash_pair_t * p;
3833 name_sort_t * nses = 0, * ns;
3834 sw_interface_subif_t * sub = NULL;
3835
3836 /* Toss the old name table */
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08003837 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
Ed Warnickecb9cada2015-12-08 15:45:58 -07003838 ({
3839 vec_add2 (nses, ns, 1);
3840 ns->name = (u8 *)(p->key);
3841 ns->value = (u32) p->value[0];
3842 }));
3843
3844 hash_free (vam->sw_if_index_by_interface_name);
3845
3846 vec_foreach (ns, nses)
3847 vec_free (ns->name);
3848
3849 vec_free (nses);
3850
3851 vec_foreach (sub, vam->sw_if_subif_table) {
3852 vec_free (sub->interface_name);
3853 }
3854 vec_free (vam->sw_if_subif_table);
3855
3856 /* recreate the interface name hash table */
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08003857 vam->sw_if_index_by_interface_name
Ed Warnickecb9cada2015-12-08 15:45:58 -07003858 = hash_create_string (0, sizeof(uword));
3859
3860 /* Get list of ethernets */
3861 M(SW_INTERFACE_DUMP, sw_interface_dump);
3862 mp->name_filter_valid = 1;
Damjan Marionfa693552016-04-26 19:30:36 +02003863 strncpy ((char *) mp->name_filter, "Ether", sizeof(mp->name_filter)-1);
Ed Warnickecb9cada2015-12-08 15:45:58 -07003864 S;
3865
3866 /* and local / loopback interfaces */
3867 M(SW_INTERFACE_DUMP, sw_interface_dump);
3868 mp->name_filter_valid = 1;
Damjan Marionfa693552016-04-26 19:30:36 +02003869 strncpy ((char *) mp->name_filter, "lo", sizeof(mp->name_filter)-1);
Ed Warnickecb9cada2015-12-08 15:45:58 -07003870 S;
3871
Hongjun Nic4248792016-06-08 01:07:12 +08003872
3873 /* and vxlan-gpe tunnel interfaces */
3874 M(SW_INTERFACE_DUMP, sw_interface_dump);
3875 mp->name_filter_valid = 1;
3876 strncpy ((char *) mp->name_filter, "vxlan_gpe", sizeof(mp->name_filter)-1);
3877 S;
3878
Ed Warnickecb9cada2015-12-08 15:45:58 -07003879 /* and vxlan tunnel interfaces */
3880 M(SW_INTERFACE_DUMP, sw_interface_dump);
3881 mp->name_filter_valid = 1;
Damjan Marionfa693552016-04-26 19:30:36 +02003882 strncpy ((char *) mp->name_filter, "vxlan", sizeof(mp->name_filter)-1);
Ed Warnickecb9cada2015-12-08 15:45:58 -07003883 S;
3884
Damjan Marionb02e49c2016-03-31 17:44:25 +02003885 /* and host (af_packet) interfaces */
3886 M(SW_INTERFACE_DUMP, sw_interface_dump);
3887 mp->name_filter_valid = 1;
Damjan Marionfa693552016-04-26 19:30:36 +02003888 strncpy ((char *) mp->name_filter, "host", sizeof(mp->name_filter)-1);
Damjan Marionb02e49c2016-03-31 17:44:25 +02003889 S;
3890
Ed Warnickecb9cada2015-12-08 15:45:58 -07003891 /* and l2tpv3 tunnel interfaces */
3892 M(SW_INTERFACE_DUMP, sw_interface_dump);
3893 mp->name_filter_valid = 1;
Damjan Marionfa693552016-04-26 19:30:36 +02003894 strncpy ((char *) mp->name_filter, "l2tpv3_tunnel", sizeof(mp->name_filter)-1);
Ed Warnickecb9cada2015-12-08 15:45:58 -07003895 S;
3896
Chris Lukea6116ef2016-05-06 10:12:30 -04003897 /* and GRE tunnel interfaces */
3898 M(SW_INTERFACE_DUMP, sw_interface_dump);
3899 mp->name_filter_valid = 1;
3900 strncpy ((char *) mp->name_filter, "gre", sizeof(mp->name_filter)-1);
3901 S;
3902
Ed Warnickecb9cada2015-12-08 15:45:58 -07003903 /* Use a control ping for synchronization */
3904 {
3905 vl_api_control_ping_t * mp;
3906 M(CONTROL_PING, control_ping);
3907 S;
3908 }
3909 W;
3910}
3911
3912static int api_sw_interface_set_flags (vat_main_t * vam)
3913{
3914 unformat_input_t * i = vam->input;
3915 vl_api_sw_interface_set_flags_t *mp;
3916 f64 timeout;
3917 u32 sw_if_index;
3918 u8 sw_if_index_set = 0;
3919 u8 admin_up = 0, link_up = 0;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08003920
Ed Warnickecb9cada2015-12-08 15:45:58 -07003921 /* Parse args required to build the message */
3922 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3923 if (unformat (i, "admin-up"))
3924 admin_up = 1;
3925 else if (unformat (i, "admin-down"))
3926 admin_up = 0;
3927 else if (unformat (i, "link-up"))
3928 link_up = 1;
3929 else if (unformat (i, "link-down"))
3930 link_up = 0;
3931 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3932 sw_if_index_set = 1;
3933 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3934 sw_if_index_set = 1;
3935 else
3936 break;
3937 }
3938
3939 if (sw_if_index_set == 0) {
3940 errmsg ("missing interface name or sw_if_index\n");
3941 return -99;
3942 }
3943
3944 /* Construct the API message */
3945 M(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
3946 mp->sw_if_index = ntohl (sw_if_index);
3947 mp->admin_up_down = admin_up;
3948 mp->link_up_down = link_up;
3949
3950 /* send it... */
3951 S;
3952
3953 /* Wait for a reply, return the good/bad news... */
3954 W;
3955}
3956
Pavel Kotucek00bbf272016-03-03 13:27:11 +01003957static int api_sw_interface_clear_stats (vat_main_t * vam)
3958{
3959 unformat_input_t * i = vam->input;
3960 vl_api_sw_interface_clear_stats_t *mp;
3961 f64 timeout;
3962 u32 sw_if_index;
3963 u8 sw_if_index_set = 0;
3964
3965 /* Parse args required to build the message */
3966 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3967 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3968 sw_if_index_set = 1;
3969 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3970 sw_if_index_set = 1;
3971 else
3972 break;
3973 }
3974
3975 /* Construct the API message */
3976 M(SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
3977
3978 if (sw_if_index_set == 1)
3979 mp->sw_if_index = ntohl (sw_if_index);
3980 else
3981 mp->sw_if_index = ~0;
3982
3983 /* send it... */
3984 S;
3985
3986 /* Wait for a reply, return the good/bad news... */
3987 W;
3988}
3989
Ed Warnickecb9cada2015-12-08 15:45:58 -07003990static int api_sw_interface_add_del_address (vat_main_t * vam)
3991{
3992 unformat_input_t * i = vam->input;
3993 vl_api_sw_interface_add_del_address_t *mp;
3994 f64 timeout;
3995 u32 sw_if_index;
3996 u8 sw_if_index_set = 0;
3997 u8 is_add = 1, del_all = 0;
3998 u32 address_length = 0;
3999 u8 v4_address_set = 0;
4000 u8 v6_address_set = 0;
4001 ip4_address_t v4address;
4002 ip6_address_t v6address;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004003
Ed Warnickecb9cada2015-12-08 15:45:58 -07004004 /* Parse args required to build the message */
4005 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4006 if (unformat (i, "del-all"))
4007 del_all = 1;
4008 else if (unformat (i, "del"))
4009 is_add = 0;
4010 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4011 sw_if_index_set = 1;
4012 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4013 sw_if_index_set = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004014 else if (unformat (i, "%U/%d",
4015 unformat_ip4_address, &v4address,
Ed Warnickecb9cada2015-12-08 15:45:58 -07004016 &address_length))
4017 v4_address_set = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004018 else if (unformat (i, "%U/%d",
4019 unformat_ip6_address, &v6address,
Ed Warnickecb9cada2015-12-08 15:45:58 -07004020 &address_length))
4021 v6_address_set = 1;
4022 else
4023 break;
4024 }
4025
4026 if (sw_if_index_set == 0) {
4027 errmsg ("missing interface name or sw_if_index\n");
4028 return -99;
4029 }
4030 if (v4_address_set && v6_address_set) {
4031 errmsg ("both v4 and v6 addresses set\n");
4032 return -99;
4033 }
4034 if (!v4_address_set && !v6_address_set && !del_all) {
4035 errmsg ("no addresses set\n");
4036 return -99;
4037 }
4038
4039 /* Construct the API message */
4040 M(SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
4041
4042 mp->sw_if_index = ntohl (sw_if_index);
4043 mp->is_add = is_add;
4044 mp->del_all = del_all;
4045 if (v6_address_set) {
4046 mp->is_ipv6 = 1;
Damjan Marionf1213b82016-03-13 02:22:06 +01004047 clib_memcpy (mp->address, &v6address, sizeof (v6address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004048 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01004049 clib_memcpy (mp->address, &v4address, sizeof (v4address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004050 }
4051 mp->address_length = address_length;
4052
4053 /* send it... */
4054 S;
4055
4056 /* Wait for a reply, return good/bad news */
4057 W;
4058}
4059
4060static int api_sw_interface_set_table (vat_main_t * vam)
4061{
4062 unformat_input_t * i = vam->input;
4063 vl_api_sw_interface_set_table_t *mp;
4064 f64 timeout;
4065 u32 sw_if_index, vrf_id = 0;
4066 u8 sw_if_index_set = 0;
4067 u8 is_ipv6 = 0;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004068
Ed Warnickecb9cada2015-12-08 15:45:58 -07004069 /* Parse args required to build the message */
4070 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4071 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4072 sw_if_index_set = 1;
4073 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4074 sw_if_index_set = 1;
4075 else if (unformat (i, "vrf %d", &vrf_id))
4076 ;
4077 else if (unformat (i, "ipv6"))
4078 is_ipv6 = 1;
4079 else
4080 break;
4081 }
4082
4083 if (sw_if_index_set == 0) {
4084 errmsg ("missing interface name or sw_if_index\n");
4085 return -99;
4086 }
4087
4088 /* Construct the API message */
4089 M(SW_INTERFACE_SET_TABLE, sw_interface_set_table);
4090
4091 mp->sw_if_index = ntohl (sw_if_index);
4092 mp->is_ipv6 = is_ipv6;
4093 mp->vrf_id = ntohl (vrf_id);
4094
4095 /* send it... */
4096 S;
4097
4098 /* Wait for a reply... */
4099 W;
4100}
4101
4102static int api_sw_interface_set_vpath (vat_main_t * vam)
4103{
4104 unformat_input_t * i = vam->input;
4105 vl_api_sw_interface_set_vpath_t *mp;
4106 f64 timeout;
4107 u32 sw_if_index = 0;
4108 u8 sw_if_index_set = 0;
4109 u8 is_enable = 0;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004110
Ed Warnickecb9cada2015-12-08 15:45:58 -07004111 /* Parse args required to build the message */
4112 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4113 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4114 sw_if_index_set = 1;
4115 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4116 sw_if_index_set = 1;
4117 else if (unformat (i, "enable"))
4118 is_enable = 1;
4119 else if (unformat (i, "disable"))
4120 is_enable = 0;
4121 else
4122 break;
4123 }
4124
4125 if (sw_if_index_set == 0) {
4126 errmsg ("missing interface name or sw_if_index\n");
4127 return -99;
4128 }
4129
4130 /* Construct the API message */
4131 M(SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
4132
4133 mp->sw_if_index = ntohl (sw_if_index);
4134 mp->enable = is_enable;
4135
4136 /* send it... */
4137 S;
4138
4139 /* Wait for a reply... */
4140 W;
4141}
4142
4143static int api_sw_interface_set_l2_xconnect (vat_main_t * vam)
4144{
4145 unformat_input_t * i = vam->input;
4146 vl_api_sw_interface_set_l2_xconnect_t *mp;
4147 f64 timeout;
4148 u32 rx_sw_if_index;
4149 u8 rx_sw_if_index_set = 0;
4150 u32 tx_sw_if_index;
4151 u8 tx_sw_if_index_set = 0;
4152 u8 enable = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004153
Ed Warnickecb9cada2015-12-08 15:45:58 -07004154 /* Parse args required to build the message */
4155 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4156 if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004157 rx_sw_if_index_set = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -07004158 else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
4159 tx_sw_if_index_set = 1;
4160 else if (unformat (i, "rx")) {
4161 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4162 if (unformat (i, "%U", unformat_sw_if_index, vam,
4163 &rx_sw_if_index))
4164 rx_sw_if_index_set = 1;
4165 } else
4166 break;
4167 } else if (unformat (i, "tx")) {
4168 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4169 if (unformat (i, "%U", unformat_sw_if_index, vam,
4170 &tx_sw_if_index))
4171 tx_sw_if_index_set = 1;
4172 } else
4173 break;
4174 } else if (unformat (i, "enable"))
4175 enable = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004176 else if (unformat (i, "disable"))
Ed Warnickecb9cada2015-12-08 15:45:58 -07004177 enable = 0;
4178 else
4179 break;
4180 }
4181
4182 if (rx_sw_if_index_set == 0) {
4183 errmsg ("missing rx interface name or rx_sw_if_index\n");
4184 return -99;
4185 }
4186
4187 if (enable && (tx_sw_if_index_set == 0)) {
4188 errmsg ("missing tx interface name or tx_sw_if_index\n");
4189 return -99;
4190 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004191
Ed Warnickecb9cada2015-12-08 15:45:58 -07004192 M(SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
4193
4194 mp->rx_sw_if_index = ntohl(rx_sw_if_index);
4195 mp->tx_sw_if_index = ntohl(tx_sw_if_index);
4196 mp->enable = enable;
4197
4198 S; W;
4199 /* NOTREACHED */
4200 return 0;
4201}
4202
4203static int api_sw_interface_set_l2_bridge (vat_main_t * vam)
4204{
4205 unformat_input_t * i = vam->input;
4206 vl_api_sw_interface_set_l2_bridge_t *mp;
4207 f64 timeout;
4208 u32 rx_sw_if_index;
4209 u8 rx_sw_if_index_set = 0;
4210 u32 bd_id;
4211 u8 bd_id_set = 0;
4212 u8 bvi = 0;
4213 u32 shg = 0;
4214 u8 enable = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004215
Ed Warnickecb9cada2015-12-08 15:45:58 -07004216 /* Parse args required to build the message */
4217 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4218 if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004219 rx_sw_if_index_set = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -07004220 else if (unformat (i, "bd_id %d", &bd_id))
4221 bd_id_set = 1;
4222 else if (unformat (i, "%U", unformat_sw_if_index, vam,
4223 &rx_sw_if_index))
4224 rx_sw_if_index_set = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004225 else if (unformat (i, "shg %d", &shg))
Ed Warnickecb9cada2015-12-08 15:45:58 -07004226 ;
4227 else if (unformat (i, "bvi"))
4228 bvi = 1;
4229 else if (unformat (i, "enable"))
4230 enable = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004231 else if (unformat (i, "disable"))
Ed Warnickecb9cada2015-12-08 15:45:58 -07004232 enable = 0;
4233 else
4234 break;
4235 }
4236
4237 if (rx_sw_if_index_set == 0) {
4238 errmsg ("missing rx interface name or sw_if_index\n");
4239 return -99;
4240 }
4241
4242 if (enable && (bd_id_set == 0)) {
4243 errmsg ("missing bridge domain\n");
4244 return -99;
4245 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004246
Ed Warnickecb9cada2015-12-08 15:45:58 -07004247 M(SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
4248
4249 mp->rx_sw_if_index = ntohl(rx_sw_if_index);
4250 mp->bd_id = ntohl(bd_id);
4251 mp->shg = (u8)shg;
4252 mp->bvi = bvi;
4253 mp->enable = enable;
4254
4255 S; W;
4256 /* NOTREACHED */
4257 return 0;
4258}
4259
4260static int api_bridge_domain_dump (vat_main_t * vam)
4261{
4262 unformat_input_t * i = vam->input;
4263 vl_api_bridge_domain_dump_t *mp;
4264 f64 timeout;
4265 u32 bd_id = ~0;
4266
4267 /* Parse args required to build the message */
4268 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4269 if (unformat (i, "bd_id %d", &bd_id))
4270 ;
4271 else
4272 break;
4273 }
4274
4275 M(BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
4276 mp->bd_id = ntohl(bd_id);
4277 S;
4278
4279 /* Use a control ping for synchronization */
4280 {
4281 vl_api_control_ping_t * mp;
4282 M(CONTROL_PING, control_ping);
4283 S;
4284 }
4285
4286 W;
4287 /* NOTREACHED */
4288 return 0;
4289}
4290
4291static int api_bridge_domain_add_del (vat_main_t * vam)
4292{
4293 unformat_input_t * i = vam->input;
4294 vl_api_bridge_domain_add_del_t *mp;
4295 f64 timeout;
4296 u32 bd_id = ~0;
4297 u8 is_add = 1;
4298 u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
4299
4300 /* Parse args required to build the message */
4301 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4302 if (unformat (i, "bd_id %d", &bd_id))
4303 ;
4304 else if (unformat (i, "flood %d", &flood))
4305 ;
4306 else if (unformat (i, "uu-flood %d", &uu_flood))
4307 ;
4308 else if (unformat (i, "forward %d", &forward))
4309 ;
4310 else if (unformat (i, "learn %d", &learn))
4311 ;
4312 else if (unformat (i, "arp-term %d", &arp_term))
4313 ;
4314 else if (unformat (i, "del")) {
4315 is_add = 0;
4316 flood = uu_flood = forward = learn = 0;
4317 }
4318 else
4319 break;
4320 }
4321
4322 if (bd_id == ~0) {
4323 errmsg ("missing bridge domain\n");
4324 return -99;
4325 }
4326
4327 M(BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
4328
4329 mp->bd_id = ntohl(bd_id);
4330 mp->flood = flood;
4331 mp->uu_flood = uu_flood;
4332 mp->forward = forward;
4333 mp->learn = learn;
4334 mp->arp_term = arp_term;
4335 mp->is_add = is_add;
4336
4337 S; W;
4338 /* NOTREACHED */
4339 return 0;
4340}
4341
4342static int api_l2fib_add_del (vat_main_t * vam)
4343{
4344 unformat_input_t * i = vam->input;
4345 vl_api_l2fib_add_del_t *mp;
4346 f64 timeout;
4347 u64 mac = 0;
4348 u8 mac_set = 0;
4349 u32 bd_id;
4350 u8 bd_id_set = 0;
4351 u32 sw_if_index;
4352 u8 sw_if_index_set = 0;
4353 u8 is_add = 1;
4354 u8 static_mac = 0;
4355 u8 filter_mac = 0;
marek zavodsky689acaf2016-07-01 03:49:53 +02004356 u8 bvi_mac = 0;
Dave Barach41da02d2016-07-11 16:48:42 -07004357 int count = 1;
4358 f64 before = 0;
4359 int j;
Ed Warnickecb9cada2015-12-08 15:45:58 -07004360
4361 /* Parse args required to build the message */
4362 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4363 if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
4364 mac_set = 1;
4365 else if (unformat (i, "bd_id %d", &bd_id))
4366 bd_id_set = 1;
4367 else if (unformat (i, "sw_if_index %d", &sw_if_index))
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004368 sw_if_index_set = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -07004369 else if (unformat (i, "sw_if")) {
4370 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
Dave Barach41da02d2016-07-11 16:48:42 -07004371 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4372 sw_if_index_set = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -07004373 } else
4374 break;
4375 } else if (unformat (i, "static"))
Dave Barach41da02d2016-07-11 16:48:42 -07004376 static_mac = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -07004377 else if (unformat (i, "filter")) {
Dave Barach41da02d2016-07-11 16:48:42 -07004378 filter_mac = 1;
4379 static_mac = 1;
4380 } else if (unformat (i, "bvi")) {
4381 bvi_mac = 1;
4382 static_mac = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -07004383 } else if (unformat (i, "del"))
Dave Barach41da02d2016-07-11 16:48:42 -07004384 is_add = 0;
4385 else if (unformat (i, "count %d", &count))
4386 ;
Ed Warnickecb9cada2015-12-08 15:45:58 -07004387 else
Dave Barach41da02d2016-07-11 16:48:42 -07004388 break;
Ed Warnickecb9cada2015-12-08 15:45:58 -07004389 }
4390
4391 if (mac_set == 0) {
4392 errmsg ("missing mac address\n");
4393 return -99;
4394 }
4395
4396 if (bd_id_set == 0) {
4397 errmsg ("missing bridge domain\n");
4398 return -99;
4399 }
4400
4401 if (is_add && (sw_if_index_set == 0)) {
4402 errmsg ("missing interface name or sw_if_index\n");
4403 return -99;
4404 }
4405
Dave Barach41da02d2016-07-11 16:48:42 -07004406 if (count > 1) {
4407 /* Turn on async mode */
4408 vam->async_mode = 1;
4409 vam->async_errors = 0;
4410 before = vat_time_now(vam);
Ed Warnickecb9cada2015-12-08 15:45:58 -07004411 }
Dave Barach41da02d2016-07-11 16:48:42 -07004412
4413 for (j = 0; j < count; j++) {
4414 M(L2FIB_ADD_DEL, l2fib_add_del);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004415
Dave Barach41da02d2016-07-11 16:48:42 -07004416 mp->mac = mac;
4417 mp->bd_id = ntohl(bd_id);
4418 mp->is_add = is_add;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004419
Dave Barach41da02d2016-07-11 16:48:42 -07004420 if (is_add) {
4421 mp->sw_if_index = ntohl(sw_if_index);
4422 mp->static_mac = static_mac;
4423 mp->filter_mac = filter_mac;
4424 mp->bvi_mac = bvi_mac;
4425 }
4426 increment_mac_address (&mac);
4427 /* send it... */
4428 S;
4429 }
4430
4431 if (count > 1) {
4432 vl_api_control_ping_t * mp;
4433 f64 after;
4434
4435 /* Shut off async mode */
4436 vam->async_mode = 0;
4437
4438 M(CONTROL_PING, control_ping);
4439 S;
4440
4441 timeout = vat_time_now(vam) + 1.0;
4442 while (vat_time_now (vam) < timeout)
4443 if (vam->result_ready == 1)
4444 goto out;
4445 vam->retval = -99;
4446
4447 out:
4448 if (vam->retval == -99)
4449 errmsg ("timeout\n");
4450
4451 if (vam->async_errors > 0) {
4452 errmsg ("%d asynchronous errors\n", vam->async_errors);
4453 vam->retval = -98;
4454 }
4455 vam->async_errors = 0;
4456 after = vat_time_now(vam);
4457
4458 fformat(vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
4459 count, after - before, count / (after - before));
4460 } else {
4461 /* Wait for a reply... */
4462 W;
4463 }
4464 /* Return the good/bad news */
4465 return (vam->retval);
Ed Warnickecb9cada2015-12-08 15:45:58 -07004466}
4467
4468static int api_l2_flags (vat_main_t * vam)
4469{
4470 unformat_input_t * i = vam->input;
4471 vl_api_l2_flags_t *mp;
4472 f64 timeout;
4473 u32 sw_if_index;
4474 u32 feature_bitmap = 0;
4475 u8 sw_if_index_set = 0;
4476
4477 /* Parse args required to build the message */
4478 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4479 if (unformat (i, "sw_if_index %d", &sw_if_index))
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004480 sw_if_index_set = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -07004481 else if (unformat (i, "sw_if")) {
4482 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4483 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4484 sw_if_index_set = 1;
4485 } else
4486 break;
4487 } else if (unformat (i, "learn"))
4488 feature_bitmap |= L2INPUT_FEAT_LEARN;
4489 else if (unformat (i, "forward"))
4490 feature_bitmap |= L2INPUT_FEAT_FWD;
4491 else if (unformat (i, "flood"))
4492 feature_bitmap |= L2INPUT_FEAT_FLOOD;
4493 else if (unformat (i, "uu-flood"))
4494 feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
4495 else
4496 break;
4497 }
4498
4499 if (sw_if_index_set == 0) {
4500 errmsg ("missing interface name or sw_if_index\n");
4501 return -99;
4502 }
4503
4504 M(L2_FLAGS, l2_flags);
4505
4506 mp->sw_if_index = ntohl(sw_if_index);
4507 mp->feature_bitmap = ntohl(feature_bitmap);
4508
4509 S; W;
4510 /* NOTREACHED */
4511 return 0;
4512}
4513
4514static int api_bridge_flags (vat_main_t * vam)
4515{
4516 unformat_input_t * i = vam->input;
4517 vl_api_bridge_flags_t *mp;
4518 f64 timeout;
4519 u32 bd_id;
4520 u8 bd_id_set = 0;
4521 u8 is_set = 1;
4522 u32 flags = 0;
4523
4524 /* Parse args required to build the message */
4525 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4526 if (unformat (i, "bd_id %d", &bd_id))
4527 bd_id_set = 1;
4528 else if (unformat (i, "learn"))
4529 flags |= L2_LEARN;
4530 else if (unformat (i, "forward"))
4531 flags |= L2_FWD;
4532 else if (unformat (i, "flood"))
4533 flags |= L2_FLOOD;
4534 else if (unformat (i, "uu-flood"))
4535 flags |= L2_UU_FLOOD;
4536 else if (unformat (i, "arp-term"))
4537 flags |= L2_ARP_TERM;
4538 else if (unformat (i, "off"))
4539 is_set = 0;
4540 else if (unformat (i, "disable"))
4541 is_set = 0;
4542 else
4543 break;
4544 }
4545
4546 if (bd_id_set == 0) {
4547 errmsg ("missing bridge domain\n");
4548 return -99;
4549 }
4550
4551 M(BRIDGE_FLAGS, bridge_flags);
4552
4553 mp->bd_id = ntohl(bd_id);
4554 mp->feature_bitmap = ntohl(flags);
4555 mp->is_set = is_set;
4556
4557 S; W;
4558 /* NOTREACHED */
4559 return 0;
4560}
4561
4562static int api_bd_ip_mac_add_del (vat_main_t * vam)
4563{
4564 unformat_input_t * i = vam->input;
4565 vl_api_bd_ip_mac_add_del_t *mp;
4566 f64 timeout;
4567 u32 bd_id;
4568 u8 is_ipv6 = 0;
4569 u8 is_add = 1;
4570 u8 bd_id_set = 0;
4571 u8 ip_set = 0;
4572 u8 mac_set = 0;
4573 ip4_address_t v4addr;
4574 ip6_address_t v6addr;
4575 u8 macaddr[6];
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004576
Ed Warnickecb9cada2015-12-08 15:45:58 -07004577
4578 /* Parse args required to build the message */
4579 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4580 if (unformat (i, "bd_id %d", &bd_id)) {
4581 bd_id_set++;
4582 } else if (unformat (i, "%U", unformat_ip4_address, &v4addr)) {
4583 ip_set++;
4584 } else if (unformat (i, "%U", unformat_ip6_address, &v6addr)) {
4585 ip_set++;
4586 is_ipv6++;
4587 } else if (unformat (i, "%U", unformat_ethernet_address, macaddr)) {
4588 mac_set++;
4589 } else if (unformat (i, "del"))
4590 is_add = 0;
4591 else
4592 break;
4593 }
4594
4595 if (bd_id_set == 0) {
4596 errmsg ("missing bridge domain\n");
4597 return -99;
4598 } else if (ip_set == 0) {
4599 errmsg ("missing IP address\n");
4600 return -99;
4601 } else if (mac_set == 0) {
4602 errmsg ("missing MAC address\n");
4603 return -99;
4604 }
4605
4606 M(BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
4607
4608 mp->bd_id = ntohl(bd_id);
4609 mp->is_ipv6 = is_ipv6;
4610 mp->is_add = is_add;
4611 if (is_ipv6)
Damjan Marionf1213b82016-03-13 02:22:06 +01004612 clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
4613 else clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
4614 clib_memcpy (mp->mac_address, macaddr, 6);
Ed Warnickecb9cada2015-12-08 15:45:58 -07004615 S; W;
4616 /* NOTREACHED */
4617 return 0;
4618}
4619
4620static int api_tap_connect (vat_main_t * vam)
4621{
4622 unformat_input_t * i = vam->input;
4623 vl_api_tap_connect_t *mp;
4624 f64 timeout;
4625 u8 mac_address[6];
4626 u8 random_mac = 1;
4627 u8 name_set = 0;
4628 u8 * tap_name;
4629
4630 memset (mac_address, 0, sizeof (mac_address));
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004631
Ed Warnickecb9cada2015-12-08 15:45:58 -07004632 /* Parse args required to build the message */
4633 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4634 if (unformat (i, "mac %U", unformat_ethernet_address, mac_address)) {
4635 random_mac = 0;
4636 }
4637 else if (unformat (i, "random-mac"))
4638 random_mac = 1;
4639 else if (unformat (i, "tapname %s", &tap_name))
4640 name_set = 1;
4641 else
4642 break;
4643 }
4644
4645 if (name_set == 0) {
4646 errmsg ("missing tap name\n");
4647 return -99;
4648 }
4649 if (vec_len (tap_name) > 63) {
4650 errmsg ("tap name too long\n");
4651 }
4652 vec_add1 (tap_name, 0);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004653
Ed Warnickecb9cada2015-12-08 15:45:58 -07004654 /* Construct the API message */
4655 M(TAP_CONNECT, tap_connect);
4656
4657 mp->use_random_mac = random_mac;
Damjan Marionf1213b82016-03-13 02:22:06 +01004658 clib_memcpy (mp->mac_address, mac_address, 6);
4659 clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004660 vec_free (tap_name);
4661
4662 /* send it... */
4663 S;
4664
4665 /* Wait for a reply... */
4666 W;
4667}
4668
4669static int api_tap_modify (vat_main_t * vam)
4670{
4671 unformat_input_t * i = vam->input;
4672 vl_api_tap_modify_t *mp;
4673 f64 timeout;
4674 u8 mac_address[6];
4675 u8 random_mac = 1;
4676 u8 name_set = 0;
4677 u8 * tap_name;
4678 u32 sw_if_index = ~0;
4679 u8 sw_if_index_set = 0;
4680
4681 memset (mac_address, 0, sizeof (mac_address));
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004682
Ed Warnickecb9cada2015-12-08 15:45:58 -07004683 /* Parse args required to build the message */
4684 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4685 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4686 sw_if_index_set = 1;
4687 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4688 sw_if_index_set = 1;
4689 else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address)) {
4690 random_mac = 0;
4691 }
4692 else if (unformat (i, "random-mac"))
4693 random_mac = 1;
4694 else if (unformat (i, "tapname %s", &tap_name))
4695 name_set = 1;
4696 else
4697 break;
4698 }
4699
4700 if (sw_if_index_set == 0) {
4701 errmsg ("missing vpp interface name");
4702 return -99;
4703 }
4704 if (name_set == 0) {
4705 errmsg ("missing tap name\n");
4706 return -99;
4707 }
4708 if (vec_len (tap_name) > 63) {
4709 errmsg ("tap name too long\n");
4710 }
4711 vec_add1 (tap_name, 0);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004712
Ed Warnickecb9cada2015-12-08 15:45:58 -07004713 /* Construct the API message */
4714 M(TAP_MODIFY, tap_modify);
4715
4716 mp->use_random_mac = random_mac;
4717 mp->sw_if_index = ntohl(sw_if_index);
Damjan Marionf1213b82016-03-13 02:22:06 +01004718 clib_memcpy (mp->mac_address, mac_address, 6);
4719 clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004720 vec_free (tap_name);
4721
4722 /* send it... */
4723 S;
4724
4725 /* Wait for a reply... */
4726 W;
4727}
4728
4729static int api_tap_delete (vat_main_t * vam)
4730{
4731 unformat_input_t * i = vam->input;
4732 vl_api_tap_delete_t *mp;
4733 f64 timeout;
4734 u32 sw_if_index = ~0;
4735 u8 sw_if_index_set = 0;
4736
4737 /* Parse args required to build the message */
4738 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4739 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4740 sw_if_index_set = 1;
4741 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4742 sw_if_index_set = 1;
4743 else
4744 break;
4745 }
4746
4747 if (sw_if_index_set == 0) {
4748 errmsg ("missing vpp interface name");
4749 return -99;
4750 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004751
Ed Warnickecb9cada2015-12-08 15:45:58 -07004752 /* Construct the API message */
4753 M(TAP_DELETE, tap_delete);
4754
4755 mp->sw_if_index = ntohl(sw_if_index);
4756
4757 /* send it... */
4758 S;
4759
4760 /* Wait for a reply... */
4761 W;
4762}
4763
4764static int api_ip_add_del_route (vat_main_t * vam)
4765{
4766 unformat_input_t * i = vam->input;
4767 vl_api_ip_add_del_route_t *mp;
4768 f64 timeout;
Nealee9dbd2b2016-07-01 13:00:09 +01004769 u32 sw_if_index = ~0, vrf_id = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -07004770 u8 sw_if_index_set = 0;
4771 u8 is_ipv6 = 0;
4772 u8 is_local = 0, is_drop = 0;
4773 u8 create_vrf_if_needed = 0;
4774 u8 is_add = 1;
4775 u8 next_hop_weight = 1;
4776 u8 not_last = 0;
4777 u8 is_multipath = 0;
4778 u8 address_set = 0;
4779 u8 address_length_set = 0;
4780 u32 lookup_in_vrf = 0;
4781 u32 resolve_attempts = 0;
4782 u32 dst_address_length = 0;
4783 u8 next_hop_set = 0;
4784 ip4_address_t v4_dst_address, v4_next_hop_address;
4785 ip6_address_t v6_dst_address, v6_next_hop_address;
4786 int count = 1;
4787 int j;
4788 f64 before = 0;
4789 u32 random_add_del = 0;
4790 u32 * random_vector = 0;
4791 uword * random_hash;
4792 u32 random_seed = 0xdeaddabe;
4793 u32 classify_table_index = ~0;
4794 u8 is_classify = 0;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004795
Ed Warnickecb9cada2015-12-08 15:45:58 -07004796 /* Parse args required to build the message */
4797 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4798 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4799 sw_if_index_set = 1;
4800 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4801 sw_if_index_set = 1;
4802 else if (unformat (i, "%U", unformat_ip4_address,
4803 &v4_dst_address)) {
4804 address_set = 1;
4805 is_ipv6 = 0;
4806 }
4807 else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address)) {
4808 address_set = 1;
4809 is_ipv6 = 1;
4810 }
4811 else if (unformat (i, "/%d", &dst_address_length)) {
4812 address_length_set = 1;
4813 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004814
4815 else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
Ed Warnickecb9cada2015-12-08 15:45:58 -07004816 &v4_next_hop_address)) {
4817 next_hop_set = 1;
4818 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004819 else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
Ed Warnickecb9cada2015-12-08 15:45:58 -07004820 &v6_next_hop_address)) {
4821 next_hop_set = 1;
4822 }
4823 else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
4824 ;
4825 else if (unformat (i, "weight %d", &next_hop_weight))
4826 ;
4827 else if (unformat (i, "drop")) {
4828 is_drop = 1;
4829 } else if (unformat (i, "local")) {
4830 is_local = 1;
4831 } else if (unformat (i, "classify %d", &classify_table_index)) {
4832 is_classify = 1;
4833 } else if (unformat (i, "del"))
4834 is_add = 0;
4835 else if (unformat (i, "add"))
4836 is_add = 1;
4837 else if (unformat (i, "not-last"))
4838 not_last = 1;
4839 else if (unformat (i, "multipath"))
4840 is_multipath = 1;
4841 else if (unformat (i, "vrf %d", &vrf_id))
4842 ;
4843 else if (unformat (i, "create-vrf"))
4844 create_vrf_if_needed = 1;
4845 else if (unformat (i, "count %d", &count))
4846 ;
4847 else if (unformat (i, "lookup-in-vrf %d", &lookup_in_vrf))
4848 ;
4849 else if (unformat (i, "random"))
4850 random_add_del = 1;
4851 else if (unformat (i, "seed %d", &random_seed))
4852 ;
4853 else {
4854 clib_warning ("parse error '%U'", format_unformat_error, i);
4855 return -99;
4856 }
4857 }
4858
4859 if (resolve_attempts > 0 && sw_if_index_set == 0) {
4860 errmsg ("ARP resolution needs explicit interface or sw_if_index\n");
4861 return -99;
4862 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004863
Ed Warnickecb9cada2015-12-08 15:45:58 -07004864 if (!next_hop_set && !is_drop && !is_local && !is_classify) {
4865 errmsg ("next hop / local / drop / classify not set\n");
4866 return -99;
4867 }
4868
4869 if (address_set == 0) {
4870 errmsg ("missing addresses\n");
4871 return -99;
4872 }
4873
4874 if (address_length_set == 0) {
4875 errmsg ("missing address length\n");
4876 return -99;
4877 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004878
Ed Warnickecb9cada2015-12-08 15:45:58 -07004879 /* Generate a pile of unique, random routes */
4880 if (random_add_del) {
4881 u32 this_random_address;
4882 random_hash = hash_create (count, sizeof(uword));
4883
4884 hash_set (random_hash, v4_next_hop_address.as_u32, 1);
4885 for (j = 0; j <= count; j++) {
4886 do {
4887 this_random_address = random_u32 (&random_seed);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004888 this_random_address =
Ed Warnickecb9cada2015-12-08 15:45:58 -07004889 clib_host_to_net_u32 (this_random_address);
4890 } while (hash_get (random_hash, this_random_address));
4891 vec_add1 (random_vector, this_random_address);
4892 hash_set (random_hash, this_random_address, 1);
4893 }
4894 hash_free (random_hash);
4895 v4_dst_address.as_u32 = random_vector[0];
4896 }
4897
4898 if (count > 1) {
4899 /* Turn on async mode */
4900 vam->async_mode = 1;
4901 vam->async_errors = 0;
4902 before = vat_time_now(vam);
4903 }
4904
4905 for (j = 0; j < count; j++) {
4906 /* Construct the API message */
4907 M(IP_ADD_DEL_ROUTE, ip_add_del_route);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004908
Ed Warnickecb9cada2015-12-08 15:45:58 -07004909 mp->next_hop_sw_if_index = ntohl (sw_if_index);
4910 mp->vrf_id = ntohl (vrf_id);
4911 if (resolve_attempts > 0) {
4912 mp->resolve_attempts = ntohl (resolve_attempts);
4913 mp->resolve_if_needed = 1;
4914 }
4915 mp->create_vrf_if_needed = create_vrf_if_needed;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004916
Ed Warnickecb9cada2015-12-08 15:45:58 -07004917 mp->is_add = is_add;
4918 mp->is_drop = is_drop;
4919 mp->is_ipv6 = is_ipv6;
4920 mp->is_local = is_local;
4921 mp->is_classify = is_classify;
4922 mp->is_multipath = is_multipath;
4923 mp->not_last = not_last;
4924 mp->next_hop_weight = next_hop_weight;
4925 mp->dst_address_length = dst_address_length;
4926 mp->lookup_in_vrf = ntohl(lookup_in_vrf);
4927 mp->classify_table_index = ntohl(classify_table_index);
4928
4929 if (is_ipv6){
Damjan Marionf1213b82016-03-13 02:22:06 +01004930 clib_memcpy (mp->dst_address, &v6_dst_address, sizeof (v6_dst_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004931 if (next_hop_set)
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004932 clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
Ed Warnickecb9cada2015-12-08 15:45:58 -07004933 sizeof (v6_next_hop_address));
4934 increment_v6_address (&v6_dst_address);
4935 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01004936 clib_memcpy (mp->dst_address, &v4_dst_address, sizeof (v4_dst_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004937 if (next_hop_set)
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004938 clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
Ed Warnickecb9cada2015-12-08 15:45:58 -07004939 sizeof (v4_next_hop_address));
4940 if (random_add_del)
4941 v4_dst_address.as_u32 = random_vector[j+1];
4942 else
4943 increment_v4_address (&v4_dst_address);
4944 }
4945 /* send it... */
4946 S;
4947 }
4948
4949 /* When testing multiple add/del ops, use a control-ping to sync */
4950 if (count > 1) {
4951 vl_api_control_ping_t * mp;
4952 f64 after;
4953
4954 /* Shut off async mode */
4955 vam->async_mode = 0;
4956
4957 M(CONTROL_PING, control_ping);
4958 S;
4959
4960 timeout = vat_time_now(vam) + 1.0;
4961 while (vat_time_now (vam) < timeout)
4962 if (vam->result_ready == 1)
4963 goto out;
4964 vam->retval = -99;
4965
4966 out:
4967 if (vam->retval == -99)
4968 errmsg ("timeout\n");
4969
4970 if (vam->async_errors > 0) {
4971 errmsg ("%d asynchronous errors\n", vam->async_errors);
4972 vam->retval = -98;
4973 }
4974 vam->async_errors = 0;
4975 after = vat_time_now(vam);
4976
4977 fformat(vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
4978 count, after - before, count / (after - before));
4979 } else {
4980 /* Wait for a reply... */
4981 W;
4982 }
4983
4984 /* Return the good/bad news */
4985 return (vam->retval);
4986}
4987
4988static int api_proxy_arp_add_del (vat_main_t * vam)
4989{
4990 unformat_input_t * i = vam->input;
4991 vl_api_proxy_arp_add_del_t *mp;
4992 f64 timeout;
4993 u32 vrf_id = 0;
4994 u8 is_add = 1;
4995 ip4_address_t lo, hi;
4996 u8 range_set = 0;
4997
4998 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4999 if (unformat (i, "vrf %d", &vrf_id))
5000 ;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005001 else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
Ed Warnickecb9cada2015-12-08 15:45:58 -07005002 unformat_ip4_address, &hi))
5003 range_set = 1;
5004 else if (unformat (i, "del"))
5005 is_add = 0;
5006 else {
5007 clib_warning ("parse error '%U'", format_unformat_error, i);
5008 return -99;
5009 }
5010 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005011
Ed Warnickecb9cada2015-12-08 15:45:58 -07005012 if (range_set == 0) {
5013 errmsg ("address range not set\n");
5014 return -99;
5015 }
5016
5017 M(PROXY_ARP_ADD_DEL, proxy_arp_add_del);
5018
5019 mp->vrf_id = ntohl(vrf_id);
5020 mp->is_add = is_add;
Damjan Marionf1213b82016-03-13 02:22:06 +01005021 clib_memcpy(mp->low_address, &lo, sizeof (mp->low_address));
5022 clib_memcpy(mp->hi_address, &hi, sizeof (mp->hi_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005023
5024 S; W;
5025 /* NOTREACHED */
5026 return 0;
5027}
5028
5029static int api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
5030{
5031 unformat_input_t * i = vam->input;
5032 vl_api_proxy_arp_intfc_enable_disable_t *mp;
5033 f64 timeout;
5034 u32 sw_if_index;
5035 u8 enable = 1;
5036 u8 sw_if_index_set = 0;
5037
5038 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5039 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5040 sw_if_index_set = 1;
5041 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5042 sw_if_index_set = 1;
5043 else if (unformat (i, "enable"))
5044 enable = 1;
5045 else if (unformat (i, "disable"))
5046 enable = 0;
5047 else {
5048 clib_warning ("parse error '%U'", format_unformat_error, i);
5049 return -99;
5050 }
5051 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005052
Ed Warnickecb9cada2015-12-08 15:45:58 -07005053 if (sw_if_index_set == 0) {
5054 errmsg ("missing interface name or sw_if_index\n");
5055 return -99;
5056 }
5057
5058 M(PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
5059
5060 mp->sw_if_index = ntohl(sw_if_index);
5061 mp->enable_disable = enable;
5062
5063 S; W;
5064 /* NOTREACHED */
5065 return 0;
5066}
5067
5068static int api_mpls_add_del_decap (vat_main_t * vam)
5069{
5070 unformat_input_t * i = vam->input;
5071 vl_api_mpls_add_del_decap_t *mp;
5072 f64 timeout;
5073 u32 rx_vrf_id = 0;
5074 u32 tx_vrf_id = 0;
5075 u32 label = 0;
5076 u8 is_add = 1;
5077 u8 s_bit = 1;
5078 u32 next_index = 1;
5079
5080 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5081 if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
5082 ;
5083 else if (unformat (i, "tx_vrf_id %d", &tx_vrf_id))
5084 ;
5085 else if (unformat (i, "label %d", &label))
5086 ;
5087 else if (unformat (i, "next-index %d", &next_index))
5088 ;
5089 else if (unformat (i, "del"))
5090 is_add = 0;
5091 else if (unformat (i, "s-bit-clear"))
5092 s_bit = 0;
5093 else {
5094 clib_warning ("parse error '%U'", format_unformat_error, i);
5095 return -99;
5096 }
5097 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005098
Ed Warnickecb9cada2015-12-08 15:45:58 -07005099 M(MPLS_ADD_DEL_DECAP, mpls_add_del_decap);
5100
5101 mp->rx_vrf_id = ntohl(rx_vrf_id);
5102 mp->tx_vrf_id = ntohl(tx_vrf_id);
5103 mp->label = ntohl(label);
5104 mp->next_index = ntohl(next_index);
5105 mp->s_bit = s_bit;
5106 mp->is_add = is_add;
5107
5108 S; W;
5109 /* NOTREACHED */
5110 return 0;
5111}
5112
5113static int api_mpls_add_del_encap (vat_main_t * vam)
5114{
5115 unformat_input_t * i = vam->input;
5116 vl_api_mpls_add_del_encap_t *mp;
5117 f64 timeout;
5118 u32 vrf_id = 0;
5119 u32 *labels = 0;
5120 u32 label;
5121 ip4_address_t dst_address;
5122 u8 is_add = 1;
5123
5124 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5125 if (unformat (i, "vrf %d", &vrf_id))
5126 ;
5127 else if (unformat (i, "label %d", &label))
5128 vec_add1 (labels, ntohl(label));
5129 else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
5130 ;
5131 else if (unformat (i, "del"))
5132 is_add = 0;
5133 else {
5134 clib_warning ("parse error '%U'", format_unformat_error, i);
5135 return -99;
5136 }
5137 }
5138
5139 if (vec_len (labels) == 0) {
5140 errmsg ("missing encap label stack\n");
5141 return -99;
5142 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005143
5144 M2(MPLS_ADD_DEL_ENCAP, mpls_add_del_encap,
Ed Warnickecb9cada2015-12-08 15:45:58 -07005145 sizeof (u32) * vec_len (labels));
5146
5147 mp->vrf_id = ntohl(vrf_id);
Damjan Marionf1213b82016-03-13 02:22:06 +01005148 clib_memcpy(mp->dst_address, &dst_address, sizeof (dst_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005149 mp->is_add = is_add;
5150 mp->nlabels = vec_len (labels);
Damjan Marionf1213b82016-03-13 02:22:06 +01005151 clib_memcpy(mp->labels, labels, sizeof(u32)*mp->nlabels);
Ed Warnickecb9cada2015-12-08 15:45:58 -07005152
5153 vec_free(labels);
5154
5155 S; W;
5156 /* NOTREACHED */
5157 return 0;
5158}
5159
5160static int api_mpls_gre_add_del_tunnel (vat_main_t * vam)
5161{
5162 unformat_input_t * i = vam->input;
5163 vl_api_mpls_gre_add_del_tunnel_t *mp;
5164 f64 timeout;
5165 u32 inner_vrf_id = 0;
5166 u32 outer_vrf_id = 0;
5167 ip4_address_t src_address;
5168 ip4_address_t dst_address;
5169 ip4_address_t intfc_address;
5170 u32 tmp;
5171 u8 intfc_address_length = 0;
5172 u8 is_add = 1;
5173 u8 l2_only = 0;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005174
Ed Warnickecb9cada2015-12-08 15:45:58 -07005175 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5176 if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
5177 ;
5178 else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
5179 ;
5180 else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
5181 ;
5182 else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
5183 ;
5184 else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5185 &intfc_address, &tmp))
5186 intfc_address_length = tmp;
5187 else if (unformat (i, "l2-only"))
5188 l2_only = 1;
5189 else if (unformat (i, "del"))
5190 is_add = 0;
5191 else {
5192 clib_warning ("parse error '%U'", format_unformat_error, i);
5193 return -99;
5194 }
5195 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005196
Ed Warnickecb9cada2015-12-08 15:45:58 -07005197 M(MPLS_GRE_ADD_DEL_TUNNEL, mpls_gre_add_del_tunnel);
5198
5199 mp->inner_vrf_id = ntohl(inner_vrf_id);
5200 mp->outer_vrf_id = ntohl(outer_vrf_id);
Damjan Marionf1213b82016-03-13 02:22:06 +01005201 clib_memcpy(mp->src_address, &src_address, sizeof (src_address));
5202 clib_memcpy(mp->dst_address, &dst_address, sizeof (dst_address));
5203 clib_memcpy(mp->intfc_address, &intfc_address, sizeof (intfc_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005204 mp->intfc_address_length = intfc_address_length;
5205 mp->l2_only = l2_only;
5206 mp->is_add = is_add;
5207
5208 S; W;
5209 /* NOTREACHED */
5210 return 0;
5211}
5212
5213static int api_mpls_ethernet_add_del_tunnel (vat_main_t * vam)
5214{
5215 unformat_input_t * i = vam->input;
5216 vl_api_mpls_ethernet_add_del_tunnel_t *mp;
5217 f64 timeout;
5218 u32 inner_vrf_id = 0;
5219 ip4_address_t intfc_address;
5220 u8 dst_mac_address[6];
5221 int dst_set = 1;
5222 u32 tmp;
5223 u8 intfc_address_length = 0;
5224 u8 is_add = 1;
5225 u8 l2_only = 0;
5226 u32 tx_sw_if_index;
5227 int tx_sw_if_index_set = 0;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005228
Ed Warnickecb9cada2015-12-08 15:45:58 -07005229 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5230 if (unformat (i, "vrf %d", &inner_vrf_id))
5231 ;
5232 else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5233 &intfc_address, &tmp))
5234 intfc_address_length = tmp;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005235 else if (unformat (i, "%U",
Ed Warnickecb9cada2015-12-08 15:45:58 -07005236 unformat_sw_if_index, vam, &tx_sw_if_index))
5237 tx_sw_if_index_set = 1;
5238 else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5239 tx_sw_if_index_set = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005240 else if (unformat (i, "dst %U", unformat_ethernet_address,
Ed Warnickecb9cada2015-12-08 15:45:58 -07005241 dst_mac_address))
5242 dst_set = 1;
5243 else if (unformat (i, "l2-only"))
5244 l2_only = 1;
5245 else if (unformat (i, "del"))
5246 is_add = 0;
5247 else {
5248 clib_warning ("parse error '%U'", format_unformat_error, i);
5249 return -99;
5250 }
5251 }
5252
5253 if (!dst_set) {
5254 errmsg ("dst (mac address) not set\n");
5255 return -99;
5256 }
5257 if (!tx_sw_if_index_set) {
5258 errmsg ("tx-intfc not set\n");
5259 return -99;
5260 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005261
Ed Warnickecb9cada2015-12-08 15:45:58 -07005262 M(MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel);
5263
5264 mp->vrf_id = ntohl(inner_vrf_id);
Damjan Marionf1213b82016-03-13 02:22:06 +01005265 clib_memcpy (mp->adj_address, &intfc_address, sizeof (intfc_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005266 mp->adj_address_length = intfc_address_length;
Damjan Marionf1213b82016-03-13 02:22:06 +01005267 clib_memcpy (mp->dst_mac_address, dst_mac_address, sizeof (dst_mac_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005268 mp->tx_sw_if_index = ntohl(tx_sw_if_index);
5269 mp->l2_only = l2_only;
5270 mp->is_add = is_add;
5271
5272 S; W;
5273 /* NOTREACHED */
5274 return 0;
5275}
5276
5277static int api_mpls_ethernet_add_del_tunnel_2 (vat_main_t * vam)
5278{
5279 unformat_input_t * i = vam->input;
5280 vl_api_mpls_ethernet_add_del_tunnel_2_t *mp;
5281 f64 timeout;
5282 u32 inner_vrf_id = 0;
5283 u32 outer_vrf_id = 0;
5284 ip4_address_t adj_address;
5285 int adj_address_set = 0;
5286 ip4_address_t next_hop_address;
5287 int next_hop_address_set = 0;
5288 u32 tmp;
5289 u8 adj_address_length = 0;
5290 u8 l2_only = 0;
5291 u8 is_add = 1;
5292 u32 resolve_attempts = 5;
5293 u8 resolve_if_needed = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005294
Ed Warnickecb9cada2015-12-08 15:45:58 -07005295 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5296 if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
5297 ;
5298 else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
5299 ;
5300 else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5301 &adj_address, &tmp)) {
5302 adj_address_length = tmp;
5303 adj_address_set = 1;
5304 }
5305 else if (unformat (i, "next-hop %U", unformat_ip4_address,
5306 &next_hop_address))
5307 next_hop_address_set = 1;
5308 else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5309 ;
5310 else if (unformat (i, "resolve-if-needed %d", &tmp))
5311 resolve_if_needed = tmp;
5312 else if (unformat (i, "l2-only"))
5313 l2_only = 1;
5314 else if (unformat (i, "del"))
5315 is_add = 0;
5316 else {
5317 clib_warning ("parse error '%U'", format_unformat_error, i);
5318 return -99;
5319 }
5320 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005321
Ed Warnickecb9cada2015-12-08 15:45:58 -07005322 if (!adj_address_set) {
5323 errmsg ("adjacency address/mask not set\n");
5324 return -99;
5325 }
5326 if (!next_hop_address_set) {
5327 errmsg ("ip4 next hop address (in outer fib) not set\n");
5328 return -99;
5329 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005330
Ed Warnickecb9cada2015-12-08 15:45:58 -07005331 M(MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005332
Ed Warnickecb9cada2015-12-08 15:45:58 -07005333 mp->inner_vrf_id = ntohl(inner_vrf_id);
5334 mp->outer_vrf_id = ntohl(outer_vrf_id);
5335 mp->resolve_attempts = ntohl(resolve_attempts);
5336 mp->resolve_if_needed = resolve_if_needed;
5337 mp->is_add = is_add;
5338 mp->l2_only = l2_only;
Damjan Marionf1213b82016-03-13 02:22:06 +01005339 clib_memcpy (mp->adj_address, &adj_address, sizeof (adj_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005340 mp->adj_address_length = adj_address_length;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005341 clib_memcpy (mp->next_hop_ip4_address_in_outer_vrf, &next_hop_address,
Ed Warnickecb9cada2015-12-08 15:45:58 -07005342 sizeof (next_hop_address));
5343
5344 S; W;
5345 /* NOTREACHED */
5346 return 0;
5347}
5348
5349static int api_sw_interface_set_unnumbered (vat_main_t * vam)
5350{
5351 unformat_input_t * i = vam->input;
5352 vl_api_sw_interface_set_unnumbered_t *mp;
5353 f64 timeout;
5354 u32 sw_if_index;
5355 u32 unnum_sw_index;
5356 u8 is_add = 1;
5357 u8 sw_if_index_set = 0;
5358
5359 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5360 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5361 sw_if_index_set = 1;
5362 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5363 sw_if_index_set = 1;
5364 else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
5365 ;
5366 else if (unformat (i, "del"))
5367 is_add = 0;
5368 else {
5369 clib_warning ("parse error '%U'", format_unformat_error, i);
5370 return -99;
5371 }
5372 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005373
Ed Warnickecb9cada2015-12-08 15:45:58 -07005374 if (sw_if_index_set == 0) {
5375 errmsg ("missing interface name or sw_if_index\n");
5376 return -99;
5377 }
5378
5379 M(SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
5380
5381 mp->sw_if_index = ntohl(sw_if_index);
5382 mp->unnumbered_sw_if_index = ntohl(unnum_sw_index);
5383 mp->is_add = is_add;
5384
5385 S; W;
5386 /* NOTREACHED */
5387 return 0;
5388}
5389
5390static int api_ip_neighbor_add_del (vat_main_t * vam)
5391{
5392 unformat_input_t * i = vam->input;
5393 vl_api_ip_neighbor_add_del_t *mp;
5394 f64 timeout;
5395 u32 sw_if_index;
5396 u8 sw_if_index_set = 0;
5397 u32 vrf_id = 0;
5398 u8 is_add = 1;
5399 u8 is_static = 0;
5400 u8 mac_address[6];
5401 u8 mac_set = 0;
5402 u8 v4_address_set = 0;
5403 u8 v6_address_set = 0;
5404 ip4_address_t v4address;
5405 ip6_address_t v6address;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005406
Ed Warnickecb9cada2015-12-08 15:45:58 -07005407 memset (mac_address, 0, sizeof (mac_address));
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005408
Ed Warnickecb9cada2015-12-08 15:45:58 -07005409 /* Parse args required to build the message */
5410 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
Chris Luke49a69632016-07-08 10:34:00 -04005411 if (unformat (i, "mac %U", unformat_ethernet_address, mac_address)) {
Ed Warnickecb9cada2015-12-08 15:45:58 -07005412 mac_set = 1;
5413 }
5414 else if (unformat (i, "del"))
5415 is_add = 0;
Chris Luke49a69632016-07-08 10:34:00 -04005416 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
Ed Warnickecb9cada2015-12-08 15:45:58 -07005417 sw_if_index_set = 1;
5418 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5419 sw_if_index_set = 1;
5420 else if (unformat (i, "is_static"))
5421 is_static = 1;
5422 else if (unformat (i, "vrf %d", &vrf_id))
5423 ;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005424 else if (unformat (i, "dst %U",
Ed Warnickecb9cada2015-12-08 15:45:58 -07005425 unformat_ip4_address, &v4address))
5426 v4_address_set = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005427 else if (unformat (i, "dst %U",
Ed Warnickecb9cada2015-12-08 15:45:58 -07005428 unformat_ip6_address, &v6address))
5429 v6_address_set = 1;
5430 else {
5431 clib_warning ("parse error '%U'", format_unformat_error, i);
5432 return -99;
5433 }
5434 }
5435
5436 if (sw_if_index_set == 0) {
5437 errmsg ("missing interface name or sw_if_index\n");
5438 return -99;
5439 }
5440 if (v4_address_set && v6_address_set) {
5441 errmsg ("both v4 and v6 addresses set\n");
5442 return -99;
5443 }
5444 if (!v4_address_set && !v6_address_set) {
Chris Luke49a69632016-07-08 10:34:00 -04005445 errmsg ("no address set\n");
Ed Warnickecb9cada2015-12-08 15:45:58 -07005446 return -99;
5447 }
5448
5449 /* Construct the API message */
5450 M(IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
5451
5452 mp->sw_if_index = ntohl (sw_if_index);
5453 mp->is_add = is_add;
5454 mp->vrf_id = ntohl (vrf_id);
5455 mp->is_static = is_static;
5456 if (mac_set)
Damjan Marionf1213b82016-03-13 02:22:06 +01005457 clib_memcpy (mp->mac_address, mac_address, 6);
Ed Warnickecb9cada2015-12-08 15:45:58 -07005458 if (v6_address_set) {
5459 mp->is_ipv6 = 1;
Damjan Marionf1213b82016-03-13 02:22:06 +01005460 clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005461 } else {
5462 /* mp->is_ipv6 = 0; via memset in M macro above */
Damjan Marionf1213b82016-03-13 02:22:06 +01005463 clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005464 }
5465
5466 /* send it... */
5467 S;
5468
5469 /* Wait for a reply, return good/bad news */
5470 W;
5471
5472 /* NOTREACHED */
5473 return 0;
5474}
5475
5476static int api_reset_vrf (vat_main_t * vam)
5477{
5478 unformat_input_t * i = vam->input;
5479 vl_api_reset_vrf_t *mp;
5480 f64 timeout;
5481 u32 vrf_id = 0;
5482 u8 is_ipv6 = 0;
5483 u8 vrf_id_set = 0;
5484
5485 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5486 if (unformat (i, "vrf %d", &vrf_id))
5487 vrf_id_set = 1;
5488 else if (unformat (i, "ipv6"))
5489 is_ipv6 = 1;
5490 else {
5491 clib_warning ("parse error '%U'", format_unformat_error, i);
5492 return -99;
5493 }
5494 }
5495
5496 if (vrf_id_set == 0) {
5497 errmsg ("missing vrf id\n");
5498 return -99;
5499 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005500
Ed Warnickecb9cada2015-12-08 15:45:58 -07005501 M(RESET_VRF, reset_vrf);
5502
5503 mp->vrf_id = ntohl(vrf_id);
5504 mp->is_ipv6 = is_ipv6;
5505
5506 S; W;
5507 /* NOTREACHED */
5508 return 0;
5509}
5510
5511static int api_create_vlan_subif (vat_main_t * vam)
5512{
5513 unformat_input_t * i = vam->input;
5514 vl_api_create_vlan_subif_t *mp;
5515 f64 timeout;
5516 u32 sw_if_index;
5517 u8 sw_if_index_set = 0;
5518 u32 vlan_id;
5519 u8 vlan_id_set = 0;
5520
5521 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5522 if (unformat (i, "sw_if_index %d", &sw_if_index))
5523 sw_if_index_set = 1;
5524 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5525 sw_if_index_set = 1;
5526 else if (unformat (i, "vlan %d", &vlan_id))
5527 vlan_id_set = 1;
5528 else {
5529 clib_warning ("parse error '%U'", format_unformat_error, i);
5530 return -99;
5531 }
5532 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005533
Ed Warnickecb9cada2015-12-08 15:45:58 -07005534 if (sw_if_index_set == 0) {
5535 errmsg ("missing interface name or sw_if_index\n");
5536 return -99;
5537 }
5538
5539 if (vlan_id_set == 0) {
5540 errmsg ("missing vlan_id\n");
5541 return -99;
5542 }
5543 M(CREATE_VLAN_SUBIF, create_vlan_subif);
5544
5545 mp->sw_if_index = ntohl(sw_if_index);
5546 mp->vlan_id = ntohl(vlan_id);
5547
5548 S; W;
5549 /* NOTREACHED */
5550 return 0;
5551}
5552
5553#define foreach_create_subif_bit \
5554_(no_tags) \
5555_(one_tag) \
5556_(two_tags) \
5557_(dot1ad) \
5558_(exact_match) \
5559_(default_sub) \
5560_(outer_vlan_id_any) \
5561_(inner_vlan_id_any)
5562
5563static int api_create_subif (vat_main_t * vam)
5564{
5565 unformat_input_t * i = vam->input;
5566 vl_api_create_subif_t *mp;
5567 f64 timeout;
5568 u32 sw_if_index;
5569 u8 sw_if_index_set = 0;
5570 u32 sub_id;
5571 u8 sub_id_set = 0;
5572 u32 no_tags = 0;
5573 u32 one_tag = 0;
5574 u32 two_tags = 0;
5575 u32 dot1ad = 0;
5576 u32 exact_match = 0;
5577 u32 default_sub = 0;
5578 u32 outer_vlan_id_any = 0;
5579 u32 inner_vlan_id_any = 0;
5580 u32 tmp;
5581 u16 outer_vlan_id = 0;
5582 u16 inner_vlan_id = 0;
5583
5584 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5585 if (unformat (i, "sw_if_index %d", &sw_if_index))
5586 sw_if_index_set = 1;
5587 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5588 sw_if_index_set = 1;
5589 else if (unformat (i, "sub_id %d", &sub_id))
5590 sub_id_set = 1;
5591 else if (unformat (i, "outer_vlan_id %d", &tmp))
5592 outer_vlan_id = tmp;
5593 else if (unformat (i, "inner_vlan_id %d", &tmp))
5594 inner_vlan_id = tmp;
5595
5596#define _(a) else if (unformat (i, #a)) a = 1 ;
5597 foreach_create_subif_bit
5598#undef _
5599
5600 else {
5601 clib_warning ("parse error '%U'", format_unformat_error, i);
5602 return -99;
5603 }
5604 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005605
Ed Warnickecb9cada2015-12-08 15:45:58 -07005606 if (sw_if_index_set == 0) {
5607 errmsg ("missing interface name or sw_if_index\n");
5608 return -99;
5609 }
5610
5611 if (sub_id_set == 0) {
5612 errmsg ("missing sub_id\n");
5613 return -99;
5614 }
5615 M(CREATE_SUBIF, create_subif);
5616
5617 mp->sw_if_index = ntohl(sw_if_index);
5618 mp->sub_id = ntohl(sub_id);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005619
Ed Warnickecb9cada2015-12-08 15:45:58 -07005620#define _(a) mp->a = a;
5621 foreach_create_subif_bit;
5622#undef _
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005623
Ed Warnickecb9cada2015-12-08 15:45:58 -07005624 mp->outer_vlan_id = ntohs (outer_vlan_id);
5625 mp->inner_vlan_id = ntohs (inner_vlan_id);
5626
5627 S; W;
5628 /* NOTREACHED */
5629 return 0;
5630}
5631
5632static int api_oam_add_del (vat_main_t * vam)
5633{
5634 unformat_input_t * i = vam->input;
5635 vl_api_oam_add_del_t *mp;
5636 f64 timeout;
5637 u32 vrf_id = 0;
5638 u8 is_add = 1;
5639 ip4_address_t src, dst;
5640 u8 src_set = 0;
5641 u8 dst_set = 0;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005642
Ed Warnickecb9cada2015-12-08 15:45:58 -07005643 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5644 if (unformat (i, "vrf %d", &vrf_id))
5645 ;
5646 else if (unformat (i, "src %U", unformat_ip4_address, &src))
5647 src_set = 1;
5648 else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
5649 dst_set = 1;
5650 else if (unformat (i, "del"))
5651 is_add = 0;
5652 else {
5653 clib_warning ("parse error '%U'", format_unformat_error, i);
5654 return -99;
5655 }
5656 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005657
Ed Warnickecb9cada2015-12-08 15:45:58 -07005658 if (src_set == 0) {
5659 errmsg ("missing src addr\n");
5660 return -99;
5661 }
5662
5663 if (dst_set == 0) {
5664 errmsg ("missing dst addr\n");
5665 return -99;
5666 }
5667
5668 M(OAM_ADD_DEL, oam_add_del);
5669
5670 mp->vrf_id = ntohl(vrf_id);
5671 mp->is_add = is_add;
Damjan Marionf1213b82016-03-13 02:22:06 +01005672 clib_memcpy(mp->src_address, &src, sizeof (mp->src_address));
5673 clib_memcpy(mp->dst_address, &dst, sizeof (mp->dst_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005674
5675 S; W;
5676 /* NOTREACHED */
5677 return 0;
5678}
5679
5680static int api_reset_fib (vat_main_t * vam)
5681{
5682 unformat_input_t * i = vam->input;
5683 vl_api_reset_fib_t *mp;
5684 f64 timeout;
5685 u32 vrf_id = 0;
5686 u8 is_ipv6 = 0;
5687 u8 vrf_id_set = 0;
5688
5689 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5690 if (unformat (i, "vrf %d", &vrf_id))
5691 vrf_id_set = 1;
5692 else if (unformat (i, "ipv6"))
5693 is_ipv6 = 1;
5694 else {
5695 clib_warning ("parse error '%U'", format_unformat_error, i);
5696 return -99;
5697 }
5698 }
5699
5700 if (vrf_id_set == 0) {
5701 errmsg ("missing vrf id\n");
5702 return -99;
5703 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005704
Ed Warnickecb9cada2015-12-08 15:45:58 -07005705 M(RESET_FIB, reset_fib);
5706
5707 mp->vrf_id = ntohl(vrf_id);
5708 mp->is_ipv6 = is_ipv6;
5709
5710 S; W;
5711 /* NOTREACHED */
5712 return 0;
5713}
5714
5715static int api_dhcp_proxy_config (vat_main_t * vam)
5716{
5717 unformat_input_t * i = vam->input;
5718 vl_api_dhcp_proxy_config_t *mp;
5719 f64 timeout;
5720 u32 vrf_id = 0;
5721 u8 is_add = 1;
5722 u8 insert_cid = 1;
5723 u8 v4_address_set = 0;
5724 u8 v6_address_set = 0;
5725 ip4_address_t v4address;
5726 ip6_address_t v6address;
5727 u8 v4_src_address_set = 0;
5728 u8 v6_src_address_set = 0;
5729 ip4_address_t v4srcaddress;
5730 ip6_address_t v6srcaddress;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005731
Ed Warnickecb9cada2015-12-08 15:45:58 -07005732 /* Parse args required to build the message */
5733 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5734 if (unformat (i, "del"))
5735 is_add = 0;
5736 else if (unformat (i, "vrf %d", &vrf_id))
5737 ;
5738 else if (unformat (i, "insert-cid %d", &insert_cid))
5739 ;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005740 else if (unformat (i, "svr %U",
Ed Warnickecb9cada2015-12-08 15:45:58 -07005741 unformat_ip4_address, &v4address))
5742 v4_address_set = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005743 else if (unformat (i, "svr %U",
Ed Warnickecb9cada2015-12-08 15:45:58 -07005744 unformat_ip6_address, &v6address))
5745 v6_address_set = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005746 else if (unformat (i, "src %U",
Ed Warnickecb9cada2015-12-08 15:45:58 -07005747 unformat_ip4_address, &v4srcaddress))
5748 v4_src_address_set = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005749 else if (unformat (i, "src %U",
Ed Warnickecb9cada2015-12-08 15:45:58 -07005750 unformat_ip6_address, &v6srcaddress))
5751 v6_src_address_set = 1;
5752 else
5753 break;
5754 }
5755
5756 if (v4_address_set && v6_address_set) {
5757 errmsg ("both v4 and v6 server addresses set\n");
5758 return -99;
5759 }
5760 if (!v4_address_set && !v6_address_set) {
5761 errmsg ("no server addresses set\n");
5762 return -99;
5763 }
5764
5765 if (v4_src_address_set && v6_src_address_set) {
5766 errmsg ("both v4 and v6 src addresses set\n");
5767 return -99;
5768 }
5769 if (!v4_src_address_set && !v6_src_address_set) {
5770 errmsg ("no src addresses set\n");
5771 return -99;
5772 }
5773
5774 if (!(v4_src_address_set && v4_address_set) &&
5775 !(v6_src_address_set && v6_address_set)) {
5776 errmsg ("no matching server and src addresses set\n");
5777 return -99;
5778 }
5779
5780 /* Construct the API message */
5781 M(DHCP_PROXY_CONFIG, dhcp_proxy_config);
5782
5783 mp->insert_circuit_id = insert_cid;
5784 mp->is_add = is_add;
5785 mp->vrf_id = ntohl (vrf_id);
5786 if (v6_address_set) {
5787 mp->is_ipv6 = 1;
Damjan Marionf1213b82016-03-13 02:22:06 +01005788 clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
5789 clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005790 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01005791 clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
5792 clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005793 }
5794
5795 /* send it... */
5796 S;
5797
5798 /* Wait for a reply, return good/bad news */
5799 W;
5800 /* NOTREACHED */
5801 return 0;
5802}
5803
5804static int api_dhcp_proxy_config_2 (vat_main_t * vam)
5805{
5806 unformat_input_t * i = vam->input;
5807 vl_api_dhcp_proxy_config_2_t *mp;
5808 f64 timeout;
5809 u32 rx_vrf_id = 0;
5810 u32 server_vrf_id = 0;
5811 u8 is_add = 1;
5812 u8 insert_cid = 1;
5813 u8 v4_address_set = 0;
5814 u8 v6_address_set = 0;
5815 ip4_address_t v4address;
5816 ip6_address_t v6address;
5817 u8 v4_src_address_set = 0;
5818 u8 v6_src_address_set = 0;
5819 ip4_address_t v4srcaddress;
5820 ip6_address_t v6srcaddress;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005821
Ed Warnickecb9cada2015-12-08 15:45:58 -07005822 /* Parse args required to build the message */
5823 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5824 if (unformat (i, "del"))
5825 is_add = 0;
5826 else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
5827 ;
5828 else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
5829 ;
5830 else if (unformat (i, "insert-cid %d", &insert_cid))
5831 ;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005832 else if (unformat (i, "svr %U",
Ed Warnickecb9cada2015-12-08 15:45:58 -07005833 unformat_ip4_address, &v4address))
5834 v4_address_set = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005835 else if (unformat (i, "svr %U",
Ed Warnickecb9cada2015-12-08 15:45:58 -07005836 unformat_ip6_address, &v6address))
5837 v6_address_set = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005838 else if (unformat (i, "src %U",
Ed Warnickecb9cada2015-12-08 15:45:58 -07005839 unformat_ip4_address, &v4srcaddress))
5840 v4_src_address_set = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005841 else if (unformat (i, "src %U",
Ed Warnickecb9cada2015-12-08 15:45:58 -07005842 unformat_ip6_address, &v6srcaddress))
5843 v6_src_address_set = 1;
5844 else
5845 break;
5846 }
5847
5848 if (v4_address_set && v6_address_set) {
5849 errmsg ("both v4 and v6 server addresses set\n");
5850 return -99;
5851 }
5852 if (!v4_address_set && !v6_address_set) {
5853 errmsg ("no server addresses set\n");
5854 return -99;
5855 }
5856
5857 if (v4_src_address_set && v6_src_address_set) {
5858 errmsg ("both v4 and v6 src addresses set\n");
5859 return -99;
5860 }
5861 if (!v4_src_address_set && !v6_src_address_set) {
5862 errmsg ("no src addresses set\n");
5863 return -99;
5864 }
5865
5866 if (!(v4_src_address_set && v4_address_set) &&
5867 !(v6_src_address_set && v6_address_set)) {
5868 errmsg ("no matching server and src addresses set\n");
5869 return -99;
5870 }
5871
5872 /* Construct the API message */
5873 M(DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
5874
5875 mp->insert_circuit_id = insert_cid;
5876 mp->is_add = is_add;
5877 mp->rx_vrf_id = ntohl (rx_vrf_id);
5878 mp->server_vrf_id = ntohl (server_vrf_id);
5879 if (v6_address_set) {
5880 mp->is_ipv6 = 1;
Damjan Marionf1213b82016-03-13 02:22:06 +01005881 clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
5882 clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005883 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01005884 clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
5885 clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005886 }
5887
5888 /* send it... */
5889 S;
5890
5891 /* Wait for a reply, return good/bad news */
5892 W;
5893 /* NOTREACHED */
5894 return 0;
5895}
5896
5897static int api_dhcp_proxy_set_vss (vat_main_t * vam)
5898{
5899 unformat_input_t * i = vam->input;
5900 vl_api_dhcp_proxy_set_vss_t *mp;
5901 f64 timeout;
5902 u8 is_ipv6 = 0;
5903 u8 is_add = 1;
5904 u32 tbl_id;
5905 u8 tbl_id_set = 0;
5906 u32 oui;
5907 u8 oui_set = 0;
5908 u32 fib_id;
5909 u8 fib_id_set = 0;
5910
5911 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5912 if (unformat (i, "tbl_id %d", &tbl_id))
5913 tbl_id_set = 1;
5914 if (unformat (i, "fib_id %d", &fib_id))
5915 fib_id_set = 1;
5916 if (unformat (i, "oui %d", &oui))
5917 oui_set = 1;
5918 else if (unformat (i, "ipv6"))
5919 is_ipv6 = 1;
5920 else if (unformat (i, "del"))
5921 is_add = 0;
5922 else {
5923 clib_warning ("parse error '%U'", format_unformat_error, i);
5924 return -99;
5925 }
5926 }
5927
5928 if (tbl_id_set == 0) {
5929 errmsg ("missing tbl id\n");
5930 return -99;
5931 }
5932
5933 if (fib_id_set == 0) {
5934 errmsg ("missing fib id\n");
5935 return -99;
5936 }
5937 if (oui_set == 0) {
5938 errmsg ("missing oui\n");
5939 return -99;
5940 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005941
Ed Warnickecb9cada2015-12-08 15:45:58 -07005942 M(DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
5943 mp->tbl_id = ntohl(tbl_id);
5944 mp->fib_id = ntohl(fib_id);
5945 mp->oui = ntohl(oui);
5946 mp->is_ipv6 = is_ipv6;
5947 mp->is_add = is_add;
5948
5949 S; W;
5950 /* NOTREACHED */
5951 return 0;
5952}
5953
5954static int api_dhcp_client_config (vat_main_t * vam)
5955{
5956 unformat_input_t * i = vam->input;
5957 vl_api_dhcp_client_config_t *mp;
5958 f64 timeout;
5959 u32 sw_if_index;
5960 u8 sw_if_index_set = 0;
5961 u8 is_add = 1;
5962 u8 * hostname = 0;
5963 u8 disable_event = 0;
5964
5965 /* Parse args required to build the message */
5966 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5967 if (unformat (i, "del"))
5968 is_add = 0;
5969 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5970 sw_if_index_set = 1;
5971 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5972 sw_if_index_set = 1;
5973 else if (unformat (i, "hostname %s", &hostname))
5974 ;
5975 else if (unformat (i, "disable_event"))
5976 disable_event = 1;
5977 else
5978 break;
5979 }
5980
5981 if (sw_if_index_set == 0) {
5982 errmsg ("missing interface name or sw_if_index\n");
5983 return -99;
5984 }
5985
5986 if (vec_len (hostname) > 63) {
5987 errmsg ("hostname too long\n");
5988 }
5989 vec_add1 (hostname, 0);
5990
5991 /* Construct the API message */
5992 M(DHCP_CLIENT_CONFIG, dhcp_client_config);
5993
5994 mp->sw_if_index = ntohl (sw_if_index);
Damjan Marionf1213b82016-03-13 02:22:06 +01005995 clib_memcpy (mp->hostname, hostname, vec_len (hostname));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005996 vec_free (hostname);
5997 mp->is_add = is_add;
5998 mp->want_dhcp_event = disable_event ? 0 : 1;
5999 mp->pid = getpid();
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006000
Ed Warnickecb9cada2015-12-08 15:45:58 -07006001 /* send it... */
6002 S;
6003
6004 /* Wait for a reply, return good/bad news */
6005 W;
6006 /* NOTREACHED */
6007 return 0;
6008}
6009
6010static int api_set_ip_flow_hash (vat_main_t * vam)
6011{
6012 unformat_input_t * i = vam->input;
6013 vl_api_set_ip_flow_hash_t *mp;
6014 f64 timeout;
6015 u32 vrf_id = 0;
6016 u8 is_ipv6 = 0;
6017 u8 vrf_id_set = 0;
6018 u8 src = 0;
6019 u8 dst = 0;
6020 u8 sport = 0;
6021 u8 dport = 0;
6022 u8 proto = 0;
6023 u8 reverse = 0;
6024
6025 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6026 if (unformat (i, "vrf %d", &vrf_id))
6027 vrf_id_set = 1;
6028 else if (unformat (i, "ipv6"))
6029 is_ipv6 = 1;
6030 else if (unformat (i, "src"))
6031 src = 1;
6032 else if (unformat (i, "dst"))
6033 dst = 1;
6034 else if (unformat (i, "sport"))
6035 sport = 1;
6036 else if (unformat (i, "dport"))
6037 dport = 1;
6038 else if (unformat (i, "proto"))
6039 proto = 1;
6040 else if (unformat (i, "reverse"))
6041 reverse = 1;
6042
6043 else {
6044 clib_warning ("parse error '%U'", format_unformat_error, i);
6045 return -99;
6046 }
6047 }
6048
6049 if (vrf_id_set == 0) {
6050 errmsg ("missing vrf id\n");
6051 return -99;
6052 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006053
Ed Warnickecb9cada2015-12-08 15:45:58 -07006054 M(SET_IP_FLOW_HASH, set_ip_flow_hash);
6055 mp->src = src;
6056 mp->dst = dst;
6057 mp->sport = sport;
6058 mp->dport = dport;
6059 mp->proto = proto;
6060 mp->reverse = reverse;
6061 mp->vrf_id = ntohl(vrf_id);
6062 mp->is_ipv6 = is_ipv6;
6063
6064 S; W;
6065 /* NOTREACHED */
6066 return 0;
6067}
6068
6069static int api_sw_interface_ip6_enable_disable (vat_main_t * vam)
6070{
6071 unformat_input_t * i = vam->input;
6072 vl_api_sw_interface_ip6_enable_disable_t *mp;
6073 f64 timeout;
6074 u32 sw_if_index;
6075 u8 sw_if_index_set = 0;
6076 u8 enable = 0;
6077
6078 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6079 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6080 sw_if_index_set = 1;
6081 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6082 sw_if_index_set = 1;
6083 else if (unformat (i, "enable"))
6084 enable = 1;
6085 else if (unformat (i, "disable"))
6086 enable = 0;
6087 else {
6088 clib_warning ("parse error '%U'", format_unformat_error, i);
6089 return -99;
6090 }
6091 }
6092
6093 if (sw_if_index_set == 0) {
6094 errmsg ("missing interface name or sw_if_index\n");
6095 return -99;
6096 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006097
Ed Warnickecb9cada2015-12-08 15:45:58 -07006098 M(SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
6099
6100 mp->sw_if_index = ntohl(sw_if_index);
6101 mp->enable = enable;
6102
6103 S; W;
6104 /* NOTREACHED */
6105 return 0;
6106}
6107
6108static int api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
6109{
6110 unformat_input_t * i = vam->input;
6111 vl_api_sw_interface_ip6_set_link_local_address_t *mp;
6112 f64 timeout;
6113 u32 sw_if_index;
6114 u8 sw_if_index_set = 0;
6115 u32 address_length = 0;
6116 u8 v6_address_set = 0;
6117 ip6_address_t v6address;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006118
Ed Warnickecb9cada2015-12-08 15:45:58 -07006119 /* Parse args required to build the message */
6120 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6121 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6122 sw_if_index_set = 1;
6123 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6124 sw_if_index_set = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006125 else if (unformat (i, "%U/%d",
6126 unformat_ip6_address, &v6address,
Ed Warnickecb9cada2015-12-08 15:45:58 -07006127 &address_length))
6128 v6_address_set = 1;
6129 else
6130 break;
6131 }
6132
6133 if (sw_if_index_set == 0) {
6134 errmsg ("missing interface name or sw_if_index\n");
6135 return -99;
6136 }
6137 if (!v6_address_set) {
6138 errmsg ("no address set\n");
6139 return -99;
6140 }
6141
6142 /* Construct the API message */
6143 M(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, \
6144 sw_interface_ip6_set_link_local_address);
6145
6146 mp->sw_if_index = ntohl (sw_if_index);
Damjan Marionf1213b82016-03-13 02:22:06 +01006147 clib_memcpy (mp->address, &v6address, sizeof (v6address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07006148 mp->address_length = address_length;
6149
6150 /* send it... */
6151 S;
6152
6153 /* Wait for a reply, return good/bad news */
6154 W;
6155
6156 /* NOTREACHED */
6157 return 0;
6158}
6159
6160
6161static int api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
6162{
6163 unformat_input_t * i = vam->input;
6164 vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
6165 f64 timeout;
6166 u32 sw_if_index;
6167 u8 sw_if_index_set = 0;
6168 u32 address_length = 0;
6169 u8 v6_address_set = 0;
6170 ip6_address_t v6address;
6171 u8 use_default = 0;
6172 u8 no_advertise = 0;
6173 u8 off_link = 0;
6174 u8 no_autoconfig = 0;
6175 u8 no_onlink = 0;
6176 u8 is_no = 0;
6177 u32 val_lifetime = 0;
6178 u32 pref_lifetime = 0;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006179
Ed Warnickecb9cada2015-12-08 15:45:58 -07006180 /* Parse args required to build the message */
6181 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6182 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6183 sw_if_index_set = 1;
6184 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6185 sw_if_index_set = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006186 else if (unformat (i, "%U/%d",
6187 unformat_ip6_address, &v6address,
Ed Warnickecb9cada2015-12-08 15:45:58 -07006188 &address_length))
6189 v6_address_set = 1;
6190 else if (unformat (i, "val_life %d", &val_lifetime))
6191 ;
6192 else if (unformat (i, "pref_life %d", &pref_lifetime))
6193 ;
6194 else if (unformat (i, "def"))
6195 use_default = 1;
6196 else if (unformat (i, "noadv"))
6197 no_advertise = 1;
6198 else if (unformat (i, "offl"))
6199 off_link = 1;
6200 else if (unformat (i, "noauto"))
6201 no_autoconfig = 1;
6202 else if (unformat (i, "nolink"))
6203 no_onlink = 1;
6204 else if (unformat (i, "isno"))
6205 is_no = 1;
6206 else {
6207 clib_warning ("parse error '%U'", format_unformat_error, i);
6208 return -99;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006209 }
Ed Warnickecb9cada2015-12-08 15:45:58 -07006210 }
6211
6212 if (sw_if_index_set == 0) {
6213 errmsg ("missing interface name or sw_if_index\n");
6214 return -99;
6215 }
6216 if (!v6_address_set) {
6217 errmsg ("no address set\n");
6218 return -99;
6219 }
6220
6221 /* Construct the API message */
6222 M(SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
6223
6224 mp->sw_if_index = ntohl (sw_if_index);
Damjan Marionf1213b82016-03-13 02:22:06 +01006225 clib_memcpy (mp->address, &v6address, sizeof (v6address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07006226 mp->address_length = address_length;
6227 mp->use_default = use_default;
6228 mp->no_advertise = no_advertise;
6229 mp->off_link = off_link;
6230 mp->no_autoconfig = no_autoconfig;
6231 mp->no_onlink = no_onlink;
6232 mp->is_no = is_no;
6233 mp->val_lifetime = ntohl(val_lifetime);
6234 mp->pref_lifetime = ntohl(pref_lifetime);
6235
6236 /* send it... */
6237 S;
6238
6239 /* Wait for a reply, return good/bad news */
6240 W;
6241
6242 /* NOTREACHED */
6243 return 0;
6244}
6245
6246static int api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
6247{
6248 unformat_input_t * i = vam->input;
6249 vl_api_sw_interface_ip6nd_ra_config_t *mp;
6250 f64 timeout;
6251 u32 sw_if_index;
6252 u8 sw_if_index_set = 0;
Chris Luke33879c92016-06-28 19:54:21 -04006253 u8 suppress = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -07006254 u8 managed = 0;
6255 u8 other = 0;
6256 u8 ll_option = 0;
6257 u8 send_unicast = 0;
6258 u8 cease = 0;
6259 u8 is_no = 0;
6260 u8 default_router = 0;
6261 u32 max_interval = 0;
6262 u32 min_interval = 0;
6263 u32 lifetime = 0;
6264 u32 initial_count = 0;
6265 u32 initial_interval = 0;
6266
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006267
Ed Warnickecb9cada2015-12-08 15:45:58 -07006268 /* Parse args required to build the message */
6269 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6270 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6271 sw_if_index_set = 1;
6272 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6273 sw_if_index_set = 1;
6274 else if (unformat (i, "maxint %d", &max_interval))
6275 ;
6276 else if (unformat (i, "minint %d", &min_interval))
6277 ;
6278 else if (unformat (i, "life %d", &lifetime))
6279 ;
6280 else if (unformat (i, "count %d", &initial_count))
6281 ;
6282 else if (unformat (i, "interval %d", &initial_interval))
6283 ;
Chris Luke33879c92016-06-28 19:54:21 -04006284 else if (unformat (i, "suppress") || unformat (i, "surpress"))
6285 suppress = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -07006286 else if (unformat (i, "managed"))
6287 managed = 1;
6288 else if (unformat (i, "other"))
6289 other = 1;
6290 else if (unformat (i, "ll"))
6291 ll_option = 1;
6292 else if (unformat (i, "send"))
6293 send_unicast = 1;
6294 else if (unformat (i, "cease"))
6295 cease = 1;
6296 else if (unformat (i, "isno"))
6297 is_no = 1;
6298 else if (unformat (i, "def"))
6299 default_router = 1;
6300 else {
6301 clib_warning ("parse error '%U'", format_unformat_error, i);
6302 return -99;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006303 }
Ed Warnickecb9cada2015-12-08 15:45:58 -07006304 }
6305
6306 if (sw_if_index_set == 0) {
6307 errmsg ("missing interface name or sw_if_index\n");
6308 return -99;
6309 }
6310
6311 /* Construct the API message */
6312 M(SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
6313
6314 mp->sw_if_index = ntohl (sw_if_index);
6315 mp->max_interval = ntohl(max_interval);
6316 mp->min_interval = ntohl(min_interval);
6317 mp->lifetime = ntohl(lifetime);
6318 mp->initial_count = ntohl(initial_count);
6319 mp->initial_interval = ntohl(initial_interval);
Chris Luke33879c92016-06-28 19:54:21 -04006320 mp->suppress = suppress;
Ed Warnickecb9cada2015-12-08 15:45:58 -07006321 mp->managed = managed;
6322 mp->other = other;
6323 mp->ll_option = ll_option;
6324 mp->send_unicast = send_unicast;
6325 mp->cease = cease;
6326 mp->is_no = is_no;
6327 mp->default_router = default_router;
6328
6329 /* send it... */
6330 S;
6331
6332 /* Wait for a reply, return good/bad news */
6333 W;
6334
6335 /* NOTREACHED */
6336 return 0;
6337}
6338
6339static int api_set_arp_neighbor_limit (vat_main_t * vam)
6340{
6341 unformat_input_t * i = vam->input;
6342 vl_api_set_arp_neighbor_limit_t *mp;
6343 f64 timeout;
6344 u32 arp_nbr_limit;
6345 u8 limit_set = 0;
6346 u8 is_ipv6 = 0;
6347
6348 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6349 if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
6350 limit_set = 1;
6351 else if (unformat (i, "ipv6"))
6352 is_ipv6 = 1;
6353 else {
6354 clib_warning ("parse error '%U'", format_unformat_error, i);
6355 return -99;
6356 }
6357 }
6358
6359 if (limit_set == 0) {
6360 errmsg ("missing limit value\n");
6361 return -99;
6362 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006363
Ed Warnickecb9cada2015-12-08 15:45:58 -07006364 M(SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
6365
6366 mp->arp_neighbor_limit = ntohl(arp_nbr_limit);
6367 mp->is_ipv6 = is_ipv6;
6368
6369 S; W;
6370 /* NOTREACHED */
6371 return 0;
6372}
6373
6374static int api_l2_patch_add_del (vat_main_t * vam)
6375{
6376 unformat_input_t * i = vam->input;
6377 vl_api_l2_patch_add_del_t *mp;
6378 f64 timeout;
6379 u32 rx_sw_if_index;
6380 u8 rx_sw_if_index_set = 0;
6381 u32 tx_sw_if_index;
6382 u8 tx_sw_if_index_set = 0;
6383 u8 is_add = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006384
Ed Warnickecb9cada2015-12-08 15:45:58 -07006385 /* Parse args required to build the message */
6386 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6387 if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006388 rx_sw_if_index_set = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -07006389 else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6390 tx_sw_if_index_set = 1;
6391 else if (unformat (i, "rx")) {
6392 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6393 if (unformat (i, "%U", unformat_sw_if_index, vam,
6394 &rx_sw_if_index))
6395 rx_sw_if_index_set = 1;
6396 } else
6397 break;
6398 } else if (unformat (i, "tx")) {
6399 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6400 if (unformat (i, "%U", unformat_sw_if_index, vam,
6401 &tx_sw_if_index))
6402 tx_sw_if_index_set = 1;
6403 } else
6404 break;
6405 } else if (unformat (i, "del"))
6406 is_add = 0;
6407 else
6408 break;
6409 }
6410
6411 if (rx_sw_if_index_set == 0) {
6412 errmsg ("missing rx interface name or rx_sw_if_index\n");
6413 return -99;
6414 }
6415
6416 if (tx_sw_if_index_set == 0) {
6417 errmsg ("missing tx interface name or tx_sw_if_index\n");
6418 return -99;
6419 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006420
Ed Warnickecb9cada2015-12-08 15:45:58 -07006421 M(L2_PATCH_ADD_DEL, l2_patch_add_del);
6422
6423 mp->rx_sw_if_index = ntohl(rx_sw_if_index);
6424 mp->tx_sw_if_index = ntohl(tx_sw_if_index);
6425 mp->is_add = is_add;
6426
6427 S; W;
6428 /* NOTREACHED */
6429 return 0;
6430}
Shwetha20a64f52016-03-25 10:55:01 +00006431static int api_trace_profile_add (vat_main_t *vam)
6432{
6433 unformat_input_t * input = vam->input;
6434 vl_api_trace_profile_add_t *mp;
6435 f64 timeout;
6436 u32 id = 0;
6437 u32 trace_option_elts = 0;
6438 u32 trace_type = 0, node_id = 0, app_data = 0, trace_tsp = 2;
6439 int has_pow_option = 0;
6440 int has_ppc_option = 0;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006441
Shwetha20a64f52016-03-25 10:55:01 +00006442 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
6443 {
6444 if (unformat (input, "id %d trace-type 0x%x trace-elts %d "
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006445 "trace-tsp %d node-id 0x%x app-data 0x%x",
Shwetha20a64f52016-03-25 10:55:01 +00006446 &id, &trace_type, &trace_option_elts, &trace_tsp,
6447 &node_id, &app_data))
6448 ;
6449 else if (unformat (input, "pow"))
6450 has_pow_option = 1;
6451 else if (unformat (input, "ppc encap"))
6452 has_ppc_option = PPC_ENCAP;
6453 else if (unformat (input, "ppc decap"))
6454 has_ppc_option = PPC_DECAP;
6455 else if (unformat (input, "ppc none"))
6456 has_ppc_option = PPC_NONE;
6457 else
6458 break;
6459 }
6460 M(TRACE_PROFILE_ADD, trace_profile_add);
6461 mp->id = htons(id);
6462 mp->trace_type = trace_type;
6463 mp->trace_num_elt = trace_option_elts;
6464 mp->trace_ppc = has_ppc_option;
6465 mp->trace_app_data = htonl(app_data);
6466 mp->pow_enable = has_pow_option;
6467 mp->trace_tsp = trace_tsp;
6468 mp->node_id = htonl(node_id);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006469
Shwetha20a64f52016-03-25 10:55:01 +00006470 S; W;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006471
Shwetha20a64f52016-03-25 10:55:01 +00006472 return(0);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006473
Shwetha20a64f52016-03-25 10:55:01 +00006474}
6475static int api_trace_profile_apply (vat_main_t *vam)
6476{
6477 unformat_input_t * input = vam->input;
6478 vl_api_trace_profile_apply_t *mp;
6479 f64 timeout;
6480 ip6_address_t addr;
6481 u32 mask_width = ~0;
6482 int is_add = 0;
6483 int is_pop = 0;
6484 int is_none = 0;
6485 u32 vrf_id = 0;
6486 u32 id = 0;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006487
Shwetha20a64f52016-03-25 10:55:01 +00006488 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
6489 {
6490 if (unformat (input, "%U/%d",
6491 unformat_ip6_address, &addr, &mask_width))
6492 ;
6493 else if (unformat (input, "id %d", &id))
6494 ;
6495 else if (unformat (input, "vrf-id %d", &vrf_id))
6496 ;
6497 else if (unformat (input, "add"))
6498 is_add = 1;
6499 else if (unformat (input, "pop"))
6500 is_pop = 1;
6501 else if (unformat (input, "none"))
6502 is_none = 1;
6503 else
6504 break;
6505 }
Ed Warnickecb9cada2015-12-08 15:45:58 -07006506
Shwetha20a64f52016-03-25 10:55:01 +00006507 if ((is_add + is_pop + is_none) != 1) {
6508 errmsg("One of (add, pop, none) required");
6509 return -99;
6510 }
6511 if (mask_width == ~0) {
6512 errmsg("<address>/<mask-width> required");
6513 return -99;
6514 }
6515 M(TRACE_PROFILE_APPLY, trace_profile_apply);
Damjan Marionf1213b82016-03-13 02:22:06 +01006516 clib_memcpy(mp->dest_ipv6, &addr, sizeof(mp->dest_ipv6));
Shwetha20a64f52016-03-25 10:55:01 +00006517 mp->id = htons(id);
6518 mp->prefix_length = htonl(mask_width);
6519 mp->vrf_id = htonl(vrf_id);
6520 if (is_add)
6521 mp->trace_op = IOAM_HBYH_ADD;
6522 else if (is_pop)
6523 mp->trace_op = IOAM_HBYH_POP;
6524 else
6525 mp->trace_op = IOAM_HBYH_MOD;
6526
6527 if(is_none)
6528 mp->enable = 0;
6529 else
6530 mp->enable = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006531
Shwetha20a64f52016-03-25 10:55:01 +00006532 S; W;
6533
6534 return 0;
6535}
6536
6537static int api_trace_profile_del (vat_main_t *vam)
6538{
6539 vl_api_trace_profile_del_t *mp;
6540 f64 timeout;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006541
Shwetha20a64f52016-03-25 10:55:01 +00006542 M(TRACE_PROFILE_DEL, trace_profile_del);
6543 S; W;
6544 return 0;
6545}
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07006546
Ed Warnickecb9cada2015-12-08 15:45:58 -07006547static int api_sr_tunnel_add_del (vat_main_t * vam)
6548{
6549 unformat_input_t * i = vam->input;
6550 vl_api_sr_tunnel_add_del_t *mp;
6551 f64 timeout;
6552 int is_del = 0;
6553 int pl_index;
6554 ip6_address_t src_address;
6555 int src_address_set = 0;
6556 ip6_address_t dst_address;
6557 u32 dst_mask_width;
6558 int dst_address_set = 0;
6559 u16 flags = 0;
6560 u32 rx_table_id = 0;
6561 u32 tx_table_id = 0;
6562 ip6_address_t * segments = 0;
6563 ip6_address_t * this_seg;
6564 ip6_address_t * tags = 0;
6565 ip6_address_t * this_tag;
6566 ip6_address_t next_address, tag;
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07006567 u8 * name = 0;
6568 u8 * policy_name = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -07006569
6570 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6571 {
6572 if (unformat (i, "del"))
6573 is_del = 1;
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07006574 else if (unformat (i, "name %s", &name))
6575 ;
6576 else if (unformat (i, "policy %s", &policy_name))
6577 ;
Ed Warnickecb9cada2015-12-08 15:45:58 -07006578 else if (unformat (i, "rx_fib_id %d", &rx_table_id))
6579 ;
6580 else if (unformat (i, "tx_fib_id %d", &tx_table_id))
6581 ;
6582 else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
6583 src_address_set = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006584 else if (unformat (i, "dst %U/%d",
Ed Warnickecb9cada2015-12-08 15:45:58 -07006585 unformat_ip6_address, &dst_address,
6586 &dst_mask_width))
6587 dst_address_set = 1;
6588 else if (unformat (i, "next %U", unformat_ip6_address,
6589 &next_address))
6590 {
6591 vec_add2 (segments, this_seg, 1);
Damjan Marionf1213b82016-03-13 02:22:06 +01006592 clib_memcpy (this_seg->as_u8, next_address.as_u8, sizeof (*this_seg));
Ed Warnickecb9cada2015-12-08 15:45:58 -07006593 }
6594 else if (unformat (i, "tag %U", unformat_ip6_address,
6595 &tag))
6596 {
6597 vec_add2 (tags, this_tag, 1);
Damjan Marionf1213b82016-03-13 02:22:06 +01006598 clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
Ed Warnickecb9cada2015-12-08 15:45:58 -07006599 }
6600 else if (unformat (i, "clean"))
6601 flags |= IP6_SR_HEADER_FLAG_CLEANUP;
6602 else if (unformat (i, "protected"))
6603 flags |= IP6_SR_HEADER_FLAG_PROTECTED;
6604 else if (unformat (i, "InPE %d", &pl_index))
6605 {
6606 if (pl_index <= 0 || pl_index > 4)
6607 {
6608 pl_index_range_error:
6609 errmsg ("pl index %d out of range\n", pl_index);
6610 return -99;
6611 }
6612 flags |= IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3*(pl_index - 1));
6613 }
6614 else if (unformat (i, "EgPE %d", &pl_index))
6615 {
6616 if (pl_index <= 0 || pl_index > 4)
6617 goto pl_index_range_error;
6618 flags |= IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3*(pl_index - 1));
6619 }
6620 else if (unformat (i, "OrgSrc %d", &pl_index))
6621 {
6622 if (pl_index <= 0 || pl_index > 4)
6623 goto pl_index_range_error;
6624 flags |= IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3*(pl_index - 1));
6625 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006626 else
Ed Warnickecb9cada2015-12-08 15:45:58 -07006627 break;
6628 }
6629
6630 if (!src_address_set)
6631 {
6632 errmsg ("src address required\n");
6633 return -99;
6634 }
6635
6636 if (!dst_address_set)
6637 {
6638 errmsg ("dst address required\n");
6639 return -99;
6640 }
6641
6642 if (!segments)
6643 {
6644 errmsg ("at least one sr segment required\n");
6645 return -99;
6646 }
6647
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006648 M2(SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
6649 vec_len(segments) * sizeof (ip6_address_t)
Ed Warnickecb9cada2015-12-08 15:45:58 -07006650 + vec_len(tags) * sizeof (ip6_address_t));
6651
Damjan Marionf1213b82016-03-13 02:22:06 +01006652 clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
6653 clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07006654 mp->dst_mask_width = dst_mask_width;
6655 mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
6656 mp->n_segments = vec_len (segments);
6657 mp->n_tags = vec_len (tags);
6658 mp->is_add = is_del == 0;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006659 clib_memcpy (mp->segs_and_tags, segments,
Ed Warnickecb9cada2015-12-08 15:45:58 -07006660 vec_len(segments)* sizeof (ip6_address_t));
Damjan Marionf1213b82016-03-13 02:22:06 +01006661 clib_memcpy (mp->segs_and_tags + vec_len(segments)*sizeof (ip6_address_t),
Ed Warnickecb9cada2015-12-08 15:45:58 -07006662 tags, vec_len(tags)* sizeof (ip6_address_t));
6663
6664 mp->outer_vrf_id = ntohl (rx_table_id);
6665 mp->inner_vrf_id = ntohl (tx_table_id);
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07006666 memcpy (mp->name, name, vec_len(name));
6667 memcpy (mp->policy_name, policy_name, vec_len(policy_name));
Ed Warnickecb9cada2015-12-08 15:45:58 -07006668
6669 vec_free (segments);
6670 vec_free (tags);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006671
Ed Warnickecb9cada2015-12-08 15:45:58 -07006672 S; W;
6673 /* NOTREACHED */
6674}
6675
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07006676static int api_sr_policy_add_del (vat_main_t * vam)
6677{
6678 unformat_input_t * input = vam->input;
6679 vl_api_sr_policy_add_del_t *mp;
6680 f64 timeout;
6681 int is_del = 0;
6682 u8 * name = 0;
6683 u8 * tunnel_name = 0;
6684 u8 ** tunnel_names = 0;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006685
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07006686 int name_set = 0 ;
6687 int tunnel_set = 0;
6688 int j = 0;
6689 int tunnel_names_length = 1; // Init to 1 to offset the #tunnel_names counter byte
6690 int tun_name_len = 0; // Different naming convention used as confusing these would be "bad" (TM)
6691
6692 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
6693 {
6694 if (unformat (input, "del"))
6695 is_del = 1;
6696 else if (unformat (input, "name %s", &name))
6697 name_set = 1;
6698 else if (unformat (input, "tunnel %s", &tunnel_name))
6699 {
6700 if (tunnel_name)
6701 {
6702 vec_add1 (tunnel_names, tunnel_name);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006703 /* For serializer:
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07006704 - length = #bytes to store in serial vector
6705 - +1 = byte to store that length
6706 */
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006707 tunnel_names_length += (vec_len (tunnel_name) + 1);
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07006708 tunnel_set = 1;
6709 tunnel_name = 0;
6710 }
6711 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006712 else
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07006713 break;
6714 }
6715
6716 if (!name_set)
6717 {
6718 errmsg ("policy name required\n");
6719 return -99;
6720 }
6721
6722 if ((!tunnel_set) && (!is_del))
6723 {
6724 errmsg ("tunnel name required\n");
6725 return -99;
6726 }
6727
6728 M2(SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
6729
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006730
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07006731
6732 mp->is_add = !is_del;
6733
6734 memcpy (mp->name, name, vec_len(name));
6735 // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
6736 u8 * serial_orig = 0;
6737 vec_validate (serial_orig, tunnel_names_length);
6738 *serial_orig = vec_len(tunnel_names); // Store the number of tunnels as length in first byte of serialized vector
6739 serial_orig += 1; // Move along one byte to store the length of first tunnel_name
6740
6741 for (j=0; j < vec_len(tunnel_names); j++)
6742 {
6743 tun_name_len = vec_len (tunnel_names[j]);
6744 *serial_orig = tun_name_len; // Store length of tunnel name in first byte of Length/Value pair
6745 serial_orig += 1; // Move along one byte to store the actual tunnel name
6746 memcpy (serial_orig, tunnel_names[j], tun_name_len);
6747 serial_orig += tun_name_len; // Advance past the copy
6748 }
6749 memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length); // Regress serial_orig to head then copy fwd
6750
6751 vec_free (tunnel_names);
6752 vec_free (tunnel_name);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006753
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07006754 S; W;
6755 /* NOTREACHED */
6756}
6757
6758static int api_sr_multicast_map_add_del (vat_main_t * vam)
6759{
6760 unformat_input_t * input = vam->input;
6761 vl_api_sr_multicast_map_add_del_t *mp;
6762 f64 timeout;
6763 int is_del = 0;
6764 ip6_address_t multicast_address;
6765 u8 * policy_name = 0;
6766 int multicast_address_set = 0;
6767
6768 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
6769 {
6770 if (unformat (input, "del"))
6771 is_del = 1;
6772 else if (unformat (input, "address %U", unformat_ip6_address, &multicast_address))
6773 multicast_address_set = 1;
6774 else if (unformat (input, "sr-policy %s", &policy_name))
6775 ;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006776 else
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07006777 break;
6778 }
6779
6780 if (!is_del && !policy_name)
6781 {
6782 errmsg ("sr-policy name required\n");
6783 return -99;
6784 }
6785
6786
6787 if (!multicast_address_set)
6788 {
6789 errmsg ("address required\n");
6790 return -99;
6791 }
6792
6793 M(SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
6794
6795 mp->is_add = !is_del;
6796 memcpy (mp->policy_name, policy_name, vec_len(policy_name));
6797 clib_memcpy (mp->multicast_address, &multicast_address, sizeof (mp->multicast_address));
6798
6799
6800 vec_free (policy_name);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006801
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07006802 S; W;
6803 /* NOTREACHED */
6804}
6805
Ed Warnickecb9cada2015-12-08 15:45:58 -07006806
6807#define foreach_ip4_proto_field \
6808_(src_address) \
6809_(dst_address) \
6810_(tos) \
6811_(length) \
6812_(fragment_id) \
6813_(ttl) \
6814_(protocol) \
6815_(checksum)
6816
6817uword unformat_ip4_mask (unformat_input_t * input, va_list * args)
6818{
6819 u8 ** maskp = va_arg (*args, u8 **);
6820 u8 * mask = 0;
6821 u8 found_something = 0;
6822 ip4_header_t * ip;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006823
Ed Warnickecb9cada2015-12-08 15:45:58 -07006824#define _(a) u8 a=0;
6825 foreach_ip4_proto_field;
6826#undef _
6827 u8 version = 0;
6828 u8 hdr_length = 0;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006829
6830
6831 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
Ed Warnickecb9cada2015-12-08 15:45:58 -07006832 {
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006833 if (unformat (input, "version"))
Ed Warnickecb9cada2015-12-08 15:45:58 -07006834 version = 1;
6835 else if (unformat (input, "hdr_length"))
6836 hdr_length = 1;
6837 else if (unformat (input, "src"))
6838 src_address = 1;
6839 else if (unformat (input, "dst"))
6840 dst_address = 1;
6841 else if (unformat (input, "proto"))
6842 protocol = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006843
Ed Warnickecb9cada2015-12-08 15:45:58 -07006844#define _(a) else if (unformat (input, #a)) a=1;
6845 foreach_ip4_proto_field
6846#undef _
6847 else
6848 break;
6849 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006850
Ed Warnickecb9cada2015-12-08 15:45:58 -07006851#define _(a) found_something += a;
6852 foreach_ip4_proto_field;
6853#undef _
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006854
Ed Warnickecb9cada2015-12-08 15:45:58 -07006855 if (found_something == 0)
6856 return 0;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006857
Ed Warnickecb9cada2015-12-08 15:45:58 -07006858 vec_validate (mask, sizeof (*ip) - 1);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006859
Ed Warnickecb9cada2015-12-08 15:45:58 -07006860 ip = (ip4_header_t *) mask;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006861
Ed Warnickecb9cada2015-12-08 15:45:58 -07006862#define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
6863 foreach_ip4_proto_field;
6864#undef _
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006865
Ed Warnickecb9cada2015-12-08 15:45:58 -07006866 ip->ip_version_and_header_length = 0;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006867
Ed Warnickecb9cada2015-12-08 15:45:58 -07006868 if (version)
6869 ip->ip_version_and_header_length |= 0xF0;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006870
Ed Warnickecb9cada2015-12-08 15:45:58 -07006871 if (hdr_length)
6872 ip->ip_version_and_header_length |= 0x0F;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006873
Ed Warnickecb9cada2015-12-08 15:45:58 -07006874 *maskp = mask;
6875 return 1;
6876}
6877
6878#define foreach_ip6_proto_field \
6879_(src_address) \
6880_(dst_address) \
6881_(payload_length) \
6882_(hop_limit) \
6883_(protocol)
6884
6885uword unformat_ip6_mask (unformat_input_t * input, va_list * args)
6886{
6887 u8 ** maskp = va_arg (*args, u8 **);
6888 u8 * mask = 0;
6889 u8 found_something = 0;
6890 ip6_header_t * ip;
6891 u32 ip_version_traffic_class_and_flow_label;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006892
Ed Warnickecb9cada2015-12-08 15:45:58 -07006893#define _(a) u8 a=0;
6894 foreach_ip6_proto_field;
6895#undef _
6896 u8 version = 0;
6897 u8 traffic_class = 0;
6898 u8 flow_label = 0;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006899
6900 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
Ed Warnickecb9cada2015-12-08 15:45:58 -07006901 {
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006902 if (unformat (input, "version"))
Ed Warnickecb9cada2015-12-08 15:45:58 -07006903 version = 1;
6904 else if (unformat (input, "traffic-class"))
6905 traffic_class = 1;
6906 else if (unformat (input, "flow-label"))
6907 flow_label = 1;
6908 else if (unformat (input, "src"))
6909 src_address = 1;
6910 else if (unformat (input, "dst"))
6911 dst_address = 1;
6912 else if (unformat (input, "proto"))
6913 protocol = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006914
Ed Warnickecb9cada2015-12-08 15:45:58 -07006915#define _(a) else if (unformat (input, #a)) a=1;
6916 foreach_ip6_proto_field
6917#undef _
6918 else
6919 break;
6920 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006921
Ed Warnickecb9cada2015-12-08 15:45:58 -07006922#define _(a) found_something += a;
6923 foreach_ip6_proto_field;
6924#undef _
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006925
Ed Warnickecb9cada2015-12-08 15:45:58 -07006926 if (found_something == 0)
6927 return 0;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006928
Ed Warnickecb9cada2015-12-08 15:45:58 -07006929 vec_validate (mask, sizeof (*ip) - 1);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006930
Ed Warnickecb9cada2015-12-08 15:45:58 -07006931 ip = (ip6_header_t *) mask;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006932
Ed Warnickecb9cada2015-12-08 15:45:58 -07006933#define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
6934 foreach_ip6_proto_field;
6935#undef _
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006936
Ed Warnickecb9cada2015-12-08 15:45:58 -07006937 ip_version_traffic_class_and_flow_label = 0;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006938
Ed Warnickecb9cada2015-12-08 15:45:58 -07006939 if (version)
6940 ip_version_traffic_class_and_flow_label |= 0xF0000000;
6941
6942 if (traffic_class)
6943 ip_version_traffic_class_and_flow_label |= 0x0FF00000;
6944
6945 if (flow_label)
6946 ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
6947
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006948 ip->ip_version_traffic_class_and_flow_label =
Ed Warnickecb9cada2015-12-08 15:45:58 -07006949 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006950
Ed Warnickecb9cada2015-12-08 15:45:58 -07006951 *maskp = mask;
6952 return 1;
6953}
6954
6955uword unformat_l3_mask (unformat_input_t * input, va_list * args)
6956{
6957 u8 ** maskp = va_arg (*args, u8 **);
6958
6959 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
6960 if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
6961 return 1;
6962 else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
6963 return 1;
6964 else
6965 break;
6966 }
6967 return 0;
6968}
6969
6970uword unformat_l2_mask (unformat_input_t * input, va_list * args)
6971{
6972 u8 ** maskp = va_arg (*args, u8 **);
6973 u8 * mask = 0;
6974 u8 src = 0;
6975 u8 dst = 0;
6976 u8 proto = 0;
6977 u8 tag1 = 0;
6978 u8 tag2 = 0;
6979 u8 ignore_tag1 = 0;
6980 u8 ignore_tag2 = 0;
6981 u8 cos1 = 0;
6982 u8 cos2 = 0;
6983 u8 dot1q = 0;
6984 u8 dot1ad = 0;
6985 int len = 14;
6986
6987 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
6988 if (unformat (input, "src"))
6989 src = 1;
6990 else if (unformat (input, "dst"))
6991 dst = 1;
6992 else if (unformat (input, "proto"))
6993 proto = 1;
6994 else if (unformat (input, "tag1"))
6995 tag1 = 1;
6996 else if (unformat (input, "tag2"))
6997 tag2 = 1;
6998 else if (unformat (input, "ignore-tag1"))
6999 ignore_tag1 = 1;
7000 else if (unformat (input, "ignore-tag2"))
7001 ignore_tag2 = 1;
7002 else if (unformat (input, "cos1"))
7003 cos1 = 1;
7004 else if (unformat (input, "cos2"))
7005 cos2 = 1;
7006 else if (unformat (input, "dot1q"))
7007 dot1q = 1;
7008 else if (unformat (input, "dot1ad"))
7009 dot1ad = 1;
7010 else
7011 break;
7012 }
7013 if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
7014 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
7015 return 0;
7016
7017 if (tag1 || ignore_tag1 || cos1 || dot1q)
7018 len = 18;
7019 if (tag2 || ignore_tag2 || cos2 || dot1ad)
7020 len = 22;
7021
7022 vec_validate (mask, len-1);
7023
7024 if (dst)
7025 memset (mask, 0xff, 6);
7026
7027 if (src)
7028 memset (mask + 6, 0xff, 6);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007029
Ed Warnickecb9cada2015-12-08 15:45:58 -07007030 if (tag2 || dot1ad)
7031 {
7032 /* inner vlan tag */
7033 if (tag2)
7034 {
7035 mask[19] = 0xff;
7036 mask[18] = 0x0f;
7037 }
7038 if (cos2)
7039 mask[18] |= 0xe0;
7040 if (proto)
7041 mask[21] = mask [20] = 0xff;
7042 if (tag1)
7043 {
7044 mask [15] = 0xff;
7045 mask [14] = 0x0f;
7046 }
7047 if (cos1)
7048 mask[14] |= 0xe0;
7049 *maskp = mask;
7050 return 1;
7051 }
7052 if (tag1 | dot1q)
7053 {
7054 if (tag1)
7055 {
7056 mask [15] = 0xff;
7057 mask [14] = 0x0f;
7058 }
7059 if (cos1)
7060 mask[14] |= 0xe0;
7061 if (proto)
7062 mask[16] = mask [17] = 0xff;
7063
7064 *maskp = mask;
7065 return 1;
7066 }
7067 if (cos2)
7068 mask[18] |= 0xe0;
7069 if (cos1)
7070 mask[14] |= 0xe0;
7071 if (proto)
7072 mask[12] = mask [13] = 0xff;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007073
Ed Warnickecb9cada2015-12-08 15:45:58 -07007074 *maskp = mask;
7075 return 1;
7076}
7077
7078uword unformat_classify_mask (unformat_input_t * input, va_list * args)
7079{
7080 u8 ** maskp = va_arg (*args, u8 **);
7081 u32 * skipp = va_arg (*args, u32 *);
7082 u32 * matchp = va_arg (*args, u32 *);
7083 u32 match;
7084 u8 * mask = 0;
7085 u8 * l2 = 0;
7086 u8 * l3 = 0;
7087 int i;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007088
Ed Warnickecb9cada2015-12-08 15:45:58 -07007089 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
7090 if (unformat (input, "hex %U", unformat_hex_string, &mask))
7091 ;
7092 else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
7093 ;
7094 else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
7095 ;
7096 else
7097 break;
7098 }
7099
7100 if (mask || l2 || l3)
7101 {
7102 if (l2 || l3)
7103 {
7104 /* "With a free Ethernet header in every package" */
7105 if (l2 == 0)
7106 vec_validate (l2, 13);
7107 mask = l2;
7108 vec_append (mask, l3);
7109 vec_free (l3);
7110 }
7111
7112 /* Scan forward looking for the first significant mask octet */
7113 for (i = 0; i < vec_len (mask); i++)
7114 if (mask[i])
7115 break;
7116
7117 /* compute (skip, match) params */
7118 *skipp = i / sizeof(u32x4);
7119 vec_delete (mask, *skipp * sizeof(u32x4), 0);
7120
7121 /* Pad mask to an even multiple of the vector size */
7122 while (vec_len (mask) % sizeof (u32x4))
7123 vec_add1 (mask, 0);
7124
7125 match = vec_len (mask) / sizeof (u32x4);
7126
7127 for (i = match*sizeof(u32x4); i > 0; i-= sizeof(u32x4))
7128 {
7129 u64 *tmp = (u64 *)(mask + (i-sizeof(u32x4)));
7130 if (*tmp || *(tmp+1))
7131 break;
7132 match--;
7133 }
7134 if (match == 0)
7135 clib_warning ("BUG: match 0");
7136
7137 _vec_len (mask) = match * sizeof(u32x4);
7138
7139 *matchp = match;
7140 *maskp = mask;
7141
7142 return 1;
7143 }
7144
7145 return 0;
7146}
7147
7148#define foreach_l2_next \
7149_(drop, DROP) \
7150_(ethernet, ETHERNET_INPUT) \
7151_(ip4, IP4_INPUT) \
7152_(ip6, IP6_INPUT)
7153
7154uword unformat_l2_next_index (unformat_input_t * input, va_list * args)
7155{
7156 u32 * miss_next_indexp = va_arg (*args, u32 *);
7157 u32 next_index = 0;
7158 u32 tmp;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007159
Ed Warnickecb9cada2015-12-08 15:45:58 -07007160#define _(n,N) \
7161 if (unformat (input, #n)) { next_index = L2_CLASSIFY_NEXT_##N; goto out;}
7162 foreach_l2_next;
7163#undef _
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007164
Ed Warnickecb9cada2015-12-08 15:45:58 -07007165 if (unformat (input, "%d", &tmp))
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007166 {
7167 next_index = tmp;
7168 goto out;
Ed Warnickecb9cada2015-12-08 15:45:58 -07007169 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007170
Ed Warnickecb9cada2015-12-08 15:45:58 -07007171 return 0;
7172
7173 out:
7174 *miss_next_indexp = next_index;
7175 return 1;
7176}
7177
7178#define foreach_ip_next \
7179_(miss, MISS) \
7180_(drop, DROP) \
7181_(local, LOCAL) \
7182_(rewrite, REWRITE)
7183
7184uword unformat_ip_next_index (unformat_input_t * input, va_list * args)
7185{
7186 u32 * miss_next_indexp = va_arg (*args, u32 *);
7187 u32 next_index = 0;
7188 u32 tmp;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007189
Ed Warnickecb9cada2015-12-08 15:45:58 -07007190#define _(n,N) \
7191 if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
7192 foreach_ip_next;
7193#undef _
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007194
Ed Warnickecb9cada2015-12-08 15:45:58 -07007195 if (unformat (input, "%d", &tmp))
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007196 {
7197 next_index = tmp;
7198 goto out;
Ed Warnickecb9cada2015-12-08 15:45:58 -07007199 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007200
Ed Warnickecb9cada2015-12-08 15:45:58 -07007201 return 0;
7202
7203 out:
7204 *miss_next_indexp = next_index;
7205 return 1;
7206}
7207
7208#define foreach_acl_next \
7209_(deny, DENY)
7210
7211uword unformat_acl_next_index (unformat_input_t * input, va_list * args)
7212{
7213 u32 * miss_next_indexp = va_arg (*args, u32 *);
7214 u32 next_index = 0;
7215 u32 tmp;
7216
7217#define _(n,N) \
7218 if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
7219 foreach_acl_next;
7220#undef _
7221
7222 if (unformat (input, "permit"))
7223 {
7224 next_index = ~0;
7225 goto out;
7226 }
7227 else if (unformat (input, "%d", &tmp))
7228 {
7229 next_index = tmp;
7230 goto out;
7231 }
7232
7233 return 0;
7234
7235 out:
7236 *miss_next_indexp = next_index;
7237 return 1;
7238}
7239
Matus Fabian70e6a8d2016-06-20 08:10:42 -07007240uword unformat_policer_precolor (unformat_input_t * input, va_list * args)
7241{
7242 u32 * r = va_arg (*args, u32 *);
7243
7244 if (unformat (input, "conform-color"))
7245 *r = POLICE_CONFORM;
7246 else if (unformat (input, "exceed-color"))
7247 *r = POLICE_EXCEED;
7248 else
7249 return 0;
7250
7251 return 1;
7252}
7253
Ed Warnickecb9cada2015-12-08 15:45:58 -07007254static int api_classify_add_del_table (vat_main_t * vam)
7255{
7256 unformat_input_t * i = vam->input;
7257 vl_api_classify_add_del_table_t *mp;
7258
7259 u32 nbuckets = 2;
7260 u32 skip = ~0;
7261 u32 match = ~0;
7262 int is_add = 1;
7263 u32 table_index = ~0;
7264 u32 next_table_index = ~0;
7265 u32 miss_next_index = ~0;
7266 u32 memory_size = 32<<20;
7267 u8 * mask = 0;
7268 f64 timeout;
7269
7270 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7271 if (unformat (i, "del"))
7272 is_add = 0;
7273 else if (unformat (i, "buckets %d", &nbuckets))
7274 ;
7275 else if (unformat (i, "memory_size %d", &memory_size))
7276 ;
7277 else if (unformat (i, "skip %d", &skip))
7278 ;
7279 else if (unformat (i, "match %d", &match))
7280 ;
7281 else if (unformat (i, "table %d", &table_index))
7282 ;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007283 else if (unformat (i, "mask %U", unformat_classify_mask,
Ed Warnickecb9cada2015-12-08 15:45:58 -07007284 &mask, &skip, &match))
7285 ;
7286 else if (unformat (i, "next-table %d", &next_table_index))
7287 ;
7288 else if (unformat (i, "miss-next %U", unformat_ip_next_index,
7289 &miss_next_index))
7290 ;
7291 else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
7292 &miss_next_index))
7293 ;
7294 else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
7295 &miss_next_index))
7296 ;
7297 else
7298 break;
7299 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007300
Ed Warnickecb9cada2015-12-08 15:45:58 -07007301 if (is_add && mask == 0) {
7302 errmsg ("Mask required\n");
7303 return -99;
7304 }
7305
7306 if (is_add && skip == ~0) {
7307 errmsg ("skip count required\n");
7308 return -99;
7309 }
7310
7311 if (is_add && match == ~0) {
7312 errmsg ("match count required\n");
7313 return -99;
7314 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007315
Ed Warnickecb9cada2015-12-08 15:45:58 -07007316 if (!is_add && table_index == ~0) {
7317 errmsg ("table index required for delete\n");
7318 return -99;
7319 }
7320
7321 M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table,
7322 vec_len(mask));
7323
7324 mp->is_add = is_add;
7325 mp->table_index = ntohl(table_index);
7326 mp->nbuckets = ntohl(nbuckets);
7327 mp->memory_size = ntohl(memory_size);
7328 mp->skip_n_vectors = ntohl(skip);
7329 mp->match_n_vectors = ntohl(match);
7330 mp->next_table_index = ntohl(next_table_index);
7331 mp->miss_next_index = ntohl(miss_next_index);
Damjan Marionf1213b82016-03-13 02:22:06 +01007332 clib_memcpy (mp->mask, mask, vec_len(mask));
Ed Warnickecb9cada2015-12-08 15:45:58 -07007333
7334 vec_free(mask);
7335
7336 S; W;
7337 /* NOTREACHED */
7338}
7339
7340uword unformat_ip4_match (unformat_input_t * input, va_list * args)
7341{
7342 u8 ** matchp = va_arg (*args, u8 **);
7343 u8 * match = 0;
7344 ip4_header_t * ip;
7345 int version = 0;
7346 u32 version_val;
7347 int hdr_length = 0;
7348 u32 hdr_length_val;
7349 int src = 0, dst = 0;
7350 ip4_address_t src_val, dst_val;
7351 int proto = 0;
7352 u32 proto_val;
7353 int tos = 0;
7354 u32 tos_val;
7355 int length = 0;
7356 u32 length_val;
7357 int fragment_id = 0;
7358 u32 fragment_id_val;
7359 int ttl = 0;
7360 int ttl_val;
7361 int checksum = 0;
7362 u32 checksum_val;
7363
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007364 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
Ed Warnickecb9cada2015-12-08 15:45:58 -07007365 {
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007366 if (unformat (input, "version %d", &version_val))
Ed Warnickecb9cada2015-12-08 15:45:58 -07007367 version = 1;
7368 else if (unformat (input, "hdr_length %d", &hdr_length_val))
7369 hdr_length = 1;
7370 else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
7371 src = 1;
7372 else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
7373 dst = 1;
7374 else if (unformat (input, "proto %d", &proto_val))
7375 proto = 1;
7376 else if (unformat (input, "tos %d", &tos_val))
7377 tos = 1;
7378 else if (unformat (input, "length %d", &length_val))
7379 length = 1;
7380 else if (unformat (input, "fragment_id %d", &fragment_id_val))
7381 fragment_id = 1;
7382 else if (unformat (input, "ttl %d", &ttl_val))
7383 ttl = 1;
7384 else if (unformat (input, "checksum %d", &checksum_val))
7385 checksum = 1;
7386 else
7387 break;
7388 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007389
Ed Warnickecb9cada2015-12-08 15:45:58 -07007390 if (version + hdr_length + src + dst + proto + tos + length + fragment_id
7391 + ttl + checksum == 0)
7392 return 0;
7393
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007394 /*
Ed Warnickecb9cada2015-12-08 15:45:58 -07007395 * Aligned because we use the real comparison functions
7396 */
7397 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof(u32x4));
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007398
Ed Warnickecb9cada2015-12-08 15:45:58 -07007399 ip = (ip4_header_t *) match;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007400
Ed Warnickecb9cada2015-12-08 15:45:58 -07007401 /* These are realistically matched in practice */
7402 if (src)
7403 ip->src_address.as_u32 = src_val.as_u32;
7404
7405 if (dst)
7406 ip->dst_address.as_u32 = dst_val.as_u32;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007407
Ed Warnickecb9cada2015-12-08 15:45:58 -07007408 if (proto)
7409 ip->protocol = proto_val;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007410
Ed Warnickecb9cada2015-12-08 15:45:58 -07007411
7412 /* These are not, but they're included for completeness */
7413 if (version)
7414 ip->ip_version_and_header_length |= (version_val & 0xF)<<4;
7415
7416 if (hdr_length)
7417 ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007418
Ed Warnickecb9cada2015-12-08 15:45:58 -07007419 if (tos)
7420 ip->tos = tos_val;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007421
Ed Warnickecb9cada2015-12-08 15:45:58 -07007422 if (length)
7423 ip->length = length_val;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007424
Ed Warnickecb9cada2015-12-08 15:45:58 -07007425 if (ttl)
7426 ip->ttl = ttl_val;
7427
7428 if (checksum)
7429 ip->checksum = checksum_val;
7430
7431 *matchp = match;
7432 return 1;
7433}
7434
7435uword unformat_ip6_match (unformat_input_t * input, va_list * args)
7436{
7437 u8 ** matchp = va_arg (*args, u8 **);
7438 u8 * match = 0;
7439 ip6_header_t * ip;
7440 int version = 0;
7441 u32 version_val;
7442 u8 traffic_class;
7443 u32 traffic_class_val;
7444 u8 flow_label;
7445 u8 flow_label_val;
7446 int src = 0, dst = 0;
7447 ip6_address_t src_val, dst_val;
7448 int proto = 0;
7449 u32 proto_val;
7450 int payload_length = 0;
7451 u32 payload_length_val;
7452 int hop_limit = 0;
7453 int hop_limit_val;
7454 u32 ip_version_traffic_class_and_flow_label;
7455
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007456 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
Ed Warnickecb9cada2015-12-08 15:45:58 -07007457 {
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007458 if (unformat (input, "version %d", &version_val))
Ed Warnickecb9cada2015-12-08 15:45:58 -07007459 version = 1;
7460 else if (unformat (input, "traffic_class %d", &traffic_class_val))
7461 traffic_class = 1;
7462 else if (unformat (input, "flow_label %d", &flow_label_val))
7463 flow_label = 1;
7464 else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
7465 src = 1;
7466 else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
7467 dst = 1;
7468 else if (unformat (input, "proto %d", &proto_val))
7469 proto = 1;
7470 else if (unformat (input, "payload_length %d", &payload_length_val))
7471 payload_length = 1;
7472 else if (unformat (input, "hop_limit %d", &hop_limit_val))
7473 hop_limit = 1;
7474 else
7475 break;
7476 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007477
Ed Warnickecb9cada2015-12-08 15:45:58 -07007478 if (version + traffic_class + flow_label + src + dst + proto +
7479 payload_length + hop_limit == 0)
7480 return 0;
7481
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007482 /*
Ed Warnickecb9cada2015-12-08 15:45:58 -07007483 * Aligned because we use the real comparison functions
7484 */
7485 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof(u32x4));
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007486
Ed Warnickecb9cada2015-12-08 15:45:58 -07007487 ip = (ip6_header_t *) match;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007488
Ed Warnickecb9cada2015-12-08 15:45:58 -07007489 if (src)
Damjan Marionf1213b82016-03-13 02:22:06 +01007490 clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07007491
7492 if (dst)
Damjan Marionf1213b82016-03-13 02:22:06 +01007493 clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007494
Ed Warnickecb9cada2015-12-08 15:45:58 -07007495 if (proto)
7496 ip->protocol = proto_val;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007497
Ed Warnickecb9cada2015-12-08 15:45:58 -07007498 ip_version_traffic_class_and_flow_label = 0;
7499
7500 if (version)
7501 ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
7502
7503 if (traffic_class)
7504 ip_version_traffic_class_and_flow_label |= (traffic_class_val & 0xFF) << 20;
7505
7506 if (flow_label)
7507 ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007508
7509 ip->ip_version_traffic_class_and_flow_label =
Ed Warnickecb9cada2015-12-08 15:45:58 -07007510 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
7511
7512 if (payload_length)
7513 ip->payload_length = clib_host_to_net_u16 (payload_length_val);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007514
Ed Warnickecb9cada2015-12-08 15:45:58 -07007515 if (hop_limit)
7516 ip->hop_limit = hop_limit_val;
7517
7518 *matchp = match;
7519 return 1;
7520}
7521
7522uword unformat_l3_match (unformat_input_t * input, va_list * args)
7523{
7524 u8 ** matchp = va_arg (*args, u8 **);
7525
7526 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
7527 if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
7528 return 1;
7529 else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
7530 return 1;
7531 else
7532 break;
7533 }
7534 return 0;
7535}
7536
7537uword unformat_vlan_tag (unformat_input_t * input, va_list * args)
7538{
7539 u8 * tagp = va_arg (*args, u8 *);
7540 u32 tag;
7541
7542 if (unformat(input, "%d", &tag))
7543 {
7544 tagp[0] = (tag>>8) & 0x0F;
7545 tagp[1] = tag & 0xFF;
7546 return 1;
7547 }
7548
7549 return 0;
7550}
7551
7552uword unformat_l2_match (unformat_input_t * input, va_list * args)
7553{
7554 u8 ** matchp = va_arg (*args, u8 **);
7555 u8 * match = 0;
7556 u8 src = 0;
7557 u8 src_val[6];
7558 u8 dst = 0;
7559 u8 dst_val[6];
7560 u8 proto = 0;
7561 u16 proto_val;
7562 u8 tag1 = 0;
7563 u8 tag1_val [2];
7564 u8 tag2 = 0;
7565 u8 tag2_val [2];
7566 int len = 14;
7567 u8 ignore_tag1 = 0;
7568 u8 ignore_tag2 = 0;
7569 u8 cos1 = 0;
7570 u8 cos2 = 0;
7571 u32 cos1_val = 0;
7572 u32 cos2_val = 0;
7573
7574 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
7575 if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
7576 src = 1;
7577 else if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
7578 dst = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007579 else if (unformat (input, "proto %U",
Ed Warnickecb9cada2015-12-08 15:45:58 -07007580 unformat_ethernet_type_host_byte_order, &proto_val))
7581 proto = 1;
7582 else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
7583 tag1 = 1;
7584 else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
7585 tag2 = 1;
7586 else if (unformat (input, "ignore-tag1"))
7587 ignore_tag1 = 1;
7588 else if (unformat (input, "ignore-tag2"))
7589 ignore_tag2 = 1;
7590 else if (unformat (input, "cos1 %d", &cos1_val))
7591 cos1 = 1;
7592 else if (unformat (input, "cos2 %d", &cos2_val))
7593 cos2 = 1;
7594 else
7595 break;
7596 }
7597 if ((src + dst + proto + tag1 + tag2 +
7598 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
7599 return 0;
7600
7601 if (tag1 || ignore_tag1 || cos1)
7602 len = 18;
7603 if (tag2 || ignore_tag2 || cos2)
7604 len = 22;
7605
7606 vec_validate_aligned (match, len-1, sizeof(u32x4));
7607
7608 if (dst)
Damjan Marionf1213b82016-03-13 02:22:06 +01007609 clib_memcpy (match, dst_val, 6);
Ed Warnickecb9cada2015-12-08 15:45:58 -07007610
7611 if (src)
Damjan Marionf1213b82016-03-13 02:22:06 +01007612 clib_memcpy (match + 6, src_val, 6);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007613
Ed Warnickecb9cada2015-12-08 15:45:58 -07007614 if (tag2)
7615 {
7616 /* inner vlan tag */
7617 match[19] = tag2_val[1];
7618 match[18] = tag2_val[0];
7619 if (cos2)
7620 match [18] |= (cos2_val & 0x7) << 5;
7621 if (proto)
7622 {
7623 match[21] = proto_val & 0xff;
7624 match[20] = proto_val >> 8;
7625 }
7626 if (tag1)
7627 {
7628 match [15] = tag1_val[1];
7629 match [14] = tag1_val[0];
7630 }
7631 if (cos1)
7632 match [14] |= (cos1_val & 0x7) << 5;
7633 *matchp = match;
7634 return 1;
7635 }
7636 if (tag1)
7637 {
7638 match [15] = tag1_val[1];
7639 match [14] = tag1_val[0];
7640 if (proto)
7641 {
7642 match[17] = proto_val & 0xff;
7643 match[16] = proto_val >> 8;
7644 }
7645 if (cos1)
7646 match [14] |= (cos1_val & 0x7) << 5;
7647
7648 *matchp = match;
7649 return 1;
7650 }
7651 if (cos2)
7652 match [18] |= (cos2_val & 0x7) << 5;
7653 if (cos1)
7654 match [14] |= (cos1_val & 0x7) << 5;
7655 if (proto)
7656 {
7657 match[13] = proto_val & 0xff;
7658 match[12] = proto_val >> 8;
7659 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007660
Ed Warnickecb9cada2015-12-08 15:45:58 -07007661 *matchp = match;
7662 return 1;
7663}
7664
7665
7666uword unformat_classify_match (unformat_input_t * input, va_list * args)
7667{
7668 u8 ** matchp = va_arg (*args, u8 **);
7669 u32 skip_n_vectors = va_arg (*args, u32);
7670 u32 match_n_vectors = va_arg (*args, u32);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007671
Ed Warnickecb9cada2015-12-08 15:45:58 -07007672 u8 * match = 0;
7673 u8 * l2 = 0;
7674 u8 * l3 = 0;
7675
7676 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
7677 if (unformat (input, "hex %U", unformat_hex_string, &match))
7678 ;
7679 else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
7680 ;
7681 else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
7682 ;
7683 else
7684 break;
7685 }
7686
7687 if (match || l2 || l3)
7688 {
7689 if (l2 || l3)
7690 {
7691 /* "Win a free Ethernet header in every packet" */
7692 if (l2 == 0)
7693 vec_validate_aligned (l2, 13, sizeof(u32x4));
7694 match = l2;
7695 vec_append_aligned (match, l3, sizeof(u32x4));
7696 vec_free (l3);
7697 }
7698
7699 /* Make sure the vector is big enough even if key is all 0's */
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007700 vec_validate_aligned
Ed Warnickecb9cada2015-12-08 15:45:58 -07007701 (match, ((match_n_vectors + skip_n_vectors) * sizeof(u32x4)) - 1,
7702 sizeof(u32x4));
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007703
Ed Warnickecb9cada2015-12-08 15:45:58 -07007704 /* Set size, include skipped vectors*/
7705 _vec_len (match) = (match_n_vectors+skip_n_vectors) * sizeof(u32x4);
7706
7707 *matchp = match;
7708
7709 return 1;
7710 }
7711
7712 return 0;
7713}
7714
7715static int api_classify_add_del_session (vat_main_t * vam)
7716{
7717 unformat_input_t * i = vam->input;
7718 vl_api_classify_add_del_session_t *mp;
7719 int is_add = 1;
7720 u32 table_index = ~0;
7721 u32 hit_next_index = ~0;
7722 u32 opaque_index = ~0;
7723 u8 * match = 0;
7724 i32 advance = 0;
7725 f64 timeout;
7726 u32 skip_n_vectors = 0;
7727 u32 match_n_vectors = 0;
7728
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007729 /*
Ed Warnickecb9cada2015-12-08 15:45:58 -07007730 * Warning: you have to supply skip_n and match_n
7731 * because the API client cant simply look at the classify
7732 * table object.
7733 */
7734
7735 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7736 if (unformat (i, "del"))
7737 is_add = 0;
7738 else if (unformat (i, "hit-next %U", unformat_ip_next_index,
7739 &hit_next_index))
7740 ;
7741 else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
7742 &hit_next_index))
7743 ;
7744 else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
7745 &hit_next_index))
7746 ;
Matus Fabian70e6a8d2016-06-20 08:10:42 -07007747 else if (unformat (i, "policer-hit-next %d", &hit_next_index))
7748 ;
7749 else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
7750 ;
Ed Warnickecb9cada2015-12-08 15:45:58 -07007751 else if (unformat (i, "opaque-index %d", &opaque_index))
7752 ;
7753 else if (unformat (i, "skip_n %d", &skip_n_vectors))
7754 ;
7755 else if (unformat (i, "match_n %d", &match_n_vectors))
7756 ;
7757 else if (unformat (i, "match %U", unformat_classify_match,
7758 &match, skip_n_vectors, match_n_vectors))
7759 ;
7760 else if (unformat (i, "advance %d", &advance))
7761 ;
7762 else if (unformat (i, "table-index %d", &table_index))
7763 ;
7764 else
7765 break;
7766 }
7767
7768 if (table_index == ~0) {
7769 errmsg ("Table index required\n");
7770 return -99;
7771 }
7772
7773 if (is_add && match == 0) {
7774 errmsg ("Match value required\n");
7775 return -99;
7776 }
7777
7778 M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session,
7779 vec_len(match));
7780
7781 mp->is_add = is_add;
7782 mp->table_index = ntohl(table_index);
7783 mp->hit_next_index = ntohl(hit_next_index);
7784 mp->opaque_index = ntohl(opaque_index);
7785 mp->advance = ntohl(advance);
Damjan Marionf1213b82016-03-13 02:22:06 +01007786 clib_memcpy (mp->match, match, vec_len(match));
Ed Warnickecb9cada2015-12-08 15:45:58 -07007787 vec_free(match);
7788
7789 S; W;
7790 /* NOTREACHED */
7791}
7792
7793static int api_classify_set_interface_ip_table (vat_main_t * vam)
7794{
7795 unformat_input_t * i = vam->input;
7796 vl_api_classify_set_interface_ip_table_t *mp;
7797 f64 timeout;
7798 u32 sw_if_index;
7799 int sw_if_index_set;
7800 u32 table_index = ~0;
7801 u8 is_ipv6 = 0;
7802
7803 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7804 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7805 sw_if_index_set = 1;
7806 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7807 sw_if_index_set = 1;
7808 else if (unformat (i, "table %d", &table_index))
7809 ;
7810 else {
7811 clib_warning ("parse error '%U'", format_unformat_error, i);
7812 return -99;
7813 }
7814 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007815
Ed Warnickecb9cada2015-12-08 15:45:58 -07007816 if (sw_if_index_set == 0) {
7817 errmsg ("missing interface name or sw_if_index\n");
7818 return -99;
7819 }
7820
7821
7822 M(CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
7823
7824 mp->sw_if_index = ntohl(sw_if_index);
7825 mp->table_index = ntohl(table_index);
7826 mp->is_ipv6 = is_ipv6;
7827
7828 S; W;
7829 /* NOTREACHED */
7830 return 0;
7831}
7832
7833static int api_classify_set_interface_l2_tables (vat_main_t * vam)
7834{
7835 unformat_input_t * i = vam->input;
7836 vl_api_classify_set_interface_l2_tables_t *mp;
7837 f64 timeout;
7838 u32 sw_if_index;
7839 int sw_if_index_set;
7840 u32 ip4_table_index = ~0;
7841 u32 ip6_table_index = ~0;
7842 u32 other_table_index = ~0;
7843
7844 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7845 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7846 sw_if_index_set = 1;
7847 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7848 sw_if_index_set = 1;
7849 else if (unformat (i, "ip4-table %d", &ip4_table_index))
7850 ;
7851 else if (unformat (i, "ip6-table %d", &ip6_table_index))
7852 ;
7853 else if (unformat (i, "other-table %d", &other_table_index))
7854 ;
7855 else {
7856 clib_warning ("parse error '%U'", format_unformat_error, i);
7857 return -99;
7858 }
7859 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007860
Ed Warnickecb9cada2015-12-08 15:45:58 -07007861 if (sw_if_index_set == 0) {
7862 errmsg ("missing interface name or sw_if_index\n");
7863 return -99;
7864 }
7865
7866
7867 M(CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
7868
7869 mp->sw_if_index = ntohl(sw_if_index);
7870 mp->ip4_table_index = ntohl(ip4_table_index);
7871 mp->ip6_table_index = ntohl(ip6_table_index);
7872 mp->other_table_index = ntohl(other_table_index);
7873
7874
7875 S; W;
7876 /* NOTREACHED */
7877 return 0;
7878}
7879
Juraj Slobodaac645ad2016-07-07 00:18:57 -07007880static int api_ipfix_enable (vat_main_t * vam)
7881{
7882 unformat_input_t * i = vam->input;
7883 vl_api_ipfix_enable_t *mp;
7884 ip4_address_t collector_address;
7885 u8 collector_address_set = 0;
7886 u32 collector_port = ~0;
7887 ip4_address_t src_address;
7888 u8 src_address_set = 0;
7889 u32 vrf_id = ~0;
7890 u32 path_mtu = ~0;
7891 u32 template_interval = ~0;
7892 f64 timeout;
7893
7894 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7895 if (unformat (i, "collector_address %U", unformat_ip4_address,
7896 &collector_address))
7897 collector_address_set = 1;
7898 else if (unformat (i, "collector_port %d", &collector_port))
7899 ;
7900 else if (unformat (i, "src_address %U", unformat_ip4_address,
7901 &src_address))
7902 src_address_set = 1;
7903 else if (unformat (i, "vrf_id %d", &vrf_id))
7904 ;
7905 else if (unformat (i, "path_mtu %d", &path_mtu))
7906 ;
7907 else if (unformat (i, "template_interval %d", &template_interval))
7908 ;
7909 else
7910 break;
7911 }
7912
7913 if (collector_address_set == 0) {
7914 errmsg ("collector_address required\n");
7915 return -99;
7916 }
7917
7918 if (src_address_set == 0) {
7919 errmsg ("src_address required\n");
7920 return -99;
7921 }
7922
7923 M (IPFIX_ENABLE, ipfix_enable);
7924
7925 memcpy(mp->collector_address, collector_address.data,
7926 sizeof(collector_address.data));
7927 mp->collector_port = htons((u16)collector_port);
7928 memcpy(mp->src_address, src_address.data,
7929 sizeof(src_address.data));
7930 mp->vrf_id = htonl(vrf_id);
7931 mp->path_mtu = htonl(path_mtu);
7932 mp->template_interval = htonl(template_interval);
7933
7934 S; W;
7935 /* NOTREACHED */
7936}
7937
Ed Warnickecb9cada2015-12-08 15:45:58 -07007938static int api_get_node_index (vat_main_t * vam)
7939{
7940 unformat_input_t * i = vam->input;
7941 vl_api_get_node_index_t * mp;
7942 f64 timeout;
7943 u8 * name = 0;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007944
Ed Warnickecb9cada2015-12-08 15:45:58 -07007945 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7946 if (unformat (i, "node %s", &name))
7947 ;
7948 else
7949 break;
7950 }
7951 if (name == 0) {
7952 errmsg ("node name required\n");
7953 return -99;
7954 }
7955 if (vec_len (name) >= ARRAY_LEN(mp->node_name)) {
7956 errmsg ("node name too long, max %d\n", ARRAY_LEN(mp->node_name));
7957 return -99;
7958 }
7959
7960 M(GET_NODE_INDEX, get_node_index);
Damjan Marionf1213b82016-03-13 02:22:06 +01007961 clib_memcpy (mp->node_name, name, vec_len(name));
Ed Warnickecb9cada2015-12-08 15:45:58 -07007962 vec_free(name);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007963
Ed Warnickecb9cada2015-12-08 15:45:58 -07007964 S; W;
7965 /* NOTREACHED */
7966 return 0;
7967}
7968
Keith Burns (alagalah)c61080e2016-07-19 14:47:43 -07007969static int api_get_next_index (vat_main_t * vam)
7970{
7971 unformat_input_t * i = vam->input;
7972 vl_api_get_next_index_t * mp;
7973 f64 timeout;
7974 u8 * node_name = 0, * next_node_name = 0;
7975
7976 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7977 if (unformat (i, "node-name %s", &node_name))
7978 ;
7979 else if (unformat (i, "next-node-name %s", &next_node_name))
7980 break;
7981 }
7982
7983 if (node_name == 0) {
7984 errmsg ("node name required\n");
7985 return -99;
7986 }
7987 if (vec_len (node_name) >= ARRAY_LEN(mp->node_name)) {
7988 errmsg ("node name too long, max %d\n", ARRAY_LEN(mp->node_name));
7989 return -99;
7990 }
7991
7992 if (next_node_name == 0) {
7993 errmsg ("next node name required\n");
7994 return -99;
7995 }
7996 if (vec_len (next_node_name) >= ARRAY_LEN(mp->next_name)) {
7997 errmsg ("next node name too long, max %d\n", ARRAY_LEN(mp->next_name));
7998 return -99;
7999 }
8000
8001 M(GET_NEXT_INDEX, get_next_index);
8002 clib_memcpy (mp->node_name, node_name, vec_len(node_name));
8003 clib_memcpy (mp->next_name, next_node_name, vec_len(next_node_name));
8004 vec_free(node_name);
8005 vec_free(next_node_name);
8006
8007 S; W;
8008 /* NOTREACHED */
8009 return 0;
8010}
8011
Ed Warnickecb9cada2015-12-08 15:45:58 -07008012static int api_add_node_next (vat_main_t * vam)
8013{
8014 unformat_input_t * i = vam->input;
8015 vl_api_add_node_next_t * mp;
8016 f64 timeout;
8017 u8 * name = 0;
8018 u8 * next = 0;
8019
8020 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8021 if (unformat (i, "node %s", &name))
8022 ;
8023 else if (unformat (i, "next %s", &next))
8024 ;
8025 else
8026 break;
8027 }
8028 if (name == 0) {
8029 errmsg ("node name required\n");
8030 return -99;
8031 }
8032 if (vec_len (name) >= ARRAY_LEN(mp->node_name)) {
8033 errmsg ("node name too long, max %d\n", ARRAY_LEN(mp->node_name));
8034 return -99;
8035 }
8036 if (next == 0) {
8037 errmsg ("next node required\n");
8038 return -99;
8039 }
8040 if (vec_len (next) >= ARRAY_LEN(mp->next_name)) {
8041 errmsg ("next name too long, max %d\n", ARRAY_LEN(mp->next_name));
8042 return -99;
8043 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08008044
Ed Warnickecb9cada2015-12-08 15:45:58 -07008045 M(ADD_NODE_NEXT, add_node_next);
Damjan Marionf1213b82016-03-13 02:22:06 +01008046 clib_memcpy (mp->node_name, name, vec_len(name));
8047 clib_memcpy (mp->next_name, next, vec_len(next));
Ed Warnickecb9cada2015-12-08 15:45:58 -07008048 vec_free(name);
8049 vec_free(next);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08008050
Ed Warnickecb9cada2015-12-08 15:45:58 -07008051 S; W;
8052 /* NOTREACHED */
8053 return 0;
8054}
8055
8056static int api_l2tpv3_create_tunnel (vat_main_t * vam)
8057{
8058 unformat_input_t * i = vam->input;
8059 ip6_address_t client_address, our_address;
8060 int client_address_set = 0;
8061 int our_address_set = 0;
8062 u32 local_session_id = 0;
8063 u32 remote_session_id = 0;
8064 u64 local_cookie = 0;
8065 u64 remote_cookie = 0;
8066 u8 l2_sublayer_present = 0;
8067 vl_api_l2tpv3_create_tunnel_t * mp;
8068 f64 timeout;
8069
8070 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08008071 if (unformat (i, "client_address %U", unformat_ip6_address,
Ed Warnickecb9cada2015-12-08 15:45:58 -07008072 &client_address))
8073 client_address_set = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08008074 else if (unformat (i, "our_address %U", unformat_ip6_address,
Ed Warnickecb9cada2015-12-08 15:45:58 -07008075 &our_address))
8076 our_address_set = 1;
8077 else if (unformat (i, "local_session_id %d", &local_session_id))
8078 ;
8079 else if (unformat (i, "remote_session_id %d", &remote_session_id))
8080 ;
8081 else if (unformat (i, "local_cookie %lld", &local_cookie))
8082 ;
8083 else if (unformat (i, "remote_cookie %lld", &remote_cookie))
8084 ;
8085 else if (unformat (i, "l2-sublayer-present"))
8086 l2_sublayer_present = 1;
8087 else
8088 break;
8089 }
8090
8091 if (client_address_set == 0) {
8092 errmsg ("client_address required\n");
8093 return -99;
8094 }
8095
8096 if (our_address_set == 0) {
8097 errmsg ("our_address required\n");
8098 return -99;
8099 }
8100
8101 M(L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
8102
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08008103 clib_memcpy (mp->client_address, client_address.as_u8,
Ed Warnickecb9cada2015-12-08 15:45:58 -07008104 sizeof (mp->client_address));
8105
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08008106 clib_memcpy (mp->our_address, our_address.as_u8,
Ed Warnickecb9cada2015-12-08 15:45:58 -07008107 sizeof (mp->our_address));
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08008108
Ed Warnickecb9cada2015-12-08 15:45:58 -07008109 mp->local_session_id = ntohl (local_session_id);
8110 mp->remote_session_id = ntohl (remote_session_id);
8111 mp->local_cookie = clib_host_to_net_u64 (local_cookie);
8112 mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
8113 mp->l2_sublayer_present = l2_sublayer_present;
8114 mp->is_ipv6 = 1;
8115
8116 S; W;
8117 /* NOTREACHED */
8118 return 0;
8119}
8120
8121static int api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
8122{
8123 unformat_input_t * i = vam->input;
8124 u32 sw_if_index;
8125 u8 sw_if_index_set = 0;
8126 u64 new_local_cookie = 0;
8127 u64 new_remote_cookie = 0;
8128 vl_api_l2tpv3_set_tunnel_cookies_t *mp;
8129 f64 timeout;
8130
8131 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8132 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8133 sw_if_index_set = 1;
8134 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8135 sw_if_index_set = 1;
8136 else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
8137 ;
8138 else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
8139 ;
8140 else
8141 break;
8142 }
8143
8144 if (sw_if_index_set == 0) {
8145 errmsg ("missing interface name or sw_if_index\n");
8146 return -99;
8147 }
8148
8149 M(L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
8150
8151 mp->sw_if_index = ntohl(sw_if_index);
8152 mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
8153 mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
8154
8155 S; W;
8156 /* NOTREACHED */
8157 return 0;
8158}
8159
8160static int api_l2tpv3_interface_enable_disable (vat_main_t * vam)
8161{
8162 unformat_input_t * i = vam->input;
8163 vl_api_l2tpv3_interface_enable_disable_t *mp;
8164 f64 timeout;
8165 u32 sw_if_index;
8166 u8 sw_if_index_set = 0;
8167 u8 enable_disable = 1;
8168
8169 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8170 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8171 sw_if_index_set = 1;
8172 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8173 sw_if_index_set = 1;
8174 else if (unformat (i, "enable"))
8175 enable_disable = 1;
8176 else if (unformat (i, "disable"))
8177 enable_disable = 0;
8178 else
8179 break;
8180 }
8181
8182 if (sw_if_index_set == 0) {
8183 errmsg ("missing interface name or sw_if_index\n");
8184 return -99;
8185 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08008186
Ed Warnickecb9cada2015-12-08 15:45:58 -07008187 M(L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
8188
8189 mp->sw_if_index = ntohl(sw_if_index);
8190 mp->enable_disable = enable_disable;
8191
8192 S; W;
8193 /* NOTREACHED */
8194 return 0;
8195}
8196
8197static int api_l2tpv3_set_lookup_key (vat_main_t * vam)
8198{
8199 unformat_input_t * i = vam->input;
8200 vl_api_l2tpv3_set_lookup_key_t * mp;
8201 f64 timeout;
8202 u8 key = ~0;
8203
8204 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8205 if (unformat (i, "lookup_v6_src"))
8206 key = L2T_LOOKUP_SRC_ADDRESS;
8207 else if (unformat (i, "lookup_v6_dst"))
8208 key = L2T_LOOKUP_DST_ADDRESS;
8209 else if (unformat (i, "lookup_session_id"))
8210 key = L2T_LOOKUP_SESSION_ID;
8211 else
8212 break;
8213 }
8214
Damjan Marionfa693552016-04-26 19:30:36 +02008215 if (key == (u8) ~0) {
Ed Warnickecb9cada2015-12-08 15:45:58 -07008216 errmsg ("l2tp session lookup key unset\n");
8217 return -99;
8218 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08008219
Ed Warnickecb9cada2015-12-08 15:45:58 -07008220 M(L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
8221
8222 mp->key = key;
8223
8224 S; W;
8225 /* NOTREACHED */
8226 return 0;
8227}
8228
8229static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
8230(vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
8231{
8232 vat_main_t * vam = &vat_main;
8233
8234 fformat(vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
8235 format_ip6_address, mp->our_address,
8236 format_ip6_address, mp->client_address,
8237 clib_net_to_host_u32(mp->sw_if_index));
8238
8239 fformat (vam->ofp, " local cookies %016llx %016llx remote cookie %016llx\n",
8240 clib_net_to_host_u64 (mp->local_cookie[0]),
8241 clib_net_to_host_u64 (mp->local_cookie[1]),
8242 clib_net_to_host_u64 (mp->remote_cookie));
8243
8244 fformat (vam->ofp, " local session-id %d remote session-id %d\n",
8245 clib_net_to_host_u32 (mp->local_session_id),
8246 clib_net_to_host_u32 (mp->remote_session_id));
8247
8248 fformat (vam->ofp, " l2 specific sublayer %s\n\n",
8249 mp->l2_sublayer_present ? "preset" : "absent");
8250
8251}
8252
8253static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
8254(vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
8255{
8256 vat_main_t * vam = &vat_main;
8257 vat_json_node_t *node = NULL;
8258 struct in6_addr addr;
8259
8260 if (VAT_JSON_ARRAY != vam->json_tree.type) {
8261 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
8262 vat_json_init_array(&vam->json_tree);
8263 }
8264 node = vat_json_array_add(&vam->json_tree);
8265
8266 vat_json_init_object(node);
8267
Damjan Marionf1213b82016-03-13 02:22:06 +01008268 clib_memcpy(&addr, mp->our_address, sizeof(addr));
Ed Warnickecb9cada2015-12-08 15:45:58 -07008269 vat_json_object_add_ip6(node, "our_address", addr);
Damjan Marionf1213b82016-03-13 02:22:06 +01008270 clib_memcpy(&addr, mp->client_address, sizeof(addr));
Ed Warnickecb9cada2015-12-08 15:45:58 -07008271 vat_json_object_add_ip6(node, "client_address", addr);
8272
8273 vat_json_node_t * lc = vat_json_object_add(node, "local_cookie");
8274 vat_json_init_array(lc);
8275 vat_json_array_add_uint(lc, clib_net_to_host_u64(mp->local_cookie[0]));
8276 vat_json_array_add_uint(lc, clib_net_to_host_u64(mp->local_cookie[1]));
8277 vat_json_object_add_uint(node, "remote_cookie", clib_net_to_host_u64(mp->remote_cookie));
8278
8279 printf("local id: %u", clib_net_to_host_u32(mp->local_session_id));
8280 vat_json_object_add_uint(node, "local_session_id", clib_net_to_host_u32(mp->local_session_id));
8281 vat_json_object_add_uint(node, "remote_session_id", clib_net_to_host_u32(mp->remote_session_id));
8282 vat_json_object_add_string_copy(node, "l2_sublayer", mp->l2_sublayer_present ?
8283 (u8*)"present" : (u8*)"absent");
8284}
8285
8286static int api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
8287{
8288 vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
8289 f64 timeout;
8290
8291 /* Get list of l2tpv3-tunnel interfaces */
8292 M(SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
8293 S;
8294
8295 /* Use a control ping for synchronization */
8296 {
8297 vl_api_control_ping_t * mp;
8298 M(CONTROL_PING, control_ping);
8299 S;
8300 }
8301 W;
8302}
8303
8304
8305static void vl_api_sw_interface_tap_details_t_handler
8306(vl_api_sw_interface_tap_details_t * mp)
8307{
8308 vat_main_t * vam = &vat_main;
8309
8310 fformat(vam->ofp, "%-16s %d\n",
8311 mp->dev_name,
8312 clib_net_to_host_u32(mp->sw_if_index));
8313}
8314
8315static void vl_api_sw_interface_tap_details_t_handler_json
8316(vl_api_sw_interface_tap_details_t * mp)
8317{
8318 vat_main_t * vam = &vat_main;
8319 vat_json_node_t *node = NULL;
8320
8321 if (VAT_JSON_ARRAY != vam->json_tree.type) {
8322 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
8323 vat_json_init_array(&vam->json_tree);
8324 }
8325 node = vat_json_array_add(&vam->json_tree);
8326
8327 vat_json_init_object(node);
8328 vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
8329 vat_json_object_add_string_copy(node, "dev_name", mp->dev_name);
8330}
8331
8332static int api_sw_interface_tap_dump (vat_main_t * vam)
8333{
8334 vl_api_sw_interface_tap_dump_t *mp;
8335 f64 timeout;
8336
8337 fformat(vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
8338 /* Get list of tap interfaces */
8339 M(SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
8340 S;
8341
8342 /* Use a control ping for synchronization */
8343 {
8344 vl_api_control_ping_t * mp;
8345 M(CONTROL_PING, control_ping);
8346 S;
8347 }
8348 W;
8349}
8350
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08008351static uword unformat_vxlan_decap_next
Ed Warnickecb9cada2015-12-08 15:45:58 -07008352(unformat_input_t * input, va_list * args)
8353{
8354 u32 * result = va_arg (*args, u32 *);
8355 u32 tmp;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08008356
Ed Warnickecb9cada2015-12-08 15:45:58 -07008357 if (unformat (input, "drop"))
8358 *result = VXLAN_INPUT_NEXT_DROP;
8359 else if (unformat (input, "ip4"))
8360 *result = VXLAN_INPUT_NEXT_IP4_INPUT;
8361 else if (unformat (input, "ip6"))
8362 *result = VXLAN_INPUT_NEXT_IP6_INPUT;
8363 else if (unformat (input, "l2"))
8364 *result = VXLAN_INPUT_NEXT_L2_INPUT;
8365 else if (unformat (input, "%d", &tmp))
8366 *result = tmp;
8367 else
8368 return 0;
8369 return 1;
8370}
8371
8372static int api_vxlan_add_del_tunnel (vat_main_t * vam)
8373{
8374 unformat_input_t * line_input = vam->input;
8375 vl_api_vxlan_add_del_tunnel_t *mp;
8376 f64 timeout;
Chris Luke99cb3352016-04-26 10:49:53 -04008377 ip4_address_t src4, dst4;
8378 ip6_address_t src6, dst6;
Ed Warnickecb9cada2015-12-08 15:45:58 -07008379 u8 is_add = 1;
Chris Luke99cb3352016-04-26 10:49:53 -04008380 u8 ipv4_set = 0, ipv6_set = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -07008381 u8 src_set = 0;
8382 u8 dst_set = 0;
8383 u32 encap_vrf_id = 0;
8384 u32 decap_next_index = ~0;
8385 u32 vni = 0;
8386
8387 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
8388 if (unformat (line_input, "del"))
8389 is_add = 0;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08008390 else if (unformat (line_input, "src %U",
Chris Luke99cb3352016-04-26 10:49:53 -04008391 unformat_ip4_address, &src4))
8392 {
8393 ipv4_set = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -07008394 src_set = 1;
Chris Luke99cb3352016-04-26 10:49:53 -04008395 }
Ed Warnickecb9cada2015-12-08 15:45:58 -07008396 else if (unformat (line_input, "dst %U",
Chris Luke99cb3352016-04-26 10:49:53 -04008397 unformat_ip4_address, &dst4))
8398 {
8399 ipv4_set = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -07008400 dst_set = 1;
Chris Luke99cb3352016-04-26 10:49:53 -04008401 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08008402 else if (unformat (line_input, "src %U",
Chris Luke99cb3352016-04-26 10:49:53 -04008403 unformat_ip6_address, &src6))
8404 {
8405 ipv6_set = 1;
8406 src_set = 1;
8407 }
8408 else if (unformat (line_input, "dst %U",
8409 unformat_ip6_address, &dst6))
8410 {
8411 ipv6_set = 1;
8412 dst_set = 1;
8413 }
Ed Warnickecb9cada2015-12-08 15:45:58 -07008414 else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
8415 ;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08008416 else if (unformat (line_input, "decap-next %U",
Ed Warnickecb9cada2015-12-08 15:45:58 -07008417 unformat_vxlan_decap_next, &decap_next_index))
8418 ;
8419 else if (unformat (line_input, "vni %d", &vni))
8420 ;
8421 else {
8422 errmsg ("parse error '%U'\n", format_unformat_error, line_input);
8423 return -99;
8424 }
8425 }
8426
8427 if (src_set == 0) {
8428 errmsg ("tunnel src address not specified\n");
8429 return -99;
8430 }
8431 if (dst_set == 0) {
8432 errmsg ("tunnel dst address not specified\n");
8433 return -99;
8434 }
8435
Chris Luke99cb3352016-04-26 10:49:53 -04008436 if (ipv4_set && ipv6_set) {
8437 errmsg ("both IPv4 and IPv6 addresses specified");
8438 return -99;
8439 }
8440
Ed Warnickecb9cada2015-12-08 15:45:58 -07008441 if ((vni == 0) || (vni>>24)) {
8442 errmsg ("vni not specified or out of range\n");
8443 return -99;
8444 }
8445
8446 M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
Chris Luke99cb3352016-04-26 10:49:53 -04008447
8448 if (ipv6_set) {
Chris Luked686c632016-05-20 12:13:02 -04008449 clib_memcpy(&mp->src_address, &src6, sizeof(src6));
8450 clib_memcpy(&mp->dst_address, &dst6, sizeof(dst6));
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08008451 } else {
Chris Luke99cb3352016-04-26 10:49:53 -04008452 clib_memcpy(&mp->src_address, &src4, sizeof(src4));
8453 clib_memcpy(&mp->dst_address, &dst4, sizeof(dst4));
8454 }
Ed Warnickecb9cada2015-12-08 15:45:58 -07008455 mp->encap_vrf_id = ntohl(encap_vrf_id);
8456 mp->decap_next_index = ntohl(decap_next_index);
8457 mp->vni = ntohl(vni);
8458 mp->is_add = is_add;
Chris Luke99cb3352016-04-26 10:49:53 -04008459 mp->is_ipv6 = ipv6_set;
Ed Warnickecb9cada2015-12-08 15:45:58 -07008460
8461 S; W;
8462 /* NOTREACHED */
8463 return 0;
8464}
8465
Dave Wallace60231f32015-12-17 21:04:30 -05008466static void vl_api_vxlan_tunnel_details_t_handler
8467(vl_api_vxlan_tunnel_details_t * mp)
8468{
8469 vat_main_t * vam = &vat_main;
8470
Chris Luke99cb3352016-04-26 10:49:53 -04008471 fformat(vam->ofp, "%11d%24U%24U%14d%18d%13d\n",
Dave Wallace60231f32015-12-17 21:04:30 -05008472 ntohl(mp->sw_if_index),
Chris Luke99cb3352016-04-26 10:49:53 -04008473 format_ip46_address, &(mp->src_address[0]),
Damjan Marion86be4872016-05-24 23:19:11 +02008474 IP46_TYPE_ANY,
Chris Luke99cb3352016-04-26 10:49:53 -04008475 format_ip46_address, &(mp->dst_address[0]),
Damjan Marion86be4872016-05-24 23:19:11 +02008476 IP46_TYPE_ANY,
Dave Wallace60231f32015-12-17 21:04:30 -05008477 ntohl(mp->encap_vrf_id),
8478 ntohl(mp->decap_next_index),
8479 ntohl(mp->vni));
8480}
8481
8482static void vl_api_vxlan_tunnel_details_t_handler_json
8483(vl_api_vxlan_tunnel_details_t * mp)
8484{
8485 vat_main_t * vam = &vat_main;
8486 vat_json_node_t *node = NULL;
8487 struct in_addr ip4;
Chris Luke99cb3352016-04-26 10:49:53 -04008488 struct in6_addr ip6;
Dave Wallace60231f32015-12-17 21:04:30 -05008489
8490 if (VAT_JSON_ARRAY != vam->json_tree.type) {
8491 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
8492 vat_json_init_array(&vam->json_tree);
8493 }
8494 node = vat_json_array_add(&vam->json_tree);
8495
8496 vat_json_init_object(node);
8497 vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
Chris Luke99cb3352016-04-26 10:49:53 -04008498 if (mp->is_ipv6) {
8499 clib_memcpy(&ip6, &(mp->src_address[0]), sizeof(ip6));
8500 vat_json_object_add_ip6(node, "src_address", ip6);
8501 clib_memcpy(&ip6, &(mp->dst_address[0]), sizeof(ip6));
8502 vat_json_object_add_ip6(node, "dst_address", ip6);
8503 } else {
8504 clib_memcpy(&ip4, &(mp->src_address[0]), sizeof(ip4));
8505 vat_json_object_add_ip4(node, "src_address", ip4);
8506 clib_memcpy(&ip4, &(mp->dst_address[0]), sizeof(ip4));
8507 vat_json_object_add_ip4(node, "dst_address", ip4);
8508 }
Dave Wallace60231f32015-12-17 21:04:30 -05008509 vat_json_object_add_uint(node, "encap_vrf_id", ntohl(mp->encap_vrf_id));
8510 vat_json_object_add_uint(node, "decap_next_index", ntohl(mp->decap_next_index));
8511 vat_json_object_add_uint(node, "vni", ntohl(mp->vni));
Chris Luke99cb3352016-04-26 10:49:53 -04008512 vat_json_object_add_uint(node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
Dave Wallace60231f32015-12-17 21:04:30 -05008513}
8514
8515static int api_vxlan_tunnel_dump (vat_main_t * vam)
8516{
8517 unformat_input_t * i = vam->input;
8518 vl_api_vxlan_tunnel_dump_t *mp;
8519 f64 timeout;
8520 u32 sw_if_index;
8521 u8 sw_if_index_set = 0;
8522
8523 /* Parse args required to build the message */
8524 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8525 if (unformat (i, "sw_if_index %d", &sw_if_index))
8526 sw_if_index_set = 1;
8527 else
8528 break;
8529 }
8530
8531 if (sw_if_index_set == 0) {
8532 sw_if_index = ~0;
8533 }
8534
8535 if (!vam->json_output) {
Chris Luke99cb3352016-04-26 10:49:53 -04008536 fformat(vam->ofp, "%11s%24s%24s%14s%18s%13s\n",
Dave Wallace60231f32015-12-17 21:04:30 -05008537 "sw_if_index", "src_address", "dst_address",
8538 "encap_vrf_id", "decap_next_index", "vni");
8539 }
8540
Chris Luke99cb3352016-04-26 10:49:53 -04008541 /* Get list of vxlan-tunnel interfaces */
Dave Wallace60231f32015-12-17 21:04:30 -05008542 M(VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
8543
8544 mp->sw_if_index = htonl(sw_if_index);
8545
8546 S;
8547
8548 /* Use a control ping for synchronization */
8549 {
8550 vl_api_control_ping_t * mp;
8551 M(CONTROL_PING, control_ping);
8552 S;
8553 }
8554 W;
8555}
8556
Chris Luke27fe48f2016-04-28 13:44:38 -04008557static int api_gre_add_del_tunnel (vat_main_t * vam)
8558{
8559 unformat_input_t * line_input = vam->input;
8560 vl_api_gre_add_del_tunnel_t *mp;
8561 f64 timeout;
8562 ip4_address_t src4, dst4;
8563 u8 is_add = 1;
8564 u8 src_set = 0;
8565 u8 dst_set = 0;
8566 u32 outer_fib_id = 0;
8567
8568 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
8569 if (unformat (line_input, "del"))
8570 is_add = 0;
8571 else if (unformat (line_input, "src %U",
8572 unformat_ip4_address, &src4))
8573 src_set = 1;
8574 else if (unformat (line_input, "dst %U",
8575 unformat_ip4_address, &dst4))
8576 dst_set = 1;
8577 else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
8578 ;
8579 else {
8580 errmsg ("parse error '%U'\n", format_unformat_error, line_input);
8581 return -99;
8582 }
8583 }
8584
8585 if (src_set == 0) {
8586 errmsg ("tunnel src address not specified\n");
8587 return -99;
8588 }
8589 if (dst_set == 0) {
8590 errmsg ("tunnel dst address not specified\n");
8591 return -99;
8592 }
8593
8594
8595 M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
8596
8597 clib_memcpy(&mp->src_address, &src4, sizeof(src4));
8598 clib_memcpy(&mp->dst_address, &dst4, sizeof(dst4));
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08008599 mp->outer_fib_id = ntohl(outer_fib_id);
Chris Luke27fe48f2016-04-28 13:44:38 -04008600 mp->is_add = is_add;
8601
8602 S; W;
8603 /* NOTREACHED */
8604 return 0;
8605}
8606
8607static void vl_api_gre_tunnel_details_t_handler
8608(vl_api_gre_tunnel_details_t * mp)
8609{
8610 vat_main_t * vam = &vat_main;
8611
8612 fformat(vam->ofp, "%11d%15U%15U%14d\n",
8613 ntohl(mp->sw_if_index),
8614 format_ip4_address, &mp->src_address,
8615 format_ip4_address, &mp->dst_address,
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08008616 ntohl(mp->outer_fib_id));
Chris Luke27fe48f2016-04-28 13:44:38 -04008617}
8618
8619static void vl_api_gre_tunnel_details_t_handler_json
8620(vl_api_gre_tunnel_details_t * mp)
8621{
8622 vat_main_t * vam = &vat_main;
8623 vat_json_node_t *node = NULL;
8624 struct in_addr ip4;
8625
8626 if (VAT_JSON_ARRAY != vam->json_tree.type) {
8627 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
8628 vat_json_init_array(&vam->json_tree);
8629 }
8630 node = vat_json_array_add(&vam->json_tree);
8631
8632 vat_json_init_object(node);
8633 vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
8634 clib_memcpy(&ip4, &mp->src_address, sizeof(ip4));
8635 vat_json_object_add_ip4(node, "src_address", ip4);
8636 clib_memcpy(&ip4, &mp->dst_address, sizeof(ip4));
8637 vat_json_object_add_ip4(node, "dst_address", ip4);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08008638 vat_json_object_add_uint(node, "outer_fib_id", ntohl(mp->outer_fib_id));
Chris Luke27fe48f2016-04-28 13:44:38 -04008639}
8640
8641static int api_gre_tunnel_dump (vat_main_t * vam)
8642{
8643 unformat_input_t * i = vam->input;
8644 vl_api_gre_tunnel_dump_t *mp;
8645 f64 timeout;
8646 u32 sw_if_index;
8647 u8 sw_if_index_set = 0;
8648
8649 /* Parse args required to build the message */
8650 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8651 if (unformat (i, "sw_if_index %d", &sw_if_index))
8652 sw_if_index_set = 1;
8653 else
8654 break;
8655 }
8656
8657 if (sw_if_index_set == 0) {
8658 sw_if_index = ~0;
8659 }
8660
8661 if (!vam->json_output) {
8662 fformat(vam->ofp, "%11s%15s%15s%14s\n",
8663 "sw_if_index", "src_address", "dst_address",
8664 "outer_fib_id");
8665 }
8666
8667 /* Get list of gre-tunnel interfaces */
8668 M(GRE_TUNNEL_DUMP, gre_tunnel_dump);
8669
8670 mp->sw_if_index = htonl(sw_if_index);
8671
8672 S;
8673
8674 /* Use a control ping for synchronization */
8675 {
8676 vl_api_control_ping_t * mp;
8677 M(CONTROL_PING, control_ping);
8678 S;
8679 }
8680 W;
8681}
8682
Ed Warnickecb9cada2015-12-08 15:45:58 -07008683static int api_l2_fib_clear_table (vat_main_t * vam)
8684{
8685// unformat_input_t * i = vam->input;
8686 vl_api_l2_fib_clear_table_t *mp;
8687 f64 timeout;
8688
8689 M(L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
8690
8691 S; W;
8692 /* NOTREACHED */
8693 return 0;
8694}
8695
8696static int api_l2_interface_efp_filter (vat_main_t * vam)
8697{
8698 unformat_input_t * i = vam->input;
8699 vl_api_l2_interface_efp_filter_t *mp;
8700 f64 timeout;
8701 u32 sw_if_index;
8702 u8 enable = 1;
8703 u8 sw_if_index_set = 0;
8704
8705 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8706 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8707 sw_if_index_set = 1;
8708 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8709 sw_if_index_set = 1;
8710 else if (unformat (i, "enable"))
8711 enable = 1;
8712 else if (unformat (i, "disable"))
8713 enable = 0;
8714 else {
8715 clib_warning ("parse error '%U'", format_unformat_error, i);
8716 return -99;
8717 }
8718 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08008719
Ed Warnickecb9cada2015-12-08 15:45:58 -07008720 if (sw_if_index_set == 0) {
8721 errmsg ("missing sw_if_index\n");
8722 return -99;
8723 }
8724
8725 M(L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
8726
8727 mp->sw_if_index = ntohl(sw_if_index);
8728 mp->enable_disable = enable;
8729
8730 S; W;
8731 /* NOTREACHED */
8732 return 0;
8733}
8734
8735#define foreach_vtr_op \
8736_("disable", L2_VTR_DISABLED) \
8737_("push-1", L2_VTR_PUSH_1) \
8738_("push-2", L2_VTR_PUSH_2) \
8739_("pop-1", L2_VTR_POP_1) \
8740_("pop-2", L2_VTR_POP_2) \
8741_("translate-1-1", L2_VTR_TRANSLATE_1_1) \
8742_("translate-1-2", L2_VTR_TRANSLATE_1_2) \
8743_("translate-2-1", L2_VTR_TRANSLATE_2_1) \
8744_("translate-2-2", L2_VTR_TRANSLATE_2_2)
8745
8746static int api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
8747{
8748 unformat_input_t * i = vam->input;
8749 vl_api_l2_interface_vlan_tag_rewrite_t *mp;
8750 f64 timeout;
8751 u32 sw_if_index;
8752 u8 sw_if_index_set = 0;
8753 u8 vtr_op_set = 0;
8754 u32 vtr_op = 0;
8755 u32 push_dot1q = 1;
8756 u32 tag1 = ~0;
8757 u32 tag2 = ~0;
8758
8759 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8760 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8761 sw_if_index_set = 1;
8762 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8763 sw_if_index_set = 1;
8764 else if (unformat (i, "vtr_op %d", &vtr_op))
8765 vtr_op_set = 1;
8766#define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
8767 foreach_vtr_op
8768#undef _
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08008769
Ed Warnickecb9cada2015-12-08 15:45:58 -07008770 else if (unformat (i, "push_dot1q %d", &push_dot1q))
8771 ;
8772 else if (unformat (i, "tag1 %d", &tag1))
8773 ;
8774 else if (unformat (i, "tag2 %d", &tag2))
8775 ;
8776 else {
8777 clib_warning ("parse error '%U'", format_unformat_error, i);
8778 return -99;
8779 }
8780 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08008781
Ed Warnickecb9cada2015-12-08 15:45:58 -07008782 if ((sw_if_index_set == 0)||(vtr_op_set == 0)) {
8783 errmsg ("missing vtr operation or sw_if_index\n");
8784 return -99;
8785 }
8786
8787 M(L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
8788
8789 mp->sw_if_index = ntohl(sw_if_index);
8790 mp->vtr_op = ntohl(vtr_op);
8791 mp->push_dot1q = ntohl(push_dot1q);
8792 mp->tag1 = ntohl(tag1);
8793 mp->tag2 = ntohl(tag2);
8794
8795 S; W;
8796 /* NOTREACHED */
8797 return 0;
8798}
8799
8800static int api_create_vhost_user_if (vat_main_t * vam)
8801{
8802 unformat_input_t * i = vam->input;
8803 vl_api_create_vhost_user_if_t *mp;
8804 f64 timeout;
8805 u8 * file_name;
8806 u8 is_server = 0;
8807 u8 file_name_set = 0;
8808 u32 custom_dev_instance = ~0;
Pierre Pfisteref65cb02016-02-19 13:52:44 +00008809 u8 hwaddr[6];
8810 u8 use_custom_mac = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -07008811
8812 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8813 if (unformat (i, "socket %s", &file_name)) {
8814 file_name_set = 1;
8815 }
8816 else if (unformat (i, "renumber %"PRIu32, &custom_dev_instance))
8817 ;
Pierre Pfisteref65cb02016-02-19 13:52:44 +00008818 else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
8819 use_custom_mac = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -07008820 else if (unformat (i, "server"))
8821 is_server = 1;
8822 else
8823 break;
8824 }
8825
8826 if (file_name_set == 0) {
8827 errmsg ("missing socket file name\n");
8828 return -99;
8829 }
8830
8831 if (vec_len (file_name) > 255) {
8832 errmsg ("socket file name too long\n");
8833 return -99;
8834 }
8835 vec_add1 (file_name, 0);
8836
8837 M(CREATE_VHOST_USER_IF, create_vhost_user_if);
8838
8839 mp->is_server = is_server;
Damjan Marionf1213b82016-03-13 02:22:06 +01008840 clib_memcpy(mp->sock_filename, file_name, vec_len(file_name));
Ed Warnickecb9cada2015-12-08 15:45:58 -07008841 vec_free(file_name);
8842 if (custom_dev_instance != ~0) {
8843 mp->renumber = 1;
8844 mp->custom_dev_instance = ntohl(custom_dev_instance);
8845 }
Pierre Pfisteref65cb02016-02-19 13:52:44 +00008846 mp->use_custom_mac = use_custom_mac;
Damjan Marionf1213b82016-03-13 02:22:06 +01008847 clib_memcpy(mp->mac_address, hwaddr, 6);
Ed Warnickecb9cada2015-12-08 15:45:58 -07008848
8849 S; W;
8850 /* NOTREACHED */
8851 return 0;
8852}
8853
8854static int api_modify_vhost_user_if (vat_main_t * vam)
8855{
8856 unformat_input_t * i = vam->input;
8857 vl_api_modify_vhost_user_if_t *mp;
8858 f64 timeout;
8859 u8 * file_name;
8860 u8 is_server = 0;
8861 u8 file_name_set = 0;
8862 u32 custom_dev_instance = ~0;
8863 u8 sw_if_index_set = 0;
8864 u32 sw_if_index = (u32)~0;
8865
8866 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8867 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8868 sw_if_index_set = 1;
8869 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8870 sw_if_index_set = 1;
8871 else if (unformat (i, "socket %s", &file_name)) {
8872 file_name_set = 1;
8873 }
8874 else if (unformat (i, "renumber %"PRIu32, &custom_dev_instance))
8875 ;
8876 else if (unformat (i, "server"))
8877 is_server = 1;
8878 else
8879 break;
8880 }
8881
8882 if (sw_if_index_set == 0) {
8883 errmsg ("missing sw_if_index or interface name\n");
8884 return -99;
8885 }
8886
8887 if (file_name_set == 0) {
8888 errmsg ("missing socket file name\n");
8889 return -99;
8890 }
8891
8892 if (vec_len (file_name) > 255) {
8893 errmsg ("socket file name too long\n");
8894 return -99;
8895 }
8896 vec_add1 (file_name, 0);
8897
8898 M(MODIFY_VHOST_USER_IF, modify_vhost_user_if);
8899
8900 mp->sw_if_index = ntohl(sw_if_index);
8901 mp->is_server = is_server;
Damjan Marionf1213b82016-03-13 02:22:06 +01008902 clib_memcpy(mp->sock_filename, file_name, vec_len(file_name));
Ed Warnickecb9cada2015-12-08 15:45:58 -07008903 vec_free(file_name);
8904 if (custom_dev_instance != ~0) {
8905 mp->renumber = 1;
8906 mp->custom_dev_instance = ntohl(custom_dev_instance);
8907 }
8908
8909 S; W;
8910 /* NOTREACHED */
8911 return 0;
8912}
8913
8914static int api_delete_vhost_user_if (vat_main_t * vam)
8915{
8916 unformat_input_t * i = vam->input;
8917 vl_api_delete_vhost_user_if_t *mp;
8918 f64 timeout;
8919 u32 sw_if_index = ~0;
8920 u8 sw_if_index_set = 0;
8921
8922 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8923 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8924 sw_if_index_set = 1;
8925 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8926 sw_if_index_set = 1;
8927 else
8928 break;
8929 }
8930
8931 if (sw_if_index_set == 0) {
8932 errmsg ("missing sw_if_index or interface name\n");
8933 return -99;
8934 }
8935
8936
8937 M(DELETE_VHOST_USER_IF, delete_vhost_user_if);
8938
8939 mp->sw_if_index = ntohl(sw_if_index);
8940
8941 S; W;
8942 /* NOTREACHED */
8943 return 0;
8944}
8945
8946static void vl_api_sw_interface_vhost_user_details_t_handler
8947(vl_api_sw_interface_vhost_user_details_t * mp)
8948{
8949 vat_main_t * vam = &vat_main;
8950
8951 fformat(vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
8952 (char *)mp->interface_name,
8953 ntohl(mp->sw_if_index), ntohl(mp->virtio_net_hdr_sz),
8954 clib_net_to_host_u64(mp->features), mp->is_server,
8955 ntohl(mp->num_regions), (char *)mp->sock_filename);
8956 fformat(vam->ofp, " Status: '%s'\n", strerror(ntohl(mp->sock_errno)));
8957}
8958
8959static void vl_api_sw_interface_vhost_user_details_t_handler_json
8960(vl_api_sw_interface_vhost_user_details_t * mp)
8961{
8962 vat_main_t * vam = &vat_main;
8963 vat_json_node_t *node = NULL;
8964
8965 if (VAT_JSON_ARRAY != vam->json_tree.type) {
8966 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
8967 vat_json_init_array(&vam->json_tree);
8968 }
8969 node = vat_json_array_add(&vam->json_tree);
8970
8971 vat_json_init_object(node);
8972 vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
8973 vat_json_object_add_string_copy(node, "interface_name", mp->interface_name);
8974 vat_json_object_add_uint(node, "virtio_net_hdr_sz", ntohl(mp->virtio_net_hdr_sz));
8975 vat_json_object_add_uint(node, "features", clib_net_to_host_u64(mp->features));
8976 vat_json_object_add_uint(node, "is_server", mp->is_server);
8977 vat_json_object_add_string_copy(node, "sock_filename", mp->sock_filename);
8978 vat_json_object_add_uint(node, "num_regions", ntohl(mp->num_regions));
8979 vat_json_object_add_uint(node, "sock_errno", ntohl(mp->sock_errno));
8980}
8981
8982static int api_sw_interface_vhost_user_dump (vat_main_t * vam)
8983{
8984 vl_api_sw_interface_vhost_user_dump_t *mp;
8985 f64 timeout;
8986 fformat(vam->ofp, "Interface name idx hdr_sz features server regions filename\n");
8987
8988 /* Get list of vhost-user interfaces */
8989 M(SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
8990 S;
8991
8992 /* Use a control ping for synchronization */
8993 {
8994 vl_api_control_ping_t * mp;
8995 M(CONTROL_PING, control_ping);
8996 S;
8997 }
8998 W;
8999}
9000
9001static int api_show_version (vat_main_t * vam)
9002{
9003 vl_api_show_version_t *mp;
9004 f64 timeout;
9005
9006 M(SHOW_VERSION, show_version);
9007
9008 S; W;
9009 /* NOTREACHED */
9010 return 0;
9011}
9012
Ed Warnickecb9cada2015-12-08 15:45:58 -07009013
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07009014static int api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
Ed Warnickecb9cada2015-12-08 15:45:58 -07009015{
9016 unformat_input_t * line_input = vam->input;
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07009017 vl_api_vxlan_gpe_add_del_tunnel_t *mp;
Ed Warnickecb9cada2015-12-08 15:45:58 -07009018 f64 timeout;
Hongjun Nidf921cc2016-05-25 01:16:19 +08009019 ip4_address_t local4, remote4;
9020 ip6_address_t local6, remote6;
Ed Warnickecb9cada2015-12-08 15:45:58 -07009021 u8 is_add = 1;
Hongjun Nidf921cc2016-05-25 01:16:19 +08009022 u8 ipv4_set = 0, ipv6_set = 0;
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07009023 u8 local_set = 0;
9024 u8 remote_set = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -07009025 u32 encap_vrf_id = 0;
9026 u32 decap_vrf_id = 0;
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07009027 u8 protocol = ~0;
Ed Warnickecb9cada2015-12-08 15:45:58 -07009028 u32 vni;
9029 u8 vni_set = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -07009030
9031 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
9032 if (unformat (line_input, "del"))
9033 is_add = 0;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08009034 else if (unformat (line_input, "local %U",
Hongjun Nidf921cc2016-05-25 01:16:19 +08009035 unformat_ip4_address, &local4))
9036 {
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07009037 local_set = 1;
Hongjun Nidf921cc2016-05-25 01:16:19 +08009038 ipv4_set = 1;
9039 }
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07009040 else if (unformat (line_input, "remote %U",
Hongjun Nidf921cc2016-05-25 01:16:19 +08009041 unformat_ip4_address, &remote4))
9042 {
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07009043 remote_set = 1;
Hongjun Nidf921cc2016-05-25 01:16:19 +08009044 ipv4_set = 1;
9045 }
9046 else if (unformat (line_input, "local %U",
9047 unformat_ip6_address, &local6))
9048 {
9049 local_set = 1;
9050 ipv6_set = 1;
9051 }
9052 else if (unformat (line_input, "remote %U",
9053 unformat_ip6_address, &remote6))
9054 {
9055 remote_set = 1;
9056 ipv6_set = 1;
9057 }
Ed Warnickecb9cada2015-12-08 15:45:58 -07009058 else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
9059 ;
9060 else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
9061 ;
Ed Warnickecb9cada2015-12-08 15:45:58 -07009062 else if (unformat (line_input, "vni %d", &vni))
9063 vni_set = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -07009064 else if (unformat(line_input, "next-ip4"))
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07009065 protocol = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -07009066 else if (unformat(line_input, "next-ip6"))
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07009067 protocol = 2;
Ed Warnickecb9cada2015-12-08 15:45:58 -07009068 else if (unformat(line_input, "next-ethernet"))
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07009069 protocol = 3;
9070 else if (unformat(line_input, "next-nsh"))
9071 protocol = 4;
Ed Warnickecb9cada2015-12-08 15:45:58 -07009072 else {
9073 errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9074 return -99;
9075 }
9076 }
9077
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07009078 if (local_set == 0) {
9079 errmsg ("tunnel local address not specified\n");
Ed Warnickecb9cada2015-12-08 15:45:58 -07009080 return -99;
9081 }
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07009082 if (remote_set == 0) {
9083 errmsg ("tunnel remote address not specified\n");
Ed Warnickecb9cada2015-12-08 15:45:58 -07009084 return -99;
9085 }
Hongjun Nidf921cc2016-05-25 01:16:19 +08009086 if (ipv4_set && ipv6_set) {
9087 errmsg ("both IPv4 and IPv6 addresses specified");
9088 return -99;
9089 }
Ed Warnickecb9cada2015-12-08 15:45:58 -07009090
Ed Warnickecb9cada2015-12-08 15:45:58 -07009091 if (vni_set == 0) {
9092 errmsg ("vni not specified\n");
9093 return -99;
9094 }
9095
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07009096 M(VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08009097
Hongjun Nidf921cc2016-05-25 01:16:19 +08009098
9099 if (ipv6_set) {
9100 clib_memcpy(&mp->local, &local6, sizeof(local6));
9101 clib_memcpy(&mp->remote, &remote6, sizeof(remote6));
9102 } else {
9103 clib_memcpy(&mp->local, &local4, sizeof(local4));
9104 clib_memcpy(&mp->remote, &remote4, sizeof(remote4));
9105 }
9106
Ed Warnickecb9cada2015-12-08 15:45:58 -07009107 mp->encap_vrf_id = ntohl(encap_vrf_id);
9108 mp->decap_vrf_id = ntohl(decap_vrf_id);
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07009109 mp->protocol = ntohl(protocol);
Ed Warnickecb9cada2015-12-08 15:45:58 -07009110 mp->vni = ntohl(vni);
9111 mp->is_add = is_add;
Hongjun Nidf921cc2016-05-25 01:16:19 +08009112 mp->is_ipv6 = ipv6_set;
Ed Warnickecb9cada2015-12-08 15:45:58 -07009113
9114 S; W;
9115 /* NOTREACHED */
9116 return 0;
9117}
9118
Hongjun Ni0e06e2b2016-05-30 19:45:51 +08009119static void vl_api_vxlan_gpe_tunnel_details_t_handler
9120(vl_api_vxlan_gpe_tunnel_details_t * mp)
9121{
9122 vat_main_t * vam = &vat_main;
9123
9124 fformat(vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
9125 ntohl(mp->sw_if_index),
9126 format_ip46_address, &(mp->local[0]),
9127 format_ip46_address, &(mp->remote[0]),
9128 ntohl(mp->vni),
9129 ntohl(mp->protocol),
9130 ntohl(mp->encap_vrf_id),
9131 ntohl(mp->decap_vrf_id));
9132}
9133
9134static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
9135(vl_api_vxlan_gpe_tunnel_details_t * mp)
9136{
9137 vat_main_t * vam = &vat_main;
9138 vat_json_node_t *node = NULL;
9139 struct in_addr ip4;
9140 struct in6_addr ip6;
9141
9142 if (VAT_JSON_ARRAY != vam->json_tree.type) {
9143 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
9144 vat_json_init_array(&vam->json_tree);
9145 }
9146 node = vat_json_array_add(&vam->json_tree);
9147
9148 vat_json_init_object(node);
9149 vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
9150 if (mp->is_ipv6) {
9151 clib_memcpy(&ip6, &(mp->local[0]), sizeof(ip6));
9152 vat_json_object_add_ip6(node, "local", ip6);
9153 clib_memcpy(&ip6, &(mp->remote[0]), sizeof(ip6));
9154 vat_json_object_add_ip6(node, "remote", ip6);
9155 } else {
9156 clib_memcpy(&ip4, &(mp->local[0]), sizeof(ip4));
9157 vat_json_object_add_ip4(node, "local", ip4);
9158 clib_memcpy(&ip4, &(mp->remote[0]), sizeof(ip4));
9159 vat_json_object_add_ip4(node, "remote", ip4);
9160 }
9161 vat_json_object_add_uint(node, "vni", ntohl(mp->vni));
9162 vat_json_object_add_uint(node, "protocol", ntohl(mp->protocol));
9163 vat_json_object_add_uint(node, "encap_vrf_id", ntohl(mp->encap_vrf_id));
9164 vat_json_object_add_uint(node, "decap_vrf_id", ntohl(mp->decap_vrf_id));
9165 vat_json_object_add_uint(node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
9166}
9167
9168static int api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
9169{
9170 unformat_input_t * i = vam->input;
9171 vl_api_vxlan_gpe_tunnel_dump_t *mp;
9172 f64 timeout;
9173 u32 sw_if_index;
9174 u8 sw_if_index_set = 0;
9175
9176 /* Parse args required to build the message */
9177 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9178 if (unformat (i, "sw_if_index %d", &sw_if_index))
9179 sw_if_index_set = 1;
9180 else
9181 break;
9182 }
9183
9184 if (sw_if_index_set == 0) {
9185 sw_if_index = ~0;
9186 }
9187
9188 if (!vam->json_output) {
9189 fformat(vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
9190 "sw_if_index", "local", "remote", "vni",
9191 "protocol","encap_vrf_id", "decap_vrf_id");
9192 }
9193
9194 /* Get list of vxlan-tunnel interfaces */
9195 M(VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
9196
9197 mp->sw_if_index = htonl(sw_if_index);
9198
9199 S;
9200
9201 /* Use a control ping for synchronization */
9202 {
9203 vl_api_control_ping_t * mp;
9204 M(CONTROL_PING, control_ping);
9205 S;
9206 }
9207 W;
9208}
9209
Ed Warnickecb9cada2015-12-08 15:45:58 -07009210u8 * format_l2_fib_mac_address (u8 * s, va_list * args)
9211{
9212 u8 * a = va_arg (*args, u8 *);
9213
9214 return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
9215 a[2], a[3], a[4], a[5], a[6], a[7]);
9216}
9217
9218static void vl_api_l2_fib_table_entry_t_handler
9219(vl_api_l2_fib_table_entry_t * mp)
9220{
9221 vat_main_t * vam = &vat_main;
9222
9223 fformat(vam->ofp, "%3" PRIu32 " %U %3" PRIu32
9224 " %d %d %d\n",
9225 ntohl(mp->bd_id), format_l2_fib_mac_address, &mp->mac,
9226 ntohl(mp->sw_if_index), mp->static_mac, mp->filter_mac,
9227 mp->bvi_mac);
9228}
9229
9230static void vl_api_l2_fib_table_entry_t_handler_json
9231(vl_api_l2_fib_table_entry_t * mp)
9232{
9233 vat_main_t * vam = &vat_main;
9234 vat_json_node_t *node = NULL;
9235
9236 if (VAT_JSON_ARRAY != vam->json_tree.type) {
9237 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
9238 vat_json_init_array(&vam->json_tree);
9239 }
9240 node = vat_json_array_add(&vam->json_tree);
9241
9242 vat_json_init_object(node);
9243 vat_json_object_add_uint(node, "bd_id", ntohl(mp->bd_id));
9244 vat_json_object_add_uint(node, "mac", clib_net_to_host_u64(mp->mac));
9245 vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
9246 vat_json_object_add_uint(node, "static_mac", mp->static_mac);
9247 vat_json_object_add_uint(node, "filter_mac", mp->filter_mac);
9248 vat_json_object_add_uint(node, "bvi_mac", mp->bvi_mac);
9249}
9250
9251static int api_l2_fib_table_dump (vat_main_t * vam)
9252{
9253 unformat_input_t * i = vam->input;
9254 vl_api_l2_fib_table_dump_t *mp;
9255 f64 timeout;
9256 u32 bd_id;
9257 u8 bd_id_set = 0;
9258
9259 /* Parse args required to build the message */
9260 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9261 if (unformat (i, "bd_id %d", &bd_id))
9262 bd_id_set = 1;
9263 else
9264 break;
9265 }
9266
9267 if (bd_id_set == 0) {
9268 errmsg ("missing bridge domain\n");
9269 return -99;
9270 }
9271
9272 fformat(vam->ofp, "BD-ID Mac Address sw-ndx Static Filter BVI\n");
9273
9274 /* Get list of l2 fib entries */
9275 M(L2_FIB_TABLE_DUMP, l2_fib_table_dump);
9276
9277 mp->bd_id = ntohl(bd_id);
9278 S;
9279
9280 /* Use a control ping for synchronization */
9281 {
9282 vl_api_control_ping_t * mp;
9283 M(CONTROL_PING, control_ping);
9284 S;
9285 }
9286 W;
9287}
9288
9289
9290static int
9291api_interface_name_renumber (vat_main_t * vam)
9292{
9293 unformat_input_t * line_input = vam->input;
9294 vl_api_interface_name_renumber_t *mp;
9295 u32 sw_if_index = ~0;
9296 f64 timeout;
9297 u32 new_show_dev_instance = ~0;
9298
9299 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08009300 if (unformat (line_input, "%U", unformat_sw_if_index, vam,
Ed Warnickecb9cada2015-12-08 15:45:58 -07009301 &sw_if_index))
9302 ;
9303 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
9304 ;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08009305 else if (unformat (line_input, "new_show_dev_instance %d",
Ed Warnickecb9cada2015-12-08 15:45:58 -07009306 &new_show_dev_instance))
9307 ;
9308 else
9309 break;
9310 }
9311
9312 if (sw_if_index == ~0) {
9313 errmsg ("missing interface name or sw_if_index\n");
9314 return -99;
9315 }
9316
9317 if (new_show_dev_instance == ~0) {
9318 errmsg ("missing new_show_dev_instance\n");
9319 return -99;
9320 }
9321
9322 M(INTERFACE_NAME_RENUMBER, interface_name_renumber);
9323
9324 mp->sw_if_index = ntohl (sw_if_index);
9325 mp->new_show_dev_instance = ntohl (new_show_dev_instance);
9326
9327 S; W;
9328}
9329
9330static int
9331api_want_ip4_arp_events (vat_main_t * vam)
9332{
9333 unformat_input_t * line_input = vam->input;
9334 vl_api_want_ip4_arp_events_t * mp;
9335 f64 timeout;
9336 ip4_address_t address;
9337 int address_set = 0;
9338 u32 enable_disable = 1;
9339
9340 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08009341 if (unformat (line_input, "address %U",
Ed Warnickecb9cada2015-12-08 15:45:58 -07009342 unformat_ip4_address, &address))
9343 address_set = 1;
9344 else if (unformat (line_input, "del"))
9345 enable_disable = 0;
9346 else
9347 break;
9348 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08009349
Ed Warnickecb9cada2015-12-08 15:45:58 -07009350 if (address_set == 0) {
9351 errmsg ("missing addresses\n");
9352 return -99;
9353 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08009354
Ed Warnickecb9cada2015-12-08 15:45:58 -07009355 M(WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
9356 mp->enable_disable = enable_disable;
9357 mp->pid = getpid();
9358 mp->address = address.as_u32;
9359
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08009360 S; W;
Ed Warnickecb9cada2015-12-08 15:45:58 -07009361}
9362
9363static int api_input_acl_set_interface (vat_main_t * vam)
9364{
9365 unformat_input_t * i = vam->input;
9366 vl_api_input_acl_set_interface_t *mp;
9367 f64 timeout;
9368 u32 sw_if_index;
9369 int sw_if_index_set;
9370 u32 ip4_table_index = ~0;
9371 u32 ip6_table_index = ~0;
9372 u32 l2_table_index = ~0;
9373 u8 is_add = 1;
9374
9375 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9376 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9377 sw_if_index_set = 1;
9378 else if (unformat (i, "sw_if_index %d", &sw_if_index))
9379 sw_if_index_set = 1;
9380 else if (unformat (i, "del"))
9381 is_add = 0;
9382 else if (unformat (i, "ip4-table %d", &ip4_table_index))
9383 ;
9384 else if (unformat (i, "ip6-table %d", &ip6_table_index))
9385 ;
9386 else if (unformat (i, "l2-table %d", &l2_table_index))
9387 ;
9388 else {
9389 clib_warning ("parse error '%U'", format_unformat_error, i);
9390 return -99;
9391 }
9392 }
9393
9394 if (sw_if_index_set == 0) {
9395 errmsg ("missing interface name or sw_if_index\n");
9396 return -99;
9397 }
9398
9399 M(INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
9400
9401 mp->sw_if_index = ntohl(sw_if_index);
9402 mp->ip4_table_index = ntohl(ip4_table_index);
9403 mp->ip6_table_index = ntohl(ip6_table_index);
9404 mp->l2_table_index = ntohl(l2_table_index);
9405 mp->is_add = is_add;
9406
9407 S; W;
9408 /* NOTREACHED */
9409 return 0;
9410}
9411
9412static int
9413api_ip_address_dump (vat_main_t * vam)
9414{
9415 unformat_input_t * i = vam->input;
9416 vl_api_ip_address_dump_t * mp;
9417 u32 sw_if_index = ~0;
9418 u8 sw_if_index_set = 0;
9419 u8 ipv4_set = 0;
9420 u8 ipv6_set = 0;
9421 f64 timeout;
9422
9423 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9424 if (unformat (i, "sw_if_index %d", &sw_if_index))
9425 sw_if_index_set = 1;
9426 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9427 sw_if_index_set = 1;
9428 else if (unformat (i, "ipv4"))
9429 ipv4_set = 1;
9430 else if (unformat (i, "ipv6"))
9431 ipv6_set = 1;
9432 else
9433 break;
9434 }
9435
9436 if (ipv4_set && ipv6_set) {
9437 errmsg ("ipv4 and ipv6 flags cannot be both set\n");
9438 return -99;
9439 }
9440
9441 if ((!ipv4_set) && (!ipv6_set)) {
9442 errmsg ("no ipv4 nor ipv6 flag set\n");
9443 return -99;
9444 }
9445
9446 if (sw_if_index_set == 0) {
9447 errmsg ("missing interface name or sw_if_index\n");
9448 return -99;
9449 }
9450
9451 vam->current_sw_if_index = sw_if_index;
9452 vam->is_ipv6 = ipv6_set;
9453
9454 M(IP_ADDRESS_DUMP, ip_address_dump);
9455 mp->sw_if_index = ntohl(sw_if_index);
9456 mp->is_ipv6 = ipv6_set;
9457 S;
9458
9459 /* Use a control ping for synchronization */
9460 {
9461 vl_api_control_ping_t * mp;
9462 M(CONTROL_PING, control_ping);
9463 S;
9464 }
9465 W;
9466}
9467
9468static int
9469api_ip_dump (vat_main_t * vam)
9470{
9471 vl_api_ip_dump_t * mp;
9472 unformat_input_t * in = vam->input;
9473 int ipv4_set = 0;
9474 int ipv6_set = 0;
9475 int is_ipv6;
9476 f64 timeout;
9477 int i;
9478
9479 while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT) {
9480 if (unformat (in, "ipv4"))
9481 ipv4_set = 1;
9482 else if (unformat (in, "ipv6"))
9483 ipv6_set = 1;
9484 else
9485 break;
9486 }
9487
9488 if (ipv4_set && ipv6_set) {
9489 errmsg ("ipv4 and ipv6 flags cannot be both set\n");
9490 return -99;
9491 }
9492
9493 if ((!ipv4_set) && (!ipv6_set)) {
9494 errmsg ("no ipv4 nor ipv6 flag set\n");
9495 return -99;
9496 }
9497
9498 is_ipv6 = ipv6_set;
9499 vam->is_ipv6 = is_ipv6;
9500
9501 /* free old data */
9502 for (i = 0; i < vec_len(vam->ip_details_by_sw_if_index[is_ipv6]); i++) {
9503 vec_free(vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
9504 }
9505 vec_free(vam->ip_details_by_sw_if_index[is_ipv6]);
9506
9507 M(IP_DUMP, ip_dump);
9508 mp->is_ipv6 = ipv6_set;
9509 S;
9510
9511 /* Use a control ping for synchronization */
9512 {
9513 vl_api_control_ping_t * mp;
9514 M(CONTROL_PING, control_ping);
9515 S;
9516 }
9517 W;
9518}
9519
9520static int
9521api_ipsec_spd_add_del (vat_main_t * vam)
9522{
Dave Barachbfdedbd2016-01-20 09:11:55 -05009523#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -07009524 unformat_input_t * i = vam->input;
9525 vl_api_ipsec_spd_add_del_t *mp;
9526 f64 timeout;
9527 u32 spd_id = ~0;
9528 u8 is_add = 1;
9529
9530 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9531 if (unformat (i, "spd_id %d", &spd_id))
9532 ;
9533 else if (unformat (i, "del"))
9534 is_add = 0;
9535 else {
9536 clib_warning ("parse error '%U'", format_unformat_error, i);
9537 return -99;
9538 }
9539 }
9540 if (spd_id == ~0) {
9541 errmsg ("spd_id must be set\n");
9542 return -99;
9543 }
9544
9545 M(IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
9546
9547 mp->spd_id = ntohl(spd_id);
9548 mp->is_add = is_add;
9549
9550 S; W;
9551 /* NOTREACHED */
9552 return 0;
Dave Barachbfdedbd2016-01-20 09:11:55 -05009553#else
9554 clib_warning ("unsupported (no dpdk)");
9555 return -99;
9556#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -07009557}
9558
9559static int
9560api_ipsec_interface_add_del_spd (vat_main_t * vam)
9561{
Dave Barachbfdedbd2016-01-20 09:11:55 -05009562#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -07009563 unformat_input_t * i = vam->input;
9564 vl_api_ipsec_interface_add_del_spd_t *mp;
9565 f64 timeout;
9566 u32 sw_if_index;
9567 u8 sw_if_index_set = 0;
9568 u32 spd_id = (u32) ~0;
9569 u8 is_add = 1;
9570
9571 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9572 if (unformat (i, "del"))
9573 is_add = 0;
9574 else if (unformat (i, "spd_id %d", &spd_id))
9575 ;
9576 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9577 sw_if_index_set = 1;
9578 else if (unformat (i, "sw_if_index %d", &sw_if_index))
9579 sw_if_index_set = 1;
9580 else {
9581 clib_warning ("parse error '%U'", format_unformat_error, i);
9582 return -99;
9583 }
9584
9585 }
9586
9587 if (spd_id == (u32) ~0) {
9588 errmsg ("spd_id must be set\n");
9589 return -99;
9590 }
9591
9592 if (sw_if_index_set == 0) {
9593 errmsg ("missing interface name or sw_if_index\n");
9594 return -99;
9595 }
9596
9597 M(IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
9598
9599 mp->spd_id = ntohl(spd_id);
9600 mp->sw_if_index = ntohl (sw_if_index);
9601 mp->is_add = is_add;
9602
9603 S; W;
9604 /* NOTREACHED */
9605 return 0;
Dave Barachbfdedbd2016-01-20 09:11:55 -05009606#else
9607 clib_warning ("unsupported (no dpdk)");
9608 return -99;
9609#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -07009610}
9611
9612static int
9613api_ipsec_spd_add_del_entry (vat_main_t * vam)
9614{
Dave Barachbfdedbd2016-01-20 09:11:55 -05009615#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -07009616 unformat_input_t * i = vam->input;
9617 vl_api_ipsec_spd_add_del_entry_t *mp;
9618 f64 timeout;
9619 u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
9620 u32 spd_id, sa_id, protocol = 0, policy = 0;
9621 i32 priority;
9622 u32 rport_start = 0, rport_stop = (u32) ~0;
9623 u32 lport_start = 0, lport_stop = (u32) ~0;
9624 ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
9625 ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
9626
9627 laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
9628 laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~0;
9629 laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
9630 laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
9631 laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~0;
9632 laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~0;
9633
9634 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9635 if (unformat (i, "del"))
9636 is_add = 0;
9637 if (unformat (i, "outbound"))
9638 is_outbound = 1;
9639 if (unformat (i, "inbound"))
9640 is_outbound = 0;
9641 else if (unformat (i, "spd_id %d", &spd_id))
9642 ;
9643 else if (unformat (i, "sa_id %d", &sa_id))
9644 ;
9645 else if (unformat (i, "priority %d", &priority))
9646 ;
9647 else if (unformat (i, "protocol %d", &protocol))
9648 ;
9649 else if (unformat (i, "lport_start %d", &lport_start))
9650 ;
9651 else if (unformat (i, "lport_stop %d", &lport_stop))
9652 ;
9653 else if (unformat (i, "rport_start %d", &rport_start))
9654 ;
9655 else if (unformat (i, "rport_stop %d", &rport_stop))
9656 ;
9657 else if (unformat (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
9658 {
9659 is_ipv6 = 0;
9660 is_ip_any =0;
9661 }
9662 else if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
9663 {
9664 is_ipv6 = 0;
9665 is_ip_any = 0;
9666 }
9667 else if (unformat (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
9668 {
9669 is_ipv6 = 0;
9670 is_ip_any = 0;
9671 }
9672 else if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
9673 {
9674 is_ipv6 = 0;
9675 is_ip_any = 0;
9676 }
9677 else if (unformat (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
9678 {
9679 is_ipv6 = 1;
9680 is_ip_any = 0;
9681 }
9682 else if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
9683 {
9684 is_ipv6 = 1;
9685 is_ip_any = 0;
9686 }
9687 else if (unformat (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
9688 {
9689 is_ipv6 = 1;
9690 is_ip_any = 0;
9691 }
9692 else if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
9693 {
9694 is_ipv6 = 1;
9695 is_ip_any = 0;
9696 }
9697 else if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
9698 {
9699 if (policy == IPSEC_POLICY_ACTION_RESOLVE) {
9700 clib_warning ("unsupported action: 'resolve'");
9701 return -99;
9702 }
9703 }
9704 else {
9705 clib_warning ("parse error '%U'", format_unformat_error, i);
9706 return -99;
9707 }
9708
9709 }
9710
9711 M(IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
9712
9713 mp->spd_id = ntohl(spd_id);
9714 mp->priority = ntohl(priority);
9715 mp->is_outbound = is_outbound;
9716
9717 mp->is_ipv6 = is_ipv6;
9718 if (is_ipv6 || is_ip_any) {
Damjan Marionf1213b82016-03-13 02:22:06 +01009719 clib_memcpy (mp->remote_address_start, &raddr6_start, sizeof(ip6_address_t));
9720 clib_memcpy (mp->remote_address_stop, &raddr6_stop, sizeof(ip6_address_t));
9721 clib_memcpy (mp->local_address_start, &laddr6_start, sizeof(ip6_address_t));
9722 clib_memcpy (mp->local_address_stop, &laddr6_stop, sizeof(ip6_address_t));
Ed Warnickecb9cada2015-12-08 15:45:58 -07009723 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01009724 clib_memcpy (mp->remote_address_start, &raddr4_start, sizeof(ip4_address_t));
9725 clib_memcpy (mp->remote_address_stop, &raddr4_stop, sizeof(ip4_address_t));
9726 clib_memcpy (mp->local_address_start, &laddr4_start, sizeof(ip4_address_t));
9727 clib_memcpy (mp->local_address_stop, &laddr4_stop, sizeof(ip4_address_t));
Ed Warnickecb9cada2015-12-08 15:45:58 -07009728 }
9729 mp->protocol = (u8) protocol;
9730 mp->local_port_start = ntohs((u16) lport_start);
9731 mp->local_port_stop = ntohs((u16) lport_stop);
9732 mp->remote_port_start = ntohs((u16) rport_start);
9733 mp->remote_port_stop = ntohs((u16) rport_stop);
9734 mp->policy = (u8) policy;
9735 mp->sa_id = ntohl(sa_id);
9736 mp->is_add = is_add;
9737 mp->is_ip_any = is_ip_any;
9738 S; W;
9739 /* NOTREACHED */
9740 return 0;
Dave Barachbfdedbd2016-01-20 09:11:55 -05009741#else
9742 clib_warning ("unsupported (no dpdk)");
9743 return -99;
9744#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -07009745}
9746
9747static int
9748api_ipsec_sad_add_del_entry (vat_main_t * vam)
9749{
Dave Barachbfdedbd2016-01-20 09:11:55 -05009750#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -07009751 unformat_input_t * i = vam->input;
9752 vl_api_ipsec_sad_add_del_entry_t *mp;
9753 f64 timeout;
9754 u32 sad_id, spi;
Matus Fabian683d3ee2016-07-26 23:54:07 -07009755 u8 * ck = 0, * ik = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -07009756 u8 is_add = 1;
9757
9758 u8 protocol = IPSEC_PROTOCOL_AH;
9759 u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
9760 u32 crypto_alg = 0, integ_alg = 0;
9761 ip4_address_t tun_src4;
9762 ip4_address_t tun_dst4;
9763 ip6_address_t tun_src6;
9764 ip6_address_t tun_dst6;
9765
9766 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9767 if (unformat (i, "del"))
9768 is_add = 0;
9769 else if (unformat (i, "sad_id %d", &sad_id))
9770 ;
9771 else if (unformat (i, "spi %d", &spi))
9772 ;
9773 else if (unformat (i, "esp"))
9774 protocol = IPSEC_PROTOCOL_ESP;
9775 else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4)) {
9776 is_tunnel = 1;
9777 is_tunnel_ipv6 = 0;
9778 }
9779 else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4)) {
9780 is_tunnel = 1;
9781 is_tunnel_ipv6 = 0;
9782 }
9783 else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6)) {
9784 is_tunnel = 1;
9785 is_tunnel_ipv6 = 1;
9786 }
9787 else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6)) {
9788 is_tunnel = 1;
9789 is_tunnel_ipv6 = 1;
9790 }
9791 else if (unformat (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg)) {
9792 if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
9793 crypto_alg > IPSEC_INTEG_ALG_SHA_512_256) {
9794 clib_warning ("unsupported crypto-alg: '%U'",
9795 format_ipsec_crypto_alg, crypto_alg);
9796 return -99;
9797 }
9798 }
9799 else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
9800 ;
9801 else if (unformat (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg)) {
9802 if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
9803 integ_alg > IPSEC_INTEG_ALG_SHA_512_256) {
9804 clib_warning ("unsupported integ-alg: '%U'",
9805 format_ipsec_integ_alg, integ_alg);
9806 return -99;
9807 }
9808 }
9809 else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
9810 ;
9811 else {
9812 clib_warning ("parse error '%U'", format_unformat_error, i);
9813 return -99;
9814 }
9815
9816 }
9817
9818 M(IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
9819
9820 mp->sad_id = ntohl(sad_id);
9821 mp->is_add = is_add;
9822 mp->protocol = protocol;
9823 mp->spi = ntohl(spi);
9824 mp->is_tunnel = is_tunnel;
9825 mp->is_tunnel_ipv6 = is_tunnel_ipv6;
9826 mp->crypto_algorithm = crypto_alg;
9827 mp->integrity_algorithm = integ_alg;
9828 mp->crypto_key_length = vec_len(ck);
9829 mp->integrity_key_length = vec_len(ik);
9830
9831 if (mp->crypto_key_length > sizeof(mp->crypto_key))
9832 mp->crypto_key_length = sizeof(mp->crypto_key);
9833
9834 if (mp->integrity_key_length > sizeof(mp->integrity_key))
9835 mp->integrity_key_length = sizeof(mp->integrity_key);
9836
Damjan Marionf1213b82016-03-13 02:22:06 +01009837 clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
9838 clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
Ed Warnickecb9cada2015-12-08 15:45:58 -07009839
9840 if (is_tunnel) {
9841 if (is_tunnel_ipv6) {
Damjan Marionf1213b82016-03-13 02:22:06 +01009842 clib_memcpy (mp->tunnel_src_address, &tun_src6, sizeof(ip6_address_t));
9843 clib_memcpy (mp->tunnel_dst_address, &tun_dst6, sizeof(ip6_address_t));
Ed Warnickecb9cada2015-12-08 15:45:58 -07009844 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01009845 clib_memcpy (mp->tunnel_src_address, &tun_src4, sizeof(ip4_address_t));
9846 clib_memcpy (mp->tunnel_dst_address, &tun_dst4, sizeof(ip4_address_t));
Ed Warnickecb9cada2015-12-08 15:45:58 -07009847 }
9848 }
9849
9850 S; W;
9851 /* NOTREACHED */
9852 return 0;
Dave Barachbfdedbd2016-01-20 09:11:55 -05009853#else
9854 clib_warning ("unsupported (no dpdk)");
9855 return -99;
9856#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -07009857}
9858
9859static int
9860api_ipsec_sa_set_key (vat_main_t * vam)
9861{
Dave Barachbfdedbd2016-01-20 09:11:55 -05009862#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -07009863 unformat_input_t * i = vam->input;
9864 vl_api_ipsec_sa_set_key_t *mp;
9865 f64 timeout;
9866 u32 sa_id;
Matus Fabian683d3ee2016-07-26 23:54:07 -07009867 u8 * ck = 0, * ik = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -07009868
9869 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9870 if (unformat (i, "sa_id %d", &sa_id))
9871 ;
9872 else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
9873 ;
9874 else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
9875 ;
9876 else {
9877 clib_warning ("parse error '%U'", format_unformat_error, i);
9878 return -99;
9879 }
9880 }
9881
9882 M(IPSEC_SA_SET_KEY, ipsec_set_sa_key);
9883
9884 mp->sa_id = ntohl(sa_id);
9885 mp->crypto_key_length = vec_len(ck);
9886 mp->integrity_key_length = vec_len(ik);
9887
9888 if (mp->crypto_key_length > sizeof(mp->crypto_key))
9889 mp->crypto_key_length = sizeof(mp->crypto_key);
9890
9891 if (mp->integrity_key_length > sizeof(mp->integrity_key))
9892 mp->integrity_key_length = sizeof(mp->integrity_key);
9893
Damjan Marionf1213b82016-03-13 02:22:06 +01009894 clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
9895 clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
Ed Warnickecb9cada2015-12-08 15:45:58 -07009896
9897 S; W;
9898 /* NOTREACHED */
9899 return 0;
Dave Barachbfdedbd2016-01-20 09:11:55 -05009900#else
9901 clib_warning ("unsupported (no dpdk)");
9902 return -99;
9903#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -07009904}
9905
Matus Fabiane5f42fe2016-04-08 11:18:08 +02009906static int
9907api_ikev2_profile_add_del (vat_main_t * vam)
9908{
9909#if DPDK > 0
9910 unformat_input_t * i = vam->input;
9911 vl_api_ikev2_profile_add_del_t * mp;
9912 f64 timeout;
9913 u8 is_add = 1;
9914 u8 * name = 0;
9915
9916 const char * valid_chars = "a-zA-Z0-9_";
9917
9918 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9919 if (unformat (i, "del"))
9920 is_add = 0;
9921 else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
9922 vec_add1 (name, 0);
9923 else {
9924 errmsg ("parse error '%U'", format_unformat_error, i);
9925 return -99;
9926 }
9927 }
9928
9929 if (!vec_len (name)) {
9930 errmsg ("profile name must be specified");
9931 return -99;
9932 }
9933
9934 if (vec_len (name) > 64) {
9935 errmsg ("profile name too long");
9936 return -99;
9937 }
9938
9939 M(IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
9940
Damjan Marionf1213b82016-03-13 02:22:06 +01009941 clib_memcpy(mp->name, name, vec_len (name));
Matus Fabiane5f42fe2016-04-08 11:18:08 +02009942 mp->is_add = is_add;
9943 vec_free (name);
9944
9945 S; W;
9946 /* NOTREACHED */
9947 return 0;
9948#else
9949 clib_warning ("unsupported (no dpdk)");
9950 return -99;
9951#endif
9952}
9953
9954static int
9955api_ikev2_profile_set_auth (vat_main_t * vam)
9956{
9957#if DPDK > 0
9958 unformat_input_t * i = vam->input;
9959 vl_api_ikev2_profile_set_auth_t * mp;
9960 f64 timeout;
9961 u8 * name = 0;
9962 u8 * data = 0;
9963 u32 auth_method = 0;
9964 u8 is_hex = 0;
9965
9966 const char * valid_chars = "a-zA-Z0-9_";
9967
9968 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9969 if (unformat (i, "name %U", unformat_token, valid_chars, &name))
9970 vec_add1 (name, 0);
9971 else if (unformat (i, "auth_method %U",
9972 unformat_ikev2_auth_method, &auth_method))
9973 ;
9974 else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
9975 is_hex = 1;
9976 else if (unformat (i, "auth_data %v", &data))
9977 ;
9978 else {
9979 errmsg ("parse error '%U'", format_unformat_error, i);
9980 return -99;
9981 }
9982 }
9983
9984 if (!vec_len (name)) {
9985 errmsg ("profile name must be specified");
9986 return -99;
9987 }
9988
9989 if (vec_len (name) > 64) {
9990 errmsg ("profile name too long");
9991 return -99;
9992 }
9993
9994 if (!vec_len(data)) {
9995 errmsg ("auth_data must be specified");
9996 return -99;
9997 }
9998
9999 if (!auth_method) {
10000 errmsg ("auth_method must be specified");
10001 return -99;
10002 }
10003
10004 M(IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
10005
10006 mp->is_hex = is_hex;
10007 mp->auth_method = (u8) auth_method;
10008 mp->data_len = vec_len (data);
Damjan Marionf1213b82016-03-13 02:22:06 +010010009 clib_memcpy (mp->name, name, vec_len (name));
10010 clib_memcpy (mp->data, data, vec_len (data));
Matus Fabiane5f42fe2016-04-08 11:18:08 +020010011 vec_free (name);
10012 vec_free (data);
10013
10014 S; W;
10015 /* NOTREACHED */
10016 return 0;
10017#else
10018 clib_warning ("unsupported (no dpdk)");
10019 return -99;
10020#endif
10021}
10022
10023static int
10024api_ikev2_profile_set_id (vat_main_t * vam)
10025{
10026#if DPDK > 0
10027 unformat_input_t * i = vam->input;
10028 vl_api_ikev2_profile_set_id_t * mp;
10029 f64 timeout;
10030 u8 * name = 0;
10031 u8 * data = 0;
10032 u8 is_local = 0;
10033 u32 id_type = 0;
10034 ip4_address_t ip4;
10035
10036 const char * valid_chars = "a-zA-Z0-9_";
10037
10038 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
10039 if (unformat (i, "name %U", unformat_token, valid_chars, &name))
10040 vec_add1 (name, 0);
10041 else if (unformat (i, "id_type %U",
10042 unformat_ikev2_id_type, &id_type))
10043 ;
10044 else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
10045 {
10046 data = vec_new(u8, 4);
Damjan Marionf1213b82016-03-13 02:22:06 +010010047 clib_memcpy(data, ip4.as_u8, 4);
Matus Fabiane5f42fe2016-04-08 11:18:08 +020010048 }
10049 else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
10050 ;
10051 else if (unformat (i, "id_data %v", &data))
10052 ;
10053 else if (unformat (i, "local"))
10054 is_local = 1;
10055 else if (unformat (i, "remote"))
10056 is_local = 0;
10057 else {
10058 errmsg ("parse error '%U'", format_unformat_error, i);
10059 return -99;
10060 }
10061 }
10062
10063 if (!vec_len (name)) {
10064 errmsg ("profile name must be specified");
10065 return -99;
10066 }
10067
10068 if (vec_len (name) > 64) {
10069 errmsg ("profile name too long");
10070 return -99;
10071 }
10072
10073 if (!vec_len(data)) {
10074 errmsg ("id_data must be specified");
10075 return -99;
10076 }
10077
10078 if (!id_type) {
10079 errmsg ("id_type must be specified");
10080 return -99;
10081 }
10082
10083 M(IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
10084
10085 mp->is_local = is_local;
10086 mp->id_type = (u8) id_type;
10087 mp->data_len = vec_len (data);
Damjan Marionf1213b82016-03-13 02:22:06 +010010088 clib_memcpy (mp->name, name, vec_len (name));
10089 clib_memcpy (mp->data, data, vec_len (data));
Matus Fabiane5f42fe2016-04-08 11:18:08 +020010090 vec_free (name);
10091 vec_free (data);
10092
10093 S; W;
10094 /* NOTREACHED */
10095 return 0;
10096#else
10097 clib_warning ("unsupported (no dpdk)");
10098 return -99;
10099#endif
10100}
10101
10102static int
10103api_ikev2_profile_set_ts (vat_main_t * vam)
10104{
10105#if DPDK > 0
10106 unformat_input_t * i = vam->input;
10107 vl_api_ikev2_profile_set_ts_t * mp;
10108 f64 timeout;
10109 u8 * name = 0;
10110 u8 is_local = 0;
10111 u32 proto = 0, start_port = 0, end_port = (u32) ~0;
10112 ip4_address_t start_addr, end_addr;
10113
10114 const char * valid_chars = "a-zA-Z0-9_";
10115
10116 start_addr.as_u32 = 0;
10117 end_addr.as_u32 = (u32) ~0;
10118
10119 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
10120 if (unformat (i, "name %U", unformat_token, valid_chars, &name))
10121 vec_add1 (name, 0);
10122 else if (unformat (i, "protocol %d", &proto))
10123 ;
10124 else if (unformat (i, "start_port %d", &start_port))
10125 ;
10126 else if (unformat (i, "end_port %d", &end_port))
10127 ;
10128 else if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
10129 ;
10130 else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
10131 ;
10132 else if (unformat (i, "local"))
10133 is_local = 1;
10134 else if (unformat (i, "remote"))
10135 is_local = 0;
10136 else {
10137 errmsg ("parse error '%U'", format_unformat_error, i);
10138 return -99;
10139 }
10140 }
10141
10142 if (!vec_len (name)) {
10143 errmsg ("profile name must be specified");
10144 return -99;
10145 }
10146
10147 if (vec_len (name) > 64) {
10148 errmsg ("profile name too long");
10149 return -99;
10150 }
10151
10152 M(IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
10153
10154 mp->is_local = is_local;
10155 mp->proto = (u8) proto;
10156 mp->start_port = (u16) start_port;
10157 mp->end_port = (u16) end_port;
10158 mp->start_addr = start_addr.as_u32;
10159 mp->end_addr = end_addr.as_u32;
Damjan Marionf1213b82016-03-13 02:22:06 +010010160 clib_memcpy (mp->name, name, vec_len (name));
Matus Fabiane5f42fe2016-04-08 11:18:08 +020010161 vec_free (name);
10162
10163 S; W;
10164 /* NOTREACHED */
10165 return 0;
10166#else
10167 clib_warning ("unsupported (no dpdk)");
10168 return -99;
10169#endif
10170}
10171
10172static int
10173api_ikev2_set_local_key (vat_main_t * vam)
10174{
10175#if DPDK > 0
10176 unformat_input_t * i = vam->input;
10177 vl_api_ikev2_set_local_key_t * mp;
10178 f64 timeout;
10179 u8 * file = 0;
10180
10181 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
10182 if (unformat (i, "file %v", &file))
10183 vec_add1 (file, 0);
10184 else {
10185 errmsg ("parse error '%U'", format_unformat_error, i);
10186 return -99;
10187 }
10188 }
10189
10190 if (!vec_len (file)) {
10191 errmsg ("RSA key file must be specified");
10192 return -99;
10193 }
10194
10195 if (vec_len (file) > 256) {
10196 errmsg ("file name too long");
10197 return -99;
10198 }
10199
10200 M(IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
10201
Damjan Marionf1213b82016-03-13 02:22:06 +010010202 clib_memcpy (mp->key_file, file, vec_len (file));
Matus Fabiane5f42fe2016-04-08 11:18:08 +020010203 vec_free (file);
10204
10205 S; W;
10206 /* NOTREACHED */
10207 return 0;
10208#else
10209 clib_warning ("unsupported (no dpdk)");
10210 return -99;
10211#endif
10212}
10213
Ed Warnickecb9cada2015-12-08 15:45:58 -070010214/*
10215 * MAP
10216 */
10217static int api_map_add_domain (vat_main_t * vam)
10218{
10219 unformat_input_t *i = vam->input;
10220 vl_api_map_add_domain_t *mp;
10221 f64 timeout;
10222
10223 ip4_address_t ip4_prefix;
10224 ip6_address_t ip6_prefix;
10225 ip6_address_t ip6_src;
10226 u32 num_m_args = 0;
10227 u32 ip6_prefix_len, ip4_prefix_len, ea_bits_len, psid_offset,
10228 psid_length;
10229 u8 is_translation = 0;
10230 u32 mtu = 0;
10231 u8 ip6_src_len = 128;
10232
10233 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
10234 if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
10235 &ip4_prefix, &ip4_prefix_len))
10236 num_m_args++;
10237 else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
10238 &ip6_prefix, &ip6_prefix_len))
10239 num_m_args++;
10240 else if (unformat (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src, &ip6_src_len))
10241 num_m_args++;
10242 else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
10243 num_m_args++;
10244 else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
10245 num_m_args++;
10246 else if (unformat (i, "psid-offset %d", &psid_offset))
10247 num_m_args++;
10248 else if (unformat (i, "psid-len %d", &psid_length))
10249 num_m_args++;
10250 else if (unformat (i, "mtu %d", &mtu))
10251 num_m_args++;
10252 else if (unformat (i, "map-t"))
10253 is_translation = 1;
10254 else {
10255 clib_warning ("parse error '%U'", format_unformat_error, i);
10256 return -99;
10257 }
10258 }
10259
10260 if (num_m_args != 6) {
10261 errmsg("mandatory argument(s) missing\n");
10262 return -99;
10263 }
10264
10265 /* Construct the API message */
10266 M(MAP_ADD_DOMAIN, map_add_domain);
10267
Damjan Marionf1213b82016-03-13 02:22:06 +010010268 clib_memcpy(mp->ip4_prefix, &ip4_prefix, sizeof(ip4_prefix));
Ed Warnickecb9cada2015-12-08 15:45:58 -070010269 mp->ip4_prefix_len = ip4_prefix_len;
10270
Damjan Marionf1213b82016-03-13 02:22:06 +010010271 clib_memcpy(mp->ip6_prefix, &ip6_prefix, sizeof(ip6_prefix));
Ed Warnickecb9cada2015-12-08 15:45:58 -070010272 mp->ip6_prefix_len = ip6_prefix_len;
10273
Damjan Marionf1213b82016-03-13 02:22:06 +010010274 clib_memcpy(mp->ip6_src, &ip6_src, sizeof(ip6_src));
Ed Warnickecb9cada2015-12-08 15:45:58 -070010275 mp->ip6_src_prefix_len = ip6_src_len;
10276
10277 mp->ea_bits_len = ea_bits_len;
10278 mp->psid_offset = psid_offset;
10279 mp->psid_length = psid_length;
10280 mp->is_translation = is_translation;
10281 mp->mtu = htons(mtu);
10282
10283 /* send it... */
10284 S;
10285
10286 /* Wait for a reply, return good/bad news */
10287 W;
10288}
10289
10290static int api_map_del_domain (vat_main_t * vam)
10291{
10292 unformat_input_t *i = vam->input;
10293 vl_api_map_del_domain_t *mp;
10294 f64 timeout;
10295
10296 u32 num_m_args = 0;
10297 u32 index;
10298
10299 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
10300 if (unformat (i, "index %d", &index))
10301 num_m_args++;
10302 else {
10303 clib_warning ("parse error '%U'", format_unformat_error, i);
10304 return -99;
10305 }
10306 }
10307
10308 if (num_m_args != 1) {
10309 errmsg("mandatory argument(s) missing\n");
10310 return -99;
10311 }
10312
10313 /* Construct the API message */
10314 M(MAP_DEL_DOMAIN, map_del_domain);
10315
10316 mp->index = ntohl(index);
10317
10318 /* send it... */
10319 S;
10320
10321 /* Wait for a reply, return good/bad news */
10322 W;
10323}
10324
10325static int api_map_add_del_rule (vat_main_t * vam)
10326{
10327 unformat_input_t *i = vam->input;
10328 vl_api_map_add_del_rule_t *mp;
10329 f64 timeout;
10330 u8 is_add = 1;
10331 ip6_address_t ip6_dst;
10332 u32 num_m_args = 0, index, psid;
10333
10334 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
10335 if (unformat (i, "index %d", &index))
10336 num_m_args++;
10337 else if (unformat (i, "psid %d", &psid))
10338 num_m_args++;
10339 else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
10340 num_m_args++;
10341 else if (unformat (i, "del")) {
10342 is_add = 0;
10343 } else {
10344 clib_warning ("parse error '%U'", format_unformat_error, i);
10345 return -99;
10346 }
10347 }
10348
10349 /* Construct the API message */
10350 M(MAP_ADD_DEL_RULE, map_add_del_rule);
10351
10352 mp->index = ntohl(index);
10353 mp->is_add = is_add;
Damjan Marionf1213b82016-03-13 02:22:06 +010010354 clib_memcpy(mp->ip6_dst, &ip6_dst, sizeof(ip6_dst));
Ed Warnickecb9cada2015-12-08 15:45:58 -070010355 mp->psid = ntohs(psid);
10356
10357 /* send it... */
10358 S;
10359
10360 /* Wait for a reply, return good/bad news */
10361 W;
10362}
10363
10364static int api_map_domain_dump (vat_main_t * vam)
10365{
10366 vl_api_map_domain_dump_t *mp;
10367 f64 timeout;
10368
10369 /* Construct the API message */
10370 M(MAP_DOMAIN_DUMP, map_domain_dump);
10371
10372 /* send it... */
10373 S;
10374
10375 /* Use a control ping for synchronization */
10376 {
10377 vl_api_control_ping_t * mp;
10378 M(CONTROL_PING, control_ping);
10379 S;
10380 }
10381 W;
10382}
10383
10384static int api_map_rule_dump (vat_main_t * vam)
10385{
10386 unformat_input_t *i = vam->input;
10387 vl_api_map_rule_dump_t *mp;
10388 f64 timeout;
10389 u32 domain_index = ~0;
10390
10391 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
10392 if (unformat (i, "index %u", &domain_index))
10393 ;
10394 else
10395 break;
10396 }
10397
10398 if (domain_index == ~0) {
10399 clib_warning("parse error: domain index expected");
10400 return -99;
10401 }
10402
10403 /* Construct the API message */
10404 M(MAP_RULE_DUMP, map_rule_dump);
10405
10406 mp->domain_index = htonl(domain_index);
10407
10408 /* send it... */
10409 S;
10410
10411 /* Use a control ping for synchronization */
10412 {
10413 vl_api_control_ping_t * mp;
10414 M(CONTROL_PING, control_ping);
10415 S;
10416 }
10417 W;
10418}
10419
10420static void vl_api_map_add_domain_reply_t_handler
10421(vl_api_map_add_domain_reply_t * mp)
10422{
10423 vat_main_t * vam = &vat_main;
10424 i32 retval = ntohl(mp->retval);
10425
10426 if (vam->async_mode) {
10427 vam->async_errors += (retval < 0);
10428 } else {
10429 vam->retval = retval;
10430 vam->result_ready = 1;
10431 }
10432}
10433
10434static void vl_api_map_add_domain_reply_t_handler_json
10435(vl_api_map_add_domain_reply_t * mp)
10436{
10437 vat_main_t * vam = &vat_main;
10438 vat_json_node_t node;
10439
10440 vat_json_init_object(&node);
10441 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
10442 vat_json_object_add_uint(&node, "index", ntohl(mp->index));
10443
10444 vat_json_print(vam->ofp, &node);
10445 vat_json_free(&node);
10446
10447 vam->retval = ntohl(mp->retval);
10448 vam->result_ready = 1;
10449}
10450
10451static int
10452api_get_first_msg_id (vat_main_t * vam)
10453{
10454 vl_api_get_first_msg_id_t * mp;
10455 f64 timeout;
10456 unformat_input_t * i = vam->input;
10457 u8 * name;
10458 u8 name_set = 0;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +080010459
Ed Warnickecb9cada2015-12-08 15:45:58 -070010460 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
10461 if (unformat (i, "client %s", &name))
10462 name_set = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +080010463 else
Ed Warnickecb9cada2015-12-08 15:45:58 -070010464 break;
10465 }
10466
10467 if (name_set == 0) {
10468 errmsg ("missing client name\n");
10469 return -99;
10470 }
10471 vec_add1 (name, 0);
10472
10473 if (vec_len (name) > 63) {
10474 errmsg ("client name too long\n");
10475 return -99;
10476 }
10477
10478 M(GET_FIRST_MSG_ID, get_first_msg_id);
Damjan Marionf1213b82016-03-13 02:22:06 +010010479 clib_memcpy (mp->name, name, vec_len(name));
Ed Warnickecb9cada2015-12-08 15:45:58 -070010480 S; W;
10481 /* NOTREACHED */
10482 return 0;
10483}
10484
Dave Barachc07bf5d2016-02-17 17:52:26 -050010485static int api_cop_interface_enable_disable (vat_main_t * vam)
10486{
10487 unformat_input_t * line_input = vam->input;
10488 vl_api_cop_interface_enable_disable_t * mp;
10489 f64 timeout;
10490 u32 sw_if_index = ~0;
10491 u8 enable_disable = 1;
10492
10493 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
10494 if (unformat (line_input, "disable"))
10495 enable_disable = 0;
10496 if (unformat (line_input, "enable"))
10497 enable_disable = 1;
10498 else if (unformat (line_input, "%U", unformat_sw_if_index,
10499 vam, &sw_if_index))
10500 ;
10501 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
10502 ;
10503 else
10504 break;
10505 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +080010506
Dave Barachc07bf5d2016-02-17 17:52:26 -050010507 if (sw_if_index == ~0) {
10508 errmsg ("missing interface name or sw_if_index\n");
10509 return -99;
10510 }
10511
10512 /* Construct the API message */
10513 M(COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
10514 mp->sw_if_index = ntohl(sw_if_index);
10515 mp->enable_disable = enable_disable;
10516
10517 /* send it... */
10518 S;
10519 /* Wait for the reply */
10520 W;
10521}
10522
10523static int api_cop_whitelist_enable_disable (vat_main_t * vam)
10524{
10525 unformat_input_t * line_input = vam->input;
10526 vl_api_cop_whitelist_enable_disable_t * mp;
10527 f64 timeout;
10528 u32 sw_if_index = ~0;
10529 u8 ip4=0, ip6=0, default_cop=0;
10530 u32 fib_id;
10531
10532 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
10533 if (unformat (line_input, "ip4"))
10534 ip4 = 1;
10535 else if (unformat (line_input, "ip6"))
10536 ip6 = 1;
10537 else if (unformat (line_input, "default"))
10538 default_cop = 1;
10539 else if (unformat (line_input, "%U", unformat_sw_if_index,
10540 vam, &sw_if_index))
10541 ;
10542 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
10543 ;
10544 else if (unformat (line_input, "fib-id %d", &fib_id))
10545 ;
10546 else
10547 break;
10548 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +080010549
Dave Barachc07bf5d2016-02-17 17:52:26 -050010550 if (sw_if_index == ~0) {
10551 errmsg ("missing interface name or sw_if_index\n");
10552 return -99;
10553 }
10554
10555 /* Construct the API message */
10556 M(COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
10557 mp->sw_if_index = ntohl(sw_if_index);
10558 mp->fib_id = ntohl(fib_id);
10559 mp->ip4 = ip4;
10560 mp->ip6 = ip6;
10561 mp->default_cop = default_cop;
10562
10563 /* send it... */
10564 S;
10565 /* Wait for the reply */
10566 W;
10567}
10568
Dave Barachb44e9bc2016-02-19 09:06:23 -050010569static int api_get_node_graph (vat_main_t * vam)
10570{
10571 vl_api_get_node_graph_t * mp;
10572 f64 timeout;
10573
10574 M(GET_NODE_GRAPH, get_node_graph);
10575
10576 /* send it... */
10577 S;
10578 /* Wait for the reply */
10579 W;
10580}
10581
Florin Coras429e7952016-08-02 02:31:03 +020010582/** Used for parsing LISP eids */
10583typedef CLIB_PACKED(struct{
10584 u8 addr[16]; /**< eid address */
10585 u32 len; /**< prefix length if IP */
10586 u8 type; /**< type of eid */
10587}) lisp_eid_vat_t;
10588
10589static uword
10590unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
10591{
10592 lisp_eid_vat_t * a = va_arg(*args, lisp_eid_vat_t *);
10593
10594 memset(a, 0, sizeof(a[0]));
10595
10596 if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len)) {
10597 a->type = 0; /* ipv4 type */
10598 } else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr,
10599 &a->len)) {
10600 a->type = 1; /* ipv6 type */
10601 } else if (unformat (input, "%U", unformat_ethernet_address, a->addr)) {
10602 a->type = 2; /* mac type */
10603 } else {
10604 return 0;
10605 }
10606
10607 if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128)) {
10608 return 0;
10609 }
10610
10611 return 1;
10612}
10613
10614static int
10615lisp_eid_size_vat (u8 type)
10616{
10617 switch (type) {
10618 case 0:
10619 return 4;
10620 case 1:
10621 return 16;
10622 case 2:
10623 return 6;
10624 }
10625 return 0;
10626}
10627
10628static void
10629lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
10630{
10631 clib_memcpy(dst, eid, lisp_eid_size_vat(type));
10632}
10633
Andrej Kozemcaka8691752016-07-27 10:33:38 +020010634/** Used for transferring locators via VPP API */
10635typedef CLIB_PACKED(struct
10636{
10637 u32 sw_if_index; /**< locator sw_if_index */
10638 u8 priority; /**< locator priority */
10639 u8 weight; /**< locator weight */
10640}) ls_locator_t;
10641
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010642static int
10643api_lisp_add_del_locator_set(vat_main_t * vam)
10644{
10645 unformat_input_t * input = vam->input;
10646 vl_api_lisp_add_del_locator_set_t *mp;
10647 f64 timeout = ~0;
10648 u8 is_add = 1;
10649 u8 *locator_set_name = NULL;
10650 u8 locator_set_name_set = 0;
Andrej Kozemcaka8691752016-07-27 10:33:38 +020010651 ls_locator_t locator, * locators = 0;
10652 u32 sw_if_index, priority, weight;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010653
10654 /* Parse args required to build the message */
10655 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
10656 if (unformat(input, "del")) {
10657 is_add = 0;
10658 } else if (unformat(input, "locator-set %s", &locator_set_name)) {
10659 locator_set_name_set = 1;
Andrej Kozemcaka8691752016-07-27 10:33:38 +020010660 } else if (unformat(input, "sw_if_index %u p %u w %u",
10661 &sw_if_index, &priority, &weight)) {
10662 locator.sw_if_index = htonl(sw_if_index);
10663 locator.priority = priority;
10664 locator.weight = weight;
10665 vec_add1(locators, locator);
10666 } else if (unformat(input, "iface %U p %u w %u", unformat_sw_if_index,
10667 vam, &sw_if_index, &priority, &weight)) {
10668 locator.sw_if_index = htonl(sw_if_index);
10669 locator.priority = priority;
10670 locator.weight = weight;
10671 vec_add1(locators, locator);
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010672 } else
10673 break;
10674 }
10675
10676 if (locator_set_name_set == 0) {
10677 errmsg ("missing locator-set name");
Andrej Kozemcaka8691752016-07-27 10:33:38 +020010678 vec_free(locators);
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010679 return -99;
10680 }
10681
10682 if (vec_len(locator_set_name) > 64) {
10683 errmsg ("locator-set name too long\n");
10684 vec_free(locator_set_name);
Andrej Kozemcaka8691752016-07-27 10:33:38 +020010685 vec_free(locators);
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010686 return -99;
10687 }
10688 vec_add1(locator_set_name, 0);
10689
10690 /* Construct the API message */
10691 M(LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set);
10692
10693 mp->is_add = is_add;
Damjan Marionf1213b82016-03-13 02:22:06 +010010694 clib_memcpy(mp->locator_set_name, locator_set_name,
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010695 vec_len(locator_set_name));
10696 vec_free(locator_set_name);
10697
Andrej Kozemcaka8691752016-07-27 10:33:38 +020010698 mp->locator_num = vec_len (locators);
10699 clib_memcpy (mp->locators, locators,
10700 (sizeof (ls_locator_t) * vec_len (locators)));
10701 vec_free (locators);
10702
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010703 /* send it... */
10704 S;
10705
10706 /* Wait for a reply... */
10707 W;
10708
10709 /* NOTREACHED */
10710 return 0;
10711}
10712
10713static int
10714api_lisp_add_del_locator(vat_main_t * vam)
10715{
10716 unformat_input_t * input = vam->input;
10717 vl_api_lisp_add_del_locator_t *mp;
10718 f64 timeout = ~0;
10719 u32 tmp_if_index = ~0;
10720 u32 sw_if_index = ~0;
10721 u8 sw_if_index_set = 0;
10722 u8 sw_if_index_if_name_set = 0;
Filip Tehlarc4770ec2016-06-30 09:46:08 +020010723 u32 priority = ~0;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010724 u8 priority_set = 0;
Filip Tehlarc4770ec2016-06-30 09:46:08 +020010725 u32 weight = ~0;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010726 u8 weight_set = 0;
10727 u8 is_add = 1;
10728 u8 *locator_set_name = NULL;
10729 u8 locator_set_name_set = 0;
10730
10731 /* Parse args required to build the message */
10732 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
10733 if (unformat(input, "del")) {
10734 is_add = 0;
10735 } else if (unformat(input, "locator-set %s", &locator_set_name)) {
10736 locator_set_name_set = 1;
10737 } else if (unformat(input, "iface %U", unformat_sw_if_index, vam,
10738 &tmp_if_index)) {
10739 sw_if_index_if_name_set = 1;
10740 sw_if_index = tmp_if_index;
10741 } else if (unformat(input,"sw_if_index %d", &tmp_if_index)) {
10742 sw_if_index_set = 1;
10743 sw_if_index = tmp_if_index;
10744 } else if (unformat(input, "p %d", &priority)) {
10745 priority_set = 1;
10746 } else if (unformat(input, "w %d", &weight)) {
10747 weight_set = 1;
10748 } else
10749 break;
10750 }
10751
10752 if (locator_set_name_set == 0) {
10753 errmsg ("missing locator-set name");
10754 return -99;
10755 }
10756
10757 if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0) {
10758 errmsg ("missing sw_if_index");
10759 vec_free(locator_set_name);
10760 return -99;
10761 }
10762
10763 if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0) {
10764 errmsg ("cannot use both params interface name and sw_if_index");
10765 vec_free(locator_set_name);
10766 return -99;
10767 }
10768
10769 if (priority_set == 0) {
10770 errmsg ("missing locator-set priority\n");
10771 vec_free(locator_set_name);
10772 return -99;
10773 }
10774
10775 if (weight_set == 0) {
10776 errmsg ("missing locator-set weight\n");
10777 vec_free(locator_set_name);
10778 return -99;
10779 }
10780
10781 if (vec_len(locator_set_name) > 64) {
10782 errmsg ("locator-set name too long\n");
10783 vec_free(locator_set_name);
10784 return -99;
10785 }
10786 vec_add1(locator_set_name, 0);
10787
10788 /* Construct the API message */
10789 M(LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
10790
10791 mp->is_add = is_add;
10792 mp->sw_if_index = ntohl(sw_if_index);
10793 mp->priority = priority;
10794 mp->weight = weight;
Damjan Marionf1213b82016-03-13 02:22:06 +010010795 clib_memcpy(mp->locator_set_name, locator_set_name,
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010796 vec_len(locator_set_name));
10797 vec_free(locator_set_name);
10798
10799 /* send it... */
10800 S;
10801
10802 /* Wait for a reply... */
10803 W;
10804
10805 /* NOTREACHED */
10806 return 0;
10807}
10808
10809static int
10810api_lisp_add_del_local_eid(vat_main_t * vam)
10811{
10812 unformat_input_t * input = vam->input;
10813 vl_api_lisp_add_del_local_eid_t *mp;
10814 f64 timeout = ~0;
10815 u8 is_add = 1;
Florin Coras429e7952016-08-02 02:31:03 +020010816 u8 eid_set = 0;
10817 lisp_eid_vat_t _eid, *eid = &_eid;
10818 u8 *locator_set_name = 0;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010819 u8 locator_set_name_set = 0;
Filip Tehlar324112f2016-06-02 16:07:38 +020010820 u32 vni = 0;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010821
10822 /* Parse args required to build the message */
10823 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
10824 if (unformat(input, "del")) {
10825 is_add = 0;
Florin Corasbb433382016-07-18 17:06:20 +020010826 } else if (unformat(input, "vni %d", &vni)) {
Filip Tehlar324112f2016-06-02 16:07:38 +020010827 ;
Florin Coras429e7952016-08-02 02:31:03 +020010828 } else if (unformat(input, "eid %U", unformat_lisp_eid_vat, eid)) {
10829 eid_set = 1;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010830 } else if (unformat(input, "locator-set %s", &locator_set_name)) {
10831 locator_set_name_set = 1;
10832 } else
10833 break;
10834 }
10835
10836 if (locator_set_name_set == 0) {
10837 errmsg ("missing locator-set name\n");
10838 return -99;
10839 }
10840
Florin Coras429e7952016-08-02 02:31:03 +020010841 if (0 == eid_set) {
Filip Tehlar006eb262016-06-27 13:09:20 +020010842 errmsg ("EID address not set!");
10843 vec_free(locator_set_name);
10844 return -99;
10845 }
10846
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010847 if (vec_len(locator_set_name) > 64) {
10848 errmsg ("locator-set name too long\n");
10849 vec_free(locator_set_name);
10850 return -99;
10851 }
10852 vec_add1(locator_set_name, 0);
10853
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010854 /* Construct the API message */
10855 M(LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
10856
10857 mp->is_add = is_add;
Florin Coras429e7952016-08-02 02:31:03 +020010858 lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
10859 mp->eid_type = eid->type;
10860 mp->prefix_len = eid->len;
Filip Tehlar324112f2016-06-02 16:07:38 +020010861 mp->vni = clib_host_to_net_u32(vni);
Damjan Marionf1213b82016-03-13 02:22:06 +010010862 clib_memcpy(mp->locator_set_name, locator_set_name,
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010863 vec_len(locator_set_name));
Florin Coras429e7952016-08-02 02:31:03 +020010864
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010865 vec_free(locator_set_name);
10866
10867 /* send it... */
10868 S;
10869
10870 /* Wait for a reply... */
10871 W;
10872
10873 /* NOTREACHED */
10874 return 0;
10875}
10876
Florin Coras429e7952016-08-02 02:31:03 +020010877/** Used for transferring locators via VPP API */
10878typedef CLIB_PACKED(struct
10879{
10880 u8 is_ip4; /**< is locator an IPv4 address? */
10881 u8 priority; /**< locator priority */
10882 u8 weight; /**< locator weight */
10883 u8 addr[16]; /**< IPv4/IPv6 address */
10884}) rloc_t;
10885
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010886static int
10887api_lisp_gpe_add_del_fwd_entry(vat_main_t * vam)
10888{
10889 unformat_input_t * input = vam->input;
10890 vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
10891 f64 timeout = ~0;
10892 u8 is_add = 1;
Florin Coras429e7952016-08-02 02:31:03 +020010893 lisp_eid_vat_t _rmt_eid, * rmt_eid = &_rmt_eid;
10894 lisp_eid_vat_t _lcl_eid, * lcl_eid = &_lcl_eid;
10895 u8 rmt_eid_set = 0, lcl_eid_set = 0;
10896 u32 action = ~0, p, w;
10897 ip4_address_t rmt_rloc4, lcl_rloc4;
10898 ip6_address_t rmt_rloc6, lcl_rloc6;
10899 rloc_t * rmt_locs = 0, * lcl_locs = 0, rloc, * curr_rloc = 0;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010900
10901 /* Parse args required to build the message */
10902 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
10903 if (unformat(input, "del")) {
10904 is_add = 0;
Florin Coras429e7952016-08-02 02:31:03 +020010905 } else if (unformat(input, "rmt_eid %U", unformat_lisp_eid_vat,
10906 rmt_eid)) {
10907 rmt_eid_set = 1;
10908 } else if (unformat(input, "lcl_eid %U", unformat_lisp_eid_vat,
10909 lcl_eid)) {
10910 lcl_eid_set = 1;
10911 } else if (unformat(input, "p %d w %d", &p, &w)) {
10912 if (!curr_rloc) {
10913 errmsg ("No RLOC configured for setting priority/weight!");
10914 return -99;
10915 }
10916 curr_rloc->priority = p;
10917 curr_rloc->weight = w;
10918 } else if (unformat(input, "loc-pair %U %U", unformat_ip4_address,
10919 &lcl_rloc4, unformat_ip4_address, &rmt_rloc4)) {
10920 rloc.is_ip4 = 1;
10921 clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
10922 vec_add1 (lcl_locs, rloc);
10923 clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
10924 vec_add1 (rmt_locs, rloc);
10925 curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
10926 } else if (unformat(input, "loc-pair %U", unformat_ip6_address,
10927 &lcl_rloc6, unformat_ip6_address, &rmt_rloc6)) {
10928 rloc.is_ip4 = 0;
10929 clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
10930 vec_add1 (lcl_locs, rloc);
10931 clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
10932 vec_add1 (rmt_locs, rloc);
10933 curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
10934 } else if (unformat(input, "action %d", &action)) {
10935 ;
10936 } else {
10937 clib_warning ("parse error '%U'", format_unformat_error, input);
10938 return -99;
10939 }
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010940 }
10941
Florin Coras429e7952016-08-02 02:31:03 +020010942 if (!rmt_eid_set) {
10943 errmsg ("remote eid addresses not set\n");
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010944 return -99;
10945 }
10946
Florin Coras429e7952016-08-02 02:31:03 +020010947 if (lcl_eid_set && rmt_eid->type != lcl_eid->type) {
10948 errmsg ("eid types don't match\n");
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010949 return -99;
10950 }
10951
10952 /* Construct the API message */
10953 M(LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
10954
10955 mp->is_add = is_add;
Florin Coras429e7952016-08-02 02:31:03 +020010956 lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
10957 lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
10958 mp->eid_type = rmt_eid->type;
10959 mp->rmt_len = rmt_eid->len;
10960 mp->lcl_len = lcl_eid->len;
Florin Corasbb5c22f2016-08-02 02:31:03 +020010961 mp->action = action;
Florin Coras429e7952016-08-02 02:31:03 +020010962
10963 mp->loc_num = vec_len (rmt_locs);
10964 clib_memcpy (mp->lcl_locs, lcl_locs,
10965 (sizeof(rloc_t) * vec_len(lcl_locs)));
10966 clib_memcpy (mp->rmt_locs, rmt_locs,
10967 (sizeof(rloc_t) * vec_len(rmt_locs)));
10968 vec_free(lcl_locs);
10969 vec_free(rmt_locs);
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010970
10971 /* send it... */
10972 S;
10973
10974 /* Wait for a reply... */
10975 W;
10976
10977 /* NOTREACHED */
10978 return 0;
10979}
10980
10981static int
10982api_lisp_add_del_map_resolver(vat_main_t * vam)
10983{
10984 unformat_input_t * input = vam->input;
10985 vl_api_lisp_add_del_map_resolver_t *mp;
10986 f64 timeout = ~0;
10987 u8 is_add = 1;
10988 u8 ipv4_set = 0;
10989 u8 ipv6_set = 0;
10990 ip4_address_t ipv4;
10991 ip6_address_t ipv6;
10992
10993 /* Parse args required to build the message */
10994 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
10995 if (unformat(input, "del")) {
10996 is_add = 0;
10997 } else if (unformat(input, "%U", unformat_ip4_address, &ipv4)) {
10998 ipv4_set = 1;
10999 } else if (unformat(input, "%U", unformat_ip6_address, &ipv6)) {
11000 ipv6_set = 1;
11001 } else
11002 break;
11003 }
11004
11005 if (ipv4_set && ipv6_set) {
11006 errmsg ("both eid v4 and v6 addresses set\n");
11007 return -99;
11008 }
11009
11010 if (!ipv4_set && !ipv6_set) {
11011 errmsg ("eid addresses not set\n");
11012 return -99;
11013 }
11014
11015 /* Construct the API message */
11016 M(LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
11017
11018 mp->is_add = is_add;
11019 if (ipv6_set) {
11020 mp->is_ipv6 = 1;
Damjan Marionf1213b82016-03-13 02:22:06 +010011021 clib_memcpy(mp->ip_address, &ipv6, sizeof(ipv6));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020011022 } else {
11023 mp->is_ipv6 = 0;
Damjan Marionf1213b82016-03-13 02:22:06 +010011024 clib_memcpy(mp->ip_address, &ipv4, sizeof(ipv4));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020011025 }
11026
11027 /* send it... */
11028 S;
11029
11030 /* Wait for a reply... */
11031 W;
11032
11033 /* NOTREACHED */
11034 return 0;
11035}
11036
11037static int
Florin Coras577c3552016-04-21 00:45:40 +020011038api_lisp_gpe_enable_disable (vat_main_t * vam)
11039{
11040 unformat_input_t * input = vam->input;
11041 vl_api_lisp_gpe_enable_disable_t *mp;
11042 f64 timeout = ~0;
11043 u8 is_set = 0;
11044 u8 is_en = 1;
11045
11046 /* Parse args required to build the message */
11047 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
11048 if (unformat(input, "enable")) {
11049 is_set = 1;
11050 is_en = 1;
11051 } else if (unformat(input, "disable")) {
11052 is_set = 1;
11053 is_en = 0;
11054 } else
11055 break;
11056 }
11057
11058 if (is_set == 0) {
11059 errmsg("Value not set\n");
11060 return -99;
11061 }
11062
11063 /* Construct the API message */
11064 M(LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
11065
11066 mp->is_en = is_en;
11067
11068 /* send it... */
11069 S;
11070
11071 /* Wait for a reply... */
11072 W;
11073
11074 /* NOTREACHED */
11075 return 0;
11076}
11077
11078static int
Filip Tehlar46d4e362016-05-09 09:39:26 +020011079api_lisp_enable_disable (vat_main_t * vam)
11080{
11081 unformat_input_t * input = vam->input;
11082 vl_api_lisp_enable_disable_t *mp;
11083 f64 timeout = ~0;
11084 u8 is_set = 0;
11085 u8 is_en = 0;
11086
11087 /* Parse args required to build the message */
11088 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11089 {
11090 if (unformat (input, "enable"))
11091 {
11092 is_set = 1;
11093 is_en = 1;
11094 }
11095 else if (unformat (input, "disable"))
11096 {
11097 is_set = 1;
11098 }
11099 else
11100 break;
11101 }
11102
11103 if (!is_set)
11104 {
11105 errmsg ("Value not set\n");
11106 return -99;
11107 }
11108
11109 /* Construct the API message */
11110 M(LISP_ENABLE_DISABLE, lisp_enable_disable);
11111
11112 mp->is_en = is_en;
11113
11114 /* send it... */
11115 S;
11116
11117 /* Wait for a reply... */
11118 W;
11119
11120 /* NOTREACHED */
11121 return 0;
11122}
11123
Filip Tehlar195bcee2016-05-13 17:37:35 +020011124/**
Filip Tehlar53f09e32016-05-19 14:25:44 +020011125 * Enable/disable LISP proxy ITR.
11126 *
11127 * @param vam vpp API test context
11128 * @return return code
11129 */
11130static int
11131api_lisp_pitr_set_locator_set (vat_main_t * vam)
11132{
11133 f64 timeout = ~0;
11134 u8 ls_name_set = 0;
11135 unformat_input_t * input = vam->input;
11136 vl_api_lisp_pitr_set_locator_set_t * mp;
11137 u8 is_add = 1;
11138 u8 * ls_name = 0;
11139
11140 /* Parse args required to build the message */
11141 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11142 {
11143 if (unformat (input, "del"))
11144 is_add = 0;
11145 else if (unformat (input, "locator-set %s", &ls_name))
11146 ls_name_set = 1;
11147 else
11148 {
11149 errmsg ("parse error '%U'", format_unformat_error, input);
11150 return -99;
11151 }
11152 }
11153
11154 if (!ls_name_set)
11155 {
11156 errmsg ("locator-set name not set!");
11157 return -99;
11158 }
11159
11160 M(LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
11161
11162 mp->is_add = is_add;
11163 clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
11164 vec_free (ls_name);
11165
11166 /* send */
11167 S;
11168
11169 /* wait for reply */
11170 W;
11171
11172 /* notreached*/
11173 return 0;
11174}
11175
Andrej Kozemcak914f91b2016-07-18 13:55:37 +020011176static int
11177api_show_lisp_pitr (vat_main_t * vam)
11178{
11179 vl_api_show_lisp_pitr_t *mp;
11180 f64 timeout = ~0;
11181
11182 if (!vam->json_output) {
11183 fformat(vam->ofp, "%=20s\n",
11184 "lisp status:");
11185 }
11186
11187 M(SHOW_LISP_PITR, show_lisp_pitr);
11188 /* send it... */
11189 S;
11190
11191 /* Wait for a reply... */
11192 W;
11193
11194 /* NOTREACHED */
11195 return 0;
11196}
11197
Filip Tehlar53f09e32016-05-19 14:25:44 +020011198/**
Filip Tehlar324112f2016-06-02 16:07:38 +020011199 * Add/delete mapping between vni and vrf
11200 */
11201static int
11202api_lisp_eid_table_add_del_map (vat_main_t * vam)
11203{
11204 f64 timeout = ~0;
11205 unformat_input_t * input = vam->input;
11206 vl_api_lisp_eid_table_add_del_map_t *mp;
Florin Coras1a1adc72016-07-22 01:45:30 +020011207 u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
11208 u32 vni, vrf, bd_index;
Filip Tehlar324112f2016-06-02 16:07:38 +020011209
11210 /* Parse args required to build the message */
11211 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11212 {
11213 if (unformat (input, "del"))
11214 is_add = 0;
11215 else if (unformat(input, "vrf %d", &vrf))
11216 vrf_set = 1;
Florin Coras1a1adc72016-07-22 01:45:30 +020011217 else if (unformat(input, "bd_index %d", &bd_index))
11218 bd_index_set = 1;
Filip Tehlar324112f2016-06-02 16:07:38 +020011219 else if (unformat(input, "vni %d", &vni))
11220 vni_set = 1;
11221 else
11222 break;
11223 }
11224
Florin Coras1a1adc72016-07-22 01:45:30 +020011225 if (!vni_set || (!vrf_set && !bd_index_set))
Filip Tehlar324112f2016-06-02 16:07:38 +020011226 {
11227 errmsg ("missing arguments!");
11228 return -99;
11229 }
11230
11231 M(LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
11232
11233 mp->is_add = is_add;
11234 mp->vni = htonl (vni);
Florin Coras1a1adc72016-07-22 01:45:30 +020011235 mp->dp_table = htonl (vrf);
11236 mp->is_l2 = bd_index_set;
Filip Tehlar324112f2016-06-02 16:07:38 +020011237
11238 /* send */
11239 S;
11240
11241 /* wait for reply */
11242 W;
11243
11244 /* notreached*/
11245 return 0;
11246}
11247
11248/**
Florin Corasf727db92016-06-23 15:01:58 +020011249 * Add/del remote mapping to/from LISP control plane
Filip Tehlar195bcee2016-05-13 17:37:35 +020011250 *
11251 * @param vam vpp API test context
11252 * @return return code
11253 */
11254static int
11255api_lisp_add_del_remote_mapping (vat_main_t * vam)
11256{
11257 unformat_input_t * input = vam->input;
11258 vl_api_lisp_add_del_remote_mapping_t *mp;
11259 f64 timeout = ~0;
11260 u32 vni = 0;
Andrej Kozemcak438109d2016-07-22 12:54:12 +020011261 //TODO: seid need remove
Florin Coras429e7952016-08-02 02:31:03 +020011262 lisp_eid_vat_t _eid, * eid = &_eid;
11263 lisp_eid_vat_t _seid, * seid = &_seid;
11264 u8 is_add = 1, del_all = 0, eid_set = 0;
Filip Tehlar4d5cabd2016-07-07 15:40:36 +020011265 u32 action = ~0, p, w;
Florin Coras429e7952016-08-02 02:31:03 +020011266 ip4_address_t rloc4;
11267 ip6_address_t rloc6;
Filip Tehlar4d5cabd2016-07-07 15:40:36 +020011268 rloc_t * rlocs = 0, rloc, * curr_rloc = 0;
Filip Tehlar195bcee2016-05-13 17:37:35 +020011269
11270 /* Parse args required to build the message */
11271 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
Filip Tehlar58f886a2016-05-30 15:57:40 +020011272 if (unformat(input, "del-all")) {
11273 del_all = 1;
11274 } else if (unformat(input, "del")) {
Filip Tehlar195bcee2016-05-13 17:37:35 +020011275 is_add = 0;
11276 } else if (unformat(input, "add")) {
11277 is_add = 1;
Florin Coras429e7952016-08-02 02:31:03 +020011278 } else if (unformat(input, "deid %U", unformat_lisp_eid_vat, eid)) {
11279 eid_set = 1;
11280 } else if (unformat(input, "seid %U", unformat_lisp_eid_vat, &seid)) {
Andrej Kozemcak438109d2016-07-22 12:54:12 +020011281 //TODO: Need remove, but first must be remove from CSIT test
Filip Tehlar195bcee2016-05-13 17:37:35 +020011282 } else if (unformat(input, "vni %d", &vni)) {
11283 ;
Filip Tehlar4d5cabd2016-07-07 15:40:36 +020011284 } else if (unformat(input, "p %d w %d", &p, &w)) {
11285 if (!curr_rloc) {
11286 errmsg ("No RLOC configured for setting priority/weight!");
11287 return -99;
11288 }
11289 curr_rloc->priority = p;
11290 curr_rloc->weight = w;
Filip Tehlar195bcee2016-05-13 17:37:35 +020011291 } else if (unformat(input, "rloc %U", unformat_ip4_address, &rloc4)) {
11292 rloc.is_ip4 = 1;
11293 clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
11294 vec_add1 (rlocs, rloc);
Filip Tehlar4d5cabd2016-07-07 15:40:36 +020011295 curr_rloc = &rlocs[vec_len (rlocs) - 1];
Filip Tehlar195bcee2016-05-13 17:37:35 +020011296 } else if (unformat(input, "rloc %U", unformat_ip6_address, &rloc6)) {
11297 rloc.is_ip4 = 0;
11298 clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
11299 vec_add1 (rlocs, rloc);
Filip Tehlar4d5cabd2016-07-07 15:40:36 +020011300 curr_rloc = &rlocs[vec_len (rlocs) - 1];
Filip Tehlar195bcee2016-05-13 17:37:35 +020011301 } else if (unformat(input, "action %d", &action)) {
11302 ;
11303 } else {
11304 clib_warning ("parse error '%U'", format_unformat_error, input);
11305 return -99;
11306 }
11307 }
11308
Florin Coras429e7952016-08-02 02:31:03 +020011309 if (0 == eid_set) {
Filip Tehlar195bcee2016-05-13 17:37:35 +020011310 errmsg ("missing params!");
11311 return -99;
11312 }
11313
Filip Tehlar195bcee2016-05-13 17:37:35 +020011314 if (is_add && (~0 == action)
11315 && 0 == vec_len (rlocs)) {
11316 errmsg ("no action set for negative map-reply!");
11317 return -99;
11318 }
11319
11320 M(LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping);
11321 mp->is_add = is_add;
11322 mp->vni = htonl (vni);
Filip Tehlar195bcee2016-05-13 17:37:35 +020011323 mp->action = (u8) action;
Florin Coras429e7952016-08-02 02:31:03 +020011324 mp->eid_len = eid->len;
Filip Tehlar58f886a2016-05-30 15:57:40 +020011325 mp->del_all = del_all;
Florin Coras429e7952016-08-02 02:31:03 +020011326 mp->eid_type = eid->type;
11327 lisp_eid_put_vat(mp->eid, eid->addr, eid->type);
Filip Tehlar195bcee2016-05-13 17:37:35 +020011328
11329 mp->rloc_num = vec_len (rlocs);
11330 clib_memcpy (mp->rlocs, rlocs, (sizeof (rloc_t) * vec_len (rlocs)));
11331 vec_free (rlocs);
11332
11333 /* send it... */
11334 S;
11335
11336 /* Wait for a reply... */
11337 W;
11338
11339 /* NOTREACHED */
11340 return 0;
11341}
11342
Florin Corasf727db92016-06-23 15:01:58 +020011343/**
11344 * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
11345 * forwarding entries in data-plane accordingly.
11346 *
11347 * @param vam vpp API test context
11348 * @return return code
11349 */
11350static int
11351api_lisp_add_del_adjacency (vat_main_t * vam)
11352{
11353 unformat_input_t * input = vam->input;
11354 vl_api_lisp_add_del_adjacency_t *mp;
11355 f64 timeout = ~0;
11356 u32 vni = 0;
Florin Coras71893ac2016-07-10 20:09:32 +020011357 ip4_address_t seid4, deid4;
11358 ip6_address_t seid6, deid6;
Florin Corasf727db92016-06-23 15:01:58 +020011359 u8 deid_mac[6] = {0};
11360 u8 seid_mac[6] = {0};
11361 u8 deid_type, seid_type;
11362 u32 seid_len = 0, deid_len = 0, len;
11363 u8 is_add = 1;
Florin Corasf727db92016-06-23 15:01:58 +020011364
Florin Corasf727db92016-06-23 15:01:58 +020011365 seid_type = deid_type = (u8)~0;
11366
11367 /* Parse args required to build the message */
11368 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
11369 if (unformat(input, "del")) {
11370 is_add = 0;
11371 } else if (unformat(input, "add")) {
11372 is_add = 1;
11373 } else if (unformat(input, "deid %U/%d", unformat_ip4_address,
11374 &deid4, &len)) {
11375 deid_type = 0; /* ipv4 */
11376 deid_len = len;
11377 } else if (unformat(input, "deid %U/%d", unformat_ip6_address,
11378 &deid6, &len)) {
11379 deid_type = 1; /* ipv6 */
11380 deid_len = len;
11381 } else if (unformat(input, "deid %U", unformat_ethernet_address,
11382 deid_mac)) {
11383 deid_type = 2; /* mac */
11384 } else if (unformat(input, "seid %U/%d", unformat_ip4_address,
11385 &seid4, &len)) {
11386 seid_type = 0; /* ipv4 */
11387 seid_len = len;
11388 } else if (unformat(input, "seid %U/%d", unformat_ip6_address,
11389 &seid6, &len)) {
11390 seid_type = 1; /* ipv6 */
11391 seid_len = len;
11392 } else if (unformat(input, "seid %U", unformat_ethernet_address,
11393 seid_mac)) {
11394 seid_type = 2; /* mac */
11395 } else if (unformat(input, "vni %d", &vni)) {
11396 ;
Florin Corasf727db92016-06-23 15:01:58 +020011397 } else {
Filip Tehlar4d5cabd2016-07-07 15:40:36 +020011398 errmsg ("parse error '%U'", format_unformat_error, input);
Florin Corasf727db92016-06-23 15:01:58 +020011399 return -99;
11400 }
11401 }
11402
11403 if ((u8)~0 == deid_type) {
11404 errmsg ("missing params!");
11405 return -99;
11406 }
11407
11408 if (seid_type != deid_type) {
11409 errmsg ("source and destination EIDs are of different types!");
11410 return -99;
11411 }
11412
Florin Corasf727db92016-06-23 15:01:58 +020011413 M(LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
11414 mp->is_add = is_add;
11415 mp->vni = htonl (vni);
11416 mp->seid_len = seid_len;
Florin Corasf727db92016-06-23 15:01:58 +020011417 mp->deid_len = deid_len;
11418 mp->eid_type = deid_type;
11419
11420 switch (mp->eid_type) {
11421 case 0:
11422 clib_memcpy (mp->seid, &seid4, sizeof (seid4));
11423 clib_memcpy (mp->deid, &deid4, sizeof (deid4));
11424 break;
11425 case 1:
11426 clib_memcpy (mp->seid, &seid6, sizeof (seid6));
11427 clib_memcpy (mp->deid, &deid6, sizeof (deid6));
11428 break;
11429 case 2:
11430 clib_memcpy (mp->seid, seid_mac, 6);
11431 clib_memcpy (mp->deid, deid_mac, 6);
11432 break;
11433 default:
11434 errmsg ("unknown EID type %d!", mp->eid_type);
11435 return 0;
11436 }
11437
Florin Corasf727db92016-06-23 15:01:58 +020011438 /* send it... */
11439 S;
11440
11441 /* Wait for a reply... */
11442 W;
11443
11444 /* NOTREACHED */
11445 return 0;
11446}
11447
Filip Tehlar46d4e362016-05-09 09:39:26 +020011448static int
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020011449api_lisp_gpe_add_del_iface(vat_main_t * vam)
11450{
11451 unformat_input_t * input = vam->input;
11452 vl_api_lisp_gpe_add_del_iface_t *mp;
11453 f64 timeout = ~0;
Florin Coras429e7952016-08-02 02:31:03 +020011454 u8 is_set = 0, is_add = 1, is_l2 = 0;
11455 u32 dp_table, vni;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020011456
11457 /* Parse args required to build the message */
11458 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
11459 if (unformat(input, "up")) {
11460 is_set = 1;
11461 is_add = 1;
11462 } else if (unformat(input, "down")) {
11463 is_set = 1;
11464 is_add = 0;
Florin Coras429e7952016-08-02 02:31:03 +020011465 } else if (unformat(input, "table_id %d", &dp_table)) {
Florin Coras577c3552016-04-21 00:45:40 +020011466 ;
Florin Coras429e7952016-08-02 02:31:03 +020011467 } else if (unformat(input, "bd_id %d", &dp_table)) {
11468 is_l2 = 1;
Florin Coras577c3552016-04-21 00:45:40 +020011469 } else if (unformat(input, "vni %d", &vni)) {
11470 ;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020011471 } else
11472 break;
11473 }
11474
11475 if (is_set == 0) {
11476 errmsg("Value not set\n");
11477 return -99;
11478 }
11479
11480 /* Construct the API message */
11481 M(LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
11482
11483 mp->is_add = is_add;
Florin Coras429e7952016-08-02 02:31:03 +020011484 mp->dp_table = dp_table;
11485 mp->is_l2 = is_l2;
Florin Coras577c3552016-04-21 00:45:40 +020011486 mp->vni = vni;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020011487
11488 /* send it... */
11489 S;
11490
11491 /* Wait for a reply... */
11492 W;
11493
11494 /* NOTREACHED */
11495 return 0;
11496}
11497
Andrej Kozemcakb6e4d392016-06-14 13:55:57 +020011498/**
11499 * Add/del map request itr rlocs from LISP control plane and updates
11500 *
11501 * @param vam vpp API test context
11502 * @return return code
11503 */
11504static int
11505api_lisp_add_del_map_request_itr_rlocs(vat_main_t * vam)
11506{
11507 unformat_input_t * input = vam->input;
11508 vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
11509 f64 timeout = ~0;
11510 u8 *locator_set_name = 0;
11511 u8 locator_set_name_set = 0;
11512 u8 is_add = 1;
11513
11514 /* Parse args required to build the message */
11515 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
11516 if (unformat(input, "del")) {
11517 is_add = 0;
11518 } else if (unformat(input, "%_%v%_", &locator_set_name)) {
11519 locator_set_name_set = 1;
11520 } else {
11521 clib_warning ("parse error '%U'", format_unformat_error, input);
11522 return -99;
11523 }
11524 }
11525
11526 if (is_add && !locator_set_name_set) {
11527 errmsg ("itr-rloc is not set!");
11528 return -99;
11529 }
11530
11531 if (is_add && vec_len(locator_set_name) > 64) {
11532 errmsg ("itr-rloc locator-set name too long\n");
11533 vec_free(locator_set_name);
11534 return -99;
11535 }
11536
11537 M(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
11538 mp->is_add = is_add;
11539 if (is_add) {
11540 clib_memcpy (mp->locator_set_name , locator_set_name,
11541 vec_len(locator_set_name));
11542 } else {
11543 memset(mp->locator_set_name, 0, sizeof(mp->locator_set_name));
11544 }
11545 vec_free (locator_set_name);
11546
11547 /* send it... */
11548 S;
11549
11550 /* Wait for a reply... */
11551 W;
11552
11553 /* NOTREACHED */
11554 return 0;
11555}
11556
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020011557static int
Andrej Kozemcakd9831182016-06-20 08:47:57 +020011558lisp_locator_dump_send_msg(vat_main_t * vam, u32 locator_set_index, u8 filter)
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020011559{
Andrej Kozemcakd9831182016-06-20 08:47:57 +020011560 vl_api_lisp_locator_dump_t *mp;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020011561 f64 timeout = ~0;
11562
Andrej Kozemcakd9831182016-06-20 08:47:57 +020011563 M(LISP_LOCATOR_DUMP, lisp_locator_dump);
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020011564
Andrej Kozemcakd9831182016-06-20 08:47:57 +020011565 mp->locator_set_index = htonl(locator_set_index);
11566 mp->filter = filter;
11567
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020011568 /* send it... */
11569 S;
11570
11571 /* Use a control ping for synchronization */
11572 {
Andrej Kozemcakd9831182016-06-20 08:47:57 +020011573 vl_api_noprint_control_ping_t * mp;
11574 M(NOPRINT_CONTROL_PING, noprint_control_ping);
11575 S;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020011576 }
11577 /* Wait for a reply... */
11578 W;
Andrej Kozemcakd9831182016-06-20 08:47:57 +020011579}
11580
Andrej Kozemcak6cc6f912016-07-13 13:01:01 +020011581static inline void
11582clean_locator_set_message(vat_main_t * vam)
11583{
11584 locator_set_msg_t * ls = 0;
11585
11586 vec_foreach (ls, vam->locator_set_msg) {
11587 vec_free(ls->locator_set_name);
11588 }
11589
11590 vec_free(vam->locator_set_msg);
11591}
11592
Andrej Kozemcakd9831182016-06-20 08:47:57 +020011593static int
11594print_locator_in_locator_set(vat_main_t * vam, u8 filter)
11595{
11596 locator_set_msg_t * ls;
11597 locator_msg_t * loc;
11598 u8 * tmp_str = 0;
11599 int i = 0, ret = 0;
11600
11601 vec_foreach(ls, vam->locator_set_msg) {
11602 ret = lisp_locator_dump_send_msg(vam, ls->locator_set_index, filter);
11603 if (ret) {
Andrej Kozemcakd9831182016-06-20 08:47:57 +020011604 vec_free(vam->locator_msg);
Andrej Kozemcak6cc6f912016-07-13 13:01:01 +020011605 clean_locator_set_message(vam);
Andrej Kozemcakd9831182016-06-20 08:47:57 +020011606 return ret;
11607 }
11608
11609 tmp_str = format(0, "%=20s%=16d%s", ls->locator_set_name,
11610 ls->locator_set_index,
11611 vec_len(vam->locator_msg) ? "" : "\n");
11612 i = 0;
11613 vec_foreach(loc, vam->locator_msg) {
11614 if (i) {
11615 tmp_str = format(tmp_str, "%=37s", " ");
11616 }
11617 if (loc->local) {
11618 tmp_str = format(tmp_str, "%=16d%=16d%=16d\n",
11619 loc->sw_if_index,
11620 loc->priority,
11621 loc->weight);
11622 } else {
11623 tmp_str = format(tmp_str, "%=16U%=16d%=16d\n",
11624 loc->is_ipv6 ? format_ip6_address :
11625 format_ip4_address,
11626 loc->ip_address,
11627 loc->priority,
11628 loc->weight);
11629 }
11630 i++;
11631 }
11632
11633 fformat(vam->ofp, "%s", tmp_str);
11634 vec_free(tmp_str);
Andrej Kozemcakd9831182016-06-20 08:47:57 +020011635 vec_free(vam->locator_msg);
11636 }
11637
Andrej Kozemcak6cc6f912016-07-13 13:01:01 +020011638 clean_locator_set_message(vam);
Andrej Kozemcakd9831182016-06-20 08:47:57 +020011639
11640 return ret;
11641}
11642
11643static int
11644json_locator_in_locator_set(vat_main_t * vam, u8 filter)
11645{
11646 locator_set_msg_t * ls;
11647 locator_msg_t * loc;
11648 vat_json_node_t * node = NULL;
11649 vat_json_node_t * locator_array;
11650 vat_json_node_t * locator;
11651 struct in6_addr ip6;
11652 struct in_addr ip4;
11653 int ret = 0;
11654
11655 if (!vec_len(vam->locator_set_msg)) {
11656 /* just print [] */
11657 vat_json_init_array(&vam->json_tree);
11658 vat_json_print(vam->ofp, &vam->json_tree);
11659 vam->json_tree.type = VAT_JSON_NONE;
11660 return ret;
11661 }
11662
11663 if (VAT_JSON_ARRAY != vam->json_tree.type) {
11664 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
11665 vat_json_init_array(&vam->json_tree);
11666 }
11667
11668 vec_foreach(ls, vam->locator_set_msg) {
11669 ret = lisp_locator_dump_send_msg(vam, ls->locator_set_index, filter);
11670 if (ret) {
11671 vec_free(ls->locator_set_name);
11672 vec_free(vam->locator_msg);
11673 vec_free(vam->locator_set_msg);
11674 vat_json_free(&vam->json_tree);
11675 vam->json_tree.type = VAT_JSON_NONE;
11676 return ret;
11677 }
11678
11679 node = vat_json_array_add(&vam->json_tree);
11680 vat_json_init_object(node);
11681
11682 vat_json_object_add_uint(node, "locator-set-index",
11683 ls->locator_set_index);
11684 vat_json_object_add_string_copy(node, "locator-set",
11685 ls->locator_set_name);
11686 locator_array = vat_json_object_add_list(node, "locator");
11687 vec_foreach(loc, vam->locator_msg) {
11688 locator = vat_json_array_add(locator_array);
11689 vat_json_init_object(locator);
11690 if (loc->local) {
11691 vat_json_object_add_uint(locator, "locator-index",
11692 loc->sw_if_index);
11693 } else {
11694 if (loc->is_ipv6) {
11695 clib_memcpy(&ip6, loc->ip_address, sizeof(ip6));
11696 vat_json_object_add_ip6(locator, "locator", ip6);
11697 } else {
11698 clib_memcpy(&ip4, loc->ip_address, sizeof(ip4));
11699 vat_json_object_add_ip4(locator, "locator", ip4);
11700 }
11701 }
11702 vat_json_object_add_uint(locator, "priority", loc->priority);
11703 vat_json_object_add_uint(locator, "weight", loc->weight);
11704 }
11705
11706 vec_free(ls->locator_set_name);
11707 vec_free(vam->locator_msg);
11708 }
11709
11710 vat_json_print(vam->ofp, &vam->json_tree);
11711 vat_json_free(&vam->json_tree);
11712 vam->json_tree.type = VAT_JSON_NONE;
11713
11714 vec_free(vam->locator_set_msg);
11715
11716 return ret;
11717}
11718
11719static int
11720get_locator_set_index_from_msg(vat_main_t * vam, u8 * locator_set,
11721 u32 * locator_set_index)
11722{
11723 locator_set_msg_t * ls;
11724 int ret = 0;
11725
11726 * locator_set_index = ~0;
11727
11728 if (!vec_len(vam->locator_set_msg)) {
11729 return ret;
11730 }
11731
11732 vec_foreach(ls, vam->locator_set_msg) {
11733 if (!strcmp((char *) locator_set, (char *) ls->locator_set_name)) {
11734 * locator_set_index = ls->locator_set_index;
11735 vec_free(vam->locator_set_msg);
11736 return ret;
11737 }
11738 }
11739
11740 vec_free(vam->locator_set_msg);
11741
11742 return ret;
11743}
11744
11745static int
11746get_locator_set_index(vat_main_t * vam, u8 * locator_set,
11747 u32 * locator_set_index)
11748{
11749 vl_api_lisp_locator_set_dump_t *mp;
11750 f64 timeout = ~0;
11751
11752 M(LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
11753 /* send it... */
11754 S;
11755
11756 /* Use a control ping for synchronization */
11757 {
11758 vl_api_noprint_control_ping_t * mp;
11759 M(NOPRINT_CONTROL_PING, noprint_control_ping);
11760 S;
11761 }
11762
11763 vam->noprint_msg = 1;
11764 /* Wait for a reply... */
11765 W_L({
11766 get_locator_set_index_from_msg(vam, locator_set, locator_set_index);
11767 vam->noprint_msg = 0;
11768 })
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020011769
11770 /* NOTREACHED */
11771 return 0;
11772}
11773
Andrej Kozemcakd9831182016-06-20 08:47:57 +020011774static inline int
11775lisp_locator_dump(vat_main_t * vam, u32 locator_set_index, u8 * locator_set,
11776 u8 filter)
11777{
11778 int ret = 0;
11779
11780 ASSERT(vam);
11781
11782 if (!vam->json_output) {
11783 fformat(vam->ofp, "%=20s%=16s%=16s\n",
11784 "locator", "priority", "weight");
11785 }
11786
11787 if (locator_set) {
11788 ret = get_locator_set_index(vam, locator_set, &locator_set_index);
11789 }
11790
11791 if (!ret && ~0 == locator_set_index) {
11792 return -99;
11793 }
11794
11795 ret = lisp_locator_dump_send_msg(vam, locator_set_index, filter);
11796
11797 return ret;
11798}
11799
11800static int
11801lisp_locator_set_dump(vat_main_t * vam, u8 filter)
11802{
11803 vl_api_lisp_locator_set_dump_t *mp;
11804 f64 timeout = ~0;
11805
11806 if (!vam->json_output) {
11807 fformat(vam->ofp, "%=20s%=16s%=16s%=16s%=16s\n",
11808 "locator-set", "locator-set-index", "locator", "priority",
11809 "weight");
11810 }
11811
11812 vam->noprint_msg = 1;
11813
11814 M(LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
11815
11816 mp->filter = filter;
11817
11818 /* send it... */
11819 S;
11820
11821 /* Use a control ping for synchronization */
11822 {
11823 vl_api_noprint_control_ping_t * mp;
11824 M(NOPRINT_CONTROL_PING, noprint_control_ping);
11825 S;
11826 }
11827
11828 /* Wait for a reply... */
11829 W_L({
11830 if (vam->noprint_msg) {
11831 if (!vam->json_output) {
11832 print_locator_in_locator_set(vam, filter);
11833 } else {
11834 json_locator_in_locator_set(vam, filter);
11835 }
11836 }
11837
11838 vam->noprint_msg = 0;
11839 });
11840
11841 /* NOTREACHED */
11842 return 0;
11843}
11844
11845static int
11846api_lisp_locator_set_dump(vat_main_t *vam)
11847{
11848 unformat_input_t * input = vam->input;
11849 vam->noprint_msg = 0;
11850 u32 locator_set_index = ~0;
11851 u8 locator_set_index_set = 0;
11852 u8 * locator_set = 0;
11853 u8 locator_set_set = 0;
11854 u8 filter = 0;
11855 int ret = 0;
11856
11857 /* Parse args required to build the message */
11858 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
11859 if (unformat(input, "locator-set-index %u", &locator_set_index)) {
11860 locator_set_index_set = 1;
11861 } else if (unformat(input, "locator-set %s", &locator_set)) {
11862 locator_set_set = 1;
11863 } else if (unformat(input, "local")) {
11864 filter = 1;
11865 } else if (unformat(input, "remote")) {
11866 filter = 2;
11867 } else {
11868 break;
11869 }
11870 }
11871
11872 if (locator_set_index_set && locator_set_set) {
11873 errmsg ("use only input parameter!\n");
11874 return -99;
11875 }
11876
11877 if (locator_set_index_set || locator_set_set) {
11878 ret = lisp_locator_dump(vam, locator_set_index, locator_set, filter);
11879 } else {
11880 ret = lisp_locator_set_dump(vam, filter);
11881 }
11882
11883 vec_free(locator_set);
11884
11885 return ret;
11886}
11887
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020011888static int
Filip Tehlar2f653d02016-07-13 13:17:15 +020011889api_lisp_eid_table_map_dump(vat_main_t *vam)
11890{
11891 vl_api_lisp_eid_table_map_dump_t *mp;
11892 f64 timeout = ~0;
11893
11894 if (!vam->json_output) {
11895 fformat (vam->ofp, "%=10s%=10s\n", "VNI", "VRF");
11896 }
11897
11898 M(LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
11899
11900 /* send it... */
11901 S;
11902
11903 /* Use a control ping for synchronization */
11904 {
11905 vl_api_control_ping_t * mp;
11906 M(CONTROL_PING, control_ping);
11907 S;
11908 }
11909 /* Wait for a reply... */
11910 W;
11911
11912 /* NOTREACHED */
11913 return 0;
11914}
11915
11916static int
Andrej Kozemcak6cc6f912016-07-13 13:01:01 +020011917get_locator_set(vat_main_t * vam)
11918{
11919 vl_api_lisp_locator_set_dump_t *mp;
11920 f64 timeout = ~0;
11921
11922 M(LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
11923 /* send it... */
11924 S;
11925
11926 /* Use a control ping for synchronization */
11927 {
11928 vl_api_noprint_control_ping_t * mp;
11929 M(NOPRINT_CONTROL_PING, noprint_control_ping);
11930 S;
11931 }
11932
11933 /* Wait for a reply... */
11934 W;
11935
11936 /* NOTREACHED */
11937 return 0;
11938}
11939
11940static inline u8 *
11941format_eid_for_eid_table(vat_main_t *vam, u8 * str, eid_table_t * eid_table,
11942 int *ret)
11943{
11944 u8 * (*format_eid)(u8 *, va_list *) = 0;
11945
11946 ASSERT(vam != NULL);
11947 ASSERT(eid_table != NULL);
11948
11949 if (ret) {
11950 *ret = 0;
11951 }
11952
11953 switch (eid_table->eid_type)
11954 {
11955 case 0:
11956 case 1:
11957 format_eid = (eid_table->eid_type ? format_ip6_address :
11958 format_ip4_address);
11959 str = format(0, "[%d] %U/%d",
11960 clib_net_to_host_u32 (eid_table->vni),
11961 format_eid, eid_table->eid, eid_table->eid_prefix_len);
11962 break;
11963 case 2:
11964 str = format(0, "[%d] %U",
11965 clib_net_to_host_u32 (eid_table->vni),
11966 format_ethernet_address, eid_table->eid);
11967 break;
11968 default:
11969 errmsg ("unknown EID type %d!", eid_table->eid_type);
11970 if (ret) {
11971 *ret = -99;
11972 }
11973 return 0;
11974 }
11975
11976 return str;
11977}
11978
11979static inline u8 *
11980format_locator_set_for_eid_table(vat_main_t * vam, u8 * str,
11981 eid_table_t * eid_table)
11982{
11983 locator_set_msg_t * ls = 0;
11984
11985 ASSERT(vam != NULL);
11986 ASSERT(eid_table != NULL);
11987
11988 if (eid_table->is_local) {
11989 vec_foreach (ls, vam->locator_set_msg) {
11990 if (ls->locator_set_index == eid_table->locator_set_index) {
11991 str = format(0, "local(%s)", ls->locator_set_name);
11992 return str;
11993 }
11994 }
11995
11996 str = format(0, "local(N/A)");
11997 } else {
11998 str = format(0, "remote");
11999 }
12000
12001 return str;
12002}
12003
12004static inline u8 *
12005format_locator_for_eid_table(vat_main_t * vam, u8 * str,
12006 eid_table_t * eid_table)
12007{
12008 locator_msg_t * loc = 0;
12009 int first_line = 1;
12010
12011 ASSERT(vam != NULL);
12012 ASSERT(eid_table != NULL);
12013
12014 vec_foreach(loc, vam->locator_msg) {
12015 if (!first_line) {
12016 if (loc->local) {
12017 str = format(str, "%-55s%-d\n", " ", loc->sw_if_index);
12018 } else {
12019 str = format(str, "%=55s%-U\n", " ",
12020 loc->is_ipv6 ? format_ip6_address :
12021 format_ip4_address,
12022 loc->ip_address);
12023 }
12024
12025 continue;
12026 }
12027
12028 if (loc->local) {
12029 str = format(str, "%-30d%-20u%-u\n", loc->sw_if_index,
12030 eid_table->ttl, eid_table->authoritative);
12031 } else {
12032 str = format(str, "%-30U%-20u%-u\n",
12033 loc->is_ipv6 ? format_ip6_address :
12034 format_ip4_address,
12035 loc->ip_address, eid_table->ttl,
12036 eid_table->authoritative);
12037 }
12038 first_line = 0;
12039 }
12040
12041 return str;
12042}
12043
12044static int
12045print_lisp_eid_table_dump(vat_main_t * vam)
12046{
12047 eid_table_t * eid_table = 0;
12048 u8 * tmp_str = 0, * tmp_str2 = 0;
12049 int ret = 0;
12050
12051 ASSERT(vam != NULL);
12052
12053 ret = get_locator_set(vam);
12054 if (ret) {
12055 vec_free(vam->eid_tables);
12056 return ret;
12057 }
12058
12059 fformat(vam->ofp, "%-35s%-20s%-30s%-20s%-s\n", "EID", "type", "locators",
12060 "ttl", "authoritative");
12061
12062 vec_foreach(eid_table, vam->eid_tables) {
12063 ret = lisp_locator_dump_send_msg(vam, eid_table->locator_set_index, 0);
12064 if (ret) {
12065 vec_free(vam->locator_msg);
12066 clean_locator_set_message(vam);
12067 vec_free(vam->eid_tables);
12068 return ret;
12069 }
12070
12071 tmp_str2 = format_eid_for_eid_table(vam, tmp_str2, eid_table, &ret);
12072 if (ret) {
12073 vec_free(vam->locator_msg);
12074 clean_locator_set_message(vam);
12075 vec_free(vam->eid_tables);
12076 return ret;
12077 }
12078
12079 tmp_str = format(0, "%-35s", tmp_str2);
12080 vec_free(tmp_str2);
12081
12082 tmp_str2 = format_locator_set_for_eid_table(vam, tmp_str2, eid_table);
12083 tmp_str = format(tmp_str, "%-20s", tmp_str2);
12084 vec_free(tmp_str2);
12085
12086 tmp_str2 = format_locator_for_eid_table(vam, tmp_str2, eid_table);
12087 tmp_str = format(tmp_str, "%-s", tmp_str2);
12088 vec_free(tmp_str2);
12089
12090 fformat(vam->ofp, "%s", tmp_str);
12091 vec_free(tmp_str);
12092 vec_free(vam->locator_msg);
12093 }
12094
12095 clean_locator_set_message(vam);
12096 vec_free(vam->eid_tables);
12097
12098 return ret;
12099}
12100
12101static inline void
12102json_locator_set_for_eid_table(vat_main_t * vam, vat_json_node_t * node,
12103 eid_table_t * eid_table)
12104{
12105 locator_set_msg_t * ls = 0;
12106 u8 * s = 0;
12107
12108 ASSERT(vam != NULL);
12109 ASSERT(node != NULL);
12110 ASSERT(eid_table != NULL);
12111
12112 if (eid_table->is_local) {
12113 vec_foreach (ls, vam->locator_set_msg) {
12114 if (ls->locator_set_index == eid_table->locator_set_index) {
12115 vat_json_object_add_string_copy(node, "locator-set",
12116 ls->locator_set_name);
12117 return;
12118 }
12119 }
12120
12121 s = format(0, "N/A");
12122 vec_add1(s, 0);
12123 vat_json_object_add_string_copy(node, "locator-set", s);
12124 vec_free(s);
12125 } else {
12126 s = format(0, "remote");
12127 vec_add1(s, 0);
12128 vat_json_object_add_string_copy(node, "locator-set", s);
12129 vec_free(s);
12130 }
12131}
12132
12133static inline int
12134json_eid_for_eid_table(vat_main_t * vam, vat_json_node_t * node,
12135 eid_table_t * eid_table)
12136{
12137 u8 * s = 0;
12138 struct in6_addr ip6;
12139 struct in_addr ip4;
12140
12141 ASSERT(vam != NULL);
12142 ASSERT(node != NULL);
12143 ASSERT(eid_table != NULL);
12144
12145 switch (eid_table->eid_type)
12146 {
12147 case 0:
12148 clib_memcpy(&ip4, eid_table->eid, sizeof(ip4));
12149 vat_json_object_add_ip4(node, "eid", ip4);
12150 vat_json_object_add_uint(node, "eid-prefix-len",
12151 eid_table->eid_prefix_len);
12152 break;
12153 case 1:
12154 clib_memcpy(&ip6, eid_table->eid, sizeof(ip6));
12155 vat_json_object_add_ip6(node, "eid", ip6);
12156 vat_json_object_add_uint(node, "eid-prefix-len",
12157 eid_table->eid_prefix_len);
12158 break;
12159 case 2:
12160 s = format (0, "%U", format_ethernet_address, eid_table->eid);
12161 vec_add1(s, 0);
12162 vat_json_object_add_string_copy(node, "eid", s);
12163 vec_free(s);
12164 break;
12165 default:
12166 errmsg ("unknown EID type %d!", eid_table->eid_type);
12167 return -99;
12168 }
12169
12170 return 0;
12171}
12172
12173static inline void
12174json_locator_for_eid_table(vat_main_t * vam, vat_json_node_t * node,
12175 eid_table_t * eid_table)
12176{
12177 locator_msg_t * loc = 0;
12178 vat_json_node_t * locator_array = 0;
12179 vat_json_node_t * locator = 0;
12180 struct in6_addr ip6;
12181 struct in_addr ip4;
12182
12183 ASSERT(vam != NULL);
12184 ASSERT(node != NULL);
12185 ASSERT(eid_table != NULL);
12186
12187 locator_array = vat_json_object_add_list(node, "locator");
12188 vec_foreach(loc, vam->locator_msg) {
12189 locator = vat_json_array_add(locator_array);
12190 vat_json_init_object(locator);
12191 if (loc->local) {
12192 vat_json_object_add_uint(locator, "locator-index",
12193 loc->sw_if_index);
12194 } else {
12195 if (loc->is_ipv6) {
12196 clib_memcpy(&ip6, loc->ip_address, sizeof(ip6));
12197 vat_json_object_add_ip6(locator, "locator", ip6);
12198 } else {
12199 clib_memcpy(&ip4, loc->ip_address, sizeof(ip4));
12200 vat_json_object_add_ip4(locator, "locator", ip4);
12201 }
12202 }
12203 }
12204}
12205
12206static int
12207json_lisp_eid_table_dump(vat_main_t * vam)
12208{
12209 eid_table_t * eid_table;
12210 vat_json_node_t * node = 0;
12211 int ret = 0;
12212
12213 ASSERT(vam != NULL);
12214
12215 ret = get_locator_set(vam);
12216 if (ret) {
12217 vec_free(vam->eid_tables);
12218 return ret;
12219 }
12220
12221 if (!vec_len(vam->eid_tables)) {
12222 /* just print [] */
12223 vat_json_init_array(&vam->json_tree);
12224 vat_json_print(vam->ofp, &vam->json_tree);
12225 vam->json_tree.type = VAT_JSON_NONE;
12226 return ret;
12227 }
12228
12229 if (VAT_JSON_ARRAY != vam->json_tree.type) {
12230 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
12231 vat_json_init_array(&vam->json_tree);
12232 }
12233
12234 vec_foreach(eid_table, vam->eid_tables) {
12235 ret = lisp_locator_dump_send_msg(vam, eid_table->locator_set_index, 0);
12236 if (ret) {
12237 vec_free(vam->locator_msg);
12238 vec_free(vam->eid_tables);
12239 clean_locator_set_message(vam);
12240 vat_json_free(&vam->json_tree);
12241 vam->json_tree.type = VAT_JSON_NONE;
12242 return ret;
12243 }
12244
12245 node = vat_json_array_add(&vam->json_tree);
12246 vat_json_init_object(node);
12247
12248 vat_json_object_add_uint(node, "vni", eid_table->vni);
12249
12250 json_locator_set_for_eid_table(vam, node, eid_table);
12251 ret = json_eid_for_eid_table(vam, node, eid_table);
12252 if (ret) {
12253 vec_free(vam->locator_msg);
12254 vec_free(vam->eid_tables);
12255 clean_locator_set_message(vam);
12256 vat_json_free(&vam->json_tree);
12257 vam->json_tree.type = VAT_JSON_NONE;
12258 return ret;
12259 }
12260
12261 json_locator_for_eid_table(vam, node, eid_table);
12262
12263 vat_json_object_add_uint(node, "ttl", eid_table->ttl);
12264 vat_json_object_add_uint(node, "authoritative",
12265 eid_table->authoritative);
12266
12267 vec_free(vam->locator_msg);
12268 }
12269
12270 vat_json_print(vam->ofp, &vam->json_tree);
12271 vat_json_free(&vam->json_tree);
12272 vam->json_tree.type = VAT_JSON_NONE;
12273
12274 clean_locator_set_message(vam);
12275 vec_free(vam->eid_tables);
12276
12277 return ret;
12278}
12279
12280static int
12281api_lisp_eid_table_dump(vat_main_t *vam)
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020012282{
Filip Tehlar1b1ee4f2016-07-04 11:43:11 +020012283 unformat_input_t * i = vam->input;
Andrej Kozemcak6cc6f912016-07-13 13:01:01 +020012284 vl_api_lisp_eid_table_dump_t *mp;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020012285 f64 timeout = ~0;
Filip Tehlar1b1ee4f2016-07-04 11:43:11 +020012286 struct in_addr ip4;
12287 struct in6_addr ip6;
12288 u8 mac[6];
Andrej Kozemcakd9831182016-06-20 08:47:57 +020012289 u8 eid_type = ~0, eid_set = 0;
Filip Tehlar1b1ee4f2016-07-04 11:43:11 +020012290 u32 prefix_length = ~0, t, vni = 0;
Andrej Kozemcak6cc6f912016-07-13 13:01:01 +020012291 u8 filter = 0;
Filip Tehlar1b1ee4f2016-07-04 11:43:11 +020012292
12293 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
12294 if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t)) {
12295 eid_set = 1;
12296 eid_type = 0;
12297 prefix_length = t;
12298 } else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t)) {
12299 eid_set = 1;
12300 eid_type = 1;
12301 prefix_length = t;
12302 } else if (unformat (i, "eid %U", unformat_ethernet_address, mac)) {
12303 eid_set = 1;
12304 eid_type = 2;
Andrej Kozemcak6cc6f912016-07-13 13:01:01 +020012305 } else if (unformat (i, "vni %d", &t)) {
Filip Tehlar1b1ee4f2016-07-04 11:43:11 +020012306 vni = t;
Andrej Kozemcak6cc6f912016-07-13 13:01:01 +020012307 } else if (unformat (i, "local")) {
12308 filter = 1;
12309 } else if (unformat (i, "remote")) {
12310 filter = 2;
12311 } else {
Filip Tehlar1b1ee4f2016-07-04 11:43:11 +020012312 errmsg ("parse error '%U'", format_unformat_error, i);
12313 return -99;
12314 }
12315 }
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020012316
Andrej Kozemcak6cc6f912016-07-13 13:01:01 +020012317 M(LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020012318
Andrej Kozemcak6cc6f912016-07-13 13:01:01 +020012319 mp->filter = filter;
Filip Tehlar1b1ee4f2016-07-04 11:43:11 +020012320 if (eid_set) {
12321 mp->eid_set = 1;
12322 mp->vni = htonl (vni);
12323 mp->eid_type = eid_type;
12324 switch (eid_type) {
12325 case 0:
12326 mp->prefix_length = prefix_length;
12327 clib_memcpy (mp->eid, &ip4, sizeof (ip4));
12328 break;
12329 case 1:
12330 mp->prefix_length = prefix_length;
12331 clib_memcpy (mp->eid, &ip6, sizeof (ip6));
12332 break;
12333 case 2:
12334 clib_memcpy (mp->eid, mac, sizeof (mac));
12335 break;
12336 default:
12337 errmsg ("unknown EID type %d!", eid_type);
12338 return -99;
12339 }
12340 }
12341
Andrej Kozemcak6cc6f912016-07-13 13:01:01 +020012342 vam->noprint_msg = 1;
12343
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020012344 /* send it... */
12345 S;
12346
12347 /* Use a control ping for synchronization */
12348 {
Andrej Kozemcak6cc6f912016-07-13 13:01:01 +020012349 vl_api_noprint_control_ping_t * mp;
12350 M(NOPRINT_CONTROL_PING, noprint_control_ping);
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020012351 S;
12352 }
Andrej Kozemcak6cc6f912016-07-13 13:01:01 +020012353
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020012354 /* Wait for a reply... */
Andrej Kozemcak6cc6f912016-07-13 13:01:01 +020012355 W_L({
12356 if (vam->noprint_msg) {
12357 if (!vam->json_output) {
12358 vam->retval = print_lisp_eid_table_dump(vam);
12359 } else {
12360 vam->retval = json_lisp_eid_table_dump(vam);
12361 }
12362 }
12363
12364 vam->noprint_msg = 0;
12365 });
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020012366
12367 /* NOTREACHED */
12368 return 0;
12369}
12370
12371static int
12372api_lisp_gpe_tunnel_dump(vat_main_t *vam)
12373{
12374 vl_api_lisp_gpe_tunnel_dump_t *mp;
12375 f64 timeout = ~0;
12376
12377 if (!vam->json_output) {
12378 fformat(vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
12379 "%=16s%=16s%=16s%=16s%=16s\n",
12380 "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
12381 "Decap next", "Lisp version", "Flags", "Next protocol",
12382 "ver_res", "res", "iid");
12383 }
12384
12385 M(LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
12386 /* send it... */
12387 S;
12388
12389 /* Use a control ping for synchronization */
12390 {
12391 vl_api_control_ping_t * mp;
12392 M(CONTROL_PING, control_ping);
12393 S;
12394 }
12395 /* Wait for a reply... */
12396 W;
12397
12398 /* NOTREACHED */
12399 return 0;
12400}
12401
12402static int
12403api_lisp_map_resolver_dump(vat_main_t *vam)
12404{
12405 vl_api_lisp_map_resolver_dump_t *mp;
12406 f64 timeout = ~0;
12407
12408 if (!vam->json_output) {
12409 fformat(vam->ofp, "%=20s\n",
12410 "Map resolver");
12411 }
12412
12413 M(LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
12414 /* send it... */
12415 S;
12416
12417 /* Use a control ping for synchronization */
12418 {
12419 vl_api_control_ping_t * mp;
12420 M(CONTROL_PING, control_ping);
12421 S;
12422 }
12423 /* Wait for a reply... */
12424 W;
12425
12426 /* NOTREACHED */
12427 return 0;
12428}
12429
Andrej Kozemcaka9edd852016-05-02 12:14:33 +020012430static int
Andrej Kozemcakd9831182016-06-20 08:47:57 +020012431api_show_lisp_status(vat_main_t *vam)
Andrej Kozemcaka9edd852016-05-02 12:14:33 +020012432{
Andrej Kozemcakd9831182016-06-20 08:47:57 +020012433 vl_api_show_lisp_status_t *mp;
Andrej Kozemcaka9edd852016-05-02 12:14:33 +020012434 f64 timeout = ~0;
12435
12436 if (!vam->json_output) {
Andrej Kozemcak914f91b2016-07-18 13:55:37 +020012437 fformat(vam->ofp, "%-20s%-16s\n",
12438 "lisp status", "locator-set");
Andrej Kozemcaka9edd852016-05-02 12:14:33 +020012439 }
12440
Andrej Kozemcakd9831182016-06-20 08:47:57 +020012441 M(SHOW_LISP_STATUS, show_lisp_status);
Andrej Kozemcaka9edd852016-05-02 12:14:33 +020012442 /* send it... */
12443 S;
Andrej Kozemcaka9edd852016-05-02 12:14:33 +020012444 /* Wait for a reply... */
12445 W;
12446
12447 /* NOTREACHED */
12448 return 0;
12449}
12450
Matus Fabian8a95a482016-05-06 15:14:13 +020012451static int
Andrej Kozemcakb6e4d392016-06-14 13:55:57 +020012452api_lisp_get_map_request_itr_rlocs(vat_main_t *vam)
12453{
12454 vl_api_lisp_get_map_request_itr_rlocs_t *mp;
12455 f64 timeout = ~0;
12456
12457 if (!vam->json_output) {
12458 fformat(vam->ofp, "%=20s\n",
12459 "itr-rlocs:");
12460 }
12461
12462 M(LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
12463 /* send it... */
12464 S;
12465 /* Wait for a reply... */
12466 W;
12467
12468 /* NOTREACHED */
12469 return 0;
12470}
12471
12472static int
Matus Fabian8a95a482016-05-06 15:14:13 +020012473api_af_packet_create (vat_main_t * vam)
12474{
12475 unformat_input_t * i = vam->input;
12476 vl_api_af_packet_create_t * mp;
12477 f64 timeout;
12478 u8 * host_if_name = 0;
12479 u8 hw_addr[6];
12480 u8 random_hw_addr = 1;
12481
12482 memset (hw_addr, 0, sizeof (hw_addr));
12483
12484 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
12485 if (unformat (i, "name %s", &host_if_name))
12486 vec_add1 (host_if_name, 0);
12487 else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
12488 random_hw_addr = 0;
12489 else
12490 break;
12491 }
12492
12493 if (!vec_len (host_if_name)) {
12494 errmsg ("host-interface name must be specified");
12495 return -99;
12496 }
12497
12498 if (vec_len (host_if_name) > 64) {
12499 errmsg ("host-interface name too long");
12500 return -99;
12501 }
12502
12503 M(AF_PACKET_CREATE, af_packet_create);
12504
12505 clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
12506 clib_memcpy (mp->hw_addr, hw_addr, 6);
12507 mp->use_random_hw_addr = random_hw_addr;
12508 vec_free (host_if_name);
12509
Keith Burns (alagalah)802255c2016-06-13 16:56:04 -070012510 S; W2(fprintf(vam->ofp," new sw_if_index = %d ", vam->sw_if_index));
Matus Fabian8a95a482016-05-06 15:14:13 +020012511 /* NOTREACHED */
12512 return 0;
12513}
12514
12515static int
12516api_af_packet_delete (vat_main_t * vam)
12517{
12518 unformat_input_t * i = vam->input;
12519 vl_api_af_packet_delete_t * mp;
12520 f64 timeout;
12521 u8 * host_if_name = 0;
12522
12523 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
12524 if (unformat (i, "name %s", &host_if_name))
12525 vec_add1 (host_if_name, 0);
12526 else
12527 break;
12528 }
12529
12530 if (!vec_len (host_if_name)) {
12531 errmsg ("host-interface name must be specified");
12532 return -99;
12533 }
12534
12535 if (vec_len (host_if_name) > 64) {
12536 errmsg ("host-interface name too long");
12537 return -99;
12538 }
12539
12540 M(AF_PACKET_DELETE, af_packet_delete);
12541
12542 clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
12543 vec_free (host_if_name);
12544
12545 S; W;
12546 /* NOTREACHED */
12547 return 0;
12548}
12549
Matus Fabian65fcd4d2016-05-13 05:44:48 -070012550static int
12551api_policer_add_del (vat_main_t * vam)
12552{
12553 unformat_input_t * i = vam->input;
12554 vl_api_policer_add_del_t * mp;
12555 f64 timeout;
12556 u8 is_add = 1;
12557 u8 * name = 0;
12558 u32 cir = 0;
12559 u32 eir = 0;
12560 u64 cb = 0;
12561 u64 eb = 0;
12562 u8 rate_type = 0;
12563 u8 round_type = 0;
12564 u8 type = 0;
Matus Fabian70e6a8d2016-06-20 08:10:42 -070012565 u8 color_aware = 0;
Matus Fabian4ac74c92016-05-31 07:33:29 -070012566 sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
Matus Fabian65fcd4d2016-05-13 05:44:48 -070012567
12568 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
12569 if (unformat (i, "del"))
12570 is_add = 0;
12571 else if (unformat (i, "name %s", &name))
12572 vec_add1 (name, 0);
12573 else if (unformat (i, "cir %u", &cir))
12574 ;
12575 else if (unformat (i, "eir %u", &eir))
12576 ;
12577 else if (unformat (i, "cb %u", &cb))
12578 ;
12579 else if (unformat (i, "eb %u", &eb))
12580 ;
12581 else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
12582 &rate_type))
12583 ;
12584 else if (unformat (i, "round_type %U", unformat_policer_round_type,
12585 &round_type))
12586 ;
12587 else if (unformat (i, "type %U", unformat_policer_type, &type))
12588 ;
Matus Fabian4ac74c92016-05-31 07:33:29 -070012589 else if (unformat (i, "conform_action %U", unformat_policer_action_type,
12590 &conform_action))
12591 ;
12592 else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
12593 &exceed_action))
12594 ;
12595 else if (unformat (i, "violate_action %U", unformat_policer_action_type,
12596 &violate_action))
12597 ;
Matus Fabian70e6a8d2016-06-20 08:10:42 -070012598 else if (unformat (i, "color-aware"))
12599 color_aware = 1;
Matus Fabian65fcd4d2016-05-13 05:44:48 -070012600 else
12601 break;
12602 }
12603
12604 if (!vec_len (name)) {
12605 errmsg ("policer name must be specified");
12606 return -99;
12607 }
12608
12609 if (vec_len (name) > 64) {
12610 errmsg ("policer name too long");
12611 return -99;
12612 }
12613
12614 M(POLICER_ADD_DEL, policer_add_del);
12615
12616 clib_memcpy (mp->name, name, vec_len (name));
12617 vec_free (name);
12618 mp->is_add = is_add;
12619 mp->cir = cir;
12620 mp->eir = eir;
12621 mp->cb = cb;
12622 mp->eb = eb;
12623 mp->rate_type = rate_type;
12624 mp->round_type = round_type;
12625 mp->type = type;
Matus Fabian4ac74c92016-05-31 07:33:29 -070012626 mp->conform_action_type = conform_action.action_type;
12627 mp->conform_dscp = conform_action.dscp;
12628 mp->exceed_action_type = exceed_action.action_type;
12629 mp->exceed_dscp = exceed_action.dscp;
12630 mp->violate_action_type = violate_action.action_type;
12631 mp->violate_dscp = violate_action.dscp;
Matus Fabian70e6a8d2016-06-20 08:10:42 -070012632 mp->color_aware = color_aware;
Matus Fabian65fcd4d2016-05-13 05:44:48 -070012633
12634 S; W;
12635 /* NOTREACHED */
12636 return 0;
12637}
12638
Matus Fabian82e29c42016-05-11 04:49:46 -070012639static int
Matus Fabiane8554802016-05-18 23:40:37 -070012640api_policer_dump(vat_main_t *vam)
12641{
12642 unformat_input_t * i = vam->input;
12643 vl_api_policer_dump_t *mp;
12644 f64 timeout = ~0;
12645 u8 *match_name = 0;
12646 u8 match_name_valid = 0;
12647
12648 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
12649 if (unformat (i, "name %s", &match_name)) {
12650 vec_add1 (match_name, 0);
12651 match_name_valid = 1;
12652 } else
12653 break;
12654 }
12655
12656 M(POLICER_DUMP, policer_dump);
12657 mp->match_name_valid = match_name_valid;
12658 clib_memcpy (mp->match_name, match_name, vec_len (match_name));
12659 vec_free (match_name);
12660 /* send it... */
12661 S;
12662
12663 /* Use a control ping for synchronization */
12664 {
12665 vl_api_control_ping_t * mp;
12666 M(CONTROL_PING, control_ping);
12667 S;
12668 }
12669 /* Wait for a reply... */
12670 W;
12671
12672 /* NOTREACHED */
12673 return 0;
12674}
12675
12676static int
Matus Fabian70e6a8d2016-06-20 08:10:42 -070012677api_policer_classify_set_interface (vat_main_t * vam)
12678{
12679 unformat_input_t * i = vam->input;
12680 vl_api_policer_classify_set_interface_t *mp;
12681 f64 timeout;
12682 u32 sw_if_index;
12683 int sw_if_index_set;
12684 u32 ip4_table_index = ~0;
12685 u32 ip6_table_index = ~0;
12686 u32 l2_table_index = ~0;
12687 u8 is_add = 1;
12688
12689 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
12690 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
12691 sw_if_index_set = 1;
12692 else if (unformat (i, "sw_if_index %d", &sw_if_index))
12693 sw_if_index_set = 1;
12694 else if (unformat (i, "del"))
12695 is_add = 0;
12696 else if (unformat (i, "ip4-table %d", &ip4_table_index))
12697 ;
12698 else if (unformat (i, "ip6-table %d", &ip6_table_index))
12699 ;
12700 else if (unformat (i, "l2-table %d", &l2_table_index))
12701 ;
12702 else {
12703 clib_warning ("parse error '%U'", format_unformat_error, i);
12704 return -99;
12705 }
12706 }
12707
12708 if (sw_if_index_set == 0) {
12709 errmsg ("missing interface name or sw_if_index\n");
12710 return -99;
12711 }
12712
12713 M(POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
12714
12715 mp->sw_if_index = ntohl(sw_if_index);
12716 mp->ip4_table_index = ntohl(ip4_table_index);
12717 mp->ip6_table_index = ntohl(ip6_table_index);
12718 mp->l2_table_index = ntohl(l2_table_index);
12719 mp->is_add = is_add;
12720
12721 S; W;
12722 /* NOTREACHED */
12723 return 0;
12724}
12725
12726static int
12727api_policer_classify_dump(vat_main_t *vam)
12728{
12729 unformat_input_t * i = vam->input;
12730 vl_api_policer_classify_dump_t *mp;
12731 f64 timeout = ~0;
12732 u8 type = POLICER_CLASSIFY_N_TABLES;
12733
12734 if (unformat (i, "type %U", unformat_classify_table_type, &type))
12735 ;
12736 else {
12737 errmsg ("classify table type must be specified\n");
12738 return -99;
12739 }
12740
12741 if (!vam->json_output) {
12742 fformat(vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
12743 }
12744
12745 M(POLICER_CLASSIFY_DUMP, policer_classify_dump);
12746 mp->type = type;
12747 /* send it... */
12748 S;
12749
12750 /* Use a control ping for synchronization */
12751 {
12752 vl_api_control_ping_t * mp;
12753 M(CONTROL_PING, control_ping);
12754 S;
12755 }
12756 /* Wait for a reply... */
12757 W;
12758
12759 /* NOTREACHED */
12760 return 0;
12761}
12762
12763static int
Matus Fabian82e29c42016-05-11 04:49:46 -070012764api_netmap_create (vat_main_t * vam)
12765{
12766 unformat_input_t * i = vam->input;
12767 vl_api_netmap_create_t * mp;
12768 f64 timeout;
12769 u8 * if_name = 0;
12770 u8 hw_addr[6];
12771 u8 random_hw_addr = 1;
12772 u8 is_pipe = 0;
12773 u8 is_master = 0;
12774
12775 memset (hw_addr, 0, sizeof (hw_addr));
12776
12777 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
12778 if (unformat (i, "name %s", &if_name))
12779 vec_add1 (if_name, 0);
12780 else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
12781 random_hw_addr = 0;
12782 else if (unformat (i, "pipe"))
12783 is_pipe = 1;
12784 else if (unformat (i, "master"))
12785 is_master = 1;
12786 else if (unformat (i, "slave"))
12787 is_master = 0;
12788 else
12789 break;
12790 }
12791
12792 if (!vec_len (if_name)) {
12793 errmsg ("interface name must be specified");
12794 return -99;
12795 }
12796
12797 if (vec_len (if_name) > 64) {
12798 errmsg ("interface name too long");
12799 return -99;
12800 }
12801
12802 M(NETMAP_CREATE, netmap_create);
12803
Dave Barach6f7b9922016-05-20 14:43:57 -040012804 clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
Matus Fabian82e29c42016-05-11 04:49:46 -070012805 clib_memcpy (mp->hw_addr, hw_addr, 6);
12806 mp->use_random_hw_addr = random_hw_addr;
12807 mp->is_pipe = is_pipe;
12808 mp->is_master = is_master;
12809 vec_free (if_name);
12810
12811 S; W;
12812 /* NOTREACHED */
12813 return 0;
12814}
12815
12816static int
12817api_netmap_delete (vat_main_t * vam)
12818{
12819 unformat_input_t * i = vam->input;
12820 vl_api_netmap_delete_t * mp;
12821 f64 timeout;
12822 u8 * if_name = 0;
12823
12824 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
12825 if (unformat (i, "name %s", &if_name))
12826 vec_add1 (if_name, 0);
12827 else
12828 break;
12829 }
12830
12831 if (!vec_len (if_name)) {
12832 errmsg ("interface name must be specified");
12833 return -99;
12834 }
12835
12836 if (vec_len (if_name) > 64) {
12837 errmsg ("interface name too long");
12838 return -99;
12839 }
12840
12841 M(NETMAP_DELETE, netmap_delete);
12842
Dave Barach6f7b9922016-05-20 14:43:57 -040012843 clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
Matus Fabian82e29c42016-05-11 04:49:46 -070012844 vec_free (if_name);
12845
12846 S; W;
12847 /* NOTREACHED */
12848 return 0;
12849}
12850
marek zavodsky2c21a9a2016-06-21 05:35:16 +020012851static void vl_api_mpls_gre_tunnel_details_t_handler
12852(vl_api_mpls_gre_tunnel_details_t * mp)
12853{
12854 vat_main_t * vam = &vat_main;
12855 i32 i;
12856 i32 len = ntohl(mp->nlabels);
12857
12858 if (mp->l2_only == 0) {
12859 fformat(vam->ofp, "[%d]: src %U, dst %U, adj %U/%d, labels ",
12860 ntohl(mp->tunnel_index),
12861 format_ip4_address, &mp->tunnel_src,
12862 format_ip4_address, &mp->tunnel_dst,
12863 format_ip4_address, &mp->intfc_address,
12864 ntohl(mp->mask_width));
12865 for (i = 0; i < len; i++) {
12866 fformat(vam->ofp, "%u ", ntohl(mp->labels[i]));
12867 }
12868 fformat(vam->ofp, "\n");
12869 fformat(vam->ofp, " inner fib index %d, outer fib index %d\n",
12870 ntohl(mp->inner_fib_index), ntohl(mp->outer_fib_index));
12871 } else {
12872 fformat(vam->ofp, "[%d]: src %U, dst %U, key %U, labels ",
12873 ntohl(mp->tunnel_index),
12874 format_ip4_address, &mp->tunnel_src,
12875 format_ip4_address, &mp->tunnel_dst,
12876 format_ip4_address, &mp->intfc_address);
12877 for (i = 0; i < len; i++) {
12878 fformat(vam->ofp, "%u ", ntohl(mp->labels[i]));
12879 }
12880 fformat(vam->ofp, "\n");
12881 fformat(vam->ofp, " l2 interface %d, outer fib index %d\n",
12882 ntohl(mp->hw_if_index), ntohl(mp->outer_fib_index));
12883 }
12884}
12885
12886static void vl_api_mpls_gre_tunnel_details_t_handler_json
12887(vl_api_mpls_gre_tunnel_details_t * mp)
12888{
12889 vat_main_t * vam = &vat_main;
12890 vat_json_node_t *node = NULL;
12891 struct in_addr ip4;
12892 i32 i;
12893 i32 len = ntohl(mp->nlabels);
12894
12895 if (VAT_JSON_ARRAY != vam->json_tree.type) {
12896 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
12897 vat_json_init_array(&vam->json_tree);
12898 }
12899 node = vat_json_array_add(&vam->json_tree);
12900
12901 vat_json_init_object(node);
12902 vat_json_object_add_uint(node, "tunnel_index", ntohl(mp->tunnel_index));
12903 clib_memcpy(&ip4, &(mp->intfc_address), sizeof(ip4));
12904 vat_json_object_add_ip4(node, "intfc_address", ip4);
12905 vat_json_object_add_uint(node, "inner_fib_index", ntohl(mp->inner_fib_index));
12906 vat_json_object_add_uint(node, "mask_width", ntohl(mp->mask_width));
12907 vat_json_object_add_uint(node, "encap_index", ntohl(mp->encap_index));
12908 vat_json_object_add_uint(node, "hw_if_index", ntohl(mp->hw_if_index));
12909 vat_json_object_add_uint(node, "l2_only", ntohl(mp->l2_only));
12910 clib_memcpy(&ip4, &(mp->tunnel_src), sizeof(ip4));
12911 vat_json_object_add_ip4(node, "tunnel_src", ip4);
12912 clib_memcpy(&ip4, &(mp->tunnel_dst), sizeof(ip4));
12913 vat_json_object_add_ip4(node, "tunnel_dst", ip4);
12914 vat_json_object_add_uint(node, "outer_fib_index", ntohl(mp->outer_fib_index));
12915 vat_json_object_add_uint(node, "label_count", len);
12916 for (i = 0; i < len; i++) {
12917 vat_json_object_add_uint(node, "label", ntohl(mp->labels[i]));
12918 }
12919}
12920
12921static int api_mpls_gre_tunnel_dump (vat_main_t * vam)
12922{
12923 vl_api_mpls_gre_tunnel_dump_t *mp;
12924 f64 timeout;
12925 i32 index = -1;
12926
12927 /* Parse args required to build the message */
12928 while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT) {
12929 if (!unformat (vam->input, "tunnel_index %d", &index)) {
12930 index = -1;
12931 break;
12932 }
12933 }
12934
12935 fformat(vam->ofp, " tunnel_index %d\n", index);
12936
12937 M(MPLS_GRE_TUNNEL_DUMP, mpls_gre_tunnel_dump);
12938 mp->tunnel_index = htonl(index);
12939 S;
12940
12941 /* Use a control ping for synchronization */
12942 {
12943 vl_api_control_ping_t * mp;
12944 M(CONTROL_PING, control_ping);
12945 S;
12946 }
12947 W;
12948}
12949
12950static void vl_api_mpls_eth_tunnel_details_t_handler
12951(vl_api_mpls_eth_tunnel_details_t * mp)
12952{
12953 vat_main_t * vam = &vat_main;
12954 i32 i;
12955 i32 len = ntohl(mp->nlabels);
12956
12957 fformat(vam->ofp, "[%d]: dst %U, adj %U/%d, labels ",
12958 ntohl(mp->tunnel_index),
12959 format_ethernet_address, &mp->tunnel_dst_mac,
12960 format_ip4_address, &mp->intfc_address,
12961 ntohl(mp->mask_width));
12962 for (i = 0; i < len; i++) {
12963 fformat(vam->ofp, "%u ", ntohl(mp->labels[i]));
12964 }
12965 fformat(vam->ofp, "\n");
12966 fformat(vam->ofp, " tx on %d, rx fib index %d\n",
12967 ntohl(mp->tx_sw_if_index),
12968 ntohl(mp->inner_fib_index));
12969}
12970
12971static void vl_api_mpls_eth_tunnel_details_t_handler_json
12972(vl_api_mpls_eth_tunnel_details_t * mp)
12973{
12974 vat_main_t * vam = &vat_main;
12975 vat_json_node_t *node = NULL;
12976 struct in_addr ip4;
12977 i32 i;
12978 i32 len = ntohl(mp->nlabels);
12979
12980 if (VAT_JSON_ARRAY != vam->json_tree.type) {
12981 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
12982 vat_json_init_array(&vam->json_tree);
12983 }
12984 node = vat_json_array_add(&vam->json_tree);
12985
12986 vat_json_init_object(node);
12987 vat_json_object_add_uint(node, "tunnel_index", ntohl(mp->tunnel_index));
12988 clib_memcpy(&ip4, &(mp->intfc_address), sizeof(ip4));
12989 vat_json_object_add_ip4(node, "intfc_address", ip4);
12990 vat_json_object_add_uint(node, "inner_fib_index", ntohl(mp->inner_fib_index));
12991 vat_json_object_add_uint(node, "mask_width", ntohl(mp->mask_width));
12992 vat_json_object_add_uint(node, "encap_index", ntohl(mp->encap_index));
12993 vat_json_object_add_uint(node, "hw_if_index", ntohl(mp->hw_if_index));
12994 vat_json_object_add_uint(node, "l2_only", ntohl(mp->l2_only));
12995 vat_json_object_add_string_copy(node, "tunnel_dst_mac",
12996 format(0, "%U", format_ethernet_address, &mp->tunnel_dst_mac));
12997 vat_json_object_add_uint(node, "tx_sw_if_index", ntohl(mp->tx_sw_if_index));
12998 vat_json_object_add_uint(node, "label_count", len);
12999 for (i = 0; i < len; i++) {
13000 vat_json_object_add_uint(node, "label", ntohl(mp->labels[i]));
13001 }
13002}
13003
13004static int api_mpls_eth_tunnel_dump (vat_main_t * vam)
13005{
13006 vl_api_mpls_eth_tunnel_dump_t *mp;
13007 f64 timeout;
13008 i32 index = -1;
13009
13010 /* Parse args required to build the message */
13011 while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT) {
13012 if (!unformat (vam->input, "tunnel_index %d", &index)) {
13013 index = -1;
13014 break;
13015 }
13016 }
13017
13018 fformat(vam->ofp, " tunnel_index %d\n", index);
13019
13020 M(MPLS_ETH_TUNNEL_DUMP, mpls_eth_tunnel_dump);
13021 mp->tunnel_index = htonl(index);
13022 S;
13023
13024 /* Use a control ping for synchronization */
13025 {
13026 vl_api_control_ping_t * mp;
13027 M(CONTROL_PING, control_ping);
13028 S;
13029 }
13030 W;
13031}
13032
13033static void vl_api_mpls_fib_encap_details_t_handler
13034(vl_api_mpls_fib_encap_details_t * mp)
13035{
13036 vat_main_t * vam = &vat_main;
13037 i32 i;
13038 i32 len = ntohl(mp->nlabels);
13039
13040 fformat(vam->ofp, "table %d, dest %U, label ",
13041 ntohl(mp->fib_index),
13042 format_ip4_address, &mp->dest,
13043 len);
13044 for (i = 0; i < len; i++) {
13045 fformat(vam->ofp, "%u ", ntohl(mp->labels[i]));
13046 }
13047 fformat(vam->ofp, "\n");
13048}
13049
13050static void vl_api_mpls_fib_encap_details_t_handler_json
13051(vl_api_mpls_fib_encap_details_t * mp)
13052{
13053 vat_main_t * vam = &vat_main;
13054 vat_json_node_t *node = NULL;
13055 i32 i;
13056 i32 len = ntohl(mp->nlabels);
13057 struct in_addr ip4;
13058
13059 if (VAT_JSON_ARRAY != vam->json_tree.type) {
13060 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
13061 vat_json_init_array(&vam->json_tree);
13062 }
13063 node = vat_json_array_add(&vam->json_tree);
13064
13065 vat_json_init_object(node);
13066 vat_json_object_add_uint(node, "table", ntohl(mp->fib_index));
13067 vat_json_object_add_uint(node, "entry_index", ntohl(mp->entry_index));
13068 clib_memcpy(&ip4, &(mp->dest), sizeof(ip4));
13069 vat_json_object_add_ip4(node, "dest", ip4);
13070 vat_json_object_add_uint(node, "s_bit", ntohl(mp->s_bit));
13071 vat_json_object_add_uint(node, "label_count", len);
13072 for (i = 0; i < len; i++) {
13073 vat_json_object_add_uint(node, "label", ntohl(mp->labels[i]));
13074 }
13075}
13076
13077static int api_mpls_fib_encap_dump (vat_main_t * vam)
13078{
13079 vl_api_mpls_fib_encap_dump_t *mp;
13080 f64 timeout;
13081
13082 M(MPLS_FIB_ENCAP_DUMP, mpls_fib_encap_dump);
13083 S;
13084
13085 /* Use a control ping for synchronization */
13086 {
13087 vl_api_control_ping_t * mp;
13088 M(CONTROL_PING, control_ping);
13089 S;
13090 }
13091 W;
13092}
13093
13094static void vl_api_mpls_fib_decap_details_t_handler
13095(vl_api_mpls_fib_decap_details_t * mp)
13096{
13097 vat_main_t * vam = &vat_main;
13098
13099 fformat(vam->ofp, "RX table %d, TX table/intfc %u, swif_tag '%s', label %u, s_bit %u\n",
13100 ntohl(mp->rx_table_id),
13101 ntohl(mp->tx_table_id),
13102 mp->swif_tag,
13103 ntohl(mp->label),
13104 ntohl(mp->s_bit));
13105}
13106
13107static void vl_api_mpls_fib_decap_details_t_handler_json
13108(vl_api_mpls_fib_decap_details_t * mp)
13109{
13110 vat_main_t * vam = &vat_main;
13111 vat_json_node_t *node = NULL;
13112 struct in_addr ip4;
13113
13114 if (VAT_JSON_ARRAY != vam->json_tree.type) {
13115 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
13116 vat_json_init_array(&vam->json_tree);
13117 }
13118 node = vat_json_array_add(&vam->json_tree);
13119
13120 vat_json_init_object(node);
13121 vat_json_object_add_uint(node, "table", ntohl(mp->fib_index));
13122 vat_json_object_add_uint(node, "entry_index", ntohl(mp->entry_index));
13123 clib_memcpy(&ip4, &(mp->dest), sizeof(ip4));
13124 vat_json_object_add_ip4(node, "dest", ip4);
13125 vat_json_object_add_uint(node, "s_bit", ntohl(mp->s_bit));
13126 vat_json_object_add_uint(node, "label", ntohl(mp->label));
13127 vat_json_object_add_uint(node, "rx_table_id", ntohl(mp->rx_table_id));
13128 vat_json_object_add_uint(node, "tx_table_id", ntohl(mp->tx_table_id));
13129 vat_json_object_add_string_copy(node, "swif_tag", mp->swif_tag);
13130}
13131
13132static int api_mpls_fib_decap_dump (vat_main_t * vam)
13133{
13134 vl_api_mpls_fib_decap_dump_t *mp;
13135 f64 timeout;
13136
13137 M(MPLS_FIB_DECAP_DUMP, mpls_fib_decap_dump);
13138 S;
13139
13140 /* Use a control ping for synchronization */
13141 {
13142 vl_api_control_ping_t * mp;
13143 M(CONTROL_PING, control_ping);
13144 S;
13145 }
13146 W;
13147}
13148
Pavel Kotucek20c90f72016-06-07 14:44:26 +020013149int api_classify_table_ids (vat_main_t *vam)
13150{
13151 vl_api_classify_table_ids_t *mp;
13152 f64 timeout;
13153
13154 /* Construct the API message */
13155 M(CLASSIFY_TABLE_IDS, classify_table_ids);
13156 mp->context = 0;
13157
13158 S; W;
13159 /* NOTREACHED */
13160 return 0;
13161}
13162
13163int api_classify_table_by_interface (vat_main_t *vam)
13164{
13165 unformat_input_t * input = vam->input;
13166 vl_api_classify_table_by_interface_t *mp;
13167 f64 timeout;
13168
13169 u32 sw_if_index = ~0;
13170 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
13171 if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
13172 ;
13173 else if (unformat (input, "sw_if_index %d", &sw_if_index))
13174 ;
13175 else
13176 break;
13177 }
13178 if (sw_if_index == ~0) {
13179 errmsg ("missing interface name or sw_if_index\n");
13180 return -99;
13181 }
13182
13183 /* Construct the API message */
13184 M(CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
13185 mp->context = 0;
13186 mp->sw_if_index = ntohl(sw_if_index);
13187
13188 S; W;
13189 /* NOTREACHED */
13190 return 0;
13191}
13192
13193int api_classify_table_info (vat_main_t *vam)
13194{
13195 unformat_input_t * input = vam->input;
13196 vl_api_classify_table_info_t *mp;
13197 f64 timeout;
13198
13199 u32 table_id = ~0;
13200 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
13201 if (unformat (input, "table_id %d", &table_id))
13202 ;
13203 else
13204 break;
13205 }
13206 if (table_id == ~0) {
13207 errmsg ("missing table id\n");
13208 return -99;
13209 }
13210
13211 /* Construct the API message */
13212 M(CLASSIFY_TABLE_INFO, classify_table_info);
13213 mp->context = 0;
13214 mp->table_id = ntohl(table_id);
13215
13216 S; W;
13217 /* NOTREACHED */
13218 return 0;
13219}
13220
13221int api_classify_session_dump (vat_main_t *vam)
13222{
13223 unformat_input_t * input = vam->input;
13224 vl_api_classify_session_dump_t *mp;
13225 f64 timeout;
13226
13227 u32 table_id = ~0;
13228 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
13229 if (unformat (input, "table_id %d", &table_id))
13230 ;
13231 else
13232 break;
13233 }
13234 if (table_id == ~0) {
13235 errmsg ("missing table id\n");
13236 return -99;
13237 }
13238
13239 /* Construct the API message */
13240 M(CLASSIFY_SESSION_DUMP, classify_session_dump);
13241 mp->context = 0;
13242 mp->table_id = ntohl(table_id);
13243 S;
13244
13245 /* Use a control ping for synchronization */
13246 {
13247 vl_api_control_ping_t * mp;
13248 M(CONTROL_PING, control_ping);
13249 S;
13250 }
13251 W;
13252 /* NOTREACHED */
13253 return 0;
13254}
13255
Juraj Slobodaac645ad2016-07-07 00:18:57 -070013256static void vl_api_ipfix_details_t_handler (vl_api_ipfix_details_t * mp)
13257{
13258 vat_main_t * vam = &vat_main;
13259
13260 fformat(vam->ofp, "collector_address %U, collector_port %d, "
13261 "src_address %U, fib_index %u, path_mtu %u, "
13262 "template_interval %u\n",
13263 format_ip4_address, mp->collector_address,
13264 ntohs(mp->collector_port),
13265 format_ip4_address, mp->src_address,
13266 ntohl(mp->fib_index),
13267 ntohl(mp->path_mtu),
13268 ntohl(mp->template_interval));
13269
13270 vam->retval = 0;
13271 vam->result_ready = 1;
13272}
13273
13274static void vl_api_ipfix_details_t_handler_json
13275(vl_api_ipfix_details_t * mp)
13276{
13277 vat_main_t * vam = &vat_main;
13278 vat_json_node_t node;
13279 struct in_addr collector_address;
13280 struct in_addr src_address;
13281
13282 vat_json_init_object(&node);
13283 clib_memcpy(&collector_address, &mp->collector_address,
13284 sizeof(collector_address));
13285 vat_json_object_add_ip4(&node, "collector_address", collector_address);
13286 vat_json_object_add_uint(&node, "collector_port",
13287 ntohs(mp->collector_port));
13288 clib_memcpy(&src_address, &mp->src_address, sizeof(src_address));
13289 vat_json_object_add_ip4(&node, "src_address", src_address);
13290 vat_json_object_add_uint(&node, "fib_index", ntohl(mp->fib_index));
13291 vat_json_object_add_uint(&node, "path_mtu", ntohl(mp->path_mtu));
13292 vat_json_object_add_uint(&node, "template_interval",
13293 ntohl(mp->template_interval));
13294
13295 vat_json_print(vam->ofp, &node);
13296 vat_json_free(&node);
13297 vam->retval = 0;
13298 vam->result_ready = 1;
13299}
13300
13301int api_ipfix_dump (vat_main_t *vam)
13302{
13303 vl_api_ipfix_dump_t *mp;
13304 f64 timeout;
13305
13306 /* Construct the API message */
13307 M(IPFIX_DUMP, ipfix_dump);
13308 mp->context = 0;
13309
13310 S; W;
13311 /* NOTREACHED */
13312 return 0;
13313}
13314
Pavel Kotucek9e6ed6e2016-07-12 10:18:26 +020013315int api_pg_create_interface (vat_main_t *vam)
13316{
13317 unformat_input_t * input = vam->input;
13318 vl_api_pg_create_interface_t *mp;
13319 f64 timeout;
13320
13321 u32 if_id = ~0;
13322 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
13323 if (unformat (input, "if_id %d", &if_id))
13324 ;
13325 else
13326 break;
13327 }
13328 if (if_id == ~0) {
13329 errmsg ("missing pg interface index\n");
13330 return -99;
13331 }
13332
13333 /* Construct the API message */
13334 M(PG_CREATE_INTERFACE, pg_create_interface);
13335 mp->context = 0;
13336 mp->interface_id = ntohl(if_id);
13337
13338 S; W;
13339 /* NOTREACHED */
13340 return 0;
13341}
13342
13343int api_pg_capture (vat_main_t *vam)
13344{
13345 unformat_input_t * input = vam->input;
13346 vl_api_pg_capture_t *mp;
13347 f64 timeout;
13348
13349 u32 if_id = ~0;
13350 u8 enable = 1;
13351 u32 count = 1;
13352 u8 pcap_file_set = 0;
13353 u8 * pcap_file = 0;
13354 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
13355 if (unformat (input, "if_id %d", &if_id))
13356 ;
13357 else if (unformat (input, "pcap %s", &pcap_file))
13358 pcap_file_set = 1;
13359 else if (unformat (input, "count %d", &count))
13360 ;
13361 else if (unformat (input, "disable"))
13362 enable = 0;
13363 else
13364 break;
13365 }
13366 if (if_id == ~0) {
13367 errmsg ("missing pg interface index\n");
13368 return -99;
13369 }
13370 if (pcap_file_set>0) {
13371 if (vec_len (pcap_file) > 255) {
13372 errmsg ("pcap file name is too long\n");
13373 return -99;
13374 }
13375 }
13376
13377 u32 name_len = vec_len(pcap_file);
13378 /* Construct the API message */
13379 M(PG_CAPTURE, pg_capture);
13380 mp->context = 0;
13381 mp->interface_id = ntohl(if_id);
13382 mp->is_enabled = enable;
13383 mp->count = ntohl(count);
13384 mp->pcap_name_length = ntohl(name_len);
13385 if (pcap_file_set != 0) {
13386 clib_memcpy(mp->pcap_file_name, pcap_file, name_len);
13387 }
13388 vec_free(pcap_file);
13389
13390 S; W;
13391 /* NOTREACHED */
13392 return 0;
13393}
13394
13395int api_pg_enable_disable (vat_main_t *vam)
13396{
13397 unformat_input_t * input = vam->input;
13398 vl_api_pg_enable_disable_t *mp;
13399 f64 timeout;
13400
13401 u8 enable = 1;
13402 u8 stream_name_set = 0;
13403 u8 * stream_name = 0;
13404 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
13405 if (unformat (input, "stream %s", &stream_name))
13406 stream_name_set = 1;
13407 else if (unformat (input, "disable"))
13408 enable = 0;
13409 else
13410 break;
13411 }
13412
13413 if (stream_name_set>0) {
13414 if (vec_len (stream_name) > 255) {
13415 errmsg ("stream name too long\n");
13416 return -99;
13417 }
13418 }
13419
13420 u32 name_len = vec_len(stream_name);
13421 /* Construct the API message */
13422 M(PG_ENABLE_DISABLE, pg_enable_disable);
13423 mp->context = 0;
13424 mp->is_enabled = enable;
13425 if (stream_name_set != 0) {
13426 mp->stream_name_length = ntohl(name_len);
13427 clib_memcpy(mp->stream_name, stream_name, name_len);
13428 }
13429 vec_free(stream_name);
13430
13431 S; W;
13432 /* NOTREACHED */
13433 return 0;
13434}
13435
Dave Barach6f9bca22016-04-30 10:25:32 -040013436int api_ip_source_and_port_range_check_add_del (vat_main_t *vam)
13437{
13438 unformat_input_t * input = vam->input;
13439 vl_api_ip_source_and_port_range_check_add_del_t *mp;
13440 f64 timeout;
13441
13442 u16 * low_ports = 0;
13443 u16 * high_ports = 0;
13444 u16 this_low;
13445 u16 this_hi;
13446 ip4_address_t ip4_addr;
13447 ip6_address_t ip6_addr;
13448 u32 length;
13449 u32 tmp, tmp2;
13450 u8 prefix_set = 0;
13451 u32 vrf_id =~0;
13452 u8 is_add = 1;
13453 u8 is_ipv6 = 0;
13454
13455 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13456 {
13457 if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
13458 {
13459 prefix_set = 1;
13460 }
13461 else if (unformat (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
13462 {
13463 prefix_set = 1;
13464 is_ipv6 = 1;
13465 }
13466 else if (unformat (input, "vrf %d", &vrf_id))
13467 ;
13468 else if (unformat (input, "del"))
13469 is_add = 0;
13470 else if (unformat (input, "port %d", &tmp))
13471 {
13472 if (tmp == 0 || tmp > 65535) {
13473 errmsg ("port %d out of range", tmp);
13474 return -99;
13475 }
13476 this_low = tmp;
13477 this_hi = this_low + 1;
13478 vec_add1 (low_ports, this_low);
13479 vec_add1 (high_ports, this_hi);
13480 }
13481 else if (unformat (input, "range %d - %d", &tmp, &tmp2))
13482 {
13483 if ((tmp > tmp2) ||
13484 (tmp == 0) ||
13485 (tmp2 > 65535)) {
13486 errmsg ("incorrect range parameters\n");
13487 return -99;
13488 }
13489 this_low = tmp;
13490 /* Note: in debug CLI +1 is added to high before
13491 passing to real fn that does "the work"
13492 (ip_source_and_port_range_check_add_del).
13493 This fn is a wrapper around the binary API fn a
13494 control plane will call, which expects this increment
13495 to have occurred. Hence letting the binary API control
13496 plane fn do the increment for consistency between VAT
13497 and other control planes.
13498 */
13499 this_hi = tmp2;
13500 vec_add1 (low_ports, this_low);
13501 vec_add1 (high_ports, this_hi);
13502 }
13503 else
13504 break;
13505 }
13506
13507 if (prefix_set == 0) {
13508 errmsg ("<address>/<mask> not specified\n");
13509 return -99;
13510 }
13511
13512 if (vrf_id == ~0) {
13513 errmsg ("VRF ID required, not specified\n");
13514 return -99;
13515 }
13516
13517 if (vrf_id == 0) {
13518 errmsg ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
13519 return -99;
13520 }
13521
13522 if (vec_len(low_ports) == 0) {
13523 errmsg ("At least one port or port range required\n");
13524 return -99;
13525 }
13526
13527 M(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, ip_source_and_port_range_check_add_del);
13528
13529 mp->is_add = is_add;
13530
13531 if (is_ipv6) {
13532 mp->is_ipv6 = 1;
13533 clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
13534 } else {
13535 mp->is_ipv6 = 0;
13536 clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
13537 }
13538
13539 mp->mask_length = length;
13540 mp->number_of_ranges = vec_len (low_ports);
13541
13542 clib_memcpy (mp->low_ports, low_ports, vec_len(low_ports));
13543 vec_free(low_ports);
13544
13545 clib_memcpy (mp->high_ports, high_ports, vec_len(high_ports));
13546 vec_free (high_ports);
13547
13548 mp->vrf_id = ntohl(vrf_id);
13549
13550 S; W;
13551 /* NOTREACHED */
13552 return 0;
13553}
13554
13555int api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
13556{
13557 unformat_input_t * input = vam->input;
13558 vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
13559 f64 timeout;
13560 u32 sw_if_index = ~0;
Keith Burns (alagalah)9d3a8792016-08-02 11:57:37 -070013561 int vrf_set = 0;
13562 u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
13563 u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
Dave Barach6f9bca22016-04-30 10:25:32 -040013564 u8 is_add = 1;
13565
13566 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
Keith Burns (alagalah)9d3a8792016-08-02 11:57:37 -070013567 {
13568 if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
Dave Barach6f9bca22016-04-30 10:25:32 -040013569 ;
Keith Burns (alagalah)9d3a8792016-08-02 11:57:37 -070013570 else if (unformat (input, "sw_if_index %d", &sw_if_index))
Dave Barach6f9bca22016-04-30 10:25:32 -040013571 ;
Keith Burns (alagalah)9d3a8792016-08-02 11:57:37 -070013572 else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
13573 vrf_set=1;
13574 else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
13575 vrf_set=1;
13576 else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
13577 vrf_set=1;
13578 else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
13579 vrf_set=1;
13580 else if (unformat (input, "del"))
13581 is_add = 0;
13582 else
13583 break;
13584 }
Dave Barach6f9bca22016-04-30 10:25:32 -040013585
13586 if (sw_if_index == ~0) {
Keith Burns (alagalah)9d3a8792016-08-02 11:57:37 -070013587 errmsg ("Interface required but not specified\n");
13588 return -99;
Dave Barach6f9bca22016-04-30 10:25:32 -040013589 }
13590
Keith Burns (alagalah)9d3a8792016-08-02 11:57:37 -070013591 if (vrf_set == 0) {
Dave Barach6f9bca22016-04-30 10:25:32 -040013592 errmsg ("VRF ID required but not specified\n");
13593 return -99;
13594 }
13595
Keith Burns (alagalah)9d3a8792016-08-02 11:57:37 -070013596 if (tcp_out_vrf_id == 0
13597 || udp_out_vrf_id == 0
13598 || tcp_in_vrf_id == 0
13599 || udp_in_vrf_id == 0) {
Dave Barach6f9bca22016-04-30 10:25:32 -040013600 errmsg ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
13601 return -99;
13602 }
13603
13604 /* Construct the API message */
13605 M(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, ip_source_and_port_range_check_interface_add_del);
13606
13607 mp->sw_if_index = ntohl (sw_if_index);
13608 mp->is_add = is_add;
Keith Burns (alagalah)9d3a8792016-08-02 11:57:37 -070013609 mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
13610 mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
13611 mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
13612 mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
Dave Barach6f9bca22016-04-30 10:25:32 -040013613
13614 /* send it... */
13615 S;
13616
13617 /* Wait for a reply... */
13618 W;
13619}
13620
Ed Warnickecb9cada2015-12-08 15:45:58 -070013621static int q_or_quit (vat_main_t * vam)
13622{
13623 longjmp (vam->jump_buf, 1);
13624 return 0; /* not so much */
13625}
13626static int q (vat_main_t * vam) {return q_or_quit (vam);}
13627static int quit (vat_main_t * vam) {return q_or_quit (vam);}
13628
13629static int comment (vat_main_t * vam)
13630{
13631 return 0;
13632}
13633
Matus Fabiand2dc3df2015-12-14 10:31:33 -050013634static int cmd_cmp (void * a1, void * a2)
13635{
13636 u8 ** c1 = a1;
13637 u8 ** c2 = a2;
13638
13639 return strcmp ((char *)(c1[0]), (char *)(c2[0]));
13640}
13641
Ed Warnickecb9cada2015-12-08 15:45:58 -070013642static int help (vat_main_t * vam)
13643{
13644 u8 ** cmds = 0;
13645 u8 * name = 0;
13646 hash_pair_t * p;
13647 unformat_input_t * i = vam->input;
13648 int j;
13649
13650 if (unformat (i, "%s", &name)) {
13651 uword *hs;
13652
13653 vec_add1(name, 0);
13654
13655 hs = hash_get_mem (vam->help_by_name, name);
13656 if (hs)
13657 fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
13658 else
13659 fformat (vam->ofp, "No such msg / command '%s'\n", name);
13660 vec_free(name);
13661 return 0;
13662 }
13663
13664 fformat(vam->ofp, "Help is available for the following:\n");
13665
Hongjun Ni11bfc2f2016-07-22 18:19:19 +080013666 hash_foreach_pair (p, vam->function_by_name,
Ed Warnickecb9cada2015-12-08 15:45:58 -070013667 ({
13668 vec_add1 (cmds, (u8 *)(p->key));
13669 }));
13670
Matus Fabiand2dc3df2015-12-14 10:31:33 -050013671 vec_sort_with_function (cmds, cmd_cmp);
Ed Warnickecb9cada2015-12-08 15:45:58 -070013672
13673 for (j = 0; j < vec_len(cmds); j++)
13674 fformat (vam->ofp, "%s\n", cmds[j]);
13675
13676 vec_free (cmds);
13677 return 0;
13678}
13679
13680static int set (vat_main_t * vam)
13681{
13682 u8 * name = 0, * value = 0;
13683 unformat_input_t * i = vam->input;
13684
13685 if (unformat (i, "%s", &name)) {
13686 /* The input buffer is a vector, not a string. */
13687 value = vec_dup (i->buffer);
13688 vec_delete (value, i->index, 0);
13689 /* Almost certainly has a trailing newline */
13690 if (value[vec_len(value)-1] == '\n')
13691 value[vec_len(value)-1] = 0;
13692 /* Make sure it's a proper string, one way or the other */
13693 vec_add1 (value, 0);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +080013694 (void) clib_macro_set_value (&vam->macro_main,
Ed Warnickecb9cada2015-12-08 15:45:58 -070013695 (char *)name, (char *)value);
13696 }
13697 else
13698 errmsg ("usage: set <name> <value>\n");
13699
13700 vec_free (name);
13701 vec_free (value);
13702 return 0;
13703}
13704
13705static int unset (vat_main_t * vam)
13706{
13707 u8 * name = 0;
13708
13709 if (unformat (vam->input, "%s", &name))
13710 if (clib_macro_unset (&vam->macro_main, (char *)name) == 1)
13711 errmsg ("unset: %s wasn't set\n", name);
13712 vec_free (name);
13713 return 0;
13714}
13715
13716typedef struct {
13717 u8 * name;
13718 u8 * value;
13719} macro_sort_t;
13720
13721
Matus Fabiand2dc3df2015-12-14 10:31:33 -050013722static int macro_sort_cmp (void * a1, void * a2)
13723{
13724 macro_sort_t * s1 = a1;
13725 macro_sort_t * s2 = a2;
13726
13727 return strcmp ((char *)(s1->name), (char *)(s2->name));
13728}
13729
Ed Warnickecb9cada2015-12-08 15:45:58 -070013730static int dump_macro_table (vat_main_t * vam)
13731{
Hongjun Ni11bfc2f2016-07-22 18:19:19 +080013732 macro_sort_t * sort_me = 0, * sm;
Ed Warnickecb9cada2015-12-08 15:45:58 -070013733 int i;
13734 hash_pair_t * p;
13735
Hongjun Ni11bfc2f2016-07-22 18:19:19 +080013736 hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
Ed Warnickecb9cada2015-12-08 15:45:58 -070013737 ({
13738 vec_add2 (sort_me, sm, 1);
13739 sm->name = (u8 *)(p->key);
13740 sm->value = (u8 *) (p->value[0]);
13741 }));
Hongjun Ni11bfc2f2016-07-22 18:19:19 +080013742
Matus Fabiand2dc3df2015-12-14 10:31:33 -050013743 vec_sort_with_function (sort_me, macro_sort_cmp);
Ed Warnickecb9cada2015-12-08 15:45:58 -070013744
13745 if (vec_len(sort_me))
13746 fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
13747 else
13748 fformat (vam->ofp, "The macro table is empty...\n");
13749
13750 for (i = 0; i < vec_len (sort_me); i++)
13751 fformat (vam->ofp, "%-15s%s\n", sort_me[i].name,
13752 sort_me[i].value);
13753 return 0;
13754}
13755
Dave Barachb44e9bc2016-02-19 09:06:23 -050013756static int dump_node_table (vat_main_t * vam)
13757{
13758 int i, j;
13759 vlib_node_t * node, * next_node;
13760
13761 if (vec_len (vam->graph_nodes) == 0) {
13762 fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
13763 return 0;
13764 }
13765
13766 for (i = 0; i < vec_len (vam->graph_nodes); i++) {
13767 node = vam->graph_nodes[i];
13768 fformat (vam->ofp, "[%d] %s\n", i, node->name);
13769 for (j = 0; j < vec_len (node->next_nodes); j++) {
13770 if (node->next_nodes[j] != ~0) {
13771 next_node = vam->graph_nodes[node->next_nodes[j]];
13772 fformat (vam->ofp, " [%d] %s\n", j, next_node->name);
13773 }
13774 }
13775 }
13776 return 0;
13777}
13778
13779static int search_node_table (vat_main_t * vam)
13780{
13781 unformat_input_t * line_input = vam->input;
13782 u8 * node_to_find;
13783 int j;
13784 vlib_node_t * node, * next_node;
13785 uword * p;
13786
13787 if (vam->graph_node_index_by_name == 0) {
13788 fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
13789 return 0;
13790 }
13791
13792 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
13793 if (unformat (line_input, "%s", &node_to_find)) {
13794 vec_add1 (node_to_find, 0);
13795 p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
13796 if (p == 0) {
13797 fformat (vam->ofp, "%s not found...\n", node_to_find);
13798 goto out;
13799 }
13800 node = vam->graph_nodes[p[0]];
13801 fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
13802 for (j = 0; j < vec_len (node->next_nodes); j++) {
13803 if (node->next_nodes[j] != ~0) {
13804 next_node = vam->graph_nodes[node->next_nodes[j]];
13805 fformat (vam->ofp, " [%d] %s\n", j, next_node->name);
13806 }
13807 }
13808 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +080013809
Dave Barachb44e9bc2016-02-19 09:06:23 -050013810 else {
Hongjun Ni11bfc2f2016-07-22 18:19:19 +080013811 clib_warning ("parse error '%U'", format_unformat_error,
Dave Barachb44e9bc2016-02-19 09:06:23 -050013812 line_input);
13813 return -99;
13814 }
13815
13816 out:
13817 vec_free(node_to_find);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +080013818
Dave Barachb44e9bc2016-02-19 09:06:23 -050013819 }
13820
Hongjun Ni11bfc2f2016-07-22 18:19:19 +080013821 return 0;
Dave Barachb44e9bc2016-02-19 09:06:23 -050013822}
13823
13824
Ed Warnickecb9cada2015-12-08 15:45:58 -070013825static int script (vat_main_t * vam)
13826{
13827 u8 * s = 0;
13828 char * save_current_file;
13829 unformat_input_t save_input;
13830 jmp_buf save_jump_buf;
13831 u32 save_line_number;
13832
13833 FILE * new_fp, * save_ifp;
13834
13835 if (unformat (vam->input, "%s", &s)) {
13836 new_fp = fopen ((char *)s, "r");
13837 if (new_fp == 0) {
13838 errmsg ("Couldn't open script file %s\n", s);
13839 vec_free (s);
13840 return -99;
13841 }
13842 } else {
13843 errmsg ("Missing script name\n");
13844 return -99;
13845 }
13846
Damjan Marionf1213b82016-03-13 02:22:06 +010013847 clib_memcpy (&save_input, &vam->input, sizeof (save_input));
13848 clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
Ed Warnickecb9cada2015-12-08 15:45:58 -070013849 save_ifp = vam->ifp;
13850 save_line_number = vam->input_line_number;
13851 save_current_file = (char *) vam->current_file;
13852
13853 vam->input_line_number = 0;
13854 vam->ifp = new_fp;
13855 vam->current_file = s;
13856 do_one_file (vam);
13857
Damjan Marionf1213b82016-03-13 02:22:06 +010013858 clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
13859 clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
Ed Warnickecb9cada2015-12-08 15:45:58 -070013860 vam->ifp = save_ifp;
13861 vam->input_line_number = save_line_number;
13862 vam->current_file = (u8 *) save_current_file;
13863 vec_free (s);
13864
13865 return 0;
13866}
13867
13868static int echo (vat_main_t * vam)
13869{
13870 fformat (vam->ofp, "%v", vam->input->buffer);
13871 return 0;
13872}
13873
13874/* List of API message constructors, CLI names map to api_xxx */
13875#define foreach_vpe_api_msg \
13876_(create_loopback,"[mac <mac-addr>]") \
13877_(sw_interface_dump,"") \
13878_(sw_interface_set_flags, \
13879 "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
13880_(sw_interface_add_del_address, \
13881 "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
13882_(sw_interface_set_table, \
13883 "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]") \
13884_(sw_interface_set_vpath, \
13885 "<intfc> | sw_if_index <id> enable | disable") \
13886_(sw_interface_set_l2_xconnect, \
13887 "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
13888 "enable | disable") \
13889_(sw_interface_set_l2_bridge, \
13890 "rx <intfc> | rx_sw_if_index <id> bd_id <bridge-domain-id>\n" \
13891 "[shg <split-horizon-group>] [bvi]\n" \
13892 "enable | disable") \
13893_(bridge_domain_add_del, \
13894 "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
13895_(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n") \
13896_(l2fib_add_del, \
Dave Barach41da02d2016-07-11 16:48:42 -070013897 "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
Ed Warnickecb9cada2015-12-08 15:45:58 -070013898_(l2_flags, \
13899 "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
13900_(bridge_flags, \
13901 "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
13902_(tap_connect, \
13903 "tapname <name> mac <mac-addr> | random-mac") \
13904_(tap_modify, \
13905 "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
13906_(tap_delete, \
13907 "<vpp-if-name> | sw_if_index <id>") \
13908_(sw_interface_tap_dump, "") \
13909_(ip_add_del_route, \
13910 "<addr>/<mask> via <addr> [vrf <n>]\n" \
13911 "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n" \
13912 "[weight <n>] [drop] [local] [classify <n>] [del]\n" \
13913 "[multipath] [count <n>]") \
13914_(proxy_arp_add_del, \
13915 "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]") \
13916_(proxy_arp_intfc_enable_disable, \
13917 "<intfc> | sw_if_index <id> enable | disable") \
13918_(mpls_add_del_encap, \
13919 "label <n> dst <ip4-addr> [vrf <n>] [del]") \
13920_(mpls_add_del_decap, \
13921 "label <n> [rx_vrf_id <n>] [tx_vrf_id] [s-bit-clear][del]") \
13922_(mpls_gre_add_del_tunnel, \
13923 "inner_vrf_id <n> outer_vrf_id <n> src <ip4-address> dst <ip4-address>\n" \
13924 "adj <ip4-address>/<mask-width> [del]") \
13925_(sw_interface_set_unnumbered, \
13926 "<intfc> | sw_if_index <id> unnum_if_index <id> [del]") \
13927_(ip_neighbor_add_del, \
Chris Luke49a69632016-07-08 10:34:00 -040013928 "(<intfc> | sw_if_index <id>) dst <ip46-address> " \
13929 "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]") \
Ed Warnickecb9cada2015-12-08 15:45:58 -070013930_(reset_vrf, "vrf <id> [ipv6]") \
13931_(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>") \
13932_(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n" \
13933 "[outer_vlan_id <n>][inner_vlan_id <n>]\n" \
13934 "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n" \
13935 "[outer_vlan_id_any][inner_vlan_id_any]") \
13936_(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]") \
13937_(reset_fib, "vrf <n> [ipv6]") \
13938_(dhcp_proxy_config, \
13939 "svr <v46-address> src <v46-address>\n" \
13940 "insert-cid <n> [del]") \
13941_(dhcp_proxy_config_2, \
13942 "svr <v46-address> src <v46-address>\n" \
13943 "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]") \
13944_(dhcp_proxy_set_vss, \
13945 "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]") \
13946_(dhcp_client_config, \
13947 "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
13948_(set_ip_flow_hash, \
13949 "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]") \
13950_(sw_interface_ip6_enable_disable, \
13951 "<intfc> | sw_if_index <id> enable | disable") \
13952_(sw_interface_ip6_set_link_local_address, \
13953 "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>") \
13954_(sw_interface_ip6nd_ra_prefix, \
13955 "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n" \
13956 "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n" \
13957 "[nolink] [isno]") \
13958_(sw_interface_ip6nd_ra_config, \
13959 "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n" \
Chris Luke33879c92016-06-28 19:54:21 -040013960 "[life <n>] [count <n>] [interval <n>] [suppress]\n" \
Ed Warnickecb9cada2015-12-08 15:45:58 -070013961 "[managed] [other] [ll] [send] [cease] [isno] [def]") \
13962_(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]") \
13963_(l2_patch_add_del, \
13964 "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
13965 "enable | disable") \
13966_(mpls_ethernet_add_del_tunnel, \
13967 "tx <intfc> | tx_sw_if_index <n> dst <mac-addr>\n" \
13968 "adj <ip4-addr>/<mw> dst <mac-addr> [del]") \
13969_(mpls_ethernet_add_del_tunnel_2, \
13970 "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n" \
13971 "resolve-attempts <n> resolve-if-needed 0 | 1 [del]") \
13972_(sr_tunnel_add_del, \
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -070013973 "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n" \
13974 "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n" \
13975 "[policy <policy_name>]") \
13976_(sr_policy_add_del, \
13977 "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]") \
13978_(sr_multicast_map_add_del, \
13979 "address [ip6 multicast address] sr-policy [policy name] [del]") \
Ed Warnickecb9cada2015-12-08 15:45:58 -070013980_(classify_add_del_table, \
13981 "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n" \
13982 "[del] mask <mask-value>\n" \
13983 " [l2-miss-next | miss-next | acl-miss-next] <name|nn>") \
13984_(classify_add_del_session, \
Matus Fabian70e6a8d2016-06-20 08:10:42 -070013985 "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n" \
13986 " table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n" \
13987 " [l3 [ip4|ip6]]") \
Ed Warnickecb9cada2015-12-08 15:45:58 -070013988_(classify_set_interface_ip_table, \
13989 "<intfc> | sw_if_index <nn> table <nn>") \
13990_(classify_set_interface_l2_tables, \
13991 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
13992 " [other-table <nn>]") \
13993_(get_node_index, "node <node-name") \
13994_(add_node_next, "node <node-name> next <next-node-name>") \
13995_(l2tpv3_create_tunnel, \
13996 "client_address <ip6-addr> our_address <ip6-addr>\n" \
13997 "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
13998 "[remote_cookie <nn>]\n[l2-sublayer-preset]\n") \
13999_(l2tpv3_set_tunnel_cookies, \
14000 "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n" \
14001 "[new_remote_cookie <nn>]\n") \
14002_(l2tpv3_interface_enable_disable, \
14003 "<intfc> | sw_if_index <nn> enable | disable") \
14004_(l2tpv3_set_lookup_key, \
14005 "lookup_v6_src | lookup_v6_dst | lookup_session_id") \
14006_(sw_if_l2tpv3_tunnel_dump, "") \
14007_(vxlan_add_del_tunnel, \
Chris Luke404be662016-05-27 12:11:24 -040014008 "src <ip-addr> dst <ip-addr> vni <vni> [encap-vrf-id <nn>]\n" \
Ed Warnickecb9cada2015-12-08 15:45:58 -070014009 " [decap-next l2|ip4|ip6] [del]") \
Dave Wallace60231f32015-12-17 21:04:30 -050014010_(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
Chris Luke27fe48f2016-04-28 13:44:38 -040014011_(gre_add_del_tunnel, \
14012 "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [del]\n") \
14013_(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
Ed Warnickecb9cada2015-12-08 15:45:58 -070014014_(l2_fib_clear_table, "") \
14015_(l2_interface_efp_filter, "sw_if_index <nn> enable | disable") \
14016_(l2_interface_vlan_tag_rewrite, \
14017 "<intfc> | sw_if_index <nn> \n" \
14018 "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n" \
14019 "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>") \
14020_(create_vhost_user_if, \
Pierre Pfisteref65cb02016-02-19 13:52:44 +000014021 "socket <filename> [server] [renumber <dev_instance>] " \
14022 "[mac <mac_address>]") \
Ed Warnickecb9cada2015-12-08 15:45:58 -070014023_(modify_vhost_user_if, \
14024 "<intfc> | sw_if_index <nn> socket <filename>\n" \
14025 "[server] [renumber <dev_instance>]") \
14026_(delete_vhost_user_if, "<intfc> | sw_if_index <nn>") \
14027_(sw_interface_vhost_user_dump, "") \
14028_(show_version, "") \
Hongjun Ni0e06e2b2016-05-30 19:45:51 +080014029_(vxlan_gpe_add_del_tunnel, \
14030 "local <addr> remote <addr> vni <nn>\n" \
14031 "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]" \
14032 "[next-ethernet] [next-nsh]\n") \
14033_(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
Ed Warnickecb9cada2015-12-08 15:45:58 -070014034_(l2_fib_table_dump, "bd_id <bridge-domain-id>") \
Ed Warnickecb9cada2015-12-08 15:45:58 -070014035_(interface_name_renumber, \
14036 "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>") \
14037_(input_acl_set_interface, \
14038 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
14039 " [l2-table <nn>] [del]") \
14040_(want_ip4_arp_events, "address <ip4-address> [del]") \
14041_(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)") \
14042_(ip_dump, "ipv4 | ipv6") \
14043_(ipsec_spd_add_del, "spd_id <n> [del]") \
14044_(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n" \
14045 " spid_id <n> ") \
14046_(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n" \
14047 " crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n" \
14048 " integ_alg <alg> integ_key <hex>") \
14049_(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n" \
14050 " (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n" \
14051 " laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
14052 " [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
14053_(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>") \
Matus Fabiane5f42fe2016-04-08 11:18:08 +020014054_(ikev2_profile_add_del, "name <profile_name> [del]") \
14055_(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n" \
14056 "(auth_data 0x<data> | auth_data <data>)") \
14057_(ikev2_profile_set_id, "name <profile_name> id_type <type>\n" \
14058 "(id_data 0x<data> | id_data <data>) (local|remote)") \
14059_(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n" \
14060 "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
14061 "(local|remote)") \
14062_(ikev2_set_local_key, "file <absolute_file_path>") \
Ed Warnickecb9cada2015-12-08 15:45:58 -070014063_(delete_loopback,"sw_if_index <nn>") \
14064_(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
14065_(map_add_domain, \
14066 "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> " \
14067 "ip6-src <ip6addr> " \
14068 "ea-bits-len <n> psid-offset <n> psid-len <n>") \
14069_(map_del_domain, "index <n>") \
14070_(map_add_del_rule, \
14071 "index <n> psid <n> dst <ip6addr> [del]") \
14072_(map_domain_dump, "") \
14073_(map_rule_dump, "index <map-domain>") \
14074_(want_interface_events, "enable|disable") \
14075_(want_stats,"enable|disable") \
Dave Barachc07bf5d2016-02-17 17:52:26 -050014076_(get_first_msg_id, "client <name>") \
14077_(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
14078_(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n" \
Dave Barachb44e9bc2016-02-19 09:06:23 -050014079 "fib-id <nn> [ip4][ip6][default]") \
Pavel Kotucek00bbf272016-03-03 13:27:11 +010014080_(get_node_graph, " ") \
Shwetha20a64f52016-03-25 10:55:01 +000014081_(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>") \
14082_(trace_profile_add, "id <nn> trace-type <0x1f|0x3|0x9|0x11|0x19> " \
14083 "trace-elts <nn> trace-tsp <0|1|2|3> node-id <node id in hex> " \
14084 "app-data <app_data in hex> [pow] [ppc <encap|decap>]") \
14085_(trace_profile_apply, "id <nn> <ip6-address>/<width>" \
14086 " vrf_id <nn> add | pop | none") \
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020014087_(trace_profile_del, "") \
Andrej Kozemcaka8691752016-07-27 10:33:38 +020014088_(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
14089 " sw_if_index <sw_if_index> p <priority> " \
14090 "w <weight>] [del]") \
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020014091_(lisp_add_del_locator, "locator-set <locator_name> " \
14092 "iface <intf> | sw_if_index <sw_if_index> " \
14093 "p <priority> w <weight> [del]") \
Andrej Kozemcakd9831182016-06-20 08:47:57 +020014094_(lisp_add_del_local_eid,"vni <vni> eid " \
14095 "<ipv4|ipv6>/<prefix> | <L2 address> " \
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020014096 "locator-set <locator_name> [del]") \
Florin Coras429e7952016-08-02 02:31:03 +020014097_(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
14098 "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]") \
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020014099_(lisp_add_del_map_resolver, "<ip4|6-addr> [del]") \
Florin Coras577c3552016-04-21 00:45:40 +020014100_(lisp_gpe_enable_disable, "enable|disable") \
Filip Tehlar46d4e362016-05-09 09:39:26 +020014101_(lisp_enable_disable, "enable|disable") \
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020014102_(lisp_gpe_add_del_iface, "up|down") \
Andrej Kozemcak438109d2016-07-22 12:54:12 +020014103_(lisp_add_del_remote_mapping, "add|del vni <vni> deid <dest-eid> " \
14104 "rloc <locator> p <prio> " \
Filip Tehlar4d5cabd2016-07-07 15:40:36 +020014105 "w <weight> [rloc <loc> ... ] " \
Andrej Kozemcak438109d2016-07-22 12:54:12 +020014106 "action <action> [del-all]") \
Filip Tehlar4d5cabd2016-07-07 15:40:36 +020014107_(lisp_add_del_adjacency, "add|del vni <vni> deid <dest-eid> seid " \
14108 "<src-eid> rloc <locator> p <prio> w <weight>"\
14109 "[rloc <loc> ... ] action <action>") \
Filip Tehlar53f09e32016-05-19 14:25:44 +020014110_(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del") \
Andrej Kozemcakb6e4d392016-06-14 13:55:57 +020014111_(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]") \
Filip Tehlar324112f2016-06-02 16:07:38 +020014112_(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>") \
Andrej Kozemcakd9831182016-06-20 08:47:57 +020014113_(lisp_locator_set_dump, "[locator-set-index <ls-index> | " \
14114 "locator-set <loc-set-name>] [local | remote]")\
Andrej Kozemcak6cc6f912016-07-13 13:01:01 +020014115_(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] " \
14116 "[local] | [remote]") \
Filip Tehlar2f653d02016-07-13 13:17:15 +020014117_(lisp_eid_table_map_dump, "") \
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020014118_(lisp_gpe_tunnel_dump, "") \
Andrej Kozemcaka9edd852016-05-02 12:14:33 +020014119_(lisp_map_resolver_dump, "") \
Andrej Kozemcakd9831182016-06-20 08:47:57 +020014120_(show_lisp_status, "") \
Andrej Kozemcakb6e4d392016-06-14 13:55:57 +020014121_(lisp_get_map_request_itr_rlocs, "") \
Andrej Kozemcak914f91b2016-07-18 13:55:37 +020014122_(show_lisp_pitr, "") \
Matus Fabian8a95a482016-05-06 15:14:13 +020014123_(af_packet_create, "name <host interface name> [hw_addr <mac>]") \
Matus Fabian65fcd4d2016-05-13 05:44:48 -070014124_(af_packet_delete, "name <host interface name>") \
Matus Fabian82e29c42016-05-11 04:49:46 -070014125_(policer_add_del, "name <policer name> <params> [del]") \
Matus Fabiane8554802016-05-18 23:40:37 -070014126_(policer_dump, "[name <policer name>]") \
Matus Fabian70e6a8d2016-06-20 08:10:42 -070014127_(policer_classify_set_interface, \
14128 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
14129 " [l2-table <nn>] [del]") \
14130_(policer_classify_dump, "type [ip4|ip6|l2]") \
Matus Fabian82e29c42016-05-11 04:49:46 -070014131_(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] " \
14132 "[master|slave]") \
marek zavodsky2c21a9a2016-06-21 05:35:16 +020014133_(netmap_delete, "name <interface name>") \
14134_(mpls_gre_tunnel_dump, "tunnel_index <tunnel-id>") \
14135_(mpls_eth_tunnel_dump, "tunnel_index <tunnel-id>") \
14136_(mpls_fib_encap_dump, "") \
Pavel Kotucek20c90f72016-06-07 14:44:26 +020014137_(mpls_fib_decap_dump, "") \
14138_(classify_table_ids, "") \
14139_(classify_table_by_interface, "sw_if_index <sw_if_index>") \
14140_(classify_table_info, "table_id <nn>") \
Juraj Slobodaac645ad2016-07-07 00:18:57 -070014141_(classify_session_dump, "table_id <nn>") \
14142_(ipfix_enable, "collector_address <ip4> [collector_port <nn>] " \
14143 "src_address <ip4> [fib_id <nn>] [path_mtu <nn>] " \
14144 "[template_interval <nn>]") \
Keith Burns (alagalah)c61080e2016-07-19 14:47:43 -070014145_(ipfix_dump, "") \
Pavel Kotucek9e6ed6e2016-07-12 10:18:26 +020014146_(get_next_index, "node-name <node-name> next-node-name <node-name>") \
14147_(pg_create_interface, "if_id <nn>") \
14148_(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]") \
Dave Barach6f9bca22016-04-30 10:25:32 -040014149_(pg_enable_disable, "[stream <id>] disable") \
14150_(ip_source_and_port_range_check_add_del, \
14151 "<ip-addr>/<mask> range <nn>-<nn> vrf <id>") \
14152_(ip_source_and_port_range_check_interface_add_del, \
Keith Burns (alagalah)9d3a8792016-08-02 11:57:37 -070014153 "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]" \
14154 "[udp-in-vrf <id>] [udp-out-vrf <id>]")
Ed Warnickecb9cada2015-12-08 15:45:58 -070014155
14156/* List of command functions, CLI names map directly to functions */
14157#define foreach_cli_function \
14158_(comment, "usage: comment <ignore-rest-of-line>") \
14159_(dump_interface_table, "usage: dump_interface_table") \
14160_(dump_sub_interface_table, "usage: dump_sub_interface_table") \
14161_(dump_ipv4_table, "usage: dump_ipv4_table") \
14162_(dump_ipv6_table, "usage: dump_ipv6_table") \
14163_(dump_stats_table, "usage: dump_stats_table") \
14164_(dump_macro_table, "usage: dump_macro_table ") \
Dave Barachb44e9bc2016-02-19 09:06:23 -050014165_(dump_node_table, "usage: dump_node_table") \
Ed Warnickecb9cada2015-12-08 15:45:58 -070014166_(echo, "usage: echo <message>") \
14167_(exec, "usage: exec <vpe-debug-CLI-command>") \
14168_(help, "usage: help") \
14169_(q, "usage: quit") \
14170_(quit, "usage: quit") \
Dave Barachb44e9bc2016-02-19 09:06:23 -050014171_(search_node_table, "usage: search_node_table <name>...") \
Ed Warnickecb9cada2015-12-08 15:45:58 -070014172_(set, "usage: set <variable-name> <value>") \
14173_(script, "usage: script <file-name>") \
14174_(unset, "usage: unset <variable-name>")
14175
14176#define _(N,n) \
14177 static void vl_api_##n##_t_handler_uni \
14178 (vl_api_##n##_t * mp) \
14179 { \
14180 vat_main_t * vam = &vat_main; \
14181 if (vam->json_output) { \
14182 vl_api_##n##_t_handler_json(mp); \
14183 } else { \
14184 vl_api_##n##_t_handler(mp); \
14185 } \
14186 }
14187foreach_vpe_api_reply_msg;
14188#undef _
14189
14190void vat_api_hookup (vat_main_t *vam)
14191{
14192#define _(N,n) \
14193 vl_msg_api_set_handlers(VL_API_##N, #n, \
14194 vl_api_##n##_t_handler_uni, \
14195 vl_noop_handler, \
14196 vl_api_##n##_t_endian, \
14197 vl_api_##n##_t_print, \
Hongjun Ni11bfc2f2016-07-22 18:19:19 +080014198 sizeof(vl_api_##n##_t), 1);
Ed Warnickecb9cada2015-12-08 15:45:58 -070014199 foreach_vpe_api_reply_msg;
14200#undef _
14201
14202 vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
14203
Hongjun Ni11bfc2f2016-07-22 18:19:19 +080014204 vam->sw_if_index_by_interface_name =
Ed Warnickecb9cada2015-12-08 15:45:58 -070014205 hash_create_string (0, sizeof (uword));
14206
Hongjun Ni11bfc2f2016-07-22 18:19:19 +080014207 vam->function_by_name =
Ed Warnickecb9cada2015-12-08 15:45:58 -070014208 hash_create_string (0, sizeof(uword));
14209
Hongjun Ni11bfc2f2016-07-22 18:19:19 +080014210 vam->help_by_name =
Ed Warnickecb9cada2015-12-08 15:45:58 -070014211 hash_create_string (0, sizeof(uword));
14212
14213 /* API messages we can send */
14214#define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
14215 foreach_vpe_api_msg;
14216#undef _
14217
14218 /* Help strings */
14219#define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
14220 foreach_vpe_api_msg;
14221#undef _
14222
14223 /* CLI functions */
14224#define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
14225 foreach_cli_function;
14226#undef _
14227
14228 /* Help strings */
14229#define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
14230 foreach_cli_function;
14231#undef _
14232}
14233
14234#undef vl_api_version
14235#define vl_api_version(n,v) static u32 vpe_api_version = v;
Dave Barachaa6920e2016-06-27 09:25:13 -040014236#include <vpp-api/vpe.api.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070014237#undef vl_api_version
14238
Hongjun Ni11bfc2f2016-07-22 18:19:19 +080014239void vl_client_add_api_signatures (vl_api_memclnt_create_t *mp)
Ed Warnickecb9cada2015-12-08 15:45:58 -070014240{
Hongjun Ni11bfc2f2016-07-22 18:19:19 +080014241 /*
Ed Warnickecb9cada2015-12-08 15:45:58 -070014242 * Send the main API signature in slot 0. This bit of code must
14243 * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
14244 */
14245 mp->api_versions[0] = clib_host_to_net_u32 (vpe_api_version);
14246}