blob: 90c69a2cd66a7f6038654dee986dc7365fa71c89 [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>
Matus Fabian65fcd4d2016-05-13 05:44:48 -070048#include <vnet/policer/xlate.h>
Matus Fabian4ac74c92016-05-31 07:33:29 -070049#include <vnet/policer/policer.h>
Matus Fabian70e6a8d2016-06-20 08:10:42 -070050#include <vnet/policer/police.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070051
52#include "vat/json_format.h"
53
Pavel Kotucek9e6ed6e2016-07-12 10:18:26 +020054#include <sys/stat.h>
55
Ed Warnickecb9cada2015-12-08 15:45:58 -070056#define vl_typedefs /* define message structures */
Hongjun Ni11bfc2f2016-07-22 18:19:19 +080057#include <vpp-api/vpe_all_api_h.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070058#undef vl_typedefs
59
60/* declare message handlers for each api */
61
62#define vl_endianfun /* define message structures */
Hongjun Ni11bfc2f2016-07-22 18:19:19 +080063#include <vpp-api/vpe_all_api_h.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070064#undef vl_endianfun
65
66/* instantiate all the print functions we know about */
67#define vl_print(handle, ...)
68#define vl_printfun
Dave Barachaa6920e2016-06-27 09:25:13 -040069#include <vpp-api/vpe_all_api_h.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070070#undef vl_printfun
71
72uword unformat_sw_if_index (unformat_input_t * input, va_list * args)
73{
74 vat_main_t * vam = va_arg (*args, vat_main_t *);
75 u32 * result = va_arg (*args, u32 *);
76 u8 * if_name;
77 uword * p;
78
79 if (!unformat (input, "%s", &if_name))
80 return 0;
81
82 p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
83 if (p == 0)
84 return 0;
85 *result = p[0];
86 return 1;
87}
88
89/* Parse an IP4 address %d.%d.%d.%d. */
90uword unformat_ip4_address (unformat_input_t * input, va_list * args)
91{
92 u8 * result = va_arg (*args, u8 *);
93 unsigned a[4];
94
95 if (! unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
96 return 0;
97
98 if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
99 return 0;
100
101 result[0] = a[0];
102 result[1] = a[1];
103 result[2] = a[2];
104 result[3] = a[3];
105
106 return 1;
107}
108
109
110uword
111unformat_ethernet_address (unformat_input_t * input, va_list * args)
112{
113 u8 * result = va_arg (*args, u8 *);
114 u32 i, a[6];
115
116 if (! unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
117 &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
118 return 0;
119
120 /* Check range. */
121 for (i = 0; i < 6; i++)
122 if (a[i] >= (1 << 8))
123 return 0;
124
125 for (i = 0; i < 6; i++)
126 result[i] = a[i];
127
128 return 1;
129}
130
131/* Returns ethernet type as an int in host byte order. */
132uword
133unformat_ethernet_type_host_byte_order (unformat_input_t * input,
134 va_list * args)
135{
136 u16 * result = va_arg (*args, u16 *);
137 int type;
138
139 /* Numeric type. */
140 if (unformat (input, "0x%x", &type)
141 || unformat (input, "%d", &type))
142 {
143 if (type >= (1 << 16))
144 return 0;
145 *result = type;
146 return 1;
147 }
148 return 0;
149}
150
151/* Parse an IP6 address. */
152uword unformat_ip6_address (unformat_input_t * input, va_list * args)
153{
154 ip6_address_t * result = va_arg (*args, ip6_address_t *);
155 u16 hex_quads[8];
156 uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
157 uword c, n_colon, double_colon_index;
158
159 n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
160 double_colon_index = ARRAY_LEN (hex_quads);
161 while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
162 {
163 hex_digit = 16;
164 if (c >= '0' && c <= '9')
165 hex_digit = c - '0';
166 else if (c >= 'a' && c <= 'f')
167 hex_digit = c + 10 - 'a';
168 else if (c >= 'A' && c <= 'F')
169 hex_digit = c + 10 - 'A';
170 else if (c == ':' && n_colon < 2)
171 n_colon++;
172 else
173 {
174 unformat_put_input (input);
175 break;
176 }
177
178 /* Too many hex quads. */
179 if (n_hex_quads >= ARRAY_LEN (hex_quads))
180 return 0;
181
182 if (hex_digit < 16)
183 {
184 hex_quad = (hex_quad << 4) | hex_digit;
185
186 /* Hex quad must fit in 16 bits. */
187 if (n_hex_digits >= 4)
188 return 0;
189
190 n_colon = 0;
191 n_hex_digits++;
192 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +0800193
Ed Warnickecb9cada2015-12-08 15:45:58 -0700194 /* Save position of :: */
195 if (n_colon == 2)
196 {
197 /* More than one :: ? */
198 if (double_colon_index < ARRAY_LEN (hex_quads))
199 return 0;
200 double_colon_index = n_hex_quads;
201 }
202
203 if (n_colon > 0 && n_hex_digits > 0)
204 {
205 hex_quads[n_hex_quads++] = hex_quad;
206 hex_quad = 0;
207 n_hex_digits = 0;
208 }
209 }
210
211 if (n_hex_digits > 0)
212 hex_quads[n_hex_quads++] = hex_quad;
213
214 {
215 word i;
216
217 /* Expand :: to appropriate number of zero hex quads. */
218 if (double_colon_index < ARRAY_LEN (hex_quads))
219 {
220 word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
221
222 for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
223 hex_quads[n_zero + i] = hex_quads[i];
224
225 for (i = 0; i < n_zero; i++)
226 hex_quads[double_colon_index + i] = 0;
227
228 n_hex_quads = ARRAY_LEN (hex_quads);
229 }
230
231 /* Too few hex quads given. */
232 if (n_hex_quads < ARRAY_LEN (hex_quads))
233 return 0;
234
235 for (i = 0; i < ARRAY_LEN (hex_quads); i++)
236 result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
237
238 return 1;
239 }
240}
241
242uword
243unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
244{
Dave Barachbfdedbd2016-01-20 09:11:55 -0500245#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -0700246 u32 * r = va_arg (*args, u32 *);
247
248 if (0) ;
249#define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
250 foreach_ipsec_policy_action
251#undef _
252 else
253 return 0;
254 return 1;
Dave Barachbfdedbd2016-01-20 09:11:55 -0500255#else
256 return 0;
257#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -0700258}
259
260uword
261unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
262{
Dave Barachbfdedbd2016-01-20 09:11:55 -0500263#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -0700264 u32 * r = va_arg (*args, u32 *);
265
266 if (0) ;
267#define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
268 foreach_ipsec_crypto_alg
269#undef _
270 else
271 return 0;
272 return 1;
Dave Barachbfdedbd2016-01-20 09:11:55 -0500273#else
274 return 0;
275#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -0700276}
277
278u8 *
279format_ipsec_crypto_alg (u8 * s, va_list * args)
280{
Dave Barachbfdedbd2016-01-20 09:11:55 -0500281#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -0700282 u32 i = va_arg (*args, u32);
283 u8 * t = 0;
284
285 switch (i)
286 {
287#define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
288 foreach_ipsec_crypto_alg
289#undef _
290 default:
291 return format (s, "unknown");
292 }
293 return format (s, "%s", t);
Dave Barachbfdedbd2016-01-20 09:11:55 -0500294#else
295 return format (s, "Unimplemented");
296#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -0700297}
298
299uword
300unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
301{
Dave Barachbfdedbd2016-01-20 09:11:55 -0500302#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -0700303 u32 * r = va_arg (*args, u32 *);
304
305 if (0) ;
306#define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
307 foreach_ipsec_integ_alg
308#undef _
309 else
310 return 0;
311 return 1;
Dave Barachbfdedbd2016-01-20 09:11:55 -0500312#else
313 return 0;
314#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -0700315}
316
317u8 *
318format_ipsec_integ_alg (u8 * s, va_list * args)
319{
Dave Barachbfdedbd2016-01-20 09:11:55 -0500320#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -0700321 u32 i = va_arg (*args, u32);
322 u8 * t = 0;
323
324 switch (i)
325 {
326#define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
327 foreach_ipsec_integ_alg
328#undef _
329 default:
330 return format (s, "unknown");
331 }
332 return format (s, "%s", t);
Dave Barachbfdedbd2016-01-20 09:11:55 -0500333#else
334 return format (s, "Unsupported");
335#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -0700336}
337
Matus Fabiane5f42fe2016-04-08 11:18:08 +0200338uword
339unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
340{
341#if DPDK > 0
342 u32 * r = va_arg (*args, u32 *);
343
344 if (0) ;
345#define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
346 foreach_ikev2_auth_method
347#undef _
348 else
349 return 0;
350 return 1;
351#else
352 return 0;
353#endif
354}
355
356uword
357unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
358{
359#if DPDK > 0
360 u32 * r = va_arg (*args, u32 *);
361
362 if (0) ;
363#define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
364 foreach_ikev2_id_type
365#undef _
366 else
367 return 0;
368 return 1;
369#else
370 return 0;
371#endif
372}
373
Matus Fabian65fcd4d2016-05-13 05:44:48 -0700374uword
375unformat_policer_rate_type (unformat_input_t * input, va_list * args)
376{
377 u8 * r = va_arg (*args, u8 *);
378
379 if (unformat (input, "kbps"))
380 *r = SSE2_QOS_RATE_KBPS;
381 else if (unformat(input, "pps"))
382 *r = SSE2_QOS_RATE_PPS;
383 else
384 return 0;
385 return 1;
386}
387
388uword
389unformat_policer_round_type (unformat_input_t * input, va_list * args)
390{
391 u8 * r = va_arg (*args, u8 *);
392
393 if (unformat(input, "closest"))
394 *r = SSE2_QOS_ROUND_TO_CLOSEST;
395 else if (unformat (input, "up"))
396 *r = SSE2_QOS_ROUND_TO_UP;
397 else if (unformat (input, "down"))
398 *r = SSE2_QOS_ROUND_TO_DOWN;
399 else
400 return 0;
401 return 1;
402}
403
404uword
405unformat_policer_type (unformat_input_t * input, va_list * args)
406{
407 u8 * r = va_arg (*args, u8 *);
408
409 if (unformat (input, "1r2c"))
410 *r = SSE2_QOS_POLICER_TYPE_1R2C;
411 else if (unformat (input, "1r3c"))
412 *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
413 else if (unformat (input, "2r3c-2698"))
414 *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
415 else if (unformat (input, "2r3c-4115"))
416 *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
417 else if (unformat (input, "2r3c-mef5cf1"))
418 *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
419 else
420 return 0;
421 return 1;
422}
423
Matus Fabian4ac74c92016-05-31 07:33:29 -0700424uword
425unformat_dscp (unformat_input_t * input, va_list * va)
426{
427 u8 * r = va_arg (*va, u8 *);
428
429 if (0) ;
430#define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
431 foreach_vnet_dscp
432#undef _
433 else
434 return 0;
435 return 1;
436}
437
438uword
439unformat_policer_action_type (unformat_input_t * input, va_list * va)
440{
441 sse2_qos_pol_action_params_st * a
442 = va_arg (*va, sse2_qos_pol_action_params_st *);
443
444 if (unformat (input, "drop"))
445 a->action_type = SSE2_QOS_ACTION_DROP;
446 else if (unformat (input, "transmit"))
447 a->action_type = SSE2_QOS_ACTION_TRANSMIT;
448 else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
449 a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
450 else
451 return 0;
452 return 1;
453}
454
Matus Fabian70e6a8d2016-06-20 08:10:42 -0700455uword
456unformat_classify_table_type (unformat_input_t * input, va_list * va)
457{
458 u32 * r = va_arg (*va, u32 *);
459 u32 tid;
460
461 if (unformat (input, "ip4"))
462 tid = POLICER_CLASSIFY_TABLE_IP4;
463 else if (unformat (input, "ip6"))
464 tid = POLICER_CLASSIFY_TABLE_IP6;
465 else if (unformat (input, "l2"))
466 tid = POLICER_CLASSIFY_TABLE_L2;
467 else
468 return 0;
469
470 *r = tid;
471 return 1;
472}
473
Ed Warnickecb9cada2015-12-08 15:45:58 -0700474u8 * format_ip4_address (u8 * s, va_list * args)
475{
476 u8 * a = va_arg (*args, u8 *);
477 return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
478}
479
480u8 * format_ip6_address (u8 * s, va_list * args)
481{
482 ip6_address_t * a = va_arg (*args, ip6_address_t *);
483 u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
484
485 i_max_n_zero = ARRAY_LEN (a->as_u16);
486 max_n_zeros = 0;
487 i_first_zero = i_max_n_zero;
488 n_zeros = 0;
489 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
490 {
491 u32 is_zero = a->as_u16[i] == 0;
492 if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
493 {
494 i_first_zero = i;
495 n_zeros = 0;
496 }
497 n_zeros += is_zero;
498 if ((! is_zero && n_zeros > max_n_zeros)
499 || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
500 {
501 i_max_n_zero = i_first_zero;
502 max_n_zeros = n_zeros;
503 i_first_zero = ARRAY_LEN (a->as_u16);
504 n_zeros = 0;
505 }
506 }
507
508 last_double_colon = 0;
509 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
510 {
511 if (i == i_max_n_zero && max_n_zeros > 1)
512 {
513 s = format (s, "::");
514 i += max_n_zeros - 1;
515 last_double_colon = 1;
516 }
517 else
518 {
519 s = format (s, "%s%x",
520 (last_double_colon || i == 0) ? "" : ":",
521 clib_net_to_host_u16 (a->as_u16[i]));
522 last_double_colon = 0;
523 }
524 }
525
526 return s;
527}
528
Chris Luke99cb3352016-04-26 10:49:53 -0400529/* Format an IP46 address. */
530u8 * format_ip46_address (u8 * s, va_list * args)
531{
532 ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
Damjan Marion86be4872016-05-24 23:19:11 +0200533 ip46_type_t type = va_arg (*args, ip46_type_t);
534 int is_ip4 = 1;
535
536 switch (type)
537 {
538 case IP46_TYPE_ANY:
539 is_ip4 = ip46_address_is_ip4(ip46);
540 break;
541 case IP46_TYPE_IP4:
542 is_ip4 = 1;
543 break;
544 case IP46_TYPE_IP6:
545 is_ip4 = 0;
546 break;
547 }
548
549 return is_ip4 ?
Chris Luke99cb3352016-04-26 10:49:53 -0400550 format(s, "%U", format_ip4_address, &ip46->ip4):
551 format(s, "%U", format_ip6_address, &ip46->ip6);
552}
553
Ed Warnickecb9cada2015-12-08 15:45:58 -0700554u8 * format_ethernet_address (u8 * s, va_list * args)
555{
556 u8 * a = va_arg (*args, u8 *);
557
558 return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
559 a[0], a[1], a[2], a[3], a[4], a[5]);
560}
561
562void increment_v4_address (ip4_address_t * a)
563{
564 u32 v;
565
566 v = ntohl(a->as_u32) + 1;
567 a->as_u32 = ntohl(v);
568}
569
570void increment_v6_address (ip6_address_t * a)
571{
572 u64 v0, v1;
573
574 v0 = clib_net_to_host_u64 (a->as_u64[0]);
575 v1 = clib_net_to_host_u64 (a->as_u64[1]);
576
577 v1 += 1;
578 if (v1 == 0)
579 v0 += 1;
580 a->as_u64[0] = clib_net_to_host_u64 (v0);
581 a->as_u64[1] = clib_net_to_host_u64 (v1);
582}
583
Dave Barach41da02d2016-07-11 16:48:42 -0700584void increment_mac_address (u64 *mac)
585{
586 u64 tmp = *mac;
587
588 tmp = clib_net_to_host_u64(tmp);
589 tmp += 1<<16; /* skip unused (least significant) octets */
590 tmp = clib_host_to_net_u64 (tmp);
591 *mac = tmp;
592}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700593
Hongjun Ni11bfc2f2016-07-22 18:19:19 +0800594static void vl_api_create_loopback_reply_t_handler
Ed Warnickecb9cada2015-12-08 15:45:58 -0700595(vl_api_create_loopback_reply_t * mp)
596{
597 vat_main_t * vam = &vat_main;
598 i32 retval = ntohl(mp->retval);
599
600 vam->retval = retval;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700601 vam->regenerate_interface_table = 1;
Keith Burns (alagalah)802255c2016-06-13 16:56:04 -0700602 vam->sw_if_index = ntohl (mp->sw_if_index);
603 vam->result_ready = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700604}
605
606static void vl_api_create_loopback_reply_t_handler_json
607(vl_api_create_loopback_reply_t * mp)
608{
609 vat_main_t * vam = &vat_main;
610 vat_json_node_t node;
611
612 vat_json_init_object(&node);
613 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
614 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
615
616 vat_json_print(vam->ofp, &node);
617 vat_json_free(&node);
Keith Burns (alagalah)802255c2016-06-13 16:56:04 -0700618 vam->retval = ntohl(mp->retval);
619 vam->result_ready = 1;
620}
621
Hongjun Ni11bfc2f2016-07-22 18:19:19 +0800622static void vl_api_af_packet_create_reply_t_handler
Keith Burns (alagalah)802255c2016-06-13 16:56:04 -0700623(vl_api_af_packet_create_reply_t * mp)
624{
625 vat_main_t * vam = &vat_main;
626 i32 retval = ntohl(mp->retval);
627
628 vam->retval = retval;
629 vam->regenerate_interface_table = 1;
630 vam->sw_if_index = ntohl (mp->sw_if_index);
631 vam->result_ready = 1;
632}
633
634static void vl_api_af_packet_create_reply_t_handler_json
635(vl_api_af_packet_create_reply_t * mp)
636{
637 vat_main_t * vam = &vat_main;
638 vat_json_node_t node;
639
640 vat_json_init_object(&node);
641 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
642 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
643
644 vat_json_print(vam->ofp, &node);
645 vat_json_free(&node);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700646
647 vam->retval = ntohl(mp->retval);
648 vam->result_ready = 1;
649}
650
Hongjun Ni11bfc2f2016-07-22 18:19:19 +0800651static void vl_api_create_vlan_subif_reply_t_handler
Ed Warnickecb9cada2015-12-08 15:45:58 -0700652(vl_api_create_vlan_subif_reply_t * mp)
653{
654 vat_main_t * vam = &vat_main;
655 i32 retval = ntohl(mp->retval);
656
657 vam->retval = retval;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700658 vam->regenerate_interface_table = 1;
Keith Burns (alagalah)802255c2016-06-13 16:56:04 -0700659 vam->sw_if_index = ntohl (mp->sw_if_index);
660 vam->result_ready = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700661}
662
663static void vl_api_create_vlan_subif_reply_t_handler_json
664(vl_api_create_vlan_subif_reply_t * mp)
665{
666 vat_main_t * vam = &vat_main;
667 vat_json_node_t node;
668
669 vat_json_init_object(&node);
670 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
671 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
672
673 vat_json_print(vam->ofp, &node);
674 vat_json_free(&node);
675
676 vam->retval = ntohl(mp->retval);
677 vam->result_ready = 1;
678}
679
Hongjun Ni11bfc2f2016-07-22 18:19:19 +0800680static void vl_api_create_subif_reply_t_handler
Ed Warnickecb9cada2015-12-08 15:45:58 -0700681(vl_api_create_subif_reply_t * mp)
682{
683 vat_main_t * vam = &vat_main;
684 i32 retval = ntohl(mp->retval);
685
686 vam->retval = retval;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700687 vam->regenerate_interface_table = 1;
Keith Burns (alagalah)802255c2016-06-13 16:56:04 -0700688 vam->sw_if_index = ntohl (mp->sw_if_index);
689 vam->result_ready = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700690}
691
692static void vl_api_create_subif_reply_t_handler_json
693(vl_api_create_subif_reply_t * mp)
694{
695 vat_main_t * vam = &vat_main;
696 vat_json_node_t node;
697
698 vat_json_init_object(&node);
699 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
700 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
701
702 vat_json_print(vam->ofp, &node);
703 vat_json_free(&node);
704
705 vam->retval = ntohl(mp->retval);
706 vam->result_ready = 1;
707}
708
Hongjun Ni11bfc2f2016-07-22 18:19:19 +0800709static void vl_api_interface_name_renumber_reply_t_handler
Ed Warnickecb9cada2015-12-08 15:45:58 -0700710(vl_api_interface_name_renumber_reply_t * mp)
711{
712 vat_main_t * vam = &vat_main;
713 i32 retval = ntohl(mp->retval);
714
715 vam->retval = retval;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700716 vam->regenerate_interface_table = 1;
Keith Burns (alagalah)802255c2016-06-13 16:56:04 -0700717 vam->result_ready = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700718}
719
720static void vl_api_interface_name_renumber_reply_t_handler_json
721(vl_api_interface_name_renumber_reply_t * mp)
722{
723 vat_main_t * vam = &vat_main;
724 vat_json_node_t node;
725
726 vat_json_init_object(&node);
727 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
728
729 vat_json_print(vam->ofp, &node);
730 vat_json_free(&node);
731
732 vam->retval = ntohl(mp->retval);
733 vam->result_ready = 1;
734}
735
Hongjun Ni11bfc2f2016-07-22 18:19:19 +0800736/*
Ed Warnickecb9cada2015-12-08 15:45:58 -0700737 * Special-case: build the interface table, maintain
738 * the next loopback sw_if_index vbl.
739 */
740static void vl_api_sw_interface_details_t_handler
741(vl_api_sw_interface_details_t * mp)
742{
743 vat_main_t * vam = &vat_main;
744 u8 * s = format (0, "%s%c", mp->interface_name, 0);
745
Hongjun Ni11bfc2f2016-07-22 18:19:19 +0800746 hash_set_mem (vam->sw_if_index_by_interface_name, s,
Ed Warnickecb9cada2015-12-08 15:45:58 -0700747 ntohl(mp->sw_if_index));
748
749 /* In sub interface case, fill the sub interface table entry */
750 if (mp->sw_if_index != mp->sup_sw_if_index) {
751 sw_interface_subif_t * sub = NULL;
752
753 vec_add2(vam->sw_if_subif_table, sub, 1);
754
755 vec_validate(sub->interface_name, strlen((char *)s) + 1);
756 strncpy((char *)sub->interface_name, (char *)s,
757 vec_len(sub->interface_name));
758 sub->sw_if_index = ntohl(mp->sw_if_index);
759 sub->sub_id = ntohl(mp->sub_id);
760
761 sub->sub_dot1ad = mp->sub_dot1ad;
762 sub->sub_number_of_tags = mp->sub_number_of_tags;
763 sub->sub_outer_vlan_id = ntohs(mp->sub_outer_vlan_id);
764 sub->sub_inner_vlan_id = ntohs(mp->sub_inner_vlan_id);
765 sub->sub_exact_match = mp->sub_exact_match;
766 sub->sub_default = mp->sub_default;
767 sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
768 sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
769
770 /* vlan tag rewrite */
771 sub->vtr_op = ntohl(mp->vtr_op);
772 sub->vtr_push_dot1q = ntohl(mp->vtr_push_dot1q);
773 sub->vtr_tag1 = ntohl(mp->vtr_tag1);
774 sub->vtr_tag2 = ntohl(mp->vtr_tag2);
775 }
776}
777
778static void vl_api_sw_interface_details_t_handler_json
779(vl_api_sw_interface_details_t * mp)
780{
781 vat_main_t * vam = &vat_main;
782 vat_json_node_t *node = NULL;
783
784 if (VAT_JSON_ARRAY != vam->json_tree.type) {
785 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
786 vat_json_init_array(&vam->json_tree);
787 }
788 node = vat_json_array_add(&vam->json_tree);
789
790 vat_json_init_object(node);
791 vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
792 vat_json_object_add_uint(node, "sup_sw_if_index", ntohl(mp->sup_sw_if_index));
793 vat_json_object_add_uint(node, "l2_address_length", ntohl(mp->l2_address_length));
794 vat_json_object_add_bytes(node, "l2_address", mp->l2_address, sizeof(mp->l2_address));
795 vat_json_object_add_string_copy(node, "interface_name", mp->interface_name);
796 vat_json_object_add_uint(node, "admin_up_down", mp->admin_up_down);
797 vat_json_object_add_uint(node, "link_up_down", mp->link_up_down);
798 vat_json_object_add_uint(node, "link_duplex", mp->link_duplex);
799 vat_json_object_add_uint(node, "link_speed", mp->link_speed);
Pavel84e4ffe2016-02-17 15:10:04 +0100800 vat_json_object_add_uint(node, "mtu", ntohs(mp->link_mtu));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700801 vat_json_object_add_uint(node, "sub_id", ntohl(mp->sub_id));
802 vat_json_object_add_uint(node, "sub_dot1ad", mp->sub_dot1ad);
803 vat_json_object_add_uint(node, "sub_number_of_tags", mp->sub_number_of_tags);
804 vat_json_object_add_uint(node, "sub_outer_vlan_id", ntohs(mp->sub_outer_vlan_id));
805 vat_json_object_add_uint(node, "sub_inner_vlan_id", ntohs(mp->sub_inner_vlan_id));
806 vat_json_object_add_uint(node, "sub_exact_match", mp->sub_exact_match);
807 vat_json_object_add_uint(node, "sub_default", mp->sub_default);
808 vat_json_object_add_uint(node, "sub_outer_vlan_id_any", mp->sub_outer_vlan_id_any);
809 vat_json_object_add_uint(node, "sub_inner_vlan_id_any", mp->sub_inner_vlan_id_any);
810 vat_json_object_add_uint(node, "vtr_op", ntohl(mp->vtr_op));
811 vat_json_object_add_uint(node, "vtr_push_dot1q", ntohl(mp->vtr_push_dot1q));
812 vat_json_object_add_uint(node, "vtr_tag1", ntohl(mp->vtr_tag1));
813 vat_json_object_add_uint(node, "vtr_tag2", ntohl(mp->vtr_tag2));
814}
815
816static void vl_api_sw_interface_set_flags_t_handler
817(vl_api_sw_interface_set_flags_t * mp)
818{
819 vat_main_t * vam = &vat_main;
820 if (vam->interface_event_display)
821 errmsg ("interface flags: sw_if_index %d %s %s\n",
822 ntohl(mp->sw_if_index),
823 mp->admin_up_down ? "admin-up" : "admin-down",
824 mp->link_up_down ? "link-up" : "link-down");
825}
826
827static void vl_api_sw_interface_set_flags_t_handler_json
828(vl_api_sw_interface_set_flags_t * mp)
829{
830 /* JSON output not supported */
831}
832
Pavel Kotucek00bbf272016-03-03 13:27:11 +0100833static void vl_api_cli_reply_t_handler
Ed Warnickecb9cada2015-12-08 15:45:58 -0700834(vl_api_cli_reply_t * mp)
835{
836 vat_main_t * vam = &vat_main;
837 i32 retval = ntohl(mp->retval);
838
839 vam->retval = retval;
840 vam->shmem_result = (u8 *) mp->reply_in_shmem;
841 vam->result_ready = 1;
842}
843
844static void vl_api_cli_reply_t_handler_json
845(vl_api_cli_reply_t * mp)
846{
847 vat_main_t * vam = &vat_main;
848 vat_json_node_t node;
Dave Barachb44e9bc2016-02-19 09:06:23 -0500849 api_main_t * am = &api_main;
850 void * oldheap;
851 u8 * reply;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700852
853 vat_json_init_object(&node);
854 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
Hongjun Ni11bfc2f2016-07-22 18:19:19 +0800855 vat_json_object_add_uint(&node, "reply_in_shmem",
Dave Barachb44e9bc2016-02-19 09:06:23 -0500856 ntohl(mp->reply_in_shmem));
857 /* Toss the shared-memory original... */
858 pthread_mutex_lock (&am->vlib_rp->mutex);
859 oldheap = svm_push_data_heap (am->vlib_rp);
860
861 reply = (u8 *)(mp->reply_in_shmem);
862 vec_free (reply);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +0800863
Dave Barachb44e9bc2016-02-19 09:06:23 -0500864 svm_pop_heap (oldheap);
865 pthread_mutex_unlock (&am->vlib_rp->mutex);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700866
867 vat_json_print(vam->ofp, &node);
868 vat_json_free(&node);
869
870 vam->retval = ntohl(mp->retval);
871 vam->result_ready = 1;
872}
873
874static void vl_api_classify_add_del_table_reply_t_handler
875(vl_api_classify_add_del_table_reply_t * mp)
876{
877 vat_main_t * vam = &vat_main;
878 i32 retval = ntohl(mp->retval);
879 if (vam->async_mode) {
880 vam->async_errors += (retval < 0);
881 } else {
882 vam->retval = retval;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +0800883 if (retval == 0 &&
Ed Warnickecb9cada2015-12-08 15:45:58 -0700884 ((mp->new_table_index != 0xFFFFFFFF) ||
885 (mp->skip_n_vectors != 0xFFFFFFFF) ||
886 (mp->match_n_vectors != 0xFFFFFFFF)))
Hongjun Ni11bfc2f2016-07-22 18:19:19 +0800887 /*
Ed Warnickecb9cada2015-12-08 15:45:58 -0700888 * Note: this is just barely thread-safe, depends on
889 * the main thread spinning waiting for an answer...
890 */
891 errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d\n",
892 ntohl(mp->new_table_index),
893 ntohl(mp->skip_n_vectors), ntohl(mp->match_n_vectors));
Keith Burns (alagalah)802255c2016-06-13 16:56:04 -0700894 vam->result_ready = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700895 }
896}
897
898static void vl_api_classify_add_del_table_reply_t_handler_json
899(vl_api_classify_add_del_table_reply_t * mp)
900{
901 vat_main_t * vam = &vat_main;
902 vat_json_node_t node;
903
904 vat_json_init_object(&node);
905 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
906 vat_json_object_add_uint(&node, "new_table_index", ntohl(mp->new_table_index));
907 vat_json_object_add_uint(&node, "skip_n_vectors", ntohl(mp->skip_n_vectors));
908 vat_json_object_add_uint(&node, "match_n_vectors", ntohl(mp->match_n_vectors));
909
910 vat_json_print(vam->ofp, &node);
911 vat_json_free(&node);
912
913 vam->retval = ntohl(mp->retval);
914 vam->result_ready = 1;
915}
916
917static void vl_api_get_node_index_reply_t_handler
918(vl_api_get_node_index_reply_t * mp)
919{
920 vat_main_t * vam = &vat_main;
921 i32 retval = ntohl(mp->retval);
922 if (vam->async_mode) {
923 vam->async_errors += (retval < 0);
924 } else {
925 vam->retval = retval;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700926 if (retval == 0)
927 errmsg ("node index %d\n", ntohl(mp->node_index));
Keith Burns (alagalah)802255c2016-06-13 16:56:04 -0700928 vam->result_ready = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700929 }
930}
931
932static void vl_api_get_node_index_reply_t_handler_json
933(vl_api_get_node_index_reply_t * mp)
934{
935 vat_main_t * vam = &vat_main;
936 vat_json_node_t node;
937
938 vat_json_init_object(&node);
939 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
940 vat_json_object_add_uint(&node, "node_index", ntohl(mp->node_index));
941
942 vat_json_print(vam->ofp, &node);
943 vat_json_free(&node);
944
945 vam->retval = ntohl(mp->retval);
946 vam->result_ready = 1;
947}
948
Keith Burns (alagalah)c61080e2016-07-19 14:47:43 -0700949static void vl_api_get_next_index_reply_t_handler
950(vl_api_get_next_index_reply_t * mp)
951{
952 vat_main_t * vam = &vat_main;
953 i32 retval = ntohl(mp->retval);
954 if (vam->async_mode) {
955 vam->async_errors += (retval < 0);
956 } else {
957 vam->retval = retval;
958 if (retval == 0)
959 errmsg ("next node index %d\n", ntohl(mp->next_index));
960 vam->result_ready = 1;
961 }
962}
963
964static void vl_api_get_next_index_reply_t_handler_json
965(vl_api_get_next_index_reply_t * mp)
966{
967 vat_main_t * vam = &vat_main;
968 vat_json_node_t node;
969
970 vat_json_init_object(&node);
971 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
972 vat_json_object_add_uint(&node, "next_index", ntohl(mp->next_index));
973
974 vat_json_print(vam->ofp, &node);
975 vat_json_free(&node);
976
977 vam->retval = ntohl(mp->retval);
978 vam->result_ready = 1;
979}
980
Ed Warnickecb9cada2015-12-08 15:45:58 -0700981static void vl_api_add_node_next_reply_t_handler
982(vl_api_add_node_next_reply_t * mp)
983{
984 vat_main_t * vam = &vat_main;
985 i32 retval = ntohl(mp->retval);
986 if (vam->async_mode) {
987 vam->async_errors += (retval < 0);
988 } else {
989 vam->retval = retval;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700990 if (retval == 0)
991 errmsg ("next index %d\n", ntohl(mp->next_index));
Keith Burns (alagalah)802255c2016-06-13 16:56:04 -0700992 vam->result_ready = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700993 }
994}
995
996static void vl_api_add_node_next_reply_t_handler_json
997(vl_api_add_node_next_reply_t * mp)
998{
999 vat_main_t * vam = &vat_main;
1000 vat_json_node_t node;
1001
1002 vat_json_init_object(&node);
1003 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1004 vat_json_object_add_uint(&node, "next_index", ntohl(mp->next_index));
1005
1006 vat_json_print(vam->ofp, &node);
1007 vat_json_free(&node);
1008
1009 vam->retval = ntohl(mp->retval);
1010 vam->result_ready = 1;
1011}
1012
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08001013static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler
Ed Warnickecb9cada2015-12-08 15:45:58 -07001014(vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
1015{
1016 vat_main_t * vam = &vat_main;
1017 i32 retval = ntohl(mp->retval);
1018 u32 sw_if_index = ntohl(mp->tunnel_sw_if_index);
1019
1020 if (retval >= 0 && sw_if_index != (u32)~0) {
1021 errmsg ("tunnel_sw_if_index %d\n", sw_if_index);
1022 }
1023 vam->retval = retval;
1024 vam->result_ready = 1;
1025}
1026
1027static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler_json
1028(vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
1029{
1030 vat_main_t * vam = &vat_main;
1031 vat_json_node_t node;
1032
1033 vat_json_init_object(&node);
1034 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1035 vat_json_object_add_uint(&node, "tunnel_sw_if_index", ntohl(mp->tunnel_sw_if_index));
1036
1037 vat_json_print(vam->ofp, &node);
1038 vat_json_free(&node);
1039
1040 vam->retval = ntohl(mp->retval);
1041 vam->result_ready = 1;
1042}
1043
Ed Warnickecb9cada2015-12-08 15:45:58 -07001044
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08001045static void vl_api_show_version_reply_t_handler
Ed Warnickecb9cada2015-12-08 15:45:58 -07001046(vl_api_show_version_reply_t * mp)
1047{
1048 vat_main_t * vam = &vat_main;
1049 i32 retval = ntohl(mp->retval);
1050
1051 if (retval >= 0) {
1052 errmsg (" program: %s\n", mp->program);
Damjan Mariona0d4a1a2015-12-12 14:40:59 +01001053 errmsg (" version: %s\n", mp->version);
Ed Warnickecb9cada2015-12-08 15:45:58 -07001054 errmsg (" build date: %s\n", mp->build_date);
1055 errmsg ("build directory: %s\n", mp->build_directory);
1056 }
1057 vam->retval = retval;
1058 vam->result_ready = 1;
1059}
1060
1061static void vl_api_show_version_reply_t_handler_json
1062(vl_api_show_version_reply_t * mp)
1063{
1064 vat_main_t * vam = &vat_main;
1065 vat_json_node_t node;
1066
1067 vat_json_init_object(&node);
1068 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1069 vat_json_object_add_string_copy(&node, "program", mp->program);
Damjan Mariona0d4a1a2015-12-12 14:40:59 +01001070 vat_json_object_add_string_copy(&node, "version", mp->version);
Ed Warnickecb9cada2015-12-08 15:45:58 -07001071 vat_json_object_add_string_copy(&node, "build_date", mp->build_date);
1072 vat_json_object_add_string_copy(&node, "build_directory", mp->build_directory);
1073
1074 vat_json_print(vam->ofp, &node);
1075 vat_json_free(&node);
1076
1077 vam->retval = ntohl(mp->retval);
1078 vam->result_ready = 1;
1079}
1080
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08001081static void vl_api_ip4_arp_event_t_handler
Ed Warnickecb9cada2015-12-08 15:45:58 -07001082(vl_api_ip4_arp_event_t * mp)
1083{
1084 vat_main_t * vam = &vat_main;
1085 errmsg ("arp event: address %U new mac %U sw_if_index %d\n",
1086 format_ip4_address, &mp->address,
1087 format_ethernet_address, mp->new_mac, mp->sw_if_index);
1088}
1089
1090static void vl_api_ip4_arp_event_t_handler_json
1091(vl_api_ip4_arp_event_t * mp)
1092{
1093 /* JSON output not supported */
1094}
1095
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08001096/*
Ed Warnickecb9cada2015-12-08 15:45:58 -07001097 * Special-case: build the bridge domain table, maintain
1098 * the next bd id vbl.
1099 */
1100static void vl_api_bridge_domain_details_t_handler
1101(vl_api_bridge_domain_details_t * mp)
1102{
1103 vat_main_t * vam = &vat_main;
1104 u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1105
1106 fformat (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s\n",
1107 " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1108
1109 fformat (vam->ofp, "%3d %3d %3d %3d %3d %3d\n",
1110 ntohl (mp->bd_id), mp->learn, mp->forward,
1111 mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1112
1113 if (n_sw_ifs)
1114 fformat (vam->ofp, "\n\n%s %s %s\n", "sw_if_index", "SHG",
1115 "Interface Name");
1116}
1117
1118static void vl_api_bridge_domain_details_t_handler_json
1119(vl_api_bridge_domain_details_t * mp)
1120{
1121 vat_main_t * vam = &vat_main;
1122 vat_json_node_t *node, *array = NULL;
1123
1124 if (VAT_JSON_ARRAY != vam->json_tree.type) {
1125 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
1126 vat_json_init_array(&vam->json_tree);
1127 }
1128 node = vat_json_array_add(&vam->json_tree);
1129
1130 vat_json_init_object(node);
1131 vat_json_object_add_uint(node, "bd_id", ntohl(mp->bd_id));
1132 vat_json_object_add_uint(node, "flood", mp->flood);
1133 vat_json_object_add_uint(node, "forward", mp->forward);
1134 vat_json_object_add_uint(node, "learn", mp->learn);
1135 vat_json_object_add_uint(node, "bvi_sw_if_index", ntohl(mp->bvi_sw_if_index));
1136 vat_json_object_add_uint(node, "n_sw_ifs", ntohl(mp->n_sw_ifs));
1137 array = vat_json_object_add(node, "sw_if");
1138 vat_json_init_array(array);
1139}
1140
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08001141/*
Ed Warnickecb9cada2015-12-08 15:45:58 -07001142 * Special-case: build the bridge domain sw if table.
1143 */
1144static void vl_api_bridge_domain_sw_if_details_t_handler
1145(vl_api_bridge_domain_sw_if_details_t * mp)
1146{
1147 vat_main_t * vam = &vat_main;
1148 hash_pair_t * p;
1149 u8 * sw_if_name = 0;
1150 u32 sw_if_index;
1151
1152 sw_if_index = ntohl (mp->sw_if_index);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08001153 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
Ed Warnickecb9cada2015-12-08 15:45:58 -07001154 ({
1155 if ((u32) p->value[0] == sw_if_index) {
1156 sw_if_name = (u8 *)(p->key);
1157 break;
1158 }
1159 }));
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08001160
1161 fformat (vam->ofp, "%7d %3d %s", sw_if_index,
1162 mp->shg, sw_if_name ? (char *)sw_if_name :
Ed Warnickecb9cada2015-12-08 15:45:58 -07001163 "sw_if_index not found!");
1164}
1165
1166static void vl_api_bridge_domain_sw_if_details_t_handler_json
1167(vl_api_bridge_domain_sw_if_details_t * mp)
1168{
1169 vat_main_t * vam = &vat_main;
1170 vat_json_node_t *node = NULL;
1171 uword last_index = 0;
1172
1173 ASSERT(VAT_JSON_ARRAY == vam->json_tree.type);
1174 ASSERT(vec_len(vam->json_tree.array) >= 1);
1175 last_index = vec_len(vam->json_tree.array) - 1;
1176 node = &vam->json_tree.array[last_index];
1177 node = vat_json_object_get_element(node, "sw_if");
1178 ASSERT(NULL != node);
1179 node = vat_json_array_add(node);
1180
1181 vat_json_init_object(node);
1182 vat_json_object_add_uint(node, "bd_id", ntohl(mp->bd_id));
1183 vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
1184 vat_json_object_add_uint(node, "shg", mp->shg);
1185}
1186
1187static void vl_api_control_ping_reply_t_handler
1188(vl_api_control_ping_reply_t * mp)
1189{
1190 vat_main_t * vam = &vat_main;
1191 i32 retval = ntohl(mp->retval);
1192 if (vam->async_mode) {
1193 vam->async_errors += (retval < 0);
1194 } else {
1195 vam->retval = retval;
1196 vam->result_ready = 1;
1197 }
1198}
1199
1200static void vl_api_control_ping_reply_t_handler_json
1201(vl_api_control_ping_reply_t * mp)
1202{
1203 vat_main_t * vam = &vat_main;
1204 i32 retval = ntohl(mp->retval);
1205
1206 if (VAT_JSON_NONE != vam->json_tree.type) {
1207 vat_json_print(vam->ofp, &vam->json_tree);
1208 vat_json_free(&vam->json_tree);
1209 vam->json_tree.type = VAT_JSON_NONE;
1210 } else {
1211 /* just print [] */
1212 vat_json_init_array(&vam->json_tree);
1213 vat_json_print(vam->ofp, &vam->json_tree);
1214 vam->json_tree.type = VAT_JSON_NONE;
1215 }
1216
1217 vam->retval = retval;
1218 vam->result_ready = 1;
1219}
1220
Andrej Kozemcakd9831182016-06-20 08:47:57 +02001221static void vl_api_noprint_control_ping_reply_t_handler
1222(vl_api_noprint_control_ping_reply_t * mp)
1223{
1224 vat_main_t * vam = &vat_main;
1225 i32 retval = ntohl(mp->retval);
1226 if (vam->async_mode) {
1227 vam->async_errors += (retval < 0);
1228 } else {
1229 vam->retval = retval;
1230 vam->result_ready = 1;
1231 }
1232}
1233
1234static void vl_api_noprint_control_ping_reply_t_handler_json
1235(vl_api_noprint_control_ping_reply_t * mp)
1236{
1237 vat_main_t * vam = &vat_main;
1238 i32 retval = ntohl(mp->retval);
1239
1240 if (vam->noprint_msg) {
1241 vam->retval = retval;
1242 vam->result_ready = 1;
1243 return;
1244 }
1245
1246 if (VAT_JSON_NONE != vam->json_tree.type) {
1247 vat_json_print(vam->ofp, &vam->json_tree);
1248 vat_json_free(&vam->json_tree);
1249 vam->json_tree.type = VAT_JSON_NONE;
1250 } else {
1251 /* just print [] */
1252 vat_json_init_array(&vam->json_tree);
1253 vat_json_print(vam->ofp, &vam->json_tree);
1254 vam->json_tree.type = VAT_JSON_NONE;
1255 }
1256
1257 vam->retval = retval;
1258 vam->result_ready = 1;
1259}
1260
Ed Warnickecb9cada2015-12-08 15:45:58 -07001261static void vl_api_l2_flags_reply_t_handler
1262(vl_api_l2_flags_reply_t * mp)
1263{
1264 vat_main_t * vam = &vat_main;
1265 i32 retval = ntohl(mp->retval);
1266 if (vam->async_mode) {
1267 vam->async_errors += (retval < 0);
1268 } else {
1269 vam->retval = retval;
1270 vam->result_ready = 1;
1271 }
1272}
1273
1274static void vl_api_l2_flags_reply_t_handler_json
1275(vl_api_l2_flags_reply_t * mp)
1276{
1277 vat_main_t * vam = &vat_main;
1278 vat_json_node_t node;
1279
1280 vat_json_init_object(&node);
1281 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1282 vat_json_object_add_uint(&node, "resulting_feature_bitmap", ntohl(mp->resulting_feature_bitmap));
1283
1284 vat_json_print(vam->ofp, &node);
1285 vat_json_free(&node);
1286
1287 vam->retval = ntohl(mp->retval);
1288 vam->result_ready = 1;
1289}
1290
1291static void vl_api_bridge_flags_reply_t_handler
1292(vl_api_bridge_flags_reply_t * mp)
1293{
1294 vat_main_t * vam = &vat_main;
1295 i32 retval = ntohl(mp->retval);
1296 if (vam->async_mode) {
1297 vam->async_errors += (retval < 0);
1298 } else {
1299 vam->retval = retval;
1300 vam->result_ready = 1;
1301 }
1302}
1303
1304static void vl_api_bridge_flags_reply_t_handler_json
1305(vl_api_bridge_flags_reply_t * mp)
1306{
1307 vat_main_t * vam = &vat_main;
1308 vat_json_node_t node;
1309
1310 vat_json_init_object(&node);
1311 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1312 vat_json_object_add_uint(&node, "resulting_feature_bitmap", ntohl(mp->resulting_feature_bitmap));
1313
1314 vat_json_print(vam->ofp, &node);
1315 vat_json_free(&node);
1316
1317 vam->retval = ntohl(mp->retval);
1318 vam->result_ready = 1;
1319}
1320
1321static void vl_api_tap_connect_reply_t_handler
1322(vl_api_tap_connect_reply_t * mp)
1323{
1324 vat_main_t * vam = &vat_main;
1325 i32 retval = ntohl(mp->retval);
1326 if (vam->async_mode) {
1327 vam->async_errors += (retval < 0);
1328 } else {
1329 vam->retval = retval;
Keith Burns (alagalah)802255c2016-06-13 16:56:04 -07001330 vam->sw_if_index = ntohl (mp->sw_if_index);
1331 vam->result_ready = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -07001332 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08001333
Ed Warnickecb9cada2015-12-08 15:45:58 -07001334}
1335
1336static void vl_api_tap_connect_reply_t_handler_json
1337(vl_api_tap_connect_reply_t * mp)
1338{
1339 vat_main_t * vam = &vat_main;
1340 vat_json_node_t node;
1341
1342 vat_json_init_object(&node);
1343 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1344 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
1345
1346 vat_json_print(vam->ofp, &node);
1347 vat_json_free(&node);
1348
1349 vam->retval = ntohl(mp->retval);
1350 vam->result_ready = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08001351
Ed Warnickecb9cada2015-12-08 15:45:58 -07001352}
1353
1354static void vl_api_tap_modify_reply_t_handler
1355(vl_api_tap_modify_reply_t * mp)
1356{
1357 vat_main_t * vam = &vat_main;
1358 i32 retval = ntohl(mp->retval);
1359 if (vam->async_mode) {
1360 vam->async_errors += (retval < 0);
1361 } else {
1362 vam->retval = retval;
Keith Burns (alagalah)802255c2016-06-13 16:56:04 -07001363 vam->sw_if_index = ntohl (mp->sw_if_index);
Ed Warnickecb9cada2015-12-08 15:45:58 -07001364 vam->result_ready = 1;
1365 }
1366}
1367
1368static void vl_api_tap_modify_reply_t_handler_json
1369(vl_api_tap_modify_reply_t * mp)
1370{
1371 vat_main_t * vam = &vat_main;
1372 vat_json_node_t node;
1373
1374 vat_json_init_object(&node);
1375 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1376 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
1377
1378 vat_json_print(vam->ofp, &node);
1379 vat_json_free(&node);
1380
1381 vam->retval = ntohl(mp->retval);
1382 vam->result_ready = 1;
1383}
1384
1385static void vl_api_tap_delete_reply_t_handler
1386(vl_api_tap_delete_reply_t * mp)
1387{
1388 vat_main_t * vam = &vat_main;
1389 i32 retval = ntohl(mp->retval);
1390 if (vam->async_mode) {
1391 vam->async_errors += (retval < 0);
1392 } else {
1393 vam->retval = retval;
1394 vam->result_ready = 1;
1395 }
1396}
1397
1398static void vl_api_tap_delete_reply_t_handler_json
1399(vl_api_tap_delete_reply_t * mp)
1400{
1401 vat_main_t * vam = &vat_main;
1402 vat_json_node_t node;
1403
1404 vat_json_init_object(&node);
1405 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1406
1407 vat_json_print(vam->ofp, &node);
1408 vat_json_free(&node);
1409
1410 vam->retval = ntohl(mp->retval);
1411 vam->result_ready = 1;
1412}
1413
1414static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler
1415(vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1416{
1417 vat_main_t * vam = &vat_main;
1418 i32 retval = ntohl(mp->retval);
1419 if (vam->async_mode) {
1420 vam->async_errors += (retval < 0);
1421 } else {
1422 vam->retval = retval;
1423 vam->result_ready = 1;
1424 }
1425}
1426
1427static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler_json
1428(vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1429{
1430 vat_main_t * vam = &vat_main;
1431 vat_json_node_t node;
1432
1433 vat_json_init_object(&node);
1434 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1435 vat_json_object_add_uint(&node, "tunnel_sw_if_index", ntohl(mp->tunnel_sw_if_index));
1436
1437 vat_json_print(vam->ofp, &node);
1438 vat_json_free(&node);
1439
1440 vam->retval = ntohl(mp->retval);
1441 vam->result_ready = 1;
1442}
1443
1444static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1445(vl_api_l2tpv3_create_tunnel_reply_t * mp)
1446{
1447 vat_main_t * vam = &vat_main;
1448 i32 retval = ntohl(mp->retval);
1449 if (vam->async_mode) {
1450 vam->async_errors += (retval < 0);
1451 } else {
1452 vam->retval = retval;
Keith Burns (alagalah)802255c2016-06-13 16:56:04 -07001453 vam->sw_if_index = ntohl (mp->sw_if_index);
Ed Warnickecb9cada2015-12-08 15:45:58 -07001454 vam->result_ready = 1;
1455 }
1456}
1457
1458static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1459(vl_api_l2tpv3_create_tunnel_reply_t * mp)
1460{
1461 vat_main_t * vam = &vat_main;
1462 vat_json_node_t node;
1463
1464 vat_json_init_object(&node);
1465 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1466 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
1467
1468 vat_json_print(vam->ofp, &node);
1469 vat_json_free(&node);
1470
1471 vam->retval = ntohl(mp->retval);
1472 vam->result_ready = 1;
1473}
1474
1475static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1476(vl_api_vxlan_add_del_tunnel_reply_t * mp)
1477{
1478 vat_main_t * vam = &vat_main;
1479 i32 retval = ntohl(mp->retval);
1480 if (vam->async_mode) {
1481 vam->async_errors += (retval < 0);
1482 } else {
1483 vam->retval = retval;
Keith Burns (alagalah)802255c2016-06-13 16:56:04 -07001484 vam->sw_if_index = ntohl (mp->sw_if_index);
Ed Warnickecb9cada2015-12-08 15:45:58 -07001485 vam->result_ready = 1;
1486 }
1487}
1488
1489static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1490(vl_api_vxlan_add_del_tunnel_reply_t * mp)
1491{
1492 vat_main_t * vam = &vat_main;
1493 vat_json_node_t node;
1494
1495 vat_json_init_object(&node);
1496 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1497 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
1498
1499 vat_json_print(vam->ofp, &node);
1500 vat_json_free(&node);
1501
1502 vam->retval = ntohl(mp->retval);
1503 vam->result_ready = 1;
1504}
1505
Chris Luke27fe48f2016-04-28 13:44:38 -04001506static void vl_api_gre_add_del_tunnel_reply_t_handler
1507(vl_api_gre_add_del_tunnel_reply_t * mp)
1508{
1509 vat_main_t * vam = &vat_main;
1510 i32 retval = ntohl(mp->retval);
1511 if (vam->async_mode) {
1512 vam->async_errors += (retval < 0);
1513 } else {
1514 vam->retval = retval;
Keith Burns (alagalah)802255c2016-06-13 16:56:04 -07001515 vam->sw_if_index = ntohl (mp->sw_if_index);
Chris Luke27fe48f2016-04-28 13:44:38 -04001516 vam->result_ready = 1;
1517 }
1518}
1519
1520static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1521(vl_api_gre_add_del_tunnel_reply_t * mp)
1522{
1523 vat_main_t * vam = &vat_main;
1524 vat_json_node_t node;
1525
1526 vat_json_init_object(&node);
1527 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1528 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
1529
1530 vat_json_print(vam->ofp, &node);
1531 vat_json_free(&node);
1532
1533 vam->retval = ntohl(mp->retval);
1534 vam->result_ready = 1;
1535}
1536
Ed Warnickecb9cada2015-12-08 15:45:58 -07001537static void vl_api_create_vhost_user_if_reply_t_handler
1538(vl_api_create_vhost_user_if_reply_t * mp)
1539{
1540 vat_main_t * vam = &vat_main;
1541 i32 retval = ntohl(mp->retval);
1542 if (vam->async_mode) {
1543 vam->async_errors += (retval < 0);
1544 } else {
1545 vam->retval = retval;
Keith Burns (alagalah)802255c2016-06-13 16:56:04 -07001546 vam->sw_if_index = ntohl (mp->sw_if_index);
Ed Warnickecb9cada2015-12-08 15:45:58 -07001547 vam->result_ready = 1;
1548 }
1549}
1550
1551static void vl_api_create_vhost_user_if_reply_t_handler_json
1552(vl_api_create_vhost_user_if_reply_t * mp)
1553{
1554 vat_main_t * vam = &vat_main;
1555 vat_json_node_t node;
1556
1557 vat_json_init_object(&node);
1558 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1559 vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
1560
1561 vat_json_print(vam->ofp, &node);
1562 vat_json_free(&node);
1563
1564 vam->retval = ntohl(mp->retval);
1565 vam->result_ready = 1;
1566}
1567
1568static void vl_api_ip_address_details_t_handler
1569(vl_api_ip_address_details_t * mp)
1570{
1571 vat_main_t * vam = &vat_main;
1572 static ip_address_details_t empty_ip_address_details = {{0}};
1573 ip_address_details_t * address = NULL;
1574 ip_details_t * current_ip_details = NULL;
1575 ip_details_t * details = NULL;
1576
1577 details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1578
1579 if (!details || vam->current_sw_if_index >= vec_len(details)
1580 || !details[vam->current_sw_if_index].present) {
1581 errmsg ("ip address details arrived but not stored\n");
1582 errmsg ("ip_dump should be called first\n");
1583 return;
1584 }
1585
1586 current_ip_details = vec_elt_at_index(details,
1587 vam->current_sw_if_index);
1588
1589#define addresses (current_ip_details->addr)
1590
1591 vec_validate_init_empty(addresses, vec_len(addresses),
1592 empty_ip_address_details);
1593
1594 address = vec_elt_at_index(addresses, vec_len(addresses) - 1);
1595
Damjan Marionf1213b82016-03-13 02:22:06 +01001596 clib_memcpy(&address->ip, &mp->ip, sizeof(address->ip));
Ed Warnickecb9cada2015-12-08 15:45:58 -07001597 address->prefix_length = mp->prefix_length;
1598#undef addresses
1599}
1600
1601static void vl_api_ip_address_details_t_handler_json
1602(vl_api_ip_address_details_t * mp)
1603{
1604 vat_main_t * vam = &vat_main;
1605 vat_json_node_t *node = NULL;
1606 struct in6_addr ip6;
1607 struct in_addr ip4;
1608
1609 if (VAT_JSON_ARRAY != vam->json_tree.type) {
1610 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
1611 vat_json_init_array(&vam->json_tree);
1612 }
1613 node = vat_json_array_add(&vam->json_tree);
1614
1615 vat_json_init_object(node);
1616 if (vam->is_ipv6) {
Damjan Marionf1213b82016-03-13 02:22:06 +01001617 clib_memcpy(&ip6, mp->ip, sizeof(ip6));
Ed Warnickecb9cada2015-12-08 15:45:58 -07001618 vat_json_object_add_ip6(node, "ip", ip6);
1619 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01001620 clib_memcpy(&ip4, mp->ip, sizeof(ip4));
Ed Warnickecb9cada2015-12-08 15:45:58 -07001621 vat_json_object_add_ip4(node, "ip", ip4);
1622 }
1623 vat_json_object_add_uint(node, "prefix_length", mp->prefix_length);
1624}
1625
1626static void vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1627{
1628 vat_main_t * vam = &vat_main;
1629 static ip_details_t empty_ip_details = {0};
1630 ip_details_t * ip = NULL;
1631 u32 sw_if_index = ~0;
1632
1633 sw_if_index = ntohl(mp->sw_if_index);
1634
1635 vec_validate_init_empty(vam->ip_details_by_sw_if_index[vam->is_ipv6],
1636 sw_if_index, empty_ip_details);
1637
1638 ip = vec_elt_at_index(vam->ip_details_by_sw_if_index[vam->is_ipv6],
1639 sw_if_index);
1640
1641 ip->present = 1;
1642}
1643
1644static void vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1645{
1646 vat_main_t * vam = &vat_main;
1647
1648 if (VAT_JSON_ARRAY != vam->json_tree.type) {
1649 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
1650 vat_json_init_array(&vam->json_tree);
1651 }
1652 vat_json_array_add_uint(&vam->json_tree, clib_net_to_host_u32(mp->sw_if_index));
1653}
1654
1655static void vl_api_map_domain_details_t_handler_json
1656(vl_api_map_domain_details_t * mp)
1657{
1658 vat_json_node_t * node = NULL;
1659 vat_main_t * vam = &vat_main;
1660 struct in6_addr ip6;
1661 struct in_addr ip4;
1662
1663 if (VAT_JSON_ARRAY != vam->json_tree.type) {
1664 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
1665 vat_json_init_array(&vam->json_tree);
1666 }
1667
1668 node = vat_json_array_add(&vam->json_tree);
1669 vat_json_init_object(node);
1670
1671 vat_json_object_add_uint(node, "domain_index", clib_net_to_host_u32(mp->domain_index));
Damjan Marionf1213b82016-03-13 02:22:06 +01001672 clib_memcpy(&ip6, mp->ip6_prefix, sizeof(ip6));
Ed Warnickecb9cada2015-12-08 15:45:58 -07001673 vat_json_object_add_ip6(node, "ip6_prefix", ip6);
Damjan Marionf1213b82016-03-13 02:22:06 +01001674 clib_memcpy(&ip4, mp->ip4_prefix, sizeof(ip4));
Ed Warnickecb9cada2015-12-08 15:45:58 -07001675 vat_json_object_add_ip4(node, "ip4_prefix", ip4);
Damjan Marionf1213b82016-03-13 02:22:06 +01001676 clib_memcpy(&ip6, mp->ip6_src, sizeof(ip6));
Ed Warnickecb9cada2015-12-08 15:45:58 -07001677 vat_json_object_add_ip6(node, "ip6_src", ip6);
1678 vat_json_object_add_int(node, "ip6_prefix_len", mp->ip6_prefix_len);
1679 vat_json_object_add_int(node, "ip4_prefix_len", mp->ip4_prefix_len);
1680 vat_json_object_add_int(node, "ip6_src_len", mp->ip6_src_len);
1681 vat_json_object_add_int(node, "ea_bits_len", mp->ea_bits_len);
1682 vat_json_object_add_int(node, "psid_offset", mp->psid_offset);
1683 vat_json_object_add_int(node, "psid_length", mp->psid_length);
1684 vat_json_object_add_uint(node, "flags", mp->flags);
1685 vat_json_object_add_uint(node, "mtu", clib_net_to_host_u16(mp->mtu));
1686 vat_json_object_add_int(node, "is_translation", mp->is_translation);
1687}
1688
1689static void vl_api_map_domain_details_t_handler
1690(vl_api_map_domain_details_t * mp)
1691{
1692 vat_main_t * vam = &vat_main;
1693
1694 if (mp->is_translation) {
1695 fformat(vam->ofp, "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u\n",
1696 format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1697 format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1698 format_ip6_address, mp->ip6_src, mp->ip6_src_len, clib_net_to_host_u32(mp->domain_index));
1699 } else {
1700 fformat(vam->ofp, "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u\n",
1701 format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1702 format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1703 format_ip6_address, mp->ip6_src, clib_net_to_host_u32(mp->domain_index));
1704 }
1705 fformat(vam->ofp, " ea-len %d psid-offset %d psid-len %d mtu %d %s\n",
1706 mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu, mp->is_translation? "map-t":"");
1707}
1708
1709static void vl_api_map_rule_details_t_handler_json
1710(vl_api_map_rule_details_t * mp)
1711{
1712 struct in6_addr ip6;
1713 vat_json_node_t * node = NULL;
1714 vat_main_t * vam = &vat_main;
1715
1716 if (VAT_JSON_ARRAY != vam->json_tree.type) {
1717 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
1718 vat_json_init_array(&vam->json_tree);
1719 }
1720
1721 node = vat_json_array_add(&vam->json_tree);
1722 vat_json_init_object(node);
1723
1724 vat_json_object_add_uint(node, "psid", clib_net_to_host_u16(mp->psid));
Damjan Marionf1213b82016-03-13 02:22:06 +01001725 clib_memcpy(&ip6, mp->ip6_dst, sizeof(ip6));
Ed Warnickecb9cada2015-12-08 15:45:58 -07001726 vat_json_object_add_ip6(node, "ip6_dst", ip6);
1727}
1728
1729static void vl_api_map_rule_details_t_handler
1730(vl_api_map_rule_details_t * mp)
1731{
1732 vat_main_t * vam = &vat_main;
1733 fformat(vam->ofp, " %d (psid) %U (ip6-dst)\n", clib_net_to_host_u16(mp->psid),
1734 format_ip6_address, mp->ip6_dst);
1735}
1736
1737static void vl_api_dhcp_compl_event_t_handler
1738(vl_api_dhcp_compl_event_t * mp)
1739{
1740 vat_main_t * vam = &vat_main;
1741 errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1742 "router_addr %U host_mac %U\n",
1743 mp->pid, mp->is_ipv6 ? "ipv6":"ipv4", mp->hostname,
1744 format_ip4_address, &mp->host_address,
1745 format_ip4_address, &mp->router_address,
1746 format_ethernet_address, mp->host_mac);
1747}
1748
1749static void vl_api_dhcp_compl_event_t_handler_json
1750(vl_api_dhcp_compl_event_t * mp)
1751{
1752 /* JSON output not supported */
1753}
1754
1755static void set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1756 u32 counter)
1757{
1758 vat_main_t * vam = &vat_main;
1759 static u64 default_counter = 0;
1760
1761 vec_validate_init_empty(vam->simple_interface_counters, vnet_counter_type, NULL);
1762 vec_validate_init_empty(vam->simple_interface_counters[vnet_counter_type],
1763 sw_if_index, default_counter);
1764 vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1765}
1766
1767static void set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1768 interface_counter_t counter)
1769{
1770 vat_main_t * vam = &vat_main;
1771 static interface_counter_t default_counter = {0, };
1772
1773 vec_validate_init_empty(vam->combined_interface_counters, vnet_counter_type, NULL);
1774 vec_validate_init_empty(vam->combined_interface_counters[vnet_counter_type],
1775 sw_if_index, default_counter);
1776 vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1777}
1778
1779static void vl_api_vnet_interface_counters_t_handler
1780(vl_api_vnet_interface_counters_t *mp)
1781{
1782 /* not supported */
1783}
1784
1785static void vl_api_vnet_interface_counters_t_handler_json
1786(vl_api_vnet_interface_counters_t *mp)
1787{
1788 interface_counter_t counter;
1789 vlib_counter_t *v;
1790 u64 *v_packets;
1791 u64 packets;
1792 u32 count;
1793 u32 first_sw_if_index;
1794 int i;
1795
1796 count = ntohl(mp->count);
1797 first_sw_if_index = ntohl(mp->first_sw_if_index);
1798
1799 if (!mp->is_combined) {
1800 v_packets = (u64*)&mp->data;
1801 for (i = 0; i < count; i++) {
1802 packets = clib_net_to_host_u64(clib_mem_unaligned(v_packets, u64));
1803 set_simple_interface_counter(mp->vnet_counter_type,
1804 first_sw_if_index + i, packets);
1805 v_packets++;
1806 }
1807 } else {
1808 v = (vlib_counter_t*)&mp->data;
1809 for (i = 0; i < count; i++) {
1810 counter.packets = clib_net_to_host_u64(
1811 clib_mem_unaligned(&v->packets, u64));
1812 counter.bytes = clib_net_to_host_u64(
1813 clib_mem_unaligned(&v->bytes, u64));
1814 set_combined_interface_counter(mp->vnet_counter_type,
1815 first_sw_if_index + i, counter);
1816 v++;
1817 }
1818 }
1819}
1820
1821static u32 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1822{
1823 vat_main_t * vam = &vat_main;
1824 u32 i;
1825
1826 for (i = 0; i < vec_len(vam->ip4_fib_counters_vrf_id_by_index); i++) {
1827 if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id) {
1828 return i;
1829 }
1830 }
1831 return ~0;
1832}
1833
1834static u32 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1835{
1836 vat_main_t * vam = &vat_main;
1837 u32 i;
1838
1839 for (i = 0; i < vec_len(vam->ip6_fib_counters_vrf_id_by_index); i++) {
1840 if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id) {
1841 return i;
1842 }
1843 }
1844 return ~0;
1845}
1846
1847static void vl_api_vnet_ip4_fib_counters_t_handler
1848(vl_api_vnet_ip4_fib_counters_t *mp)
1849{
1850 /* not supported */
1851}
1852
1853static void vl_api_vnet_ip4_fib_counters_t_handler_json
1854(vl_api_vnet_ip4_fib_counters_t *mp)
1855{
1856 vat_main_t * vam = &vat_main;
1857 vl_api_ip4_fib_counter_t *v;
1858 ip4_fib_counter_t *counter;
1859 struct in_addr ip4;
1860 u32 vrf_id;
1861 u32 vrf_index;
1862 u32 count;
1863 int i;
1864
1865 vrf_id = ntohl(mp->vrf_id);
1866 vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id(vrf_id);
1867 if (~0 == vrf_index) {
1868 vrf_index = vec_len(vam->ip4_fib_counters_vrf_id_by_index);
1869 vec_validate(vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
1870 vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
1871 vec_validate(vam->ip4_fib_counters, vrf_index);
1872 vam->ip4_fib_counters[vrf_index] = NULL;
1873 }
1874
1875 vec_free(vam->ip4_fib_counters[vrf_index]);
1876 v = (vl_api_ip4_fib_counter_t*)&mp->c;
1877 count = ntohl(mp->count);
1878 for (i = 0; i < count; i++) {
1879 vec_validate(vam->ip4_fib_counters[vrf_index], i);
1880 counter = &vam->ip4_fib_counters[vrf_index][i];
Damjan Marionf1213b82016-03-13 02:22:06 +01001881 clib_memcpy(&ip4, &v->address, sizeof(ip4));
Ed Warnickecb9cada2015-12-08 15:45:58 -07001882 counter->address = ip4;
1883 counter->address_length = v->address_length;
1884 counter->packets = clib_net_to_host_u64(v->packets);
1885 counter->bytes = clib_net_to_host_u64(v->bytes);
1886 v++;
1887 }
1888}
1889
1890static void vl_api_vnet_ip6_fib_counters_t_handler
1891(vl_api_vnet_ip6_fib_counters_t *mp)
1892{
1893 /* not supported */
1894}
1895
1896static void vl_api_vnet_ip6_fib_counters_t_handler_json
1897(vl_api_vnet_ip6_fib_counters_t *mp)
1898{
1899 vat_main_t * vam = &vat_main;
1900 vl_api_ip6_fib_counter_t *v;
1901 ip6_fib_counter_t *counter;
1902 struct in6_addr ip6;
1903 u32 vrf_id;
1904 u32 vrf_index;
1905 u32 count;
1906 int i;
1907
1908 vrf_id = ntohl(mp->vrf_id);
1909 vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id(vrf_id);
1910 if (~0 == vrf_index) {
1911 vrf_index = vec_len(vam->ip6_fib_counters_vrf_id_by_index);
1912 vec_validate(vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
1913 vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
1914 vec_validate(vam->ip6_fib_counters, vrf_index);
1915 vam->ip6_fib_counters[vrf_index] = NULL;
1916 }
1917
1918 vec_free(vam->ip6_fib_counters[vrf_index]);
1919 v = (vl_api_ip6_fib_counter_t*)&mp->c;
1920 count = ntohl(mp->count);
1921 for (i = 0; i < count; i++) {
1922 vec_validate(vam->ip6_fib_counters[vrf_index], i);
1923 counter = &vam->ip6_fib_counters[vrf_index][i];
Damjan Marionf1213b82016-03-13 02:22:06 +01001924 clib_memcpy(&ip6, &v->address, sizeof(ip6));
Ed Warnickecb9cada2015-12-08 15:45:58 -07001925 counter->address = ip6;
1926 counter->address_length = v->address_length;
1927 counter->packets = clib_net_to_host_u64(v->packets);
1928 counter->bytes = clib_net_to_host_u64(v->bytes);
1929 v++;
1930 }
1931}
1932
1933static void vl_api_get_first_msg_id_reply_t_handler
1934(vl_api_get_first_msg_id_reply_t * mp)
1935{
1936 vat_main_t * vam = &vat_main;
1937 i32 retval = ntohl(mp->retval);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08001938
Ed Warnickecb9cada2015-12-08 15:45:58 -07001939 if (vam->async_mode) {
1940 vam->async_errors += (retval < 0);
1941 } else {
1942 vam->retval = retval;
1943 vam->result_ready = 1;
1944 }
1945 if (retval >= 0) {
1946 errmsg ("first message id %d\n", ntohs(mp->first_msg_id));
1947 }
1948}
1949
1950static void vl_api_get_first_msg_id_reply_t_handler_json
1951(vl_api_get_first_msg_id_reply_t * mp)
1952{
1953 vat_main_t * vam = &vat_main;
1954 vat_json_node_t node;
1955
1956 vat_json_init_object(&node);
1957 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08001958 vat_json_object_add_uint(&node, "first_msg_id",
Ed Warnickecb9cada2015-12-08 15:45:58 -07001959 (uint) ntohs(mp->first_msg_id));
1960
1961 vat_json_print(vam->ofp, &node);
1962 vat_json_free(&node);
1963
1964 vam->retval = ntohl(mp->retval);
1965 vam->result_ready = 1;
1966}
1967
Dave Barachb44e9bc2016-02-19 09:06:23 -05001968static void vl_api_get_node_graph_reply_t_handler
1969(vl_api_get_node_graph_reply_t * mp)
1970{
1971 vat_main_t * vam = &vat_main;
1972 api_main_t * am = &api_main;
1973 i32 retval = ntohl(mp->retval);
1974 u8 * pvt_copy, * reply;
1975 void * oldheap;
1976 vlib_node_t * node;
1977 int i;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08001978
Dave Barachb44e9bc2016-02-19 09:06:23 -05001979 if (vam->async_mode) {
1980 vam->async_errors += (retval < 0);
1981 } else {
1982 vam->retval = retval;
1983 vam->result_ready = 1;
1984 }
1985
1986 /* "Should never happen..." */
1987 if (retval != 0)
1988 return;
1989
1990 reply = (u8 *)(mp->reply_in_shmem);
1991 pvt_copy = vec_dup (reply);
1992
1993 /* Toss the shared-memory original... */
1994 pthread_mutex_lock (&am->vlib_rp->mutex);
1995 oldheap = svm_push_data_heap (am->vlib_rp);
1996
1997 vec_free (reply);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08001998
Dave Barachb44e9bc2016-02-19 09:06:23 -05001999 svm_pop_heap (oldheap);
2000 pthread_mutex_unlock (&am->vlib_rp->mutex);
2001
2002 if (vam->graph_nodes) {
2003 hash_free (vam->graph_node_index_by_name);
2004
2005 for (i = 0; i < vec_len (vam->graph_nodes); i++) {
2006 node = vam->graph_nodes[i];
2007 vec_free (node->name);
2008 vec_free (node->next_nodes);
2009 vec_free (node);
2010 }
2011 vec_free(vam->graph_nodes);
2012 }
2013
2014 vam->graph_node_index_by_name = hash_create_string (0, sizeof(uword));
2015 vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2016 vec_free (pvt_copy);
2017
2018 for (i = 0; i < vec_len (vam->graph_nodes); i++) {
2019 node = vam->graph_nodes[i];
2020 hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2021 }
2022}
2023
2024static void vl_api_get_node_graph_reply_t_handler_json
2025(vl_api_get_node_graph_reply_t * mp)
2026{
2027 vat_main_t * vam = &vat_main;
2028 api_main_t * am = &api_main;
2029 void * oldheap;
2030 vat_json_node_t node;
2031 u8 * reply;
2032
2033 /* $$$$ make this real? */
2034 vat_json_init_object(&node);
2035 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
2036 vat_json_object_add_uint(&node, "reply_in_shmem", mp->reply_in_shmem);
2037
2038 reply = (u8 *)(mp->reply_in_shmem);
2039
2040 /* Toss the shared-memory original... */
2041 pthread_mutex_lock (&am->vlib_rp->mutex);
2042 oldheap = svm_push_data_heap (am->vlib_rp);
2043
2044 vec_free (reply);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08002045
Dave Barachb44e9bc2016-02-19 09:06:23 -05002046 svm_pop_heap (oldheap);
2047 pthread_mutex_unlock (&am->vlib_rp->mutex);
2048
2049 vat_json_print(vam->ofp, &node);
2050 vat_json_free(&node);
2051
2052 vam->retval = ntohl(mp->retval);
2053 vam->result_ready = 1;
2054}
2055
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002056static void
Andrej Kozemcakd9831182016-06-20 08:47:57 +02002057vl_api_lisp_locator_details_t_handler (
2058 vl_api_lisp_locator_details_t *mp)
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002059{
2060 vat_main_t *vam = &vat_main;
Andrej Kozemcakd9831182016-06-20 08:47:57 +02002061 locator_msg_t loc;
2062 u8 * tmp_str = 0;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002063
Andrej Kozemcakd9831182016-06-20 08:47:57 +02002064 memset(&loc, 0, sizeof(loc));
2065 if (vam->noprint_msg) {
2066 loc.local = mp->local;
2067 loc.priority = mp->priority;
2068 loc.weight = mp->weight;
2069 if (loc.local) {
2070 loc.sw_if_index = ntohl(mp->sw_if_index);
2071 } else {
2072 loc.is_ipv6 = mp->is_ipv6;
2073 clib_memcpy(loc.ip_address, mp->ip_address, sizeof(loc.ip_address));
2074 }
2075 vec_add1(vam->locator_msg, loc);
Andrej Kozemcak3e53fc52016-05-09 10:52:16 +02002076 } else {
Andrej Kozemcakd9831182016-06-20 08:47:57 +02002077 if (mp->local) {
2078 tmp_str = format(tmp_str, "%=16d%=16d%=16d\n",
2079 ntohl(mp->sw_if_index),
2080 mp->priority,
2081 mp->weight);
2082 } else {
2083 tmp_str = format(tmp_str, "%=16U%=16d%=16d\n",
2084 mp->is_ipv6 ? format_ip6_address :
2085 format_ip4_address,
2086 mp->ip_address,
2087 mp->priority,
2088 mp->weight);
2089 }
Andrej Kozemcak3e53fc52016-05-09 10:52:16 +02002090
Andrej Kozemcakd9831182016-06-20 08:47:57 +02002091 fformat(vam->ofp, "%s", tmp_str);
2092
Andrej Kozemcak3e53fc52016-05-09 10:52:16 +02002093 vec_free(tmp_str);
2094 }
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002095}
2096
2097static void
Andrej Kozemcakd9831182016-06-20 08:47:57 +02002098vl_api_lisp_locator_details_t_handler_json (
2099 vl_api_lisp_locator_details_t *mp)
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002100{
2101 vat_main_t *vam = &vat_main;
2102 vat_json_node_t *node = NULL;
Andrej Kozemcakd9831182016-06-20 08:47:57 +02002103 locator_msg_t loc;
Andrej Kozemcak3e53fc52016-05-09 10:52:16 +02002104 struct in6_addr ip6;
2105 struct in_addr ip4;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002106
Andrej Kozemcakd9831182016-06-20 08:47:57 +02002107 memset(&loc, 0, sizeof(loc));
2108 if (vam->noprint_msg) {
2109 loc.local = mp->local;
2110 loc.priority = mp->priority;
2111 loc.weight = mp->weight;
2112 if (loc.local) {
2113 loc.sw_if_index = ntohl(mp->sw_if_index);
2114 } else {
2115 loc.is_ipv6 = mp->is_ipv6;
2116 clib_memcpy(loc.ip_address, mp->ip_address, sizeof(loc.ip_address));
2117 }
2118 vec_add1(vam->locator_msg, loc);
2119 return;
2120 }
2121
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002122 if (VAT_JSON_ARRAY != vam->json_tree.type) {
2123 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
2124 vat_json_init_array(&vam->json_tree);
2125 }
2126 node = vat_json_array_add(&vam->json_tree);
2127
2128 vat_json_init_object(node);
Andrej Kozemcakd9831182016-06-20 08:47:57 +02002129
Andrej Kozemcak3e53fc52016-05-09 10:52:16 +02002130 if (mp->local) {
Andrej Kozemcakd9831182016-06-20 08:47:57 +02002131 vat_json_object_add_uint(node, "locator_index", ntohl(mp->sw_if_index));
Andrej Kozemcak3e53fc52016-05-09 10:52:16 +02002132 } else {
Andrej Kozemcakd9831182016-06-20 08:47:57 +02002133 if (mp->is_ipv6) {
2134 clib_memcpy(&ip6, mp->ip_address, sizeof(ip6));
2135 vat_json_object_add_ip6(node, "locator", ip6);
2136 } else {
2137 clib_memcpy(&ip4, mp->ip_address, sizeof(ip4));
2138 vat_json_object_add_ip4(node, "locator", ip4);
2139 }
Andrej Kozemcak3e53fc52016-05-09 10:52:16 +02002140 }
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002141 vat_json_object_add_uint(node, "priority", mp->priority);
2142 vat_json_object_add_uint(node, "weight", mp->weight);
2143}
2144
2145static void
Andrej Kozemcakd9831182016-06-20 08:47:57 +02002146vl_api_lisp_locator_set_details_t_handler (
2147 vl_api_lisp_locator_set_details_t *mp)
2148{
2149 vat_main_t *vam = &vat_main;
2150 locator_set_msg_t ls;
2151
2152 ls.locator_set_index = ntohl(mp->locator_set_index);
2153 ls.locator_set_name = format(0, "%s", mp->locator_set_name);
2154 vec_add1(vam->locator_set_msg, ls);
2155}
2156
2157static void
2158vl_api_lisp_locator_set_details_t_handler_json (
2159 vl_api_lisp_locator_set_details_t *mp)
2160{
2161 vat_main_t *vam = &vat_main;
2162 locator_set_msg_t ls;
2163
2164 ls.locator_set_index = ntohl(mp->locator_set_index);
2165 ls.locator_set_name = format(0, "%s", mp->locator_set_name);
2166 vec_add1(vam->locator_set_msg, ls);
2167}
2168
2169static void
Andrej Kozemcak6cc6f912016-07-13 13:01:01 +02002170vl_api_lisp_eid_table_details_t_handler (
2171 vl_api_lisp_eid_table_details_t * mp)
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002172{
2173 vat_main_t *vam = &vat_main;
Andrej Kozemcak6cc6f912016-07-13 13:01:01 +02002174 eid_table_t eid_table;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002175
Andrej Kozemcak6cc6f912016-07-13 13:01:01 +02002176 memset(&eid_table, 0, sizeof(eid_table));
2177 eid_table.is_local = mp->is_local;
2178 eid_table.locator_set_index = mp->locator_set_index;
2179 eid_table.eid_type = mp->eid_type;
2180 eid_table.vni = mp->vni;
2181 eid_table.eid_prefix_len = mp->eid_prefix_len;
2182 eid_table.ttl = mp->ttl;
2183 eid_table.authoritative = mp->authoritative;
2184 clib_memcpy(eid_table.eid, mp->eid, sizeof(eid_table.eid));
2185 vec_add1(vam->eid_tables, eid_table);
2186}
Filip Tehlar006eb262016-06-27 13:09:20 +02002187
Andrej Kozemcak6cc6f912016-07-13 13:01:01 +02002188static void
2189vl_api_lisp_eid_table_details_t_handler_json (
2190 vl_api_lisp_eid_table_details_t * mp)
2191{
2192 vat_main_t *vam = &vat_main;
2193 eid_table_t eid_table;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002194
Andrej Kozemcak6cc6f912016-07-13 13:01:01 +02002195 memset(&eid_table, 0, sizeof(eid_table));
2196 eid_table.is_local = mp->is_local;
2197 eid_table.locator_set_index = mp->locator_set_index;
2198 eid_table.eid_type = mp->eid_type;
2199 eid_table.vni = mp->vni;
2200 eid_table.eid_prefix_len = mp->eid_prefix_len;
2201 eid_table.ttl = mp->ttl;
2202 eid_table.authoritative = mp->authoritative;
2203 clib_memcpy(eid_table.eid, mp->eid, sizeof(eid_table.eid));
2204 vec_add1(vam->eid_tables, eid_table);
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002205}
2206
2207static void
Filip Tehlar2f653d02016-07-13 13:17:15 +02002208vl_api_lisp_eid_table_map_details_t_handler (
2209 vl_api_lisp_eid_table_map_details_t *mp)
2210{
2211 vat_main_t *vam = &vat_main;
2212
2213 u8 * line = format(0, "%=10d%=10d",
2214 clib_net_to_host_u32 (mp->vni),
2215 clib_net_to_host_u32 (mp->vrf));
2216 fformat(vam->ofp, "%v\n", line);
2217 vec_free(line);
2218}
2219
2220static void
2221vl_api_lisp_eid_table_map_details_t_handler_json (
2222 vl_api_lisp_eid_table_map_details_t *mp)
2223{
2224 vat_main_t *vam = &vat_main;
2225 vat_json_node_t *node = NULL;
2226
2227 if (VAT_JSON_ARRAY != vam->json_tree.type) {
2228 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
2229 vat_json_init_array(&vam->json_tree);
2230 }
2231 node = vat_json_array_add(&vam->json_tree);
2232 vat_json_init_object(node);
2233 vat_json_object_add_uint(node, "vrf", clib_net_to_host_u32 (mp->vrf));
2234 vat_json_object_add_uint(node, "vni", clib_net_to_host_u32 (mp->vni));
2235}
2236
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002237
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002238
2239static u8 *
2240format_decap_next (u8 * s, va_list * args)
2241{
2242 u32 next_index = va_arg (*args, u32);
2243
2244 switch (next_index)
2245 {
2246 case LISP_GPE_INPUT_NEXT_DROP:
2247 return format (s, "drop");
2248 case LISP_GPE_INPUT_NEXT_IP4_INPUT:
2249 return format (s, "ip4");
2250 case LISP_GPE_INPUT_NEXT_IP6_INPUT:
2251 return format (s, "ip6");
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002252 default:
2253 return format (s, "unknown %d", next_index);
2254 }
2255 return s;
2256}
2257
2258static void
2259vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *mp)
2260{
2261 vat_main_t *vam = &vat_main;
2262 u8 *iid_str;
2263 u8 *flag_str = NULL;
2264
2265 iid_str = format(0, "%d (0x%x)", ntohl(mp->iid), ntohl(mp->iid));
2266
2267#define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n);
2268 foreach_lisp_gpe_flag_bit;
2269#undef _
2270
2271 fformat(vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U"
2272 "%=16d%=16d%=16sd=16d%=16s%=16s\n",
2273 mp->tunnels,
2274 mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2275 mp->source_ip,
2276 mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2277 mp->destination_ip,
2278 ntohl(mp->encap_fib_id),
2279 ntohl(mp->decap_fib_id),
2280 format_decap_next, ntohl(mp->dcap_next),
2281 mp->ver_res >> 6,
2282 flag_str,
2283 mp->next_protocol,
2284 mp->ver_res,
2285 mp->res,
2286 iid_str);
2287
2288 vec_free(iid_str);
2289}
2290
2291static void
2292vl_api_lisp_gpe_tunnel_details_t_handler_json (
2293 vl_api_lisp_gpe_tunnel_details_t *mp)
2294{
2295 vat_main_t *vam = &vat_main;
2296 vat_json_node_t *node = NULL;
2297 struct in6_addr ip6;
2298 struct in_addr ip4;
2299 u8 *next_decap_str;
2300
2301 next_decap_str = format(0, "%U", format_decap_next, htonl(mp->dcap_next));
2302
2303 if (VAT_JSON_ARRAY != vam->json_tree.type) {
2304 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
2305 vat_json_init_array(&vam->json_tree);
2306 }
2307 node = vat_json_array_add(&vam->json_tree);
2308
2309 vat_json_init_object(node);
2310 vat_json_object_add_uint(node, "tunel", mp->tunnels);
2311 if (mp->is_ipv6) {
Damjan Marionf1213b82016-03-13 02:22:06 +01002312 clib_memcpy(&ip6, mp->source_ip, sizeof(ip6));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002313 vat_json_object_add_ip6(node, "source address", ip6);
Damjan Marionf1213b82016-03-13 02:22:06 +01002314 clib_memcpy(&ip6, mp->destination_ip, sizeof(ip6));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002315 vat_json_object_add_ip6(node, "destination address", ip6);
2316 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01002317 clib_memcpy(&ip4, mp->source_ip, sizeof(ip4));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002318 vat_json_object_add_ip4(node, "source address", ip4);
Damjan Marionf1213b82016-03-13 02:22:06 +01002319 clib_memcpy(&ip4, mp->destination_ip, sizeof(ip4));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002320 vat_json_object_add_ip4(node, "destination address", ip4);
2321 }
2322 vat_json_object_add_uint(node, "fib encap", ntohl(mp->encap_fib_id));
2323 vat_json_object_add_uint(node, "fib decap", ntohl(mp->decap_fib_id));
2324 vat_json_object_add_string_copy(node, "decap next", next_decap_str);
2325 vat_json_object_add_uint(node, "lisp version", mp->ver_res >> 6);
2326 vat_json_object_add_uint(node, "flags", mp->flags);
2327 vat_json_object_add_uint(node, "next protocol", mp->next_protocol);
2328 vat_json_object_add_uint(node, "ver_res", mp->ver_res);
2329 vat_json_object_add_uint(node, "res", mp->res);
2330 vat_json_object_add_uint(node, "iid", ntohl(mp->iid));
2331
2332 vec_free(next_decap_str);
2333}
2334
2335static void
2336vl_api_lisp_map_resolver_details_t_handler (
2337 vl_api_lisp_map_resolver_details_t *mp)
2338{
2339 vat_main_t *vam = &vat_main;
2340
2341 fformat(vam->ofp, "%=20U\n",
2342 mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2343 mp->ip_address);
2344}
2345
2346static void
2347vl_api_lisp_map_resolver_details_t_handler_json (
2348 vl_api_lisp_map_resolver_details_t *mp)
2349{
2350 vat_main_t *vam = &vat_main;
2351 vat_json_node_t *node = NULL;
2352 struct in6_addr ip6;
2353 struct in_addr ip4;
2354
2355 if (VAT_JSON_ARRAY != vam->json_tree.type) {
2356 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
2357 vat_json_init_array(&vam->json_tree);
2358 }
2359 node = vat_json_array_add(&vam->json_tree);
2360
2361 vat_json_init_object(node);
2362 if (mp->is_ipv6) {
Damjan Marionf1213b82016-03-13 02:22:06 +01002363 clib_memcpy(&ip6, mp->ip_address, sizeof(ip6));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002364 vat_json_object_add_ip6(node, "map resolver", ip6);
2365 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01002366 clib_memcpy(&ip4, mp->ip_address, sizeof(ip4));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02002367 vat_json_object_add_ip4(node, "map resolver", ip4);
2368 }
2369}
2370
Andrej Kozemcaka9edd852016-05-02 12:14:33 +02002371static void
Andrej Kozemcakd9831182016-06-20 08:47:57 +02002372vl_api_show_lisp_status_reply_t_handler
2373(vl_api_show_lisp_status_reply_t * mp)
Andrej Kozemcaka9edd852016-05-02 12:14:33 +02002374{
2375 vat_main_t *vam = &vat_main;
Andrej Kozemcakd9831182016-06-20 08:47:57 +02002376 i32 retval = ntohl(mp->retval);
Andrej Kozemcaka9edd852016-05-02 12:14:33 +02002377
Andrej Kozemcakd9831182016-06-20 08:47:57 +02002378 if (0 <= retval) {
2379 fformat(vam->ofp, "feature: %s\ngpe: %s\n",
2380 mp->feature_status ? "enabled" : "disabled",
2381 mp->gpe_status ? "enabled" : "disabled");
2382 }
2383
2384 vam->retval = retval;
2385 vam->result_ready = 1;
Andrej Kozemcaka9edd852016-05-02 12:14:33 +02002386}
2387
2388static void
Andrej Kozemcakd9831182016-06-20 08:47:57 +02002389vl_api_show_lisp_status_reply_t_handler_json
2390(vl_api_show_lisp_status_reply_t *mp)
Andrej Kozemcaka9edd852016-05-02 12:14:33 +02002391{
2392 vat_main_t *vam = &vat_main;
Andrej Kozemcakd9831182016-06-20 08:47:57 +02002393 vat_json_node_t node;
Filip Tehlar46d4e362016-05-09 09:39:26 +02002394 u8 * gpe_status = NULL;
2395 u8 * feature_status = NULL;
Andrej Kozemcaka9edd852016-05-02 12:14:33 +02002396
Filip Tehlar46d4e362016-05-09 09:39:26 +02002397 gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2398 feature_status = format (0, "%s",
2399 mp->feature_status ? "enabled" : "disabled");
Filip Tehlar6f91cfe2016-06-06 13:13:16 +02002400 vec_add1 (gpe_status, 0);
2401 vec_add1 (feature_status, 0);
Andrej Kozemcaka9edd852016-05-02 12:14:33 +02002402
Andrej Kozemcakd9831182016-06-20 08:47:57 +02002403 vat_json_init_object(&node);
2404 vat_json_object_add_string_copy(&node, "gpe_status", gpe_status);
2405 vat_json_object_add_string_copy(&node, "feature_status", feature_status);
Filip Tehlar46d4e362016-05-09 09:39:26 +02002406
2407 vec_free (gpe_status);
2408 vec_free (feature_status);
Andrej Kozemcakd9831182016-06-20 08:47:57 +02002409
2410 vat_json_print(vam->ofp, &node);
2411 vat_json_free(&node);
2412
2413 vam->retval = ntohl(mp->retval);
2414 vam->result_ready = 1;
Andrej Kozemcaka9edd852016-05-02 12:14:33 +02002415}
2416
Andrej Kozemcakb6e4d392016-06-14 13:55:57 +02002417static void
2418vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler (
2419 vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2420{
2421 vat_main_t * vam = &vat_main;
2422 i32 retval = ntohl(mp->retval);
2423
2424 if (retval >= 0) {
2425 fformat(vam->ofp, "%=20s\n",
2426 mp->locator_set_name);
2427 }
2428
2429 vam->retval = retval;
2430 vam->result_ready = 1;
2431}
2432
2433static void
2434vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json (
2435 vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2436{
2437 vat_main_t * vam = &vat_main;
2438 vat_json_node_t * node = NULL;
2439
2440 if (VAT_JSON_ARRAY != vam->json_tree.type) {
2441 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
2442 vat_json_init_array(&vam->json_tree);
2443 }
2444 node = vat_json_array_add(&vam->json_tree);
2445
2446 vat_json_init_object(node);
2447 vat_json_object_add_string_copy(node, "itr-rlocs", mp->locator_set_name);
2448
2449 vat_json_print(vam->ofp, node);
2450 vat_json_free(node);
2451
2452 vam->retval = ntohl(mp->retval);
2453 vam->result_ready = 1;
2454}
2455
Andrej Kozemcak914f91b2016-07-18 13:55:37 +02002456static void
2457vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2458{
2459 vat_main_t *vam = &vat_main;
2460 i32 retval = ntohl(mp->retval);
2461
2462 if (0 <= retval) {
2463 fformat(vam->ofp, "%-20s%-16s\n",
2464 mp->status ? "enabled" : "disabled",
2465 mp->status ? (char *) mp->locator_set_name : "");
2466 }
2467
2468 vam->retval = retval;
2469 vam->result_ready = 1;
2470}
2471
2472static void
2473vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t * mp)
2474{
2475 vat_main_t *vam = &vat_main;
2476 vat_json_node_t node;
2477 u8 * status = 0;
2478
2479 status = format (0, "%s", mp->status ? "enabled" : "disabled");
2480 vec_add1 (status, 0);
2481
2482 vat_json_init_object(&node);
2483 vat_json_object_add_string_copy(&node, "status", status);
2484 if (mp->status) {
2485 vat_json_object_add_string_copy(&node, "locator_set", mp->locator_set_name);
2486 }
2487
2488 vec_free (status);
2489
2490 vat_json_print(vam->ofp, &node);
2491 vat_json_free(&node);
2492
2493 vam->retval = ntohl(mp->retval);
2494 vam->result_ready = 1;
2495}
2496
Matus Fabiane8554802016-05-18 23:40:37 -07002497static u8 * format_policer_type (u8 * s, va_list * va)
2498{
2499 u32 i = va_arg (*va, u32);
2500
2501 if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2502 s = format (s, "1r2c");
2503 else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2504 s = format (s, "1r3c");
2505 else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2506 s = format (s, "2r3c-2698");
2507 else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2508 s = format (s, "2r3c-4115");
2509 else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2510 s = format (s, "2r3c-mef5cf1");
2511 else
2512 s = format (s, "ILLEGAL");
2513 return s;
2514}
2515
2516static u8 * format_policer_rate_type (u8 * s, va_list * va)
2517{
2518 u32 i = va_arg (*va, u32);
2519
2520 if (i == SSE2_QOS_RATE_KBPS)
2521 s = format (s, "kbps");
2522 else if (i == SSE2_QOS_RATE_PPS)
2523 s = format(s, "pps");
2524 else
2525 s = format (s, "ILLEGAL");
2526 return s;
2527}
2528
2529static u8 * format_policer_round_type (u8 * s, va_list * va)
2530{
2531 u32 i = va_arg (*va, u32);
2532
2533 if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2534 s = format(s, "closest");
2535 else if (i == SSE2_QOS_ROUND_TO_UP)
2536 s = format (s, "up");
2537 else if (i == SSE2_QOS_ROUND_TO_DOWN)
2538 s = format (s, "down");
2539 else
2540 s = format (s, "ILLEGAL");
2541 return s;
2542}
2543
Matus Fabian4ac74c92016-05-31 07:33:29 -07002544static u8 * format_policer_action_type (u8 * s, va_list * va)
2545{
2546 u32 i = va_arg (*va, u32);
2547
2548 if (i == SSE2_QOS_ACTION_DROP)
2549 s = format (s, "drop");
2550 else if (i == SSE2_QOS_ACTION_TRANSMIT)
2551 s = format (s, "transmit");
2552 else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2553 s = format (s, "mark-and-transmit");
2554 else
2555 s = format (s, "ILLEGAL");
2556 return s;
2557}
2558
2559static u8 * format_dscp (u8 * s, va_list * va)
2560{
2561 u32 i = va_arg (*va, u32);
2562 char * t = 0;
2563
2564 switch (i) {
2565 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
2566 foreach_vnet_dscp
2567 #undef _
2568 default:
2569 return format (s, "ILLEGAL");
2570 }
2571 s = format (s, "%s", t);
2572 return s;
2573}
2574
Matus Fabiane8554802016-05-18 23:40:37 -07002575static void vl_api_policer_details_t_handler
2576(vl_api_policer_details_t * mp)
2577{
2578 vat_main_t * vam = &vat_main;
Matus Fabian4ac74c92016-05-31 07:33:29 -07002579 u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2580
2581 if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2582 conform_dscp_str = format(0, "%U", format_dscp, mp->conform_dscp);
2583 else
2584 conform_dscp_str = format(0, "");
2585
2586 if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2587 exceed_dscp_str = format(0, "%U", format_dscp, mp->exceed_dscp);
2588 else
2589 exceed_dscp_str = format(0, "");
2590
2591 if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2592 violate_dscp_str = format(0, "%U", format_dscp, mp->violate_dscp);
2593 else
2594 violate_dscp_str = format(0, "");
Matus Fabiane8554802016-05-18 23:40:37 -07002595
2596 fformat (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2597 "rate type %U, round type %U, %s rate, %s color-aware, "
2598 "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
Matus Fabian4ac74c92016-05-31 07:33:29 -07002599 "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
2600 "conform action %U%s, exceed action %U%s, violate action %U%s\n",
Matus Fabiane8554802016-05-18 23:40:37 -07002601 mp->name,
2602 format_policer_type, mp->type,
2603 ntohl(mp->cir),
2604 ntohl(mp->eir),
Matus Fabian70e6a8d2016-06-20 08:10:42 -07002605 clib_net_to_host_u64(mp->cb),
2606 clib_net_to_host_u64(mp->eb),
Matus Fabiane8554802016-05-18 23:40:37 -07002607 format_policer_rate_type, mp->rate_type,
2608 format_policer_round_type, mp->round_type,
2609 mp->single_rate ? "single" : "dual",
2610 mp->color_aware ? "is" : "not",
2611 ntohl(mp->cir_tokens_per_period),
2612 ntohl(mp->pir_tokens_per_period),
2613 ntohl(mp->scale),
2614 ntohl(mp->current_limit),
2615 ntohl(mp->current_bucket),
2616 ntohl(mp->extended_limit),
2617 ntohl(mp->extended_bucket),
Matus Fabian4ac74c92016-05-31 07:33:29 -07002618 clib_net_to_host_u64(mp->last_update_time),
2619 format_policer_action_type, mp->conform_action_type,
2620 conform_dscp_str,
2621 format_policer_action_type, mp->exceed_action_type,
2622 exceed_dscp_str,
2623 format_policer_action_type, mp->violate_action_type,
2624 violate_dscp_str);
2625
2626 vec_free(conform_dscp_str);
2627 vec_free(exceed_dscp_str);
2628 vec_free(violate_dscp_str);
Matus Fabiane8554802016-05-18 23:40:37 -07002629}
2630
2631static void vl_api_policer_details_t_handler_json
2632(vl_api_policer_details_t * mp)
2633{
2634 vat_main_t * vam = &vat_main;
2635 vat_json_node_t *node;
2636 u8 *rate_type_str, *round_type_str, *type_str;
Matus Fabian4ac74c92016-05-31 07:33:29 -07002637 u8 *conform_action_str, *exceed_action_str, *violate_action_str;
Matus Fabiane8554802016-05-18 23:40:37 -07002638
2639 rate_type_str = format(0, "%U", format_policer_rate_type, mp->rate_type);
2640 round_type_str = format(0, "%U", format_policer_round_type, mp->round_type);
2641 type_str = format(0, "%U", format_policer_type, mp->type);
Matus Fabian4ac74c92016-05-31 07:33:29 -07002642 conform_action_str = format(0, "%U", format_policer_action_type,
2643 mp->conform_action_type);
2644 exceed_action_str = format(0, "%U", format_policer_action_type,
2645 mp->exceed_action_type);
2646 violate_action_str = format(0, "%U", format_policer_action_type,
2647 mp->violate_action_type);
Matus Fabiane8554802016-05-18 23:40:37 -07002648
2649 if (VAT_JSON_ARRAY != vam->json_tree.type) {
2650 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
2651 vat_json_init_array(&vam->json_tree);
2652 }
2653 node = vat_json_array_add(&vam->json_tree);
2654
2655 vat_json_init_object(node);
2656 vat_json_object_add_string_copy(node, "name", mp->name);
2657 vat_json_object_add_uint(node, "cir", ntohl(mp->cir));
2658 vat_json_object_add_uint(node, "eir", ntohl(mp->eir));
2659 vat_json_object_add_uint(node, "cb", ntohl(mp->cb));
2660 vat_json_object_add_uint(node, "eb", ntohl(mp->eb));
2661 vat_json_object_add_string_copy(node, "rate_type", rate_type_str);
2662 vat_json_object_add_string_copy(node, "round_type", round_type_str);
2663 vat_json_object_add_string_copy(node, "type", type_str);
2664 vat_json_object_add_uint(node, "single_rate", mp->single_rate);
2665 vat_json_object_add_uint(node, "color_aware", mp->color_aware);
2666 vat_json_object_add_uint(node, "scale", ntohl(mp->scale));
2667 vat_json_object_add_uint(node, "cir_tokens_per_period",
2668 ntohl(mp->cir_tokens_per_period));
2669 vat_json_object_add_uint(node, "eir_tokens_per_period",
2670 ntohl(mp->pir_tokens_per_period));
2671 vat_json_object_add_uint(node, "current_limit", ntohl(mp->current_limit));
2672 vat_json_object_add_uint(node, "current_bucket", ntohl(mp->current_bucket));
2673 vat_json_object_add_uint(node, "extended_limit", ntohl(mp->extended_limit));
2674 vat_json_object_add_uint(node, "extended_bucket",
2675 ntohl(mp->extended_bucket));
2676 vat_json_object_add_uint(node, "last_update_time",
2677 ntohl(mp->last_update_time));
Matus Fabian4ac74c92016-05-31 07:33:29 -07002678 vat_json_object_add_string_copy(node, "conform_action", conform_action_str);
2679 if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT) {
2680 u8 *dscp_str = format(0, "%U", format_dscp, mp->conform_dscp);
2681 vat_json_object_add_string_copy(node, "conform_dscp", dscp_str);
2682 vec_free(dscp_str);
2683 }
2684 vat_json_object_add_string_copy(node, "exceed_action", exceed_action_str);
2685 if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT) {
2686 u8 *dscp_str = format(0, "%U", format_dscp, mp->exceed_dscp);
2687 vat_json_object_add_string_copy(node, "exceed_dscp", dscp_str);
2688 vec_free(dscp_str);
2689 }
2690 vat_json_object_add_string_copy(node, "violate_action", violate_action_str);
2691 if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT) {
2692 u8 *dscp_str = format(0, "%U", format_dscp, mp->violate_dscp);
2693 vat_json_object_add_string_copy(node, "violate_dscp", dscp_str);
2694 vec_free(dscp_str);
2695 }
Matus Fabiane8554802016-05-18 23:40:37 -07002696
2697 vec_free(rate_type_str);
2698 vec_free(round_type_str);
2699 vec_free(type_str);
Matus Fabian4ac74c92016-05-31 07:33:29 -07002700 vec_free(conform_action_str);
2701 vec_free(exceed_action_str);
2702 vec_free(violate_action_str);
Matus Fabiane8554802016-05-18 23:40:37 -07002703}
2704
Pavel Kotucek20c90f72016-06-07 14:44:26 +02002705static void vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t * mp)
2706{
2707 vat_main_t * vam = &vat_main;
2708 int i, count = ntohl(mp->count);
2709
2710 if (count>0)
2711 fformat (vam->ofp, "classify table ids (%d) : ", count);
2712 for (i = 0; i < count; i++)
2713 {
2714 fformat (vam->ofp, "%d", ntohl(mp->ids[i]));
2715 fformat (vam->ofp, (i<count-1)?",":"\n");
2716 }
2717 vam->retval = ntohl(mp->retval);
2718 vam->result_ready = 1;
2719}
2720
2721static void vl_api_classify_table_ids_reply_t_handler_json (vl_api_classify_table_ids_reply_t * mp)
2722{
2723 vat_main_t * vam = &vat_main;
2724 int i, count = ntohl(mp->count);
2725
2726 if (count>0) {
2727 vat_json_node_t node;
2728
2729 vat_json_init_object(&node);
2730 for (i = 0; i < count; i++)
2731 {
2732 vat_json_object_add_uint(&node, "table_id", ntohl(mp->ids[i]));
2733 }
2734 vat_json_print(vam->ofp, &node);
2735 vat_json_free(&node);
2736 }
2737 vam->retval = ntohl(mp->retval);
2738 vam->result_ready = 1;
2739}
2740
2741static void vl_api_classify_table_by_interface_reply_t_handler (vl_api_classify_table_by_interface_reply_t * mp)
2742{
2743 vat_main_t * vam = &vat_main;
2744 u32 table_id;
2745
2746 table_id = ntohl(mp->l2_table_id);
2747 if (table_id != ~0)
2748 fformat (vam->ofp, "l2 table id : %d\n", table_id);
2749 else
2750 fformat (vam->ofp, "l2 table id : No input ACL tables configured\n");
2751 table_id = ntohl(mp->ip4_table_id);
2752 if (table_id != ~0)
2753 fformat (vam->ofp, "ip4 table id : %d\n", table_id);
2754 else
2755 fformat (vam->ofp, "ip4 table id : No input ACL tables configured\n");
2756 table_id = ntohl(mp->ip6_table_id);
2757 if (table_id != ~0)
2758 fformat (vam->ofp, "ip6 table id : %d\n", table_id);
2759 else
2760 fformat (vam->ofp, "ip6 table id : No input ACL tables configured\n");
2761 vam->retval = ntohl(mp->retval);
2762 vam->result_ready = 1;
2763}
2764
2765static void vl_api_classify_table_by_interface_reply_t_handler_json (vl_api_classify_table_by_interface_reply_t * mp)
2766{
2767 vat_main_t * vam = &vat_main;
2768 vat_json_node_t node;
2769
2770 vat_json_init_object(&node);
2771
2772 vat_json_object_add_int(&node, "l2_table_id", ntohl(mp->l2_table_id));
2773 vat_json_object_add_int(&node, "ip4_table_id", ntohl(mp->ip4_table_id));
2774 vat_json_object_add_int(&node, "ip6_table_id", ntohl(mp->ip6_table_id));
2775
2776 vat_json_print(vam->ofp, &node);
2777 vat_json_free(&node);
2778
2779 vam->retval = ntohl(mp->retval);
2780 vam->result_ready = 1;
2781}
2782
Matus Fabian70e6a8d2016-06-20 08:10:42 -07002783static void vl_api_policer_add_del_reply_t_handler
2784(vl_api_policer_add_del_reply_t * mp)
2785{
2786 vat_main_t * vam = &vat_main;
2787 i32 retval = ntohl(mp->retval);
2788 if (vam->async_mode) {
2789 vam->async_errors += (retval < 0);
2790 } else {
2791 vam->retval = retval;
2792 vam->result_ready = 1;
2793 if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
2794 /*
2795 * Note: this is just barely thread-safe, depends on
2796 * the main thread spinning waiting for an answer...
2797 */
2798 errmsg ("policer index %d\n", ntohl(mp->policer_index));
2799 }
2800}
2801
2802static void vl_api_policer_add_del_reply_t_handler_json
2803(vl_api_policer_add_del_reply_t * mp)
2804{
2805 vat_main_t * vam = &vat_main;
2806 vat_json_node_t node;
2807
2808 vat_json_init_object(&node);
2809 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
2810 vat_json_object_add_uint(&node, "policer_index", ntohl(mp->policer_index));
2811
2812 vat_json_print(vam->ofp, &node);
2813 vat_json_free(&node);
2814
2815 vam->retval = ntohl(mp->retval);
2816 vam->result_ready = 1;
2817}
2818
Pavel Kotucek20c90f72016-06-07 14:44:26 +02002819/* Format hex dump. */
2820u8 * format_hex_bytes (u8 * s, va_list * va)
2821{
2822 u8 * bytes = va_arg (*va, u8 *);
2823 int n_bytes = va_arg (*va, int);
2824 uword i;
2825
2826 /* Print short or long form depending on byte count. */
2827 uword short_form = n_bytes <= 32;
2828 uword indent = format_get_indent (s);
2829
2830 if (n_bytes == 0)
2831 return s;
2832
2833 for (i = 0; i < n_bytes; i++)
2834 {
2835 if (! short_form && (i % 32) == 0)
2836 s = format (s, "%08x: ", i);
2837 s = format (s, "%02x", bytes[i]);
2838 if (! short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
2839 s = format (s, "\n%U", format_white_space, indent);
2840 }
2841
2842 return s;
2843}
2844
2845static void vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t * mp)
2846{
2847 vat_main_t * vam = &vat_main;
2848 i32 retval = ntohl(mp->retval);
2849 if (retval == 0) {
2850 fformat (vam->ofp, "classify table info :\n");
2851 fformat (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d\n", ntohl(mp->active_sessions), ntohl(mp->next_table_index), ntohl(mp->miss_next_index));
2852 fformat (vam->ofp, "nbuckets: %d skip: %d match: %d\n", ntohl(mp->nbuckets), ntohl(mp->skip_n_vectors), ntohl(mp->match_n_vectors));
2853 fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->mask, ntohl(mp->mask_length));
2854 }
2855 vam->retval = retval;
2856 vam->result_ready = 1;
2857}
2858
2859static void vl_api_classify_table_info_reply_t_handler_json (vl_api_classify_table_info_reply_t * mp)
2860{
2861 vat_main_t * vam = &vat_main;
2862 vat_json_node_t node;
2863
2864 i32 retval = ntohl(mp->retval);
2865 if (retval == 0) {
2866 vat_json_init_object(&node);
2867
2868 vat_json_object_add_int(&node, "sessions", ntohl(mp->active_sessions));
2869 vat_json_object_add_int(&node, "nexttbl", ntohl(mp->next_table_index));
2870 vat_json_object_add_int(&node, "nextnode", ntohl(mp->miss_next_index));
2871 vat_json_object_add_int(&node, "nbuckets", ntohl(mp->nbuckets));
2872 vat_json_object_add_int(&node, "skip", ntohl(mp->skip_n_vectors));
2873 vat_json_object_add_int(&node, "match", ntohl(mp->match_n_vectors));
2874 u8 * s = format (0, "%U%c",format_hex_bytes, mp->mask, ntohl(mp->mask_length), 0);
2875 vat_json_object_add_string_copy(&node, "mask", s);
2876
2877 vat_json_print(vam->ofp, &node);
2878 vat_json_free(&node);
2879 }
2880 vam->retval = ntohl(mp->retval);
2881 vam->result_ready = 1;
2882}
2883
2884static void vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t * mp)
2885{
2886 vat_main_t * vam = &vat_main;
2887
2888 fformat (vam->ofp, "next_index: %d advance: %d opaque: %d ", ntohl(mp->hit_next_index), ntohl(mp->advance), ntohl(mp->opaque_index));
2889 fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->match, ntohl(mp->match_length));
2890}
2891
2892static void vl_api_classify_session_details_t_handler_json (vl_api_classify_session_details_t * mp)
2893{
2894 vat_main_t * vam = &vat_main;
2895 vat_json_node_t *node = NULL;
2896
2897 if (VAT_JSON_ARRAY != vam->json_tree.type) {
2898 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
2899 vat_json_init_array(&vam->json_tree);
2900 }
2901 node = vat_json_array_add(&vam->json_tree);
2902
2903 vat_json_init_object(node);
2904 vat_json_object_add_int(node, "next_index", ntohl(mp->hit_next_index));
2905 vat_json_object_add_int(node, "advance", ntohl(mp->advance));
2906 vat_json_object_add_int(node, "opaque", ntohl(mp->opaque_index));
2907 u8 * s = format (0, "%U%c",format_hex_bytes, mp->match, ntohl(mp->match_length), 0);
2908 vat_json_object_add_string_copy(node, "match", s);
2909}
Matus Fabiane8554802016-05-18 23:40:37 -07002910
Pavel Kotucek9e6ed6e2016-07-12 10:18:26 +02002911static void vl_api_pg_create_interface_reply_t_handler
2912(vl_api_pg_create_interface_reply_t * mp)
2913{
2914 vat_main_t * vam = &vat_main;
2915
2916 vam->retval = ntohl(mp->retval);
2917 vam->result_ready = 1;
2918}
2919
2920static void vl_api_pg_create_interface_reply_t_handler_json
2921(vl_api_pg_create_interface_reply_t * mp)
2922{
2923 vat_main_t * vam = &vat_main;
2924 vat_json_node_t node;
2925
2926 i32 retval = ntohl(mp->retval);
2927 if (retval == 0) {
2928 vat_json_init_object(&node);
2929
2930 vat_json_object_add_int(&node, "sw_if_index", ntohl(mp->sw_if_index));
2931
2932 vat_json_print(vam->ofp, &node);
2933 vat_json_free(&node);
2934 }
2935 vam->retval = ntohl(mp->retval);
2936 vam->result_ready = 1;
2937}
2938
Matus Fabian70e6a8d2016-06-20 08:10:42 -07002939static void vl_api_policer_classify_details_t_handler
2940(vl_api_policer_classify_details_t * mp)
2941{
2942 vat_main_t * vam = &vat_main;
2943
2944 fformat (vam->ofp, "%10d%20d\n", ntohl(mp->sw_if_index),
2945 ntohl(mp->table_index));
2946}
2947
2948static void vl_api_policer_classify_details_t_handler_json
2949(vl_api_policer_classify_details_t * mp)
2950{
2951 vat_main_t * vam = &vat_main;
2952 vat_json_node_t * node;
2953
2954 if (VAT_JSON_ARRAY != vam->json_tree.type) {
2955 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
2956 vat_json_init_array(&vam->json_tree);
2957 }
2958 node = vat_json_array_add(&vam->json_tree);
2959
2960 vat_json_init_object(node);
2961 vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
2962 vat_json_object_add_uint(node, "table_index", ntohl(mp->table_index));
2963}
2964
2965
Ed Warnickecb9cada2015-12-08 15:45:58 -07002966#define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
2967#define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
2968#define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
2969#define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
2970
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08002971/*
Pavel Kotucek9e6ed6e2016-07-12 10:18:26 +02002972 * Generate boilerplate reply handlers, which
Ed Warnickecb9cada2015-12-08 15:45:58 -07002973 * dig the return value out of the xxx_reply_t API message,
2974 * stick it into vam->retval, and set vam->result_ready
2975 *
2976 * Could also do this by pointing N message decode slots at
2977 * a single function, but that could break in subtle ways.
2978 */
2979
2980#define foreach_standard_reply_retval_handler \
2981_(sw_interface_set_flags_reply) \
2982_(sw_interface_add_del_address_reply) \
2983_(sw_interface_set_table_reply) \
2984_(sw_interface_set_vpath_reply) \
2985_(sw_interface_set_l2_bridge_reply) \
2986_(bridge_domain_add_del_reply) \
2987_(sw_interface_set_l2_xconnect_reply) \
2988_(l2fib_add_del_reply) \
2989_(ip_add_del_route_reply) \
2990_(proxy_arp_add_del_reply) \
2991_(proxy_arp_intfc_enable_disable_reply) \
2992_(mpls_add_del_encap_reply) \
2993_(mpls_add_del_decap_reply) \
2994_(mpls_ethernet_add_del_tunnel_2_reply) \
2995_(sw_interface_set_unnumbered_reply) \
2996_(ip_neighbor_add_del_reply) \
2997_(reset_vrf_reply) \
2998_(oam_add_del_reply) \
2999_(reset_fib_reply) \
3000_(dhcp_proxy_config_reply) \
3001_(dhcp_proxy_config_2_reply) \
3002_(dhcp_proxy_set_vss_reply) \
3003_(dhcp_client_config_reply) \
3004_(set_ip_flow_hash_reply) \
3005_(sw_interface_ip6_enable_disable_reply) \
3006_(sw_interface_ip6_set_link_local_address_reply) \
3007_(sw_interface_ip6nd_ra_prefix_reply) \
3008_(sw_interface_ip6nd_ra_config_reply) \
3009_(set_arp_neighbor_limit_reply) \
3010_(l2_patch_add_del_reply) \
3011_(sr_tunnel_add_del_reply) \
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07003012_(sr_policy_add_del_reply) \
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07003013_(sr_multicast_map_add_del_reply) \
Ed Warnickecb9cada2015-12-08 15:45:58 -07003014_(classify_add_del_session_reply) \
3015_(classify_set_interface_ip_table_reply) \
3016_(classify_set_interface_l2_tables_reply) \
3017_(l2tpv3_set_tunnel_cookies_reply) \
3018_(l2tpv3_interface_enable_disable_reply) \
3019_(l2tpv3_set_lookup_key_reply) \
3020_(l2_fib_clear_table_reply) \
3021_(l2_interface_efp_filter_reply) \
3022_(l2_interface_vlan_tag_rewrite_reply) \
3023_(modify_vhost_user_if_reply) \
3024_(delete_vhost_user_if_reply) \
3025_(want_ip4_arp_events_reply) \
3026_(input_acl_set_interface_reply) \
3027_(ipsec_spd_add_del_reply) \
3028_(ipsec_interface_add_del_spd_reply) \
3029_(ipsec_spd_add_del_entry_reply) \
3030_(ipsec_sad_add_del_entry_reply) \
3031_(ipsec_sa_set_key_reply) \
Matus Fabiane5f42fe2016-04-08 11:18:08 +02003032_(ikev2_profile_add_del_reply) \
3033_(ikev2_profile_set_auth_reply) \
3034_(ikev2_profile_set_id_reply) \
3035_(ikev2_profile_set_ts_reply) \
3036_(ikev2_set_local_key_reply) \
Ed Warnickecb9cada2015-12-08 15:45:58 -07003037_(delete_loopback_reply) \
3038_(bd_ip_mac_add_del_reply) \
3039_(map_del_domain_reply) \
3040_(map_add_del_rule_reply) \
3041_(want_interface_events_reply) \
Dave Barachc07bf5d2016-02-17 17:52:26 -05003042_(want_stats_reply) \
3043_(cop_interface_enable_disable_reply) \
Pavel Kotucek00bbf272016-03-03 13:27:11 +01003044_(cop_whitelist_enable_disable_reply) \
Shwetha20a64f52016-03-25 10:55:01 +00003045_(sw_interface_clear_stats_reply) \
3046_(trace_profile_add_reply) \
3047_(trace_profile_apply_reply) \
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02003048_(trace_profile_del_reply) \
3049_(lisp_add_del_locator_set_reply) \
3050_(lisp_add_del_locator_reply) \
3051_(lisp_add_del_local_eid_reply) \
Florin Corasf727db92016-06-23 15:01:58 +02003052_(lisp_add_del_remote_mapping_reply) \
3053_(lisp_add_del_adjacency_reply) \
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02003054_(lisp_gpe_add_del_fwd_entry_reply) \
3055_(lisp_add_del_map_resolver_reply) \
Florin Coras577c3552016-04-21 00:45:40 +02003056_(lisp_gpe_enable_disable_reply) \
Matus Fabian8a95a482016-05-06 15:14:13 +02003057_(lisp_gpe_add_del_iface_reply) \
Filip Tehlar46d4e362016-05-09 09:39:26 +02003058_(lisp_enable_disable_reply) \
Filip Tehlar53f09e32016-05-19 14:25:44 +02003059_(lisp_pitr_set_locator_set_reply) \
Andrej Kozemcakb6e4d392016-06-14 13:55:57 +02003060_(lisp_add_del_map_request_itr_rlocs_reply) \
Filip Tehlar324112f2016-06-02 16:07:38 +02003061_(lisp_eid_table_add_del_map_reply) \
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07003062_(vxlan_gpe_add_del_tunnel_reply) \
Matus Fabian65fcd4d2016-05-13 05:44:48 -07003063_(af_packet_delete_reply) \
Matus Fabian70e6a8d2016-06-20 08:10:42 -07003064_(policer_classify_set_interface_reply) \
Matus Fabian82e29c42016-05-11 04:49:46 -07003065_(netmap_create_reply) \
Juraj Slobodaac645ad2016-07-07 00:18:57 -07003066_(netmap_delete_reply) \
Pavel Kotucek9e6ed6e2016-07-12 10:18:26 +02003067_(ipfix_enable_reply) \
3068_(pg_capture_reply) \
3069_(pg_enable_disable_reply)
Ed Warnickecb9cada2015-12-08 15:45:58 -07003070
3071#define _(n) \
3072 static void vl_api_##n##_t_handler \
3073 (vl_api_##n##_t * mp) \
3074 { \
3075 vat_main_t * vam = &vat_main; \
3076 i32 retval = ntohl(mp->retval); \
3077 if (vam->async_mode) { \
3078 vam->async_errors += (retval < 0); \
3079 } else { \
3080 vam->retval = retval; \
3081 vam->result_ready = 1; \
3082 } \
3083 }
3084foreach_standard_reply_retval_handler;
3085#undef _
3086
3087#define _(n) \
3088 static void vl_api_##n##_t_handler_json \
3089 (vl_api_##n##_t * mp) \
3090 { \
3091 vat_main_t * vam = &vat_main; \
3092 vat_json_node_t node; \
3093 vat_json_init_object(&node); \
3094 vat_json_object_add_int(&node, "retval", ntohl(mp->retval)); \
3095 vat_json_print(vam->ofp, &node); \
3096 vam->retval = ntohl(mp->retval); \
3097 vam->result_ready = 1; \
3098 }
3099foreach_standard_reply_retval_handler;
3100#undef _
3101
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08003102/*
Ed Warnickecb9cada2015-12-08 15:45:58 -07003103 * Table of message reply handlers, must include boilerplate handlers
3104 * we just generated
3105 */
3106
3107#define foreach_vpe_api_reply_msg \
3108_(CREATE_LOOPBACK_REPLY, create_loopback_reply) \
3109_(SW_INTERFACE_DETAILS, sw_interface_details) \
3110_(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags) \
3111_(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply) \
3112_(CONTROL_PING_REPLY, control_ping_reply) \
Andrej Kozemcakd9831182016-06-20 08:47:57 +02003113_(NOPRINT_CONTROL_PING_REPLY, noprint_control_ping_reply) \
Ed Warnickecb9cada2015-12-08 15:45:58 -07003114_(CLI_REPLY, cli_reply) \
3115_(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY, \
3116 sw_interface_add_del_address_reply) \
3117_(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply) \
3118_(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply) \
3119_(SW_INTERFACE_SET_L2_XCONNECT_REPLY, \
3120 sw_interface_set_l2_xconnect_reply) \
3121_(SW_INTERFACE_SET_L2_BRIDGE_REPLY, \
3122 sw_interface_set_l2_bridge_reply) \
3123_(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply) \
3124_(BRIDGE_DOMAIN_DETAILS, bridge_domain_details) \
3125_(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details) \
3126_(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply) \
3127_(L2_FLAGS_REPLY, l2_flags_reply) \
3128_(BRIDGE_FLAGS_REPLY, bridge_flags_reply) \
3129_(TAP_CONNECT_REPLY, tap_connect_reply) \
3130_(TAP_MODIFY_REPLY, tap_modify_reply) \
3131_(TAP_DELETE_REPLY, tap_delete_reply) \
3132_(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details) \
3133_(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply) \
3134_(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply) \
3135_(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY, \
3136 proxy_arp_intfc_enable_disable_reply) \
3137_(MPLS_ADD_DEL_ENCAP_REPLY, mpls_add_del_encap_reply) \
3138_(MPLS_ADD_DEL_DECAP_REPLY, mpls_add_del_decap_reply) \
3139_(MPLS_GRE_ADD_DEL_TUNNEL_REPLY, mpls_gre_add_del_tunnel_reply) \
3140_(MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY, \
3141 mpls_ethernet_add_del_tunnel_reply) \
3142_(MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY, \
3143 mpls_ethernet_add_del_tunnel_2_reply) \
3144_(SW_INTERFACE_SET_UNNUMBERED_REPLY, \
3145 sw_interface_set_unnumbered_reply) \
3146_(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply) \
3147_(RESET_VRF_REPLY, reset_vrf_reply) \
3148_(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply) \
3149_(CREATE_SUBIF_REPLY, create_subif_reply) \
3150_(OAM_ADD_DEL_REPLY, oam_add_del_reply) \
3151_(RESET_FIB_REPLY, reset_fib_reply) \
3152_(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply) \
3153_(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply) \
3154_(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply) \
3155_(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply) \
3156_(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply) \
3157_(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY, \
3158 sw_interface_ip6_enable_disable_reply) \
3159_(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY, \
3160 sw_interface_ip6_set_link_local_address_reply) \
3161_(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY, \
3162 sw_interface_ip6nd_ra_prefix_reply) \
3163_(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY, \
3164 sw_interface_ip6nd_ra_config_reply) \
3165_(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply) \
3166_(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply) \
3167_(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply) \
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07003168_(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply) \
3169_(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply) \
Ed Warnickecb9cada2015-12-08 15:45:58 -07003170_(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply) \
3171_(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply) \
3172_(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY, \
3173classify_set_interface_ip_table_reply) \
3174_(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY, \
3175 classify_set_interface_l2_tables_reply) \
3176_(GET_NODE_INDEX_REPLY, get_node_index_reply) \
3177_(ADD_NODE_NEXT_REPLY, add_node_next_reply) \
3178_(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply) \
3179_(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply) \
3180_(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY, \
3181 l2tpv3_interface_enable_disable_reply) \
3182_(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply) \
3183_(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details) \
3184_(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply) \
Dave Wallace60231f32015-12-17 21:04:30 -05003185_(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details) \
Chris Luke27fe48f2016-04-28 13:44:38 -04003186_(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply) \
3187_(GRE_TUNNEL_DETAILS, gre_tunnel_details) \
Ed Warnickecb9cada2015-12-08 15:45:58 -07003188_(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply) \
3189_(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply) \
3190_(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3191_(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details) \
3192_(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply) \
3193_(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply) \
3194_(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply) \
3195_(SHOW_VERSION_REPLY, show_version_reply) \
Ed Warnickecb9cada2015-12-08 15:45:58 -07003196_(L2_FIB_TABLE_ENTRY, l2_fib_table_entry) \
Hongjun Ni0e06e2b2016-05-30 19:45:51 +08003197_(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply) \
3198_(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details) \
Ed Warnickecb9cada2015-12-08 15:45:58 -07003199_(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply) \
3200_(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply) \
3201_(IP4_ARP_EVENT, ip4_arp_event) \
3202_(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply) \
3203_(IP_ADDRESS_DETAILS, ip_address_details) \
3204_(IP_DETAILS, ip_details) \
3205_(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply) \
3206_(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3207_(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply) \
3208_(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply) \
3209_(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply) \
Matus Fabiane5f42fe2016-04-08 11:18:08 +02003210_(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply) \
3211_(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply) \
3212_(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply) \
3213_(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply) \
3214_(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply) \
Ed Warnickecb9cada2015-12-08 15:45:58 -07003215_(DELETE_LOOPBACK_REPLY, delete_loopback_reply) \
3216_(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply) \
3217_(DHCP_COMPL_EVENT, dhcp_compl_event) \
3218_(VNET_INTERFACE_COUNTERS, vnet_interface_counters) \
3219_(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters) \
3220_(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters) \
3221_(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply) \
3222_(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply) \
Dave Barachc07bf5d2016-02-17 17:52:26 -05003223_(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply) \
Ed Warnickecb9cada2015-12-08 15:45:58 -07003224_(MAP_DOMAIN_DETAILS, map_domain_details) \
3225_(MAP_RULE_DETAILS, map_rule_details) \
3226_(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply) \
3227_(WANT_STATS_REPLY, want_stats_reply) \
Dave Barachc07bf5d2016-02-17 17:52:26 -05003228_(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply) \
3229_(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
Dave Barachb44e9bc2016-02-19 09:06:23 -05003230_(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
Pavel Kotucek00bbf272016-03-03 13:27:11 +01003231_(GET_NODE_GRAPH_REPLY, get_node_graph_reply) \
Shwetha20a64f52016-03-25 10:55:01 +00003232_(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply) \
3233_(TRACE_PROFILE_ADD_REPLY, trace_profile_add_reply) \
3234_(TRACE_PROFILE_APPLY_REPLY, trace_profile_apply_reply) \
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02003235_(TRACE_PROFILE_DEL_REPLY, trace_profile_del_reply) \
3236_(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply) \
3237_(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply) \
3238_(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply) \
Florin Corasf727db92016-06-23 15:01:58 +02003239_(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3240_(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply) \
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02003241_(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply) \
3242_(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply) \
Florin Coras577c3552016-04-21 00:45:40 +02003243_(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply) \
Filip Tehlar46d4e362016-05-09 09:39:26 +02003244_(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply) \
Filip Tehlar53f09e32016-05-19 14:25:44 +02003245_(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply) \
Filip Tehlar324112f2016-06-02 16:07:38 +02003246_(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply) \
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02003247_(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply) \
3248_(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details) \
Andrej Kozemcakd9831182016-06-20 08:47:57 +02003249_(LISP_LOCATOR_DETAILS, lisp_locator_details) \
Andrej Kozemcak6cc6f912016-07-13 13:01:01 +02003250_(LISP_EID_TABLE_DETAILS, lisp_eid_table_details) \
Filip Tehlar2f653d02016-07-13 13:17:15 +02003251_(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details) \
Andrej Kozemcakb92feb62016-03-31 13:51:42 +02003252_(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details) \
Andrej Kozemcaka9edd852016-05-02 12:14:33 +02003253_(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details) \
Andrej Kozemcakd9831182016-06-20 08:47:57 +02003254_(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply) \
Andrej Kozemcakb6e4d392016-06-14 13:55:57 +02003255_(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY, \
3256 lisp_add_del_map_request_itr_rlocs_reply) \
3257_(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY, \
3258 lisp_get_map_request_itr_rlocs_reply) \
Andrej Kozemcak914f91b2016-07-18 13:55:37 +02003259_(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply) \
Matus Fabian8a95a482016-05-06 15:14:13 +02003260_(AF_PACKET_CREATE_REPLY, af_packet_create_reply) \
Matus Fabian65fcd4d2016-05-13 05:44:48 -07003261_(AF_PACKET_DELETE_REPLY, af_packet_delete_reply) \
Matus Fabian82e29c42016-05-11 04:49:46 -07003262_(POLICER_ADD_DEL_REPLY, policer_add_del_reply) \
Matus Fabiane8554802016-05-18 23:40:37 -07003263_(POLICER_DETAILS, policer_details) \
Matus Fabian70e6a8d2016-06-20 08:10:42 -07003264_(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3265_(POLICER_CLASSIFY_DETAILS, policer_classify_details) \
Matus Fabian82e29c42016-05-11 04:49:46 -07003266_(NETMAP_CREATE_REPLY, netmap_create_reply) \
marek zavodsky2c21a9a2016-06-21 05:35:16 +02003267_(NETMAP_DELETE_REPLY, netmap_delete_reply) \
3268_(MPLS_GRE_TUNNEL_DETAILS, mpls_gre_tunnel_details) \
3269_(MPLS_ETH_TUNNEL_DETAILS, mpls_eth_tunnel_details) \
3270_(MPLS_FIB_ENCAP_DETAILS, mpls_fib_encap_details) \
Pavel Kotucek20c90f72016-06-07 14:44:26 +02003271_(MPLS_FIB_DECAP_DETAILS, mpls_fib_decap_details) \
3272_(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply) \
3273_(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3274_(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply) \
Juraj Slobodaac645ad2016-07-07 00:18:57 -07003275_(CLASSIFY_SESSION_DETAILS, classify_session_details) \
3276_(IPFIX_ENABLE_REPLY, ipfix_enable_reply) \
Keith Burns (alagalah)c61080e2016-07-19 14:47:43 -07003277_(IPFIX_DETAILS, ipfix_details) \
Pavel Kotucek9e6ed6e2016-07-12 10:18:26 +02003278_(GET_NEXT_INDEX_REPLY, get_next_index_reply) \
3279_(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply) \
3280_(PG_CAPTURE_REPLY, pg_capture_reply) \
3281_(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)
Ed Warnickecb9cada2015-12-08 15:45:58 -07003282
3283/* M: construct, but don't yet send a message */
3284
3285#define M(T,t) \
3286do { \
3287 vam->result_ready = 0; \
3288 mp = vl_msg_api_alloc(sizeof(*mp)); \
3289 memset (mp, 0, sizeof (*mp)); \
3290 mp->_vl_msg_id = ntohs (VL_API_##T); \
3291 mp->client_index = vam->my_client_index; \
3292} while(0);
3293
3294#define M2(T,t,n) \
3295do { \
3296 vam->result_ready = 0; \
3297 mp = vl_msg_api_alloc(sizeof(*mp)+(n)); \
3298 memset (mp, 0, sizeof (*mp)); \
3299 mp->_vl_msg_id = ntohs (VL_API_##T); \
3300 mp->client_index = vam->my_client_index; \
3301} while(0);
3302
3303
3304/* S: send a message */
3305#define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3306
3307/* W: wait for results, with timeout */
3308#define W \
3309do { \
3310 timeout = vat_time_now (vam) + 1.0; \
3311 \
3312 while (vat_time_now (vam) < timeout) { \
3313 if (vam->result_ready == 1) { \
3314 return (vam->retval); \
3315 } \
3316 } \
3317 return -99; \
3318} while(0);
3319
Keith Burns (alagalah)802255c2016-06-13 16:56:04 -07003320/* W2: wait for results, with timeout */
3321#define W2(body) \
3322do { \
3323 timeout = vat_time_now (vam) + 1.0; \
3324 \
3325 while (vat_time_now (vam) < timeout) { \
3326 if (vam->result_ready == 1) { \
3327 (body); \
3328 return (vam->retval); \
3329 } \
3330 } \
3331 return -99; \
3332} while(0);
3333
Andrej Kozemcakd9831182016-06-20 08:47:57 +02003334/* W_L: wait for results, with timeout */
3335#define W_L(body) \
3336do { \
3337 timeout = vat_time_now (vam) + 1.0; \
3338 \
3339 while (vat_time_now (vam) < timeout) { \
3340 if (vam->result_ready == 1) { \
3341 (body); \
3342 return (vam->retval); \
3343 } \
3344 } \
3345 vam->noprint_msg = 0; \
3346 return -99; \
3347} while(0);
3348
Ed Warnickecb9cada2015-12-08 15:45:58 -07003349typedef struct {
3350 u8 * name;
3351 u32 value;
3352} name_sort_t;
3353
3354
3355#define STR_VTR_OP_CASE(op) \
3356 case L2_VTR_ ## op: \
3357 return "" # op;
3358
3359static const char *str_vtr_op(u32 vtr_op)
3360{
3361 switch(vtr_op) {
3362 STR_VTR_OP_CASE(DISABLED);
3363 STR_VTR_OP_CASE(PUSH_1);
3364 STR_VTR_OP_CASE(PUSH_2);
3365 STR_VTR_OP_CASE(POP_1);
3366 STR_VTR_OP_CASE(POP_2);
3367 STR_VTR_OP_CASE(TRANSLATE_1_1);
3368 STR_VTR_OP_CASE(TRANSLATE_1_2);
3369 STR_VTR_OP_CASE(TRANSLATE_2_1);
3370 STR_VTR_OP_CASE(TRANSLATE_2_2);
3371 }
3372
3373 return "UNKNOWN";
3374}
3375
3376static int dump_sub_interface_table (vat_main_t * vam)
3377{
3378 const sw_interface_subif_t * sub = NULL;
3379
3380 if (vam->json_output) {
3381 clib_warning ("JSON output supported only for VPE API calls and dump_stats_table");
3382 return -99;
3383 }
3384
3385 fformat (vam->ofp,
3386 "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
3387 "Interface", "sw_if_index",
3388 "sub id", "dot1ad", "tags", "outer id",
3389 "inner id", "exact", "default",
3390 "outer any", "inner any");
3391
3392 vec_foreach (sub, vam->sw_if_subif_table) {
3393 fformat (vam->ofp,
3394 "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
3395 sub->interface_name,
3396 sub->sw_if_index,
3397 sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3398 sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3399 sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3400 sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3401 if (sub->vtr_op != L2_VTR_DISABLED) {
3402 fformat (vam->ofp,
3403 " vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3404 "tag1: %d tag2: %d ]\n",
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08003405 str_vtr_op(sub->vtr_op), sub->vtr_push_dot1q,
Ed Warnickecb9cada2015-12-08 15:45:58 -07003406 sub->vtr_tag1, sub->vtr_tag2);
3407 }
3408 }
3409
3410 return 0;
3411}
3412
Matus Fabiand2dc3df2015-12-14 10:31:33 -05003413static int name_sort_cmp (void * a1, void * a2)
3414{
3415 name_sort_t * n1 = a1;
3416 name_sort_t * n2 = a2;
3417
3418 return strcmp ((char *)n1->name, (char *)n2->name);
3419}
3420
Ed Warnickecb9cada2015-12-08 15:45:58 -07003421static int dump_interface_table (vat_main_t * vam)
3422{
3423 hash_pair_t * p;
3424 name_sort_t * nses = 0, * ns;
3425
3426 if (vam->json_output) {
3427 clib_warning ("JSON output supported only for VPE API calls and dump_stats_table");
3428 return -99;
3429 }
3430
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08003431 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
Ed Warnickecb9cada2015-12-08 15:45:58 -07003432 ({
3433 vec_add2 (nses, ns, 1);
3434 ns->name = (u8 *)(p->key);
3435 ns->value = (u32) p->value[0];
3436 }));
3437
Matus Fabiand2dc3df2015-12-14 10:31:33 -05003438 vec_sort_with_function (nses, name_sort_cmp);
Ed Warnickecb9cada2015-12-08 15:45:58 -07003439
3440 fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
3441 vec_foreach (ns, nses) {
3442 fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
3443 }
3444 vec_free (nses);
3445 return 0;
3446}
3447
3448static int dump_ip_table (vat_main_t * vam, int is_ipv6)
3449{
3450 const ip_details_t * det = NULL;
3451 const ip_address_details_t * address = NULL;
3452 u32 i = ~0;
3453
3454 fformat (vam->ofp,
3455 "%-12s\n",
3456 "sw_if_index");
3457
Damjan Marionfa693552016-04-26 19:30:36 +02003458 if (0 == vam) {
Ed Warnickecb9cada2015-12-08 15:45:58 -07003459 return 0;
3460 }
3461
3462 vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6]) {
3463 i++;
3464 if (!det->present) {
3465 continue;
3466 }
3467 fformat (vam->ofp,
3468 "%-12d\n",
3469 i);
3470 fformat (vam->ofp,
3471 " %-30s%-13s\n",
3472 "Address", "Prefix length");
3473 if (!det->addr) {
3474 continue;
3475 }
3476 vec_foreach (address, det->addr) {
3477 fformat (vam->ofp,
3478 " %-30U%-13d\n",
3479 is_ipv6 ? format_ip6_address : format_ip4_address,
3480 address->ip,
3481 address->prefix_length);
3482 }
3483 }
3484
3485 return 0;
3486}
3487
3488static int dump_ipv4_table (vat_main_t * vam)
3489{
3490 if (vam->json_output) {
3491 clib_warning ("JSON output supported only for VPE API calls and dump_stats_table");
3492 return -99;
3493 }
3494
3495 return dump_ip_table (vam, 0);
3496}
3497
3498static int dump_ipv6_table (vat_main_t * vam)
3499{
3500 if (vam->json_output) {
3501 clib_warning ("JSON output supported only for VPE API calls and dump_stats_table");
3502 return -99;
3503 }
3504
3505 return dump_ip_table (vam, 1);
3506}
3507
3508static char* counter_type_to_str (u8 counter_type, u8 is_combined)
3509{
3510 if (!is_combined) {
3511 switch(counter_type) {
3512 case VNET_INTERFACE_COUNTER_DROP:
3513 return "drop";
3514 case VNET_INTERFACE_COUNTER_PUNT:
3515 return "punt";
3516 case VNET_INTERFACE_COUNTER_IP4:
3517 return "ip4";
3518 case VNET_INTERFACE_COUNTER_IP6:
3519 return "ip6";
3520 case VNET_INTERFACE_COUNTER_RX_NO_BUF:
3521 return "rx-no-buf";
3522 case VNET_INTERFACE_COUNTER_RX_MISS:
3523 return "rx-miss";
3524 case VNET_INTERFACE_COUNTER_RX_ERROR:
3525 return "rx-error";
3526 case VNET_INTERFACE_COUNTER_TX_ERROR:
3527 return "tx-error";
3528 default:
3529 return "INVALID-COUNTER-TYPE";
3530 }
3531 } else {
3532 switch(counter_type) {
3533 case VNET_INTERFACE_COUNTER_RX:
3534 return "rx";
3535 case VNET_INTERFACE_COUNTER_TX:
3536 return "tx";
3537 default:
3538 return "INVALID-COUNTER-TYPE";
3539 }
3540 }
3541}
3542
3543static int dump_stats_table (vat_main_t * vam)
3544{
3545 vat_json_node_t node;
3546 vat_json_node_t *msg_array;
3547 vat_json_node_t *msg;
3548 vat_json_node_t *counter_array;
3549 vat_json_node_t *counter;
3550 interface_counter_t c;
3551 u64 packets;
3552 ip4_fib_counter_t *c4;
3553 ip6_fib_counter_t *c6;
3554 int i, j;
3555
3556 if (!vam->json_output) {
3557 clib_warning ("dump_stats_table supported only in JSON format");
3558 return -99;
3559 }
3560
3561 vat_json_init_object(&node);
3562
3563 /* interface counters */
3564 msg_array = vat_json_object_add(&node, "interface_counters");
3565 vat_json_init_array(msg_array);
3566 for (i = 0; i < vec_len(vam->simple_interface_counters); i++) {
3567 msg = vat_json_array_add(msg_array);
3568 vat_json_init_object(msg);
3569 vat_json_object_add_string_copy(msg, "vnet_counter_type",
3570 (u8*)counter_type_to_str(i, 0));
3571 vat_json_object_add_int(msg, "is_combined", 0);
3572 counter_array = vat_json_object_add(msg, "data");
3573 vat_json_init_array(counter_array);
3574 for (j = 0; j < vec_len(vam->simple_interface_counters[i]); j++) {
3575 packets = vam->simple_interface_counters[i][j];
3576 vat_json_array_add_uint(counter_array, packets);
3577 }
3578 }
3579 for (i = 0; i < vec_len(vam->combined_interface_counters); i++) {
3580 msg = vat_json_array_add(msg_array);
3581 vat_json_init_object(msg);
3582 vat_json_object_add_string_copy(msg, "vnet_counter_type",
3583 (u8*)counter_type_to_str(i, 1));
3584 vat_json_object_add_int(msg, "is_combined", 1);
3585 counter_array = vat_json_object_add(msg, "data");
3586 vat_json_init_array(counter_array);
3587 for (j = 0; j < vec_len(vam->combined_interface_counters[i]); j++) {
3588 c = vam->combined_interface_counters[i][j];
3589 counter = vat_json_array_add(counter_array);
3590 vat_json_init_object(counter);
3591 vat_json_object_add_uint(counter, "packets", c.packets);
3592 vat_json_object_add_uint(counter, "bytes", c.bytes);
3593 }
3594 }
3595
3596 /* ip4 fib counters */
3597 msg_array = vat_json_object_add(&node, "ip4_fib_counters");
3598 vat_json_init_array(msg_array);
3599 for (i = 0; i < vec_len(vam->ip4_fib_counters); i++) {
3600 msg = vat_json_array_add(msg_array);
3601 vat_json_init_object(msg);
3602 vat_json_object_add_uint(msg, "vrf_id", vam->ip4_fib_counters_vrf_id_by_index[i]);
3603 counter_array = vat_json_object_add(msg, "c");
3604 vat_json_init_array(counter_array);
3605 for (j = 0; j < vec_len(vam->ip4_fib_counters[i]); j++) {
3606 counter = vat_json_array_add(counter_array);
3607 vat_json_init_object(counter);
3608 c4 = &vam->ip4_fib_counters[i][j];
3609 vat_json_object_add_ip4(counter, "address", c4->address);
3610 vat_json_object_add_uint(counter, "address_length", c4->address_length);
3611 vat_json_object_add_uint(counter, "packets", c4->packets);
3612 vat_json_object_add_uint(counter, "bytes", c4->bytes);
3613 }
3614 }
3615
3616 /* ip6 fib counters */
3617 msg_array = vat_json_object_add(&node, "ip6_fib_counters");
3618 vat_json_init_array(msg_array);
3619 for (i = 0; i < vec_len(vam->ip6_fib_counters); i++) {
3620 msg = vat_json_array_add(msg_array);
3621 vat_json_init_object(msg);
3622 vat_json_object_add_uint(msg, "vrf_id", vam->ip6_fib_counters_vrf_id_by_index[i]);
3623 counter_array = vat_json_object_add(msg, "c");
3624 vat_json_init_array(counter_array);
3625 for (j = 0; j < vec_len(vam->ip6_fib_counters[i]); j++) {
3626 counter = vat_json_array_add(counter_array);
3627 vat_json_init_object(counter);
3628 c6 = &vam->ip6_fib_counters[i][j];
3629 vat_json_object_add_ip6(counter, "address", c6->address);
3630 vat_json_object_add_uint(counter, "address_length", c6->address_length);
3631 vat_json_object_add_uint(counter, "packets", c6->packets);
3632 vat_json_object_add_uint(counter, "bytes", c6->bytes);
3633 }
3634 }
3635
3636 vat_json_print(vam->ofp, &node);
3637 vat_json_free(&node);
3638
3639 return 0;
3640}
3641
3642int exec (vat_main_t * vam)
3643{
3644 api_main_t * am = &api_main;
3645 vl_api_cli_request_t *mp;
3646 f64 timeout;
3647 void * oldheap;
3648 u8 * cmd = 0;
3649 unformat_input_t * i = vam->input;
3650
3651 if (vec_len(i->buffer) == 0)
3652 return -1;
3653
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08003654 if (vam->exec_mode == 0 && unformat (i, "mode")) {
Ed Warnickecb9cada2015-12-08 15:45:58 -07003655 vam->exec_mode = 1;
3656 return 0;
3657 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08003658 if (vam->exec_mode == 1 &&
Ed Warnickecb9cada2015-12-08 15:45:58 -07003659 (unformat (i, "exit") || unformat (i, "quit"))) {
3660 vam->exec_mode = 0;
3661 return 0;
3662 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08003663
Ed Warnickecb9cada2015-12-08 15:45:58 -07003664
3665 M(CLI_REQUEST, cli_request);
3666
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08003667 /*
Ed Warnickecb9cada2015-12-08 15:45:58 -07003668 * Copy cmd into shared memory.
3669 * In order for the CLI command to work, it
3670 * must be a vector ending in \n, not a C-string ending
3671 * in \n\0.
3672 */
3673 pthread_mutex_lock (&am->vlib_rp->mutex);
3674 oldheap = svm_push_data_heap (am->vlib_rp);
3675
3676 vec_validate (cmd, vec_len(vam->input->buffer)-1);
Damjan Marionf1213b82016-03-13 02:22:06 +01003677 clib_memcpy (cmd, vam->input->buffer, vec_len(vam->input->buffer));
Ed Warnickecb9cada2015-12-08 15:45:58 -07003678
3679 svm_pop_heap (oldheap);
3680 pthread_mutex_unlock (&am->vlib_rp->mutex);
3681
3682 mp->cmd_in_shmem = (u64) cmd;
3683 S;
3684 timeout = vat_time_now (vam) + 10.0;
3685
3686 while (vat_time_now (vam) < timeout) {
3687 if (vam->result_ready == 1) {
3688 u8 * free_me;
Pavel Kotucek060c6fc2016-02-24 15:52:42 +01003689 if (vam->shmem_result != NULL)
3690 fformat (vam->ofp, "%s", vam->shmem_result);
Ed Warnickecb9cada2015-12-08 15:45:58 -07003691 pthread_mutex_lock (&am->vlib_rp->mutex);
3692 oldheap = svm_push_data_heap (am->vlib_rp);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08003693
Ed Warnickecb9cada2015-12-08 15:45:58 -07003694 free_me = (u8 *)vam->shmem_result;
3695 vec_free (free_me);
3696
3697 svm_pop_heap (oldheap);
3698 pthread_mutex_unlock (&am->vlib_rp->mutex);
3699 return 0;
3700 }
3701 }
3702 return -99;
3703}
3704
3705static int api_create_loopback (vat_main_t * vam)
3706{
3707 unformat_input_t * i = vam->input;
3708 vl_api_create_loopback_t *mp;
3709 f64 timeout;
3710 u8 mac_address[6];
3711 u8 mac_set = 0;
3712
3713 memset (mac_address, 0, sizeof (mac_address));
3714
3715 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3716 {
3717 if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
3718 mac_set = 1;
3719 else
3720 break;
3721 }
3722
3723 /* Construct the API message */
3724 M(CREATE_LOOPBACK, create_loopback);
3725 if (mac_set)
Damjan Marionf1213b82016-03-13 02:22:06 +01003726 clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07003727
3728 S; W;
3729}
3730
3731static int api_delete_loopback (vat_main_t * vam)
3732{
3733 unformat_input_t * i = vam->input;
3734 vl_api_delete_loopback_t *mp;
3735 f64 timeout;
3736 u32 sw_if_index = ~0;
3737
3738 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3739 {
3740 if (unformat (i, "sw_if_index %d", &sw_if_index))
3741 ;
3742 else
3743 break;
3744 }
3745
3746 if (sw_if_index == ~0)
3747 {
3748 errmsg ("missing sw_if_index\n");
3749 return -99;
3750 }
3751
3752 /* Construct the API message */
3753 M(DELETE_LOOPBACK, delete_loopback);
3754 mp->sw_if_index = ntohl (sw_if_index);
3755
3756 S; W;
3757}
3758
3759static int api_want_stats (vat_main_t * vam)
3760{
3761 unformat_input_t * i = vam->input;
3762 vl_api_want_stats_t * mp;
3763 f64 timeout;
3764 int enable = -1;
3765
3766 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3767 {
3768 if (unformat (i, "enable"))
3769 enable = 1;
3770 else if (unformat (i, "disable"))
3771 enable = 0;
3772 else
3773 break;
3774 }
3775
3776 if (enable == -1)
3777 {
3778 errmsg ("missing enable|disable\n");
3779 return -99;
3780 }
3781
3782 M(WANT_STATS, want_stats);
3783 mp->enable_disable = enable;
3784
3785 S; W;
3786}
3787
3788static int api_want_interface_events (vat_main_t * vam)
3789{
3790 unformat_input_t * i = vam->input;
3791 vl_api_want_interface_events_t * mp;
3792 f64 timeout;
3793 int enable = -1;
3794
3795 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3796 {
3797 if (unformat (i, "enable"))
3798 enable = 1;
3799 else if (unformat (i, "disable"))
3800 enable = 0;
3801 else
3802 break;
3803 }
3804
3805 if (enable == -1)
3806 {
3807 errmsg ("missing enable|disable\n");
3808 return -99;
3809 }
3810
3811 M(WANT_INTERFACE_EVENTS, want_interface_events);
3812 mp->enable_disable = enable;
3813
3814 vam->interface_event_display = enable;
3815
3816 S; W;
3817}
3818
3819
3820/* Note: non-static, called once to set up the initial intfc table */
3821int api_sw_interface_dump (vat_main_t * vam)
3822{
3823 vl_api_sw_interface_dump_t *mp;
3824 f64 timeout;
3825 hash_pair_t * p;
3826 name_sort_t * nses = 0, * ns;
3827 sw_interface_subif_t * sub = NULL;
3828
3829 /* Toss the old name table */
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08003830 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
Ed Warnickecb9cada2015-12-08 15:45:58 -07003831 ({
3832 vec_add2 (nses, ns, 1);
3833 ns->name = (u8 *)(p->key);
3834 ns->value = (u32) p->value[0];
3835 }));
3836
3837 hash_free (vam->sw_if_index_by_interface_name);
3838
3839 vec_foreach (ns, nses)
3840 vec_free (ns->name);
3841
3842 vec_free (nses);
3843
3844 vec_foreach (sub, vam->sw_if_subif_table) {
3845 vec_free (sub->interface_name);
3846 }
3847 vec_free (vam->sw_if_subif_table);
3848
3849 /* recreate the interface name hash table */
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08003850 vam->sw_if_index_by_interface_name
Ed Warnickecb9cada2015-12-08 15:45:58 -07003851 = hash_create_string (0, sizeof(uword));
3852
3853 /* Get list of ethernets */
3854 M(SW_INTERFACE_DUMP, sw_interface_dump);
3855 mp->name_filter_valid = 1;
Damjan Marionfa693552016-04-26 19:30:36 +02003856 strncpy ((char *) mp->name_filter, "Ether", sizeof(mp->name_filter)-1);
Ed Warnickecb9cada2015-12-08 15:45:58 -07003857 S;
3858
3859 /* and local / loopback interfaces */
3860 M(SW_INTERFACE_DUMP, sw_interface_dump);
3861 mp->name_filter_valid = 1;
Damjan Marionfa693552016-04-26 19:30:36 +02003862 strncpy ((char *) mp->name_filter, "lo", sizeof(mp->name_filter)-1);
Ed Warnickecb9cada2015-12-08 15:45:58 -07003863 S;
3864
Hongjun Nic4248792016-06-08 01:07:12 +08003865
3866 /* and vxlan-gpe tunnel interfaces */
3867 M(SW_INTERFACE_DUMP, sw_interface_dump);
3868 mp->name_filter_valid = 1;
3869 strncpy ((char *) mp->name_filter, "vxlan_gpe", sizeof(mp->name_filter)-1);
3870 S;
3871
Ed Warnickecb9cada2015-12-08 15:45:58 -07003872 /* and vxlan tunnel interfaces */
3873 M(SW_INTERFACE_DUMP, sw_interface_dump);
3874 mp->name_filter_valid = 1;
Damjan Marionfa693552016-04-26 19:30:36 +02003875 strncpy ((char *) mp->name_filter, "vxlan", sizeof(mp->name_filter)-1);
Ed Warnickecb9cada2015-12-08 15:45:58 -07003876 S;
3877
Damjan Marionb02e49c2016-03-31 17:44:25 +02003878 /* and host (af_packet) interfaces */
3879 M(SW_INTERFACE_DUMP, sw_interface_dump);
3880 mp->name_filter_valid = 1;
Damjan Marionfa693552016-04-26 19:30:36 +02003881 strncpy ((char *) mp->name_filter, "host", sizeof(mp->name_filter)-1);
Damjan Marionb02e49c2016-03-31 17:44:25 +02003882 S;
3883
Ed Warnickecb9cada2015-12-08 15:45:58 -07003884 /* and l2tpv3 tunnel interfaces */
3885 M(SW_INTERFACE_DUMP, sw_interface_dump);
3886 mp->name_filter_valid = 1;
Damjan Marionfa693552016-04-26 19:30:36 +02003887 strncpy ((char *) mp->name_filter, "l2tpv3_tunnel", sizeof(mp->name_filter)-1);
Ed Warnickecb9cada2015-12-08 15:45:58 -07003888 S;
3889
Chris Lukea6116ef2016-05-06 10:12:30 -04003890 /* and GRE tunnel interfaces */
3891 M(SW_INTERFACE_DUMP, sw_interface_dump);
3892 mp->name_filter_valid = 1;
3893 strncpy ((char *) mp->name_filter, "gre", sizeof(mp->name_filter)-1);
3894 S;
3895
Ed Warnickecb9cada2015-12-08 15:45:58 -07003896 /* Use a control ping for synchronization */
3897 {
3898 vl_api_control_ping_t * mp;
3899 M(CONTROL_PING, control_ping);
3900 S;
3901 }
3902 W;
3903}
3904
3905static int api_sw_interface_set_flags (vat_main_t * vam)
3906{
3907 unformat_input_t * i = vam->input;
3908 vl_api_sw_interface_set_flags_t *mp;
3909 f64 timeout;
3910 u32 sw_if_index;
3911 u8 sw_if_index_set = 0;
3912 u8 admin_up = 0, link_up = 0;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08003913
Ed Warnickecb9cada2015-12-08 15:45:58 -07003914 /* Parse args required to build the message */
3915 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3916 if (unformat (i, "admin-up"))
3917 admin_up = 1;
3918 else if (unformat (i, "admin-down"))
3919 admin_up = 0;
3920 else if (unformat (i, "link-up"))
3921 link_up = 1;
3922 else if (unformat (i, "link-down"))
3923 link_up = 0;
3924 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3925 sw_if_index_set = 1;
3926 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3927 sw_if_index_set = 1;
3928 else
3929 break;
3930 }
3931
3932 if (sw_if_index_set == 0) {
3933 errmsg ("missing interface name or sw_if_index\n");
3934 return -99;
3935 }
3936
3937 /* Construct the API message */
3938 M(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
3939 mp->sw_if_index = ntohl (sw_if_index);
3940 mp->admin_up_down = admin_up;
3941 mp->link_up_down = link_up;
3942
3943 /* send it... */
3944 S;
3945
3946 /* Wait for a reply, return the good/bad news... */
3947 W;
3948}
3949
Pavel Kotucek00bbf272016-03-03 13:27:11 +01003950static int api_sw_interface_clear_stats (vat_main_t * vam)
3951{
3952 unformat_input_t * i = vam->input;
3953 vl_api_sw_interface_clear_stats_t *mp;
3954 f64 timeout;
3955 u32 sw_if_index;
3956 u8 sw_if_index_set = 0;
3957
3958 /* Parse args required to build the message */
3959 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3960 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3961 sw_if_index_set = 1;
3962 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3963 sw_if_index_set = 1;
3964 else
3965 break;
3966 }
3967
3968 /* Construct the API message */
3969 M(SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
3970
3971 if (sw_if_index_set == 1)
3972 mp->sw_if_index = ntohl (sw_if_index);
3973 else
3974 mp->sw_if_index = ~0;
3975
3976 /* send it... */
3977 S;
3978
3979 /* Wait for a reply, return the good/bad news... */
3980 W;
3981}
3982
Ed Warnickecb9cada2015-12-08 15:45:58 -07003983static int api_sw_interface_add_del_address (vat_main_t * vam)
3984{
3985 unformat_input_t * i = vam->input;
3986 vl_api_sw_interface_add_del_address_t *mp;
3987 f64 timeout;
3988 u32 sw_if_index;
3989 u8 sw_if_index_set = 0;
3990 u8 is_add = 1, del_all = 0;
3991 u32 address_length = 0;
3992 u8 v4_address_set = 0;
3993 u8 v6_address_set = 0;
3994 ip4_address_t v4address;
3995 ip6_address_t v6address;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08003996
Ed Warnickecb9cada2015-12-08 15:45:58 -07003997 /* Parse args required to build the message */
3998 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3999 if (unformat (i, "del-all"))
4000 del_all = 1;
4001 else if (unformat (i, "del"))
4002 is_add = 0;
4003 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4004 sw_if_index_set = 1;
4005 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4006 sw_if_index_set = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004007 else if (unformat (i, "%U/%d",
4008 unformat_ip4_address, &v4address,
Ed Warnickecb9cada2015-12-08 15:45:58 -07004009 &address_length))
4010 v4_address_set = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004011 else if (unformat (i, "%U/%d",
4012 unformat_ip6_address, &v6address,
Ed Warnickecb9cada2015-12-08 15:45:58 -07004013 &address_length))
4014 v6_address_set = 1;
4015 else
4016 break;
4017 }
4018
4019 if (sw_if_index_set == 0) {
4020 errmsg ("missing interface name or sw_if_index\n");
4021 return -99;
4022 }
4023 if (v4_address_set && v6_address_set) {
4024 errmsg ("both v4 and v6 addresses set\n");
4025 return -99;
4026 }
4027 if (!v4_address_set && !v6_address_set && !del_all) {
4028 errmsg ("no addresses set\n");
4029 return -99;
4030 }
4031
4032 /* Construct the API message */
4033 M(SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
4034
4035 mp->sw_if_index = ntohl (sw_if_index);
4036 mp->is_add = is_add;
4037 mp->del_all = del_all;
4038 if (v6_address_set) {
4039 mp->is_ipv6 = 1;
Damjan Marionf1213b82016-03-13 02:22:06 +01004040 clib_memcpy (mp->address, &v6address, sizeof (v6address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004041 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01004042 clib_memcpy (mp->address, &v4address, sizeof (v4address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004043 }
4044 mp->address_length = address_length;
4045
4046 /* send it... */
4047 S;
4048
4049 /* Wait for a reply, return good/bad news */
4050 W;
4051}
4052
4053static int api_sw_interface_set_table (vat_main_t * vam)
4054{
4055 unformat_input_t * i = vam->input;
4056 vl_api_sw_interface_set_table_t *mp;
4057 f64 timeout;
4058 u32 sw_if_index, vrf_id = 0;
4059 u8 sw_if_index_set = 0;
4060 u8 is_ipv6 = 0;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004061
Ed Warnickecb9cada2015-12-08 15:45:58 -07004062 /* Parse args required to build the message */
4063 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4064 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4065 sw_if_index_set = 1;
4066 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4067 sw_if_index_set = 1;
4068 else if (unformat (i, "vrf %d", &vrf_id))
4069 ;
4070 else if (unformat (i, "ipv6"))
4071 is_ipv6 = 1;
4072 else
4073 break;
4074 }
4075
4076 if (sw_if_index_set == 0) {
4077 errmsg ("missing interface name or sw_if_index\n");
4078 return -99;
4079 }
4080
4081 /* Construct the API message */
4082 M(SW_INTERFACE_SET_TABLE, sw_interface_set_table);
4083
4084 mp->sw_if_index = ntohl (sw_if_index);
4085 mp->is_ipv6 = is_ipv6;
4086 mp->vrf_id = ntohl (vrf_id);
4087
4088 /* send it... */
4089 S;
4090
4091 /* Wait for a reply... */
4092 W;
4093}
4094
4095static int api_sw_interface_set_vpath (vat_main_t * vam)
4096{
4097 unformat_input_t * i = vam->input;
4098 vl_api_sw_interface_set_vpath_t *mp;
4099 f64 timeout;
4100 u32 sw_if_index = 0;
4101 u8 sw_if_index_set = 0;
4102 u8 is_enable = 0;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004103
Ed Warnickecb9cada2015-12-08 15:45:58 -07004104 /* Parse args required to build the message */
4105 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4106 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4107 sw_if_index_set = 1;
4108 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4109 sw_if_index_set = 1;
4110 else if (unformat (i, "enable"))
4111 is_enable = 1;
4112 else if (unformat (i, "disable"))
4113 is_enable = 0;
4114 else
4115 break;
4116 }
4117
4118 if (sw_if_index_set == 0) {
4119 errmsg ("missing interface name or sw_if_index\n");
4120 return -99;
4121 }
4122
4123 /* Construct the API message */
4124 M(SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
4125
4126 mp->sw_if_index = ntohl (sw_if_index);
4127 mp->enable = is_enable;
4128
4129 /* send it... */
4130 S;
4131
4132 /* Wait for a reply... */
4133 W;
4134}
4135
4136static int api_sw_interface_set_l2_xconnect (vat_main_t * vam)
4137{
4138 unformat_input_t * i = vam->input;
4139 vl_api_sw_interface_set_l2_xconnect_t *mp;
4140 f64 timeout;
4141 u32 rx_sw_if_index;
4142 u8 rx_sw_if_index_set = 0;
4143 u32 tx_sw_if_index;
4144 u8 tx_sw_if_index_set = 0;
4145 u8 enable = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004146
Ed Warnickecb9cada2015-12-08 15:45:58 -07004147 /* Parse args required to build the message */
4148 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4149 if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004150 rx_sw_if_index_set = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -07004151 else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
4152 tx_sw_if_index_set = 1;
4153 else if (unformat (i, "rx")) {
4154 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4155 if (unformat (i, "%U", unformat_sw_if_index, vam,
4156 &rx_sw_if_index))
4157 rx_sw_if_index_set = 1;
4158 } else
4159 break;
4160 } else if (unformat (i, "tx")) {
4161 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4162 if (unformat (i, "%U", unformat_sw_if_index, vam,
4163 &tx_sw_if_index))
4164 tx_sw_if_index_set = 1;
4165 } else
4166 break;
4167 } else if (unformat (i, "enable"))
4168 enable = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004169 else if (unformat (i, "disable"))
Ed Warnickecb9cada2015-12-08 15:45:58 -07004170 enable = 0;
4171 else
4172 break;
4173 }
4174
4175 if (rx_sw_if_index_set == 0) {
4176 errmsg ("missing rx interface name or rx_sw_if_index\n");
4177 return -99;
4178 }
4179
4180 if (enable && (tx_sw_if_index_set == 0)) {
4181 errmsg ("missing tx interface name or tx_sw_if_index\n");
4182 return -99;
4183 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004184
Ed Warnickecb9cada2015-12-08 15:45:58 -07004185 M(SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
4186
4187 mp->rx_sw_if_index = ntohl(rx_sw_if_index);
4188 mp->tx_sw_if_index = ntohl(tx_sw_if_index);
4189 mp->enable = enable;
4190
4191 S; W;
4192 /* NOTREACHED */
4193 return 0;
4194}
4195
4196static int api_sw_interface_set_l2_bridge (vat_main_t * vam)
4197{
4198 unformat_input_t * i = vam->input;
4199 vl_api_sw_interface_set_l2_bridge_t *mp;
4200 f64 timeout;
4201 u32 rx_sw_if_index;
4202 u8 rx_sw_if_index_set = 0;
4203 u32 bd_id;
4204 u8 bd_id_set = 0;
4205 u8 bvi = 0;
4206 u32 shg = 0;
4207 u8 enable = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004208
Ed Warnickecb9cada2015-12-08 15:45:58 -07004209 /* Parse args required to build the message */
4210 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4211 if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004212 rx_sw_if_index_set = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -07004213 else if (unformat (i, "bd_id %d", &bd_id))
4214 bd_id_set = 1;
4215 else if (unformat (i, "%U", unformat_sw_if_index, vam,
4216 &rx_sw_if_index))
4217 rx_sw_if_index_set = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004218 else if (unformat (i, "shg %d", &shg))
Ed Warnickecb9cada2015-12-08 15:45:58 -07004219 ;
4220 else if (unformat (i, "bvi"))
4221 bvi = 1;
4222 else if (unformat (i, "enable"))
4223 enable = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004224 else if (unformat (i, "disable"))
Ed Warnickecb9cada2015-12-08 15:45:58 -07004225 enable = 0;
4226 else
4227 break;
4228 }
4229
4230 if (rx_sw_if_index_set == 0) {
4231 errmsg ("missing rx interface name or sw_if_index\n");
4232 return -99;
4233 }
4234
4235 if (enable && (bd_id_set == 0)) {
4236 errmsg ("missing bridge domain\n");
4237 return -99;
4238 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004239
Ed Warnickecb9cada2015-12-08 15:45:58 -07004240 M(SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
4241
4242 mp->rx_sw_if_index = ntohl(rx_sw_if_index);
4243 mp->bd_id = ntohl(bd_id);
4244 mp->shg = (u8)shg;
4245 mp->bvi = bvi;
4246 mp->enable = enable;
4247
4248 S; W;
4249 /* NOTREACHED */
4250 return 0;
4251}
4252
4253static int api_bridge_domain_dump (vat_main_t * vam)
4254{
4255 unformat_input_t * i = vam->input;
4256 vl_api_bridge_domain_dump_t *mp;
4257 f64 timeout;
4258 u32 bd_id = ~0;
4259
4260 /* Parse args required to build the message */
4261 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4262 if (unformat (i, "bd_id %d", &bd_id))
4263 ;
4264 else
4265 break;
4266 }
4267
4268 M(BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
4269 mp->bd_id = ntohl(bd_id);
4270 S;
4271
4272 /* Use a control ping for synchronization */
4273 {
4274 vl_api_control_ping_t * mp;
4275 M(CONTROL_PING, control_ping);
4276 S;
4277 }
4278
4279 W;
4280 /* NOTREACHED */
4281 return 0;
4282}
4283
4284static int api_bridge_domain_add_del (vat_main_t * vam)
4285{
4286 unformat_input_t * i = vam->input;
4287 vl_api_bridge_domain_add_del_t *mp;
4288 f64 timeout;
4289 u32 bd_id = ~0;
4290 u8 is_add = 1;
4291 u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
4292
4293 /* Parse args required to build the message */
4294 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4295 if (unformat (i, "bd_id %d", &bd_id))
4296 ;
4297 else if (unformat (i, "flood %d", &flood))
4298 ;
4299 else if (unformat (i, "uu-flood %d", &uu_flood))
4300 ;
4301 else if (unformat (i, "forward %d", &forward))
4302 ;
4303 else if (unformat (i, "learn %d", &learn))
4304 ;
4305 else if (unformat (i, "arp-term %d", &arp_term))
4306 ;
4307 else if (unformat (i, "del")) {
4308 is_add = 0;
4309 flood = uu_flood = forward = learn = 0;
4310 }
4311 else
4312 break;
4313 }
4314
4315 if (bd_id == ~0) {
4316 errmsg ("missing bridge domain\n");
4317 return -99;
4318 }
4319
4320 M(BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
4321
4322 mp->bd_id = ntohl(bd_id);
4323 mp->flood = flood;
4324 mp->uu_flood = uu_flood;
4325 mp->forward = forward;
4326 mp->learn = learn;
4327 mp->arp_term = arp_term;
4328 mp->is_add = is_add;
4329
4330 S; W;
4331 /* NOTREACHED */
4332 return 0;
4333}
4334
4335static int api_l2fib_add_del (vat_main_t * vam)
4336{
4337 unformat_input_t * i = vam->input;
4338 vl_api_l2fib_add_del_t *mp;
4339 f64 timeout;
4340 u64 mac = 0;
4341 u8 mac_set = 0;
4342 u32 bd_id;
4343 u8 bd_id_set = 0;
4344 u32 sw_if_index;
4345 u8 sw_if_index_set = 0;
4346 u8 is_add = 1;
4347 u8 static_mac = 0;
4348 u8 filter_mac = 0;
marek zavodsky689acaf2016-07-01 03:49:53 +02004349 u8 bvi_mac = 0;
Dave Barach41da02d2016-07-11 16:48:42 -07004350 int count = 1;
4351 f64 before = 0;
4352 int j;
Ed Warnickecb9cada2015-12-08 15:45:58 -07004353
4354 /* Parse args required to build the message */
4355 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4356 if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
4357 mac_set = 1;
4358 else if (unformat (i, "bd_id %d", &bd_id))
4359 bd_id_set = 1;
4360 else if (unformat (i, "sw_if_index %d", &sw_if_index))
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004361 sw_if_index_set = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -07004362 else if (unformat (i, "sw_if")) {
4363 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
Dave Barach41da02d2016-07-11 16:48:42 -07004364 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4365 sw_if_index_set = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -07004366 } else
4367 break;
4368 } else if (unformat (i, "static"))
Dave Barach41da02d2016-07-11 16:48:42 -07004369 static_mac = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -07004370 else if (unformat (i, "filter")) {
Dave Barach41da02d2016-07-11 16:48:42 -07004371 filter_mac = 1;
4372 static_mac = 1;
4373 } else if (unformat (i, "bvi")) {
4374 bvi_mac = 1;
4375 static_mac = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -07004376 } else if (unformat (i, "del"))
Dave Barach41da02d2016-07-11 16:48:42 -07004377 is_add = 0;
4378 else if (unformat (i, "count %d", &count))
4379 ;
Ed Warnickecb9cada2015-12-08 15:45:58 -07004380 else
Dave Barach41da02d2016-07-11 16:48:42 -07004381 break;
Ed Warnickecb9cada2015-12-08 15:45:58 -07004382 }
4383
4384 if (mac_set == 0) {
4385 errmsg ("missing mac address\n");
4386 return -99;
4387 }
4388
4389 if (bd_id_set == 0) {
4390 errmsg ("missing bridge domain\n");
4391 return -99;
4392 }
4393
4394 if (is_add && (sw_if_index_set == 0)) {
4395 errmsg ("missing interface name or sw_if_index\n");
4396 return -99;
4397 }
4398
Dave Barach41da02d2016-07-11 16:48:42 -07004399 if (count > 1) {
4400 /* Turn on async mode */
4401 vam->async_mode = 1;
4402 vam->async_errors = 0;
4403 before = vat_time_now(vam);
Ed Warnickecb9cada2015-12-08 15:45:58 -07004404 }
Dave Barach41da02d2016-07-11 16:48:42 -07004405
4406 for (j = 0; j < count; j++) {
4407 M(L2FIB_ADD_DEL, l2fib_add_del);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004408
Dave Barach41da02d2016-07-11 16:48:42 -07004409 mp->mac = mac;
4410 mp->bd_id = ntohl(bd_id);
4411 mp->is_add = is_add;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004412
Dave Barach41da02d2016-07-11 16:48:42 -07004413 if (is_add) {
4414 mp->sw_if_index = ntohl(sw_if_index);
4415 mp->static_mac = static_mac;
4416 mp->filter_mac = filter_mac;
4417 mp->bvi_mac = bvi_mac;
4418 }
4419 increment_mac_address (&mac);
4420 /* send it... */
4421 S;
4422 }
4423
4424 if (count > 1) {
4425 vl_api_control_ping_t * mp;
4426 f64 after;
4427
4428 /* Shut off async mode */
4429 vam->async_mode = 0;
4430
4431 M(CONTROL_PING, control_ping);
4432 S;
4433
4434 timeout = vat_time_now(vam) + 1.0;
4435 while (vat_time_now (vam) < timeout)
4436 if (vam->result_ready == 1)
4437 goto out;
4438 vam->retval = -99;
4439
4440 out:
4441 if (vam->retval == -99)
4442 errmsg ("timeout\n");
4443
4444 if (vam->async_errors > 0) {
4445 errmsg ("%d asynchronous errors\n", vam->async_errors);
4446 vam->retval = -98;
4447 }
4448 vam->async_errors = 0;
4449 after = vat_time_now(vam);
4450
4451 fformat(vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
4452 count, after - before, count / (after - before));
4453 } else {
4454 /* Wait for a reply... */
4455 W;
4456 }
4457 /* Return the good/bad news */
4458 return (vam->retval);
Ed Warnickecb9cada2015-12-08 15:45:58 -07004459}
4460
4461static int api_l2_flags (vat_main_t * vam)
4462{
4463 unformat_input_t * i = vam->input;
4464 vl_api_l2_flags_t *mp;
4465 f64 timeout;
4466 u32 sw_if_index;
4467 u32 feature_bitmap = 0;
4468 u8 sw_if_index_set = 0;
4469
4470 /* Parse args required to build the message */
4471 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4472 if (unformat (i, "sw_if_index %d", &sw_if_index))
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004473 sw_if_index_set = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -07004474 else if (unformat (i, "sw_if")) {
4475 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4476 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4477 sw_if_index_set = 1;
4478 } else
4479 break;
4480 } else if (unformat (i, "learn"))
4481 feature_bitmap |= L2INPUT_FEAT_LEARN;
4482 else if (unformat (i, "forward"))
4483 feature_bitmap |= L2INPUT_FEAT_FWD;
4484 else if (unformat (i, "flood"))
4485 feature_bitmap |= L2INPUT_FEAT_FLOOD;
4486 else if (unformat (i, "uu-flood"))
4487 feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
4488 else
4489 break;
4490 }
4491
4492 if (sw_if_index_set == 0) {
4493 errmsg ("missing interface name or sw_if_index\n");
4494 return -99;
4495 }
4496
4497 M(L2_FLAGS, l2_flags);
4498
4499 mp->sw_if_index = ntohl(sw_if_index);
4500 mp->feature_bitmap = ntohl(feature_bitmap);
4501
4502 S; W;
4503 /* NOTREACHED */
4504 return 0;
4505}
4506
4507static int api_bridge_flags (vat_main_t * vam)
4508{
4509 unformat_input_t * i = vam->input;
4510 vl_api_bridge_flags_t *mp;
4511 f64 timeout;
4512 u32 bd_id;
4513 u8 bd_id_set = 0;
4514 u8 is_set = 1;
4515 u32 flags = 0;
4516
4517 /* Parse args required to build the message */
4518 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4519 if (unformat (i, "bd_id %d", &bd_id))
4520 bd_id_set = 1;
4521 else if (unformat (i, "learn"))
4522 flags |= L2_LEARN;
4523 else if (unformat (i, "forward"))
4524 flags |= L2_FWD;
4525 else if (unformat (i, "flood"))
4526 flags |= L2_FLOOD;
4527 else if (unformat (i, "uu-flood"))
4528 flags |= L2_UU_FLOOD;
4529 else if (unformat (i, "arp-term"))
4530 flags |= L2_ARP_TERM;
4531 else if (unformat (i, "off"))
4532 is_set = 0;
4533 else if (unformat (i, "disable"))
4534 is_set = 0;
4535 else
4536 break;
4537 }
4538
4539 if (bd_id_set == 0) {
4540 errmsg ("missing bridge domain\n");
4541 return -99;
4542 }
4543
4544 M(BRIDGE_FLAGS, bridge_flags);
4545
4546 mp->bd_id = ntohl(bd_id);
4547 mp->feature_bitmap = ntohl(flags);
4548 mp->is_set = is_set;
4549
4550 S; W;
4551 /* NOTREACHED */
4552 return 0;
4553}
4554
4555static int api_bd_ip_mac_add_del (vat_main_t * vam)
4556{
4557 unformat_input_t * i = vam->input;
4558 vl_api_bd_ip_mac_add_del_t *mp;
4559 f64 timeout;
4560 u32 bd_id;
4561 u8 is_ipv6 = 0;
4562 u8 is_add = 1;
4563 u8 bd_id_set = 0;
4564 u8 ip_set = 0;
4565 u8 mac_set = 0;
4566 ip4_address_t v4addr;
4567 ip6_address_t v6addr;
4568 u8 macaddr[6];
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004569
Ed Warnickecb9cada2015-12-08 15:45:58 -07004570
4571 /* Parse args required to build the message */
4572 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4573 if (unformat (i, "bd_id %d", &bd_id)) {
4574 bd_id_set++;
4575 } else if (unformat (i, "%U", unformat_ip4_address, &v4addr)) {
4576 ip_set++;
4577 } else if (unformat (i, "%U", unformat_ip6_address, &v6addr)) {
4578 ip_set++;
4579 is_ipv6++;
4580 } else if (unformat (i, "%U", unformat_ethernet_address, macaddr)) {
4581 mac_set++;
4582 } else if (unformat (i, "del"))
4583 is_add = 0;
4584 else
4585 break;
4586 }
4587
4588 if (bd_id_set == 0) {
4589 errmsg ("missing bridge domain\n");
4590 return -99;
4591 } else if (ip_set == 0) {
4592 errmsg ("missing IP address\n");
4593 return -99;
4594 } else if (mac_set == 0) {
4595 errmsg ("missing MAC address\n");
4596 return -99;
4597 }
4598
4599 M(BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
4600
4601 mp->bd_id = ntohl(bd_id);
4602 mp->is_ipv6 = is_ipv6;
4603 mp->is_add = is_add;
4604 if (is_ipv6)
Damjan Marionf1213b82016-03-13 02:22:06 +01004605 clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
4606 else clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
4607 clib_memcpy (mp->mac_address, macaddr, 6);
Ed Warnickecb9cada2015-12-08 15:45:58 -07004608 S; W;
4609 /* NOTREACHED */
4610 return 0;
4611}
4612
4613static int api_tap_connect (vat_main_t * vam)
4614{
4615 unformat_input_t * i = vam->input;
4616 vl_api_tap_connect_t *mp;
4617 f64 timeout;
4618 u8 mac_address[6];
4619 u8 random_mac = 1;
4620 u8 name_set = 0;
4621 u8 * tap_name;
4622
4623 memset (mac_address, 0, sizeof (mac_address));
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004624
Ed Warnickecb9cada2015-12-08 15:45:58 -07004625 /* Parse args required to build the message */
4626 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4627 if (unformat (i, "mac %U", unformat_ethernet_address, mac_address)) {
4628 random_mac = 0;
4629 }
4630 else if (unformat (i, "random-mac"))
4631 random_mac = 1;
4632 else if (unformat (i, "tapname %s", &tap_name))
4633 name_set = 1;
4634 else
4635 break;
4636 }
4637
4638 if (name_set == 0) {
4639 errmsg ("missing tap name\n");
4640 return -99;
4641 }
4642 if (vec_len (tap_name) > 63) {
4643 errmsg ("tap name too long\n");
4644 }
4645 vec_add1 (tap_name, 0);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004646
Ed Warnickecb9cada2015-12-08 15:45:58 -07004647 /* Construct the API message */
4648 M(TAP_CONNECT, tap_connect);
4649
4650 mp->use_random_mac = random_mac;
Damjan Marionf1213b82016-03-13 02:22:06 +01004651 clib_memcpy (mp->mac_address, mac_address, 6);
4652 clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004653 vec_free (tap_name);
4654
4655 /* send it... */
4656 S;
4657
4658 /* Wait for a reply... */
4659 W;
4660}
4661
4662static int api_tap_modify (vat_main_t * vam)
4663{
4664 unformat_input_t * i = vam->input;
4665 vl_api_tap_modify_t *mp;
4666 f64 timeout;
4667 u8 mac_address[6];
4668 u8 random_mac = 1;
4669 u8 name_set = 0;
4670 u8 * tap_name;
4671 u32 sw_if_index = ~0;
4672 u8 sw_if_index_set = 0;
4673
4674 memset (mac_address, 0, sizeof (mac_address));
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004675
Ed Warnickecb9cada2015-12-08 15:45:58 -07004676 /* Parse args required to build the message */
4677 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4678 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4679 sw_if_index_set = 1;
4680 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4681 sw_if_index_set = 1;
4682 else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address)) {
4683 random_mac = 0;
4684 }
4685 else if (unformat (i, "random-mac"))
4686 random_mac = 1;
4687 else if (unformat (i, "tapname %s", &tap_name))
4688 name_set = 1;
4689 else
4690 break;
4691 }
4692
4693 if (sw_if_index_set == 0) {
4694 errmsg ("missing vpp interface name");
4695 return -99;
4696 }
4697 if (name_set == 0) {
4698 errmsg ("missing tap name\n");
4699 return -99;
4700 }
4701 if (vec_len (tap_name) > 63) {
4702 errmsg ("tap name too long\n");
4703 }
4704 vec_add1 (tap_name, 0);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004705
Ed Warnickecb9cada2015-12-08 15:45:58 -07004706 /* Construct the API message */
4707 M(TAP_MODIFY, tap_modify);
4708
4709 mp->use_random_mac = random_mac;
4710 mp->sw_if_index = ntohl(sw_if_index);
Damjan Marionf1213b82016-03-13 02:22:06 +01004711 clib_memcpy (mp->mac_address, mac_address, 6);
4712 clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004713 vec_free (tap_name);
4714
4715 /* send it... */
4716 S;
4717
4718 /* Wait for a reply... */
4719 W;
4720}
4721
4722static int api_tap_delete (vat_main_t * vam)
4723{
4724 unformat_input_t * i = vam->input;
4725 vl_api_tap_delete_t *mp;
4726 f64 timeout;
4727 u32 sw_if_index = ~0;
4728 u8 sw_if_index_set = 0;
4729
4730 /* Parse args required to build the message */
4731 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4732 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4733 sw_if_index_set = 1;
4734 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4735 sw_if_index_set = 1;
4736 else
4737 break;
4738 }
4739
4740 if (sw_if_index_set == 0) {
4741 errmsg ("missing vpp interface name");
4742 return -99;
4743 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004744
Ed Warnickecb9cada2015-12-08 15:45:58 -07004745 /* Construct the API message */
4746 M(TAP_DELETE, tap_delete);
4747
4748 mp->sw_if_index = ntohl(sw_if_index);
4749
4750 /* send it... */
4751 S;
4752
4753 /* Wait for a reply... */
4754 W;
4755}
4756
4757static int api_ip_add_del_route (vat_main_t * vam)
4758{
4759 unformat_input_t * i = vam->input;
4760 vl_api_ip_add_del_route_t *mp;
4761 f64 timeout;
Nealee9dbd2b2016-07-01 13:00:09 +01004762 u32 sw_if_index = ~0, vrf_id = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -07004763 u8 sw_if_index_set = 0;
4764 u8 is_ipv6 = 0;
4765 u8 is_local = 0, is_drop = 0;
4766 u8 create_vrf_if_needed = 0;
4767 u8 is_add = 1;
4768 u8 next_hop_weight = 1;
4769 u8 not_last = 0;
4770 u8 is_multipath = 0;
4771 u8 address_set = 0;
4772 u8 address_length_set = 0;
4773 u32 lookup_in_vrf = 0;
4774 u32 resolve_attempts = 0;
4775 u32 dst_address_length = 0;
4776 u8 next_hop_set = 0;
4777 ip4_address_t v4_dst_address, v4_next_hop_address;
4778 ip6_address_t v6_dst_address, v6_next_hop_address;
4779 int count = 1;
4780 int j;
4781 f64 before = 0;
4782 u32 random_add_del = 0;
4783 u32 * random_vector = 0;
4784 uword * random_hash;
4785 u32 random_seed = 0xdeaddabe;
4786 u32 classify_table_index = ~0;
4787 u8 is_classify = 0;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004788
Ed Warnickecb9cada2015-12-08 15:45:58 -07004789 /* Parse args required to build the message */
4790 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4791 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4792 sw_if_index_set = 1;
4793 else if (unformat (i, "sw_if_index %d", &sw_if_index))
4794 sw_if_index_set = 1;
4795 else if (unformat (i, "%U", unformat_ip4_address,
4796 &v4_dst_address)) {
4797 address_set = 1;
4798 is_ipv6 = 0;
4799 }
4800 else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address)) {
4801 address_set = 1;
4802 is_ipv6 = 1;
4803 }
4804 else if (unformat (i, "/%d", &dst_address_length)) {
4805 address_length_set = 1;
4806 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004807
4808 else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
Ed Warnickecb9cada2015-12-08 15:45:58 -07004809 &v4_next_hop_address)) {
4810 next_hop_set = 1;
4811 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004812 else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
Ed Warnickecb9cada2015-12-08 15:45:58 -07004813 &v6_next_hop_address)) {
4814 next_hop_set = 1;
4815 }
4816 else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
4817 ;
4818 else if (unformat (i, "weight %d", &next_hop_weight))
4819 ;
4820 else if (unformat (i, "drop")) {
4821 is_drop = 1;
4822 } else if (unformat (i, "local")) {
4823 is_local = 1;
4824 } else if (unformat (i, "classify %d", &classify_table_index)) {
4825 is_classify = 1;
4826 } else if (unformat (i, "del"))
4827 is_add = 0;
4828 else if (unformat (i, "add"))
4829 is_add = 1;
4830 else if (unformat (i, "not-last"))
4831 not_last = 1;
4832 else if (unformat (i, "multipath"))
4833 is_multipath = 1;
4834 else if (unformat (i, "vrf %d", &vrf_id))
4835 ;
4836 else if (unformat (i, "create-vrf"))
4837 create_vrf_if_needed = 1;
4838 else if (unformat (i, "count %d", &count))
4839 ;
4840 else if (unformat (i, "lookup-in-vrf %d", &lookup_in_vrf))
4841 ;
4842 else if (unformat (i, "random"))
4843 random_add_del = 1;
4844 else if (unformat (i, "seed %d", &random_seed))
4845 ;
4846 else {
4847 clib_warning ("parse error '%U'", format_unformat_error, i);
4848 return -99;
4849 }
4850 }
4851
4852 if (resolve_attempts > 0 && sw_if_index_set == 0) {
4853 errmsg ("ARP resolution needs explicit interface or sw_if_index\n");
4854 return -99;
4855 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004856
Ed Warnickecb9cada2015-12-08 15:45:58 -07004857 if (!next_hop_set && !is_drop && !is_local && !is_classify) {
4858 errmsg ("next hop / local / drop / classify not set\n");
4859 return -99;
4860 }
4861
4862 if (address_set == 0) {
4863 errmsg ("missing addresses\n");
4864 return -99;
4865 }
4866
4867 if (address_length_set == 0) {
4868 errmsg ("missing address length\n");
4869 return -99;
4870 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004871
Ed Warnickecb9cada2015-12-08 15:45:58 -07004872 /* Generate a pile of unique, random routes */
4873 if (random_add_del) {
4874 u32 this_random_address;
4875 random_hash = hash_create (count, sizeof(uword));
4876
4877 hash_set (random_hash, v4_next_hop_address.as_u32, 1);
4878 for (j = 0; j <= count; j++) {
4879 do {
4880 this_random_address = random_u32 (&random_seed);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004881 this_random_address =
Ed Warnickecb9cada2015-12-08 15:45:58 -07004882 clib_host_to_net_u32 (this_random_address);
4883 } while (hash_get (random_hash, this_random_address));
4884 vec_add1 (random_vector, this_random_address);
4885 hash_set (random_hash, this_random_address, 1);
4886 }
4887 hash_free (random_hash);
4888 v4_dst_address.as_u32 = random_vector[0];
4889 }
4890
4891 if (count > 1) {
4892 /* Turn on async mode */
4893 vam->async_mode = 1;
4894 vam->async_errors = 0;
4895 before = vat_time_now(vam);
4896 }
4897
4898 for (j = 0; j < count; j++) {
4899 /* Construct the API message */
4900 M(IP_ADD_DEL_ROUTE, ip_add_del_route);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004901
Ed Warnickecb9cada2015-12-08 15:45:58 -07004902 mp->next_hop_sw_if_index = ntohl (sw_if_index);
4903 mp->vrf_id = ntohl (vrf_id);
4904 if (resolve_attempts > 0) {
4905 mp->resolve_attempts = ntohl (resolve_attempts);
4906 mp->resolve_if_needed = 1;
4907 }
4908 mp->create_vrf_if_needed = create_vrf_if_needed;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004909
Ed Warnickecb9cada2015-12-08 15:45:58 -07004910 mp->is_add = is_add;
4911 mp->is_drop = is_drop;
4912 mp->is_ipv6 = is_ipv6;
4913 mp->is_local = is_local;
4914 mp->is_classify = is_classify;
4915 mp->is_multipath = is_multipath;
4916 mp->not_last = not_last;
4917 mp->next_hop_weight = next_hop_weight;
4918 mp->dst_address_length = dst_address_length;
4919 mp->lookup_in_vrf = ntohl(lookup_in_vrf);
4920 mp->classify_table_index = ntohl(classify_table_index);
4921
4922 if (is_ipv6){
Damjan Marionf1213b82016-03-13 02:22:06 +01004923 clib_memcpy (mp->dst_address, &v6_dst_address, sizeof (v6_dst_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004924 if (next_hop_set)
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004925 clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
Ed Warnickecb9cada2015-12-08 15:45:58 -07004926 sizeof (v6_next_hop_address));
4927 increment_v6_address (&v6_dst_address);
4928 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01004929 clib_memcpy (mp->dst_address, &v4_dst_address, sizeof (v4_dst_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07004930 if (next_hop_set)
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004931 clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
Ed Warnickecb9cada2015-12-08 15:45:58 -07004932 sizeof (v4_next_hop_address));
4933 if (random_add_del)
4934 v4_dst_address.as_u32 = random_vector[j+1];
4935 else
4936 increment_v4_address (&v4_dst_address);
4937 }
4938 /* send it... */
4939 S;
4940 }
4941
4942 /* When testing multiple add/del ops, use a control-ping to sync */
4943 if (count > 1) {
4944 vl_api_control_ping_t * mp;
4945 f64 after;
4946
4947 /* Shut off async mode */
4948 vam->async_mode = 0;
4949
4950 M(CONTROL_PING, control_ping);
4951 S;
4952
4953 timeout = vat_time_now(vam) + 1.0;
4954 while (vat_time_now (vam) < timeout)
4955 if (vam->result_ready == 1)
4956 goto out;
4957 vam->retval = -99;
4958
4959 out:
4960 if (vam->retval == -99)
4961 errmsg ("timeout\n");
4962
4963 if (vam->async_errors > 0) {
4964 errmsg ("%d asynchronous errors\n", vam->async_errors);
4965 vam->retval = -98;
4966 }
4967 vam->async_errors = 0;
4968 after = vat_time_now(vam);
4969
4970 fformat(vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
4971 count, after - before, count / (after - before));
4972 } else {
4973 /* Wait for a reply... */
4974 W;
4975 }
4976
4977 /* Return the good/bad news */
4978 return (vam->retval);
4979}
4980
4981static int api_proxy_arp_add_del (vat_main_t * vam)
4982{
4983 unformat_input_t * i = vam->input;
4984 vl_api_proxy_arp_add_del_t *mp;
4985 f64 timeout;
4986 u32 vrf_id = 0;
4987 u8 is_add = 1;
4988 ip4_address_t lo, hi;
4989 u8 range_set = 0;
4990
4991 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4992 if (unformat (i, "vrf %d", &vrf_id))
4993 ;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08004994 else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
Ed Warnickecb9cada2015-12-08 15:45:58 -07004995 unformat_ip4_address, &hi))
4996 range_set = 1;
4997 else if (unformat (i, "del"))
4998 is_add = 0;
4999 else {
5000 clib_warning ("parse error '%U'", format_unformat_error, i);
5001 return -99;
5002 }
5003 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005004
Ed Warnickecb9cada2015-12-08 15:45:58 -07005005 if (range_set == 0) {
5006 errmsg ("address range not set\n");
5007 return -99;
5008 }
5009
5010 M(PROXY_ARP_ADD_DEL, proxy_arp_add_del);
5011
5012 mp->vrf_id = ntohl(vrf_id);
5013 mp->is_add = is_add;
Damjan Marionf1213b82016-03-13 02:22:06 +01005014 clib_memcpy(mp->low_address, &lo, sizeof (mp->low_address));
5015 clib_memcpy(mp->hi_address, &hi, sizeof (mp->hi_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005016
5017 S; W;
5018 /* NOTREACHED */
5019 return 0;
5020}
5021
5022static int api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
5023{
5024 unformat_input_t * i = vam->input;
5025 vl_api_proxy_arp_intfc_enable_disable_t *mp;
5026 f64 timeout;
5027 u32 sw_if_index;
5028 u8 enable = 1;
5029 u8 sw_if_index_set = 0;
5030
5031 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5032 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5033 sw_if_index_set = 1;
5034 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5035 sw_if_index_set = 1;
5036 else if (unformat (i, "enable"))
5037 enable = 1;
5038 else if (unformat (i, "disable"))
5039 enable = 0;
5040 else {
5041 clib_warning ("parse error '%U'", format_unformat_error, i);
5042 return -99;
5043 }
5044 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005045
Ed Warnickecb9cada2015-12-08 15:45:58 -07005046 if (sw_if_index_set == 0) {
5047 errmsg ("missing interface name or sw_if_index\n");
5048 return -99;
5049 }
5050
5051 M(PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
5052
5053 mp->sw_if_index = ntohl(sw_if_index);
5054 mp->enable_disable = enable;
5055
5056 S; W;
5057 /* NOTREACHED */
5058 return 0;
5059}
5060
5061static int api_mpls_add_del_decap (vat_main_t * vam)
5062{
5063 unformat_input_t * i = vam->input;
5064 vl_api_mpls_add_del_decap_t *mp;
5065 f64 timeout;
5066 u32 rx_vrf_id = 0;
5067 u32 tx_vrf_id = 0;
5068 u32 label = 0;
5069 u8 is_add = 1;
5070 u8 s_bit = 1;
5071 u32 next_index = 1;
5072
5073 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5074 if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
5075 ;
5076 else if (unformat (i, "tx_vrf_id %d", &tx_vrf_id))
5077 ;
5078 else if (unformat (i, "label %d", &label))
5079 ;
5080 else if (unformat (i, "next-index %d", &next_index))
5081 ;
5082 else if (unformat (i, "del"))
5083 is_add = 0;
5084 else if (unformat (i, "s-bit-clear"))
5085 s_bit = 0;
5086 else {
5087 clib_warning ("parse error '%U'", format_unformat_error, i);
5088 return -99;
5089 }
5090 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005091
Ed Warnickecb9cada2015-12-08 15:45:58 -07005092 M(MPLS_ADD_DEL_DECAP, mpls_add_del_decap);
5093
5094 mp->rx_vrf_id = ntohl(rx_vrf_id);
5095 mp->tx_vrf_id = ntohl(tx_vrf_id);
5096 mp->label = ntohl(label);
5097 mp->next_index = ntohl(next_index);
5098 mp->s_bit = s_bit;
5099 mp->is_add = is_add;
5100
5101 S; W;
5102 /* NOTREACHED */
5103 return 0;
5104}
5105
5106static int api_mpls_add_del_encap (vat_main_t * vam)
5107{
5108 unformat_input_t * i = vam->input;
5109 vl_api_mpls_add_del_encap_t *mp;
5110 f64 timeout;
5111 u32 vrf_id = 0;
5112 u32 *labels = 0;
5113 u32 label;
5114 ip4_address_t dst_address;
5115 u8 is_add = 1;
5116
5117 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5118 if (unformat (i, "vrf %d", &vrf_id))
5119 ;
5120 else if (unformat (i, "label %d", &label))
5121 vec_add1 (labels, ntohl(label));
5122 else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
5123 ;
5124 else if (unformat (i, "del"))
5125 is_add = 0;
5126 else {
5127 clib_warning ("parse error '%U'", format_unformat_error, i);
5128 return -99;
5129 }
5130 }
5131
5132 if (vec_len (labels) == 0) {
5133 errmsg ("missing encap label stack\n");
5134 return -99;
5135 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005136
5137 M2(MPLS_ADD_DEL_ENCAP, mpls_add_del_encap,
Ed Warnickecb9cada2015-12-08 15:45:58 -07005138 sizeof (u32) * vec_len (labels));
5139
5140 mp->vrf_id = ntohl(vrf_id);
Damjan Marionf1213b82016-03-13 02:22:06 +01005141 clib_memcpy(mp->dst_address, &dst_address, sizeof (dst_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005142 mp->is_add = is_add;
5143 mp->nlabels = vec_len (labels);
Damjan Marionf1213b82016-03-13 02:22:06 +01005144 clib_memcpy(mp->labels, labels, sizeof(u32)*mp->nlabels);
Ed Warnickecb9cada2015-12-08 15:45:58 -07005145
5146 vec_free(labels);
5147
5148 S; W;
5149 /* NOTREACHED */
5150 return 0;
5151}
5152
5153static int api_mpls_gre_add_del_tunnel (vat_main_t * vam)
5154{
5155 unformat_input_t * i = vam->input;
5156 vl_api_mpls_gre_add_del_tunnel_t *mp;
5157 f64 timeout;
5158 u32 inner_vrf_id = 0;
5159 u32 outer_vrf_id = 0;
5160 ip4_address_t src_address;
5161 ip4_address_t dst_address;
5162 ip4_address_t intfc_address;
5163 u32 tmp;
5164 u8 intfc_address_length = 0;
5165 u8 is_add = 1;
5166 u8 l2_only = 0;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005167
Ed Warnickecb9cada2015-12-08 15:45:58 -07005168 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5169 if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
5170 ;
5171 else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
5172 ;
5173 else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
5174 ;
5175 else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
5176 ;
5177 else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5178 &intfc_address, &tmp))
5179 intfc_address_length = tmp;
5180 else if (unformat (i, "l2-only"))
5181 l2_only = 1;
5182 else if (unformat (i, "del"))
5183 is_add = 0;
5184 else {
5185 clib_warning ("parse error '%U'", format_unformat_error, i);
5186 return -99;
5187 }
5188 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005189
Ed Warnickecb9cada2015-12-08 15:45:58 -07005190 M(MPLS_GRE_ADD_DEL_TUNNEL, mpls_gre_add_del_tunnel);
5191
5192 mp->inner_vrf_id = ntohl(inner_vrf_id);
5193 mp->outer_vrf_id = ntohl(outer_vrf_id);
Damjan Marionf1213b82016-03-13 02:22:06 +01005194 clib_memcpy(mp->src_address, &src_address, sizeof (src_address));
5195 clib_memcpy(mp->dst_address, &dst_address, sizeof (dst_address));
5196 clib_memcpy(mp->intfc_address, &intfc_address, sizeof (intfc_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005197 mp->intfc_address_length = intfc_address_length;
5198 mp->l2_only = l2_only;
5199 mp->is_add = is_add;
5200
5201 S; W;
5202 /* NOTREACHED */
5203 return 0;
5204}
5205
5206static int api_mpls_ethernet_add_del_tunnel (vat_main_t * vam)
5207{
5208 unformat_input_t * i = vam->input;
5209 vl_api_mpls_ethernet_add_del_tunnel_t *mp;
5210 f64 timeout;
5211 u32 inner_vrf_id = 0;
5212 ip4_address_t intfc_address;
5213 u8 dst_mac_address[6];
5214 int dst_set = 1;
5215 u32 tmp;
5216 u8 intfc_address_length = 0;
5217 u8 is_add = 1;
5218 u8 l2_only = 0;
5219 u32 tx_sw_if_index;
5220 int tx_sw_if_index_set = 0;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005221
Ed Warnickecb9cada2015-12-08 15:45:58 -07005222 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5223 if (unformat (i, "vrf %d", &inner_vrf_id))
5224 ;
5225 else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5226 &intfc_address, &tmp))
5227 intfc_address_length = tmp;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005228 else if (unformat (i, "%U",
Ed Warnickecb9cada2015-12-08 15:45:58 -07005229 unformat_sw_if_index, vam, &tx_sw_if_index))
5230 tx_sw_if_index_set = 1;
5231 else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5232 tx_sw_if_index_set = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005233 else if (unformat (i, "dst %U", unformat_ethernet_address,
Ed Warnickecb9cada2015-12-08 15:45:58 -07005234 dst_mac_address))
5235 dst_set = 1;
5236 else if (unformat (i, "l2-only"))
5237 l2_only = 1;
5238 else if (unformat (i, "del"))
5239 is_add = 0;
5240 else {
5241 clib_warning ("parse error '%U'", format_unformat_error, i);
5242 return -99;
5243 }
5244 }
5245
5246 if (!dst_set) {
5247 errmsg ("dst (mac address) not set\n");
5248 return -99;
5249 }
5250 if (!tx_sw_if_index_set) {
5251 errmsg ("tx-intfc not set\n");
5252 return -99;
5253 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005254
Ed Warnickecb9cada2015-12-08 15:45:58 -07005255 M(MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel);
5256
5257 mp->vrf_id = ntohl(inner_vrf_id);
Damjan Marionf1213b82016-03-13 02:22:06 +01005258 clib_memcpy (mp->adj_address, &intfc_address, sizeof (intfc_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005259 mp->adj_address_length = intfc_address_length;
Damjan Marionf1213b82016-03-13 02:22:06 +01005260 clib_memcpy (mp->dst_mac_address, dst_mac_address, sizeof (dst_mac_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005261 mp->tx_sw_if_index = ntohl(tx_sw_if_index);
5262 mp->l2_only = l2_only;
5263 mp->is_add = is_add;
5264
5265 S; W;
5266 /* NOTREACHED */
5267 return 0;
5268}
5269
5270static int api_mpls_ethernet_add_del_tunnel_2 (vat_main_t * vam)
5271{
5272 unformat_input_t * i = vam->input;
5273 vl_api_mpls_ethernet_add_del_tunnel_2_t *mp;
5274 f64 timeout;
5275 u32 inner_vrf_id = 0;
5276 u32 outer_vrf_id = 0;
5277 ip4_address_t adj_address;
5278 int adj_address_set = 0;
5279 ip4_address_t next_hop_address;
5280 int next_hop_address_set = 0;
5281 u32 tmp;
5282 u8 adj_address_length = 0;
5283 u8 l2_only = 0;
5284 u8 is_add = 1;
5285 u32 resolve_attempts = 5;
5286 u8 resolve_if_needed = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005287
Ed Warnickecb9cada2015-12-08 15:45:58 -07005288 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5289 if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
5290 ;
5291 else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
5292 ;
5293 else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5294 &adj_address, &tmp)) {
5295 adj_address_length = tmp;
5296 adj_address_set = 1;
5297 }
5298 else if (unformat (i, "next-hop %U", unformat_ip4_address,
5299 &next_hop_address))
5300 next_hop_address_set = 1;
5301 else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5302 ;
5303 else if (unformat (i, "resolve-if-needed %d", &tmp))
5304 resolve_if_needed = tmp;
5305 else if (unformat (i, "l2-only"))
5306 l2_only = 1;
5307 else if (unformat (i, "del"))
5308 is_add = 0;
5309 else {
5310 clib_warning ("parse error '%U'", format_unformat_error, i);
5311 return -99;
5312 }
5313 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005314
Ed Warnickecb9cada2015-12-08 15:45:58 -07005315 if (!adj_address_set) {
5316 errmsg ("adjacency address/mask not set\n");
5317 return -99;
5318 }
5319 if (!next_hop_address_set) {
5320 errmsg ("ip4 next hop address (in outer fib) not set\n");
5321 return -99;
5322 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005323
Ed Warnickecb9cada2015-12-08 15:45:58 -07005324 M(MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005325
Ed Warnickecb9cada2015-12-08 15:45:58 -07005326 mp->inner_vrf_id = ntohl(inner_vrf_id);
5327 mp->outer_vrf_id = ntohl(outer_vrf_id);
5328 mp->resolve_attempts = ntohl(resolve_attempts);
5329 mp->resolve_if_needed = resolve_if_needed;
5330 mp->is_add = is_add;
5331 mp->l2_only = l2_only;
Damjan Marionf1213b82016-03-13 02:22:06 +01005332 clib_memcpy (mp->adj_address, &adj_address, sizeof (adj_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005333 mp->adj_address_length = adj_address_length;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005334 clib_memcpy (mp->next_hop_ip4_address_in_outer_vrf, &next_hop_address,
Ed Warnickecb9cada2015-12-08 15:45:58 -07005335 sizeof (next_hop_address));
5336
5337 S; W;
5338 /* NOTREACHED */
5339 return 0;
5340}
5341
5342static int api_sw_interface_set_unnumbered (vat_main_t * vam)
5343{
5344 unformat_input_t * i = vam->input;
5345 vl_api_sw_interface_set_unnumbered_t *mp;
5346 f64 timeout;
5347 u32 sw_if_index;
5348 u32 unnum_sw_index;
5349 u8 is_add = 1;
5350 u8 sw_if_index_set = 0;
5351
5352 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5353 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5354 sw_if_index_set = 1;
5355 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5356 sw_if_index_set = 1;
5357 else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
5358 ;
5359 else if (unformat (i, "del"))
5360 is_add = 0;
5361 else {
5362 clib_warning ("parse error '%U'", format_unformat_error, i);
5363 return -99;
5364 }
5365 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005366
Ed Warnickecb9cada2015-12-08 15:45:58 -07005367 if (sw_if_index_set == 0) {
5368 errmsg ("missing interface name or sw_if_index\n");
5369 return -99;
5370 }
5371
5372 M(SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
5373
5374 mp->sw_if_index = ntohl(sw_if_index);
5375 mp->unnumbered_sw_if_index = ntohl(unnum_sw_index);
5376 mp->is_add = is_add;
5377
5378 S; W;
5379 /* NOTREACHED */
5380 return 0;
5381}
5382
5383static int api_ip_neighbor_add_del (vat_main_t * vam)
5384{
5385 unformat_input_t * i = vam->input;
5386 vl_api_ip_neighbor_add_del_t *mp;
5387 f64 timeout;
5388 u32 sw_if_index;
5389 u8 sw_if_index_set = 0;
5390 u32 vrf_id = 0;
5391 u8 is_add = 1;
5392 u8 is_static = 0;
5393 u8 mac_address[6];
5394 u8 mac_set = 0;
5395 u8 v4_address_set = 0;
5396 u8 v6_address_set = 0;
5397 ip4_address_t v4address;
5398 ip6_address_t v6address;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005399
Ed Warnickecb9cada2015-12-08 15:45:58 -07005400 memset (mac_address, 0, sizeof (mac_address));
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005401
Ed Warnickecb9cada2015-12-08 15:45:58 -07005402 /* Parse args required to build the message */
5403 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
Chris Luke49a69632016-07-08 10:34:00 -04005404 if (unformat (i, "mac %U", unformat_ethernet_address, mac_address)) {
Ed Warnickecb9cada2015-12-08 15:45:58 -07005405 mac_set = 1;
5406 }
5407 else if (unformat (i, "del"))
5408 is_add = 0;
Chris Luke49a69632016-07-08 10:34:00 -04005409 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
Ed Warnickecb9cada2015-12-08 15:45:58 -07005410 sw_if_index_set = 1;
5411 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5412 sw_if_index_set = 1;
5413 else if (unformat (i, "is_static"))
5414 is_static = 1;
5415 else if (unformat (i, "vrf %d", &vrf_id))
5416 ;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005417 else if (unformat (i, "dst %U",
Ed Warnickecb9cada2015-12-08 15:45:58 -07005418 unformat_ip4_address, &v4address))
5419 v4_address_set = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005420 else if (unformat (i, "dst %U",
Ed Warnickecb9cada2015-12-08 15:45:58 -07005421 unformat_ip6_address, &v6address))
5422 v6_address_set = 1;
5423 else {
5424 clib_warning ("parse error '%U'", format_unformat_error, i);
5425 return -99;
5426 }
5427 }
5428
5429 if (sw_if_index_set == 0) {
5430 errmsg ("missing interface name or sw_if_index\n");
5431 return -99;
5432 }
5433 if (v4_address_set && v6_address_set) {
5434 errmsg ("both v4 and v6 addresses set\n");
5435 return -99;
5436 }
5437 if (!v4_address_set && !v6_address_set) {
Chris Luke49a69632016-07-08 10:34:00 -04005438 errmsg ("no address set\n");
Ed Warnickecb9cada2015-12-08 15:45:58 -07005439 return -99;
5440 }
5441
5442 /* Construct the API message */
5443 M(IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
5444
5445 mp->sw_if_index = ntohl (sw_if_index);
5446 mp->is_add = is_add;
5447 mp->vrf_id = ntohl (vrf_id);
5448 mp->is_static = is_static;
5449 if (mac_set)
Damjan Marionf1213b82016-03-13 02:22:06 +01005450 clib_memcpy (mp->mac_address, mac_address, 6);
Ed Warnickecb9cada2015-12-08 15:45:58 -07005451 if (v6_address_set) {
5452 mp->is_ipv6 = 1;
Damjan Marionf1213b82016-03-13 02:22:06 +01005453 clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005454 } else {
5455 /* mp->is_ipv6 = 0; via memset in M macro above */
Damjan Marionf1213b82016-03-13 02:22:06 +01005456 clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005457 }
5458
5459 /* send it... */
5460 S;
5461
5462 /* Wait for a reply, return good/bad news */
5463 W;
5464
5465 /* NOTREACHED */
5466 return 0;
5467}
5468
5469static int api_reset_vrf (vat_main_t * vam)
5470{
5471 unformat_input_t * i = vam->input;
5472 vl_api_reset_vrf_t *mp;
5473 f64 timeout;
5474 u32 vrf_id = 0;
5475 u8 is_ipv6 = 0;
5476 u8 vrf_id_set = 0;
5477
5478 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5479 if (unformat (i, "vrf %d", &vrf_id))
5480 vrf_id_set = 1;
5481 else if (unformat (i, "ipv6"))
5482 is_ipv6 = 1;
5483 else {
5484 clib_warning ("parse error '%U'", format_unformat_error, i);
5485 return -99;
5486 }
5487 }
5488
5489 if (vrf_id_set == 0) {
5490 errmsg ("missing vrf id\n");
5491 return -99;
5492 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005493
Ed Warnickecb9cada2015-12-08 15:45:58 -07005494 M(RESET_VRF, reset_vrf);
5495
5496 mp->vrf_id = ntohl(vrf_id);
5497 mp->is_ipv6 = is_ipv6;
5498
5499 S; W;
5500 /* NOTREACHED */
5501 return 0;
5502}
5503
5504static int api_create_vlan_subif (vat_main_t * vam)
5505{
5506 unformat_input_t * i = vam->input;
5507 vl_api_create_vlan_subif_t *mp;
5508 f64 timeout;
5509 u32 sw_if_index;
5510 u8 sw_if_index_set = 0;
5511 u32 vlan_id;
5512 u8 vlan_id_set = 0;
5513
5514 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5515 if (unformat (i, "sw_if_index %d", &sw_if_index))
5516 sw_if_index_set = 1;
5517 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5518 sw_if_index_set = 1;
5519 else if (unformat (i, "vlan %d", &vlan_id))
5520 vlan_id_set = 1;
5521 else {
5522 clib_warning ("parse error '%U'", format_unformat_error, i);
5523 return -99;
5524 }
5525 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005526
Ed Warnickecb9cada2015-12-08 15:45:58 -07005527 if (sw_if_index_set == 0) {
5528 errmsg ("missing interface name or sw_if_index\n");
5529 return -99;
5530 }
5531
5532 if (vlan_id_set == 0) {
5533 errmsg ("missing vlan_id\n");
5534 return -99;
5535 }
5536 M(CREATE_VLAN_SUBIF, create_vlan_subif);
5537
5538 mp->sw_if_index = ntohl(sw_if_index);
5539 mp->vlan_id = ntohl(vlan_id);
5540
5541 S; W;
5542 /* NOTREACHED */
5543 return 0;
5544}
5545
5546#define foreach_create_subif_bit \
5547_(no_tags) \
5548_(one_tag) \
5549_(two_tags) \
5550_(dot1ad) \
5551_(exact_match) \
5552_(default_sub) \
5553_(outer_vlan_id_any) \
5554_(inner_vlan_id_any)
5555
5556static int api_create_subif (vat_main_t * vam)
5557{
5558 unformat_input_t * i = vam->input;
5559 vl_api_create_subif_t *mp;
5560 f64 timeout;
5561 u32 sw_if_index;
5562 u8 sw_if_index_set = 0;
5563 u32 sub_id;
5564 u8 sub_id_set = 0;
5565 u32 no_tags = 0;
5566 u32 one_tag = 0;
5567 u32 two_tags = 0;
5568 u32 dot1ad = 0;
5569 u32 exact_match = 0;
5570 u32 default_sub = 0;
5571 u32 outer_vlan_id_any = 0;
5572 u32 inner_vlan_id_any = 0;
5573 u32 tmp;
5574 u16 outer_vlan_id = 0;
5575 u16 inner_vlan_id = 0;
5576
5577 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5578 if (unformat (i, "sw_if_index %d", &sw_if_index))
5579 sw_if_index_set = 1;
5580 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5581 sw_if_index_set = 1;
5582 else if (unformat (i, "sub_id %d", &sub_id))
5583 sub_id_set = 1;
5584 else if (unformat (i, "outer_vlan_id %d", &tmp))
5585 outer_vlan_id = tmp;
5586 else if (unformat (i, "inner_vlan_id %d", &tmp))
5587 inner_vlan_id = tmp;
5588
5589#define _(a) else if (unformat (i, #a)) a = 1 ;
5590 foreach_create_subif_bit
5591#undef _
5592
5593 else {
5594 clib_warning ("parse error '%U'", format_unformat_error, i);
5595 return -99;
5596 }
5597 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005598
Ed Warnickecb9cada2015-12-08 15:45:58 -07005599 if (sw_if_index_set == 0) {
5600 errmsg ("missing interface name or sw_if_index\n");
5601 return -99;
5602 }
5603
5604 if (sub_id_set == 0) {
5605 errmsg ("missing sub_id\n");
5606 return -99;
5607 }
5608 M(CREATE_SUBIF, create_subif);
5609
5610 mp->sw_if_index = ntohl(sw_if_index);
5611 mp->sub_id = ntohl(sub_id);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005612
Ed Warnickecb9cada2015-12-08 15:45:58 -07005613#define _(a) mp->a = a;
5614 foreach_create_subif_bit;
5615#undef _
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005616
Ed Warnickecb9cada2015-12-08 15:45:58 -07005617 mp->outer_vlan_id = ntohs (outer_vlan_id);
5618 mp->inner_vlan_id = ntohs (inner_vlan_id);
5619
5620 S; W;
5621 /* NOTREACHED */
5622 return 0;
5623}
5624
5625static int api_oam_add_del (vat_main_t * vam)
5626{
5627 unformat_input_t * i = vam->input;
5628 vl_api_oam_add_del_t *mp;
5629 f64 timeout;
5630 u32 vrf_id = 0;
5631 u8 is_add = 1;
5632 ip4_address_t src, dst;
5633 u8 src_set = 0;
5634 u8 dst_set = 0;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005635
Ed Warnickecb9cada2015-12-08 15:45:58 -07005636 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5637 if (unformat (i, "vrf %d", &vrf_id))
5638 ;
5639 else if (unformat (i, "src %U", unformat_ip4_address, &src))
5640 src_set = 1;
5641 else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
5642 dst_set = 1;
5643 else if (unformat (i, "del"))
5644 is_add = 0;
5645 else {
5646 clib_warning ("parse error '%U'", format_unformat_error, i);
5647 return -99;
5648 }
5649 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005650
Ed Warnickecb9cada2015-12-08 15:45:58 -07005651 if (src_set == 0) {
5652 errmsg ("missing src addr\n");
5653 return -99;
5654 }
5655
5656 if (dst_set == 0) {
5657 errmsg ("missing dst addr\n");
5658 return -99;
5659 }
5660
5661 M(OAM_ADD_DEL, oam_add_del);
5662
5663 mp->vrf_id = ntohl(vrf_id);
5664 mp->is_add = is_add;
Damjan Marionf1213b82016-03-13 02:22:06 +01005665 clib_memcpy(mp->src_address, &src, sizeof (mp->src_address));
5666 clib_memcpy(mp->dst_address, &dst, sizeof (mp->dst_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005667
5668 S; W;
5669 /* NOTREACHED */
5670 return 0;
5671}
5672
5673static int api_reset_fib (vat_main_t * vam)
5674{
5675 unformat_input_t * i = vam->input;
5676 vl_api_reset_fib_t *mp;
5677 f64 timeout;
5678 u32 vrf_id = 0;
5679 u8 is_ipv6 = 0;
5680 u8 vrf_id_set = 0;
5681
5682 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5683 if (unformat (i, "vrf %d", &vrf_id))
5684 vrf_id_set = 1;
5685 else if (unformat (i, "ipv6"))
5686 is_ipv6 = 1;
5687 else {
5688 clib_warning ("parse error '%U'", format_unformat_error, i);
5689 return -99;
5690 }
5691 }
5692
5693 if (vrf_id_set == 0) {
5694 errmsg ("missing vrf id\n");
5695 return -99;
5696 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005697
Ed Warnickecb9cada2015-12-08 15:45:58 -07005698 M(RESET_FIB, reset_fib);
5699
5700 mp->vrf_id = ntohl(vrf_id);
5701 mp->is_ipv6 = is_ipv6;
5702
5703 S; W;
5704 /* NOTREACHED */
5705 return 0;
5706}
5707
5708static int api_dhcp_proxy_config (vat_main_t * vam)
5709{
5710 unformat_input_t * i = vam->input;
5711 vl_api_dhcp_proxy_config_t *mp;
5712 f64 timeout;
5713 u32 vrf_id = 0;
5714 u8 is_add = 1;
5715 u8 insert_cid = 1;
5716 u8 v4_address_set = 0;
5717 u8 v6_address_set = 0;
5718 ip4_address_t v4address;
5719 ip6_address_t v6address;
5720 u8 v4_src_address_set = 0;
5721 u8 v6_src_address_set = 0;
5722 ip4_address_t v4srcaddress;
5723 ip6_address_t v6srcaddress;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005724
Ed Warnickecb9cada2015-12-08 15:45:58 -07005725 /* Parse args required to build the message */
5726 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5727 if (unformat (i, "del"))
5728 is_add = 0;
5729 else if (unformat (i, "vrf %d", &vrf_id))
5730 ;
5731 else if (unformat (i, "insert-cid %d", &insert_cid))
5732 ;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005733 else if (unformat (i, "svr %U",
Ed Warnickecb9cada2015-12-08 15:45:58 -07005734 unformat_ip4_address, &v4address))
5735 v4_address_set = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005736 else if (unformat (i, "svr %U",
Ed Warnickecb9cada2015-12-08 15:45:58 -07005737 unformat_ip6_address, &v6address))
5738 v6_address_set = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005739 else if (unformat (i, "src %U",
Ed Warnickecb9cada2015-12-08 15:45:58 -07005740 unformat_ip4_address, &v4srcaddress))
5741 v4_src_address_set = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005742 else if (unformat (i, "src %U",
Ed Warnickecb9cada2015-12-08 15:45:58 -07005743 unformat_ip6_address, &v6srcaddress))
5744 v6_src_address_set = 1;
5745 else
5746 break;
5747 }
5748
5749 if (v4_address_set && v6_address_set) {
5750 errmsg ("both v4 and v6 server addresses set\n");
5751 return -99;
5752 }
5753 if (!v4_address_set && !v6_address_set) {
5754 errmsg ("no server addresses set\n");
5755 return -99;
5756 }
5757
5758 if (v4_src_address_set && v6_src_address_set) {
5759 errmsg ("both v4 and v6 src addresses set\n");
5760 return -99;
5761 }
5762 if (!v4_src_address_set && !v6_src_address_set) {
5763 errmsg ("no src addresses set\n");
5764 return -99;
5765 }
5766
5767 if (!(v4_src_address_set && v4_address_set) &&
5768 !(v6_src_address_set && v6_address_set)) {
5769 errmsg ("no matching server and src addresses set\n");
5770 return -99;
5771 }
5772
5773 /* Construct the API message */
5774 M(DHCP_PROXY_CONFIG, dhcp_proxy_config);
5775
5776 mp->insert_circuit_id = insert_cid;
5777 mp->is_add = is_add;
5778 mp->vrf_id = ntohl (vrf_id);
5779 if (v6_address_set) {
5780 mp->is_ipv6 = 1;
Damjan Marionf1213b82016-03-13 02:22:06 +01005781 clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
5782 clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005783 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01005784 clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
5785 clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005786 }
5787
5788 /* send it... */
5789 S;
5790
5791 /* Wait for a reply, return good/bad news */
5792 W;
5793 /* NOTREACHED */
5794 return 0;
5795}
5796
5797static int api_dhcp_proxy_config_2 (vat_main_t * vam)
5798{
5799 unformat_input_t * i = vam->input;
5800 vl_api_dhcp_proxy_config_2_t *mp;
5801 f64 timeout;
5802 u32 rx_vrf_id = 0;
5803 u32 server_vrf_id = 0;
5804 u8 is_add = 1;
5805 u8 insert_cid = 1;
5806 u8 v4_address_set = 0;
5807 u8 v6_address_set = 0;
5808 ip4_address_t v4address;
5809 ip6_address_t v6address;
5810 u8 v4_src_address_set = 0;
5811 u8 v6_src_address_set = 0;
5812 ip4_address_t v4srcaddress;
5813 ip6_address_t v6srcaddress;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005814
Ed Warnickecb9cada2015-12-08 15:45:58 -07005815 /* Parse args required to build the message */
5816 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5817 if (unformat (i, "del"))
5818 is_add = 0;
5819 else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
5820 ;
5821 else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
5822 ;
5823 else if (unformat (i, "insert-cid %d", &insert_cid))
5824 ;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005825 else if (unformat (i, "svr %U",
Ed Warnickecb9cada2015-12-08 15:45:58 -07005826 unformat_ip4_address, &v4address))
5827 v4_address_set = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005828 else if (unformat (i, "svr %U",
Ed Warnickecb9cada2015-12-08 15:45:58 -07005829 unformat_ip6_address, &v6address))
5830 v6_address_set = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005831 else if (unformat (i, "src %U",
Ed Warnickecb9cada2015-12-08 15:45:58 -07005832 unformat_ip4_address, &v4srcaddress))
5833 v4_src_address_set = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005834 else if (unformat (i, "src %U",
Ed Warnickecb9cada2015-12-08 15:45:58 -07005835 unformat_ip6_address, &v6srcaddress))
5836 v6_src_address_set = 1;
5837 else
5838 break;
5839 }
5840
5841 if (v4_address_set && v6_address_set) {
5842 errmsg ("both v4 and v6 server addresses set\n");
5843 return -99;
5844 }
5845 if (!v4_address_set && !v6_address_set) {
5846 errmsg ("no server addresses set\n");
5847 return -99;
5848 }
5849
5850 if (v4_src_address_set && v6_src_address_set) {
5851 errmsg ("both v4 and v6 src addresses set\n");
5852 return -99;
5853 }
5854 if (!v4_src_address_set && !v6_src_address_set) {
5855 errmsg ("no src addresses set\n");
5856 return -99;
5857 }
5858
5859 if (!(v4_src_address_set && v4_address_set) &&
5860 !(v6_src_address_set && v6_address_set)) {
5861 errmsg ("no matching server and src addresses set\n");
5862 return -99;
5863 }
5864
5865 /* Construct the API message */
5866 M(DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
5867
5868 mp->insert_circuit_id = insert_cid;
5869 mp->is_add = is_add;
5870 mp->rx_vrf_id = ntohl (rx_vrf_id);
5871 mp->server_vrf_id = ntohl (server_vrf_id);
5872 if (v6_address_set) {
5873 mp->is_ipv6 = 1;
Damjan Marionf1213b82016-03-13 02:22:06 +01005874 clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
5875 clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005876 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01005877 clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
5878 clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005879 }
5880
5881 /* send it... */
5882 S;
5883
5884 /* Wait for a reply, return good/bad news */
5885 W;
5886 /* NOTREACHED */
5887 return 0;
5888}
5889
5890static int api_dhcp_proxy_set_vss (vat_main_t * vam)
5891{
5892 unformat_input_t * i = vam->input;
5893 vl_api_dhcp_proxy_set_vss_t *mp;
5894 f64 timeout;
5895 u8 is_ipv6 = 0;
5896 u8 is_add = 1;
5897 u32 tbl_id;
5898 u8 tbl_id_set = 0;
5899 u32 oui;
5900 u8 oui_set = 0;
5901 u32 fib_id;
5902 u8 fib_id_set = 0;
5903
5904 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5905 if (unformat (i, "tbl_id %d", &tbl_id))
5906 tbl_id_set = 1;
5907 if (unformat (i, "fib_id %d", &fib_id))
5908 fib_id_set = 1;
5909 if (unformat (i, "oui %d", &oui))
5910 oui_set = 1;
5911 else if (unformat (i, "ipv6"))
5912 is_ipv6 = 1;
5913 else if (unformat (i, "del"))
5914 is_add = 0;
5915 else {
5916 clib_warning ("parse error '%U'", format_unformat_error, i);
5917 return -99;
5918 }
5919 }
5920
5921 if (tbl_id_set == 0) {
5922 errmsg ("missing tbl id\n");
5923 return -99;
5924 }
5925
5926 if (fib_id_set == 0) {
5927 errmsg ("missing fib id\n");
5928 return -99;
5929 }
5930 if (oui_set == 0) {
5931 errmsg ("missing oui\n");
5932 return -99;
5933 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005934
Ed Warnickecb9cada2015-12-08 15:45:58 -07005935 M(DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
5936 mp->tbl_id = ntohl(tbl_id);
5937 mp->fib_id = ntohl(fib_id);
5938 mp->oui = ntohl(oui);
5939 mp->is_ipv6 = is_ipv6;
5940 mp->is_add = is_add;
5941
5942 S; W;
5943 /* NOTREACHED */
5944 return 0;
5945}
5946
5947static int api_dhcp_client_config (vat_main_t * vam)
5948{
5949 unformat_input_t * i = vam->input;
5950 vl_api_dhcp_client_config_t *mp;
5951 f64 timeout;
5952 u32 sw_if_index;
5953 u8 sw_if_index_set = 0;
5954 u8 is_add = 1;
5955 u8 * hostname = 0;
5956 u8 disable_event = 0;
5957
5958 /* Parse args required to build the message */
5959 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5960 if (unformat (i, "del"))
5961 is_add = 0;
5962 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5963 sw_if_index_set = 1;
5964 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5965 sw_if_index_set = 1;
5966 else if (unformat (i, "hostname %s", &hostname))
5967 ;
5968 else if (unformat (i, "disable_event"))
5969 disable_event = 1;
5970 else
5971 break;
5972 }
5973
5974 if (sw_if_index_set == 0) {
5975 errmsg ("missing interface name or sw_if_index\n");
5976 return -99;
5977 }
5978
5979 if (vec_len (hostname) > 63) {
5980 errmsg ("hostname too long\n");
5981 }
5982 vec_add1 (hostname, 0);
5983
5984 /* Construct the API message */
5985 M(DHCP_CLIENT_CONFIG, dhcp_client_config);
5986
5987 mp->sw_if_index = ntohl (sw_if_index);
Damjan Marionf1213b82016-03-13 02:22:06 +01005988 clib_memcpy (mp->hostname, hostname, vec_len (hostname));
Ed Warnickecb9cada2015-12-08 15:45:58 -07005989 vec_free (hostname);
5990 mp->is_add = is_add;
5991 mp->want_dhcp_event = disable_event ? 0 : 1;
5992 mp->pid = getpid();
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08005993
Ed Warnickecb9cada2015-12-08 15:45:58 -07005994 /* send it... */
5995 S;
5996
5997 /* Wait for a reply, return good/bad news */
5998 W;
5999 /* NOTREACHED */
6000 return 0;
6001}
6002
6003static int api_set_ip_flow_hash (vat_main_t * vam)
6004{
6005 unformat_input_t * i = vam->input;
6006 vl_api_set_ip_flow_hash_t *mp;
6007 f64 timeout;
6008 u32 vrf_id = 0;
6009 u8 is_ipv6 = 0;
6010 u8 vrf_id_set = 0;
6011 u8 src = 0;
6012 u8 dst = 0;
6013 u8 sport = 0;
6014 u8 dport = 0;
6015 u8 proto = 0;
6016 u8 reverse = 0;
6017
6018 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6019 if (unformat (i, "vrf %d", &vrf_id))
6020 vrf_id_set = 1;
6021 else if (unformat (i, "ipv6"))
6022 is_ipv6 = 1;
6023 else if (unformat (i, "src"))
6024 src = 1;
6025 else if (unformat (i, "dst"))
6026 dst = 1;
6027 else if (unformat (i, "sport"))
6028 sport = 1;
6029 else if (unformat (i, "dport"))
6030 dport = 1;
6031 else if (unformat (i, "proto"))
6032 proto = 1;
6033 else if (unformat (i, "reverse"))
6034 reverse = 1;
6035
6036 else {
6037 clib_warning ("parse error '%U'", format_unformat_error, i);
6038 return -99;
6039 }
6040 }
6041
6042 if (vrf_id_set == 0) {
6043 errmsg ("missing vrf id\n");
6044 return -99;
6045 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006046
Ed Warnickecb9cada2015-12-08 15:45:58 -07006047 M(SET_IP_FLOW_HASH, set_ip_flow_hash);
6048 mp->src = src;
6049 mp->dst = dst;
6050 mp->sport = sport;
6051 mp->dport = dport;
6052 mp->proto = proto;
6053 mp->reverse = reverse;
6054 mp->vrf_id = ntohl(vrf_id);
6055 mp->is_ipv6 = is_ipv6;
6056
6057 S; W;
6058 /* NOTREACHED */
6059 return 0;
6060}
6061
6062static int api_sw_interface_ip6_enable_disable (vat_main_t * vam)
6063{
6064 unformat_input_t * i = vam->input;
6065 vl_api_sw_interface_ip6_enable_disable_t *mp;
6066 f64 timeout;
6067 u32 sw_if_index;
6068 u8 sw_if_index_set = 0;
6069 u8 enable = 0;
6070
6071 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6072 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6073 sw_if_index_set = 1;
6074 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6075 sw_if_index_set = 1;
6076 else if (unformat (i, "enable"))
6077 enable = 1;
6078 else if (unformat (i, "disable"))
6079 enable = 0;
6080 else {
6081 clib_warning ("parse error '%U'", format_unformat_error, i);
6082 return -99;
6083 }
6084 }
6085
6086 if (sw_if_index_set == 0) {
6087 errmsg ("missing interface name or sw_if_index\n");
6088 return -99;
6089 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006090
Ed Warnickecb9cada2015-12-08 15:45:58 -07006091 M(SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
6092
6093 mp->sw_if_index = ntohl(sw_if_index);
6094 mp->enable = enable;
6095
6096 S; W;
6097 /* NOTREACHED */
6098 return 0;
6099}
6100
6101static int api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
6102{
6103 unformat_input_t * i = vam->input;
6104 vl_api_sw_interface_ip6_set_link_local_address_t *mp;
6105 f64 timeout;
6106 u32 sw_if_index;
6107 u8 sw_if_index_set = 0;
6108 u32 address_length = 0;
6109 u8 v6_address_set = 0;
6110 ip6_address_t v6address;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006111
Ed Warnickecb9cada2015-12-08 15:45:58 -07006112 /* Parse args required to build the message */
6113 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6114 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6115 sw_if_index_set = 1;
6116 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6117 sw_if_index_set = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006118 else if (unformat (i, "%U/%d",
6119 unformat_ip6_address, &v6address,
Ed Warnickecb9cada2015-12-08 15:45:58 -07006120 &address_length))
6121 v6_address_set = 1;
6122 else
6123 break;
6124 }
6125
6126 if (sw_if_index_set == 0) {
6127 errmsg ("missing interface name or sw_if_index\n");
6128 return -99;
6129 }
6130 if (!v6_address_set) {
6131 errmsg ("no address set\n");
6132 return -99;
6133 }
6134
6135 /* Construct the API message */
6136 M(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, \
6137 sw_interface_ip6_set_link_local_address);
6138
6139 mp->sw_if_index = ntohl (sw_if_index);
Damjan Marionf1213b82016-03-13 02:22:06 +01006140 clib_memcpy (mp->address, &v6address, sizeof (v6address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07006141 mp->address_length = address_length;
6142
6143 /* send it... */
6144 S;
6145
6146 /* Wait for a reply, return good/bad news */
6147 W;
6148
6149 /* NOTREACHED */
6150 return 0;
6151}
6152
6153
6154static int api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
6155{
6156 unformat_input_t * i = vam->input;
6157 vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
6158 f64 timeout;
6159 u32 sw_if_index;
6160 u8 sw_if_index_set = 0;
6161 u32 address_length = 0;
6162 u8 v6_address_set = 0;
6163 ip6_address_t v6address;
6164 u8 use_default = 0;
6165 u8 no_advertise = 0;
6166 u8 off_link = 0;
6167 u8 no_autoconfig = 0;
6168 u8 no_onlink = 0;
6169 u8 is_no = 0;
6170 u32 val_lifetime = 0;
6171 u32 pref_lifetime = 0;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006172
Ed Warnickecb9cada2015-12-08 15:45:58 -07006173 /* Parse args required to build the message */
6174 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6175 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6176 sw_if_index_set = 1;
6177 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6178 sw_if_index_set = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006179 else if (unformat (i, "%U/%d",
6180 unformat_ip6_address, &v6address,
Ed Warnickecb9cada2015-12-08 15:45:58 -07006181 &address_length))
6182 v6_address_set = 1;
6183 else if (unformat (i, "val_life %d", &val_lifetime))
6184 ;
6185 else if (unformat (i, "pref_life %d", &pref_lifetime))
6186 ;
6187 else if (unformat (i, "def"))
6188 use_default = 1;
6189 else if (unformat (i, "noadv"))
6190 no_advertise = 1;
6191 else if (unformat (i, "offl"))
6192 off_link = 1;
6193 else if (unformat (i, "noauto"))
6194 no_autoconfig = 1;
6195 else if (unformat (i, "nolink"))
6196 no_onlink = 1;
6197 else if (unformat (i, "isno"))
6198 is_no = 1;
6199 else {
6200 clib_warning ("parse error '%U'", format_unformat_error, i);
6201 return -99;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006202 }
Ed Warnickecb9cada2015-12-08 15:45:58 -07006203 }
6204
6205 if (sw_if_index_set == 0) {
6206 errmsg ("missing interface name or sw_if_index\n");
6207 return -99;
6208 }
6209 if (!v6_address_set) {
6210 errmsg ("no address set\n");
6211 return -99;
6212 }
6213
6214 /* Construct the API message */
6215 M(SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
6216
6217 mp->sw_if_index = ntohl (sw_if_index);
Damjan Marionf1213b82016-03-13 02:22:06 +01006218 clib_memcpy (mp->address, &v6address, sizeof (v6address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07006219 mp->address_length = address_length;
6220 mp->use_default = use_default;
6221 mp->no_advertise = no_advertise;
6222 mp->off_link = off_link;
6223 mp->no_autoconfig = no_autoconfig;
6224 mp->no_onlink = no_onlink;
6225 mp->is_no = is_no;
6226 mp->val_lifetime = ntohl(val_lifetime);
6227 mp->pref_lifetime = ntohl(pref_lifetime);
6228
6229 /* send it... */
6230 S;
6231
6232 /* Wait for a reply, return good/bad news */
6233 W;
6234
6235 /* NOTREACHED */
6236 return 0;
6237}
6238
6239static int api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
6240{
6241 unformat_input_t * i = vam->input;
6242 vl_api_sw_interface_ip6nd_ra_config_t *mp;
6243 f64 timeout;
6244 u32 sw_if_index;
6245 u8 sw_if_index_set = 0;
Chris Luke33879c92016-06-28 19:54:21 -04006246 u8 suppress = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -07006247 u8 managed = 0;
6248 u8 other = 0;
6249 u8 ll_option = 0;
6250 u8 send_unicast = 0;
6251 u8 cease = 0;
6252 u8 is_no = 0;
6253 u8 default_router = 0;
6254 u32 max_interval = 0;
6255 u32 min_interval = 0;
6256 u32 lifetime = 0;
6257 u32 initial_count = 0;
6258 u32 initial_interval = 0;
6259
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006260
Ed Warnickecb9cada2015-12-08 15:45:58 -07006261 /* Parse args required to build the message */
6262 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6263 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6264 sw_if_index_set = 1;
6265 else if (unformat (i, "sw_if_index %d", &sw_if_index))
6266 sw_if_index_set = 1;
6267 else if (unformat (i, "maxint %d", &max_interval))
6268 ;
6269 else if (unformat (i, "minint %d", &min_interval))
6270 ;
6271 else if (unformat (i, "life %d", &lifetime))
6272 ;
6273 else if (unformat (i, "count %d", &initial_count))
6274 ;
6275 else if (unformat (i, "interval %d", &initial_interval))
6276 ;
Chris Luke33879c92016-06-28 19:54:21 -04006277 else if (unformat (i, "suppress") || unformat (i, "surpress"))
6278 suppress = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -07006279 else if (unformat (i, "managed"))
6280 managed = 1;
6281 else if (unformat (i, "other"))
6282 other = 1;
6283 else if (unformat (i, "ll"))
6284 ll_option = 1;
6285 else if (unformat (i, "send"))
6286 send_unicast = 1;
6287 else if (unformat (i, "cease"))
6288 cease = 1;
6289 else if (unformat (i, "isno"))
6290 is_no = 1;
6291 else if (unformat (i, "def"))
6292 default_router = 1;
6293 else {
6294 clib_warning ("parse error '%U'", format_unformat_error, i);
6295 return -99;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006296 }
Ed Warnickecb9cada2015-12-08 15:45:58 -07006297 }
6298
6299 if (sw_if_index_set == 0) {
6300 errmsg ("missing interface name or sw_if_index\n");
6301 return -99;
6302 }
6303
6304 /* Construct the API message */
6305 M(SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
6306
6307 mp->sw_if_index = ntohl (sw_if_index);
6308 mp->max_interval = ntohl(max_interval);
6309 mp->min_interval = ntohl(min_interval);
6310 mp->lifetime = ntohl(lifetime);
6311 mp->initial_count = ntohl(initial_count);
6312 mp->initial_interval = ntohl(initial_interval);
Chris Luke33879c92016-06-28 19:54:21 -04006313 mp->suppress = suppress;
Ed Warnickecb9cada2015-12-08 15:45:58 -07006314 mp->managed = managed;
6315 mp->other = other;
6316 mp->ll_option = ll_option;
6317 mp->send_unicast = send_unicast;
6318 mp->cease = cease;
6319 mp->is_no = is_no;
6320 mp->default_router = default_router;
6321
6322 /* send it... */
6323 S;
6324
6325 /* Wait for a reply, return good/bad news */
6326 W;
6327
6328 /* NOTREACHED */
6329 return 0;
6330}
6331
6332static int api_set_arp_neighbor_limit (vat_main_t * vam)
6333{
6334 unformat_input_t * i = vam->input;
6335 vl_api_set_arp_neighbor_limit_t *mp;
6336 f64 timeout;
6337 u32 arp_nbr_limit;
6338 u8 limit_set = 0;
6339 u8 is_ipv6 = 0;
6340
6341 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6342 if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
6343 limit_set = 1;
6344 else if (unformat (i, "ipv6"))
6345 is_ipv6 = 1;
6346 else {
6347 clib_warning ("parse error '%U'", format_unformat_error, i);
6348 return -99;
6349 }
6350 }
6351
6352 if (limit_set == 0) {
6353 errmsg ("missing limit value\n");
6354 return -99;
6355 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006356
Ed Warnickecb9cada2015-12-08 15:45:58 -07006357 M(SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
6358
6359 mp->arp_neighbor_limit = ntohl(arp_nbr_limit);
6360 mp->is_ipv6 = is_ipv6;
6361
6362 S; W;
6363 /* NOTREACHED */
6364 return 0;
6365}
6366
6367static int api_l2_patch_add_del (vat_main_t * vam)
6368{
6369 unformat_input_t * i = vam->input;
6370 vl_api_l2_patch_add_del_t *mp;
6371 f64 timeout;
6372 u32 rx_sw_if_index;
6373 u8 rx_sw_if_index_set = 0;
6374 u32 tx_sw_if_index;
6375 u8 tx_sw_if_index_set = 0;
6376 u8 is_add = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006377
Ed Warnickecb9cada2015-12-08 15:45:58 -07006378 /* Parse args required to build the message */
6379 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6380 if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006381 rx_sw_if_index_set = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -07006382 else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6383 tx_sw_if_index_set = 1;
6384 else if (unformat (i, "rx")) {
6385 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6386 if (unformat (i, "%U", unformat_sw_if_index, vam,
6387 &rx_sw_if_index))
6388 rx_sw_if_index_set = 1;
6389 } else
6390 break;
6391 } else if (unformat (i, "tx")) {
6392 if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6393 if (unformat (i, "%U", unformat_sw_if_index, vam,
6394 &tx_sw_if_index))
6395 tx_sw_if_index_set = 1;
6396 } else
6397 break;
6398 } else if (unformat (i, "del"))
6399 is_add = 0;
6400 else
6401 break;
6402 }
6403
6404 if (rx_sw_if_index_set == 0) {
6405 errmsg ("missing rx interface name or rx_sw_if_index\n");
6406 return -99;
6407 }
6408
6409 if (tx_sw_if_index_set == 0) {
6410 errmsg ("missing tx interface name or tx_sw_if_index\n");
6411 return -99;
6412 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006413
Ed Warnickecb9cada2015-12-08 15:45:58 -07006414 M(L2_PATCH_ADD_DEL, l2_patch_add_del);
6415
6416 mp->rx_sw_if_index = ntohl(rx_sw_if_index);
6417 mp->tx_sw_if_index = ntohl(tx_sw_if_index);
6418 mp->is_add = is_add;
6419
6420 S; W;
6421 /* NOTREACHED */
6422 return 0;
6423}
Shwetha20a64f52016-03-25 10:55:01 +00006424static int api_trace_profile_add (vat_main_t *vam)
6425{
6426 unformat_input_t * input = vam->input;
6427 vl_api_trace_profile_add_t *mp;
6428 f64 timeout;
6429 u32 id = 0;
6430 u32 trace_option_elts = 0;
6431 u32 trace_type = 0, node_id = 0, app_data = 0, trace_tsp = 2;
6432 int has_pow_option = 0;
6433 int has_ppc_option = 0;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006434
Shwetha20a64f52016-03-25 10:55:01 +00006435 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
6436 {
6437 if (unformat (input, "id %d trace-type 0x%x trace-elts %d "
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006438 "trace-tsp %d node-id 0x%x app-data 0x%x",
Shwetha20a64f52016-03-25 10:55:01 +00006439 &id, &trace_type, &trace_option_elts, &trace_tsp,
6440 &node_id, &app_data))
6441 ;
6442 else if (unformat (input, "pow"))
6443 has_pow_option = 1;
6444 else if (unformat (input, "ppc encap"))
6445 has_ppc_option = PPC_ENCAP;
6446 else if (unformat (input, "ppc decap"))
6447 has_ppc_option = PPC_DECAP;
6448 else if (unformat (input, "ppc none"))
6449 has_ppc_option = PPC_NONE;
6450 else
6451 break;
6452 }
6453 M(TRACE_PROFILE_ADD, trace_profile_add);
6454 mp->id = htons(id);
6455 mp->trace_type = trace_type;
6456 mp->trace_num_elt = trace_option_elts;
6457 mp->trace_ppc = has_ppc_option;
6458 mp->trace_app_data = htonl(app_data);
6459 mp->pow_enable = has_pow_option;
6460 mp->trace_tsp = trace_tsp;
6461 mp->node_id = htonl(node_id);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006462
Shwetha20a64f52016-03-25 10:55:01 +00006463 S; W;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006464
Shwetha20a64f52016-03-25 10:55:01 +00006465 return(0);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006466
Shwetha20a64f52016-03-25 10:55:01 +00006467}
6468static int api_trace_profile_apply (vat_main_t *vam)
6469{
6470 unformat_input_t * input = vam->input;
6471 vl_api_trace_profile_apply_t *mp;
6472 f64 timeout;
6473 ip6_address_t addr;
6474 u32 mask_width = ~0;
6475 int is_add = 0;
6476 int is_pop = 0;
6477 int is_none = 0;
6478 u32 vrf_id = 0;
6479 u32 id = 0;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006480
Shwetha20a64f52016-03-25 10:55:01 +00006481 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
6482 {
6483 if (unformat (input, "%U/%d",
6484 unformat_ip6_address, &addr, &mask_width))
6485 ;
6486 else if (unformat (input, "id %d", &id))
6487 ;
6488 else if (unformat (input, "vrf-id %d", &vrf_id))
6489 ;
6490 else if (unformat (input, "add"))
6491 is_add = 1;
6492 else if (unformat (input, "pop"))
6493 is_pop = 1;
6494 else if (unformat (input, "none"))
6495 is_none = 1;
6496 else
6497 break;
6498 }
Ed Warnickecb9cada2015-12-08 15:45:58 -07006499
Shwetha20a64f52016-03-25 10:55:01 +00006500 if ((is_add + is_pop + is_none) != 1) {
6501 errmsg("One of (add, pop, none) required");
6502 return -99;
6503 }
6504 if (mask_width == ~0) {
6505 errmsg("<address>/<mask-width> required");
6506 return -99;
6507 }
6508 M(TRACE_PROFILE_APPLY, trace_profile_apply);
Damjan Marionf1213b82016-03-13 02:22:06 +01006509 clib_memcpy(mp->dest_ipv6, &addr, sizeof(mp->dest_ipv6));
Shwetha20a64f52016-03-25 10:55:01 +00006510 mp->id = htons(id);
6511 mp->prefix_length = htonl(mask_width);
6512 mp->vrf_id = htonl(vrf_id);
6513 if (is_add)
6514 mp->trace_op = IOAM_HBYH_ADD;
6515 else if (is_pop)
6516 mp->trace_op = IOAM_HBYH_POP;
6517 else
6518 mp->trace_op = IOAM_HBYH_MOD;
6519
6520 if(is_none)
6521 mp->enable = 0;
6522 else
6523 mp->enable = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006524
Shwetha20a64f52016-03-25 10:55:01 +00006525 S; W;
6526
6527 return 0;
6528}
6529
6530static int api_trace_profile_del (vat_main_t *vam)
6531{
6532 vl_api_trace_profile_del_t *mp;
6533 f64 timeout;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006534
Shwetha20a64f52016-03-25 10:55:01 +00006535 M(TRACE_PROFILE_DEL, trace_profile_del);
6536 S; W;
6537 return 0;
6538}
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07006539
Ed Warnickecb9cada2015-12-08 15:45:58 -07006540static int api_sr_tunnel_add_del (vat_main_t * vam)
6541{
6542 unformat_input_t * i = vam->input;
6543 vl_api_sr_tunnel_add_del_t *mp;
6544 f64 timeout;
6545 int is_del = 0;
6546 int pl_index;
6547 ip6_address_t src_address;
6548 int src_address_set = 0;
6549 ip6_address_t dst_address;
6550 u32 dst_mask_width;
6551 int dst_address_set = 0;
6552 u16 flags = 0;
6553 u32 rx_table_id = 0;
6554 u32 tx_table_id = 0;
6555 ip6_address_t * segments = 0;
6556 ip6_address_t * this_seg;
6557 ip6_address_t * tags = 0;
6558 ip6_address_t * this_tag;
6559 ip6_address_t next_address, tag;
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07006560 u8 * name = 0;
6561 u8 * policy_name = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -07006562
6563 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6564 {
6565 if (unformat (i, "del"))
6566 is_del = 1;
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07006567 else if (unformat (i, "name %s", &name))
6568 ;
6569 else if (unformat (i, "policy %s", &policy_name))
6570 ;
Ed Warnickecb9cada2015-12-08 15:45:58 -07006571 else if (unformat (i, "rx_fib_id %d", &rx_table_id))
6572 ;
6573 else if (unformat (i, "tx_fib_id %d", &tx_table_id))
6574 ;
6575 else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
6576 src_address_set = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006577 else if (unformat (i, "dst %U/%d",
Ed Warnickecb9cada2015-12-08 15:45:58 -07006578 unformat_ip6_address, &dst_address,
6579 &dst_mask_width))
6580 dst_address_set = 1;
6581 else if (unformat (i, "next %U", unformat_ip6_address,
6582 &next_address))
6583 {
6584 vec_add2 (segments, this_seg, 1);
Damjan Marionf1213b82016-03-13 02:22:06 +01006585 clib_memcpy (this_seg->as_u8, next_address.as_u8, sizeof (*this_seg));
Ed Warnickecb9cada2015-12-08 15:45:58 -07006586 }
6587 else if (unformat (i, "tag %U", unformat_ip6_address,
6588 &tag))
6589 {
6590 vec_add2 (tags, this_tag, 1);
Damjan Marionf1213b82016-03-13 02:22:06 +01006591 clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
Ed Warnickecb9cada2015-12-08 15:45:58 -07006592 }
6593 else if (unformat (i, "clean"))
6594 flags |= IP6_SR_HEADER_FLAG_CLEANUP;
6595 else if (unformat (i, "protected"))
6596 flags |= IP6_SR_HEADER_FLAG_PROTECTED;
6597 else if (unformat (i, "InPE %d", &pl_index))
6598 {
6599 if (pl_index <= 0 || pl_index > 4)
6600 {
6601 pl_index_range_error:
6602 errmsg ("pl index %d out of range\n", pl_index);
6603 return -99;
6604 }
6605 flags |= IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3*(pl_index - 1));
6606 }
6607 else if (unformat (i, "EgPE %d", &pl_index))
6608 {
6609 if (pl_index <= 0 || pl_index > 4)
6610 goto pl_index_range_error;
6611 flags |= IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3*(pl_index - 1));
6612 }
6613 else if (unformat (i, "OrgSrc %d", &pl_index))
6614 {
6615 if (pl_index <= 0 || pl_index > 4)
6616 goto pl_index_range_error;
6617 flags |= IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3*(pl_index - 1));
6618 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006619 else
Ed Warnickecb9cada2015-12-08 15:45:58 -07006620 break;
6621 }
6622
6623 if (!src_address_set)
6624 {
6625 errmsg ("src address required\n");
6626 return -99;
6627 }
6628
6629 if (!dst_address_set)
6630 {
6631 errmsg ("dst address required\n");
6632 return -99;
6633 }
6634
6635 if (!segments)
6636 {
6637 errmsg ("at least one sr segment required\n");
6638 return -99;
6639 }
6640
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006641 M2(SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
6642 vec_len(segments) * sizeof (ip6_address_t)
Ed Warnickecb9cada2015-12-08 15:45:58 -07006643 + vec_len(tags) * sizeof (ip6_address_t));
6644
Damjan Marionf1213b82016-03-13 02:22:06 +01006645 clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
6646 clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07006647 mp->dst_mask_width = dst_mask_width;
6648 mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
6649 mp->n_segments = vec_len (segments);
6650 mp->n_tags = vec_len (tags);
6651 mp->is_add = is_del == 0;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006652 clib_memcpy (mp->segs_and_tags, segments,
Ed Warnickecb9cada2015-12-08 15:45:58 -07006653 vec_len(segments)* sizeof (ip6_address_t));
Damjan Marionf1213b82016-03-13 02:22:06 +01006654 clib_memcpy (mp->segs_and_tags + vec_len(segments)*sizeof (ip6_address_t),
Ed Warnickecb9cada2015-12-08 15:45:58 -07006655 tags, vec_len(tags)* sizeof (ip6_address_t));
6656
6657 mp->outer_vrf_id = ntohl (rx_table_id);
6658 mp->inner_vrf_id = ntohl (tx_table_id);
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07006659 memcpy (mp->name, name, vec_len(name));
6660 memcpy (mp->policy_name, policy_name, vec_len(policy_name));
Ed Warnickecb9cada2015-12-08 15:45:58 -07006661
6662 vec_free (segments);
6663 vec_free (tags);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006664
Ed Warnickecb9cada2015-12-08 15:45:58 -07006665 S; W;
6666 /* NOTREACHED */
6667}
6668
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07006669static int api_sr_policy_add_del (vat_main_t * vam)
6670{
6671 unformat_input_t * input = vam->input;
6672 vl_api_sr_policy_add_del_t *mp;
6673 f64 timeout;
6674 int is_del = 0;
6675 u8 * name = 0;
6676 u8 * tunnel_name = 0;
6677 u8 ** tunnel_names = 0;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006678
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07006679 int name_set = 0 ;
6680 int tunnel_set = 0;
6681 int j = 0;
6682 int tunnel_names_length = 1; // Init to 1 to offset the #tunnel_names counter byte
6683 int tun_name_len = 0; // Different naming convention used as confusing these would be "bad" (TM)
6684
6685 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
6686 {
6687 if (unformat (input, "del"))
6688 is_del = 1;
6689 else if (unformat (input, "name %s", &name))
6690 name_set = 1;
6691 else if (unformat (input, "tunnel %s", &tunnel_name))
6692 {
6693 if (tunnel_name)
6694 {
6695 vec_add1 (tunnel_names, tunnel_name);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006696 /* For serializer:
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07006697 - length = #bytes to store in serial vector
6698 - +1 = byte to store that length
6699 */
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006700 tunnel_names_length += (vec_len (tunnel_name) + 1);
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07006701 tunnel_set = 1;
6702 tunnel_name = 0;
6703 }
6704 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006705 else
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07006706 break;
6707 }
6708
6709 if (!name_set)
6710 {
6711 errmsg ("policy name required\n");
6712 return -99;
6713 }
6714
6715 if ((!tunnel_set) && (!is_del))
6716 {
6717 errmsg ("tunnel name required\n");
6718 return -99;
6719 }
6720
6721 M2(SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
6722
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006723
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07006724
6725 mp->is_add = !is_del;
6726
6727 memcpy (mp->name, name, vec_len(name));
6728 // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
6729 u8 * serial_orig = 0;
6730 vec_validate (serial_orig, tunnel_names_length);
6731 *serial_orig = vec_len(tunnel_names); // Store the number of tunnels as length in first byte of serialized vector
6732 serial_orig += 1; // Move along one byte to store the length of first tunnel_name
6733
6734 for (j=0; j < vec_len(tunnel_names); j++)
6735 {
6736 tun_name_len = vec_len (tunnel_names[j]);
6737 *serial_orig = tun_name_len; // Store length of tunnel name in first byte of Length/Value pair
6738 serial_orig += 1; // Move along one byte to store the actual tunnel name
6739 memcpy (serial_orig, tunnel_names[j], tun_name_len);
6740 serial_orig += tun_name_len; // Advance past the copy
6741 }
6742 memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length); // Regress serial_orig to head then copy fwd
6743
6744 vec_free (tunnel_names);
6745 vec_free (tunnel_name);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006746
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07006747 S; W;
6748 /* NOTREACHED */
6749}
6750
6751static int api_sr_multicast_map_add_del (vat_main_t * vam)
6752{
6753 unformat_input_t * input = vam->input;
6754 vl_api_sr_multicast_map_add_del_t *mp;
6755 f64 timeout;
6756 int is_del = 0;
6757 ip6_address_t multicast_address;
6758 u8 * policy_name = 0;
6759 int multicast_address_set = 0;
6760
6761 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
6762 {
6763 if (unformat (input, "del"))
6764 is_del = 1;
6765 else if (unformat (input, "address %U", unformat_ip6_address, &multicast_address))
6766 multicast_address_set = 1;
6767 else if (unformat (input, "sr-policy %s", &policy_name))
6768 ;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006769 else
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07006770 break;
6771 }
6772
6773 if (!is_del && !policy_name)
6774 {
6775 errmsg ("sr-policy name required\n");
6776 return -99;
6777 }
6778
6779
6780 if (!multicast_address_set)
6781 {
6782 errmsg ("address required\n");
6783 return -99;
6784 }
6785
6786 M(SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
6787
6788 mp->is_add = !is_del;
6789 memcpy (mp->policy_name, policy_name, vec_len(policy_name));
6790 clib_memcpy (mp->multicast_address, &multicast_address, sizeof (mp->multicast_address));
6791
6792
6793 vec_free (policy_name);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006794
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -07006795 S; W;
6796 /* NOTREACHED */
6797}
6798
Ed Warnickecb9cada2015-12-08 15:45:58 -07006799
6800#define foreach_ip4_proto_field \
6801_(src_address) \
6802_(dst_address) \
6803_(tos) \
6804_(length) \
6805_(fragment_id) \
6806_(ttl) \
6807_(protocol) \
6808_(checksum)
6809
6810uword unformat_ip4_mask (unformat_input_t * input, va_list * args)
6811{
6812 u8 ** maskp = va_arg (*args, u8 **);
6813 u8 * mask = 0;
6814 u8 found_something = 0;
6815 ip4_header_t * ip;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006816
Ed Warnickecb9cada2015-12-08 15:45:58 -07006817#define _(a) u8 a=0;
6818 foreach_ip4_proto_field;
6819#undef _
6820 u8 version = 0;
6821 u8 hdr_length = 0;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006822
6823
6824 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
Ed Warnickecb9cada2015-12-08 15:45:58 -07006825 {
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006826 if (unformat (input, "version"))
Ed Warnickecb9cada2015-12-08 15:45:58 -07006827 version = 1;
6828 else if (unformat (input, "hdr_length"))
6829 hdr_length = 1;
6830 else if (unformat (input, "src"))
6831 src_address = 1;
6832 else if (unformat (input, "dst"))
6833 dst_address = 1;
6834 else if (unformat (input, "proto"))
6835 protocol = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006836
Ed Warnickecb9cada2015-12-08 15:45:58 -07006837#define _(a) else if (unformat (input, #a)) a=1;
6838 foreach_ip4_proto_field
6839#undef _
6840 else
6841 break;
6842 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006843
Ed Warnickecb9cada2015-12-08 15:45:58 -07006844#define _(a) found_something += a;
6845 foreach_ip4_proto_field;
6846#undef _
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006847
Ed Warnickecb9cada2015-12-08 15:45:58 -07006848 if (found_something == 0)
6849 return 0;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006850
Ed Warnickecb9cada2015-12-08 15:45:58 -07006851 vec_validate (mask, sizeof (*ip) - 1);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006852
Ed Warnickecb9cada2015-12-08 15:45:58 -07006853 ip = (ip4_header_t *) mask;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006854
Ed Warnickecb9cada2015-12-08 15:45:58 -07006855#define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
6856 foreach_ip4_proto_field;
6857#undef _
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006858
Ed Warnickecb9cada2015-12-08 15:45:58 -07006859 ip->ip_version_and_header_length = 0;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006860
Ed Warnickecb9cada2015-12-08 15:45:58 -07006861 if (version)
6862 ip->ip_version_and_header_length |= 0xF0;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006863
Ed Warnickecb9cada2015-12-08 15:45:58 -07006864 if (hdr_length)
6865 ip->ip_version_and_header_length |= 0x0F;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006866
Ed Warnickecb9cada2015-12-08 15:45:58 -07006867 *maskp = mask;
6868 return 1;
6869}
6870
6871#define foreach_ip6_proto_field \
6872_(src_address) \
6873_(dst_address) \
6874_(payload_length) \
6875_(hop_limit) \
6876_(protocol)
6877
6878uword unformat_ip6_mask (unformat_input_t * input, va_list * args)
6879{
6880 u8 ** maskp = va_arg (*args, u8 **);
6881 u8 * mask = 0;
6882 u8 found_something = 0;
6883 ip6_header_t * ip;
6884 u32 ip_version_traffic_class_and_flow_label;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006885
Ed Warnickecb9cada2015-12-08 15:45:58 -07006886#define _(a) u8 a=0;
6887 foreach_ip6_proto_field;
6888#undef _
6889 u8 version = 0;
6890 u8 traffic_class = 0;
6891 u8 flow_label = 0;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006892
6893 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
Ed Warnickecb9cada2015-12-08 15:45:58 -07006894 {
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006895 if (unformat (input, "version"))
Ed Warnickecb9cada2015-12-08 15:45:58 -07006896 version = 1;
6897 else if (unformat (input, "traffic-class"))
6898 traffic_class = 1;
6899 else if (unformat (input, "flow-label"))
6900 flow_label = 1;
6901 else if (unformat (input, "src"))
6902 src_address = 1;
6903 else if (unformat (input, "dst"))
6904 dst_address = 1;
6905 else if (unformat (input, "proto"))
6906 protocol = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006907
Ed Warnickecb9cada2015-12-08 15:45:58 -07006908#define _(a) else if (unformat (input, #a)) a=1;
6909 foreach_ip6_proto_field
6910#undef _
6911 else
6912 break;
6913 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006914
Ed Warnickecb9cada2015-12-08 15:45:58 -07006915#define _(a) found_something += a;
6916 foreach_ip6_proto_field;
6917#undef _
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006918
Ed Warnickecb9cada2015-12-08 15:45:58 -07006919 if (found_something == 0)
6920 return 0;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006921
Ed Warnickecb9cada2015-12-08 15:45:58 -07006922 vec_validate (mask, sizeof (*ip) - 1);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006923
Ed Warnickecb9cada2015-12-08 15:45:58 -07006924 ip = (ip6_header_t *) mask;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006925
Ed Warnickecb9cada2015-12-08 15:45:58 -07006926#define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
6927 foreach_ip6_proto_field;
6928#undef _
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006929
Ed Warnickecb9cada2015-12-08 15:45:58 -07006930 ip_version_traffic_class_and_flow_label = 0;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006931
Ed Warnickecb9cada2015-12-08 15:45:58 -07006932 if (version)
6933 ip_version_traffic_class_and_flow_label |= 0xF0000000;
6934
6935 if (traffic_class)
6936 ip_version_traffic_class_and_flow_label |= 0x0FF00000;
6937
6938 if (flow_label)
6939 ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
6940
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006941 ip->ip_version_traffic_class_and_flow_label =
Ed Warnickecb9cada2015-12-08 15:45:58 -07006942 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08006943
Ed Warnickecb9cada2015-12-08 15:45:58 -07006944 *maskp = mask;
6945 return 1;
6946}
6947
6948uword unformat_l3_mask (unformat_input_t * input, va_list * args)
6949{
6950 u8 ** maskp = va_arg (*args, u8 **);
6951
6952 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
6953 if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
6954 return 1;
6955 else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
6956 return 1;
6957 else
6958 break;
6959 }
6960 return 0;
6961}
6962
6963uword unformat_l2_mask (unformat_input_t * input, va_list * args)
6964{
6965 u8 ** maskp = va_arg (*args, u8 **);
6966 u8 * mask = 0;
6967 u8 src = 0;
6968 u8 dst = 0;
6969 u8 proto = 0;
6970 u8 tag1 = 0;
6971 u8 tag2 = 0;
6972 u8 ignore_tag1 = 0;
6973 u8 ignore_tag2 = 0;
6974 u8 cos1 = 0;
6975 u8 cos2 = 0;
6976 u8 dot1q = 0;
6977 u8 dot1ad = 0;
6978 int len = 14;
6979
6980 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
6981 if (unformat (input, "src"))
6982 src = 1;
6983 else if (unformat (input, "dst"))
6984 dst = 1;
6985 else if (unformat (input, "proto"))
6986 proto = 1;
6987 else if (unformat (input, "tag1"))
6988 tag1 = 1;
6989 else if (unformat (input, "tag2"))
6990 tag2 = 1;
6991 else if (unformat (input, "ignore-tag1"))
6992 ignore_tag1 = 1;
6993 else if (unformat (input, "ignore-tag2"))
6994 ignore_tag2 = 1;
6995 else if (unformat (input, "cos1"))
6996 cos1 = 1;
6997 else if (unformat (input, "cos2"))
6998 cos2 = 1;
6999 else if (unformat (input, "dot1q"))
7000 dot1q = 1;
7001 else if (unformat (input, "dot1ad"))
7002 dot1ad = 1;
7003 else
7004 break;
7005 }
7006 if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
7007 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
7008 return 0;
7009
7010 if (tag1 || ignore_tag1 || cos1 || dot1q)
7011 len = 18;
7012 if (tag2 || ignore_tag2 || cos2 || dot1ad)
7013 len = 22;
7014
7015 vec_validate (mask, len-1);
7016
7017 if (dst)
7018 memset (mask, 0xff, 6);
7019
7020 if (src)
7021 memset (mask + 6, 0xff, 6);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007022
Ed Warnickecb9cada2015-12-08 15:45:58 -07007023 if (tag2 || dot1ad)
7024 {
7025 /* inner vlan tag */
7026 if (tag2)
7027 {
7028 mask[19] = 0xff;
7029 mask[18] = 0x0f;
7030 }
7031 if (cos2)
7032 mask[18] |= 0xe0;
7033 if (proto)
7034 mask[21] = mask [20] = 0xff;
7035 if (tag1)
7036 {
7037 mask [15] = 0xff;
7038 mask [14] = 0x0f;
7039 }
7040 if (cos1)
7041 mask[14] |= 0xe0;
7042 *maskp = mask;
7043 return 1;
7044 }
7045 if (tag1 | dot1q)
7046 {
7047 if (tag1)
7048 {
7049 mask [15] = 0xff;
7050 mask [14] = 0x0f;
7051 }
7052 if (cos1)
7053 mask[14] |= 0xe0;
7054 if (proto)
7055 mask[16] = mask [17] = 0xff;
7056
7057 *maskp = mask;
7058 return 1;
7059 }
7060 if (cos2)
7061 mask[18] |= 0xe0;
7062 if (cos1)
7063 mask[14] |= 0xe0;
7064 if (proto)
7065 mask[12] = mask [13] = 0xff;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007066
Ed Warnickecb9cada2015-12-08 15:45:58 -07007067 *maskp = mask;
7068 return 1;
7069}
7070
7071uword unformat_classify_mask (unformat_input_t * input, va_list * args)
7072{
7073 u8 ** maskp = va_arg (*args, u8 **);
7074 u32 * skipp = va_arg (*args, u32 *);
7075 u32 * matchp = va_arg (*args, u32 *);
7076 u32 match;
7077 u8 * mask = 0;
7078 u8 * l2 = 0;
7079 u8 * l3 = 0;
7080 int i;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007081
Ed Warnickecb9cada2015-12-08 15:45:58 -07007082 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
7083 if (unformat (input, "hex %U", unformat_hex_string, &mask))
7084 ;
7085 else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
7086 ;
7087 else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
7088 ;
7089 else
7090 break;
7091 }
7092
7093 if (mask || l2 || l3)
7094 {
7095 if (l2 || l3)
7096 {
7097 /* "With a free Ethernet header in every package" */
7098 if (l2 == 0)
7099 vec_validate (l2, 13);
7100 mask = l2;
7101 vec_append (mask, l3);
7102 vec_free (l3);
7103 }
7104
7105 /* Scan forward looking for the first significant mask octet */
7106 for (i = 0; i < vec_len (mask); i++)
7107 if (mask[i])
7108 break;
7109
7110 /* compute (skip, match) params */
7111 *skipp = i / sizeof(u32x4);
7112 vec_delete (mask, *skipp * sizeof(u32x4), 0);
7113
7114 /* Pad mask to an even multiple of the vector size */
7115 while (vec_len (mask) % sizeof (u32x4))
7116 vec_add1 (mask, 0);
7117
7118 match = vec_len (mask) / sizeof (u32x4);
7119
7120 for (i = match*sizeof(u32x4); i > 0; i-= sizeof(u32x4))
7121 {
7122 u64 *tmp = (u64 *)(mask + (i-sizeof(u32x4)));
7123 if (*tmp || *(tmp+1))
7124 break;
7125 match--;
7126 }
7127 if (match == 0)
7128 clib_warning ("BUG: match 0");
7129
7130 _vec_len (mask) = match * sizeof(u32x4);
7131
7132 *matchp = match;
7133 *maskp = mask;
7134
7135 return 1;
7136 }
7137
7138 return 0;
7139}
7140
7141#define foreach_l2_next \
7142_(drop, DROP) \
7143_(ethernet, ETHERNET_INPUT) \
7144_(ip4, IP4_INPUT) \
7145_(ip6, IP6_INPUT)
7146
7147uword unformat_l2_next_index (unformat_input_t * input, va_list * args)
7148{
7149 u32 * miss_next_indexp = va_arg (*args, u32 *);
7150 u32 next_index = 0;
7151 u32 tmp;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007152
Ed Warnickecb9cada2015-12-08 15:45:58 -07007153#define _(n,N) \
7154 if (unformat (input, #n)) { next_index = L2_CLASSIFY_NEXT_##N; goto out;}
7155 foreach_l2_next;
7156#undef _
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007157
Ed Warnickecb9cada2015-12-08 15:45:58 -07007158 if (unformat (input, "%d", &tmp))
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007159 {
7160 next_index = tmp;
7161 goto out;
Ed Warnickecb9cada2015-12-08 15:45:58 -07007162 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007163
Ed Warnickecb9cada2015-12-08 15:45:58 -07007164 return 0;
7165
7166 out:
7167 *miss_next_indexp = next_index;
7168 return 1;
7169}
7170
7171#define foreach_ip_next \
7172_(miss, MISS) \
7173_(drop, DROP) \
7174_(local, LOCAL) \
7175_(rewrite, REWRITE)
7176
7177uword unformat_ip_next_index (unformat_input_t * input, va_list * args)
7178{
7179 u32 * miss_next_indexp = va_arg (*args, u32 *);
7180 u32 next_index = 0;
7181 u32 tmp;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007182
Ed Warnickecb9cada2015-12-08 15:45:58 -07007183#define _(n,N) \
7184 if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
7185 foreach_ip_next;
7186#undef _
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007187
Ed Warnickecb9cada2015-12-08 15:45:58 -07007188 if (unformat (input, "%d", &tmp))
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007189 {
7190 next_index = tmp;
7191 goto out;
Ed Warnickecb9cada2015-12-08 15:45:58 -07007192 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007193
Ed Warnickecb9cada2015-12-08 15:45:58 -07007194 return 0;
7195
7196 out:
7197 *miss_next_indexp = next_index;
7198 return 1;
7199}
7200
7201#define foreach_acl_next \
7202_(deny, DENY)
7203
7204uword unformat_acl_next_index (unformat_input_t * input, va_list * args)
7205{
7206 u32 * miss_next_indexp = va_arg (*args, u32 *);
7207 u32 next_index = 0;
7208 u32 tmp;
7209
7210#define _(n,N) \
7211 if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
7212 foreach_acl_next;
7213#undef _
7214
7215 if (unformat (input, "permit"))
7216 {
7217 next_index = ~0;
7218 goto out;
7219 }
7220 else if (unformat (input, "%d", &tmp))
7221 {
7222 next_index = tmp;
7223 goto out;
7224 }
7225
7226 return 0;
7227
7228 out:
7229 *miss_next_indexp = next_index;
7230 return 1;
7231}
7232
Matus Fabian70e6a8d2016-06-20 08:10:42 -07007233uword unformat_policer_precolor (unformat_input_t * input, va_list * args)
7234{
7235 u32 * r = va_arg (*args, u32 *);
7236
7237 if (unformat (input, "conform-color"))
7238 *r = POLICE_CONFORM;
7239 else if (unformat (input, "exceed-color"))
7240 *r = POLICE_EXCEED;
7241 else
7242 return 0;
7243
7244 return 1;
7245}
7246
Ed Warnickecb9cada2015-12-08 15:45:58 -07007247static int api_classify_add_del_table (vat_main_t * vam)
7248{
7249 unformat_input_t * i = vam->input;
7250 vl_api_classify_add_del_table_t *mp;
7251
7252 u32 nbuckets = 2;
7253 u32 skip = ~0;
7254 u32 match = ~0;
7255 int is_add = 1;
7256 u32 table_index = ~0;
7257 u32 next_table_index = ~0;
7258 u32 miss_next_index = ~0;
7259 u32 memory_size = 32<<20;
7260 u8 * mask = 0;
7261 f64 timeout;
7262
7263 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7264 if (unformat (i, "del"))
7265 is_add = 0;
7266 else if (unformat (i, "buckets %d", &nbuckets))
7267 ;
7268 else if (unformat (i, "memory_size %d", &memory_size))
7269 ;
7270 else if (unformat (i, "skip %d", &skip))
7271 ;
7272 else if (unformat (i, "match %d", &match))
7273 ;
7274 else if (unformat (i, "table %d", &table_index))
7275 ;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007276 else if (unformat (i, "mask %U", unformat_classify_mask,
Ed Warnickecb9cada2015-12-08 15:45:58 -07007277 &mask, &skip, &match))
7278 ;
7279 else if (unformat (i, "next-table %d", &next_table_index))
7280 ;
7281 else if (unformat (i, "miss-next %U", unformat_ip_next_index,
7282 &miss_next_index))
7283 ;
7284 else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
7285 &miss_next_index))
7286 ;
7287 else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
7288 &miss_next_index))
7289 ;
7290 else
7291 break;
7292 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007293
Ed Warnickecb9cada2015-12-08 15:45:58 -07007294 if (is_add && mask == 0) {
7295 errmsg ("Mask required\n");
7296 return -99;
7297 }
7298
7299 if (is_add && skip == ~0) {
7300 errmsg ("skip count required\n");
7301 return -99;
7302 }
7303
7304 if (is_add && match == ~0) {
7305 errmsg ("match count required\n");
7306 return -99;
7307 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007308
Ed Warnickecb9cada2015-12-08 15:45:58 -07007309 if (!is_add && table_index == ~0) {
7310 errmsg ("table index required for delete\n");
7311 return -99;
7312 }
7313
7314 M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table,
7315 vec_len(mask));
7316
7317 mp->is_add = is_add;
7318 mp->table_index = ntohl(table_index);
7319 mp->nbuckets = ntohl(nbuckets);
7320 mp->memory_size = ntohl(memory_size);
7321 mp->skip_n_vectors = ntohl(skip);
7322 mp->match_n_vectors = ntohl(match);
7323 mp->next_table_index = ntohl(next_table_index);
7324 mp->miss_next_index = ntohl(miss_next_index);
Damjan Marionf1213b82016-03-13 02:22:06 +01007325 clib_memcpy (mp->mask, mask, vec_len(mask));
Ed Warnickecb9cada2015-12-08 15:45:58 -07007326
7327 vec_free(mask);
7328
7329 S; W;
7330 /* NOTREACHED */
7331}
7332
7333uword unformat_ip4_match (unformat_input_t * input, va_list * args)
7334{
7335 u8 ** matchp = va_arg (*args, u8 **);
7336 u8 * match = 0;
7337 ip4_header_t * ip;
7338 int version = 0;
7339 u32 version_val;
7340 int hdr_length = 0;
7341 u32 hdr_length_val;
7342 int src = 0, dst = 0;
7343 ip4_address_t src_val, dst_val;
7344 int proto = 0;
7345 u32 proto_val;
7346 int tos = 0;
7347 u32 tos_val;
7348 int length = 0;
7349 u32 length_val;
7350 int fragment_id = 0;
7351 u32 fragment_id_val;
7352 int ttl = 0;
7353 int ttl_val;
7354 int checksum = 0;
7355 u32 checksum_val;
7356
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007357 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
Ed Warnickecb9cada2015-12-08 15:45:58 -07007358 {
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007359 if (unformat (input, "version %d", &version_val))
Ed Warnickecb9cada2015-12-08 15:45:58 -07007360 version = 1;
7361 else if (unformat (input, "hdr_length %d", &hdr_length_val))
7362 hdr_length = 1;
7363 else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
7364 src = 1;
7365 else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
7366 dst = 1;
7367 else if (unformat (input, "proto %d", &proto_val))
7368 proto = 1;
7369 else if (unformat (input, "tos %d", &tos_val))
7370 tos = 1;
7371 else if (unformat (input, "length %d", &length_val))
7372 length = 1;
7373 else if (unformat (input, "fragment_id %d", &fragment_id_val))
7374 fragment_id = 1;
7375 else if (unformat (input, "ttl %d", &ttl_val))
7376 ttl = 1;
7377 else if (unformat (input, "checksum %d", &checksum_val))
7378 checksum = 1;
7379 else
7380 break;
7381 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007382
Ed Warnickecb9cada2015-12-08 15:45:58 -07007383 if (version + hdr_length + src + dst + proto + tos + length + fragment_id
7384 + ttl + checksum == 0)
7385 return 0;
7386
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007387 /*
Ed Warnickecb9cada2015-12-08 15:45:58 -07007388 * Aligned because we use the real comparison functions
7389 */
7390 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof(u32x4));
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007391
Ed Warnickecb9cada2015-12-08 15:45:58 -07007392 ip = (ip4_header_t *) match;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007393
Ed Warnickecb9cada2015-12-08 15:45:58 -07007394 /* These are realistically matched in practice */
7395 if (src)
7396 ip->src_address.as_u32 = src_val.as_u32;
7397
7398 if (dst)
7399 ip->dst_address.as_u32 = dst_val.as_u32;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007400
Ed Warnickecb9cada2015-12-08 15:45:58 -07007401 if (proto)
7402 ip->protocol = proto_val;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007403
Ed Warnickecb9cada2015-12-08 15:45:58 -07007404
7405 /* These are not, but they're included for completeness */
7406 if (version)
7407 ip->ip_version_and_header_length |= (version_val & 0xF)<<4;
7408
7409 if (hdr_length)
7410 ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007411
Ed Warnickecb9cada2015-12-08 15:45:58 -07007412 if (tos)
7413 ip->tos = tos_val;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007414
Ed Warnickecb9cada2015-12-08 15:45:58 -07007415 if (length)
7416 ip->length = length_val;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007417
Ed Warnickecb9cada2015-12-08 15:45:58 -07007418 if (ttl)
7419 ip->ttl = ttl_val;
7420
7421 if (checksum)
7422 ip->checksum = checksum_val;
7423
7424 *matchp = match;
7425 return 1;
7426}
7427
7428uword unformat_ip6_match (unformat_input_t * input, va_list * args)
7429{
7430 u8 ** matchp = va_arg (*args, u8 **);
7431 u8 * match = 0;
7432 ip6_header_t * ip;
7433 int version = 0;
7434 u32 version_val;
7435 u8 traffic_class;
7436 u32 traffic_class_val;
7437 u8 flow_label;
7438 u8 flow_label_val;
7439 int src = 0, dst = 0;
7440 ip6_address_t src_val, dst_val;
7441 int proto = 0;
7442 u32 proto_val;
7443 int payload_length = 0;
7444 u32 payload_length_val;
7445 int hop_limit = 0;
7446 int hop_limit_val;
7447 u32 ip_version_traffic_class_and_flow_label;
7448
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007449 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
Ed Warnickecb9cada2015-12-08 15:45:58 -07007450 {
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007451 if (unformat (input, "version %d", &version_val))
Ed Warnickecb9cada2015-12-08 15:45:58 -07007452 version = 1;
7453 else if (unformat (input, "traffic_class %d", &traffic_class_val))
7454 traffic_class = 1;
7455 else if (unformat (input, "flow_label %d", &flow_label_val))
7456 flow_label = 1;
7457 else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
7458 src = 1;
7459 else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
7460 dst = 1;
7461 else if (unformat (input, "proto %d", &proto_val))
7462 proto = 1;
7463 else if (unformat (input, "payload_length %d", &payload_length_val))
7464 payload_length = 1;
7465 else if (unformat (input, "hop_limit %d", &hop_limit_val))
7466 hop_limit = 1;
7467 else
7468 break;
7469 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007470
Ed Warnickecb9cada2015-12-08 15:45:58 -07007471 if (version + traffic_class + flow_label + src + dst + proto +
7472 payload_length + hop_limit == 0)
7473 return 0;
7474
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007475 /*
Ed Warnickecb9cada2015-12-08 15:45:58 -07007476 * Aligned because we use the real comparison functions
7477 */
7478 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof(u32x4));
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007479
Ed Warnickecb9cada2015-12-08 15:45:58 -07007480 ip = (ip6_header_t *) match;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007481
Ed Warnickecb9cada2015-12-08 15:45:58 -07007482 if (src)
Damjan Marionf1213b82016-03-13 02:22:06 +01007483 clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
Ed Warnickecb9cada2015-12-08 15:45:58 -07007484
7485 if (dst)
Damjan Marionf1213b82016-03-13 02:22:06 +01007486 clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007487
Ed Warnickecb9cada2015-12-08 15:45:58 -07007488 if (proto)
7489 ip->protocol = proto_val;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007490
Ed Warnickecb9cada2015-12-08 15:45:58 -07007491 ip_version_traffic_class_and_flow_label = 0;
7492
7493 if (version)
7494 ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
7495
7496 if (traffic_class)
7497 ip_version_traffic_class_and_flow_label |= (traffic_class_val & 0xFF) << 20;
7498
7499 if (flow_label)
7500 ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007501
7502 ip->ip_version_traffic_class_and_flow_label =
Ed Warnickecb9cada2015-12-08 15:45:58 -07007503 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
7504
7505 if (payload_length)
7506 ip->payload_length = clib_host_to_net_u16 (payload_length_val);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007507
Ed Warnickecb9cada2015-12-08 15:45:58 -07007508 if (hop_limit)
7509 ip->hop_limit = hop_limit_val;
7510
7511 *matchp = match;
7512 return 1;
7513}
7514
7515uword unformat_l3_match (unformat_input_t * input, va_list * args)
7516{
7517 u8 ** matchp = va_arg (*args, u8 **);
7518
7519 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
7520 if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
7521 return 1;
7522 else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
7523 return 1;
7524 else
7525 break;
7526 }
7527 return 0;
7528}
7529
7530uword unformat_vlan_tag (unformat_input_t * input, va_list * args)
7531{
7532 u8 * tagp = va_arg (*args, u8 *);
7533 u32 tag;
7534
7535 if (unformat(input, "%d", &tag))
7536 {
7537 tagp[0] = (tag>>8) & 0x0F;
7538 tagp[1] = tag & 0xFF;
7539 return 1;
7540 }
7541
7542 return 0;
7543}
7544
7545uword unformat_l2_match (unformat_input_t * input, va_list * args)
7546{
7547 u8 ** matchp = va_arg (*args, u8 **);
7548 u8 * match = 0;
7549 u8 src = 0;
7550 u8 src_val[6];
7551 u8 dst = 0;
7552 u8 dst_val[6];
7553 u8 proto = 0;
7554 u16 proto_val;
7555 u8 tag1 = 0;
7556 u8 tag1_val [2];
7557 u8 tag2 = 0;
7558 u8 tag2_val [2];
7559 int len = 14;
7560 u8 ignore_tag1 = 0;
7561 u8 ignore_tag2 = 0;
7562 u8 cos1 = 0;
7563 u8 cos2 = 0;
7564 u32 cos1_val = 0;
7565 u32 cos2_val = 0;
7566
7567 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
7568 if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
7569 src = 1;
7570 else if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
7571 dst = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007572 else if (unformat (input, "proto %U",
Ed Warnickecb9cada2015-12-08 15:45:58 -07007573 unformat_ethernet_type_host_byte_order, &proto_val))
7574 proto = 1;
7575 else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
7576 tag1 = 1;
7577 else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
7578 tag2 = 1;
7579 else if (unformat (input, "ignore-tag1"))
7580 ignore_tag1 = 1;
7581 else if (unformat (input, "ignore-tag2"))
7582 ignore_tag2 = 1;
7583 else if (unformat (input, "cos1 %d", &cos1_val))
7584 cos1 = 1;
7585 else if (unformat (input, "cos2 %d", &cos2_val))
7586 cos2 = 1;
7587 else
7588 break;
7589 }
7590 if ((src + dst + proto + tag1 + tag2 +
7591 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
7592 return 0;
7593
7594 if (tag1 || ignore_tag1 || cos1)
7595 len = 18;
7596 if (tag2 || ignore_tag2 || cos2)
7597 len = 22;
7598
7599 vec_validate_aligned (match, len-1, sizeof(u32x4));
7600
7601 if (dst)
Damjan Marionf1213b82016-03-13 02:22:06 +01007602 clib_memcpy (match, dst_val, 6);
Ed Warnickecb9cada2015-12-08 15:45:58 -07007603
7604 if (src)
Damjan Marionf1213b82016-03-13 02:22:06 +01007605 clib_memcpy (match + 6, src_val, 6);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007606
Ed Warnickecb9cada2015-12-08 15:45:58 -07007607 if (tag2)
7608 {
7609 /* inner vlan tag */
7610 match[19] = tag2_val[1];
7611 match[18] = tag2_val[0];
7612 if (cos2)
7613 match [18] |= (cos2_val & 0x7) << 5;
7614 if (proto)
7615 {
7616 match[21] = proto_val & 0xff;
7617 match[20] = proto_val >> 8;
7618 }
7619 if (tag1)
7620 {
7621 match [15] = tag1_val[1];
7622 match [14] = tag1_val[0];
7623 }
7624 if (cos1)
7625 match [14] |= (cos1_val & 0x7) << 5;
7626 *matchp = match;
7627 return 1;
7628 }
7629 if (tag1)
7630 {
7631 match [15] = tag1_val[1];
7632 match [14] = tag1_val[0];
7633 if (proto)
7634 {
7635 match[17] = proto_val & 0xff;
7636 match[16] = proto_val >> 8;
7637 }
7638 if (cos1)
7639 match [14] |= (cos1_val & 0x7) << 5;
7640
7641 *matchp = match;
7642 return 1;
7643 }
7644 if (cos2)
7645 match [18] |= (cos2_val & 0x7) << 5;
7646 if (cos1)
7647 match [14] |= (cos1_val & 0x7) << 5;
7648 if (proto)
7649 {
7650 match[13] = proto_val & 0xff;
7651 match[12] = proto_val >> 8;
7652 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007653
Ed Warnickecb9cada2015-12-08 15:45:58 -07007654 *matchp = match;
7655 return 1;
7656}
7657
7658
7659uword unformat_classify_match (unformat_input_t * input, va_list * args)
7660{
7661 u8 ** matchp = va_arg (*args, u8 **);
7662 u32 skip_n_vectors = va_arg (*args, u32);
7663 u32 match_n_vectors = va_arg (*args, u32);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007664
Ed Warnickecb9cada2015-12-08 15:45:58 -07007665 u8 * match = 0;
7666 u8 * l2 = 0;
7667 u8 * l3 = 0;
7668
7669 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
7670 if (unformat (input, "hex %U", unformat_hex_string, &match))
7671 ;
7672 else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
7673 ;
7674 else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
7675 ;
7676 else
7677 break;
7678 }
7679
7680 if (match || l2 || l3)
7681 {
7682 if (l2 || l3)
7683 {
7684 /* "Win a free Ethernet header in every packet" */
7685 if (l2 == 0)
7686 vec_validate_aligned (l2, 13, sizeof(u32x4));
7687 match = l2;
7688 vec_append_aligned (match, l3, sizeof(u32x4));
7689 vec_free (l3);
7690 }
7691
7692 /* Make sure the vector is big enough even if key is all 0's */
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007693 vec_validate_aligned
Ed Warnickecb9cada2015-12-08 15:45:58 -07007694 (match, ((match_n_vectors + skip_n_vectors) * sizeof(u32x4)) - 1,
7695 sizeof(u32x4));
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007696
Ed Warnickecb9cada2015-12-08 15:45:58 -07007697 /* Set size, include skipped vectors*/
7698 _vec_len (match) = (match_n_vectors+skip_n_vectors) * sizeof(u32x4);
7699
7700 *matchp = match;
7701
7702 return 1;
7703 }
7704
7705 return 0;
7706}
7707
7708static int api_classify_add_del_session (vat_main_t * vam)
7709{
7710 unformat_input_t * i = vam->input;
7711 vl_api_classify_add_del_session_t *mp;
7712 int is_add = 1;
7713 u32 table_index = ~0;
7714 u32 hit_next_index = ~0;
7715 u32 opaque_index = ~0;
7716 u8 * match = 0;
7717 i32 advance = 0;
7718 f64 timeout;
7719 u32 skip_n_vectors = 0;
7720 u32 match_n_vectors = 0;
7721
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007722 /*
Ed Warnickecb9cada2015-12-08 15:45:58 -07007723 * Warning: you have to supply skip_n and match_n
7724 * because the API client cant simply look at the classify
7725 * table object.
7726 */
7727
7728 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7729 if (unformat (i, "del"))
7730 is_add = 0;
7731 else if (unformat (i, "hit-next %U", unformat_ip_next_index,
7732 &hit_next_index))
7733 ;
7734 else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
7735 &hit_next_index))
7736 ;
7737 else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
7738 &hit_next_index))
7739 ;
Matus Fabian70e6a8d2016-06-20 08:10:42 -07007740 else if (unformat (i, "policer-hit-next %d", &hit_next_index))
7741 ;
7742 else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
7743 ;
Ed Warnickecb9cada2015-12-08 15:45:58 -07007744 else if (unformat (i, "opaque-index %d", &opaque_index))
7745 ;
7746 else if (unformat (i, "skip_n %d", &skip_n_vectors))
7747 ;
7748 else if (unformat (i, "match_n %d", &match_n_vectors))
7749 ;
7750 else if (unformat (i, "match %U", unformat_classify_match,
7751 &match, skip_n_vectors, match_n_vectors))
7752 ;
7753 else if (unformat (i, "advance %d", &advance))
7754 ;
7755 else if (unformat (i, "table-index %d", &table_index))
7756 ;
7757 else
7758 break;
7759 }
7760
7761 if (table_index == ~0) {
7762 errmsg ("Table index required\n");
7763 return -99;
7764 }
7765
7766 if (is_add && match == 0) {
7767 errmsg ("Match value required\n");
7768 return -99;
7769 }
7770
7771 M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session,
7772 vec_len(match));
7773
7774 mp->is_add = is_add;
7775 mp->table_index = ntohl(table_index);
7776 mp->hit_next_index = ntohl(hit_next_index);
7777 mp->opaque_index = ntohl(opaque_index);
7778 mp->advance = ntohl(advance);
Damjan Marionf1213b82016-03-13 02:22:06 +01007779 clib_memcpy (mp->match, match, vec_len(match));
Ed Warnickecb9cada2015-12-08 15:45:58 -07007780 vec_free(match);
7781
7782 S; W;
7783 /* NOTREACHED */
7784}
7785
7786static int api_classify_set_interface_ip_table (vat_main_t * vam)
7787{
7788 unformat_input_t * i = vam->input;
7789 vl_api_classify_set_interface_ip_table_t *mp;
7790 f64 timeout;
7791 u32 sw_if_index;
7792 int sw_if_index_set;
7793 u32 table_index = ~0;
7794 u8 is_ipv6 = 0;
7795
7796 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7797 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7798 sw_if_index_set = 1;
7799 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7800 sw_if_index_set = 1;
7801 else if (unformat (i, "table %d", &table_index))
7802 ;
7803 else {
7804 clib_warning ("parse error '%U'", format_unformat_error, i);
7805 return -99;
7806 }
7807 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007808
Ed Warnickecb9cada2015-12-08 15:45:58 -07007809 if (sw_if_index_set == 0) {
7810 errmsg ("missing interface name or sw_if_index\n");
7811 return -99;
7812 }
7813
7814
7815 M(CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
7816
7817 mp->sw_if_index = ntohl(sw_if_index);
7818 mp->table_index = ntohl(table_index);
7819 mp->is_ipv6 = is_ipv6;
7820
7821 S; W;
7822 /* NOTREACHED */
7823 return 0;
7824}
7825
7826static int api_classify_set_interface_l2_tables (vat_main_t * vam)
7827{
7828 unformat_input_t * i = vam->input;
7829 vl_api_classify_set_interface_l2_tables_t *mp;
7830 f64 timeout;
7831 u32 sw_if_index;
7832 int sw_if_index_set;
7833 u32 ip4_table_index = ~0;
7834 u32 ip6_table_index = ~0;
7835 u32 other_table_index = ~0;
7836
7837 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7838 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7839 sw_if_index_set = 1;
7840 else if (unformat (i, "sw_if_index %d", &sw_if_index))
7841 sw_if_index_set = 1;
7842 else if (unformat (i, "ip4-table %d", &ip4_table_index))
7843 ;
7844 else if (unformat (i, "ip6-table %d", &ip6_table_index))
7845 ;
7846 else if (unformat (i, "other-table %d", &other_table_index))
7847 ;
7848 else {
7849 clib_warning ("parse error '%U'", format_unformat_error, i);
7850 return -99;
7851 }
7852 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007853
Ed Warnickecb9cada2015-12-08 15:45:58 -07007854 if (sw_if_index_set == 0) {
7855 errmsg ("missing interface name or sw_if_index\n");
7856 return -99;
7857 }
7858
7859
7860 M(CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
7861
7862 mp->sw_if_index = ntohl(sw_if_index);
7863 mp->ip4_table_index = ntohl(ip4_table_index);
7864 mp->ip6_table_index = ntohl(ip6_table_index);
7865 mp->other_table_index = ntohl(other_table_index);
7866
7867
7868 S; W;
7869 /* NOTREACHED */
7870 return 0;
7871}
7872
Juraj Slobodaac645ad2016-07-07 00:18:57 -07007873static int api_ipfix_enable (vat_main_t * vam)
7874{
7875 unformat_input_t * i = vam->input;
7876 vl_api_ipfix_enable_t *mp;
7877 ip4_address_t collector_address;
7878 u8 collector_address_set = 0;
7879 u32 collector_port = ~0;
7880 ip4_address_t src_address;
7881 u8 src_address_set = 0;
7882 u32 vrf_id = ~0;
7883 u32 path_mtu = ~0;
7884 u32 template_interval = ~0;
7885 f64 timeout;
7886
7887 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7888 if (unformat (i, "collector_address %U", unformat_ip4_address,
7889 &collector_address))
7890 collector_address_set = 1;
7891 else if (unformat (i, "collector_port %d", &collector_port))
7892 ;
7893 else if (unformat (i, "src_address %U", unformat_ip4_address,
7894 &src_address))
7895 src_address_set = 1;
7896 else if (unformat (i, "vrf_id %d", &vrf_id))
7897 ;
7898 else if (unformat (i, "path_mtu %d", &path_mtu))
7899 ;
7900 else if (unformat (i, "template_interval %d", &template_interval))
7901 ;
7902 else
7903 break;
7904 }
7905
7906 if (collector_address_set == 0) {
7907 errmsg ("collector_address required\n");
7908 return -99;
7909 }
7910
7911 if (src_address_set == 0) {
7912 errmsg ("src_address required\n");
7913 return -99;
7914 }
7915
7916 M (IPFIX_ENABLE, ipfix_enable);
7917
7918 memcpy(mp->collector_address, collector_address.data,
7919 sizeof(collector_address.data));
7920 mp->collector_port = htons((u16)collector_port);
7921 memcpy(mp->src_address, src_address.data,
7922 sizeof(src_address.data));
7923 mp->vrf_id = htonl(vrf_id);
7924 mp->path_mtu = htonl(path_mtu);
7925 mp->template_interval = htonl(template_interval);
7926
7927 S; W;
7928 /* NOTREACHED */
7929}
7930
Ed Warnickecb9cada2015-12-08 15:45:58 -07007931static int api_get_node_index (vat_main_t * vam)
7932{
7933 unformat_input_t * i = vam->input;
7934 vl_api_get_node_index_t * mp;
7935 f64 timeout;
7936 u8 * name = 0;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007937
Ed Warnickecb9cada2015-12-08 15:45:58 -07007938 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7939 if (unformat (i, "node %s", &name))
7940 ;
7941 else
7942 break;
7943 }
7944 if (name == 0) {
7945 errmsg ("node name required\n");
7946 return -99;
7947 }
7948 if (vec_len (name) >= ARRAY_LEN(mp->node_name)) {
7949 errmsg ("node name too long, max %d\n", ARRAY_LEN(mp->node_name));
7950 return -99;
7951 }
7952
7953 M(GET_NODE_INDEX, get_node_index);
Damjan Marionf1213b82016-03-13 02:22:06 +01007954 clib_memcpy (mp->node_name, name, vec_len(name));
Ed Warnickecb9cada2015-12-08 15:45:58 -07007955 vec_free(name);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08007956
Ed Warnickecb9cada2015-12-08 15:45:58 -07007957 S; W;
7958 /* NOTREACHED */
7959 return 0;
7960}
7961
Keith Burns (alagalah)c61080e2016-07-19 14:47:43 -07007962static int api_get_next_index (vat_main_t * vam)
7963{
7964 unformat_input_t * i = vam->input;
7965 vl_api_get_next_index_t * mp;
7966 f64 timeout;
7967 u8 * node_name = 0, * next_node_name = 0;
7968
7969 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7970 if (unformat (i, "node-name %s", &node_name))
7971 ;
7972 else if (unformat (i, "next-node-name %s", &next_node_name))
7973 break;
7974 }
7975
7976 if (node_name == 0) {
7977 errmsg ("node name required\n");
7978 return -99;
7979 }
7980 if (vec_len (node_name) >= ARRAY_LEN(mp->node_name)) {
7981 errmsg ("node name too long, max %d\n", ARRAY_LEN(mp->node_name));
7982 return -99;
7983 }
7984
7985 if (next_node_name == 0) {
7986 errmsg ("next node name required\n");
7987 return -99;
7988 }
7989 if (vec_len (next_node_name) >= ARRAY_LEN(mp->next_name)) {
7990 errmsg ("next node name too long, max %d\n", ARRAY_LEN(mp->next_name));
7991 return -99;
7992 }
7993
7994 M(GET_NEXT_INDEX, get_next_index);
7995 clib_memcpy (mp->node_name, node_name, vec_len(node_name));
7996 clib_memcpy (mp->next_name, next_node_name, vec_len(next_node_name));
7997 vec_free(node_name);
7998 vec_free(next_node_name);
7999
8000 S; W;
8001 /* NOTREACHED */
8002 return 0;
8003}
8004
Ed Warnickecb9cada2015-12-08 15:45:58 -07008005static int api_add_node_next (vat_main_t * vam)
8006{
8007 unformat_input_t * i = vam->input;
8008 vl_api_add_node_next_t * mp;
8009 f64 timeout;
8010 u8 * name = 0;
8011 u8 * next = 0;
8012
8013 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8014 if (unformat (i, "node %s", &name))
8015 ;
8016 else if (unformat (i, "next %s", &next))
8017 ;
8018 else
8019 break;
8020 }
8021 if (name == 0) {
8022 errmsg ("node name required\n");
8023 return -99;
8024 }
8025 if (vec_len (name) >= ARRAY_LEN(mp->node_name)) {
8026 errmsg ("node name too long, max %d\n", ARRAY_LEN(mp->node_name));
8027 return -99;
8028 }
8029 if (next == 0) {
8030 errmsg ("next node required\n");
8031 return -99;
8032 }
8033 if (vec_len (next) >= ARRAY_LEN(mp->next_name)) {
8034 errmsg ("next name too long, max %d\n", ARRAY_LEN(mp->next_name));
8035 return -99;
8036 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08008037
Ed Warnickecb9cada2015-12-08 15:45:58 -07008038 M(ADD_NODE_NEXT, add_node_next);
Damjan Marionf1213b82016-03-13 02:22:06 +01008039 clib_memcpy (mp->node_name, name, vec_len(name));
8040 clib_memcpy (mp->next_name, next, vec_len(next));
Ed Warnickecb9cada2015-12-08 15:45:58 -07008041 vec_free(name);
8042 vec_free(next);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08008043
Ed Warnickecb9cada2015-12-08 15:45:58 -07008044 S; W;
8045 /* NOTREACHED */
8046 return 0;
8047}
8048
8049static int api_l2tpv3_create_tunnel (vat_main_t * vam)
8050{
8051 unformat_input_t * i = vam->input;
8052 ip6_address_t client_address, our_address;
8053 int client_address_set = 0;
8054 int our_address_set = 0;
8055 u32 local_session_id = 0;
8056 u32 remote_session_id = 0;
8057 u64 local_cookie = 0;
8058 u64 remote_cookie = 0;
8059 u8 l2_sublayer_present = 0;
8060 vl_api_l2tpv3_create_tunnel_t * mp;
8061 f64 timeout;
8062
8063 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08008064 if (unformat (i, "client_address %U", unformat_ip6_address,
Ed Warnickecb9cada2015-12-08 15:45:58 -07008065 &client_address))
8066 client_address_set = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08008067 else if (unformat (i, "our_address %U", unformat_ip6_address,
Ed Warnickecb9cada2015-12-08 15:45:58 -07008068 &our_address))
8069 our_address_set = 1;
8070 else if (unformat (i, "local_session_id %d", &local_session_id))
8071 ;
8072 else if (unformat (i, "remote_session_id %d", &remote_session_id))
8073 ;
8074 else if (unformat (i, "local_cookie %lld", &local_cookie))
8075 ;
8076 else if (unformat (i, "remote_cookie %lld", &remote_cookie))
8077 ;
8078 else if (unformat (i, "l2-sublayer-present"))
8079 l2_sublayer_present = 1;
8080 else
8081 break;
8082 }
8083
8084 if (client_address_set == 0) {
8085 errmsg ("client_address required\n");
8086 return -99;
8087 }
8088
8089 if (our_address_set == 0) {
8090 errmsg ("our_address required\n");
8091 return -99;
8092 }
8093
8094 M(L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
8095
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08008096 clib_memcpy (mp->client_address, client_address.as_u8,
Ed Warnickecb9cada2015-12-08 15:45:58 -07008097 sizeof (mp->client_address));
8098
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08008099 clib_memcpy (mp->our_address, our_address.as_u8,
Ed Warnickecb9cada2015-12-08 15:45:58 -07008100 sizeof (mp->our_address));
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08008101
Ed Warnickecb9cada2015-12-08 15:45:58 -07008102 mp->local_session_id = ntohl (local_session_id);
8103 mp->remote_session_id = ntohl (remote_session_id);
8104 mp->local_cookie = clib_host_to_net_u64 (local_cookie);
8105 mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
8106 mp->l2_sublayer_present = l2_sublayer_present;
8107 mp->is_ipv6 = 1;
8108
8109 S; W;
8110 /* NOTREACHED */
8111 return 0;
8112}
8113
8114static int api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
8115{
8116 unformat_input_t * i = vam->input;
8117 u32 sw_if_index;
8118 u8 sw_if_index_set = 0;
8119 u64 new_local_cookie = 0;
8120 u64 new_remote_cookie = 0;
8121 vl_api_l2tpv3_set_tunnel_cookies_t *mp;
8122 f64 timeout;
8123
8124 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8125 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8126 sw_if_index_set = 1;
8127 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8128 sw_if_index_set = 1;
8129 else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
8130 ;
8131 else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
8132 ;
8133 else
8134 break;
8135 }
8136
8137 if (sw_if_index_set == 0) {
8138 errmsg ("missing interface name or sw_if_index\n");
8139 return -99;
8140 }
8141
8142 M(L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
8143
8144 mp->sw_if_index = ntohl(sw_if_index);
8145 mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
8146 mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
8147
8148 S; W;
8149 /* NOTREACHED */
8150 return 0;
8151}
8152
8153static int api_l2tpv3_interface_enable_disable (vat_main_t * vam)
8154{
8155 unformat_input_t * i = vam->input;
8156 vl_api_l2tpv3_interface_enable_disable_t *mp;
8157 f64 timeout;
8158 u32 sw_if_index;
8159 u8 sw_if_index_set = 0;
8160 u8 enable_disable = 1;
8161
8162 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8163 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8164 sw_if_index_set = 1;
8165 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8166 sw_if_index_set = 1;
8167 else if (unformat (i, "enable"))
8168 enable_disable = 1;
8169 else if (unformat (i, "disable"))
8170 enable_disable = 0;
8171 else
8172 break;
8173 }
8174
8175 if (sw_if_index_set == 0) {
8176 errmsg ("missing interface name or sw_if_index\n");
8177 return -99;
8178 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08008179
Ed Warnickecb9cada2015-12-08 15:45:58 -07008180 M(L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
8181
8182 mp->sw_if_index = ntohl(sw_if_index);
8183 mp->enable_disable = enable_disable;
8184
8185 S; W;
8186 /* NOTREACHED */
8187 return 0;
8188}
8189
8190static int api_l2tpv3_set_lookup_key (vat_main_t * vam)
8191{
8192 unformat_input_t * i = vam->input;
8193 vl_api_l2tpv3_set_lookup_key_t * mp;
8194 f64 timeout;
8195 u8 key = ~0;
8196
8197 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8198 if (unformat (i, "lookup_v6_src"))
8199 key = L2T_LOOKUP_SRC_ADDRESS;
8200 else if (unformat (i, "lookup_v6_dst"))
8201 key = L2T_LOOKUP_DST_ADDRESS;
8202 else if (unformat (i, "lookup_session_id"))
8203 key = L2T_LOOKUP_SESSION_ID;
8204 else
8205 break;
8206 }
8207
Damjan Marionfa693552016-04-26 19:30:36 +02008208 if (key == (u8) ~0) {
Ed Warnickecb9cada2015-12-08 15:45:58 -07008209 errmsg ("l2tp session lookup key unset\n");
8210 return -99;
8211 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08008212
Ed Warnickecb9cada2015-12-08 15:45:58 -07008213 M(L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
8214
8215 mp->key = key;
8216
8217 S; W;
8218 /* NOTREACHED */
8219 return 0;
8220}
8221
8222static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
8223(vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
8224{
8225 vat_main_t * vam = &vat_main;
8226
8227 fformat(vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
8228 format_ip6_address, mp->our_address,
8229 format_ip6_address, mp->client_address,
8230 clib_net_to_host_u32(mp->sw_if_index));
8231
8232 fformat (vam->ofp, " local cookies %016llx %016llx remote cookie %016llx\n",
8233 clib_net_to_host_u64 (mp->local_cookie[0]),
8234 clib_net_to_host_u64 (mp->local_cookie[1]),
8235 clib_net_to_host_u64 (mp->remote_cookie));
8236
8237 fformat (vam->ofp, " local session-id %d remote session-id %d\n",
8238 clib_net_to_host_u32 (mp->local_session_id),
8239 clib_net_to_host_u32 (mp->remote_session_id));
8240
8241 fformat (vam->ofp, " l2 specific sublayer %s\n\n",
8242 mp->l2_sublayer_present ? "preset" : "absent");
8243
8244}
8245
8246static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
8247(vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
8248{
8249 vat_main_t * vam = &vat_main;
8250 vat_json_node_t *node = NULL;
8251 struct in6_addr addr;
8252
8253 if (VAT_JSON_ARRAY != vam->json_tree.type) {
8254 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
8255 vat_json_init_array(&vam->json_tree);
8256 }
8257 node = vat_json_array_add(&vam->json_tree);
8258
8259 vat_json_init_object(node);
8260
Damjan Marionf1213b82016-03-13 02:22:06 +01008261 clib_memcpy(&addr, mp->our_address, sizeof(addr));
Ed Warnickecb9cada2015-12-08 15:45:58 -07008262 vat_json_object_add_ip6(node, "our_address", addr);
Damjan Marionf1213b82016-03-13 02:22:06 +01008263 clib_memcpy(&addr, mp->client_address, sizeof(addr));
Ed Warnickecb9cada2015-12-08 15:45:58 -07008264 vat_json_object_add_ip6(node, "client_address", addr);
8265
8266 vat_json_node_t * lc = vat_json_object_add(node, "local_cookie");
8267 vat_json_init_array(lc);
8268 vat_json_array_add_uint(lc, clib_net_to_host_u64(mp->local_cookie[0]));
8269 vat_json_array_add_uint(lc, clib_net_to_host_u64(mp->local_cookie[1]));
8270 vat_json_object_add_uint(node, "remote_cookie", clib_net_to_host_u64(mp->remote_cookie));
8271
8272 printf("local id: %u", clib_net_to_host_u32(mp->local_session_id));
8273 vat_json_object_add_uint(node, "local_session_id", clib_net_to_host_u32(mp->local_session_id));
8274 vat_json_object_add_uint(node, "remote_session_id", clib_net_to_host_u32(mp->remote_session_id));
8275 vat_json_object_add_string_copy(node, "l2_sublayer", mp->l2_sublayer_present ?
8276 (u8*)"present" : (u8*)"absent");
8277}
8278
8279static int api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
8280{
8281 vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
8282 f64 timeout;
8283
8284 /* Get list of l2tpv3-tunnel interfaces */
8285 M(SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
8286 S;
8287
8288 /* Use a control ping for synchronization */
8289 {
8290 vl_api_control_ping_t * mp;
8291 M(CONTROL_PING, control_ping);
8292 S;
8293 }
8294 W;
8295}
8296
8297
8298static void vl_api_sw_interface_tap_details_t_handler
8299(vl_api_sw_interface_tap_details_t * mp)
8300{
8301 vat_main_t * vam = &vat_main;
8302
8303 fformat(vam->ofp, "%-16s %d\n",
8304 mp->dev_name,
8305 clib_net_to_host_u32(mp->sw_if_index));
8306}
8307
8308static void vl_api_sw_interface_tap_details_t_handler_json
8309(vl_api_sw_interface_tap_details_t * mp)
8310{
8311 vat_main_t * vam = &vat_main;
8312 vat_json_node_t *node = NULL;
8313
8314 if (VAT_JSON_ARRAY != vam->json_tree.type) {
8315 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
8316 vat_json_init_array(&vam->json_tree);
8317 }
8318 node = vat_json_array_add(&vam->json_tree);
8319
8320 vat_json_init_object(node);
8321 vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
8322 vat_json_object_add_string_copy(node, "dev_name", mp->dev_name);
8323}
8324
8325static int api_sw_interface_tap_dump (vat_main_t * vam)
8326{
8327 vl_api_sw_interface_tap_dump_t *mp;
8328 f64 timeout;
8329
8330 fformat(vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
8331 /* Get list of tap interfaces */
8332 M(SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
8333 S;
8334
8335 /* Use a control ping for synchronization */
8336 {
8337 vl_api_control_ping_t * mp;
8338 M(CONTROL_PING, control_ping);
8339 S;
8340 }
8341 W;
8342}
8343
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08008344static uword unformat_vxlan_decap_next
Ed Warnickecb9cada2015-12-08 15:45:58 -07008345(unformat_input_t * input, va_list * args)
8346{
8347 u32 * result = va_arg (*args, u32 *);
8348 u32 tmp;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08008349
Ed Warnickecb9cada2015-12-08 15:45:58 -07008350 if (unformat (input, "drop"))
8351 *result = VXLAN_INPUT_NEXT_DROP;
8352 else if (unformat (input, "ip4"))
8353 *result = VXLAN_INPUT_NEXT_IP4_INPUT;
8354 else if (unformat (input, "ip6"))
8355 *result = VXLAN_INPUT_NEXT_IP6_INPUT;
8356 else if (unformat (input, "l2"))
8357 *result = VXLAN_INPUT_NEXT_L2_INPUT;
8358 else if (unformat (input, "%d", &tmp))
8359 *result = tmp;
8360 else
8361 return 0;
8362 return 1;
8363}
8364
8365static int api_vxlan_add_del_tunnel (vat_main_t * vam)
8366{
8367 unformat_input_t * line_input = vam->input;
8368 vl_api_vxlan_add_del_tunnel_t *mp;
8369 f64 timeout;
Chris Luke99cb3352016-04-26 10:49:53 -04008370 ip4_address_t src4, dst4;
8371 ip6_address_t src6, dst6;
Ed Warnickecb9cada2015-12-08 15:45:58 -07008372 u8 is_add = 1;
Chris Luke99cb3352016-04-26 10:49:53 -04008373 u8 ipv4_set = 0, ipv6_set = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -07008374 u8 src_set = 0;
8375 u8 dst_set = 0;
8376 u32 encap_vrf_id = 0;
8377 u32 decap_next_index = ~0;
8378 u32 vni = 0;
8379
8380 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
8381 if (unformat (line_input, "del"))
8382 is_add = 0;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08008383 else if (unformat (line_input, "src %U",
Chris Luke99cb3352016-04-26 10:49:53 -04008384 unformat_ip4_address, &src4))
8385 {
8386 ipv4_set = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -07008387 src_set = 1;
Chris Luke99cb3352016-04-26 10:49:53 -04008388 }
Ed Warnickecb9cada2015-12-08 15:45:58 -07008389 else if (unformat (line_input, "dst %U",
Chris Luke99cb3352016-04-26 10:49:53 -04008390 unformat_ip4_address, &dst4))
8391 {
8392 ipv4_set = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -07008393 dst_set = 1;
Chris Luke99cb3352016-04-26 10:49:53 -04008394 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08008395 else if (unformat (line_input, "src %U",
Chris Luke99cb3352016-04-26 10:49:53 -04008396 unformat_ip6_address, &src6))
8397 {
8398 ipv6_set = 1;
8399 src_set = 1;
8400 }
8401 else if (unformat (line_input, "dst %U",
8402 unformat_ip6_address, &dst6))
8403 {
8404 ipv6_set = 1;
8405 dst_set = 1;
8406 }
Ed Warnickecb9cada2015-12-08 15:45:58 -07008407 else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
8408 ;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08008409 else if (unformat (line_input, "decap-next %U",
Ed Warnickecb9cada2015-12-08 15:45:58 -07008410 unformat_vxlan_decap_next, &decap_next_index))
8411 ;
8412 else if (unformat (line_input, "vni %d", &vni))
8413 ;
8414 else {
8415 errmsg ("parse error '%U'\n", format_unformat_error, line_input);
8416 return -99;
8417 }
8418 }
8419
8420 if (src_set == 0) {
8421 errmsg ("tunnel src address not specified\n");
8422 return -99;
8423 }
8424 if (dst_set == 0) {
8425 errmsg ("tunnel dst address not specified\n");
8426 return -99;
8427 }
8428
Chris Luke99cb3352016-04-26 10:49:53 -04008429 if (ipv4_set && ipv6_set) {
8430 errmsg ("both IPv4 and IPv6 addresses specified");
8431 return -99;
8432 }
8433
Ed Warnickecb9cada2015-12-08 15:45:58 -07008434 if ((vni == 0) || (vni>>24)) {
8435 errmsg ("vni not specified or out of range\n");
8436 return -99;
8437 }
8438
8439 M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
Chris Luke99cb3352016-04-26 10:49:53 -04008440
8441 if (ipv6_set) {
Chris Luked686c632016-05-20 12:13:02 -04008442 clib_memcpy(&mp->src_address, &src6, sizeof(src6));
8443 clib_memcpy(&mp->dst_address, &dst6, sizeof(dst6));
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08008444 } else {
Chris Luke99cb3352016-04-26 10:49:53 -04008445 clib_memcpy(&mp->src_address, &src4, sizeof(src4));
8446 clib_memcpy(&mp->dst_address, &dst4, sizeof(dst4));
8447 }
Ed Warnickecb9cada2015-12-08 15:45:58 -07008448 mp->encap_vrf_id = ntohl(encap_vrf_id);
8449 mp->decap_next_index = ntohl(decap_next_index);
8450 mp->vni = ntohl(vni);
8451 mp->is_add = is_add;
Chris Luke99cb3352016-04-26 10:49:53 -04008452 mp->is_ipv6 = ipv6_set;
Ed Warnickecb9cada2015-12-08 15:45:58 -07008453
8454 S; W;
8455 /* NOTREACHED */
8456 return 0;
8457}
8458
Dave Wallace60231f32015-12-17 21:04:30 -05008459static void vl_api_vxlan_tunnel_details_t_handler
8460(vl_api_vxlan_tunnel_details_t * mp)
8461{
8462 vat_main_t * vam = &vat_main;
8463
Chris Luke99cb3352016-04-26 10:49:53 -04008464 fformat(vam->ofp, "%11d%24U%24U%14d%18d%13d\n",
Dave Wallace60231f32015-12-17 21:04:30 -05008465 ntohl(mp->sw_if_index),
Chris Luke99cb3352016-04-26 10:49:53 -04008466 format_ip46_address, &(mp->src_address[0]),
Damjan Marion86be4872016-05-24 23:19:11 +02008467 IP46_TYPE_ANY,
Chris Luke99cb3352016-04-26 10:49:53 -04008468 format_ip46_address, &(mp->dst_address[0]),
Damjan Marion86be4872016-05-24 23:19:11 +02008469 IP46_TYPE_ANY,
Dave Wallace60231f32015-12-17 21:04:30 -05008470 ntohl(mp->encap_vrf_id),
8471 ntohl(mp->decap_next_index),
8472 ntohl(mp->vni));
8473}
8474
8475static void vl_api_vxlan_tunnel_details_t_handler_json
8476(vl_api_vxlan_tunnel_details_t * mp)
8477{
8478 vat_main_t * vam = &vat_main;
8479 vat_json_node_t *node = NULL;
8480 struct in_addr ip4;
Chris Luke99cb3352016-04-26 10:49:53 -04008481 struct in6_addr ip6;
Dave Wallace60231f32015-12-17 21:04:30 -05008482
8483 if (VAT_JSON_ARRAY != vam->json_tree.type) {
8484 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
8485 vat_json_init_array(&vam->json_tree);
8486 }
8487 node = vat_json_array_add(&vam->json_tree);
8488
8489 vat_json_init_object(node);
8490 vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
Chris Luke99cb3352016-04-26 10:49:53 -04008491 if (mp->is_ipv6) {
8492 clib_memcpy(&ip6, &(mp->src_address[0]), sizeof(ip6));
8493 vat_json_object_add_ip6(node, "src_address", ip6);
8494 clib_memcpy(&ip6, &(mp->dst_address[0]), sizeof(ip6));
8495 vat_json_object_add_ip6(node, "dst_address", ip6);
8496 } else {
8497 clib_memcpy(&ip4, &(mp->src_address[0]), sizeof(ip4));
8498 vat_json_object_add_ip4(node, "src_address", ip4);
8499 clib_memcpy(&ip4, &(mp->dst_address[0]), sizeof(ip4));
8500 vat_json_object_add_ip4(node, "dst_address", ip4);
8501 }
Dave Wallace60231f32015-12-17 21:04:30 -05008502 vat_json_object_add_uint(node, "encap_vrf_id", ntohl(mp->encap_vrf_id));
8503 vat_json_object_add_uint(node, "decap_next_index", ntohl(mp->decap_next_index));
8504 vat_json_object_add_uint(node, "vni", ntohl(mp->vni));
Chris Luke99cb3352016-04-26 10:49:53 -04008505 vat_json_object_add_uint(node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
Dave Wallace60231f32015-12-17 21:04:30 -05008506}
8507
8508static int api_vxlan_tunnel_dump (vat_main_t * vam)
8509{
8510 unformat_input_t * i = vam->input;
8511 vl_api_vxlan_tunnel_dump_t *mp;
8512 f64 timeout;
8513 u32 sw_if_index;
8514 u8 sw_if_index_set = 0;
8515
8516 /* Parse args required to build the message */
8517 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8518 if (unformat (i, "sw_if_index %d", &sw_if_index))
8519 sw_if_index_set = 1;
8520 else
8521 break;
8522 }
8523
8524 if (sw_if_index_set == 0) {
8525 sw_if_index = ~0;
8526 }
8527
8528 if (!vam->json_output) {
Chris Luke99cb3352016-04-26 10:49:53 -04008529 fformat(vam->ofp, "%11s%24s%24s%14s%18s%13s\n",
Dave Wallace60231f32015-12-17 21:04:30 -05008530 "sw_if_index", "src_address", "dst_address",
8531 "encap_vrf_id", "decap_next_index", "vni");
8532 }
8533
Chris Luke99cb3352016-04-26 10:49:53 -04008534 /* Get list of vxlan-tunnel interfaces */
Dave Wallace60231f32015-12-17 21:04:30 -05008535 M(VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
8536
8537 mp->sw_if_index = htonl(sw_if_index);
8538
8539 S;
8540
8541 /* Use a control ping for synchronization */
8542 {
8543 vl_api_control_ping_t * mp;
8544 M(CONTROL_PING, control_ping);
8545 S;
8546 }
8547 W;
8548}
8549
Chris Luke27fe48f2016-04-28 13:44:38 -04008550static int api_gre_add_del_tunnel (vat_main_t * vam)
8551{
8552 unformat_input_t * line_input = vam->input;
8553 vl_api_gre_add_del_tunnel_t *mp;
8554 f64 timeout;
8555 ip4_address_t src4, dst4;
8556 u8 is_add = 1;
8557 u8 src_set = 0;
8558 u8 dst_set = 0;
8559 u32 outer_fib_id = 0;
8560
8561 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
8562 if (unformat (line_input, "del"))
8563 is_add = 0;
8564 else if (unformat (line_input, "src %U",
8565 unformat_ip4_address, &src4))
8566 src_set = 1;
8567 else if (unformat (line_input, "dst %U",
8568 unformat_ip4_address, &dst4))
8569 dst_set = 1;
8570 else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
8571 ;
8572 else {
8573 errmsg ("parse error '%U'\n", format_unformat_error, line_input);
8574 return -99;
8575 }
8576 }
8577
8578 if (src_set == 0) {
8579 errmsg ("tunnel src address not specified\n");
8580 return -99;
8581 }
8582 if (dst_set == 0) {
8583 errmsg ("tunnel dst address not specified\n");
8584 return -99;
8585 }
8586
8587
8588 M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
8589
8590 clib_memcpy(&mp->src_address, &src4, sizeof(src4));
8591 clib_memcpy(&mp->dst_address, &dst4, sizeof(dst4));
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08008592 mp->outer_fib_id = ntohl(outer_fib_id);
Chris Luke27fe48f2016-04-28 13:44:38 -04008593 mp->is_add = is_add;
8594
8595 S; W;
8596 /* NOTREACHED */
8597 return 0;
8598}
8599
8600static void vl_api_gre_tunnel_details_t_handler
8601(vl_api_gre_tunnel_details_t * mp)
8602{
8603 vat_main_t * vam = &vat_main;
8604
8605 fformat(vam->ofp, "%11d%15U%15U%14d\n",
8606 ntohl(mp->sw_if_index),
8607 format_ip4_address, &mp->src_address,
8608 format_ip4_address, &mp->dst_address,
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08008609 ntohl(mp->outer_fib_id));
Chris Luke27fe48f2016-04-28 13:44:38 -04008610}
8611
8612static void vl_api_gre_tunnel_details_t_handler_json
8613(vl_api_gre_tunnel_details_t * mp)
8614{
8615 vat_main_t * vam = &vat_main;
8616 vat_json_node_t *node = NULL;
8617 struct in_addr ip4;
8618
8619 if (VAT_JSON_ARRAY != vam->json_tree.type) {
8620 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
8621 vat_json_init_array(&vam->json_tree);
8622 }
8623 node = vat_json_array_add(&vam->json_tree);
8624
8625 vat_json_init_object(node);
8626 vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
8627 clib_memcpy(&ip4, &mp->src_address, sizeof(ip4));
8628 vat_json_object_add_ip4(node, "src_address", ip4);
8629 clib_memcpy(&ip4, &mp->dst_address, sizeof(ip4));
8630 vat_json_object_add_ip4(node, "dst_address", ip4);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08008631 vat_json_object_add_uint(node, "outer_fib_id", ntohl(mp->outer_fib_id));
Chris Luke27fe48f2016-04-28 13:44:38 -04008632}
8633
8634static int api_gre_tunnel_dump (vat_main_t * vam)
8635{
8636 unformat_input_t * i = vam->input;
8637 vl_api_gre_tunnel_dump_t *mp;
8638 f64 timeout;
8639 u32 sw_if_index;
8640 u8 sw_if_index_set = 0;
8641
8642 /* Parse args required to build the message */
8643 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8644 if (unformat (i, "sw_if_index %d", &sw_if_index))
8645 sw_if_index_set = 1;
8646 else
8647 break;
8648 }
8649
8650 if (sw_if_index_set == 0) {
8651 sw_if_index = ~0;
8652 }
8653
8654 if (!vam->json_output) {
8655 fformat(vam->ofp, "%11s%15s%15s%14s\n",
8656 "sw_if_index", "src_address", "dst_address",
8657 "outer_fib_id");
8658 }
8659
8660 /* Get list of gre-tunnel interfaces */
8661 M(GRE_TUNNEL_DUMP, gre_tunnel_dump);
8662
8663 mp->sw_if_index = htonl(sw_if_index);
8664
8665 S;
8666
8667 /* Use a control ping for synchronization */
8668 {
8669 vl_api_control_ping_t * mp;
8670 M(CONTROL_PING, control_ping);
8671 S;
8672 }
8673 W;
8674}
8675
Ed Warnickecb9cada2015-12-08 15:45:58 -07008676static int api_l2_fib_clear_table (vat_main_t * vam)
8677{
8678// unformat_input_t * i = vam->input;
8679 vl_api_l2_fib_clear_table_t *mp;
8680 f64 timeout;
8681
8682 M(L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
8683
8684 S; W;
8685 /* NOTREACHED */
8686 return 0;
8687}
8688
8689static int api_l2_interface_efp_filter (vat_main_t * vam)
8690{
8691 unformat_input_t * i = vam->input;
8692 vl_api_l2_interface_efp_filter_t *mp;
8693 f64 timeout;
8694 u32 sw_if_index;
8695 u8 enable = 1;
8696 u8 sw_if_index_set = 0;
8697
8698 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8699 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8700 sw_if_index_set = 1;
8701 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8702 sw_if_index_set = 1;
8703 else if (unformat (i, "enable"))
8704 enable = 1;
8705 else if (unformat (i, "disable"))
8706 enable = 0;
8707 else {
8708 clib_warning ("parse error '%U'", format_unformat_error, i);
8709 return -99;
8710 }
8711 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08008712
Ed Warnickecb9cada2015-12-08 15:45:58 -07008713 if (sw_if_index_set == 0) {
8714 errmsg ("missing sw_if_index\n");
8715 return -99;
8716 }
8717
8718 M(L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
8719
8720 mp->sw_if_index = ntohl(sw_if_index);
8721 mp->enable_disable = enable;
8722
8723 S; W;
8724 /* NOTREACHED */
8725 return 0;
8726}
8727
8728#define foreach_vtr_op \
8729_("disable", L2_VTR_DISABLED) \
8730_("push-1", L2_VTR_PUSH_1) \
8731_("push-2", L2_VTR_PUSH_2) \
8732_("pop-1", L2_VTR_POP_1) \
8733_("pop-2", L2_VTR_POP_2) \
8734_("translate-1-1", L2_VTR_TRANSLATE_1_1) \
8735_("translate-1-2", L2_VTR_TRANSLATE_1_2) \
8736_("translate-2-1", L2_VTR_TRANSLATE_2_1) \
8737_("translate-2-2", L2_VTR_TRANSLATE_2_2)
8738
8739static int api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
8740{
8741 unformat_input_t * i = vam->input;
8742 vl_api_l2_interface_vlan_tag_rewrite_t *mp;
8743 f64 timeout;
8744 u32 sw_if_index;
8745 u8 sw_if_index_set = 0;
8746 u8 vtr_op_set = 0;
8747 u32 vtr_op = 0;
8748 u32 push_dot1q = 1;
8749 u32 tag1 = ~0;
8750 u32 tag2 = ~0;
8751
8752 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8753 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8754 sw_if_index_set = 1;
8755 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8756 sw_if_index_set = 1;
8757 else if (unformat (i, "vtr_op %d", &vtr_op))
8758 vtr_op_set = 1;
8759#define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
8760 foreach_vtr_op
8761#undef _
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08008762
Ed Warnickecb9cada2015-12-08 15:45:58 -07008763 else if (unformat (i, "push_dot1q %d", &push_dot1q))
8764 ;
8765 else if (unformat (i, "tag1 %d", &tag1))
8766 ;
8767 else if (unformat (i, "tag2 %d", &tag2))
8768 ;
8769 else {
8770 clib_warning ("parse error '%U'", format_unformat_error, i);
8771 return -99;
8772 }
8773 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08008774
Ed Warnickecb9cada2015-12-08 15:45:58 -07008775 if ((sw_if_index_set == 0)||(vtr_op_set == 0)) {
8776 errmsg ("missing vtr operation or sw_if_index\n");
8777 return -99;
8778 }
8779
8780 M(L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
8781
8782 mp->sw_if_index = ntohl(sw_if_index);
8783 mp->vtr_op = ntohl(vtr_op);
8784 mp->push_dot1q = ntohl(push_dot1q);
8785 mp->tag1 = ntohl(tag1);
8786 mp->tag2 = ntohl(tag2);
8787
8788 S; W;
8789 /* NOTREACHED */
8790 return 0;
8791}
8792
8793static int api_create_vhost_user_if (vat_main_t * vam)
8794{
8795 unformat_input_t * i = vam->input;
8796 vl_api_create_vhost_user_if_t *mp;
8797 f64 timeout;
8798 u8 * file_name;
8799 u8 is_server = 0;
8800 u8 file_name_set = 0;
8801 u32 custom_dev_instance = ~0;
Pierre Pfisteref65cb02016-02-19 13:52:44 +00008802 u8 hwaddr[6];
8803 u8 use_custom_mac = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -07008804
8805 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8806 if (unformat (i, "socket %s", &file_name)) {
8807 file_name_set = 1;
8808 }
8809 else if (unformat (i, "renumber %"PRIu32, &custom_dev_instance))
8810 ;
Pierre Pfisteref65cb02016-02-19 13:52:44 +00008811 else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
8812 use_custom_mac = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -07008813 else if (unformat (i, "server"))
8814 is_server = 1;
8815 else
8816 break;
8817 }
8818
8819 if (file_name_set == 0) {
8820 errmsg ("missing socket file name\n");
8821 return -99;
8822 }
8823
8824 if (vec_len (file_name) > 255) {
8825 errmsg ("socket file name too long\n");
8826 return -99;
8827 }
8828 vec_add1 (file_name, 0);
8829
8830 M(CREATE_VHOST_USER_IF, create_vhost_user_if);
8831
8832 mp->is_server = is_server;
Damjan Marionf1213b82016-03-13 02:22:06 +01008833 clib_memcpy(mp->sock_filename, file_name, vec_len(file_name));
Ed Warnickecb9cada2015-12-08 15:45:58 -07008834 vec_free(file_name);
8835 if (custom_dev_instance != ~0) {
8836 mp->renumber = 1;
8837 mp->custom_dev_instance = ntohl(custom_dev_instance);
8838 }
Pierre Pfisteref65cb02016-02-19 13:52:44 +00008839 mp->use_custom_mac = use_custom_mac;
Damjan Marionf1213b82016-03-13 02:22:06 +01008840 clib_memcpy(mp->mac_address, hwaddr, 6);
Ed Warnickecb9cada2015-12-08 15:45:58 -07008841
8842 S; W;
8843 /* NOTREACHED */
8844 return 0;
8845}
8846
8847static int api_modify_vhost_user_if (vat_main_t * vam)
8848{
8849 unformat_input_t * i = vam->input;
8850 vl_api_modify_vhost_user_if_t *mp;
8851 f64 timeout;
8852 u8 * file_name;
8853 u8 is_server = 0;
8854 u8 file_name_set = 0;
8855 u32 custom_dev_instance = ~0;
8856 u8 sw_if_index_set = 0;
8857 u32 sw_if_index = (u32)~0;
8858
8859 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8860 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8861 sw_if_index_set = 1;
8862 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8863 sw_if_index_set = 1;
8864 else if (unformat (i, "socket %s", &file_name)) {
8865 file_name_set = 1;
8866 }
8867 else if (unformat (i, "renumber %"PRIu32, &custom_dev_instance))
8868 ;
8869 else if (unformat (i, "server"))
8870 is_server = 1;
8871 else
8872 break;
8873 }
8874
8875 if (sw_if_index_set == 0) {
8876 errmsg ("missing sw_if_index or interface name\n");
8877 return -99;
8878 }
8879
8880 if (file_name_set == 0) {
8881 errmsg ("missing socket file name\n");
8882 return -99;
8883 }
8884
8885 if (vec_len (file_name) > 255) {
8886 errmsg ("socket file name too long\n");
8887 return -99;
8888 }
8889 vec_add1 (file_name, 0);
8890
8891 M(MODIFY_VHOST_USER_IF, modify_vhost_user_if);
8892
8893 mp->sw_if_index = ntohl(sw_if_index);
8894 mp->is_server = is_server;
Damjan Marionf1213b82016-03-13 02:22:06 +01008895 clib_memcpy(mp->sock_filename, file_name, vec_len(file_name));
Ed Warnickecb9cada2015-12-08 15:45:58 -07008896 vec_free(file_name);
8897 if (custom_dev_instance != ~0) {
8898 mp->renumber = 1;
8899 mp->custom_dev_instance = ntohl(custom_dev_instance);
8900 }
8901
8902 S; W;
8903 /* NOTREACHED */
8904 return 0;
8905}
8906
8907static int api_delete_vhost_user_if (vat_main_t * vam)
8908{
8909 unformat_input_t * i = vam->input;
8910 vl_api_delete_vhost_user_if_t *mp;
8911 f64 timeout;
8912 u32 sw_if_index = ~0;
8913 u8 sw_if_index_set = 0;
8914
8915 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8916 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8917 sw_if_index_set = 1;
8918 else if (unformat (i, "sw_if_index %d", &sw_if_index))
8919 sw_if_index_set = 1;
8920 else
8921 break;
8922 }
8923
8924 if (sw_if_index_set == 0) {
8925 errmsg ("missing sw_if_index or interface name\n");
8926 return -99;
8927 }
8928
8929
8930 M(DELETE_VHOST_USER_IF, delete_vhost_user_if);
8931
8932 mp->sw_if_index = ntohl(sw_if_index);
8933
8934 S; W;
8935 /* NOTREACHED */
8936 return 0;
8937}
8938
8939static void vl_api_sw_interface_vhost_user_details_t_handler
8940(vl_api_sw_interface_vhost_user_details_t * mp)
8941{
8942 vat_main_t * vam = &vat_main;
8943
8944 fformat(vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
8945 (char *)mp->interface_name,
8946 ntohl(mp->sw_if_index), ntohl(mp->virtio_net_hdr_sz),
8947 clib_net_to_host_u64(mp->features), mp->is_server,
8948 ntohl(mp->num_regions), (char *)mp->sock_filename);
8949 fformat(vam->ofp, " Status: '%s'\n", strerror(ntohl(mp->sock_errno)));
8950}
8951
8952static void vl_api_sw_interface_vhost_user_details_t_handler_json
8953(vl_api_sw_interface_vhost_user_details_t * mp)
8954{
8955 vat_main_t * vam = &vat_main;
8956 vat_json_node_t *node = NULL;
8957
8958 if (VAT_JSON_ARRAY != vam->json_tree.type) {
8959 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
8960 vat_json_init_array(&vam->json_tree);
8961 }
8962 node = vat_json_array_add(&vam->json_tree);
8963
8964 vat_json_init_object(node);
8965 vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
8966 vat_json_object_add_string_copy(node, "interface_name", mp->interface_name);
8967 vat_json_object_add_uint(node, "virtio_net_hdr_sz", ntohl(mp->virtio_net_hdr_sz));
8968 vat_json_object_add_uint(node, "features", clib_net_to_host_u64(mp->features));
8969 vat_json_object_add_uint(node, "is_server", mp->is_server);
8970 vat_json_object_add_string_copy(node, "sock_filename", mp->sock_filename);
8971 vat_json_object_add_uint(node, "num_regions", ntohl(mp->num_regions));
8972 vat_json_object_add_uint(node, "sock_errno", ntohl(mp->sock_errno));
8973}
8974
8975static int api_sw_interface_vhost_user_dump (vat_main_t * vam)
8976{
8977 vl_api_sw_interface_vhost_user_dump_t *mp;
8978 f64 timeout;
8979 fformat(vam->ofp, "Interface name idx hdr_sz features server regions filename\n");
8980
8981 /* Get list of vhost-user interfaces */
8982 M(SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
8983 S;
8984
8985 /* Use a control ping for synchronization */
8986 {
8987 vl_api_control_ping_t * mp;
8988 M(CONTROL_PING, control_ping);
8989 S;
8990 }
8991 W;
8992}
8993
8994static int api_show_version (vat_main_t * vam)
8995{
8996 vl_api_show_version_t *mp;
8997 f64 timeout;
8998
8999 M(SHOW_VERSION, show_version);
9000
9001 S; W;
9002 /* NOTREACHED */
9003 return 0;
9004}
9005
Ed Warnickecb9cada2015-12-08 15:45:58 -07009006
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07009007static int api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
Ed Warnickecb9cada2015-12-08 15:45:58 -07009008{
9009 unformat_input_t * line_input = vam->input;
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07009010 vl_api_vxlan_gpe_add_del_tunnel_t *mp;
Ed Warnickecb9cada2015-12-08 15:45:58 -07009011 f64 timeout;
Hongjun Nidf921cc2016-05-25 01:16:19 +08009012 ip4_address_t local4, remote4;
9013 ip6_address_t local6, remote6;
Ed Warnickecb9cada2015-12-08 15:45:58 -07009014 u8 is_add = 1;
Hongjun Nidf921cc2016-05-25 01:16:19 +08009015 u8 ipv4_set = 0, ipv6_set = 0;
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07009016 u8 local_set = 0;
9017 u8 remote_set = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -07009018 u32 encap_vrf_id = 0;
9019 u32 decap_vrf_id = 0;
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07009020 u8 protocol = ~0;
Ed Warnickecb9cada2015-12-08 15:45:58 -07009021 u32 vni;
9022 u8 vni_set = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -07009023
9024 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
9025 if (unformat (line_input, "del"))
9026 is_add = 0;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08009027 else if (unformat (line_input, "local %U",
Hongjun Nidf921cc2016-05-25 01:16:19 +08009028 unformat_ip4_address, &local4))
9029 {
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07009030 local_set = 1;
Hongjun Nidf921cc2016-05-25 01:16:19 +08009031 ipv4_set = 1;
9032 }
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07009033 else if (unformat (line_input, "remote %U",
Hongjun Nidf921cc2016-05-25 01:16:19 +08009034 unformat_ip4_address, &remote4))
9035 {
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07009036 remote_set = 1;
Hongjun Nidf921cc2016-05-25 01:16:19 +08009037 ipv4_set = 1;
9038 }
9039 else if (unformat (line_input, "local %U",
9040 unformat_ip6_address, &local6))
9041 {
9042 local_set = 1;
9043 ipv6_set = 1;
9044 }
9045 else if (unformat (line_input, "remote %U",
9046 unformat_ip6_address, &remote6))
9047 {
9048 remote_set = 1;
9049 ipv6_set = 1;
9050 }
Ed Warnickecb9cada2015-12-08 15:45:58 -07009051 else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
9052 ;
9053 else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
9054 ;
Ed Warnickecb9cada2015-12-08 15:45:58 -07009055 else if (unformat (line_input, "vni %d", &vni))
9056 vni_set = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -07009057 else if (unformat(line_input, "next-ip4"))
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07009058 protocol = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -07009059 else if (unformat(line_input, "next-ip6"))
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07009060 protocol = 2;
Ed Warnickecb9cada2015-12-08 15:45:58 -07009061 else if (unformat(line_input, "next-ethernet"))
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07009062 protocol = 3;
9063 else if (unformat(line_input, "next-nsh"))
9064 protocol = 4;
Ed Warnickecb9cada2015-12-08 15:45:58 -07009065 else {
9066 errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9067 return -99;
9068 }
9069 }
9070
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07009071 if (local_set == 0) {
9072 errmsg ("tunnel local address not specified\n");
Ed Warnickecb9cada2015-12-08 15:45:58 -07009073 return -99;
9074 }
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07009075 if (remote_set == 0) {
9076 errmsg ("tunnel remote address not specified\n");
Ed Warnickecb9cada2015-12-08 15:45:58 -07009077 return -99;
9078 }
Hongjun Nidf921cc2016-05-25 01:16:19 +08009079 if (ipv4_set && ipv6_set) {
9080 errmsg ("both IPv4 and IPv6 addresses specified");
9081 return -99;
9082 }
Ed Warnickecb9cada2015-12-08 15:45:58 -07009083
Ed Warnickecb9cada2015-12-08 15:45:58 -07009084 if (vni_set == 0) {
9085 errmsg ("vni not specified\n");
9086 return -99;
9087 }
9088
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07009089 M(VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08009090
Hongjun Nidf921cc2016-05-25 01:16:19 +08009091
9092 if (ipv6_set) {
9093 clib_memcpy(&mp->local, &local6, sizeof(local6));
9094 clib_memcpy(&mp->remote, &remote6, sizeof(remote6));
9095 } else {
9096 clib_memcpy(&mp->local, &local4, sizeof(local4));
9097 clib_memcpy(&mp->remote, &remote4, sizeof(remote4));
9098 }
9099
Ed Warnickecb9cada2015-12-08 15:45:58 -07009100 mp->encap_vrf_id = ntohl(encap_vrf_id);
9101 mp->decap_vrf_id = ntohl(decap_vrf_id);
Keith Burns (alagalah)94b14422016-05-05 18:16:50 -07009102 mp->protocol = ntohl(protocol);
Ed Warnickecb9cada2015-12-08 15:45:58 -07009103 mp->vni = ntohl(vni);
9104 mp->is_add = is_add;
Hongjun Nidf921cc2016-05-25 01:16:19 +08009105 mp->is_ipv6 = ipv6_set;
Ed Warnickecb9cada2015-12-08 15:45:58 -07009106
9107 S; W;
9108 /* NOTREACHED */
9109 return 0;
9110}
9111
Hongjun Ni0e06e2b2016-05-30 19:45:51 +08009112static void vl_api_vxlan_gpe_tunnel_details_t_handler
9113(vl_api_vxlan_gpe_tunnel_details_t * mp)
9114{
9115 vat_main_t * vam = &vat_main;
9116
9117 fformat(vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
9118 ntohl(mp->sw_if_index),
9119 format_ip46_address, &(mp->local[0]),
9120 format_ip46_address, &(mp->remote[0]),
9121 ntohl(mp->vni),
9122 ntohl(mp->protocol),
9123 ntohl(mp->encap_vrf_id),
9124 ntohl(mp->decap_vrf_id));
9125}
9126
9127static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
9128(vl_api_vxlan_gpe_tunnel_details_t * mp)
9129{
9130 vat_main_t * vam = &vat_main;
9131 vat_json_node_t *node = NULL;
9132 struct in_addr ip4;
9133 struct in6_addr ip6;
9134
9135 if (VAT_JSON_ARRAY != vam->json_tree.type) {
9136 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
9137 vat_json_init_array(&vam->json_tree);
9138 }
9139 node = vat_json_array_add(&vam->json_tree);
9140
9141 vat_json_init_object(node);
9142 vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
9143 if (mp->is_ipv6) {
9144 clib_memcpy(&ip6, &(mp->local[0]), sizeof(ip6));
9145 vat_json_object_add_ip6(node, "local", ip6);
9146 clib_memcpy(&ip6, &(mp->remote[0]), sizeof(ip6));
9147 vat_json_object_add_ip6(node, "remote", ip6);
9148 } else {
9149 clib_memcpy(&ip4, &(mp->local[0]), sizeof(ip4));
9150 vat_json_object_add_ip4(node, "local", ip4);
9151 clib_memcpy(&ip4, &(mp->remote[0]), sizeof(ip4));
9152 vat_json_object_add_ip4(node, "remote", ip4);
9153 }
9154 vat_json_object_add_uint(node, "vni", ntohl(mp->vni));
9155 vat_json_object_add_uint(node, "protocol", ntohl(mp->protocol));
9156 vat_json_object_add_uint(node, "encap_vrf_id", ntohl(mp->encap_vrf_id));
9157 vat_json_object_add_uint(node, "decap_vrf_id", ntohl(mp->decap_vrf_id));
9158 vat_json_object_add_uint(node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
9159}
9160
9161static int api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
9162{
9163 unformat_input_t * i = vam->input;
9164 vl_api_vxlan_gpe_tunnel_dump_t *mp;
9165 f64 timeout;
9166 u32 sw_if_index;
9167 u8 sw_if_index_set = 0;
9168
9169 /* Parse args required to build the message */
9170 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9171 if (unformat (i, "sw_if_index %d", &sw_if_index))
9172 sw_if_index_set = 1;
9173 else
9174 break;
9175 }
9176
9177 if (sw_if_index_set == 0) {
9178 sw_if_index = ~0;
9179 }
9180
9181 if (!vam->json_output) {
9182 fformat(vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
9183 "sw_if_index", "local", "remote", "vni",
9184 "protocol","encap_vrf_id", "decap_vrf_id");
9185 }
9186
9187 /* Get list of vxlan-tunnel interfaces */
9188 M(VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
9189
9190 mp->sw_if_index = htonl(sw_if_index);
9191
9192 S;
9193
9194 /* Use a control ping for synchronization */
9195 {
9196 vl_api_control_ping_t * mp;
9197 M(CONTROL_PING, control_ping);
9198 S;
9199 }
9200 W;
9201}
9202
Ed Warnickecb9cada2015-12-08 15:45:58 -07009203u8 * format_l2_fib_mac_address (u8 * s, va_list * args)
9204{
9205 u8 * a = va_arg (*args, u8 *);
9206
9207 return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
9208 a[2], a[3], a[4], a[5], a[6], a[7]);
9209}
9210
9211static void vl_api_l2_fib_table_entry_t_handler
9212(vl_api_l2_fib_table_entry_t * mp)
9213{
9214 vat_main_t * vam = &vat_main;
9215
9216 fformat(vam->ofp, "%3" PRIu32 " %U %3" PRIu32
9217 " %d %d %d\n",
9218 ntohl(mp->bd_id), format_l2_fib_mac_address, &mp->mac,
9219 ntohl(mp->sw_if_index), mp->static_mac, mp->filter_mac,
9220 mp->bvi_mac);
9221}
9222
9223static void vl_api_l2_fib_table_entry_t_handler_json
9224(vl_api_l2_fib_table_entry_t * mp)
9225{
9226 vat_main_t * vam = &vat_main;
9227 vat_json_node_t *node = NULL;
9228
9229 if (VAT_JSON_ARRAY != vam->json_tree.type) {
9230 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
9231 vat_json_init_array(&vam->json_tree);
9232 }
9233 node = vat_json_array_add(&vam->json_tree);
9234
9235 vat_json_init_object(node);
9236 vat_json_object_add_uint(node, "bd_id", ntohl(mp->bd_id));
9237 vat_json_object_add_uint(node, "mac", clib_net_to_host_u64(mp->mac));
9238 vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
9239 vat_json_object_add_uint(node, "static_mac", mp->static_mac);
9240 vat_json_object_add_uint(node, "filter_mac", mp->filter_mac);
9241 vat_json_object_add_uint(node, "bvi_mac", mp->bvi_mac);
9242}
9243
9244static int api_l2_fib_table_dump (vat_main_t * vam)
9245{
9246 unformat_input_t * i = vam->input;
9247 vl_api_l2_fib_table_dump_t *mp;
9248 f64 timeout;
9249 u32 bd_id;
9250 u8 bd_id_set = 0;
9251
9252 /* Parse args required to build the message */
9253 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9254 if (unformat (i, "bd_id %d", &bd_id))
9255 bd_id_set = 1;
9256 else
9257 break;
9258 }
9259
9260 if (bd_id_set == 0) {
9261 errmsg ("missing bridge domain\n");
9262 return -99;
9263 }
9264
9265 fformat(vam->ofp, "BD-ID Mac Address sw-ndx Static Filter BVI\n");
9266
9267 /* Get list of l2 fib entries */
9268 M(L2_FIB_TABLE_DUMP, l2_fib_table_dump);
9269
9270 mp->bd_id = ntohl(bd_id);
9271 S;
9272
9273 /* Use a control ping for synchronization */
9274 {
9275 vl_api_control_ping_t * mp;
9276 M(CONTROL_PING, control_ping);
9277 S;
9278 }
9279 W;
9280}
9281
9282
9283static int
9284api_interface_name_renumber (vat_main_t * vam)
9285{
9286 unformat_input_t * line_input = vam->input;
9287 vl_api_interface_name_renumber_t *mp;
9288 u32 sw_if_index = ~0;
9289 f64 timeout;
9290 u32 new_show_dev_instance = ~0;
9291
9292 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08009293 if (unformat (line_input, "%U", unformat_sw_if_index, vam,
Ed Warnickecb9cada2015-12-08 15:45:58 -07009294 &sw_if_index))
9295 ;
9296 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
9297 ;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08009298 else if (unformat (line_input, "new_show_dev_instance %d",
Ed Warnickecb9cada2015-12-08 15:45:58 -07009299 &new_show_dev_instance))
9300 ;
9301 else
9302 break;
9303 }
9304
9305 if (sw_if_index == ~0) {
9306 errmsg ("missing interface name or sw_if_index\n");
9307 return -99;
9308 }
9309
9310 if (new_show_dev_instance == ~0) {
9311 errmsg ("missing new_show_dev_instance\n");
9312 return -99;
9313 }
9314
9315 M(INTERFACE_NAME_RENUMBER, interface_name_renumber);
9316
9317 mp->sw_if_index = ntohl (sw_if_index);
9318 mp->new_show_dev_instance = ntohl (new_show_dev_instance);
9319
9320 S; W;
9321}
9322
9323static int
9324api_want_ip4_arp_events (vat_main_t * vam)
9325{
9326 unformat_input_t * line_input = vam->input;
9327 vl_api_want_ip4_arp_events_t * mp;
9328 f64 timeout;
9329 ip4_address_t address;
9330 int address_set = 0;
9331 u32 enable_disable = 1;
9332
9333 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08009334 if (unformat (line_input, "address %U",
Ed Warnickecb9cada2015-12-08 15:45:58 -07009335 unformat_ip4_address, &address))
9336 address_set = 1;
9337 else if (unformat (line_input, "del"))
9338 enable_disable = 0;
9339 else
9340 break;
9341 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08009342
Ed Warnickecb9cada2015-12-08 15:45:58 -07009343 if (address_set == 0) {
9344 errmsg ("missing addresses\n");
9345 return -99;
9346 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08009347
Ed Warnickecb9cada2015-12-08 15:45:58 -07009348 M(WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
9349 mp->enable_disable = enable_disable;
9350 mp->pid = getpid();
9351 mp->address = address.as_u32;
9352
Hongjun Ni11bfc2f2016-07-22 18:19:19 +08009353 S; W;
Ed Warnickecb9cada2015-12-08 15:45:58 -07009354}
9355
9356static int api_input_acl_set_interface (vat_main_t * vam)
9357{
9358 unformat_input_t * i = vam->input;
9359 vl_api_input_acl_set_interface_t *mp;
9360 f64 timeout;
9361 u32 sw_if_index;
9362 int sw_if_index_set;
9363 u32 ip4_table_index = ~0;
9364 u32 ip6_table_index = ~0;
9365 u32 l2_table_index = ~0;
9366 u8 is_add = 1;
9367
9368 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9369 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9370 sw_if_index_set = 1;
9371 else if (unformat (i, "sw_if_index %d", &sw_if_index))
9372 sw_if_index_set = 1;
9373 else if (unformat (i, "del"))
9374 is_add = 0;
9375 else if (unformat (i, "ip4-table %d", &ip4_table_index))
9376 ;
9377 else if (unformat (i, "ip6-table %d", &ip6_table_index))
9378 ;
9379 else if (unformat (i, "l2-table %d", &l2_table_index))
9380 ;
9381 else {
9382 clib_warning ("parse error '%U'", format_unformat_error, i);
9383 return -99;
9384 }
9385 }
9386
9387 if (sw_if_index_set == 0) {
9388 errmsg ("missing interface name or sw_if_index\n");
9389 return -99;
9390 }
9391
9392 M(INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
9393
9394 mp->sw_if_index = ntohl(sw_if_index);
9395 mp->ip4_table_index = ntohl(ip4_table_index);
9396 mp->ip6_table_index = ntohl(ip6_table_index);
9397 mp->l2_table_index = ntohl(l2_table_index);
9398 mp->is_add = is_add;
9399
9400 S; W;
9401 /* NOTREACHED */
9402 return 0;
9403}
9404
9405static int
9406api_ip_address_dump (vat_main_t * vam)
9407{
9408 unformat_input_t * i = vam->input;
9409 vl_api_ip_address_dump_t * mp;
9410 u32 sw_if_index = ~0;
9411 u8 sw_if_index_set = 0;
9412 u8 ipv4_set = 0;
9413 u8 ipv6_set = 0;
9414 f64 timeout;
9415
9416 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9417 if (unformat (i, "sw_if_index %d", &sw_if_index))
9418 sw_if_index_set = 1;
9419 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9420 sw_if_index_set = 1;
9421 else if (unformat (i, "ipv4"))
9422 ipv4_set = 1;
9423 else if (unformat (i, "ipv6"))
9424 ipv6_set = 1;
9425 else
9426 break;
9427 }
9428
9429 if (ipv4_set && ipv6_set) {
9430 errmsg ("ipv4 and ipv6 flags cannot be both set\n");
9431 return -99;
9432 }
9433
9434 if ((!ipv4_set) && (!ipv6_set)) {
9435 errmsg ("no ipv4 nor ipv6 flag set\n");
9436 return -99;
9437 }
9438
9439 if (sw_if_index_set == 0) {
9440 errmsg ("missing interface name or sw_if_index\n");
9441 return -99;
9442 }
9443
9444 vam->current_sw_if_index = sw_if_index;
9445 vam->is_ipv6 = ipv6_set;
9446
9447 M(IP_ADDRESS_DUMP, ip_address_dump);
9448 mp->sw_if_index = ntohl(sw_if_index);
9449 mp->is_ipv6 = ipv6_set;
9450 S;
9451
9452 /* Use a control ping for synchronization */
9453 {
9454 vl_api_control_ping_t * mp;
9455 M(CONTROL_PING, control_ping);
9456 S;
9457 }
9458 W;
9459}
9460
9461static int
9462api_ip_dump (vat_main_t * vam)
9463{
9464 vl_api_ip_dump_t * mp;
9465 unformat_input_t * in = vam->input;
9466 int ipv4_set = 0;
9467 int ipv6_set = 0;
9468 int is_ipv6;
9469 f64 timeout;
9470 int i;
9471
9472 while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT) {
9473 if (unformat (in, "ipv4"))
9474 ipv4_set = 1;
9475 else if (unformat (in, "ipv6"))
9476 ipv6_set = 1;
9477 else
9478 break;
9479 }
9480
9481 if (ipv4_set && ipv6_set) {
9482 errmsg ("ipv4 and ipv6 flags cannot be both set\n");
9483 return -99;
9484 }
9485
9486 if ((!ipv4_set) && (!ipv6_set)) {
9487 errmsg ("no ipv4 nor ipv6 flag set\n");
9488 return -99;
9489 }
9490
9491 is_ipv6 = ipv6_set;
9492 vam->is_ipv6 = is_ipv6;
9493
9494 /* free old data */
9495 for (i = 0; i < vec_len(vam->ip_details_by_sw_if_index[is_ipv6]); i++) {
9496 vec_free(vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
9497 }
9498 vec_free(vam->ip_details_by_sw_if_index[is_ipv6]);
9499
9500 M(IP_DUMP, ip_dump);
9501 mp->is_ipv6 = ipv6_set;
9502 S;
9503
9504 /* Use a control ping for synchronization */
9505 {
9506 vl_api_control_ping_t * mp;
9507 M(CONTROL_PING, control_ping);
9508 S;
9509 }
9510 W;
9511}
9512
9513static int
9514api_ipsec_spd_add_del (vat_main_t * vam)
9515{
Dave Barachbfdedbd2016-01-20 09:11:55 -05009516#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -07009517 unformat_input_t * i = vam->input;
9518 vl_api_ipsec_spd_add_del_t *mp;
9519 f64 timeout;
9520 u32 spd_id = ~0;
9521 u8 is_add = 1;
9522
9523 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9524 if (unformat (i, "spd_id %d", &spd_id))
9525 ;
9526 else if (unformat (i, "del"))
9527 is_add = 0;
9528 else {
9529 clib_warning ("parse error '%U'", format_unformat_error, i);
9530 return -99;
9531 }
9532 }
9533 if (spd_id == ~0) {
9534 errmsg ("spd_id must be set\n");
9535 return -99;
9536 }
9537
9538 M(IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
9539
9540 mp->spd_id = ntohl(spd_id);
9541 mp->is_add = is_add;
9542
9543 S; W;
9544 /* NOTREACHED */
9545 return 0;
Dave Barachbfdedbd2016-01-20 09:11:55 -05009546#else
9547 clib_warning ("unsupported (no dpdk)");
9548 return -99;
9549#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -07009550}
9551
9552static int
9553api_ipsec_interface_add_del_spd (vat_main_t * vam)
9554{
Dave Barachbfdedbd2016-01-20 09:11:55 -05009555#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -07009556 unformat_input_t * i = vam->input;
9557 vl_api_ipsec_interface_add_del_spd_t *mp;
9558 f64 timeout;
9559 u32 sw_if_index;
9560 u8 sw_if_index_set = 0;
9561 u32 spd_id = (u32) ~0;
9562 u8 is_add = 1;
9563
9564 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9565 if (unformat (i, "del"))
9566 is_add = 0;
9567 else if (unformat (i, "spd_id %d", &spd_id))
9568 ;
9569 else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9570 sw_if_index_set = 1;
9571 else if (unformat (i, "sw_if_index %d", &sw_if_index))
9572 sw_if_index_set = 1;
9573 else {
9574 clib_warning ("parse error '%U'", format_unformat_error, i);
9575 return -99;
9576 }
9577
9578 }
9579
9580 if (spd_id == (u32) ~0) {
9581 errmsg ("spd_id must be set\n");
9582 return -99;
9583 }
9584
9585 if (sw_if_index_set == 0) {
9586 errmsg ("missing interface name or sw_if_index\n");
9587 return -99;
9588 }
9589
9590 M(IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
9591
9592 mp->spd_id = ntohl(spd_id);
9593 mp->sw_if_index = ntohl (sw_if_index);
9594 mp->is_add = is_add;
9595
9596 S; W;
9597 /* NOTREACHED */
9598 return 0;
Dave Barachbfdedbd2016-01-20 09:11:55 -05009599#else
9600 clib_warning ("unsupported (no dpdk)");
9601 return -99;
9602#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -07009603}
9604
9605static int
9606api_ipsec_spd_add_del_entry (vat_main_t * vam)
9607{
Dave Barachbfdedbd2016-01-20 09:11:55 -05009608#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -07009609 unformat_input_t * i = vam->input;
9610 vl_api_ipsec_spd_add_del_entry_t *mp;
9611 f64 timeout;
9612 u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
9613 u32 spd_id, sa_id, protocol = 0, policy = 0;
9614 i32 priority;
9615 u32 rport_start = 0, rport_stop = (u32) ~0;
9616 u32 lport_start = 0, lport_stop = (u32) ~0;
9617 ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
9618 ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
9619
9620 laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
9621 laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~0;
9622 laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
9623 laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
9624 laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~0;
9625 laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~0;
9626
9627 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9628 if (unformat (i, "del"))
9629 is_add = 0;
9630 if (unformat (i, "outbound"))
9631 is_outbound = 1;
9632 if (unformat (i, "inbound"))
9633 is_outbound = 0;
9634 else if (unformat (i, "spd_id %d", &spd_id))
9635 ;
9636 else if (unformat (i, "sa_id %d", &sa_id))
9637 ;
9638 else if (unformat (i, "priority %d", &priority))
9639 ;
9640 else if (unformat (i, "protocol %d", &protocol))
9641 ;
9642 else if (unformat (i, "lport_start %d", &lport_start))
9643 ;
9644 else if (unformat (i, "lport_stop %d", &lport_stop))
9645 ;
9646 else if (unformat (i, "rport_start %d", &rport_start))
9647 ;
9648 else if (unformat (i, "rport_stop %d", &rport_stop))
9649 ;
9650 else if (unformat (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
9651 {
9652 is_ipv6 = 0;
9653 is_ip_any =0;
9654 }
9655 else if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
9656 {
9657 is_ipv6 = 0;
9658 is_ip_any = 0;
9659 }
9660 else if (unformat (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
9661 {
9662 is_ipv6 = 0;
9663 is_ip_any = 0;
9664 }
9665 else if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
9666 {
9667 is_ipv6 = 0;
9668 is_ip_any = 0;
9669 }
9670 else if (unformat (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
9671 {
9672 is_ipv6 = 1;
9673 is_ip_any = 0;
9674 }
9675 else if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
9676 {
9677 is_ipv6 = 1;
9678 is_ip_any = 0;
9679 }
9680 else if (unformat (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
9681 {
9682 is_ipv6 = 1;
9683 is_ip_any = 0;
9684 }
9685 else if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
9686 {
9687 is_ipv6 = 1;
9688 is_ip_any = 0;
9689 }
9690 else if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
9691 {
9692 if (policy == IPSEC_POLICY_ACTION_RESOLVE) {
9693 clib_warning ("unsupported action: 'resolve'");
9694 return -99;
9695 }
9696 }
9697 else {
9698 clib_warning ("parse error '%U'", format_unformat_error, i);
9699 return -99;
9700 }
9701
9702 }
9703
9704 M(IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
9705
9706 mp->spd_id = ntohl(spd_id);
9707 mp->priority = ntohl(priority);
9708 mp->is_outbound = is_outbound;
9709
9710 mp->is_ipv6 = is_ipv6;
9711 if (is_ipv6 || is_ip_any) {
Damjan Marionf1213b82016-03-13 02:22:06 +01009712 clib_memcpy (mp->remote_address_start, &raddr6_start, sizeof(ip6_address_t));
9713 clib_memcpy (mp->remote_address_stop, &raddr6_stop, sizeof(ip6_address_t));
9714 clib_memcpy (mp->local_address_start, &laddr6_start, sizeof(ip6_address_t));
9715 clib_memcpy (mp->local_address_stop, &laddr6_stop, sizeof(ip6_address_t));
Ed Warnickecb9cada2015-12-08 15:45:58 -07009716 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01009717 clib_memcpy (mp->remote_address_start, &raddr4_start, sizeof(ip4_address_t));
9718 clib_memcpy (mp->remote_address_stop, &raddr4_stop, sizeof(ip4_address_t));
9719 clib_memcpy (mp->local_address_start, &laddr4_start, sizeof(ip4_address_t));
9720 clib_memcpy (mp->local_address_stop, &laddr4_stop, sizeof(ip4_address_t));
Ed Warnickecb9cada2015-12-08 15:45:58 -07009721 }
9722 mp->protocol = (u8) protocol;
9723 mp->local_port_start = ntohs((u16) lport_start);
9724 mp->local_port_stop = ntohs((u16) lport_stop);
9725 mp->remote_port_start = ntohs((u16) rport_start);
9726 mp->remote_port_stop = ntohs((u16) rport_stop);
9727 mp->policy = (u8) policy;
9728 mp->sa_id = ntohl(sa_id);
9729 mp->is_add = is_add;
9730 mp->is_ip_any = is_ip_any;
9731 S; W;
9732 /* NOTREACHED */
9733 return 0;
Dave Barachbfdedbd2016-01-20 09:11:55 -05009734#else
9735 clib_warning ("unsupported (no dpdk)");
9736 return -99;
9737#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -07009738}
9739
9740static int
9741api_ipsec_sad_add_del_entry (vat_main_t * vam)
9742{
Dave Barachbfdedbd2016-01-20 09:11:55 -05009743#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -07009744 unformat_input_t * i = vam->input;
9745 vl_api_ipsec_sad_add_del_entry_t *mp;
9746 f64 timeout;
9747 u32 sad_id, spi;
Matus Fabian683d3ee2016-07-26 23:54:07 -07009748 u8 * ck = 0, * ik = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -07009749 u8 is_add = 1;
9750
9751 u8 protocol = IPSEC_PROTOCOL_AH;
9752 u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
9753 u32 crypto_alg = 0, integ_alg = 0;
9754 ip4_address_t tun_src4;
9755 ip4_address_t tun_dst4;
9756 ip6_address_t tun_src6;
9757 ip6_address_t tun_dst6;
9758
9759 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9760 if (unformat (i, "del"))
9761 is_add = 0;
9762 else if (unformat (i, "sad_id %d", &sad_id))
9763 ;
9764 else if (unformat (i, "spi %d", &spi))
9765 ;
9766 else if (unformat (i, "esp"))
9767 protocol = IPSEC_PROTOCOL_ESP;
9768 else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4)) {
9769 is_tunnel = 1;
9770 is_tunnel_ipv6 = 0;
9771 }
9772 else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4)) {
9773 is_tunnel = 1;
9774 is_tunnel_ipv6 = 0;
9775 }
9776 else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6)) {
9777 is_tunnel = 1;
9778 is_tunnel_ipv6 = 1;
9779 }
9780 else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6)) {
9781 is_tunnel = 1;
9782 is_tunnel_ipv6 = 1;
9783 }
9784 else if (unformat (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg)) {
9785 if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
9786 crypto_alg > IPSEC_INTEG_ALG_SHA_512_256) {
9787 clib_warning ("unsupported crypto-alg: '%U'",
9788 format_ipsec_crypto_alg, crypto_alg);
9789 return -99;
9790 }
9791 }
9792 else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
9793 ;
9794 else if (unformat (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg)) {
9795 if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
9796 integ_alg > IPSEC_INTEG_ALG_SHA_512_256) {
9797 clib_warning ("unsupported integ-alg: '%U'",
9798 format_ipsec_integ_alg, integ_alg);
9799 return -99;
9800 }
9801 }
9802 else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
9803 ;
9804 else {
9805 clib_warning ("parse error '%U'", format_unformat_error, i);
9806 return -99;
9807 }
9808
9809 }
9810
9811 M(IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
9812
9813 mp->sad_id = ntohl(sad_id);
9814 mp->is_add = is_add;
9815 mp->protocol = protocol;
9816 mp->spi = ntohl(spi);
9817 mp->is_tunnel = is_tunnel;
9818 mp->is_tunnel_ipv6 = is_tunnel_ipv6;
9819 mp->crypto_algorithm = crypto_alg;
9820 mp->integrity_algorithm = integ_alg;
9821 mp->crypto_key_length = vec_len(ck);
9822 mp->integrity_key_length = vec_len(ik);
9823
9824 if (mp->crypto_key_length > sizeof(mp->crypto_key))
9825 mp->crypto_key_length = sizeof(mp->crypto_key);
9826
9827 if (mp->integrity_key_length > sizeof(mp->integrity_key))
9828 mp->integrity_key_length = sizeof(mp->integrity_key);
9829
Damjan Marionf1213b82016-03-13 02:22:06 +01009830 clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
9831 clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
Ed Warnickecb9cada2015-12-08 15:45:58 -07009832
9833 if (is_tunnel) {
9834 if (is_tunnel_ipv6) {
Damjan Marionf1213b82016-03-13 02:22:06 +01009835 clib_memcpy (mp->tunnel_src_address, &tun_src6, sizeof(ip6_address_t));
9836 clib_memcpy (mp->tunnel_dst_address, &tun_dst6, sizeof(ip6_address_t));
Ed Warnickecb9cada2015-12-08 15:45:58 -07009837 } else {
Damjan Marionf1213b82016-03-13 02:22:06 +01009838 clib_memcpy (mp->tunnel_src_address, &tun_src4, sizeof(ip4_address_t));
9839 clib_memcpy (mp->tunnel_dst_address, &tun_dst4, sizeof(ip4_address_t));
Ed Warnickecb9cada2015-12-08 15:45:58 -07009840 }
9841 }
9842
9843 S; W;
9844 /* NOTREACHED */
9845 return 0;
Dave Barachbfdedbd2016-01-20 09:11:55 -05009846#else
9847 clib_warning ("unsupported (no dpdk)");
9848 return -99;
9849#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -07009850}
9851
9852static int
9853api_ipsec_sa_set_key (vat_main_t * vam)
9854{
Dave Barachbfdedbd2016-01-20 09:11:55 -05009855#if DPDK > 0
Ed Warnickecb9cada2015-12-08 15:45:58 -07009856 unformat_input_t * i = vam->input;
9857 vl_api_ipsec_sa_set_key_t *mp;
9858 f64 timeout;
9859 u32 sa_id;
Matus Fabian683d3ee2016-07-26 23:54:07 -07009860 u8 * ck = 0, * ik = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -07009861
9862 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9863 if (unformat (i, "sa_id %d", &sa_id))
9864 ;
9865 else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
9866 ;
9867 else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
9868 ;
9869 else {
9870 clib_warning ("parse error '%U'", format_unformat_error, i);
9871 return -99;
9872 }
9873 }
9874
9875 M(IPSEC_SA_SET_KEY, ipsec_set_sa_key);
9876
9877 mp->sa_id = ntohl(sa_id);
9878 mp->crypto_key_length = vec_len(ck);
9879 mp->integrity_key_length = vec_len(ik);
9880
9881 if (mp->crypto_key_length > sizeof(mp->crypto_key))
9882 mp->crypto_key_length = sizeof(mp->crypto_key);
9883
9884 if (mp->integrity_key_length > sizeof(mp->integrity_key))
9885 mp->integrity_key_length = sizeof(mp->integrity_key);
9886
Damjan Marionf1213b82016-03-13 02:22:06 +01009887 clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
9888 clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
Ed Warnickecb9cada2015-12-08 15:45:58 -07009889
9890 S; W;
9891 /* NOTREACHED */
9892 return 0;
Dave Barachbfdedbd2016-01-20 09:11:55 -05009893#else
9894 clib_warning ("unsupported (no dpdk)");
9895 return -99;
9896#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -07009897}
9898
Matus Fabiane5f42fe2016-04-08 11:18:08 +02009899static int
9900api_ikev2_profile_add_del (vat_main_t * vam)
9901{
9902#if DPDK > 0
9903 unformat_input_t * i = vam->input;
9904 vl_api_ikev2_profile_add_del_t * mp;
9905 f64 timeout;
9906 u8 is_add = 1;
9907 u8 * name = 0;
9908
9909 const char * valid_chars = "a-zA-Z0-9_";
9910
9911 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9912 if (unformat (i, "del"))
9913 is_add = 0;
9914 else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
9915 vec_add1 (name, 0);
9916 else {
9917 errmsg ("parse error '%U'", format_unformat_error, i);
9918 return -99;
9919 }
9920 }
9921
9922 if (!vec_len (name)) {
9923 errmsg ("profile name must be specified");
9924 return -99;
9925 }
9926
9927 if (vec_len (name) > 64) {
9928 errmsg ("profile name too long");
9929 return -99;
9930 }
9931
9932 M(IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
9933
Damjan Marionf1213b82016-03-13 02:22:06 +01009934 clib_memcpy(mp->name, name, vec_len (name));
Matus Fabiane5f42fe2016-04-08 11:18:08 +02009935 mp->is_add = is_add;
9936 vec_free (name);
9937
9938 S; W;
9939 /* NOTREACHED */
9940 return 0;
9941#else
9942 clib_warning ("unsupported (no dpdk)");
9943 return -99;
9944#endif
9945}
9946
9947static int
9948api_ikev2_profile_set_auth (vat_main_t * vam)
9949{
9950#if DPDK > 0
9951 unformat_input_t * i = vam->input;
9952 vl_api_ikev2_profile_set_auth_t * mp;
9953 f64 timeout;
9954 u8 * name = 0;
9955 u8 * data = 0;
9956 u32 auth_method = 0;
9957 u8 is_hex = 0;
9958
9959 const char * valid_chars = "a-zA-Z0-9_";
9960
9961 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9962 if (unformat (i, "name %U", unformat_token, valid_chars, &name))
9963 vec_add1 (name, 0);
9964 else if (unformat (i, "auth_method %U",
9965 unformat_ikev2_auth_method, &auth_method))
9966 ;
9967 else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
9968 is_hex = 1;
9969 else if (unformat (i, "auth_data %v", &data))
9970 ;
9971 else {
9972 errmsg ("parse error '%U'", format_unformat_error, i);
9973 return -99;
9974 }
9975 }
9976
9977 if (!vec_len (name)) {
9978 errmsg ("profile name must be specified");
9979 return -99;
9980 }
9981
9982 if (vec_len (name) > 64) {
9983 errmsg ("profile name too long");
9984 return -99;
9985 }
9986
9987 if (!vec_len(data)) {
9988 errmsg ("auth_data must be specified");
9989 return -99;
9990 }
9991
9992 if (!auth_method) {
9993 errmsg ("auth_method must be specified");
9994 return -99;
9995 }
9996
9997 M(IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
9998
9999 mp->is_hex = is_hex;
10000 mp->auth_method = (u8) auth_method;
10001 mp->data_len = vec_len (data);
Damjan Marionf1213b82016-03-13 02:22:06 +010010002 clib_memcpy (mp->name, name, vec_len (name));
10003 clib_memcpy (mp->data, data, vec_len (data));
Matus Fabiane5f42fe2016-04-08 11:18:08 +020010004 vec_free (name);
10005 vec_free (data);
10006
10007 S; W;
10008 /* NOTREACHED */
10009 return 0;
10010#else
10011 clib_warning ("unsupported (no dpdk)");
10012 return -99;
10013#endif
10014}
10015
10016static int
10017api_ikev2_profile_set_id (vat_main_t * vam)
10018{
10019#if DPDK > 0
10020 unformat_input_t * i = vam->input;
10021 vl_api_ikev2_profile_set_id_t * mp;
10022 f64 timeout;
10023 u8 * name = 0;
10024 u8 * data = 0;
10025 u8 is_local = 0;
10026 u32 id_type = 0;
10027 ip4_address_t ip4;
10028
10029 const char * valid_chars = "a-zA-Z0-9_";
10030
10031 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
10032 if (unformat (i, "name %U", unformat_token, valid_chars, &name))
10033 vec_add1 (name, 0);
10034 else if (unformat (i, "id_type %U",
10035 unformat_ikev2_id_type, &id_type))
10036 ;
10037 else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
10038 {
10039 data = vec_new(u8, 4);
Damjan Marionf1213b82016-03-13 02:22:06 +010010040 clib_memcpy(data, ip4.as_u8, 4);
Matus Fabiane5f42fe2016-04-08 11:18:08 +020010041 }
10042 else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
10043 ;
10044 else if (unformat (i, "id_data %v", &data))
10045 ;
10046 else if (unformat (i, "local"))
10047 is_local = 1;
10048 else if (unformat (i, "remote"))
10049 is_local = 0;
10050 else {
10051 errmsg ("parse error '%U'", format_unformat_error, i);
10052 return -99;
10053 }
10054 }
10055
10056 if (!vec_len (name)) {
10057 errmsg ("profile name must be specified");
10058 return -99;
10059 }
10060
10061 if (vec_len (name) > 64) {
10062 errmsg ("profile name too long");
10063 return -99;
10064 }
10065
10066 if (!vec_len(data)) {
10067 errmsg ("id_data must be specified");
10068 return -99;
10069 }
10070
10071 if (!id_type) {
10072 errmsg ("id_type must be specified");
10073 return -99;
10074 }
10075
10076 M(IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
10077
10078 mp->is_local = is_local;
10079 mp->id_type = (u8) id_type;
10080 mp->data_len = vec_len (data);
Damjan Marionf1213b82016-03-13 02:22:06 +010010081 clib_memcpy (mp->name, name, vec_len (name));
10082 clib_memcpy (mp->data, data, vec_len (data));
Matus Fabiane5f42fe2016-04-08 11:18:08 +020010083 vec_free (name);
10084 vec_free (data);
10085
10086 S; W;
10087 /* NOTREACHED */
10088 return 0;
10089#else
10090 clib_warning ("unsupported (no dpdk)");
10091 return -99;
10092#endif
10093}
10094
10095static int
10096api_ikev2_profile_set_ts (vat_main_t * vam)
10097{
10098#if DPDK > 0
10099 unformat_input_t * i = vam->input;
10100 vl_api_ikev2_profile_set_ts_t * mp;
10101 f64 timeout;
10102 u8 * name = 0;
10103 u8 is_local = 0;
10104 u32 proto = 0, start_port = 0, end_port = (u32) ~0;
10105 ip4_address_t start_addr, end_addr;
10106
10107 const char * valid_chars = "a-zA-Z0-9_";
10108
10109 start_addr.as_u32 = 0;
10110 end_addr.as_u32 = (u32) ~0;
10111
10112 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
10113 if (unformat (i, "name %U", unformat_token, valid_chars, &name))
10114 vec_add1 (name, 0);
10115 else if (unformat (i, "protocol %d", &proto))
10116 ;
10117 else if (unformat (i, "start_port %d", &start_port))
10118 ;
10119 else if (unformat (i, "end_port %d", &end_port))
10120 ;
10121 else if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
10122 ;
10123 else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
10124 ;
10125 else if (unformat (i, "local"))
10126 is_local = 1;
10127 else if (unformat (i, "remote"))
10128 is_local = 0;
10129 else {
10130 errmsg ("parse error '%U'", format_unformat_error, i);
10131 return -99;
10132 }
10133 }
10134
10135 if (!vec_len (name)) {
10136 errmsg ("profile name must be specified");
10137 return -99;
10138 }
10139
10140 if (vec_len (name) > 64) {
10141 errmsg ("profile name too long");
10142 return -99;
10143 }
10144
10145 M(IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
10146
10147 mp->is_local = is_local;
10148 mp->proto = (u8) proto;
10149 mp->start_port = (u16) start_port;
10150 mp->end_port = (u16) end_port;
10151 mp->start_addr = start_addr.as_u32;
10152 mp->end_addr = end_addr.as_u32;
Damjan Marionf1213b82016-03-13 02:22:06 +010010153 clib_memcpy (mp->name, name, vec_len (name));
Matus Fabiane5f42fe2016-04-08 11:18:08 +020010154 vec_free (name);
10155
10156 S; W;
10157 /* NOTREACHED */
10158 return 0;
10159#else
10160 clib_warning ("unsupported (no dpdk)");
10161 return -99;
10162#endif
10163}
10164
10165static int
10166api_ikev2_set_local_key (vat_main_t * vam)
10167{
10168#if DPDK > 0
10169 unformat_input_t * i = vam->input;
10170 vl_api_ikev2_set_local_key_t * mp;
10171 f64 timeout;
10172 u8 * file = 0;
10173
10174 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
10175 if (unformat (i, "file %v", &file))
10176 vec_add1 (file, 0);
10177 else {
10178 errmsg ("parse error '%U'", format_unformat_error, i);
10179 return -99;
10180 }
10181 }
10182
10183 if (!vec_len (file)) {
10184 errmsg ("RSA key file must be specified");
10185 return -99;
10186 }
10187
10188 if (vec_len (file) > 256) {
10189 errmsg ("file name too long");
10190 return -99;
10191 }
10192
10193 M(IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
10194
Damjan Marionf1213b82016-03-13 02:22:06 +010010195 clib_memcpy (mp->key_file, file, vec_len (file));
Matus Fabiane5f42fe2016-04-08 11:18:08 +020010196 vec_free (file);
10197
10198 S; W;
10199 /* NOTREACHED */
10200 return 0;
10201#else
10202 clib_warning ("unsupported (no dpdk)");
10203 return -99;
10204#endif
10205}
10206
Ed Warnickecb9cada2015-12-08 15:45:58 -070010207/*
10208 * MAP
10209 */
10210static int api_map_add_domain (vat_main_t * vam)
10211{
10212 unformat_input_t *i = vam->input;
10213 vl_api_map_add_domain_t *mp;
10214 f64 timeout;
10215
10216 ip4_address_t ip4_prefix;
10217 ip6_address_t ip6_prefix;
10218 ip6_address_t ip6_src;
10219 u32 num_m_args = 0;
10220 u32 ip6_prefix_len, ip4_prefix_len, ea_bits_len, psid_offset,
10221 psid_length;
10222 u8 is_translation = 0;
10223 u32 mtu = 0;
10224 u8 ip6_src_len = 128;
10225
10226 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
10227 if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
10228 &ip4_prefix, &ip4_prefix_len))
10229 num_m_args++;
10230 else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
10231 &ip6_prefix, &ip6_prefix_len))
10232 num_m_args++;
10233 else if (unformat (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src, &ip6_src_len))
10234 num_m_args++;
10235 else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
10236 num_m_args++;
10237 else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
10238 num_m_args++;
10239 else if (unformat (i, "psid-offset %d", &psid_offset))
10240 num_m_args++;
10241 else if (unformat (i, "psid-len %d", &psid_length))
10242 num_m_args++;
10243 else if (unformat (i, "mtu %d", &mtu))
10244 num_m_args++;
10245 else if (unformat (i, "map-t"))
10246 is_translation = 1;
10247 else {
10248 clib_warning ("parse error '%U'", format_unformat_error, i);
10249 return -99;
10250 }
10251 }
10252
10253 if (num_m_args != 6) {
10254 errmsg("mandatory argument(s) missing\n");
10255 return -99;
10256 }
10257
10258 /* Construct the API message */
10259 M(MAP_ADD_DOMAIN, map_add_domain);
10260
Damjan Marionf1213b82016-03-13 02:22:06 +010010261 clib_memcpy(mp->ip4_prefix, &ip4_prefix, sizeof(ip4_prefix));
Ed Warnickecb9cada2015-12-08 15:45:58 -070010262 mp->ip4_prefix_len = ip4_prefix_len;
10263
Damjan Marionf1213b82016-03-13 02:22:06 +010010264 clib_memcpy(mp->ip6_prefix, &ip6_prefix, sizeof(ip6_prefix));
Ed Warnickecb9cada2015-12-08 15:45:58 -070010265 mp->ip6_prefix_len = ip6_prefix_len;
10266
Damjan Marionf1213b82016-03-13 02:22:06 +010010267 clib_memcpy(mp->ip6_src, &ip6_src, sizeof(ip6_src));
Ed Warnickecb9cada2015-12-08 15:45:58 -070010268 mp->ip6_src_prefix_len = ip6_src_len;
10269
10270 mp->ea_bits_len = ea_bits_len;
10271 mp->psid_offset = psid_offset;
10272 mp->psid_length = psid_length;
10273 mp->is_translation = is_translation;
10274 mp->mtu = htons(mtu);
10275
10276 /* send it... */
10277 S;
10278
10279 /* Wait for a reply, return good/bad news */
10280 W;
10281}
10282
10283static int api_map_del_domain (vat_main_t * vam)
10284{
10285 unformat_input_t *i = vam->input;
10286 vl_api_map_del_domain_t *mp;
10287 f64 timeout;
10288
10289 u32 num_m_args = 0;
10290 u32 index;
10291
10292 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
10293 if (unformat (i, "index %d", &index))
10294 num_m_args++;
10295 else {
10296 clib_warning ("parse error '%U'", format_unformat_error, i);
10297 return -99;
10298 }
10299 }
10300
10301 if (num_m_args != 1) {
10302 errmsg("mandatory argument(s) missing\n");
10303 return -99;
10304 }
10305
10306 /* Construct the API message */
10307 M(MAP_DEL_DOMAIN, map_del_domain);
10308
10309 mp->index = ntohl(index);
10310
10311 /* send it... */
10312 S;
10313
10314 /* Wait for a reply, return good/bad news */
10315 W;
10316}
10317
10318static int api_map_add_del_rule (vat_main_t * vam)
10319{
10320 unformat_input_t *i = vam->input;
10321 vl_api_map_add_del_rule_t *mp;
10322 f64 timeout;
10323 u8 is_add = 1;
10324 ip6_address_t ip6_dst;
10325 u32 num_m_args = 0, index, psid;
10326
10327 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
10328 if (unformat (i, "index %d", &index))
10329 num_m_args++;
10330 else if (unformat (i, "psid %d", &psid))
10331 num_m_args++;
10332 else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
10333 num_m_args++;
10334 else if (unformat (i, "del")) {
10335 is_add = 0;
10336 } else {
10337 clib_warning ("parse error '%U'", format_unformat_error, i);
10338 return -99;
10339 }
10340 }
10341
10342 /* Construct the API message */
10343 M(MAP_ADD_DEL_RULE, map_add_del_rule);
10344
10345 mp->index = ntohl(index);
10346 mp->is_add = is_add;
Damjan Marionf1213b82016-03-13 02:22:06 +010010347 clib_memcpy(mp->ip6_dst, &ip6_dst, sizeof(ip6_dst));
Ed Warnickecb9cada2015-12-08 15:45:58 -070010348 mp->psid = ntohs(psid);
10349
10350 /* send it... */
10351 S;
10352
10353 /* Wait for a reply, return good/bad news */
10354 W;
10355}
10356
10357static int api_map_domain_dump (vat_main_t * vam)
10358{
10359 vl_api_map_domain_dump_t *mp;
10360 f64 timeout;
10361
10362 /* Construct the API message */
10363 M(MAP_DOMAIN_DUMP, map_domain_dump);
10364
10365 /* send it... */
10366 S;
10367
10368 /* Use a control ping for synchronization */
10369 {
10370 vl_api_control_ping_t * mp;
10371 M(CONTROL_PING, control_ping);
10372 S;
10373 }
10374 W;
10375}
10376
10377static int api_map_rule_dump (vat_main_t * vam)
10378{
10379 unformat_input_t *i = vam->input;
10380 vl_api_map_rule_dump_t *mp;
10381 f64 timeout;
10382 u32 domain_index = ~0;
10383
10384 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
10385 if (unformat (i, "index %u", &domain_index))
10386 ;
10387 else
10388 break;
10389 }
10390
10391 if (domain_index == ~0) {
10392 clib_warning("parse error: domain index expected");
10393 return -99;
10394 }
10395
10396 /* Construct the API message */
10397 M(MAP_RULE_DUMP, map_rule_dump);
10398
10399 mp->domain_index = htonl(domain_index);
10400
10401 /* send it... */
10402 S;
10403
10404 /* Use a control ping for synchronization */
10405 {
10406 vl_api_control_ping_t * mp;
10407 M(CONTROL_PING, control_ping);
10408 S;
10409 }
10410 W;
10411}
10412
10413static void vl_api_map_add_domain_reply_t_handler
10414(vl_api_map_add_domain_reply_t * mp)
10415{
10416 vat_main_t * vam = &vat_main;
10417 i32 retval = ntohl(mp->retval);
10418
10419 if (vam->async_mode) {
10420 vam->async_errors += (retval < 0);
10421 } else {
10422 vam->retval = retval;
10423 vam->result_ready = 1;
10424 }
10425}
10426
10427static void vl_api_map_add_domain_reply_t_handler_json
10428(vl_api_map_add_domain_reply_t * mp)
10429{
10430 vat_main_t * vam = &vat_main;
10431 vat_json_node_t node;
10432
10433 vat_json_init_object(&node);
10434 vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
10435 vat_json_object_add_uint(&node, "index", ntohl(mp->index));
10436
10437 vat_json_print(vam->ofp, &node);
10438 vat_json_free(&node);
10439
10440 vam->retval = ntohl(mp->retval);
10441 vam->result_ready = 1;
10442}
10443
10444static int
10445api_get_first_msg_id (vat_main_t * vam)
10446{
10447 vl_api_get_first_msg_id_t * mp;
10448 f64 timeout;
10449 unformat_input_t * i = vam->input;
10450 u8 * name;
10451 u8 name_set = 0;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +080010452
Ed Warnickecb9cada2015-12-08 15:45:58 -070010453 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
10454 if (unformat (i, "client %s", &name))
10455 name_set = 1;
Hongjun Ni11bfc2f2016-07-22 18:19:19 +080010456 else
Ed Warnickecb9cada2015-12-08 15:45:58 -070010457 break;
10458 }
10459
10460 if (name_set == 0) {
10461 errmsg ("missing client name\n");
10462 return -99;
10463 }
10464 vec_add1 (name, 0);
10465
10466 if (vec_len (name) > 63) {
10467 errmsg ("client name too long\n");
10468 return -99;
10469 }
10470
10471 M(GET_FIRST_MSG_ID, get_first_msg_id);
Damjan Marionf1213b82016-03-13 02:22:06 +010010472 clib_memcpy (mp->name, name, vec_len(name));
Ed Warnickecb9cada2015-12-08 15:45:58 -070010473 S; W;
10474 /* NOTREACHED */
10475 return 0;
10476}
10477
Dave Barachc07bf5d2016-02-17 17:52:26 -050010478static int api_cop_interface_enable_disable (vat_main_t * vam)
10479{
10480 unformat_input_t * line_input = vam->input;
10481 vl_api_cop_interface_enable_disable_t * mp;
10482 f64 timeout;
10483 u32 sw_if_index = ~0;
10484 u8 enable_disable = 1;
10485
10486 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
10487 if (unformat (line_input, "disable"))
10488 enable_disable = 0;
10489 if (unformat (line_input, "enable"))
10490 enable_disable = 1;
10491 else if (unformat (line_input, "%U", unformat_sw_if_index,
10492 vam, &sw_if_index))
10493 ;
10494 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
10495 ;
10496 else
10497 break;
10498 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +080010499
Dave Barachc07bf5d2016-02-17 17:52:26 -050010500 if (sw_if_index == ~0) {
10501 errmsg ("missing interface name or sw_if_index\n");
10502 return -99;
10503 }
10504
10505 /* Construct the API message */
10506 M(COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
10507 mp->sw_if_index = ntohl(sw_if_index);
10508 mp->enable_disable = enable_disable;
10509
10510 /* send it... */
10511 S;
10512 /* Wait for the reply */
10513 W;
10514}
10515
10516static int api_cop_whitelist_enable_disable (vat_main_t * vam)
10517{
10518 unformat_input_t * line_input = vam->input;
10519 vl_api_cop_whitelist_enable_disable_t * mp;
10520 f64 timeout;
10521 u32 sw_if_index = ~0;
10522 u8 ip4=0, ip6=0, default_cop=0;
10523 u32 fib_id;
10524
10525 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
10526 if (unformat (line_input, "ip4"))
10527 ip4 = 1;
10528 else if (unformat (line_input, "ip6"))
10529 ip6 = 1;
10530 else if (unformat (line_input, "default"))
10531 default_cop = 1;
10532 else if (unformat (line_input, "%U", unformat_sw_if_index,
10533 vam, &sw_if_index))
10534 ;
10535 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
10536 ;
10537 else if (unformat (line_input, "fib-id %d", &fib_id))
10538 ;
10539 else
10540 break;
10541 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +080010542
Dave Barachc07bf5d2016-02-17 17:52:26 -050010543 if (sw_if_index == ~0) {
10544 errmsg ("missing interface name or sw_if_index\n");
10545 return -99;
10546 }
10547
10548 /* Construct the API message */
10549 M(COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
10550 mp->sw_if_index = ntohl(sw_if_index);
10551 mp->fib_id = ntohl(fib_id);
10552 mp->ip4 = ip4;
10553 mp->ip6 = ip6;
10554 mp->default_cop = default_cop;
10555
10556 /* send it... */
10557 S;
10558 /* Wait for the reply */
10559 W;
10560}
10561
Dave Barachb44e9bc2016-02-19 09:06:23 -050010562static int api_get_node_graph (vat_main_t * vam)
10563{
10564 vl_api_get_node_graph_t * mp;
10565 f64 timeout;
10566
10567 M(GET_NODE_GRAPH, get_node_graph);
10568
10569 /* send it... */
10570 S;
10571 /* Wait for the reply */
10572 W;
10573}
10574
Andrej Kozemcaka8691752016-07-27 10:33:38 +020010575/** Used for transferring locators via VPP API */
10576typedef CLIB_PACKED(struct
10577{
10578 u32 sw_if_index; /**< locator sw_if_index */
10579 u8 priority; /**< locator priority */
10580 u8 weight; /**< locator weight */
10581}) ls_locator_t;
10582
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010583static int
10584api_lisp_add_del_locator_set(vat_main_t * vam)
10585{
10586 unformat_input_t * input = vam->input;
10587 vl_api_lisp_add_del_locator_set_t *mp;
10588 f64 timeout = ~0;
10589 u8 is_add = 1;
10590 u8 *locator_set_name = NULL;
10591 u8 locator_set_name_set = 0;
Andrej Kozemcaka8691752016-07-27 10:33:38 +020010592 ls_locator_t locator, * locators = 0;
10593 u32 sw_if_index, priority, weight;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010594
10595 /* Parse args required to build the message */
10596 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
10597 if (unformat(input, "del")) {
10598 is_add = 0;
10599 } else if (unformat(input, "locator-set %s", &locator_set_name)) {
10600 locator_set_name_set = 1;
Andrej Kozemcaka8691752016-07-27 10:33:38 +020010601 } else if (unformat(input, "sw_if_index %u p %u w %u",
10602 &sw_if_index, &priority, &weight)) {
10603 locator.sw_if_index = htonl(sw_if_index);
10604 locator.priority = priority;
10605 locator.weight = weight;
10606 vec_add1(locators, locator);
10607 } else if (unformat(input, "iface %U p %u w %u", unformat_sw_if_index,
10608 vam, &sw_if_index, &priority, &weight)) {
10609 locator.sw_if_index = htonl(sw_if_index);
10610 locator.priority = priority;
10611 locator.weight = weight;
10612 vec_add1(locators, locator);
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010613 } else
10614 break;
10615 }
10616
10617 if (locator_set_name_set == 0) {
10618 errmsg ("missing locator-set name");
Andrej Kozemcaka8691752016-07-27 10:33:38 +020010619 vec_free(locators);
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010620 return -99;
10621 }
10622
10623 if (vec_len(locator_set_name) > 64) {
10624 errmsg ("locator-set name too long\n");
10625 vec_free(locator_set_name);
Andrej Kozemcaka8691752016-07-27 10:33:38 +020010626 vec_free(locators);
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010627 return -99;
10628 }
10629 vec_add1(locator_set_name, 0);
10630
10631 /* Construct the API message */
10632 M(LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set);
10633
10634 mp->is_add = is_add;
Damjan Marionf1213b82016-03-13 02:22:06 +010010635 clib_memcpy(mp->locator_set_name, locator_set_name,
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010636 vec_len(locator_set_name));
10637 vec_free(locator_set_name);
10638
Andrej Kozemcaka8691752016-07-27 10:33:38 +020010639 mp->locator_num = vec_len (locators);
10640 clib_memcpy (mp->locators, locators,
10641 (sizeof (ls_locator_t) * vec_len (locators)));
10642 vec_free (locators);
10643
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010644 /* send it... */
10645 S;
10646
10647 /* Wait for a reply... */
10648 W;
10649
10650 /* NOTREACHED */
10651 return 0;
10652}
10653
10654static int
10655api_lisp_add_del_locator(vat_main_t * vam)
10656{
10657 unformat_input_t * input = vam->input;
10658 vl_api_lisp_add_del_locator_t *mp;
10659 f64 timeout = ~0;
10660 u32 tmp_if_index = ~0;
10661 u32 sw_if_index = ~0;
10662 u8 sw_if_index_set = 0;
10663 u8 sw_if_index_if_name_set = 0;
Filip Tehlarc4770ec2016-06-30 09:46:08 +020010664 u32 priority = ~0;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010665 u8 priority_set = 0;
Filip Tehlarc4770ec2016-06-30 09:46:08 +020010666 u32 weight = ~0;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010667 u8 weight_set = 0;
10668 u8 is_add = 1;
10669 u8 *locator_set_name = NULL;
10670 u8 locator_set_name_set = 0;
10671
10672 /* Parse args required to build the message */
10673 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
10674 if (unformat(input, "del")) {
10675 is_add = 0;
10676 } else if (unformat(input, "locator-set %s", &locator_set_name)) {
10677 locator_set_name_set = 1;
10678 } else if (unformat(input, "iface %U", unformat_sw_if_index, vam,
10679 &tmp_if_index)) {
10680 sw_if_index_if_name_set = 1;
10681 sw_if_index = tmp_if_index;
10682 } else if (unformat(input,"sw_if_index %d", &tmp_if_index)) {
10683 sw_if_index_set = 1;
10684 sw_if_index = tmp_if_index;
10685 } else if (unformat(input, "p %d", &priority)) {
10686 priority_set = 1;
10687 } else if (unformat(input, "w %d", &weight)) {
10688 weight_set = 1;
10689 } else
10690 break;
10691 }
10692
10693 if (locator_set_name_set == 0) {
10694 errmsg ("missing locator-set name");
10695 return -99;
10696 }
10697
10698 if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0) {
10699 errmsg ("missing sw_if_index");
10700 vec_free(locator_set_name);
10701 return -99;
10702 }
10703
10704 if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0) {
10705 errmsg ("cannot use both params interface name and sw_if_index");
10706 vec_free(locator_set_name);
10707 return -99;
10708 }
10709
10710 if (priority_set == 0) {
10711 errmsg ("missing locator-set priority\n");
10712 vec_free(locator_set_name);
10713 return -99;
10714 }
10715
10716 if (weight_set == 0) {
10717 errmsg ("missing locator-set weight\n");
10718 vec_free(locator_set_name);
10719 return -99;
10720 }
10721
10722 if (vec_len(locator_set_name) > 64) {
10723 errmsg ("locator-set name too long\n");
10724 vec_free(locator_set_name);
10725 return -99;
10726 }
10727 vec_add1(locator_set_name, 0);
10728
10729 /* Construct the API message */
10730 M(LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
10731
10732 mp->is_add = is_add;
10733 mp->sw_if_index = ntohl(sw_if_index);
10734 mp->priority = priority;
10735 mp->weight = weight;
Damjan Marionf1213b82016-03-13 02:22:06 +010010736 clib_memcpy(mp->locator_set_name, locator_set_name,
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010737 vec_len(locator_set_name));
10738 vec_free(locator_set_name);
10739
10740 /* send it... */
10741 S;
10742
10743 /* Wait for a reply... */
10744 W;
10745
10746 /* NOTREACHED */
10747 return 0;
10748}
10749
10750static int
10751api_lisp_add_del_local_eid(vat_main_t * vam)
10752{
10753 unformat_input_t * input = vam->input;
10754 vl_api_lisp_add_del_local_eid_t *mp;
10755 f64 timeout = ~0;
10756 u8 is_add = 1;
10757 u8 eidv4_set = 0;
10758 u8 eidv6_set = 0;
Filip Tehlar006eb262016-06-27 13:09:20 +020010759 u8 eid_type = (u8)~0;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010760 ip4_address_t eidv4;
10761 ip6_address_t eidv6;
Filip Tehlar006eb262016-06-27 13:09:20 +020010762 u8 mac[6] = {0};
Filip Tehlarc4770ec2016-06-30 09:46:08 +020010763 u32 tmp_eid_lenght = ~0;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010764 u8 eid_lenght = ~0;
10765 u8 *locator_set_name = NULL;
10766 u8 locator_set_name_set = 0;
Filip Tehlar324112f2016-06-02 16:07:38 +020010767 u32 vni = 0;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010768
10769 /* Parse args required to build the message */
10770 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
10771 if (unformat(input, "del")) {
10772 is_add = 0;
Florin Corasbb433382016-07-18 17:06:20 +020010773 } else if (unformat(input, "vni %d", &vni)) {
Filip Tehlar324112f2016-06-02 16:07:38 +020010774 ;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010775 } else if (unformat(input, "eid %U/%d", unformat_ip4_address,
10776 &eidv4, &tmp_eid_lenght)) {
10777 eid_lenght = tmp_eid_lenght;
10778 eidv4_set = 1;
Filip Tehlar006eb262016-06-27 13:09:20 +020010779 eid_type = 0; /* ipv4 type */
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010780 } else if (unformat(input, "eid %U/%d", unformat_ip6_address,
10781 &eidv6, &tmp_eid_lenght)) {
10782 eid_lenght = tmp_eid_lenght;
10783 eidv6_set = 1;
Filip Tehlar006eb262016-06-27 13:09:20 +020010784 eid_type = 1; /* ipv6 type */
10785 } else if (unformat(input, "eid %U", unformat_ethernet_address, mac)) {
10786 eid_type = 2; /* mac type */
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010787 } else if (unformat(input, "locator-set %s", &locator_set_name)) {
10788 locator_set_name_set = 1;
10789 } else
10790 break;
10791 }
10792
10793 if (locator_set_name_set == 0) {
10794 errmsg ("missing locator-set name\n");
10795 return -99;
10796 }
10797
Filip Tehlar006eb262016-06-27 13:09:20 +020010798 if ((u8)~0 == eid_type) {
10799 errmsg ("EID address not set!");
10800 vec_free(locator_set_name);
10801 return -99;
10802 }
10803
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010804 if (vec_len(locator_set_name) > 64) {
10805 errmsg ("locator-set name too long\n");
10806 vec_free(locator_set_name);
10807 return -99;
10808 }
10809 vec_add1(locator_set_name, 0);
10810
10811 if (eidv4_set && eidv6_set) {
10812 errmsg ("both eid v4 and v6 addresses set\n");
10813 vec_free(locator_set_name);
10814 return -99;
10815 }
10816
Andrej Kozemcak3e53fc52016-05-09 10:52:16 +020010817 if (eidv4_set && eid_lenght > 32) {
10818 errmsg ("eid prefix to big\n");
10819 vec_free(locator_set_name);
10820 return -99;
10821 }
10822
10823 if (eidv6_set && eid_lenght > 128) {
10824 errmsg ("eid prefix to big\n");
10825 vec_free(locator_set_name);
10826 return -99;
10827 }
10828
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010829 /* Construct the API message */
10830 M(LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
10831
10832 mp->is_add = is_add;
Filip Tehlar006eb262016-06-27 13:09:20 +020010833 switch (eid_type) {
10834 case 0: /* ipv4 */
10835 clib_memcpy (mp->eid, &eidv4, sizeof(eidv4));
10836 break;
10837 case 1: /* ipv6 */
10838 clib_memcpy (mp->eid, &eidv6, sizeof(eidv6));
10839 break;
10840 case 2: /* mac */
10841 clib_memcpy (mp->eid, mac, 6);
10842 break;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010843 }
Filip Tehlar006eb262016-06-27 13:09:20 +020010844 mp->eid_type = eid_type;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010845 mp->prefix_len = eid_lenght;
Filip Tehlar324112f2016-06-02 16:07:38 +020010846 mp->vni = clib_host_to_net_u32(vni);
Damjan Marionf1213b82016-03-13 02:22:06 +010010847 clib_memcpy(mp->locator_set_name, locator_set_name,
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010848 vec_len(locator_set_name));
10849 vec_free(locator_set_name);
10850
10851 /* send it... */
10852 S;
10853
10854 /* Wait for a reply... */
10855 W;
10856
10857 /* NOTREACHED */
10858 return 0;
10859}
10860
10861static int
10862api_lisp_gpe_add_del_fwd_entry(vat_main_t * vam)
10863{
10864 unformat_input_t * input = vam->input;
10865 vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
10866 f64 timeout = ~0;
10867 u8 is_add = 1;
10868 u8 eidv4_set = 0, slocv4_set = 0, dlocv4_set = 0;
10869 u8 eidv6_set = 0, slocv6_set = 0, dlocv6_set = 0;
10870 ip4_address_t eidv4, slocv4, dlocv4;
10871 ip6_address_t eidv6, slocv6, dlocv6;
Filip Tehlarc4770ec2016-06-30 09:46:08 +020010872 u32 tmp_eid_lenght = ~0;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010873 u8 eid_lenght = ~0;
10874
10875 /* Parse args required to build the message */
10876 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
10877 if (unformat(input, "del")) {
10878 is_add = 0;
10879 } else if (unformat(input, "eid %U/%d", unformat_ip4_address,
10880 &eidv4, &tmp_eid_lenght)) {
10881 eid_lenght = tmp_eid_lenght;
10882 eidv4_set = 1;
10883 } else if (unformat(input, "eid %U/%d", unformat_ip6_address,
10884 &eidv6, &tmp_eid_lenght)) {
10885 eid_lenght = tmp_eid_lenght;
10886 eidv6_set = 1;
10887 } else if (unformat(input, "sloc %U", unformat_ip4_address, &slocv4)) {
10888 slocv4_set = 1;
10889 } else if (unformat(input, "sloc %U", unformat_ip6_address, &slocv6)) {
10890 slocv6_set = 1;
10891 } else if (unformat(input, "dloc %U", unformat_ip4_address, &dlocv4)) {
10892 dlocv4_set = 1;
10893 } else if (unformat(input, "dloc %U", unformat_ip6_address, &dlocv6)) {
10894 dlocv6_set = 1;
10895 } else
10896 break;
10897 }
10898
10899 if (eidv4_set && eidv6_set) {
10900 errmsg ("both eid v4 and v6 addresses set\n");
10901 return -99;
10902 }
10903
10904 if (!eidv4_set && !eidv6_set) {
10905 errmsg ("eid addresses not set\n");
10906 return -99;
10907 }
10908
10909 if (slocv4_set && slocv6_set) {
10910 errmsg ("both source v4 and v6 addresses set\n");
10911 return -99;
10912 }
10913
10914 if (!slocv4_set && !slocv6_set) {
10915 errmsg ("source addresses not set\n");
10916 return -99;
10917 }
10918
10919 if (dlocv4_set && dlocv6_set) {
10920 errmsg ("both destination v4 and v6 addresses set\n");
10921 return -99;
10922 }
10923
10924 if (dlocv4_set && dlocv6_set) {
10925 errmsg ("destination addresses not set\n");
10926 return -99;
10927 }
10928
10929 if (!(slocv4_set == dlocv4_set && slocv6_set == dlocv6_set)) {
10930 errmsg ("mixing type of source and destination address\n");
10931 return -99;
10932 }
10933
10934 /* Construct the API message */
10935 M(LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
10936
10937 mp->is_add = is_add;
10938 if (eidv6_set) {
10939 mp->eid_is_ipv6 = 1;
Damjan Marionf1213b82016-03-13 02:22:06 +010010940 clib_memcpy(mp->eid_ip_address, &eidv6, sizeof(eidv6));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010941 } else {
10942 mp->eid_is_ipv6 = 0;
Damjan Marionf1213b82016-03-13 02:22:06 +010010943 clib_memcpy(mp->eid_ip_address, &eidv4, sizeof(eidv4));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010944 }
10945 mp->eid_prefix_len = eid_lenght;
10946 if (slocv6_set) {
10947 mp->address_is_ipv6 = 1;
Damjan Marionf1213b82016-03-13 02:22:06 +010010948 clib_memcpy(mp->source_ip_address, &slocv6, sizeof(slocv6));
10949 clib_memcpy(mp->destination_ip_address, &dlocv6, sizeof(dlocv6));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010950 } else {
10951 mp->address_is_ipv6 = 0;
Damjan Marionf1213b82016-03-13 02:22:06 +010010952 clib_memcpy(mp->source_ip_address, &slocv4, sizeof(slocv4));
10953 clib_memcpy(mp->destination_ip_address, &dlocv4, sizeof(dlocv4));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020010954 }
10955
10956 /* send it... */
10957 S;
10958
10959 /* Wait for a reply... */
10960 W;
10961
10962 /* NOTREACHED */
10963 return 0;
10964}
10965
10966static int
10967api_lisp_add_del_map_resolver(vat_main_t * vam)
10968{
10969 unformat_input_t * input = vam->input;
10970 vl_api_lisp_add_del_map_resolver_t *mp;
10971 f64 timeout = ~0;
10972 u8 is_add = 1;
10973 u8 ipv4_set = 0;
10974 u8 ipv6_set = 0;
10975 ip4_address_t ipv4;
10976 ip6_address_t ipv6;
10977
10978 /* Parse args required to build the message */
10979 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
10980 if (unformat(input, "del")) {
10981 is_add = 0;
10982 } else if (unformat(input, "%U", unformat_ip4_address, &ipv4)) {
10983 ipv4_set = 1;
10984 } else if (unformat(input, "%U", unformat_ip6_address, &ipv6)) {
10985 ipv6_set = 1;
10986 } else
10987 break;
10988 }
10989
10990 if (ipv4_set && ipv6_set) {
10991 errmsg ("both eid v4 and v6 addresses set\n");
10992 return -99;
10993 }
10994
10995 if (!ipv4_set && !ipv6_set) {
10996 errmsg ("eid addresses not set\n");
10997 return -99;
10998 }
10999
11000 /* Construct the API message */
11001 M(LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
11002
11003 mp->is_add = is_add;
11004 if (ipv6_set) {
11005 mp->is_ipv6 = 1;
Damjan Marionf1213b82016-03-13 02:22:06 +010011006 clib_memcpy(mp->ip_address, &ipv6, sizeof(ipv6));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020011007 } else {
11008 mp->is_ipv6 = 0;
Damjan Marionf1213b82016-03-13 02:22:06 +010011009 clib_memcpy(mp->ip_address, &ipv4, sizeof(ipv4));
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020011010 }
11011
11012 /* send it... */
11013 S;
11014
11015 /* Wait for a reply... */
11016 W;
11017
11018 /* NOTREACHED */
11019 return 0;
11020}
11021
11022static int
Florin Coras577c3552016-04-21 00:45:40 +020011023api_lisp_gpe_enable_disable (vat_main_t * vam)
11024{
11025 unformat_input_t * input = vam->input;
11026 vl_api_lisp_gpe_enable_disable_t *mp;
11027 f64 timeout = ~0;
11028 u8 is_set = 0;
11029 u8 is_en = 1;
11030
11031 /* Parse args required to build the message */
11032 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
11033 if (unformat(input, "enable")) {
11034 is_set = 1;
11035 is_en = 1;
11036 } else if (unformat(input, "disable")) {
11037 is_set = 1;
11038 is_en = 0;
11039 } else
11040 break;
11041 }
11042
11043 if (is_set == 0) {
11044 errmsg("Value not set\n");
11045 return -99;
11046 }
11047
11048 /* Construct the API message */
11049 M(LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
11050
11051 mp->is_en = is_en;
11052
11053 /* send it... */
11054 S;
11055
11056 /* Wait for a reply... */
11057 W;
11058
11059 /* NOTREACHED */
11060 return 0;
11061}
11062
11063static int
Filip Tehlar46d4e362016-05-09 09:39:26 +020011064api_lisp_enable_disable (vat_main_t * vam)
11065{
11066 unformat_input_t * input = vam->input;
11067 vl_api_lisp_enable_disable_t *mp;
11068 f64 timeout = ~0;
11069 u8 is_set = 0;
11070 u8 is_en = 0;
11071
11072 /* Parse args required to build the message */
11073 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11074 {
11075 if (unformat (input, "enable"))
11076 {
11077 is_set = 1;
11078 is_en = 1;
11079 }
11080 else if (unformat (input, "disable"))
11081 {
11082 is_set = 1;
11083 }
11084 else
11085 break;
11086 }
11087
11088 if (!is_set)
11089 {
11090 errmsg ("Value not set\n");
11091 return -99;
11092 }
11093
11094 /* Construct the API message */
11095 M(LISP_ENABLE_DISABLE, lisp_enable_disable);
11096
11097 mp->is_en = is_en;
11098
11099 /* send it... */
11100 S;
11101
11102 /* Wait for a reply... */
11103 W;
11104
11105 /* NOTREACHED */
11106 return 0;
11107}
11108
Filip Tehlar195bcee2016-05-13 17:37:35 +020011109/** Used for transferring locators via VPP API */
11110typedef CLIB_PACKED(struct
11111{
11112 u8 is_ip4; /**< is locator an IPv4 address? */
Filip Tehlar4d5cabd2016-07-07 15:40:36 +020011113 u8 priority; /**< locator priority */
11114 u8 weight; /**< locator weight */
Filip Tehlar195bcee2016-05-13 17:37:35 +020011115 u8 addr[16]; /**< IPv4/IPv6 address */
11116}) rloc_t;
11117
11118/**
Filip Tehlar53f09e32016-05-19 14:25:44 +020011119 * Enable/disable LISP proxy ITR.
11120 *
11121 * @param vam vpp API test context
11122 * @return return code
11123 */
11124static int
11125api_lisp_pitr_set_locator_set (vat_main_t * vam)
11126{
11127 f64 timeout = ~0;
11128 u8 ls_name_set = 0;
11129 unformat_input_t * input = vam->input;
11130 vl_api_lisp_pitr_set_locator_set_t * mp;
11131 u8 is_add = 1;
11132 u8 * ls_name = 0;
11133
11134 /* Parse args required to build the message */
11135 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11136 {
11137 if (unformat (input, "del"))
11138 is_add = 0;
11139 else if (unformat (input, "locator-set %s", &ls_name))
11140 ls_name_set = 1;
11141 else
11142 {
11143 errmsg ("parse error '%U'", format_unformat_error, input);
11144 return -99;
11145 }
11146 }
11147
11148 if (!ls_name_set)
11149 {
11150 errmsg ("locator-set name not set!");
11151 return -99;
11152 }
11153
11154 M(LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
11155
11156 mp->is_add = is_add;
11157 clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
11158 vec_free (ls_name);
11159
11160 /* send */
11161 S;
11162
11163 /* wait for reply */
11164 W;
11165
11166 /* notreached*/
11167 return 0;
11168}
11169
Andrej Kozemcak914f91b2016-07-18 13:55:37 +020011170static int
11171api_show_lisp_pitr (vat_main_t * vam)
11172{
11173 vl_api_show_lisp_pitr_t *mp;
11174 f64 timeout = ~0;
11175
11176 if (!vam->json_output) {
11177 fformat(vam->ofp, "%=20s\n",
11178 "lisp status:");
11179 }
11180
11181 M(SHOW_LISP_PITR, show_lisp_pitr);
11182 /* send it... */
11183 S;
11184
11185 /* Wait for a reply... */
11186 W;
11187
11188 /* NOTREACHED */
11189 return 0;
11190}
11191
Filip Tehlar53f09e32016-05-19 14:25:44 +020011192/**
Filip Tehlar324112f2016-06-02 16:07:38 +020011193 * Add/delete mapping between vni and vrf
11194 */
11195static int
11196api_lisp_eid_table_add_del_map (vat_main_t * vam)
11197{
11198 f64 timeout = ~0;
11199 unformat_input_t * input = vam->input;
11200 vl_api_lisp_eid_table_add_del_map_t *mp;
Florin Coras1a1adc72016-07-22 01:45:30 +020011201 u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
11202 u32 vni, vrf, bd_index;
Filip Tehlar324112f2016-06-02 16:07:38 +020011203
11204 /* Parse args required to build the message */
11205 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11206 {
11207 if (unformat (input, "del"))
11208 is_add = 0;
11209 else if (unformat(input, "vrf %d", &vrf))
11210 vrf_set = 1;
Florin Coras1a1adc72016-07-22 01:45:30 +020011211 else if (unformat(input, "bd_index %d", &bd_index))
11212 bd_index_set = 1;
Filip Tehlar324112f2016-06-02 16:07:38 +020011213 else if (unformat(input, "vni %d", &vni))
11214 vni_set = 1;
11215 else
11216 break;
11217 }
11218
Florin Coras1a1adc72016-07-22 01:45:30 +020011219 if (!vni_set || (!vrf_set && !bd_index_set))
Filip Tehlar324112f2016-06-02 16:07:38 +020011220 {
11221 errmsg ("missing arguments!");
11222 return -99;
11223 }
11224
11225 M(LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
11226
11227 mp->is_add = is_add;
11228 mp->vni = htonl (vni);
Florin Coras1a1adc72016-07-22 01:45:30 +020011229 mp->dp_table = htonl (vrf);
11230 mp->is_l2 = bd_index_set;
Filip Tehlar324112f2016-06-02 16:07:38 +020011231
11232 /* send */
11233 S;
11234
11235 /* wait for reply */
11236 W;
11237
11238 /* notreached*/
11239 return 0;
11240}
11241
11242/**
Florin Corasf727db92016-06-23 15:01:58 +020011243 * Add/del remote mapping to/from LISP control plane
Filip Tehlar195bcee2016-05-13 17:37:35 +020011244 *
11245 * @param vam vpp API test context
11246 * @return return code
11247 */
11248static int
11249api_lisp_add_del_remote_mapping (vat_main_t * vam)
11250{
11251 unformat_input_t * input = vam->input;
11252 vl_api_lisp_add_del_remote_mapping_t *mp;
11253 f64 timeout = ~0;
11254 u32 vni = 0;
Andrej Kozemcak438109d2016-07-22 12:54:12 +020011255 //TODO: seid need remove
11256 ip4_address_t seid4, eid4, rloc4;
11257 ip6_address_t seid6, eid6, rloc6;
11258 u8 eid_mac[6] = {0};
Filip Tehlar006eb262016-06-27 13:09:20 +020011259 u8 seid_mac[6] = {0};
Andrej Kozemcak438109d2016-07-22 12:54:12 +020011260 u8 eid_type;
11261 u32 eid_len = 0, len;
Filip Tehlar58f886a2016-05-30 15:57:40 +020011262 u8 is_add = 1, del_all = 0;
Filip Tehlar4d5cabd2016-07-07 15:40:36 +020011263 u32 action = ~0, p, w;
11264 rloc_t * rlocs = 0, rloc, * curr_rloc = 0;
Filip Tehlar195bcee2016-05-13 17:37:35 +020011265
Andrej Kozemcak438109d2016-07-22 12:54:12 +020011266 eid_type = (u8)~0;
Filip Tehlar006eb262016-06-27 13:09:20 +020011267
Filip Tehlar195bcee2016-05-13 17:37:35 +020011268 /* Parse args required to build the message */
11269 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
Filip Tehlar58f886a2016-05-30 15:57:40 +020011270 if (unformat(input, "del-all")) {
11271 del_all = 1;
11272 } else if (unformat(input, "del")) {
Filip Tehlar195bcee2016-05-13 17:37:35 +020011273 is_add = 0;
11274 } else if (unformat(input, "add")) {
11275 is_add = 1;
11276 } else if (unformat(input, "deid %U/%d", unformat_ip4_address,
Andrej Kozemcak438109d2016-07-22 12:54:12 +020011277 &eid4, &len)) {
11278 eid_type = 0; /* ipv4 */
11279 if (32 < len) {
11280 clib_warning ("Deid prefix length to big, %d!", len);
11281 return -99;
11282 }
11283 eid_len = len;
Filip Tehlar195bcee2016-05-13 17:37:35 +020011284 } else if (unformat(input, "deid %U/%d", unformat_ip6_address,
Andrej Kozemcak438109d2016-07-22 12:54:12 +020011285 &eid6, &len)) {
11286 eid_type = 1; /* ipv6 */
11287 if (128 < len) {
11288 clib_warning ("Deid prefix length to big, %d!", len);
11289 return -99;
11290 }
11291 eid_len = len;
Filip Tehlar006eb262016-06-27 13:09:20 +020011292 } else if (unformat(input, "deid %U", unformat_ethernet_address,
Andrej Kozemcak438109d2016-07-22 12:54:12 +020011293 eid_mac)) {
11294 eid_type = 2; /* mac */
11295 //TODO: Need remove, but first must be remove from CSIT test
Filip Tehlar195bcee2016-05-13 17:37:35 +020011296 } else if (unformat(input, "seid %U/%d", unformat_ip4_address,
11297 &seid4, &len)) {
Filip Tehlar195bcee2016-05-13 17:37:35 +020011298 } else if (unformat(input, "seid %U/%d", unformat_ip6_address,
11299 &seid6, &len)) {
Andrej Kozemcak438109d2016-07-22 12:54:12 +020011300 ;
Filip Tehlar006eb262016-06-27 13:09:20 +020011301 } else if (unformat(input, "seid %U", unformat_ethernet_address,
11302 seid_mac)) {
Andrej Kozemcak438109d2016-07-22 12:54:12 +020011303 ;
Filip Tehlar195bcee2016-05-13 17:37:35 +020011304 } else if (unformat(input, "vni %d", &vni)) {
11305 ;
Filip Tehlar4d5cabd2016-07-07 15:40:36 +020011306 } else if (unformat(input, "p %d w %d", &p, &w)) {
11307 if (!curr_rloc) {
11308 errmsg ("No RLOC configured for setting priority/weight!");
11309 return -99;
11310 }
11311 curr_rloc->priority = p;
11312 curr_rloc->weight = w;
Filip Tehlar195bcee2016-05-13 17:37:35 +020011313 } else if (unformat(input, "rloc %U", unformat_ip4_address, &rloc4)) {
11314 rloc.is_ip4 = 1;
11315 clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
11316 vec_add1 (rlocs, rloc);
Filip Tehlar4d5cabd2016-07-07 15:40:36 +020011317 curr_rloc = &rlocs[vec_len (rlocs) - 1];
Filip Tehlar195bcee2016-05-13 17:37:35 +020011318 } else if (unformat(input, "rloc %U", unformat_ip6_address, &rloc6)) {
11319 rloc.is_ip4 = 0;
11320 clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
11321 vec_add1 (rlocs, rloc);
Filip Tehlar4d5cabd2016-07-07 15:40:36 +020011322 curr_rloc = &rlocs[vec_len (rlocs) - 1];
Filip Tehlar195bcee2016-05-13 17:37:35 +020011323 } else if (unformat(input, "action %d", &action)) {
11324 ;
11325 } else {
11326 clib_warning ("parse error '%U'", format_unformat_error, input);
11327 return -99;
11328 }
11329 }
11330
Andrej Kozemcak438109d2016-07-22 12:54:12 +020011331 if ((u8)~0 == eid_type) {
Filip Tehlar195bcee2016-05-13 17:37:35 +020011332 errmsg ("missing params!");
11333 return -99;
11334 }
11335
Filip Tehlar195bcee2016-05-13 17:37:35 +020011336 if (is_add && (~0 == action)
11337 && 0 == vec_len (rlocs)) {
11338 errmsg ("no action set for negative map-reply!");
11339 return -99;
11340 }
11341
11342 M(LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping);
11343 mp->is_add = is_add;
11344 mp->vni = htonl (vni);
Filip Tehlar195bcee2016-05-13 17:37:35 +020011345 mp->action = (u8) action;
Andrej Kozemcak438109d2016-07-22 12:54:12 +020011346 mp->eid_len = eid_len;
Filip Tehlar58f886a2016-05-30 15:57:40 +020011347 mp->del_all = del_all;
Andrej Kozemcak438109d2016-07-22 12:54:12 +020011348 mp->eid_type = eid_type;
Filip Tehlar195bcee2016-05-13 17:37:35 +020011349
Filip Tehlar006eb262016-06-27 13:09:20 +020011350 switch (mp->eid_type) {
11351 case 0:
Andrej Kozemcak438109d2016-07-22 12:54:12 +020011352 clib_memcpy (mp->eid, &eid4, sizeof (eid4));
Filip Tehlar006eb262016-06-27 13:09:20 +020011353 break;
11354 case 1:
Andrej Kozemcak438109d2016-07-22 12:54:12 +020011355 clib_memcpy (mp->eid, &eid6, sizeof (eid6));
Filip Tehlar006eb262016-06-27 13:09:20 +020011356 break;
11357 case 2:
Andrej Kozemcak438109d2016-07-22 12:54:12 +020011358 clib_memcpy (mp->eid, eid_mac, 6);
Filip Tehlar006eb262016-06-27 13:09:20 +020011359 break;
11360 default:
11361 errmsg ("unknown EID type %d!", mp->eid_type);
11362 return 0;
Filip Tehlar195bcee2016-05-13 17:37:35 +020011363 }
11364
11365 mp->rloc_num = vec_len (rlocs);
11366 clib_memcpy (mp->rlocs, rlocs, (sizeof (rloc_t) * vec_len (rlocs)));
11367 vec_free (rlocs);
11368
11369 /* send it... */
11370 S;
11371
11372 /* Wait for a reply... */
11373 W;
11374
11375 /* NOTREACHED */
11376 return 0;
11377}
11378
Florin Corasf727db92016-06-23 15:01:58 +020011379/**
11380 * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
11381 * forwarding entries in data-plane accordingly.
11382 *
11383 * @param vam vpp API test context
11384 * @return return code
11385 */
11386static int
11387api_lisp_add_del_adjacency (vat_main_t * vam)
11388{
11389 unformat_input_t * input = vam->input;
11390 vl_api_lisp_add_del_adjacency_t *mp;
11391 f64 timeout = ~0;
11392 u32 vni = 0;
Florin Coras71893ac2016-07-10 20:09:32 +020011393 ip4_address_t seid4, deid4;
11394 ip6_address_t seid6, deid6;
Florin Corasf727db92016-06-23 15:01:58 +020011395 u8 deid_mac[6] = {0};
11396 u8 seid_mac[6] = {0};
11397 u8 deid_type, seid_type;
11398 u32 seid_len = 0, deid_len = 0, len;
11399 u8 is_add = 1;
Florin Corasf727db92016-06-23 15:01:58 +020011400
Florin Corasf727db92016-06-23 15:01:58 +020011401 seid_type = deid_type = (u8)~0;
11402
11403 /* Parse args required to build the message */
11404 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
11405 if (unformat(input, "del")) {
11406 is_add = 0;
11407 } else if (unformat(input, "add")) {
11408 is_add = 1;
11409 } else if (unformat(input, "deid %U/%d", unformat_ip4_address,
11410 &deid4, &len)) {
11411 deid_type = 0; /* ipv4 */
11412 deid_len = len;
11413 } else if (unformat(input, "deid %U/%d", unformat_ip6_address,
11414 &deid6, &len)) {
11415 deid_type = 1; /* ipv6 */
11416 deid_len = len;
11417 } else if (unformat(input, "deid %U", unformat_ethernet_address,
11418 deid_mac)) {
11419 deid_type = 2; /* mac */
11420 } else if (unformat(input, "seid %U/%d", unformat_ip4_address,
11421 &seid4, &len)) {
11422 seid_type = 0; /* ipv4 */
11423 seid_len = len;
11424 } else if (unformat(input, "seid %U/%d", unformat_ip6_address,
11425 &seid6, &len)) {
11426 seid_type = 1; /* ipv6 */
11427 seid_len = len;
11428 } else if (unformat(input, "seid %U", unformat_ethernet_address,
11429 seid_mac)) {
11430 seid_type = 2; /* mac */
11431 } else if (unformat(input, "vni %d", &vni)) {
11432 ;
Florin Corasf727db92016-06-23 15:01:58 +020011433 } else {
Filip Tehlar4d5cabd2016-07-07 15:40:36 +020011434 errmsg ("parse error '%U'", format_unformat_error, input);
Florin Corasf727db92016-06-23 15:01:58 +020011435 return -99;
11436 }
11437 }
11438
11439 if ((u8)~0 == deid_type) {
11440 errmsg ("missing params!");
11441 return -99;
11442 }
11443
11444 if (seid_type != deid_type) {
11445 errmsg ("source and destination EIDs are of different types!");
11446 return -99;
11447 }
11448
Florin Corasf727db92016-06-23 15:01:58 +020011449 M(LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
11450 mp->is_add = is_add;
11451 mp->vni = htonl (vni);
11452 mp->seid_len = seid_len;
Florin Corasf727db92016-06-23 15:01:58 +020011453 mp->deid_len = deid_len;
11454 mp->eid_type = deid_type;
11455
11456 switch (mp->eid_type) {
11457 case 0:
11458 clib_memcpy (mp->seid, &seid4, sizeof (seid4));
11459 clib_memcpy (mp->deid, &deid4, sizeof (deid4));
11460 break;
11461 case 1:
11462 clib_memcpy (mp->seid, &seid6, sizeof (seid6));
11463 clib_memcpy (mp->deid, &deid6, sizeof (deid6));
11464 break;
11465 case 2:
11466 clib_memcpy (mp->seid, seid_mac, 6);
11467 clib_memcpy (mp->deid, deid_mac, 6);
11468 break;
11469 default:
11470 errmsg ("unknown EID type %d!", mp->eid_type);
11471 return 0;
11472 }
11473
Florin Corasf727db92016-06-23 15:01:58 +020011474 /* send it... */
11475 S;
11476
11477 /* Wait for a reply... */
11478 W;
11479
11480 /* NOTREACHED */
11481 return 0;
11482}
11483
Filip Tehlar46d4e362016-05-09 09:39:26 +020011484static int
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020011485api_lisp_gpe_add_del_iface(vat_main_t * vam)
11486{
11487 unformat_input_t * input = vam->input;
11488 vl_api_lisp_gpe_add_del_iface_t *mp;
11489 f64 timeout = ~0;
11490 u8 is_set = 0;
Florin Coras577c3552016-04-21 00:45:40 +020011491 u8 is_add = 1;
11492 u32 table_id, vni;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020011493
11494 /* Parse args required to build the message */
11495 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
11496 if (unformat(input, "up")) {
11497 is_set = 1;
11498 is_add = 1;
11499 } else if (unformat(input, "down")) {
11500 is_set = 1;
11501 is_add = 0;
Florin Coras577c3552016-04-21 00:45:40 +020011502 } else if (unformat(input, "table_id %d", &table_id)) {
11503 ;
11504 } else if (unformat(input, "vni %d", &vni)) {
11505 ;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020011506 } else
11507 break;
11508 }
11509
11510 if (is_set == 0) {
11511 errmsg("Value not set\n");
11512 return -99;
11513 }
11514
11515 /* Construct the API message */
11516 M(LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
11517
11518 mp->is_add = is_add;
Florin Coras577c3552016-04-21 00:45:40 +020011519 mp->table_id = table_id;
11520 mp->vni = vni;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020011521
11522 /* send it... */
11523 S;
11524
11525 /* Wait for a reply... */
11526 W;
11527
11528 /* NOTREACHED */
11529 return 0;
11530}
11531
Andrej Kozemcakb6e4d392016-06-14 13:55:57 +020011532/**
11533 * Add/del map request itr rlocs from LISP control plane and updates
11534 *
11535 * @param vam vpp API test context
11536 * @return return code
11537 */
11538static int
11539api_lisp_add_del_map_request_itr_rlocs(vat_main_t * vam)
11540{
11541 unformat_input_t * input = vam->input;
11542 vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
11543 f64 timeout = ~0;
11544 u8 *locator_set_name = 0;
11545 u8 locator_set_name_set = 0;
11546 u8 is_add = 1;
11547
11548 /* Parse args required to build the message */
11549 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
11550 if (unformat(input, "del")) {
11551 is_add = 0;
11552 } else if (unformat(input, "%_%v%_", &locator_set_name)) {
11553 locator_set_name_set = 1;
11554 } else {
11555 clib_warning ("parse error '%U'", format_unformat_error, input);
11556 return -99;
11557 }
11558 }
11559
11560 if (is_add && !locator_set_name_set) {
11561 errmsg ("itr-rloc is not set!");
11562 return -99;
11563 }
11564
11565 if (is_add && vec_len(locator_set_name) > 64) {
11566 errmsg ("itr-rloc locator-set name too long\n");
11567 vec_free(locator_set_name);
11568 return -99;
11569 }
11570
11571 M(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
11572 mp->is_add = is_add;
11573 if (is_add) {
11574 clib_memcpy (mp->locator_set_name , locator_set_name,
11575 vec_len(locator_set_name));
11576 } else {
11577 memset(mp->locator_set_name, 0, sizeof(mp->locator_set_name));
11578 }
11579 vec_free (locator_set_name);
11580
11581 /* send it... */
11582 S;
11583
11584 /* Wait for a reply... */
11585 W;
11586
11587 /* NOTREACHED */
11588 return 0;
11589}
11590
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020011591static int
Andrej Kozemcakd9831182016-06-20 08:47:57 +020011592lisp_locator_dump_send_msg(vat_main_t * vam, u32 locator_set_index, u8 filter)
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020011593{
Andrej Kozemcakd9831182016-06-20 08:47:57 +020011594 vl_api_lisp_locator_dump_t *mp;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020011595 f64 timeout = ~0;
11596
Andrej Kozemcakd9831182016-06-20 08:47:57 +020011597 M(LISP_LOCATOR_DUMP, lisp_locator_dump);
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020011598
Andrej Kozemcakd9831182016-06-20 08:47:57 +020011599 mp->locator_set_index = htonl(locator_set_index);
11600 mp->filter = filter;
11601
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020011602 /* send it... */
11603 S;
11604
11605 /* Use a control ping for synchronization */
11606 {
Andrej Kozemcakd9831182016-06-20 08:47:57 +020011607 vl_api_noprint_control_ping_t * mp;
11608 M(NOPRINT_CONTROL_PING, noprint_control_ping);
11609 S;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020011610 }
11611 /* Wait for a reply... */
11612 W;
Andrej Kozemcakd9831182016-06-20 08:47:57 +020011613}
11614
Andrej Kozemcak6cc6f912016-07-13 13:01:01 +020011615static inline void
11616clean_locator_set_message(vat_main_t * vam)
11617{
11618 locator_set_msg_t * ls = 0;
11619
11620 vec_foreach (ls, vam->locator_set_msg) {
11621 vec_free(ls->locator_set_name);
11622 }
11623
11624 vec_free(vam->locator_set_msg);
11625}
11626
Andrej Kozemcakd9831182016-06-20 08:47:57 +020011627static int
11628print_locator_in_locator_set(vat_main_t * vam, u8 filter)
11629{
11630 locator_set_msg_t * ls;
11631 locator_msg_t * loc;
11632 u8 * tmp_str = 0;
11633 int i = 0, ret = 0;
11634
11635 vec_foreach(ls, vam->locator_set_msg) {
11636 ret = lisp_locator_dump_send_msg(vam, ls->locator_set_index, filter);
11637 if (ret) {
Andrej Kozemcakd9831182016-06-20 08:47:57 +020011638 vec_free(vam->locator_msg);
Andrej Kozemcak6cc6f912016-07-13 13:01:01 +020011639 clean_locator_set_message(vam);
Andrej Kozemcakd9831182016-06-20 08:47:57 +020011640 return ret;
11641 }
11642
11643 tmp_str = format(0, "%=20s%=16d%s", ls->locator_set_name,
11644 ls->locator_set_index,
11645 vec_len(vam->locator_msg) ? "" : "\n");
11646 i = 0;
11647 vec_foreach(loc, vam->locator_msg) {
11648 if (i) {
11649 tmp_str = format(tmp_str, "%=37s", " ");
11650 }
11651 if (loc->local) {
11652 tmp_str = format(tmp_str, "%=16d%=16d%=16d\n",
11653 loc->sw_if_index,
11654 loc->priority,
11655 loc->weight);
11656 } else {
11657 tmp_str = format(tmp_str, "%=16U%=16d%=16d\n",
11658 loc->is_ipv6 ? format_ip6_address :
11659 format_ip4_address,
11660 loc->ip_address,
11661 loc->priority,
11662 loc->weight);
11663 }
11664 i++;
11665 }
11666
11667 fformat(vam->ofp, "%s", tmp_str);
11668 vec_free(tmp_str);
Andrej Kozemcakd9831182016-06-20 08:47:57 +020011669 vec_free(vam->locator_msg);
11670 }
11671
Andrej Kozemcak6cc6f912016-07-13 13:01:01 +020011672 clean_locator_set_message(vam);
Andrej Kozemcakd9831182016-06-20 08:47:57 +020011673
11674 return ret;
11675}
11676
11677static int
11678json_locator_in_locator_set(vat_main_t * vam, u8 filter)
11679{
11680 locator_set_msg_t * ls;
11681 locator_msg_t * loc;
11682 vat_json_node_t * node = NULL;
11683 vat_json_node_t * locator_array;
11684 vat_json_node_t * locator;
11685 struct in6_addr ip6;
11686 struct in_addr ip4;
11687 int ret = 0;
11688
11689 if (!vec_len(vam->locator_set_msg)) {
11690 /* just print [] */
11691 vat_json_init_array(&vam->json_tree);
11692 vat_json_print(vam->ofp, &vam->json_tree);
11693 vam->json_tree.type = VAT_JSON_NONE;
11694 return ret;
11695 }
11696
11697 if (VAT_JSON_ARRAY != vam->json_tree.type) {
11698 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
11699 vat_json_init_array(&vam->json_tree);
11700 }
11701
11702 vec_foreach(ls, vam->locator_set_msg) {
11703 ret = lisp_locator_dump_send_msg(vam, ls->locator_set_index, filter);
11704 if (ret) {
11705 vec_free(ls->locator_set_name);
11706 vec_free(vam->locator_msg);
11707 vec_free(vam->locator_set_msg);
11708 vat_json_free(&vam->json_tree);
11709 vam->json_tree.type = VAT_JSON_NONE;
11710 return ret;
11711 }
11712
11713 node = vat_json_array_add(&vam->json_tree);
11714 vat_json_init_object(node);
11715
11716 vat_json_object_add_uint(node, "locator-set-index",
11717 ls->locator_set_index);
11718 vat_json_object_add_string_copy(node, "locator-set",
11719 ls->locator_set_name);
11720 locator_array = vat_json_object_add_list(node, "locator");
11721 vec_foreach(loc, vam->locator_msg) {
11722 locator = vat_json_array_add(locator_array);
11723 vat_json_init_object(locator);
11724 if (loc->local) {
11725 vat_json_object_add_uint(locator, "locator-index",
11726 loc->sw_if_index);
11727 } else {
11728 if (loc->is_ipv6) {
11729 clib_memcpy(&ip6, loc->ip_address, sizeof(ip6));
11730 vat_json_object_add_ip6(locator, "locator", ip6);
11731 } else {
11732 clib_memcpy(&ip4, loc->ip_address, sizeof(ip4));
11733 vat_json_object_add_ip4(locator, "locator", ip4);
11734 }
11735 }
11736 vat_json_object_add_uint(locator, "priority", loc->priority);
11737 vat_json_object_add_uint(locator, "weight", loc->weight);
11738 }
11739
11740 vec_free(ls->locator_set_name);
11741 vec_free(vam->locator_msg);
11742 }
11743
11744 vat_json_print(vam->ofp, &vam->json_tree);
11745 vat_json_free(&vam->json_tree);
11746 vam->json_tree.type = VAT_JSON_NONE;
11747
11748 vec_free(vam->locator_set_msg);
11749
11750 return ret;
11751}
11752
11753static int
11754get_locator_set_index_from_msg(vat_main_t * vam, u8 * locator_set,
11755 u32 * locator_set_index)
11756{
11757 locator_set_msg_t * ls;
11758 int ret = 0;
11759
11760 * locator_set_index = ~0;
11761
11762 if (!vec_len(vam->locator_set_msg)) {
11763 return ret;
11764 }
11765
11766 vec_foreach(ls, vam->locator_set_msg) {
11767 if (!strcmp((char *) locator_set, (char *) ls->locator_set_name)) {
11768 * locator_set_index = ls->locator_set_index;
11769 vec_free(vam->locator_set_msg);
11770 return ret;
11771 }
11772 }
11773
11774 vec_free(vam->locator_set_msg);
11775
11776 return ret;
11777}
11778
11779static int
11780get_locator_set_index(vat_main_t * vam, u8 * locator_set,
11781 u32 * locator_set_index)
11782{
11783 vl_api_lisp_locator_set_dump_t *mp;
11784 f64 timeout = ~0;
11785
11786 M(LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
11787 /* send it... */
11788 S;
11789
11790 /* Use a control ping for synchronization */
11791 {
11792 vl_api_noprint_control_ping_t * mp;
11793 M(NOPRINT_CONTROL_PING, noprint_control_ping);
11794 S;
11795 }
11796
11797 vam->noprint_msg = 1;
11798 /* Wait for a reply... */
11799 W_L({
11800 get_locator_set_index_from_msg(vam, locator_set, locator_set_index);
11801 vam->noprint_msg = 0;
11802 })
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020011803
11804 /* NOTREACHED */
11805 return 0;
11806}
11807
Andrej Kozemcakd9831182016-06-20 08:47:57 +020011808static inline int
11809lisp_locator_dump(vat_main_t * vam, u32 locator_set_index, u8 * locator_set,
11810 u8 filter)
11811{
11812 int ret = 0;
11813
11814 ASSERT(vam);
11815
11816 if (!vam->json_output) {
11817 fformat(vam->ofp, "%=20s%=16s%=16s\n",
11818 "locator", "priority", "weight");
11819 }
11820
11821 if (locator_set) {
11822 ret = get_locator_set_index(vam, locator_set, &locator_set_index);
11823 }
11824
11825 if (!ret && ~0 == locator_set_index) {
11826 return -99;
11827 }
11828
11829 ret = lisp_locator_dump_send_msg(vam, locator_set_index, filter);
11830
11831 return ret;
11832}
11833
11834static int
11835lisp_locator_set_dump(vat_main_t * vam, u8 filter)
11836{
11837 vl_api_lisp_locator_set_dump_t *mp;
11838 f64 timeout = ~0;
11839
11840 if (!vam->json_output) {
11841 fformat(vam->ofp, "%=20s%=16s%=16s%=16s%=16s\n",
11842 "locator-set", "locator-set-index", "locator", "priority",
11843 "weight");
11844 }
11845
11846 vam->noprint_msg = 1;
11847
11848 M(LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
11849
11850 mp->filter = filter;
11851
11852 /* send it... */
11853 S;
11854
11855 /* Use a control ping for synchronization */
11856 {
11857 vl_api_noprint_control_ping_t * mp;
11858 M(NOPRINT_CONTROL_PING, noprint_control_ping);
11859 S;
11860 }
11861
11862 /* Wait for a reply... */
11863 W_L({
11864 if (vam->noprint_msg) {
11865 if (!vam->json_output) {
11866 print_locator_in_locator_set(vam, filter);
11867 } else {
11868 json_locator_in_locator_set(vam, filter);
11869 }
11870 }
11871
11872 vam->noprint_msg = 0;
11873 });
11874
11875 /* NOTREACHED */
11876 return 0;
11877}
11878
11879static int
11880api_lisp_locator_set_dump(vat_main_t *vam)
11881{
11882 unformat_input_t * input = vam->input;
11883 vam->noprint_msg = 0;
11884 u32 locator_set_index = ~0;
11885 u8 locator_set_index_set = 0;
11886 u8 * locator_set = 0;
11887 u8 locator_set_set = 0;
11888 u8 filter = 0;
11889 int ret = 0;
11890
11891 /* Parse args required to build the message */
11892 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
11893 if (unformat(input, "locator-set-index %u", &locator_set_index)) {
11894 locator_set_index_set = 1;
11895 } else if (unformat(input, "locator-set %s", &locator_set)) {
11896 locator_set_set = 1;
11897 } else if (unformat(input, "local")) {
11898 filter = 1;
11899 } else if (unformat(input, "remote")) {
11900 filter = 2;
11901 } else {
11902 break;
11903 }
11904 }
11905
11906 if (locator_set_index_set && locator_set_set) {
11907 errmsg ("use only input parameter!\n");
11908 return -99;
11909 }
11910
11911 if (locator_set_index_set || locator_set_set) {
11912 ret = lisp_locator_dump(vam, locator_set_index, locator_set, filter);
11913 } else {
11914 ret = lisp_locator_set_dump(vam, filter);
11915 }
11916
11917 vec_free(locator_set);
11918
11919 return ret;
11920}
11921
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020011922static int
Filip Tehlar2f653d02016-07-13 13:17:15 +020011923api_lisp_eid_table_map_dump(vat_main_t *vam)
11924{
11925 vl_api_lisp_eid_table_map_dump_t *mp;
11926 f64 timeout = ~0;
11927
11928 if (!vam->json_output) {
11929 fformat (vam->ofp, "%=10s%=10s\n", "VNI", "VRF");
11930 }
11931
11932 M(LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
11933
11934 /* send it... */
11935 S;
11936
11937 /* Use a control ping for synchronization */
11938 {
11939 vl_api_control_ping_t * mp;
11940 M(CONTROL_PING, control_ping);
11941 S;
11942 }
11943 /* Wait for a reply... */
11944 W;
11945
11946 /* NOTREACHED */
11947 return 0;
11948}
11949
11950static int
Andrej Kozemcak6cc6f912016-07-13 13:01:01 +020011951get_locator_set(vat_main_t * vam)
11952{
11953 vl_api_lisp_locator_set_dump_t *mp;
11954 f64 timeout = ~0;
11955
11956 M(LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
11957 /* send it... */
11958 S;
11959
11960 /* Use a control ping for synchronization */
11961 {
11962 vl_api_noprint_control_ping_t * mp;
11963 M(NOPRINT_CONTROL_PING, noprint_control_ping);
11964 S;
11965 }
11966
11967 /* Wait for a reply... */
11968 W;
11969
11970 /* NOTREACHED */
11971 return 0;
11972}
11973
11974static inline u8 *
11975format_eid_for_eid_table(vat_main_t *vam, u8 * str, eid_table_t * eid_table,
11976 int *ret)
11977{
11978 u8 * (*format_eid)(u8 *, va_list *) = 0;
11979
11980 ASSERT(vam != NULL);
11981 ASSERT(eid_table != NULL);
11982
11983 if (ret) {
11984 *ret = 0;
11985 }
11986
11987 switch (eid_table->eid_type)
11988 {
11989 case 0:
11990 case 1:
11991 format_eid = (eid_table->eid_type ? format_ip6_address :
11992 format_ip4_address);
11993 str = format(0, "[%d] %U/%d",
11994 clib_net_to_host_u32 (eid_table->vni),
11995 format_eid, eid_table->eid, eid_table->eid_prefix_len);
11996 break;
11997 case 2:
11998 str = format(0, "[%d] %U",
11999 clib_net_to_host_u32 (eid_table->vni),
12000 format_ethernet_address, eid_table->eid);
12001 break;
12002 default:
12003 errmsg ("unknown EID type %d!", eid_table->eid_type);
12004 if (ret) {
12005 *ret = -99;
12006 }
12007 return 0;
12008 }
12009
12010 return str;
12011}
12012
12013static inline u8 *
12014format_locator_set_for_eid_table(vat_main_t * vam, u8 * str,
12015 eid_table_t * eid_table)
12016{
12017 locator_set_msg_t * ls = 0;
12018
12019 ASSERT(vam != NULL);
12020 ASSERT(eid_table != NULL);
12021
12022 if (eid_table->is_local) {
12023 vec_foreach (ls, vam->locator_set_msg) {
12024 if (ls->locator_set_index == eid_table->locator_set_index) {
12025 str = format(0, "local(%s)", ls->locator_set_name);
12026 return str;
12027 }
12028 }
12029
12030 str = format(0, "local(N/A)");
12031 } else {
12032 str = format(0, "remote");
12033 }
12034
12035 return str;
12036}
12037
12038static inline u8 *
12039format_locator_for_eid_table(vat_main_t * vam, u8 * str,
12040 eid_table_t * eid_table)
12041{
12042 locator_msg_t * loc = 0;
12043 int first_line = 1;
12044
12045 ASSERT(vam != NULL);
12046 ASSERT(eid_table != NULL);
12047
12048 vec_foreach(loc, vam->locator_msg) {
12049 if (!first_line) {
12050 if (loc->local) {
12051 str = format(str, "%-55s%-d\n", " ", loc->sw_if_index);
12052 } else {
12053 str = format(str, "%=55s%-U\n", " ",
12054 loc->is_ipv6 ? format_ip6_address :
12055 format_ip4_address,
12056 loc->ip_address);
12057 }
12058
12059 continue;
12060 }
12061
12062 if (loc->local) {
12063 str = format(str, "%-30d%-20u%-u\n", loc->sw_if_index,
12064 eid_table->ttl, eid_table->authoritative);
12065 } else {
12066 str = format(str, "%-30U%-20u%-u\n",
12067 loc->is_ipv6 ? format_ip6_address :
12068 format_ip4_address,
12069 loc->ip_address, eid_table->ttl,
12070 eid_table->authoritative);
12071 }
12072 first_line = 0;
12073 }
12074
12075 return str;
12076}
12077
12078static int
12079print_lisp_eid_table_dump(vat_main_t * vam)
12080{
12081 eid_table_t * eid_table = 0;
12082 u8 * tmp_str = 0, * tmp_str2 = 0;
12083 int ret = 0;
12084
12085 ASSERT(vam != NULL);
12086
12087 ret = get_locator_set(vam);
12088 if (ret) {
12089 vec_free(vam->eid_tables);
12090 return ret;
12091 }
12092
12093 fformat(vam->ofp, "%-35s%-20s%-30s%-20s%-s\n", "EID", "type", "locators",
12094 "ttl", "authoritative");
12095
12096 vec_foreach(eid_table, vam->eid_tables) {
12097 ret = lisp_locator_dump_send_msg(vam, eid_table->locator_set_index, 0);
12098 if (ret) {
12099 vec_free(vam->locator_msg);
12100 clean_locator_set_message(vam);
12101 vec_free(vam->eid_tables);
12102 return ret;
12103 }
12104
12105 tmp_str2 = format_eid_for_eid_table(vam, tmp_str2, eid_table, &ret);
12106 if (ret) {
12107 vec_free(vam->locator_msg);
12108 clean_locator_set_message(vam);
12109 vec_free(vam->eid_tables);
12110 return ret;
12111 }
12112
12113 tmp_str = format(0, "%-35s", tmp_str2);
12114 vec_free(tmp_str2);
12115
12116 tmp_str2 = format_locator_set_for_eid_table(vam, tmp_str2, eid_table);
12117 tmp_str = format(tmp_str, "%-20s", tmp_str2);
12118 vec_free(tmp_str2);
12119
12120 tmp_str2 = format_locator_for_eid_table(vam, tmp_str2, eid_table);
12121 tmp_str = format(tmp_str, "%-s", tmp_str2);
12122 vec_free(tmp_str2);
12123
12124 fformat(vam->ofp, "%s", tmp_str);
12125 vec_free(tmp_str);
12126 vec_free(vam->locator_msg);
12127 }
12128
12129 clean_locator_set_message(vam);
12130 vec_free(vam->eid_tables);
12131
12132 return ret;
12133}
12134
12135static inline void
12136json_locator_set_for_eid_table(vat_main_t * vam, vat_json_node_t * node,
12137 eid_table_t * eid_table)
12138{
12139 locator_set_msg_t * ls = 0;
12140 u8 * s = 0;
12141
12142 ASSERT(vam != NULL);
12143 ASSERT(node != NULL);
12144 ASSERT(eid_table != NULL);
12145
12146 if (eid_table->is_local) {
12147 vec_foreach (ls, vam->locator_set_msg) {
12148 if (ls->locator_set_index == eid_table->locator_set_index) {
12149 vat_json_object_add_string_copy(node, "locator-set",
12150 ls->locator_set_name);
12151 return;
12152 }
12153 }
12154
12155 s = format(0, "N/A");
12156 vec_add1(s, 0);
12157 vat_json_object_add_string_copy(node, "locator-set", s);
12158 vec_free(s);
12159 } else {
12160 s = format(0, "remote");
12161 vec_add1(s, 0);
12162 vat_json_object_add_string_copy(node, "locator-set", s);
12163 vec_free(s);
12164 }
12165}
12166
12167static inline int
12168json_eid_for_eid_table(vat_main_t * vam, vat_json_node_t * node,
12169 eid_table_t * eid_table)
12170{
12171 u8 * s = 0;
12172 struct in6_addr ip6;
12173 struct in_addr ip4;
12174
12175 ASSERT(vam != NULL);
12176 ASSERT(node != NULL);
12177 ASSERT(eid_table != NULL);
12178
12179 switch (eid_table->eid_type)
12180 {
12181 case 0:
12182 clib_memcpy(&ip4, eid_table->eid, sizeof(ip4));
12183 vat_json_object_add_ip4(node, "eid", ip4);
12184 vat_json_object_add_uint(node, "eid-prefix-len",
12185 eid_table->eid_prefix_len);
12186 break;
12187 case 1:
12188 clib_memcpy(&ip6, eid_table->eid, sizeof(ip6));
12189 vat_json_object_add_ip6(node, "eid", ip6);
12190 vat_json_object_add_uint(node, "eid-prefix-len",
12191 eid_table->eid_prefix_len);
12192 break;
12193 case 2:
12194 s = format (0, "%U", format_ethernet_address, eid_table->eid);
12195 vec_add1(s, 0);
12196 vat_json_object_add_string_copy(node, "eid", s);
12197 vec_free(s);
12198 break;
12199 default:
12200 errmsg ("unknown EID type %d!", eid_table->eid_type);
12201 return -99;
12202 }
12203
12204 return 0;
12205}
12206
12207static inline void
12208json_locator_for_eid_table(vat_main_t * vam, vat_json_node_t * node,
12209 eid_table_t * eid_table)
12210{
12211 locator_msg_t * loc = 0;
12212 vat_json_node_t * locator_array = 0;
12213 vat_json_node_t * locator = 0;
12214 struct in6_addr ip6;
12215 struct in_addr ip4;
12216
12217 ASSERT(vam != NULL);
12218 ASSERT(node != NULL);
12219 ASSERT(eid_table != NULL);
12220
12221 locator_array = vat_json_object_add_list(node, "locator");
12222 vec_foreach(loc, vam->locator_msg) {
12223 locator = vat_json_array_add(locator_array);
12224 vat_json_init_object(locator);
12225 if (loc->local) {
12226 vat_json_object_add_uint(locator, "locator-index",
12227 loc->sw_if_index);
12228 } else {
12229 if (loc->is_ipv6) {
12230 clib_memcpy(&ip6, loc->ip_address, sizeof(ip6));
12231 vat_json_object_add_ip6(locator, "locator", ip6);
12232 } else {
12233 clib_memcpy(&ip4, loc->ip_address, sizeof(ip4));
12234 vat_json_object_add_ip4(locator, "locator", ip4);
12235 }
12236 }
12237 }
12238}
12239
12240static int
12241json_lisp_eid_table_dump(vat_main_t * vam)
12242{
12243 eid_table_t * eid_table;
12244 vat_json_node_t * node = 0;
12245 int ret = 0;
12246
12247 ASSERT(vam != NULL);
12248
12249 ret = get_locator_set(vam);
12250 if (ret) {
12251 vec_free(vam->eid_tables);
12252 return ret;
12253 }
12254
12255 if (!vec_len(vam->eid_tables)) {
12256 /* just print [] */
12257 vat_json_init_array(&vam->json_tree);
12258 vat_json_print(vam->ofp, &vam->json_tree);
12259 vam->json_tree.type = VAT_JSON_NONE;
12260 return ret;
12261 }
12262
12263 if (VAT_JSON_ARRAY != vam->json_tree.type) {
12264 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
12265 vat_json_init_array(&vam->json_tree);
12266 }
12267
12268 vec_foreach(eid_table, vam->eid_tables) {
12269 ret = lisp_locator_dump_send_msg(vam, eid_table->locator_set_index, 0);
12270 if (ret) {
12271 vec_free(vam->locator_msg);
12272 vec_free(vam->eid_tables);
12273 clean_locator_set_message(vam);
12274 vat_json_free(&vam->json_tree);
12275 vam->json_tree.type = VAT_JSON_NONE;
12276 return ret;
12277 }
12278
12279 node = vat_json_array_add(&vam->json_tree);
12280 vat_json_init_object(node);
12281
12282 vat_json_object_add_uint(node, "vni", eid_table->vni);
12283
12284 json_locator_set_for_eid_table(vam, node, eid_table);
12285 ret = json_eid_for_eid_table(vam, node, eid_table);
12286 if (ret) {
12287 vec_free(vam->locator_msg);
12288 vec_free(vam->eid_tables);
12289 clean_locator_set_message(vam);
12290 vat_json_free(&vam->json_tree);
12291 vam->json_tree.type = VAT_JSON_NONE;
12292 return ret;
12293 }
12294
12295 json_locator_for_eid_table(vam, node, eid_table);
12296
12297 vat_json_object_add_uint(node, "ttl", eid_table->ttl);
12298 vat_json_object_add_uint(node, "authoritative",
12299 eid_table->authoritative);
12300
12301 vec_free(vam->locator_msg);
12302 }
12303
12304 vat_json_print(vam->ofp, &vam->json_tree);
12305 vat_json_free(&vam->json_tree);
12306 vam->json_tree.type = VAT_JSON_NONE;
12307
12308 clean_locator_set_message(vam);
12309 vec_free(vam->eid_tables);
12310
12311 return ret;
12312}
12313
12314static int
12315api_lisp_eid_table_dump(vat_main_t *vam)
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020012316{
Filip Tehlar1b1ee4f2016-07-04 11:43:11 +020012317 unformat_input_t * i = vam->input;
Andrej Kozemcak6cc6f912016-07-13 13:01:01 +020012318 vl_api_lisp_eid_table_dump_t *mp;
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020012319 f64 timeout = ~0;
Filip Tehlar1b1ee4f2016-07-04 11:43:11 +020012320 struct in_addr ip4;
12321 struct in6_addr ip6;
12322 u8 mac[6];
Andrej Kozemcakd9831182016-06-20 08:47:57 +020012323 u8 eid_type = ~0, eid_set = 0;
Filip Tehlar1b1ee4f2016-07-04 11:43:11 +020012324 u32 prefix_length = ~0, t, vni = 0;
Andrej Kozemcak6cc6f912016-07-13 13:01:01 +020012325 u8 filter = 0;
Filip Tehlar1b1ee4f2016-07-04 11:43:11 +020012326
12327 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
12328 if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t)) {
12329 eid_set = 1;
12330 eid_type = 0;
12331 prefix_length = t;
12332 } else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t)) {
12333 eid_set = 1;
12334 eid_type = 1;
12335 prefix_length = t;
12336 } else if (unformat (i, "eid %U", unformat_ethernet_address, mac)) {
12337 eid_set = 1;
12338 eid_type = 2;
Andrej Kozemcak6cc6f912016-07-13 13:01:01 +020012339 } else if (unformat (i, "vni %d", &t)) {
Filip Tehlar1b1ee4f2016-07-04 11:43:11 +020012340 vni = t;
Andrej Kozemcak6cc6f912016-07-13 13:01:01 +020012341 } else if (unformat (i, "local")) {
12342 filter = 1;
12343 } else if (unformat (i, "remote")) {
12344 filter = 2;
12345 } else {
Filip Tehlar1b1ee4f2016-07-04 11:43:11 +020012346 errmsg ("parse error '%U'", format_unformat_error, i);
12347 return -99;
12348 }
12349 }
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020012350
Andrej Kozemcak6cc6f912016-07-13 13:01:01 +020012351 M(LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020012352
Andrej Kozemcak6cc6f912016-07-13 13:01:01 +020012353 mp->filter = filter;
Filip Tehlar1b1ee4f2016-07-04 11:43:11 +020012354 if (eid_set) {
12355 mp->eid_set = 1;
12356 mp->vni = htonl (vni);
12357 mp->eid_type = eid_type;
12358 switch (eid_type) {
12359 case 0:
12360 mp->prefix_length = prefix_length;
12361 clib_memcpy (mp->eid, &ip4, sizeof (ip4));
12362 break;
12363 case 1:
12364 mp->prefix_length = prefix_length;
12365 clib_memcpy (mp->eid, &ip6, sizeof (ip6));
12366 break;
12367 case 2:
12368 clib_memcpy (mp->eid, mac, sizeof (mac));
12369 break;
12370 default:
12371 errmsg ("unknown EID type %d!", eid_type);
12372 return -99;
12373 }
12374 }
12375
Andrej Kozemcak6cc6f912016-07-13 13:01:01 +020012376 vam->noprint_msg = 1;
12377
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020012378 /* send it... */
12379 S;
12380
12381 /* Use a control ping for synchronization */
12382 {
Andrej Kozemcak6cc6f912016-07-13 13:01:01 +020012383 vl_api_noprint_control_ping_t * mp;
12384 M(NOPRINT_CONTROL_PING, noprint_control_ping);
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020012385 S;
12386 }
Andrej Kozemcak6cc6f912016-07-13 13:01:01 +020012387
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020012388 /* Wait for a reply... */
Andrej Kozemcak6cc6f912016-07-13 13:01:01 +020012389 W_L({
12390 if (vam->noprint_msg) {
12391 if (!vam->json_output) {
12392 vam->retval = print_lisp_eid_table_dump(vam);
12393 } else {
12394 vam->retval = json_lisp_eid_table_dump(vam);
12395 }
12396 }
12397
12398 vam->noprint_msg = 0;
12399 });
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020012400
12401 /* NOTREACHED */
12402 return 0;
12403}
12404
12405static int
12406api_lisp_gpe_tunnel_dump(vat_main_t *vam)
12407{
12408 vl_api_lisp_gpe_tunnel_dump_t *mp;
12409 f64 timeout = ~0;
12410
12411 if (!vam->json_output) {
12412 fformat(vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
12413 "%=16s%=16s%=16s%=16s%=16s\n",
12414 "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
12415 "Decap next", "Lisp version", "Flags", "Next protocol",
12416 "ver_res", "res", "iid");
12417 }
12418
12419 M(LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
12420 /* send it... */
12421 S;
12422
12423 /* Use a control ping for synchronization */
12424 {
12425 vl_api_control_ping_t * mp;
12426 M(CONTROL_PING, control_ping);
12427 S;
12428 }
12429 /* Wait for a reply... */
12430 W;
12431
12432 /* NOTREACHED */
12433 return 0;
12434}
12435
12436static int
12437api_lisp_map_resolver_dump(vat_main_t *vam)
12438{
12439 vl_api_lisp_map_resolver_dump_t *mp;
12440 f64 timeout = ~0;
12441
12442 if (!vam->json_output) {
12443 fformat(vam->ofp, "%=20s\n",
12444 "Map resolver");
12445 }
12446
12447 M(LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
12448 /* send it... */
12449 S;
12450
12451 /* Use a control ping for synchronization */
12452 {
12453 vl_api_control_ping_t * mp;
12454 M(CONTROL_PING, control_ping);
12455 S;
12456 }
12457 /* Wait for a reply... */
12458 W;
12459
12460 /* NOTREACHED */
12461 return 0;
12462}
12463
Andrej Kozemcaka9edd852016-05-02 12:14:33 +020012464static int
Andrej Kozemcakd9831182016-06-20 08:47:57 +020012465api_show_lisp_status(vat_main_t *vam)
Andrej Kozemcaka9edd852016-05-02 12:14:33 +020012466{
Andrej Kozemcakd9831182016-06-20 08:47:57 +020012467 vl_api_show_lisp_status_t *mp;
Andrej Kozemcaka9edd852016-05-02 12:14:33 +020012468 f64 timeout = ~0;
12469
12470 if (!vam->json_output) {
Andrej Kozemcak914f91b2016-07-18 13:55:37 +020012471 fformat(vam->ofp, "%-20s%-16s\n",
12472 "lisp status", "locator-set");
Andrej Kozemcaka9edd852016-05-02 12:14:33 +020012473 }
12474
Andrej Kozemcakd9831182016-06-20 08:47:57 +020012475 M(SHOW_LISP_STATUS, show_lisp_status);
Andrej Kozemcaka9edd852016-05-02 12:14:33 +020012476 /* send it... */
12477 S;
Andrej Kozemcaka9edd852016-05-02 12:14:33 +020012478 /* Wait for a reply... */
12479 W;
12480
12481 /* NOTREACHED */
12482 return 0;
12483}
12484
Matus Fabian8a95a482016-05-06 15:14:13 +020012485static int
Andrej Kozemcakb6e4d392016-06-14 13:55:57 +020012486api_lisp_get_map_request_itr_rlocs(vat_main_t *vam)
12487{
12488 vl_api_lisp_get_map_request_itr_rlocs_t *mp;
12489 f64 timeout = ~0;
12490
12491 if (!vam->json_output) {
12492 fformat(vam->ofp, "%=20s\n",
12493 "itr-rlocs:");
12494 }
12495
12496 M(LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
12497 /* send it... */
12498 S;
12499 /* Wait for a reply... */
12500 W;
12501
12502 /* NOTREACHED */
12503 return 0;
12504}
12505
12506static int
Matus Fabian8a95a482016-05-06 15:14:13 +020012507api_af_packet_create (vat_main_t * vam)
12508{
12509 unformat_input_t * i = vam->input;
12510 vl_api_af_packet_create_t * mp;
12511 f64 timeout;
12512 u8 * host_if_name = 0;
12513 u8 hw_addr[6];
12514 u8 random_hw_addr = 1;
12515
12516 memset (hw_addr, 0, sizeof (hw_addr));
12517
12518 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
12519 if (unformat (i, "name %s", &host_if_name))
12520 vec_add1 (host_if_name, 0);
12521 else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
12522 random_hw_addr = 0;
12523 else
12524 break;
12525 }
12526
12527 if (!vec_len (host_if_name)) {
12528 errmsg ("host-interface name must be specified");
12529 return -99;
12530 }
12531
12532 if (vec_len (host_if_name) > 64) {
12533 errmsg ("host-interface name too long");
12534 return -99;
12535 }
12536
12537 M(AF_PACKET_CREATE, af_packet_create);
12538
12539 clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
12540 clib_memcpy (mp->hw_addr, hw_addr, 6);
12541 mp->use_random_hw_addr = random_hw_addr;
12542 vec_free (host_if_name);
12543
Keith Burns (alagalah)802255c2016-06-13 16:56:04 -070012544 S; W2(fprintf(vam->ofp," new sw_if_index = %d ", vam->sw_if_index));
Matus Fabian8a95a482016-05-06 15:14:13 +020012545 /* NOTREACHED */
12546 return 0;
12547}
12548
12549static int
12550api_af_packet_delete (vat_main_t * vam)
12551{
12552 unformat_input_t * i = vam->input;
12553 vl_api_af_packet_delete_t * mp;
12554 f64 timeout;
12555 u8 * host_if_name = 0;
12556
12557 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
12558 if (unformat (i, "name %s", &host_if_name))
12559 vec_add1 (host_if_name, 0);
12560 else
12561 break;
12562 }
12563
12564 if (!vec_len (host_if_name)) {
12565 errmsg ("host-interface name must be specified");
12566 return -99;
12567 }
12568
12569 if (vec_len (host_if_name) > 64) {
12570 errmsg ("host-interface name too long");
12571 return -99;
12572 }
12573
12574 M(AF_PACKET_DELETE, af_packet_delete);
12575
12576 clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
12577 vec_free (host_if_name);
12578
12579 S; W;
12580 /* NOTREACHED */
12581 return 0;
12582}
12583
Matus Fabian65fcd4d2016-05-13 05:44:48 -070012584static int
12585api_policer_add_del (vat_main_t * vam)
12586{
12587 unformat_input_t * i = vam->input;
12588 vl_api_policer_add_del_t * mp;
12589 f64 timeout;
12590 u8 is_add = 1;
12591 u8 * name = 0;
12592 u32 cir = 0;
12593 u32 eir = 0;
12594 u64 cb = 0;
12595 u64 eb = 0;
12596 u8 rate_type = 0;
12597 u8 round_type = 0;
12598 u8 type = 0;
Matus Fabian70e6a8d2016-06-20 08:10:42 -070012599 u8 color_aware = 0;
Matus Fabian4ac74c92016-05-31 07:33:29 -070012600 sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
Matus Fabian65fcd4d2016-05-13 05:44:48 -070012601
12602 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
12603 if (unformat (i, "del"))
12604 is_add = 0;
12605 else if (unformat (i, "name %s", &name))
12606 vec_add1 (name, 0);
12607 else if (unformat (i, "cir %u", &cir))
12608 ;
12609 else if (unformat (i, "eir %u", &eir))
12610 ;
12611 else if (unformat (i, "cb %u", &cb))
12612 ;
12613 else if (unformat (i, "eb %u", &eb))
12614 ;
12615 else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
12616 &rate_type))
12617 ;
12618 else if (unformat (i, "round_type %U", unformat_policer_round_type,
12619 &round_type))
12620 ;
12621 else if (unformat (i, "type %U", unformat_policer_type, &type))
12622 ;
Matus Fabian4ac74c92016-05-31 07:33:29 -070012623 else if (unformat (i, "conform_action %U", unformat_policer_action_type,
12624 &conform_action))
12625 ;
12626 else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
12627 &exceed_action))
12628 ;
12629 else if (unformat (i, "violate_action %U", unformat_policer_action_type,
12630 &violate_action))
12631 ;
Matus Fabian70e6a8d2016-06-20 08:10:42 -070012632 else if (unformat (i, "color-aware"))
12633 color_aware = 1;
Matus Fabian65fcd4d2016-05-13 05:44:48 -070012634 else
12635 break;
12636 }
12637
12638 if (!vec_len (name)) {
12639 errmsg ("policer name must be specified");
12640 return -99;
12641 }
12642
12643 if (vec_len (name) > 64) {
12644 errmsg ("policer name too long");
12645 return -99;
12646 }
12647
12648 M(POLICER_ADD_DEL, policer_add_del);
12649
12650 clib_memcpy (mp->name, name, vec_len (name));
12651 vec_free (name);
12652 mp->is_add = is_add;
12653 mp->cir = cir;
12654 mp->eir = eir;
12655 mp->cb = cb;
12656 mp->eb = eb;
12657 mp->rate_type = rate_type;
12658 mp->round_type = round_type;
12659 mp->type = type;
Matus Fabian4ac74c92016-05-31 07:33:29 -070012660 mp->conform_action_type = conform_action.action_type;
12661 mp->conform_dscp = conform_action.dscp;
12662 mp->exceed_action_type = exceed_action.action_type;
12663 mp->exceed_dscp = exceed_action.dscp;
12664 mp->violate_action_type = violate_action.action_type;
12665 mp->violate_dscp = violate_action.dscp;
Matus Fabian70e6a8d2016-06-20 08:10:42 -070012666 mp->color_aware = color_aware;
Matus Fabian65fcd4d2016-05-13 05:44:48 -070012667
12668 S; W;
12669 /* NOTREACHED */
12670 return 0;
12671}
12672
Matus Fabian82e29c42016-05-11 04:49:46 -070012673static int
Matus Fabiane8554802016-05-18 23:40:37 -070012674api_policer_dump(vat_main_t *vam)
12675{
12676 unformat_input_t * i = vam->input;
12677 vl_api_policer_dump_t *mp;
12678 f64 timeout = ~0;
12679 u8 *match_name = 0;
12680 u8 match_name_valid = 0;
12681
12682 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
12683 if (unformat (i, "name %s", &match_name)) {
12684 vec_add1 (match_name, 0);
12685 match_name_valid = 1;
12686 } else
12687 break;
12688 }
12689
12690 M(POLICER_DUMP, policer_dump);
12691 mp->match_name_valid = match_name_valid;
12692 clib_memcpy (mp->match_name, match_name, vec_len (match_name));
12693 vec_free (match_name);
12694 /* send it... */
12695 S;
12696
12697 /* Use a control ping for synchronization */
12698 {
12699 vl_api_control_ping_t * mp;
12700 M(CONTROL_PING, control_ping);
12701 S;
12702 }
12703 /* Wait for a reply... */
12704 W;
12705
12706 /* NOTREACHED */
12707 return 0;
12708}
12709
12710static int
Matus Fabian70e6a8d2016-06-20 08:10:42 -070012711api_policer_classify_set_interface (vat_main_t * vam)
12712{
12713 unformat_input_t * i = vam->input;
12714 vl_api_policer_classify_set_interface_t *mp;
12715 f64 timeout;
12716 u32 sw_if_index;
12717 int sw_if_index_set;
12718 u32 ip4_table_index = ~0;
12719 u32 ip6_table_index = ~0;
12720 u32 l2_table_index = ~0;
12721 u8 is_add = 1;
12722
12723 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
12724 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
12725 sw_if_index_set = 1;
12726 else if (unformat (i, "sw_if_index %d", &sw_if_index))
12727 sw_if_index_set = 1;
12728 else if (unformat (i, "del"))
12729 is_add = 0;
12730 else if (unformat (i, "ip4-table %d", &ip4_table_index))
12731 ;
12732 else if (unformat (i, "ip6-table %d", &ip6_table_index))
12733 ;
12734 else if (unformat (i, "l2-table %d", &l2_table_index))
12735 ;
12736 else {
12737 clib_warning ("parse error '%U'", format_unformat_error, i);
12738 return -99;
12739 }
12740 }
12741
12742 if (sw_if_index_set == 0) {
12743 errmsg ("missing interface name or sw_if_index\n");
12744 return -99;
12745 }
12746
12747 M(POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
12748
12749 mp->sw_if_index = ntohl(sw_if_index);
12750 mp->ip4_table_index = ntohl(ip4_table_index);
12751 mp->ip6_table_index = ntohl(ip6_table_index);
12752 mp->l2_table_index = ntohl(l2_table_index);
12753 mp->is_add = is_add;
12754
12755 S; W;
12756 /* NOTREACHED */
12757 return 0;
12758}
12759
12760static int
12761api_policer_classify_dump(vat_main_t *vam)
12762{
12763 unformat_input_t * i = vam->input;
12764 vl_api_policer_classify_dump_t *mp;
12765 f64 timeout = ~0;
12766 u8 type = POLICER_CLASSIFY_N_TABLES;
12767
12768 if (unformat (i, "type %U", unformat_classify_table_type, &type))
12769 ;
12770 else {
12771 errmsg ("classify table type must be specified\n");
12772 return -99;
12773 }
12774
12775 if (!vam->json_output) {
12776 fformat(vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
12777 }
12778
12779 M(POLICER_CLASSIFY_DUMP, policer_classify_dump);
12780 mp->type = type;
12781 /* send it... */
12782 S;
12783
12784 /* Use a control ping for synchronization */
12785 {
12786 vl_api_control_ping_t * mp;
12787 M(CONTROL_PING, control_ping);
12788 S;
12789 }
12790 /* Wait for a reply... */
12791 W;
12792
12793 /* NOTREACHED */
12794 return 0;
12795}
12796
12797static int
Matus Fabian82e29c42016-05-11 04:49:46 -070012798api_netmap_create (vat_main_t * vam)
12799{
12800 unformat_input_t * i = vam->input;
12801 vl_api_netmap_create_t * mp;
12802 f64 timeout;
12803 u8 * if_name = 0;
12804 u8 hw_addr[6];
12805 u8 random_hw_addr = 1;
12806 u8 is_pipe = 0;
12807 u8 is_master = 0;
12808
12809 memset (hw_addr, 0, sizeof (hw_addr));
12810
12811 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
12812 if (unformat (i, "name %s", &if_name))
12813 vec_add1 (if_name, 0);
12814 else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
12815 random_hw_addr = 0;
12816 else if (unformat (i, "pipe"))
12817 is_pipe = 1;
12818 else if (unformat (i, "master"))
12819 is_master = 1;
12820 else if (unformat (i, "slave"))
12821 is_master = 0;
12822 else
12823 break;
12824 }
12825
12826 if (!vec_len (if_name)) {
12827 errmsg ("interface name must be specified");
12828 return -99;
12829 }
12830
12831 if (vec_len (if_name) > 64) {
12832 errmsg ("interface name too long");
12833 return -99;
12834 }
12835
12836 M(NETMAP_CREATE, netmap_create);
12837
Dave Barach6f7b9922016-05-20 14:43:57 -040012838 clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
Matus Fabian82e29c42016-05-11 04:49:46 -070012839 clib_memcpy (mp->hw_addr, hw_addr, 6);
12840 mp->use_random_hw_addr = random_hw_addr;
12841 mp->is_pipe = is_pipe;
12842 mp->is_master = is_master;
12843 vec_free (if_name);
12844
12845 S; W;
12846 /* NOTREACHED */
12847 return 0;
12848}
12849
12850static int
12851api_netmap_delete (vat_main_t * vam)
12852{
12853 unformat_input_t * i = vam->input;
12854 vl_api_netmap_delete_t * mp;
12855 f64 timeout;
12856 u8 * if_name = 0;
12857
12858 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
12859 if (unformat (i, "name %s", &if_name))
12860 vec_add1 (if_name, 0);
12861 else
12862 break;
12863 }
12864
12865 if (!vec_len (if_name)) {
12866 errmsg ("interface name must be specified");
12867 return -99;
12868 }
12869
12870 if (vec_len (if_name) > 64) {
12871 errmsg ("interface name too long");
12872 return -99;
12873 }
12874
12875 M(NETMAP_DELETE, netmap_delete);
12876
Dave Barach6f7b9922016-05-20 14:43:57 -040012877 clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
Matus Fabian82e29c42016-05-11 04:49:46 -070012878 vec_free (if_name);
12879
12880 S; W;
12881 /* NOTREACHED */
12882 return 0;
12883}
12884
marek zavodsky2c21a9a2016-06-21 05:35:16 +020012885static void vl_api_mpls_gre_tunnel_details_t_handler
12886(vl_api_mpls_gre_tunnel_details_t * mp)
12887{
12888 vat_main_t * vam = &vat_main;
12889 i32 i;
12890 i32 len = ntohl(mp->nlabels);
12891
12892 if (mp->l2_only == 0) {
12893 fformat(vam->ofp, "[%d]: src %U, dst %U, adj %U/%d, labels ",
12894 ntohl(mp->tunnel_index),
12895 format_ip4_address, &mp->tunnel_src,
12896 format_ip4_address, &mp->tunnel_dst,
12897 format_ip4_address, &mp->intfc_address,
12898 ntohl(mp->mask_width));
12899 for (i = 0; i < len; i++) {
12900 fformat(vam->ofp, "%u ", ntohl(mp->labels[i]));
12901 }
12902 fformat(vam->ofp, "\n");
12903 fformat(vam->ofp, " inner fib index %d, outer fib index %d\n",
12904 ntohl(mp->inner_fib_index), ntohl(mp->outer_fib_index));
12905 } else {
12906 fformat(vam->ofp, "[%d]: src %U, dst %U, key %U, labels ",
12907 ntohl(mp->tunnel_index),
12908 format_ip4_address, &mp->tunnel_src,
12909 format_ip4_address, &mp->tunnel_dst,
12910 format_ip4_address, &mp->intfc_address);
12911 for (i = 0; i < len; i++) {
12912 fformat(vam->ofp, "%u ", ntohl(mp->labels[i]));
12913 }
12914 fformat(vam->ofp, "\n");
12915 fformat(vam->ofp, " l2 interface %d, outer fib index %d\n",
12916 ntohl(mp->hw_if_index), ntohl(mp->outer_fib_index));
12917 }
12918}
12919
12920static void vl_api_mpls_gre_tunnel_details_t_handler_json
12921(vl_api_mpls_gre_tunnel_details_t * mp)
12922{
12923 vat_main_t * vam = &vat_main;
12924 vat_json_node_t *node = NULL;
12925 struct in_addr ip4;
12926 i32 i;
12927 i32 len = ntohl(mp->nlabels);
12928
12929 if (VAT_JSON_ARRAY != vam->json_tree.type) {
12930 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
12931 vat_json_init_array(&vam->json_tree);
12932 }
12933 node = vat_json_array_add(&vam->json_tree);
12934
12935 vat_json_init_object(node);
12936 vat_json_object_add_uint(node, "tunnel_index", ntohl(mp->tunnel_index));
12937 clib_memcpy(&ip4, &(mp->intfc_address), sizeof(ip4));
12938 vat_json_object_add_ip4(node, "intfc_address", ip4);
12939 vat_json_object_add_uint(node, "inner_fib_index", ntohl(mp->inner_fib_index));
12940 vat_json_object_add_uint(node, "mask_width", ntohl(mp->mask_width));
12941 vat_json_object_add_uint(node, "encap_index", ntohl(mp->encap_index));
12942 vat_json_object_add_uint(node, "hw_if_index", ntohl(mp->hw_if_index));
12943 vat_json_object_add_uint(node, "l2_only", ntohl(mp->l2_only));
12944 clib_memcpy(&ip4, &(mp->tunnel_src), sizeof(ip4));
12945 vat_json_object_add_ip4(node, "tunnel_src", ip4);
12946 clib_memcpy(&ip4, &(mp->tunnel_dst), sizeof(ip4));
12947 vat_json_object_add_ip4(node, "tunnel_dst", ip4);
12948 vat_json_object_add_uint(node, "outer_fib_index", ntohl(mp->outer_fib_index));
12949 vat_json_object_add_uint(node, "label_count", len);
12950 for (i = 0; i < len; i++) {
12951 vat_json_object_add_uint(node, "label", ntohl(mp->labels[i]));
12952 }
12953}
12954
12955static int api_mpls_gre_tunnel_dump (vat_main_t * vam)
12956{
12957 vl_api_mpls_gre_tunnel_dump_t *mp;
12958 f64 timeout;
12959 i32 index = -1;
12960
12961 /* Parse args required to build the message */
12962 while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT) {
12963 if (!unformat (vam->input, "tunnel_index %d", &index)) {
12964 index = -1;
12965 break;
12966 }
12967 }
12968
12969 fformat(vam->ofp, " tunnel_index %d\n", index);
12970
12971 M(MPLS_GRE_TUNNEL_DUMP, mpls_gre_tunnel_dump);
12972 mp->tunnel_index = htonl(index);
12973 S;
12974
12975 /* Use a control ping for synchronization */
12976 {
12977 vl_api_control_ping_t * mp;
12978 M(CONTROL_PING, control_ping);
12979 S;
12980 }
12981 W;
12982}
12983
12984static void vl_api_mpls_eth_tunnel_details_t_handler
12985(vl_api_mpls_eth_tunnel_details_t * mp)
12986{
12987 vat_main_t * vam = &vat_main;
12988 i32 i;
12989 i32 len = ntohl(mp->nlabels);
12990
12991 fformat(vam->ofp, "[%d]: dst %U, adj %U/%d, labels ",
12992 ntohl(mp->tunnel_index),
12993 format_ethernet_address, &mp->tunnel_dst_mac,
12994 format_ip4_address, &mp->intfc_address,
12995 ntohl(mp->mask_width));
12996 for (i = 0; i < len; i++) {
12997 fformat(vam->ofp, "%u ", ntohl(mp->labels[i]));
12998 }
12999 fformat(vam->ofp, "\n");
13000 fformat(vam->ofp, " tx on %d, rx fib index %d\n",
13001 ntohl(mp->tx_sw_if_index),
13002 ntohl(mp->inner_fib_index));
13003}
13004
13005static void vl_api_mpls_eth_tunnel_details_t_handler_json
13006(vl_api_mpls_eth_tunnel_details_t * mp)
13007{
13008 vat_main_t * vam = &vat_main;
13009 vat_json_node_t *node = NULL;
13010 struct in_addr ip4;
13011 i32 i;
13012 i32 len = ntohl(mp->nlabels);
13013
13014 if (VAT_JSON_ARRAY != vam->json_tree.type) {
13015 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
13016 vat_json_init_array(&vam->json_tree);
13017 }
13018 node = vat_json_array_add(&vam->json_tree);
13019
13020 vat_json_init_object(node);
13021 vat_json_object_add_uint(node, "tunnel_index", ntohl(mp->tunnel_index));
13022 clib_memcpy(&ip4, &(mp->intfc_address), sizeof(ip4));
13023 vat_json_object_add_ip4(node, "intfc_address", ip4);
13024 vat_json_object_add_uint(node, "inner_fib_index", ntohl(mp->inner_fib_index));
13025 vat_json_object_add_uint(node, "mask_width", ntohl(mp->mask_width));
13026 vat_json_object_add_uint(node, "encap_index", ntohl(mp->encap_index));
13027 vat_json_object_add_uint(node, "hw_if_index", ntohl(mp->hw_if_index));
13028 vat_json_object_add_uint(node, "l2_only", ntohl(mp->l2_only));
13029 vat_json_object_add_string_copy(node, "tunnel_dst_mac",
13030 format(0, "%U", format_ethernet_address, &mp->tunnel_dst_mac));
13031 vat_json_object_add_uint(node, "tx_sw_if_index", ntohl(mp->tx_sw_if_index));
13032 vat_json_object_add_uint(node, "label_count", len);
13033 for (i = 0; i < len; i++) {
13034 vat_json_object_add_uint(node, "label", ntohl(mp->labels[i]));
13035 }
13036}
13037
13038static int api_mpls_eth_tunnel_dump (vat_main_t * vam)
13039{
13040 vl_api_mpls_eth_tunnel_dump_t *mp;
13041 f64 timeout;
13042 i32 index = -1;
13043
13044 /* Parse args required to build the message */
13045 while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT) {
13046 if (!unformat (vam->input, "tunnel_index %d", &index)) {
13047 index = -1;
13048 break;
13049 }
13050 }
13051
13052 fformat(vam->ofp, " tunnel_index %d\n", index);
13053
13054 M(MPLS_ETH_TUNNEL_DUMP, mpls_eth_tunnel_dump);
13055 mp->tunnel_index = htonl(index);
13056 S;
13057
13058 /* Use a control ping for synchronization */
13059 {
13060 vl_api_control_ping_t * mp;
13061 M(CONTROL_PING, control_ping);
13062 S;
13063 }
13064 W;
13065}
13066
13067static void vl_api_mpls_fib_encap_details_t_handler
13068(vl_api_mpls_fib_encap_details_t * mp)
13069{
13070 vat_main_t * vam = &vat_main;
13071 i32 i;
13072 i32 len = ntohl(mp->nlabels);
13073
13074 fformat(vam->ofp, "table %d, dest %U, label ",
13075 ntohl(mp->fib_index),
13076 format_ip4_address, &mp->dest,
13077 len);
13078 for (i = 0; i < len; i++) {
13079 fformat(vam->ofp, "%u ", ntohl(mp->labels[i]));
13080 }
13081 fformat(vam->ofp, "\n");
13082}
13083
13084static void vl_api_mpls_fib_encap_details_t_handler_json
13085(vl_api_mpls_fib_encap_details_t * mp)
13086{
13087 vat_main_t * vam = &vat_main;
13088 vat_json_node_t *node = NULL;
13089 i32 i;
13090 i32 len = ntohl(mp->nlabels);
13091 struct in_addr ip4;
13092
13093 if (VAT_JSON_ARRAY != vam->json_tree.type) {
13094 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
13095 vat_json_init_array(&vam->json_tree);
13096 }
13097 node = vat_json_array_add(&vam->json_tree);
13098
13099 vat_json_init_object(node);
13100 vat_json_object_add_uint(node, "table", ntohl(mp->fib_index));
13101 vat_json_object_add_uint(node, "entry_index", ntohl(mp->entry_index));
13102 clib_memcpy(&ip4, &(mp->dest), sizeof(ip4));
13103 vat_json_object_add_ip4(node, "dest", ip4);
13104 vat_json_object_add_uint(node, "s_bit", ntohl(mp->s_bit));
13105 vat_json_object_add_uint(node, "label_count", len);
13106 for (i = 0; i < len; i++) {
13107 vat_json_object_add_uint(node, "label", ntohl(mp->labels[i]));
13108 }
13109}
13110
13111static int api_mpls_fib_encap_dump (vat_main_t * vam)
13112{
13113 vl_api_mpls_fib_encap_dump_t *mp;
13114 f64 timeout;
13115
13116 M(MPLS_FIB_ENCAP_DUMP, mpls_fib_encap_dump);
13117 S;
13118
13119 /* Use a control ping for synchronization */
13120 {
13121 vl_api_control_ping_t * mp;
13122 M(CONTROL_PING, control_ping);
13123 S;
13124 }
13125 W;
13126}
13127
13128static void vl_api_mpls_fib_decap_details_t_handler
13129(vl_api_mpls_fib_decap_details_t * mp)
13130{
13131 vat_main_t * vam = &vat_main;
13132
13133 fformat(vam->ofp, "RX table %d, TX table/intfc %u, swif_tag '%s', label %u, s_bit %u\n",
13134 ntohl(mp->rx_table_id),
13135 ntohl(mp->tx_table_id),
13136 mp->swif_tag,
13137 ntohl(mp->label),
13138 ntohl(mp->s_bit));
13139}
13140
13141static void vl_api_mpls_fib_decap_details_t_handler_json
13142(vl_api_mpls_fib_decap_details_t * mp)
13143{
13144 vat_main_t * vam = &vat_main;
13145 vat_json_node_t *node = NULL;
13146 struct in_addr ip4;
13147
13148 if (VAT_JSON_ARRAY != vam->json_tree.type) {
13149 ASSERT(VAT_JSON_NONE == vam->json_tree.type);
13150 vat_json_init_array(&vam->json_tree);
13151 }
13152 node = vat_json_array_add(&vam->json_tree);
13153
13154 vat_json_init_object(node);
13155 vat_json_object_add_uint(node, "table", ntohl(mp->fib_index));
13156 vat_json_object_add_uint(node, "entry_index", ntohl(mp->entry_index));
13157 clib_memcpy(&ip4, &(mp->dest), sizeof(ip4));
13158 vat_json_object_add_ip4(node, "dest", ip4);
13159 vat_json_object_add_uint(node, "s_bit", ntohl(mp->s_bit));
13160 vat_json_object_add_uint(node, "label", ntohl(mp->label));
13161 vat_json_object_add_uint(node, "rx_table_id", ntohl(mp->rx_table_id));
13162 vat_json_object_add_uint(node, "tx_table_id", ntohl(mp->tx_table_id));
13163 vat_json_object_add_string_copy(node, "swif_tag", mp->swif_tag);
13164}
13165
13166static int api_mpls_fib_decap_dump (vat_main_t * vam)
13167{
13168 vl_api_mpls_fib_decap_dump_t *mp;
13169 f64 timeout;
13170
13171 M(MPLS_FIB_DECAP_DUMP, mpls_fib_decap_dump);
13172 S;
13173
13174 /* Use a control ping for synchronization */
13175 {
13176 vl_api_control_ping_t * mp;
13177 M(CONTROL_PING, control_ping);
13178 S;
13179 }
13180 W;
13181}
13182
Pavel Kotucek20c90f72016-06-07 14:44:26 +020013183int api_classify_table_ids (vat_main_t *vam)
13184{
13185 vl_api_classify_table_ids_t *mp;
13186 f64 timeout;
13187
13188 /* Construct the API message */
13189 M(CLASSIFY_TABLE_IDS, classify_table_ids);
13190 mp->context = 0;
13191
13192 S; W;
13193 /* NOTREACHED */
13194 return 0;
13195}
13196
13197int api_classify_table_by_interface (vat_main_t *vam)
13198{
13199 unformat_input_t * input = vam->input;
13200 vl_api_classify_table_by_interface_t *mp;
13201 f64 timeout;
13202
13203 u32 sw_if_index = ~0;
13204 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
13205 if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
13206 ;
13207 else if (unformat (input, "sw_if_index %d", &sw_if_index))
13208 ;
13209 else
13210 break;
13211 }
13212 if (sw_if_index == ~0) {
13213 errmsg ("missing interface name or sw_if_index\n");
13214 return -99;
13215 }
13216
13217 /* Construct the API message */
13218 M(CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
13219 mp->context = 0;
13220 mp->sw_if_index = ntohl(sw_if_index);
13221
13222 S; W;
13223 /* NOTREACHED */
13224 return 0;
13225}
13226
13227int api_classify_table_info (vat_main_t *vam)
13228{
13229 unformat_input_t * input = vam->input;
13230 vl_api_classify_table_info_t *mp;
13231 f64 timeout;
13232
13233 u32 table_id = ~0;
13234 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
13235 if (unformat (input, "table_id %d", &table_id))
13236 ;
13237 else
13238 break;
13239 }
13240 if (table_id == ~0) {
13241 errmsg ("missing table id\n");
13242 return -99;
13243 }
13244
13245 /* Construct the API message */
13246 M(CLASSIFY_TABLE_INFO, classify_table_info);
13247 mp->context = 0;
13248 mp->table_id = ntohl(table_id);
13249
13250 S; W;
13251 /* NOTREACHED */
13252 return 0;
13253}
13254
13255int api_classify_session_dump (vat_main_t *vam)
13256{
13257 unformat_input_t * input = vam->input;
13258 vl_api_classify_session_dump_t *mp;
13259 f64 timeout;
13260
13261 u32 table_id = ~0;
13262 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
13263 if (unformat (input, "table_id %d", &table_id))
13264 ;
13265 else
13266 break;
13267 }
13268 if (table_id == ~0) {
13269 errmsg ("missing table id\n");
13270 return -99;
13271 }
13272
13273 /* Construct the API message */
13274 M(CLASSIFY_SESSION_DUMP, classify_session_dump);
13275 mp->context = 0;
13276 mp->table_id = ntohl(table_id);
13277 S;
13278
13279 /* Use a control ping for synchronization */
13280 {
13281 vl_api_control_ping_t * mp;
13282 M(CONTROL_PING, control_ping);
13283 S;
13284 }
13285 W;
13286 /* NOTREACHED */
13287 return 0;
13288}
13289
Juraj Slobodaac645ad2016-07-07 00:18:57 -070013290static void vl_api_ipfix_details_t_handler (vl_api_ipfix_details_t * mp)
13291{
13292 vat_main_t * vam = &vat_main;
13293
13294 fformat(vam->ofp, "collector_address %U, collector_port %d, "
13295 "src_address %U, fib_index %u, path_mtu %u, "
13296 "template_interval %u\n",
13297 format_ip4_address, mp->collector_address,
13298 ntohs(mp->collector_port),
13299 format_ip4_address, mp->src_address,
13300 ntohl(mp->fib_index),
13301 ntohl(mp->path_mtu),
13302 ntohl(mp->template_interval));
13303
13304 vam->retval = 0;
13305 vam->result_ready = 1;
13306}
13307
13308static void vl_api_ipfix_details_t_handler_json
13309(vl_api_ipfix_details_t * mp)
13310{
13311 vat_main_t * vam = &vat_main;
13312 vat_json_node_t node;
13313 struct in_addr collector_address;
13314 struct in_addr src_address;
13315
13316 vat_json_init_object(&node);
13317 clib_memcpy(&collector_address, &mp->collector_address,
13318 sizeof(collector_address));
13319 vat_json_object_add_ip4(&node, "collector_address", collector_address);
13320 vat_json_object_add_uint(&node, "collector_port",
13321 ntohs(mp->collector_port));
13322 clib_memcpy(&src_address, &mp->src_address, sizeof(src_address));
13323 vat_json_object_add_ip4(&node, "src_address", src_address);
13324 vat_json_object_add_uint(&node, "fib_index", ntohl(mp->fib_index));
13325 vat_json_object_add_uint(&node, "path_mtu", ntohl(mp->path_mtu));
13326 vat_json_object_add_uint(&node, "template_interval",
13327 ntohl(mp->template_interval));
13328
13329 vat_json_print(vam->ofp, &node);
13330 vat_json_free(&node);
13331 vam->retval = 0;
13332 vam->result_ready = 1;
13333}
13334
13335int api_ipfix_dump (vat_main_t *vam)
13336{
13337 vl_api_ipfix_dump_t *mp;
13338 f64 timeout;
13339
13340 /* Construct the API message */
13341 M(IPFIX_DUMP, ipfix_dump);
13342 mp->context = 0;
13343
13344 S; W;
13345 /* NOTREACHED */
13346 return 0;
13347}
13348
Pavel Kotucek9e6ed6e2016-07-12 10:18:26 +020013349int api_pg_create_interface (vat_main_t *vam)
13350{
13351 unformat_input_t * input = vam->input;
13352 vl_api_pg_create_interface_t *mp;
13353 f64 timeout;
13354
13355 u32 if_id = ~0;
13356 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
13357 if (unformat (input, "if_id %d", &if_id))
13358 ;
13359 else
13360 break;
13361 }
13362 if (if_id == ~0) {
13363 errmsg ("missing pg interface index\n");
13364 return -99;
13365 }
13366
13367 /* Construct the API message */
13368 M(PG_CREATE_INTERFACE, pg_create_interface);
13369 mp->context = 0;
13370 mp->interface_id = ntohl(if_id);
13371
13372 S; W;
13373 /* NOTREACHED */
13374 return 0;
13375}
13376
13377int api_pg_capture (vat_main_t *vam)
13378{
13379 unformat_input_t * input = vam->input;
13380 vl_api_pg_capture_t *mp;
13381 f64 timeout;
13382
13383 u32 if_id = ~0;
13384 u8 enable = 1;
13385 u32 count = 1;
13386 u8 pcap_file_set = 0;
13387 u8 * pcap_file = 0;
13388 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
13389 if (unformat (input, "if_id %d", &if_id))
13390 ;
13391 else if (unformat (input, "pcap %s", &pcap_file))
13392 pcap_file_set = 1;
13393 else if (unformat (input, "count %d", &count))
13394 ;
13395 else if (unformat (input, "disable"))
13396 enable = 0;
13397 else
13398 break;
13399 }
13400 if (if_id == ~0) {
13401 errmsg ("missing pg interface index\n");
13402 return -99;
13403 }
13404 if (pcap_file_set>0) {
13405 if (vec_len (pcap_file) > 255) {
13406 errmsg ("pcap file name is too long\n");
13407 return -99;
13408 }
13409 }
13410
13411 u32 name_len = vec_len(pcap_file);
13412 /* Construct the API message */
13413 M(PG_CAPTURE, pg_capture);
13414 mp->context = 0;
13415 mp->interface_id = ntohl(if_id);
13416 mp->is_enabled = enable;
13417 mp->count = ntohl(count);
13418 mp->pcap_name_length = ntohl(name_len);
13419 if (pcap_file_set != 0) {
13420 clib_memcpy(mp->pcap_file_name, pcap_file, name_len);
13421 }
13422 vec_free(pcap_file);
13423
13424 S; W;
13425 /* NOTREACHED */
13426 return 0;
13427}
13428
13429int api_pg_enable_disable (vat_main_t *vam)
13430{
13431 unformat_input_t * input = vam->input;
13432 vl_api_pg_enable_disable_t *mp;
13433 f64 timeout;
13434
13435 u8 enable = 1;
13436 u8 stream_name_set = 0;
13437 u8 * stream_name = 0;
13438 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
13439 if (unformat (input, "stream %s", &stream_name))
13440 stream_name_set = 1;
13441 else if (unformat (input, "disable"))
13442 enable = 0;
13443 else
13444 break;
13445 }
13446
13447 if (stream_name_set>0) {
13448 if (vec_len (stream_name) > 255) {
13449 errmsg ("stream name too long\n");
13450 return -99;
13451 }
13452 }
13453
13454 u32 name_len = vec_len(stream_name);
13455 /* Construct the API message */
13456 M(PG_ENABLE_DISABLE, pg_enable_disable);
13457 mp->context = 0;
13458 mp->is_enabled = enable;
13459 if (stream_name_set != 0) {
13460 mp->stream_name_length = ntohl(name_len);
13461 clib_memcpy(mp->stream_name, stream_name, name_len);
13462 }
13463 vec_free(stream_name);
13464
13465 S; W;
13466 /* NOTREACHED */
13467 return 0;
13468}
13469
Ed Warnickecb9cada2015-12-08 15:45:58 -070013470static int q_or_quit (vat_main_t * vam)
13471{
13472 longjmp (vam->jump_buf, 1);
13473 return 0; /* not so much */
13474}
13475static int q (vat_main_t * vam) {return q_or_quit (vam);}
13476static int quit (vat_main_t * vam) {return q_or_quit (vam);}
13477
13478static int comment (vat_main_t * vam)
13479{
13480 return 0;
13481}
13482
Matus Fabiand2dc3df2015-12-14 10:31:33 -050013483static int cmd_cmp (void * a1, void * a2)
13484{
13485 u8 ** c1 = a1;
13486 u8 ** c2 = a2;
13487
13488 return strcmp ((char *)(c1[0]), (char *)(c2[0]));
13489}
13490
Ed Warnickecb9cada2015-12-08 15:45:58 -070013491static int help (vat_main_t * vam)
13492{
13493 u8 ** cmds = 0;
13494 u8 * name = 0;
13495 hash_pair_t * p;
13496 unformat_input_t * i = vam->input;
13497 int j;
13498
13499 if (unformat (i, "%s", &name)) {
13500 uword *hs;
13501
13502 vec_add1(name, 0);
13503
13504 hs = hash_get_mem (vam->help_by_name, name);
13505 if (hs)
13506 fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
13507 else
13508 fformat (vam->ofp, "No such msg / command '%s'\n", name);
13509 vec_free(name);
13510 return 0;
13511 }
13512
13513 fformat(vam->ofp, "Help is available for the following:\n");
13514
Hongjun Ni11bfc2f2016-07-22 18:19:19 +080013515 hash_foreach_pair (p, vam->function_by_name,
Ed Warnickecb9cada2015-12-08 15:45:58 -070013516 ({
13517 vec_add1 (cmds, (u8 *)(p->key));
13518 }));
13519
Matus Fabiand2dc3df2015-12-14 10:31:33 -050013520 vec_sort_with_function (cmds, cmd_cmp);
Ed Warnickecb9cada2015-12-08 15:45:58 -070013521
13522 for (j = 0; j < vec_len(cmds); j++)
13523 fformat (vam->ofp, "%s\n", cmds[j]);
13524
13525 vec_free (cmds);
13526 return 0;
13527}
13528
13529static int set (vat_main_t * vam)
13530{
13531 u8 * name = 0, * value = 0;
13532 unformat_input_t * i = vam->input;
13533
13534 if (unformat (i, "%s", &name)) {
13535 /* The input buffer is a vector, not a string. */
13536 value = vec_dup (i->buffer);
13537 vec_delete (value, i->index, 0);
13538 /* Almost certainly has a trailing newline */
13539 if (value[vec_len(value)-1] == '\n')
13540 value[vec_len(value)-1] = 0;
13541 /* Make sure it's a proper string, one way or the other */
13542 vec_add1 (value, 0);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +080013543 (void) clib_macro_set_value (&vam->macro_main,
Ed Warnickecb9cada2015-12-08 15:45:58 -070013544 (char *)name, (char *)value);
13545 }
13546 else
13547 errmsg ("usage: set <name> <value>\n");
13548
13549 vec_free (name);
13550 vec_free (value);
13551 return 0;
13552}
13553
13554static int unset (vat_main_t * vam)
13555{
13556 u8 * name = 0;
13557
13558 if (unformat (vam->input, "%s", &name))
13559 if (clib_macro_unset (&vam->macro_main, (char *)name) == 1)
13560 errmsg ("unset: %s wasn't set\n", name);
13561 vec_free (name);
13562 return 0;
13563}
13564
13565typedef struct {
13566 u8 * name;
13567 u8 * value;
13568} macro_sort_t;
13569
13570
Matus Fabiand2dc3df2015-12-14 10:31:33 -050013571static int macro_sort_cmp (void * a1, void * a2)
13572{
13573 macro_sort_t * s1 = a1;
13574 macro_sort_t * s2 = a2;
13575
13576 return strcmp ((char *)(s1->name), (char *)(s2->name));
13577}
13578
Ed Warnickecb9cada2015-12-08 15:45:58 -070013579static int dump_macro_table (vat_main_t * vam)
13580{
Hongjun Ni11bfc2f2016-07-22 18:19:19 +080013581 macro_sort_t * sort_me = 0, * sm;
Ed Warnickecb9cada2015-12-08 15:45:58 -070013582 int i;
13583 hash_pair_t * p;
13584
Hongjun Ni11bfc2f2016-07-22 18:19:19 +080013585 hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
Ed Warnickecb9cada2015-12-08 15:45:58 -070013586 ({
13587 vec_add2 (sort_me, sm, 1);
13588 sm->name = (u8 *)(p->key);
13589 sm->value = (u8 *) (p->value[0]);
13590 }));
Hongjun Ni11bfc2f2016-07-22 18:19:19 +080013591
Matus Fabiand2dc3df2015-12-14 10:31:33 -050013592 vec_sort_with_function (sort_me, macro_sort_cmp);
Ed Warnickecb9cada2015-12-08 15:45:58 -070013593
13594 if (vec_len(sort_me))
13595 fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
13596 else
13597 fformat (vam->ofp, "The macro table is empty...\n");
13598
13599 for (i = 0; i < vec_len (sort_me); i++)
13600 fformat (vam->ofp, "%-15s%s\n", sort_me[i].name,
13601 sort_me[i].value);
13602 return 0;
13603}
13604
Dave Barachb44e9bc2016-02-19 09:06:23 -050013605static int dump_node_table (vat_main_t * vam)
13606{
13607 int i, j;
13608 vlib_node_t * node, * next_node;
13609
13610 if (vec_len (vam->graph_nodes) == 0) {
13611 fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
13612 return 0;
13613 }
13614
13615 for (i = 0; i < vec_len (vam->graph_nodes); i++) {
13616 node = vam->graph_nodes[i];
13617 fformat (vam->ofp, "[%d] %s\n", i, node->name);
13618 for (j = 0; j < vec_len (node->next_nodes); j++) {
13619 if (node->next_nodes[j] != ~0) {
13620 next_node = vam->graph_nodes[node->next_nodes[j]];
13621 fformat (vam->ofp, " [%d] %s\n", j, next_node->name);
13622 }
13623 }
13624 }
13625 return 0;
13626}
13627
13628static int search_node_table (vat_main_t * vam)
13629{
13630 unformat_input_t * line_input = vam->input;
13631 u8 * node_to_find;
13632 int j;
13633 vlib_node_t * node, * next_node;
13634 uword * p;
13635
13636 if (vam->graph_node_index_by_name == 0) {
13637 fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
13638 return 0;
13639 }
13640
13641 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
13642 if (unformat (line_input, "%s", &node_to_find)) {
13643 vec_add1 (node_to_find, 0);
13644 p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
13645 if (p == 0) {
13646 fformat (vam->ofp, "%s not found...\n", node_to_find);
13647 goto out;
13648 }
13649 node = vam->graph_nodes[p[0]];
13650 fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
13651 for (j = 0; j < vec_len (node->next_nodes); j++) {
13652 if (node->next_nodes[j] != ~0) {
13653 next_node = vam->graph_nodes[node->next_nodes[j]];
13654 fformat (vam->ofp, " [%d] %s\n", j, next_node->name);
13655 }
13656 }
13657 }
Hongjun Ni11bfc2f2016-07-22 18:19:19 +080013658
Dave Barachb44e9bc2016-02-19 09:06:23 -050013659 else {
Hongjun Ni11bfc2f2016-07-22 18:19:19 +080013660 clib_warning ("parse error '%U'", format_unformat_error,
Dave Barachb44e9bc2016-02-19 09:06:23 -050013661 line_input);
13662 return -99;
13663 }
13664
13665 out:
13666 vec_free(node_to_find);
Hongjun Ni11bfc2f2016-07-22 18:19:19 +080013667
Dave Barachb44e9bc2016-02-19 09:06:23 -050013668 }
13669
Hongjun Ni11bfc2f2016-07-22 18:19:19 +080013670 return 0;
Dave Barachb44e9bc2016-02-19 09:06:23 -050013671}
13672
13673
Ed Warnickecb9cada2015-12-08 15:45:58 -070013674static int script (vat_main_t * vam)
13675{
13676 u8 * s = 0;
13677 char * save_current_file;
13678 unformat_input_t save_input;
13679 jmp_buf save_jump_buf;
13680 u32 save_line_number;
13681
13682 FILE * new_fp, * save_ifp;
13683
13684 if (unformat (vam->input, "%s", &s)) {
13685 new_fp = fopen ((char *)s, "r");
13686 if (new_fp == 0) {
13687 errmsg ("Couldn't open script file %s\n", s);
13688 vec_free (s);
13689 return -99;
13690 }
13691 } else {
13692 errmsg ("Missing script name\n");
13693 return -99;
13694 }
13695
Damjan Marionf1213b82016-03-13 02:22:06 +010013696 clib_memcpy (&save_input, &vam->input, sizeof (save_input));
13697 clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
Ed Warnickecb9cada2015-12-08 15:45:58 -070013698 save_ifp = vam->ifp;
13699 save_line_number = vam->input_line_number;
13700 save_current_file = (char *) vam->current_file;
13701
13702 vam->input_line_number = 0;
13703 vam->ifp = new_fp;
13704 vam->current_file = s;
13705 do_one_file (vam);
13706
Damjan Marionf1213b82016-03-13 02:22:06 +010013707 clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
13708 clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
Ed Warnickecb9cada2015-12-08 15:45:58 -070013709 vam->ifp = save_ifp;
13710 vam->input_line_number = save_line_number;
13711 vam->current_file = (u8 *) save_current_file;
13712 vec_free (s);
13713
13714 return 0;
13715}
13716
13717static int echo (vat_main_t * vam)
13718{
13719 fformat (vam->ofp, "%v", vam->input->buffer);
13720 return 0;
13721}
13722
13723/* List of API message constructors, CLI names map to api_xxx */
13724#define foreach_vpe_api_msg \
13725_(create_loopback,"[mac <mac-addr>]") \
13726_(sw_interface_dump,"") \
13727_(sw_interface_set_flags, \
13728 "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
13729_(sw_interface_add_del_address, \
13730 "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
13731_(sw_interface_set_table, \
13732 "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]") \
13733_(sw_interface_set_vpath, \
13734 "<intfc> | sw_if_index <id> enable | disable") \
13735_(sw_interface_set_l2_xconnect, \
13736 "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
13737 "enable | disable") \
13738_(sw_interface_set_l2_bridge, \
13739 "rx <intfc> | rx_sw_if_index <id> bd_id <bridge-domain-id>\n" \
13740 "[shg <split-horizon-group>] [bvi]\n" \
13741 "enable | disable") \
13742_(bridge_domain_add_del, \
13743 "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
13744_(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n") \
13745_(l2fib_add_del, \
Dave Barach41da02d2016-07-11 16:48:42 -070013746 "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 -070013747_(l2_flags, \
13748 "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
13749_(bridge_flags, \
13750 "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
13751_(tap_connect, \
13752 "tapname <name> mac <mac-addr> | random-mac") \
13753_(tap_modify, \
13754 "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
13755_(tap_delete, \
13756 "<vpp-if-name> | sw_if_index <id>") \
13757_(sw_interface_tap_dump, "") \
13758_(ip_add_del_route, \
13759 "<addr>/<mask> via <addr> [vrf <n>]\n" \
13760 "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n" \
13761 "[weight <n>] [drop] [local] [classify <n>] [del]\n" \
13762 "[multipath] [count <n>]") \
13763_(proxy_arp_add_del, \
13764 "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]") \
13765_(proxy_arp_intfc_enable_disable, \
13766 "<intfc> | sw_if_index <id> enable | disable") \
13767_(mpls_add_del_encap, \
13768 "label <n> dst <ip4-addr> [vrf <n>] [del]") \
13769_(mpls_add_del_decap, \
13770 "label <n> [rx_vrf_id <n>] [tx_vrf_id] [s-bit-clear][del]") \
13771_(mpls_gre_add_del_tunnel, \
13772 "inner_vrf_id <n> outer_vrf_id <n> src <ip4-address> dst <ip4-address>\n" \
13773 "adj <ip4-address>/<mask-width> [del]") \
13774_(sw_interface_set_unnumbered, \
13775 "<intfc> | sw_if_index <id> unnum_if_index <id> [del]") \
13776_(ip_neighbor_add_del, \
Chris Luke49a69632016-07-08 10:34:00 -040013777 "(<intfc> | sw_if_index <id>) dst <ip46-address> " \
13778 "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]") \
Ed Warnickecb9cada2015-12-08 15:45:58 -070013779_(reset_vrf, "vrf <id> [ipv6]") \
13780_(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>") \
13781_(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n" \
13782 "[outer_vlan_id <n>][inner_vlan_id <n>]\n" \
13783 "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n" \
13784 "[outer_vlan_id_any][inner_vlan_id_any]") \
13785_(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]") \
13786_(reset_fib, "vrf <n> [ipv6]") \
13787_(dhcp_proxy_config, \
13788 "svr <v46-address> src <v46-address>\n" \
13789 "insert-cid <n> [del]") \
13790_(dhcp_proxy_config_2, \
13791 "svr <v46-address> src <v46-address>\n" \
13792 "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]") \
13793_(dhcp_proxy_set_vss, \
13794 "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]") \
13795_(dhcp_client_config, \
13796 "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
13797_(set_ip_flow_hash, \
13798 "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]") \
13799_(sw_interface_ip6_enable_disable, \
13800 "<intfc> | sw_if_index <id> enable | disable") \
13801_(sw_interface_ip6_set_link_local_address, \
13802 "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>") \
13803_(sw_interface_ip6nd_ra_prefix, \
13804 "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n" \
13805 "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n" \
13806 "[nolink] [isno]") \
13807_(sw_interface_ip6nd_ra_config, \
13808 "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n" \
Chris Luke33879c92016-06-28 19:54:21 -040013809 "[life <n>] [count <n>] [interval <n>] [suppress]\n" \
Ed Warnickecb9cada2015-12-08 15:45:58 -070013810 "[managed] [other] [ll] [send] [cease] [isno] [def]") \
13811_(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]") \
13812_(l2_patch_add_del, \
13813 "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
13814 "enable | disable") \
13815_(mpls_ethernet_add_del_tunnel, \
13816 "tx <intfc> | tx_sw_if_index <n> dst <mac-addr>\n" \
13817 "adj <ip4-addr>/<mw> dst <mac-addr> [del]") \
13818_(mpls_ethernet_add_del_tunnel_2, \
13819 "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n" \
13820 "resolve-attempts <n> resolve-if-needed 0 | 1 [del]") \
13821_(sr_tunnel_add_del, \
Keith Burns (alagalah)52fc44d2016-03-25 09:38:50 -070013822 "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n" \
13823 "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n" \
13824 "[policy <policy_name>]") \
13825_(sr_policy_add_del, \
13826 "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]") \
13827_(sr_multicast_map_add_del, \
13828 "address [ip6 multicast address] sr-policy [policy name] [del]") \
Ed Warnickecb9cada2015-12-08 15:45:58 -070013829_(classify_add_del_table, \
13830 "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n" \
13831 "[del] mask <mask-value>\n" \
13832 " [l2-miss-next | miss-next | acl-miss-next] <name|nn>") \
13833_(classify_add_del_session, \
Matus Fabian70e6a8d2016-06-20 08:10:42 -070013834 "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n" \
13835 " table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n" \
13836 " [l3 [ip4|ip6]]") \
Ed Warnickecb9cada2015-12-08 15:45:58 -070013837_(classify_set_interface_ip_table, \
13838 "<intfc> | sw_if_index <nn> table <nn>") \
13839_(classify_set_interface_l2_tables, \
13840 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
13841 " [other-table <nn>]") \
13842_(get_node_index, "node <node-name") \
13843_(add_node_next, "node <node-name> next <next-node-name>") \
13844_(l2tpv3_create_tunnel, \
13845 "client_address <ip6-addr> our_address <ip6-addr>\n" \
13846 "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
13847 "[remote_cookie <nn>]\n[l2-sublayer-preset]\n") \
13848_(l2tpv3_set_tunnel_cookies, \
13849 "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n" \
13850 "[new_remote_cookie <nn>]\n") \
13851_(l2tpv3_interface_enable_disable, \
13852 "<intfc> | sw_if_index <nn> enable | disable") \
13853_(l2tpv3_set_lookup_key, \
13854 "lookup_v6_src | lookup_v6_dst | lookup_session_id") \
13855_(sw_if_l2tpv3_tunnel_dump, "") \
13856_(vxlan_add_del_tunnel, \
Chris Luke404be662016-05-27 12:11:24 -040013857 "src <ip-addr> dst <ip-addr> vni <vni> [encap-vrf-id <nn>]\n" \
Ed Warnickecb9cada2015-12-08 15:45:58 -070013858 " [decap-next l2|ip4|ip6] [del]") \
Dave Wallace60231f32015-12-17 21:04:30 -050013859_(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
Chris Luke27fe48f2016-04-28 13:44:38 -040013860_(gre_add_del_tunnel, \
13861 "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [del]\n") \
13862_(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
Ed Warnickecb9cada2015-12-08 15:45:58 -070013863_(l2_fib_clear_table, "") \
13864_(l2_interface_efp_filter, "sw_if_index <nn> enable | disable") \
13865_(l2_interface_vlan_tag_rewrite, \
13866 "<intfc> | sw_if_index <nn> \n" \
13867 "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n" \
13868 "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>") \
13869_(create_vhost_user_if, \
Pierre Pfisteref65cb02016-02-19 13:52:44 +000013870 "socket <filename> [server] [renumber <dev_instance>] " \
13871 "[mac <mac_address>]") \
Ed Warnickecb9cada2015-12-08 15:45:58 -070013872_(modify_vhost_user_if, \
13873 "<intfc> | sw_if_index <nn> socket <filename>\n" \
13874 "[server] [renumber <dev_instance>]") \
13875_(delete_vhost_user_if, "<intfc> | sw_if_index <nn>") \
13876_(sw_interface_vhost_user_dump, "") \
13877_(show_version, "") \
Hongjun Ni0e06e2b2016-05-30 19:45:51 +080013878_(vxlan_gpe_add_del_tunnel, \
13879 "local <addr> remote <addr> vni <nn>\n" \
13880 "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]" \
13881 "[next-ethernet] [next-nsh]\n") \
13882_(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
Ed Warnickecb9cada2015-12-08 15:45:58 -070013883_(l2_fib_table_dump, "bd_id <bridge-domain-id>") \
Ed Warnickecb9cada2015-12-08 15:45:58 -070013884_(interface_name_renumber, \
13885 "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>") \
13886_(input_acl_set_interface, \
13887 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
13888 " [l2-table <nn>] [del]") \
13889_(want_ip4_arp_events, "address <ip4-address> [del]") \
13890_(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)") \
13891_(ip_dump, "ipv4 | ipv6") \
13892_(ipsec_spd_add_del, "spd_id <n> [del]") \
13893_(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n" \
13894 " spid_id <n> ") \
13895_(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n" \
13896 " crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n" \
13897 " integ_alg <alg> integ_key <hex>") \
13898_(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n" \
13899 " (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n" \
13900 " laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
13901 " [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
13902_(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>") \
Matus Fabiane5f42fe2016-04-08 11:18:08 +020013903_(ikev2_profile_add_del, "name <profile_name> [del]") \
13904_(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n" \
13905 "(auth_data 0x<data> | auth_data <data>)") \
13906_(ikev2_profile_set_id, "name <profile_name> id_type <type>\n" \
13907 "(id_data 0x<data> | id_data <data>) (local|remote)") \
13908_(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n" \
13909 "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
13910 "(local|remote)") \
13911_(ikev2_set_local_key, "file <absolute_file_path>") \
Ed Warnickecb9cada2015-12-08 15:45:58 -070013912_(delete_loopback,"sw_if_index <nn>") \
13913_(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
13914_(map_add_domain, \
13915 "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> " \
13916 "ip6-src <ip6addr> " \
13917 "ea-bits-len <n> psid-offset <n> psid-len <n>") \
13918_(map_del_domain, "index <n>") \
13919_(map_add_del_rule, \
13920 "index <n> psid <n> dst <ip6addr> [del]") \
13921_(map_domain_dump, "") \
13922_(map_rule_dump, "index <map-domain>") \
13923_(want_interface_events, "enable|disable") \
13924_(want_stats,"enable|disable") \
Dave Barachc07bf5d2016-02-17 17:52:26 -050013925_(get_first_msg_id, "client <name>") \
13926_(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
13927_(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n" \
Dave Barachb44e9bc2016-02-19 09:06:23 -050013928 "fib-id <nn> [ip4][ip6][default]") \
Pavel Kotucek00bbf272016-03-03 13:27:11 +010013929_(get_node_graph, " ") \
Shwetha20a64f52016-03-25 10:55:01 +000013930_(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>") \
13931_(trace_profile_add, "id <nn> trace-type <0x1f|0x3|0x9|0x11|0x19> " \
13932 "trace-elts <nn> trace-tsp <0|1|2|3> node-id <node id in hex> " \
13933 "app-data <app_data in hex> [pow] [ppc <encap|decap>]") \
13934_(trace_profile_apply, "id <nn> <ip6-address>/<width>" \
13935 " vrf_id <nn> add | pop | none") \
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020013936_(trace_profile_del, "") \
Andrej Kozemcaka8691752016-07-27 10:33:38 +020013937_(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
13938 " sw_if_index <sw_if_index> p <priority> " \
13939 "w <weight>] [del]") \
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020013940_(lisp_add_del_locator, "locator-set <locator_name> " \
13941 "iface <intf> | sw_if_index <sw_if_index> " \
13942 "p <priority> w <weight> [del]") \
Andrej Kozemcakd9831182016-06-20 08:47:57 +020013943_(lisp_add_del_local_eid,"vni <vni> eid " \
13944 "<ipv4|ipv6>/<prefix> | <L2 address> " \
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020013945 "locator-set <locator_name> [del]") \
13946_(lisp_gpe_add_del_fwd_entry, "eid <ip4|6-addr>/<prefix> " \
13947 "sloc <ip4/6-addr> dloc <ip4|6-addr> [del]") \
13948_(lisp_add_del_map_resolver, "<ip4|6-addr> [del]") \
Florin Coras577c3552016-04-21 00:45:40 +020013949_(lisp_gpe_enable_disable, "enable|disable") \
Filip Tehlar46d4e362016-05-09 09:39:26 +020013950_(lisp_enable_disable, "enable|disable") \
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020013951_(lisp_gpe_add_del_iface, "up|down") \
Andrej Kozemcak438109d2016-07-22 12:54:12 +020013952_(lisp_add_del_remote_mapping, "add|del vni <vni> deid <dest-eid> " \
13953 "rloc <locator> p <prio> " \
Filip Tehlar4d5cabd2016-07-07 15:40:36 +020013954 "w <weight> [rloc <loc> ... ] " \
Andrej Kozemcak438109d2016-07-22 12:54:12 +020013955 "action <action> [del-all]") \
Filip Tehlar4d5cabd2016-07-07 15:40:36 +020013956_(lisp_add_del_adjacency, "add|del vni <vni> deid <dest-eid> seid " \
13957 "<src-eid> rloc <locator> p <prio> w <weight>"\
13958 "[rloc <loc> ... ] action <action>") \
Filip Tehlar53f09e32016-05-19 14:25:44 +020013959_(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del") \
Andrej Kozemcakb6e4d392016-06-14 13:55:57 +020013960_(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]") \
Filip Tehlar324112f2016-06-02 16:07:38 +020013961_(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>") \
Andrej Kozemcakd9831182016-06-20 08:47:57 +020013962_(lisp_locator_set_dump, "[locator-set-index <ls-index> | " \
13963 "locator-set <loc-set-name>] [local | remote]")\
Andrej Kozemcak6cc6f912016-07-13 13:01:01 +020013964_(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] " \
13965 "[local] | [remote]") \
Filip Tehlar2f653d02016-07-13 13:17:15 +020013966_(lisp_eid_table_map_dump, "") \
Andrej Kozemcakb92feb62016-03-31 13:51:42 +020013967_(lisp_gpe_tunnel_dump, "") \
Andrej Kozemcaka9edd852016-05-02 12:14:33 +020013968_(lisp_map_resolver_dump, "") \
Andrej Kozemcakd9831182016-06-20 08:47:57 +020013969_(show_lisp_status, "") \
Andrej Kozemcakb6e4d392016-06-14 13:55:57 +020013970_(lisp_get_map_request_itr_rlocs, "") \
Andrej Kozemcak914f91b2016-07-18 13:55:37 +020013971_(show_lisp_pitr, "") \
Matus Fabian8a95a482016-05-06 15:14:13 +020013972_(af_packet_create, "name <host interface name> [hw_addr <mac>]") \
Matus Fabian65fcd4d2016-05-13 05:44:48 -070013973_(af_packet_delete, "name <host interface name>") \
Matus Fabian82e29c42016-05-11 04:49:46 -070013974_(policer_add_del, "name <policer name> <params> [del]") \
Matus Fabiane8554802016-05-18 23:40:37 -070013975_(policer_dump, "[name <policer name>]") \
Matus Fabian70e6a8d2016-06-20 08:10:42 -070013976_(policer_classify_set_interface, \
13977 "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n" \
13978 " [l2-table <nn>] [del]") \
13979_(policer_classify_dump, "type [ip4|ip6|l2]") \
Matus Fabian82e29c42016-05-11 04:49:46 -070013980_(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] " \
13981 "[master|slave]") \
marek zavodsky2c21a9a2016-06-21 05:35:16 +020013982_(netmap_delete, "name <interface name>") \
13983_(mpls_gre_tunnel_dump, "tunnel_index <tunnel-id>") \
13984_(mpls_eth_tunnel_dump, "tunnel_index <tunnel-id>") \
13985_(mpls_fib_encap_dump, "") \
Pavel Kotucek20c90f72016-06-07 14:44:26 +020013986_(mpls_fib_decap_dump, "") \
13987_(classify_table_ids, "") \
13988_(classify_table_by_interface, "sw_if_index <sw_if_index>") \
13989_(classify_table_info, "table_id <nn>") \
Juraj Slobodaac645ad2016-07-07 00:18:57 -070013990_(classify_session_dump, "table_id <nn>") \
13991_(ipfix_enable, "collector_address <ip4> [collector_port <nn>] " \
13992 "src_address <ip4> [fib_id <nn>] [path_mtu <nn>] " \
13993 "[template_interval <nn>]") \
Keith Burns (alagalah)c61080e2016-07-19 14:47:43 -070013994_(ipfix_dump, "") \
Pavel Kotucek9e6ed6e2016-07-12 10:18:26 +020013995_(get_next_index, "node-name <node-name> next-node-name <node-name>") \
13996_(pg_create_interface, "if_id <nn>") \
13997_(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]") \
13998_(pg_enable_disable, "[stream <id>] disable")
Ed Warnickecb9cada2015-12-08 15:45:58 -070013999
14000/* List of command functions, CLI names map directly to functions */
14001#define foreach_cli_function \
14002_(comment, "usage: comment <ignore-rest-of-line>") \
14003_(dump_interface_table, "usage: dump_interface_table") \
14004_(dump_sub_interface_table, "usage: dump_sub_interface_table") \
14005_(dump_ipv4_table, "usage: dump_ipv4_table") \
14006_(dump_ipv6_table, "usage: dump_ipv6_table") \
14007_(dump_stats_table, "usage: dump_stats_table") \
14008_(dump_macro_table, "usage: dump_macro_table ") \
Dave Barachb44e9bc2016-02-19 09:06:23 -050014009_(dump_node_table, "usage: dump_node_table") \
Ed Warnickecb9cada2015-12-08 15:45:58 -070014010_(echo, "usage: echo <message>") \
14011_(exec, "usage: exec <vpe-debug-CLI-command>") \
14012_(help, "usage: help") \
14013_(q, "usage: quit") \
14014_(quit, "usage: quit") \
Dave Barachb44e9bc2016-02-19 09:06:23 -050014015_(search_node_table, "usage: search_node_table <name>...") \
Ed Warnickecb9cada2015-12-08 15:45:58 -070014016_(set, "usage: set <variable-name> <value>") \
14017_(script, "usage: script <file-name>") \
14018_(unset, "usage: unset <variable-name>")
14019
14020#define _(N,n) \
14021 static void vl_api_##n##_t_handler_uni \
14022 (vl_api_##n##_t * mp) \
14023 { \
14024 vat_main_t * vam = &vat_main; \
14025 if (vam->json_output) { \
14026 vl_api_##n##_t_handler_json(mp); \
14027 } else { \
14028 vl_api_##n##_t_handler(mp); \
14029 } \
14030 }
14031foreach_vpe_api_reply_msg;
14032#undef _
14033
14034void vat_api_hookup (vat_main_t *vam)
14035{
14036#define _(N,n) \
14037 vl_msg_api_set_handlers(VL_API_##N, #n, \
14038 vl_api_##n##_t_handler_uni, \
14039 vl_noop_handler, \
14040 vl_api_##n##_t_endian, \
14041 vl_api_##n##_t_print, \
Hongjun Ni11bfc2f2016-07-22 18:19:19 +080014042 sizeof(vl_api_##n##_t), 1);
Ed Warnickecb9cada2015-12-08 15:45:58 -070014043 foreach_vpe_api_reply_msg;
14044#undef _
14045
14046 vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
14047
Hongjun Ni11bfc2f2016-07-22 18:19:19 +080014048 vam->sw_if_index_by_interface_name =
Ed Warnickecb9cada2015-12-08 15:45:58 -070014049 hash_create_string (0, sizeof (uword));
14050
Hongjun Ni11bfc2f2016-07-22 18:19:19 +080014051 vam->function_by_name =
Ed Warnickecb9cada2015-12-08 15:45:58 -070014052 hash_create_string (0, sizeof(uword));
14053
Hongjun Ni11bfc2f2016-07-22 18:19:19 +080014054 vam->help_by_name =
Ed Warnickecb9cada2015-12-08 15:45:58 -070014055 hash_create_string (0, sizeof(uword));
14056
14057 /* API messages we can send */
14058#define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
14059 foreach_vpe_api_msg;
14060#undef _
14061
14062 /* Help strings */
14063#define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
14064 foreach_vpe_api_msg;
14065#undef _
14066
14067 /* CLI functions */
14068#define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
14069 foreach_cli_function;
14070#undef _
14071
14072 /* Help strings */
14073#define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
14074 foreach_cli_function;
14075#undef _
14076}
14077
14078#undef vl_api_version
14079#define vl_api_version(n,v) static u32 vpe_api_version = v;
Dave Barachaa6920e2016-06-27 09:25:13 -040014080#include <vpp-api/vpe.api.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070014081#undef vl_api_version
14082
Hongjun Ni11bfc2f2016-07-22 18:19:19 +080014083void vl_client_add_api_signatures (vl_api_memclnt_create_t *mp)
Ed Warnickecb9cada2015-12-08 15:45:58 -070014084{
Hongjun Ni11bfc2f2016-07-22 18:19:19 +080014085 /*
Ed Warnickecb9cada2015-12-08 15:45:58 -070014086 * Send the main API signature in slot 0. This bit of code must
14087 * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
14088 */
14089 mp->api_versions[0] = clib_host_to_net_u32 (vpe_api_version);
14090}