binary-api debug CLI works with plugins
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23 #include <vlibsocket/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/sr/sr_packet.h>
26 #include <vnet/l2/l2_input.h>
27 #include <vnet/l2tp/l2tp.h>
28 #include <vnet/vxlan/vxlan.h>
29 #include <vnet/gre/gre.h>
30 #include <vnet/vxlan-gpe/vxlan_gpe.h>
31 #include <vnet/lisp-gpe/lisp_gpe.h>
32
33 #include <vpp/api/vpe_msg_enum.h>
34 #include <vnet/l2/l2_classify.h>
35 #include <vnet/l2/l2_vtr.h>
36 #include <vnet/classify/input_acl.h>
37 #include <vnet/classify/policer_classify.h>
38 #include <vnet/classify/flow_classify.h>
39 #include <vnet/mpls/mpls.h>
40 #include <vnet/ipsec/ipsec.h>
41 #include <vnet/ipsec/ikev2.h>
42 #include <inttypes.h>
43 #include <vnet/map/map.h>
44 #include <vnet/cop/cop.h>
45 #include <vnet/ip/ip6_hop_by_hop.h>
46 #include <vnet/ip/ip_source_and_port_range_check.h>
47 #include <vnet/policer/xlate.h>
48 #include <vnet/span/span.h>
49 #include <vnet/policer/policer.h>
50 #include <vnet/policer/police.h>
51
52 #include "vat/json_format.h"
53
54 #include <inttypes.h>
55 #include <sys/stat.h>
56
57 #define vl_typedefs             /* define message structures */
58 #include <vpp/api/vpe_all_api_h.h>
59 #undef vl_typedefs
60
61 /* declare message handlers for each api */
62
63 #define vl_endianfun            /* define message structures */
64 #include <vpp/api/vpe_all_api_h.h>
65 #undef vl_endianfun
66
67 /* instantiate all the print functions we know about */
68 #define vl_print(handle, ...)
69 #define vl_printfun
70 #include <vpp/api/vpe_all_api_h.h>
71 #undef vl_printfun
72
73 #include <vlibapi/vat_helper_macros.h>
74
75 f64
76 vat_time_now (vat_main_t * vam)
77 {
78 #if VPP_API_TEST_BUILTIN
79   return vlib_time_now (vam->vlib_main);
80 #else
81   return clib_time_now (&vam->clib_time);
82 #endif
83 }
84
85 void
86 errmsg (char *fmt, ...)
87 {
88   vat_main_t *vam = &vat_main;
89   va_list va;
90   u8 *s;
91
92   va_start (va, fmt);
93   s = va_format (0, fmt, &va);
94   va_end (va);
95
96   vec_add1 (s, 0);
97
98 #if VPP_API_TEST_BUILTIN
99   vlib_cli_output (vam->vlib_main, (char *) s);
100 #else
101   {
102     if (vam->ifp != stdin)
103       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
104                vam->input_line_number);
105     fformat (vam->ofp, (char *) s);
106     fflush (vam->ofp);
107   }
108 #endif
109
110   vec_free (s);
111 }
112
113 static uword
114 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
115 {
116   vat_main_t *vam = va_arg (*args, vat_main_t *);
117   u32 *result = va_arg (*args, u32 *);
118   u8 *if_name;
119   uword *p;
120
121   if (!unformat (input, "%s", &if_name))
122     return 0;
123
124   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
125   if (p == 0)
126     return 0;
127   *result = p[0];
128   return 1;
129 }
130
131 #if VPP_API_TEST_BUILTIN == 0
132 /* Parse an IP4 address %d.%d.%d.%d. */
133 uword
134 unformat_ip4_address (unformat_input_t * input, va_list * args)
135 {
136   u8 *result = va_arg (*args, u8 *);
137   unsigned a[4];
138
139   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
140     return 0;
141
142   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
143     return 0;
144
145   result[0] = a[0];
146   result[1] = a[1];
147   result[2] = a[2];
148   result[3] = a[3];
149
150   return 1;
151 }
152
153 uword
154 unformat_ethernet_address (unformat_input_t * input, va_list * args)
155 {
156   u8 *result = va_arg (*args, u8 *);
157   u32 i, a[6];
158
159   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
160                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
161     return 0;
162
163   /* Check range. */
164   for (i = 0; i < 6; i++)
165     if (a[i] >= (1 << 8))
166       return 0;
167
168   for (i = 0; i < 6; i++)
169     result[i] = a[i];
170
171   return 1;
172 }
173
174 /* Returns ethernet type as an int in host byte order. */
175 uword
176 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
177                                         va_list * args)
178 {
179   u16 *result = va_arg (*args, u16 *);
180   int type;
181
182   /* Numeric type. */
183   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
184     {
185       if (type >= (1 << 16))
186         return 0;
187       *result = type;
188       return 1;
189     }
190   return 0;
191 }
192
193 /* Parse an IP6 address. */
194 uword
195 unformat_ip6_address (unformat_input_t * input, va_list * args)
196 {
197   ip6_address_t *result = va_arg (*args, ip6_address_t *);
198   u16 hex_quads[8];
199   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
200   uword c, n_colon, double_colon_index;
201
202   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
203   double_colon_index = ARRAY_LEN (hex_quads);
204   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
205     {
206       hex_digit = 16;
207       if (c >= '0' && c <= '9')
208         hex_digit = c - '0';
209       else if (c >= 'a' && c <= 'f')
210         hex_digit = c + 10 - 'a';
211       else if (c >= 'A' && c <= 'F')
212         hex_digit = c + 10 - 'A';
213       else if (c == ':' && n_colon < 2)
214         n_colon++;
215       else
216         {
217           unformat_put_input (input);
218           break;
219         }
220
221       /* Too many hex quads. */
222       if (n_hex_quads >= ARRAY_LEN (hex_quads))
223         return 0;
224
225       if (hex_digit < 16)
226         {
227           hex_quad = (hex_quad << 4) | hex_digit;
228
229           /* Hex quad must fit in 16 bits. */
230           if (n_hex_digits >= 4)
231             return 0;
232
233           n_colon = 0;
234           n_hex_digits++;
235         }
236
237       /* Save position of :: */
238       if (n_colon == 2)
239         {
240           /* More than one :: ? */
241           if (double_colon_index < ARRAY_LEN (hex_quads))
242             return 0;
243           double_colon_index = n_hex_quads;
244         }
245
246       if (n_colon > 0 && n_hex_digits > 0)
247         {
248           hex_quads[n_hex_quads++] = hex_quad;
249           hex_quad = 0;
250           n_hex_digits = 0;
251         }
252     }
253
254   if (n_hex_digits > 0)
255     hex_quads[n_hex_quads++] = hex_quad;
256
257   {
258     word i;
259
260     /* Expand :: to appropriate number of zero hex quads. */
261     if (double_colon_index < ARRAY_LEN (hex_quads))
262       {
263         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
264
265         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
266           hex_quads[n_zero + i] = hex_quads[i];
267
268         for (i = 0; i < n_zero; i++)
269           hex_quads[double_colon_index + i] = 0;
270
271         n_hex_quads = ARRAY_LEN (hex_quads);
272       }
273
274     /* Too few hex quads given. */
275     if (n_hex_quads < ARRAY_LEN (hex_quads))
276       return 0;
277
278     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
279       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
280
281     return 1;
282   }
283 }
284
285 uword
286 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
287 {
288   u32 *r = va_arg (*args, u32 *);
289
290   if (0);
291 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
292   foreach_ipsec_policy_action
293 #undef _
294     else
295     return 0;
296   return 1;
297 }
298
299 uword
300 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
301 {
302   u32 *r = va_arg (*args, u32 *);
303
304   if (0);
305 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
306   foreach_ipsec_crypto_alg
307 #undef _
308     else
309     return 0;
310   return 1;
311 }
312
313 u8 *
314 format_ipsec_crypto_alg (u8 * s, va_list * args)
315 {
316   u32 i = va_arg (*args, u32);
317   u8 *t = 0;
318
319   switch (i)
320     {
321 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
322       foreach_ipsec_crypto_alg
323 #undef _
324     default:
325       return format (s, "unknown");
326     }
327   return format (s, "%s", t);
328 }
329
330 uword
331 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
332 {
333   u32 *r = va_arg (*args, u32 *);
334
335   if (0);
336 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
337   foreach_ipsec_integ_alg
338 #undef _
339     else
340     return 0;
341   return 1;
342 }
343
344 u8 *
345 format_ipsec_integ_alg (u8 * s, va_list * args)
346 {
347   u32 i = va_arg (*args, u32);
348   u8 *t = 0;
349
350   switch (i)
351     {
352 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
353       foreach_ipsec_integ_alg
354 #undef _
355     default:
356       return format (s, "unknown");
357     }
358   return format (s, "%s", t);
359 }
360
361 uword
362 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
363 {
364   u32 *r = va_arg (*args, u32 *);
365
366   if (0);
367 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
368   foreach_ikev2_auth_method
369 #undef _
370     else
371     return 0;
372   return 1;
373 }
374
375 uword
376 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
377 {
378   u32 *r = va_arg (*args, u32 *);
379
380   if (0);
381 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
382   foreach_ikev2_id_type
383 #undef _
384     else
385     return 0;
386   return 1;
387 }
388 #endif /* VPP_API_TEST_BUILTIN */
389
390 static uword
391 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
392 {
393   u8 *r = va_arg (*args, u8 *);
394
395   if (unformat (input, "kbps"))
396     *r = SSE2_QOS_RATE_KBPS;
397   else if (unformat (input, "pps"))
398     *r = SSE2_QOS_RATE_PPS;
399   else
400     return 0;
401   return 1;
402 }
403
404 static uword
405 unformat_policer_round_type (unformat_input_t * input, va_list * args)
406 {
407   u8 *r = va_arg (*args, u8 *);
408
409   if (unformat (input, "closest"))
410     *r = SSE2_QOS_ROUND_TO_CLOSEST;
411   else if (unformat (input, "up"))
412     *r = SSE2_QOS_ROUND_TO_UP;
413   else if (unformat (input, "down"))
414     *r = SSE2_QOS_ROUND_TO_DOWN;
415   else
416     return 0;
417   return 1;
418 }
419
420 static uword
421 unformat_policer_type (unformat_input_t * input, va_list * args)
422 {
423   u8 *r = va_arg (*args, u8 *);
424
425   if (unformat (input, "1r2c"))
426     *r = SSE2_QOS_POLICER_TYPE_1R2C;
427   else if (unformat (input, "1r3c"))
428     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
429   else if (unformat (input, "2r3c-2698"))
430     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
431   else if (unformat (input, "2r3c-4115"))
432     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
433   else if (unformat (input, "2r3c-mef5cf1"))
434     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
435   else
436     return 0;
437   return 1;
438 }
439
440 static uword
441 unformat_dscp (unformat_input_t * input, va_list * va)
442 {
443   u8 *r = va_arg (*va, u8 *);
444
445   if (0);
446 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
447   foreach_vnet_dscp
448 #undef _
449     else
450     return 0;
451   return 1;
452 }
453
454 static uword
455 unformat_policer_action_type (unformat_input_t * input, va_list * va)
456 {
457   sse2_qos_pol_action_params_st *a
458     = va_arg (*va, sse2_qos_pol_action_params_st *);
459
460   if (unformat (input, "drop"))
461     a->action_type = SSE2_QOS_ACTION_DROP;
462   else if (unformat (input, "transmit"))
463     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
464   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
465     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
466   else
467     return 0;
468   return 1;
469 }
470
471 static uword
472 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
473 {
474   u32 *r = va_arg (*va, u32 *);
475   u32 tid;
476
477   if (unformat (input, "ip4"))
478     tid = POLICER_CLASSIFY_TABLE_IP4;
479   else if (unformat (input, "ip6"))
480     tid = POLICER_CLASSIFY_TABLE_IP6;
481   else if (unformat (input, "l2"))
482     tid = POLICER_CLASSIFY_TABLE_L2;
483   else
484     return 0;
485
486   *r = tid;
487   return 1;
488 }
489
490 static uword
491 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
492 {
493   u32 *r = va_arg (*va, u32 *);
494   u32 tid;
495
496   if (unformat (input, "ip4"))
497     tid = FLOW_CLASSIFY_TABLE_IP4;
498   else if (unformat (input, "ip6"))
499     tid = FLOW_CLASSIFY_TABLE_IP6;
500   else
501     return 0;
502
503   *r = tid;
504   return 1;
505 }
506
507 #if (VPP_API_TEST_BUILTIN==0)
508 u8 *
509 format_ip4_address (u8 * s, va_list * args)
510 {
511   u8 *a = va_arg (*args, u8 *);
512   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
513 }
514
515 u8 *
516 format_ip6_address (u8 * s, va_list * args)
517 {
518   ip6_address_t *a = va_arg (*args, ip6_address_t *);
519   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
520
521   i_max_n_zero = ARRAY_LEN (a->as_u16);
522   max_n_zeros = 0;
523   i_first_zero = i_max_n_zero;
524   n_zeros = 0;
525   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
526     {
527       u32 is_zero = a->as_u16[i] == 0;
528       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
529         {
530           i_first_zero = i;
531           n_zeros = 0;
532         }
533       n_zeros += is_zero;
534       if ((!is_zero && n_zeros > max_n_zeros)
535           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
536         {
537           i_max_n_zero = i_first_zero;
538           max_n_zeros = n_zeros;
539           i_first_zero = ARRAY_LEN (a->as_u16);
540           n_zeros = 0;
541         }
542     }
543
544   last_double_colon = 0;
545   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
546     {
547       if (i == i_max_n_zero && max_n_zeros > 1)
548         {
549           s = format (s, "::");
550           i += max_n_zeros - 1;
551           last_double_colon = 1;
552         }
553       else
554         {
555           s = format (s, "%s%x",
556                       (last_double_colon || i == 0) ? "" : ":",
557                       clib_net_to_host_u16 (a->as_u16[i]));
558           last_double_colon = 0;
559         }
560     }
561
562   return s;
563 }
564
565 /* Format an IP46 address. */
566 u8 *
567 format_ip46_address (u8 * s, va_list * args)
568 {
569   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
570   ip46_type_t type = va_arg (*args, ip46_type_t);
571   int is_ip4 = 1;
572
573   switch (type)
574     {
575     case IP46_TYPE_ANY:
576       is_ip4 = ip46_address_is_ip4 (ip46);
577       break;
578     case IP46_TYPE_IP4:
579       is_ip4 = 1;
580       break;
581     case IP46_TYPE_IP6:
582       is_ip4 = 0;
583       break;
584     }
585
586   return is_ip4 ?
587     format (s, "%U", format_ip4_address, &ip46->ip4) :
588     format (s, "%U", format_ip6_address, &ip46->ip6);
589 }
590
591 u8 *
592 format_ethernet_address (u8 * s, va_list * args)
593 {
594   u8 *a = va_arg (*args, u8 *);
595
596   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
597                  a[0], a[1], a[2], a[3], a[4], a[5]);
598 }
599 #endif
600
601 static void
602 increment_v4_address (ip4_address_t * a)
603 {
604   u32 v;
605
606   v = ntohl (a->as_u32) + 1;
607   a->as_u32 = ntohl (v);
608 }
609
610 static void
611 increment_v6_address (ip6_address_t * a)
612 {
613   u64 v0, v1;
614
615   v0 = clib_net_to_host_u64 (a->as_u64[0]);
616   v1 = clib_net_to_host_u64 (a->as_u64[1]);
617
618   v1 += 1;
619   if (v1 == 0)
620     v0 += 1;
621   a->as_u64[0] = clib_net_to_host_u64 (v0);
622   a->as_u64[1] = clib_net_to_host_u64 (v1);
623 }
624
625 static void
626 increment_mac_address (u64 * mac)
627 {
628   u64 tmp = *mac;
629
630   tmp = clib_net_to_host_u64 (tmp);
631   tmp += 1 << 16;               /* skip unused (least significant) octets */
632   tmp = clib_host_to_net_u64 (tmp);
633   *mac = tmp;
634 }
635
636 static void vl_api_create_loopback_reply_t_handler
637   (vl_api_create_loopback_reply_t * mp)
638 {
639   vat_main_t *vam = &vat_main;
640   i32 retval = ntohl (mp->retval);
641
642   vam->retval = retval;
643   vam->regenerate_interface_table = 1;
644   vam->sw_if_index = ntohl (mp->sw_if_index);
645   vam->result_ready = 1;
646 }
647
648 static void vl_api_create_loopback_reply_t_handler_json
649   (vl_api_create_loopback_reply_t * mp)
650 {
651   vat_main_t *vam = &vat_main;
652   vat_json_node_t node;
653
654   vat_json_init_object (&node);
655   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
656   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
657
658   vat_json_print (vam->ofp, &node);
659   vat_json_free (&node);
660   vam->retval = ntohl (mp->retval);
661   vam->result_ready = 1;
662 }
663
664 static void vl_api_af_packet_create_reply_t_handler
665   (vl_api_af_packet_create_reply_t * mp)
666 {
667   vat_main_t *vam = &vat_main;
668   i32 retval = ntohl (mp->retval);
669
670   vam->retval = retval;
671   vam->regenerate_interface_table = 1;
672   vam->sw_if_index = ntohl (mp->sw_if_index);
673   vam->result_ready = 1;
674 }
675
676 static void vl_api_af_packet_create_reply_t_handler_json
677   (vl_api_af_packet_create_reply_t * mp)
678 {
679   vat_main_t *vam = &vat_main;
680   vat_json_node_t node;
681
682   vat_json_init_object (&node);
683   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
684   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
685
686   vat_json_print (vam->ofp, &node);
687   vat_json_free (&node);
688
689   vam->retval = ntohl (mp->retval);
690   vam->result_ready = 1;
691 }
692
693 static void vl_api_create_vlan_subif_reply_t_handler
694   (vl_api_create_vlan_subif_reply_t * mp)
695 {
696   vat_main_t *vam = &vat_main;
697   i32 retval = ntohl (mp->retval);
698
699   vam->retval = retval;
700   vam->regenerate_interface_table = 1;
701   vam->sw_if_index = ntohl (mp->sw_if_index);
702   vam->result_ready = 1;
703 }
704
705 static void vl_api_create_vlan_subif_reply_t_handler_json
706   (vl_api_create_vlan_subif_reply_t * mp)
707 {
708   vat_main_t *vam = &vat_main;
709   vat_json_node_t node;
710
711   vat_json_init_object (&node);
712   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
713   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
714
715   vat_json_print (vam->ofp, &node);
716   vat_json_free (&node);
717
718   vam->retval = ntohl (mp->retval);
719   vam->result_ready = 1;
720 }
721
722 static void vl_api_create_subif_reply_t_handler
723   (vl_api_create_subif_reply_t * mp)
724 {
725   vat_main_t *vam = &vat_main;
726   i32 retval = ntohl (mp->retval);
727
728   vam->retval = retval;
729   vam->regenerate_interface_table = 1;
730   vam->sw_if_index = ntohl (mp->sw_if_index);
731   vam->result_ready = 1;
732 }
733
734 static void vl_api_create_subif_reply_t_handler_json
735   (vl_api_create_subif_reply_t * mp)
736 {
737   vat_main_t *vam = &vat_main;
738   vat_json_node_t node;
739
740   vat_json_init_object (&node);
741   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
742   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
743
744   vat_json_print (vam->ofp, &node);
745   vat_json_free (&node);
746
747   vam->retval = ntohl (mp->retval);
748   vam->result_ready = 1;
749 }
750
751 static void vl_api_interface_name_renumber_reply_t_handler
752   (vl_api_interface_name_renumber_reply_t * mp)
753 {
754   vat_main_t *vam = &vat_main;
755   i32 retval = ntohl (mp->retval);
756
757   vam->retval = retval;
758   vam->regenerate_interface_table = 1;
759   vam->result_ready = 1;
760 }
761
762 static void vl_api_interface_name_renumber_reply_t_handler_json
763   (vl_api_interface_name_renumber_reply_t * mp)
764 {
765   vat_main_t *vam = &vat_main;
766   vat_json_node_t node;
767
768   vat_json_init_object (&node);
769   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
770
771   vat_json_print (vam->ofp, &node);
772   vat_json_free (&node);
773
774   vam->retval = ntohl (mp->retval);
775   vam->result_ready = 1;
776 }
777
778 /*
779  * Special-case: build the interface table, maintain
780  * the next loopback sw_if_index vbl.
781  */
782 static void vl_api_sw_interface_details_t_handler
783   (vl_api_sw_interface_details_t * mp)
784 {
785   vat_main_t *vam = &vat_main;
786   u8 *s = format (0, "%s%c", mp->interface_name, 0);
787
788   hash_set_mem (vam->sw_if_index_by_interface_name, s,
789                 ntohl (mp->sw_if_index));
790
791   /* In sub interface case, fill the sub interface table entry */
792   if (mp->sw_if_index != mp->sup_sw_if_index)
793     {
794       sw_interface_subif_t *sub = NULL;
795
796       vec_add2 (vam->sw_if_subif_table, sub, 1);
797
798       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
799       strncpy ((char *) sub->interface_name, (char *) s,
800                vec_len (sub->interface_name));
801       sub->sw_if_index = ntohl (mp->sw_if_index);
802       sub->sub_id = ntohl (mp->sub_id);
803
804       sub->sub_dot1ad = mp->sub_dot1ad;
805       sub->sub_number_of_tags = mp->sub_number_of_tags;
806       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
807       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
808       sub->sub_exact_match = mp->sub_exact_match;
809       sub->sub_default = mp->sub_default;
810       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
811       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
812
813       /* vlan tag rewrite */
814       sub->vtr_op = ntohl (mp->vtr_op);
815       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
816       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
817       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
818     }
819 }
820
821 static void vl_api_sw_interface_details_t_handler_json
822   (vl_api_sw_interface_details_t * mp)
823 {
824   vat_main_t *vam = &vat_main;
825   vat_json_node_t *node = NULL;
826
827   if (VAT_JSON_ARRAY != vam->json_tree.type)
828     {
829       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
830       vat_json_init_array (&vam->json_tree);
831     }
832   node = vat_json_array_add (&vam->json_tree);
833
834   vat_json_init_object (node);
835   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
836   vat_json_object_add_uint (node, "sup_sw_if_index",
837                             ntohl (mp->sup_sw_if_index));
838   vat_json_object_add_uint (node, "l2_address_length",
839                             ntohl (mp->l2_address_length));
840   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
841                              sizeof (mp->l2_address));
842   vat_json_object_add_string_copy (node, "interface_name",
843                                    mp->interface_name);
844   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
845   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
846   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
847   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
848   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
849   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
850   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
851   vat_json_object_add_uint (node, "sub_number_of_tags",
852                             mp->sub_number_of_tags);
853   vat_json_object_add_uint (node, "sub_outer_vlan_id",
854                             ntohs (mp->sub_outer_vlan_id));
855   vat_json_object_add_uint (node, "sub_inner_vlan_id",
856                             ntohs (mp->sub_inner_vlan_id));
857   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
858   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
859   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
860                             mp->sub_outer_vlan_id_any);
861   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
862                             mp->sub_inner_vlan_id_any);
863   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
864   vat_json_object_add_uint (node, "vtr_push_dot1q",
865                             ntohl (mp->vtr_push_dot1q));
866   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
867   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
868 }
869
870 static void vl_api_sw_interface_set_flags_t_handler
871   (vl_api_sw_interface_set_flags_t * mp)
872 {
873   vat_main_t *vam = &vat_main;
874   if (vam->interface_event_display)
875     errmsg ("interface flags: sw_if_index %d %s %s",
876             ntohl (mp->sw_if_index),
877             mp->admin_up_down ? "admin-up" : "admin-down",
878             mp->link_up_down ? "link-up" : "link-down");
879 }
880
881 static void vl_api_sw_interface_set_flags_t_handler_json
882   (vl_api_sw_interface_set_flags_t * mp)
883 {
884   /* JSON output not supported */
885 }
886
887 static void
888 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
889 {
890   vat_main_t *vam = &vat_main;
891   i32 retval = ntohl (mp->retval);
892
893   vam->retval = retval;
894   vam->shmem_result = (u8 *) mp->reply_in_shmem;
895   vam->result_ready = 1;
896 }
897
898 static void
899 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
900 {
901   vat_main_t *vam = &vat_main;
902   vat_json_node_t node;
903   api_main_t *am = &api_main;
904   void *oldheap;
905   u8 *reply;
906
907   vat_json_init_object (&node);
908   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
909   vat_json_object_add_uint (&node, "reply_in_shmem",
910                             ntohl (mp->reply_in_shmem));
911   /* Toss the shared-memory original... */
912   pthread_mutex_lock (&am->vlib_rp->mutex);
913   oldheap = svm_push_data_heap (am->vlib_rp);
914
915   reply = (u8 *) (mp->reply_in_shmem);
916   vec_free (reply);
917
918   svm_pop_heap (oldheap);
919   pthread_mutex_unlock (&am->vlib_rp->mutex);
920
921   vat_json_print (vam->ofp, &node);
922   vat_json_free (&node);
923
924   vam->retval = ntohl (mp->retval);
925   vam->result_ready = 1;
926 }
927
928 static void
929 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
930 {
931   vat_main_t *vam = &vat_main;
932   i32 retval = ntohl (mp->retval);
933
934   vam->retval = retval;
935   vam->cmd_reply = mp->reply;
936   vam->result_ready = 1;
937 }
938
939 static void
940 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
941 {
942   vat_main_t *vam = &vat_main;
943   vat_json_node_t node;
944
945   vat_json_init_object (&node);
946   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
947   vat_json_object_add_string_copy (&node, "reply", mp->reply);
948
949   vat_json_print (vam->ofp, &node);
950   vat_json_free (&node);
951
952   vam->retval = ntohl (mp->retval);
953   vam->result_ready = 1;
954 }
955
956 static void vl_api_classify_add_del_table_reply_t_handler
957   (vl_api_classify_add_del_table_reply_t * mp)
958 {
959   vat_main_t *vam = &vat_main;
960   i32 retval = ntohl (mp->retval);
961   if (vam->async_mode)
962     {
963       vam->async_errors += (retval < 0);
964     }
965   else
966     {
967       vam->retval = retval;
968       if (retval == 0 &&
969           ((mp->new_table_index != 0xFFFFFFFF) ||
970            (mp->skip_n_vectors != 0xFFFFFFFF) ||
971            (mp->match_n_vectors != 0xFFFFFFFF)))
972         /*
973          * Note: this is just barely thread-safe, depends on
974          * the main thread spinning waiting for an answer...
975          */
976         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
977                 ntohl (mp->new_table_index),
978                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
979       vam->result_ready = 1;
980     }
981 }
982
983 static void vl_api_classify_add_del_table_reply_t_handler_json
984   (vl_api_classify_add_del_table_reply_t * mp)
985 {
986   vat_main_t *vam = &vat_main;
987   vat_json_node_t node;
988
989   vat_json_init_object (&node);
990   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
991   vat_json_object_add_uint (&node, "new_table_index",
992                             ntohl (mp->new_table_index));
993   vat_json_object_add_uint (&node, "skip_n_vectors",
994                             ntohl (mp->skip_n_vectors));
995   vat_json_object_add_uint (&node, "match_n_vectors",
996                             ntohl (mp->match_n_vectors));
997
998   vat_json_print (vam->ofp, &node);
999   vat_json_free (&node);
1000
1001   vam->retval = ntohl (mp->retval);
1002   vam->result_ready = 1;
1003 }
1004
1005 static void vl_api_get_node_index_reply_t_handler
1006   (vl_api_get_node_index_reply_t * mp)
1007 {
1008   vat_main_t *vam = &vat_main;
1009   i32 retval = ntohl (mp->retval);
1010   if (vam->async_mode)
1011     {
1012       vam->async_errors += (retval < 0);
1013     }
1014   else
1015     {
1016       vam->retval = retval;
1017       if (retval == 0)
1018         errmsg ("node index %d", ntohl (mp->node_index));
1019       vam->result_ready = 1;
1020     }
1021 }
1022
1023 static void vl_api_get_node_index_reply_t_handler_json
1024   (vl_api_get_node_index_reply_t * mp)
1025 {
1026   vat_main_t *vam = &vat_main;
1027   vat_json_node_t node;
1028
1029   vat_json_init_object (&node);
1030   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1031   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1032
1033   vat_json_print (vam->ofp, &node);
1034   vat_json_free (&node);
1035
1036   vam->retval = ntohl (mp->retval);
1037   vam->result_ready = 1;
1038 }
1039
1040 static void vl_api_get_next_index_reply_t_handler
1041   (vl_api_get_next_index_reply_t * mp)
1042 {
1043   vat_main_t *vam = &vat_main;
1044   i32 retval = ntohl (mp->retval);
1045   if (vam->async_mode)
1046     {
1047       vam->async_errors += (retval < 0);
1048     }
1049   else
1050     {
1051       vam->retval = retval;
1052       if (retval == 0)
1053         errmsg ("next node index %d", ntohl (mp->next_index));
1054       vam->result_ready = 1;
1055     }
1056 }
1057
1058 static void vl_api_get_next_index_reply_t_handler_json
1059   (vl_api_get_next_index_reply_t * mp)
1060 {
1061   vat_main_t *vam = &vat_main;
1062   vat_json_node_t node;
1063
1064   vat_json_init_object (&node);
1065   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1066   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1067
1068   vat_json_print (vam->ofp, &node);
1069   vat_json_free (&node);
1070
1071   vam->retval = ntohl (mp->retval);
1072   vam->result_ready = 1;
1073 }
1074
1075 static void vl_api_add_node_next_reply_t_handler
1076   (vl_api_add_node_next_reply_t * mp)
1077 {
1078   vat_main_t *vam = &vat_main;
1079   i32 retval = ntohl (mp->retval);
1080   if (vam->async_mode)
1081     {
1082       vam->async_errors += (retval < 0);
1083     }
1084   else
1085     {
1086       vam->retval = retval;
1087       if (retval == 0)
1088         errmsg ("next index %d", ntohl (mp->next_index));
1089       vam->result_ready = 1;
1090     }
1091 }
1092
1093 static void vl_api_add_node_next_reply_t_handler_json
1094   (vl_api_add_node_next_reply_t * mp)
1095 {
1096   vat_main_t *vam = &vat_main;
1097   vat_json_node_t node;
1098
1099   vat_json_init_object (&node);
1100   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1101   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1102
1103   vat_json_print (vam->ofp, &node);
1104   vat_json_free (&node);
1105
1106   vam->retval = ntohl (mp->retval);
1107   vam->result_ready = 1;
1108 }
1109
1110 static void vl_api_show_version_reply_t_handler
1111   (vl_api_show_version_reply_t * mp)
1112 {
1113   vat_main_t *vam = &vat_main;
1114   i32 retval = ntohl (mp->retval);
1115
1116   if (retval >= 0)
1117     {
1118       errmsg ("        program: %s", mp->program);
1119       errmsg ("        version: %s", mp->version);
1120       errmsg ("     build date: %s", mp->build_date);
1121       errmsg ("build directory: %s", mp->build_directory);
1122     }
1123   vam->retval = retval;
1124   vam->result_ready = 1;
1125 }
1126
1127 static void vl_api_show_version_reply_t_handler_json
1128   (vl_api_show_version_reply_t * mp)
1129 {
1130   vat_main_t *vam = &vat_main;
1131   vat_json_node_t node;
1132
1133   vat_json_init_object (&node);
1134   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1135   vat_json_object_add_string_copy (&node, "program", mp->program);
1136   vat_json_object_add_string_copy (&node, "version", mp->version);
1137   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1138   vat_json_object_add_string_copy (&node, "build_directory",
1139                                    mp->build_directory);
1140
1141   vat_json_print (vam->ofp, &node);
1142   vat_json_free (&node);
1143
1144   vam->retval = ntohl (mp->retval);
1145   vam->result_ready = 1;
1146 }
1147
1148 static void
1149 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1150 {
1151   errmsg ("arp %s event: address %U new mac %U sw_if_index %d",
1152           mp->mac_ip ? "mac/ip binding" : "address resolution",
1153           format_ip4_address, &mp->address,
1154           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1155 }
1156
1157 static void
1158 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1159 {
1160   /* JSON output not supported */
1161 }
1162
1163 static void
1164 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1165 {
1166   errmsg ("ip6 nd %s event: address %U new mac %U sw_if_index %d",
1167           mp->mac_ip ? "mac/ip binding" : "address resolution",
1168           format_ip6_address, mp->address,
1169           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1170 }
1171
1172 static void
1173 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1174 {
1175   /* JSON output not supported */
1176 }
1177
1178 /*
1179  * Special-case: build the bridge domain table, maintain
1180  * the next bd id vbl.
1181  */
1182 static void vl_api_bridge_domain_details_t_handler
1183   (vl_api_bridge_domain_details_t * mp)
1184 {
1185   vat_main_t *vam = &vat_main;
1186   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1187
1188   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1189          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1190
1191   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1192          ntohl (mp->bd_id), mp->learn, mp->forward,
1193          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1194
1195   if (n_sw_ifs)
1196     print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG", "Interface Name");
1197 }
1198
1199 static void vl_api_bridge_domain_details_t_handler_json
1200   (vl_api_bridge_domain_details_t * mp)
1201 {
1202   vat_main_t *vam = &vat_main;
1203   vat_json_node_t *node, *array = NULL;
1204
1205   if (VAT_JSON_ARRAY != vam->json_tree.type)
1206     {
1207       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1208       vat_json_init_array (&vam->json_tree);
1209     }
1210   node = vat_json_array_add (&vam->json_tree);
1211
1212   vat_json_init_object (node);
1213   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1214   vat_json_object_add_uint (node, "flood", mp->flood);
1215   vat_json_object_add_uint (node, "forward", mp->forward);
1216   vat_json_object_add_uint (node, "learn", mp->learn);
1217   vat_json_object_add_uint (node, "bvi_sw_if_index",
1218                             ntohl (mp->bvi_sw_if_index));
1219   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1220   array = vat_json_object_add (node, "sw_if");
1221   vat_json_init_array (array);
1222 }
1223
1224 /*
1225  * Special-case: build the bridge domain sw if table.
1226  */
1227 static void vl_api_bridge_domain_sw_if_details_t_handler
1228   (vl_api_bridge_domain_sw_if_details_t * mp)
1229 {
1230   vat_main_t *vam = &vat_main;
1231   hash_pair_t *p;
1232   u8 *sw_if_name = 0;
1233   u32 sw_if_index;
1234
1235   sw_if_index = ntohl (mp->sw_if_index);
1236   /* *INDENT-OFF* */
1237   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1238   ({
1239     if ((u32) p->value[0] == sw_if_index)
1240       {
1241         sw_if_name = (u8 *)(p->key);
1242         break;
1243       }
1244   }));
1245   /* *INDENT-ON* */
1246
1247   print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1248          mp->shg, sw_if_name ? (char *) sw_if_name :
1249          "sw_if_index not found!");
1250 }
1251
1252 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1253   (vl_api_bridge_domain_sw_if_details_t * mp)
1254 {
1255   vat_main_t *vam = &vat_main;
1256   vat_json_node_t *node = NULL;
1257   uword last_index = 0;
1258
1259   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1260   ASSERT (vec_len (vam->json_tree.array) >= 1);
1261   last_index = vec_len (vam->json_tree.array) - 1;
1262   node = &vam->json_tree.array[last_index];
1263   node = vat_json_object_get_element (node, "sw_if");
1264   ASSERT (NULL != node);
1265   node = vat_json_array_add (node);
1266
1267   vat_json_init_object (node);
1268   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1269   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1270   vat_json_object_add_uint (node, "shg", mp->shg);
1271 }
1272
1273 static void vl_api_control_ping_reply_t_handler
1274   (vl_api_control_ping_reply_t * mp)
1275 {
1276   vat_main_t *vam = &vat_main;
1277   i32 retval = ntohl (mp->retval);
1278   if (vam->async_mode)
1279     {
1280       vam->async_errors += (retval < 0);
1281     }
1282   else
1283     {
1284       vam->retval = retval;
1285       vam->result_ready = 1;
1286     }
1287 }
1288
1289 static void vl_api_control_ping_reply_t_handler_json
1290   (vl_api_control_ping_reply_t * mp)
1291 {
1292   vat_main_t *vam = &vat_main;
1293   i32 retval = ntohl (mp->retval);
1294
1295   if (VAT_JSON_NONE != vam->json_tree.type)
1296     {
1297       vat_json_print (vam->ofp, &vam->json_tree);
1298       vat_json_free (&vam->json_tree);
1299       vam->json_tree.type = VAT_JSON_NONE;
1300     }
1301   else
1302     {
1303       /* just print [] */
1304       vat_json_init_array (&vam->json_tree);
1305       vat_json_print (vam->ofp, &vam->json_tree);
1306       vam->json_tree.type = VAT_JSON_NONE;
1307     }
1308
1309   vam->retval = retval;
1310   vam->result_ready = 1;
1311 }
1312
1313 static void
1314 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1315 {
1316   vat_main_t *vam = &vat_main;
1317   i32 retval = ntohl (mp->retval);
1318   if (vam->async_mode)
1319     {
1320       vam->async_errors += (retval < 0);
1321     }
1322   else
1323     {
1324       vam->retval = retval;
1325       vam->result_ready = 1;
1326     }
1327 }
1328
1329 static void vl_api_l2_flags_reply_t_handler_json
1330   (vl_api_l2_flags_reply_t * mp)
1331 {
1332   vat_main_t *vam = &vat_main;
1333   vat_json_node_t node;
1334
1335   vat_json_init_object (&node);
1336   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1337   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1338                             ntohl (mp->resulting_feature_bitmap));
1339
1340   vat_json_print (vam->ofp, &node);
1341   vat_json_free (&node);
1342
1343   vam->retval = ntohl (mp->retval);
1344   vam->result_ready = 1;
1345 }
1346
1347 static void vl_api_bridge_flags_reply_t_handler
1348   (vl_api_bridge_flags_reply_t * mp)
1349 {
1350   vat_main_t *vam = &vat_main;
1351   i32 retval = ntohl (mp->retval);
1352   if (vam->async_mode)
1353     {
1354       vam->async_errors += (retval < 0);
1355     }
1356   else
1357     {
1358       vam->retval = retval;
1359       vam->result_ready = 1;
1360     }
1361 }
1362
1363 static void vl_api_bridge_flags_reply_t_handler_json
1364   (vl_api_bridge_flags_reply_t * mp)
1365 {
1366   vat_main_t *vam = &vat_main;
1367   vat_json_node_t node;
1368
1369   vat_json_init_object (&node);
1370   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1371   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1372                             ntohl (mp->resulting_feature_bitmap));
1373
1374   vat_json_print (vam->ofp, &node);
1375   vat_json_free (&node);
1376
1377   vam->retval = ntohl (mp->retval);
1378   vam->result_ready = 1;
1379 }
1380
1381 static void vl_api_tap_connect_reply_t_handler
1382   (vl_api_tap_connect_reply_t * mp)
1383 {
1384   vat_main_t *vam = &vat_main;
1385   i32 retval = ntohl (mp->retval);
1386   if (vam->async_mode)
1387     {
1388       vam->async_errors += (retval < 0);
1389     }
1390   else
1391     {
1392       vam->retval = retval;
1393       vam->sw_if_index = ntohl (mp->sw_if_index);
1394       vam->result_ready = 1;
1395     }
1396
1397 }
1398
1399 static void vl_api_tap_connect_reply_t_handler_json
1400   (vl_api_tap_connect_reply_t * mp)
1401 {
1402   vat_main_t *vam = &vat_main;
1403   vat_json_node_t node;
1404
1405   vat_json_init_object (&node);
1406   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1407   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1408
1409   vat_json_print (vam->ofp, &node);
1410   vat_json_free (&node);
1411
1412   vam->retval = ntohl (mp->retval);
1413   vam->result_ready = 1;
1414
1415 }
1416
1417 static void
1418 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1419 {
1420   vat_main_t *vam = &vat_main;
1421   i32 retval = ntohl (mp->retval);
1422   if (vam->async_mode)
1423     {
1424       vam->async_errors += (retval < 0);
1425     }
1426   else
1427     {
1428       vam->retval = retval;
1429       vam->sw_if_index = ntohl (mp->sw_if_index);
1430       vam->result_ready = 1;
1431     }
1432 }
1433
1434 static void vl_api_tap_modify_reply_t_handler_json
1435   (vl_api_tap_modify_reply_t * mp)
1436 {
1437   vat_main_t *vam = &vat_main;
1438   vat_json_node_t node;
1439
1440   vat_json_init_object (&node);
1441   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1442   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1443
1444   vat_json_print (vam->ofp, &node);
1445   vat_json_free (&node);
1446
1447   vam->retval = ntohl (mp->retval);
1448   vam->result_ready = 1;
1449 }
1450
1451 static void
1452 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1453 {
1454   vat_main_t *vam = &vat_main;
1455   i32 retval = ntohl (mp->retval);
1456   if (vam->async_mode)
1457     {
1458       vam->async_errors += (retval < 0);
1459     }
1460   else
1461     {
1462       vam->retval = retval;
1463       vam->result_ready = 1;
1464     }
1465 }
1466
1467 static void vl_api_tap_delete_reply_t_handler_json
1468   (vl_api_tap_delete_reply_t * mp)
1469 {
1470   vat_main_t *vam = &vat_main;
1471   vat_json_node_t node;
1472
1473   vat_json_init_object (&node);
1474   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1475
1476   vat_json_print (vam->ofp, &node);
1477   vat_json_free (&node);
1478
1479   vam->retval = ntohl (mp->retval);
1480   vam->result_ready = 1;
1481 }
1482
1483 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1484   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1485 {
1486   vat_main_t *vam = &vat_main;
1487   i32 retval = ntohl (mp->retval);
1488   if (vam->async_mode)
1489     {
1490       vam->async_errors += (retval < 0);
1491     }
1492   else
1493     {
1494       vam->retval = retval;
1495       vam->result_ready = 1;
1496     }
1497 }
1498
1499 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1500   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1501 {
1502   vat_main_t *vam = &vat_main;
1503   vat_json_node_t node;
1504
1505   vat_json_init_object (&node);
1506   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1507   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1508                             ntohl (mp->sw_if_index));
1509
1510   vat_json_print (vam->ofp, &node);
1511   vat_json_free (&node);
1512
1513   vam->retval = ntohl (mp->retval);
1514   vam->result_ready = 1;
1515 }
1516
1517 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1518   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1519 {
1520   vat_main_t *vam = &vat_main;
1521   i32 retval = ntohl (mp->retval);
1522   if (vam->async_mode)
1523     {
1524       vam->async_errors += (retval < 0);
1525     }
1526   else
1527     {
1528       vam->retval = retval;
1529       vam->sw_if_index = ntohl (mp->sw_if_index);
1530       vam->result_ready = 1;
1531     }
1532 }
1533
1534 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1535   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1536 {
1537   vat_main_t *vam = &vat_main;
1538   vat_json_node_t node;
1539
1540   vat_json_init_object (&node);
1541   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1542   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1543
1544   vat_json_print (vam->ofp, &node);
1545   vat_json_free (&node);
1546
1547   vam->retval = ntohl (mp->retval);
1548   vam->result_ready = 1;
1549 }
1550
1551
1552 static void vl_api_lisp_add_del_locator_set_reply_t_handler
1553   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1554 {
1555   vat_main_t *vam = &vat_main;
1556   i32 retval = ntohl (mp->retval);
1557   if (vam->async_mode)
1558     {
1559       vam->async_errors += (retval < 0);
1560     }
1561   else
1562     {
1563       vam->retval = retval;
1564       vam->result_ready = 1;
1565     }
1566 }
1567
1568 static void vl_api_lisp_add_del_locator_set_reply_t_handler_json
1569   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1570 {
1571   vat_main_t *vam = &vat_main;
1572   vat_json_node_t node;
1573
1574   vat_json_init_object (&node);
1575   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1576   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1577
1578   vat_json_print (vam->ofp, &node);
1579   vat_json_free (&node);
1580
1581   vam->retval = ntohl (mp->retval);
1582   vam->result_ready = 1;
1583 }
1584
1585 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1586   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1587 {
1588   vat_main_t *vam = &vat_main;
1589   i32 retval = ntohl (mp->retval);
1590   if (vam->async_mode)
1591     {
1592       vam->async_errors += (retval < 0);
1593     }
1594   else
1595     {
1596       vam->retval = retval;
1597       vam->sw_if_index = ntohl (mp->sw_if_index);
1598       vam->result_ready = 1;
1599     }
1600 }
1601
1602 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1603   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1604 {
1605   vat_main_t *vam = &vat_main;
1606   vat_json_node_t node;
1607
1608   vat_json_init_object (&node);
1609   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1610   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1611
1612   vat_json_print (vam->ofp, &node);
1613   vat_json_free (&node);
1614
1615   vam->retval = ntohl (mp->retval);
1616   vam->result_ready = 1;
1617 }
1618
1619 static void vl_api_gre_add_del_tunnel_reply_t_handler
1620   (vl_api_gre_add_del_tunnel_reply_t * mp)
1621 {
1622   vat_main_t *vam = &vat_main;
1623   i32 retval = ntohl (mp->retval);
1624   if (vam->async_mode)
1625     {
1626       vam->async_errors += (retval < 0);
1627     }
1628   else
1629     {
1630       vam->retval = retval;
1631       vam->sw_if_index = ntohl (mp->sw_if_index);
1632       vam->result_ready = 1;
1633     }
1634 }
1635
1636 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1637   (vl_api_gre_add_del_tunnel_reply_t * mp)
1638 {
1639   vat_main_t *vam = &vat_main;
1640   vat_json_node_t node;
1641
1642   vat_json_init_object (&node);
1643   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1644   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1645
1646   vat_json_print (vam->ofp, &node);
1647   vat_json_free (&node);
1648
1649   vam->retval = ntohl (mp->retval);
1650   vam->result_ready = 1;
1651 }
1652
1653 static void vl_api_create_vhost_user_if_reply_t_handler
1654   (vl_api_create_vhost_user_if_reply_t * mp)
1655 {
1656   vat_main_t *vam = &vat_main;
1657   i32 retval = ntohl (mp->retval);
1658   if (vam->async_mode)
1659     {
1660       vam->async_errors += (retval < 0);
1661     }
1662   else
1663     {
1664       vam->retval = retval;
1665       vam->sw_if_index = ntohl (mp->sw_if_index);
1666       vam->result_ready = 1;
1667     }
1668 }
1669
1670 static void vl_api_create_vhost_user_if_reply_t_handler_json
1671   (vl_api_create_vhost_user_if_reply_t * mp)
1672 {
1673   vat_main_t *vam = &vat_main;
1674   vat_json_node_t node;
1675
1676   vat_json_init_object (&node);
1677   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1678   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1679
1680   vat_json_print (vam->ofp, &node);
1681   vat_json_free (&node);
1682
1683   vam->retval = ntohl (mp->retval);
1684   vam->result_ready = 1;
1685 }
1686
1687 static void vl_api_ip_address_details_t_handler
1688   (vl_api_ip_address_details_t * mp)
1689 {
1690   vat_main_t *vam = &vat_main;
1691   static ip_address_details_t empty_ip_address_details = { {0} };
1692   ip_address_details_t *address = NULL;
1693   ip_details_t *current_ip_details = NULL;
1694   ip_details_t *details = NULL;
1695
1696   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1697
1698   if (!details || vam->current_sw_if_index >= vec_len (details)
1699       || !details[vam->current_sw_if_index].present)
1700     {
1701       errmsg ("ip address details arrived but not stored");
1702       errmsg ("ip_dump should be called first");
1703       return;
1704     }
1705
1706   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1707
1708 #define addresses (current_ip_details->addr)
1709
1710   vec_validate_init_empty (addresses, vec_len (addresses),
1711                            empty_ip_address_details);
1712
1713   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1714
1715   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1716   address->prefix_length = mp->prefix_length;
1717 #undef addresses
1718 }
1719
1720 static void vl_api_ip_address_details_t_handler_json
1721   (vl_api_ip_address_details_t * mp)
1722 {
1723   vat_main_t *vam = &vat_main;
1724   vat_json_node_t *node = NULL;
1725   struct in6_addr ip6;
1726   struct in_addr ip4;
1727
1728   if (VAT_JSON_ARRAY != vam->json_tree.type)
1729     {
1730       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1731       vat_json_init_array (&vam->json_tree);
1732     }
1733   node = vat_json_array_add (&vam->json_tree);
1734
1735   vat_json_init_object (node);
1736   if (vam->is_ipv6)
1737     {
1738       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1739       vat_json_object_add_ip6 (node, "ip", ip6);
1740     }
1741   else
1742     {
1743       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1744       vat_json_object_add_ip4 (node, "ip", ip4);
1745     }
1746   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1747 }
1748
1749 static void
1750 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1751 {
1752   vat_main_t *vam = &vat_main;
1753   static ip_details_t empty_ip_details = { 0 };
1754   ip_details_t *ip = NULL;
1755   u32 sw_if_index = ~0;
1756
1757   sw_if_index = ntohl (mp->sw_if_index);
1758
1759   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1760                            sw_if_index, empty_ip_details);
1761
1762   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1763                          sw_if_index);
1764
1765   ip->present = 1;
1766 }
1767
1768 static void
1769 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1770 {
1771   vat_main_t *vam = &vat_main;
1772
1773   if (VAT_JSON_ARRAY != vam->json_tree.type)
1774     {
1775       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1776       vat_json_init_array (&vam->json_tree);
1777     }
1778   vat_json_array_add_uint (&vam->json_tree,
1779                            clib_net_to_host_u32 (mp->sw_if_index));
1780 }
1781
1782 static void vl_api_map_domain_details_t_handler_json
1783   (vl_api_map_domain_details_t * mp)
1784 {
1785   vat_json_node_t *node = NULL;
1786   vat_main_t *vam = &vat_main;
1787   struct in6_addr ip6;
1788   struct in_addr ip4;
1789
1790   if (VAT_JSON_ARRAY != vam->json_tree.type)
1791     {
1792       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1793       vat_json_init_array (&vam->json_tree);
1794     }
1795
1796   node = vat_json_array_add (&vam->json_tree);
1797   vat_json_init_object (node);
1798
1799   vat_json_object_add_uint (node, "domain_index",
1800                             clib_net_to_host_u32 (mp->domain_index));
1801   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1802   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1803   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1804   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1805   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1806   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1807   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1808   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1809   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1810   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1811   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1812   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1813   vat_json_object_add_uint (node, "flags", mp->flags);
1814   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1815   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1816 }
1817
1818 static void vl_api_map_domain_details_t_handler
1819   (vl_api_map_domain_details_t * mp)
1820 {
1821   vat_main_t *vam = &vat_main;
1822
1823   if (mp->is_translation)
1824     {
1825       print (vam->ofp,
1826              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
1827              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1828              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1829              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1830              clib_net_to_host_u32 (mp->domain_index));
1831     }
1832   else
1833     {
1834       print (vam->ofp,
1835              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
1836              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1837              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1838              format_ip6_address, mp->ip6_src,
1839              clib_net_to_host_u32 (mp->domain_index));
1840     }
1841   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
1842          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1843          mp->is_translation ? "map-t" : "");
1844 }
1845
1846 static void vl_api_map_rule_details_t_handler_json
1847   (vl_api_map_rule_details_t * mp)
1848 {
1849   struct in6_addr ip6;
1850   vat_json_node_t *node = NULL;
1851   vat_main_t *vam = &vat_main;
1852
1853   if (VAT_JSON_ARRAY != vam->json_tree.type)
1854     {
1855       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1856       vat_json_init_array (&vam->json_tree);
1857     }
1858
1859   node = vat_json_array_add (&vam->json_tree);
1860   vat_json_init_object (node);
1861
1862   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1863   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1864   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1865 }
1866
1867 static void
1868 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1869 {
1870   vat_main_t *vam = &vat_main;
1871   print (vam->ofp, " %d (psid) %U (ip6-dst)",
1872          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1873 }
1874
1875 static void
1876 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1877 {
1878   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1879           "router_addr %U host_mac %U",
1880           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1881           format_ip4_address, &mp->host_address,
1882           format_ip4_address, &mp->router_address,
1883           format_ethernet_address, mp->host_mac);
1884 }
1885
1886 static void vl_api_dhcp_compl_event_t_handler_json
1887   (vl_api_dhcp_compl_event_t * mp)
1888 {
1889   /* JSON output not supported */
1890 }
1891
1892 static void
1893 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1894                               u32 counter)
1895 {
1896   vat_main_t *vam = &vat_main;
1897   static u64 default_counter = 0;
1898
1899   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1900                            NULL);
1901   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1902                            sw_if_index, default_counter);
1903   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1904 }
1905
1906 static void
1907 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1908                                 interface_counter_t counter)
1909 {
1910   vat_main_t *vam = &vat_main;
1911   static interface_counter_t default_counter = { 0, };
1912
1913   vec_validate_init_empty (vam->combined_interface_counters,
1914                            vnet_counter_type, NULL);
1915   vec_validate_init_empty (vam->combined_interface_counters
1916                            [vnet_counter_type], sw_if_index, default_counter);
1917   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1918 }
1919
1920 static void vl_api_vnet_interface_counters_t_handler
1921   (vl_api_vnet_interface_counters_t * mp)
1922 {
1923   /* not supported */
1924 }
1925
1926 static void vl_api_vnet_interface_counters_t_handler_json
1927   (vl_api_vnet_interface_counters_t * mp)
1928 {
1929   interface_counter_t counter;
1930   vlib_counter_t *v;
1931   u64 *v_packets;
1932   u64 packets;
1933   u32 count;
1934   u32 first_sw_if_index;
1935   int i;
1936
1937   count = ntohl (mp->count);
1938   first_sw_if_index = ntohl (mp->first_sw_if_index);
1939
1940   if (!mp->is_combined)
1941     {
1942       v_packets = (u64 *) & mp->data;
1943       for (i = 0; i < count; i++)
1944         {
1945           packets =
1946             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
1947           set_simple_interface_counter (mp->vnet_counter_type,
1948                                         first_sw_if_index + i, packets);
1949           v_packets++;
1950         }
1951     }
1952   else
1953     {
1954       v = (vlib_counter_t *) & mp->data;
1955       for (i = 0; i < count; i++)
1956         {
1957           counter.packets =
1958             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
1959           counter.bytes =
1960             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
1961           set_combined_interface_counter (mp->vnet_counter_type,
1962                                           first_sw_if_index + i, counter);
1963           v++;
1964         }
1965     }
1966 }
1967
1968 static u32
1969 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1970 {
1971   vat_main_t *vam = &vat_main;
1972   u32 i;
1973
1974   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
1975     {
1976       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
1977         {
1978           return i;
1979         }
1980     }
1981   return ~0;
1982 }
1983
1984 static u32
1985 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1986 {
1987   vat_main_t *vam = &vat_main;
1988   u32 i;
1989
1990   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
1991     {
1992       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
1993         {
1994           return i;
1995         }
1996     }
1997   return ~0;
1998 }
1999
2000 static void vl_api_vnet_ip4_fib_counters_t_handler
2001   (vl_api_vnet_ip4_fib_counters_t * mp)
2002 {
2003   /* not supported */
2004 }
2005
2006 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2007   (vl_api_vnet_ip4_fib_counters_t * mp)
2008 {
2009   vat_main_t *vam = &vat_main;
2010   vl_api_ip4_fib_counter_t *v;
2011   ip4_fib_counter_t *counter;
2012   struct in_addr ip4;
2013   u32 vrf_id;
2014   u32 vrf_index;
2015   u32 count;
2016   int i;
2017
2018   vrf_id = ntohl (mp->vrf_id);
2019   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2020   if (~0 == vrf_index)
2021     {
2022       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2023       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2024       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2025       vec_validate (vam->ip4_fib_counters, vrf_index);
2026       vam->ip4_fib_counters[vrf_index] = NULL;
2027     }
2028
2029   vec_free (vam->ip4_fib_counters[vrf_index]);
2030   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2031   count = ntohl (mp->count);
2032   for (i = 0; i < count; i++)
2033     {
2034       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2035       counter = &vam->ip4_fib_counters[vrf_index][i];
2036       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2037       counter->address = ip4;
2038       counter->address_length = v->address_length;
2039       counter->packets = clib_net_to_host_u64 (v->packets);
2040       counter->bytes = clib_net_to_host_u64 (v->bytes);
2041       v++;
2042     }
2043 }
2044
2045 static void vl_api_vnet_ip6_fib_counters_t_handler
2046   (vl_api_vnet_ip6_fib_counters_t * mp)
2047 {
2048   /* not supported */
2049 }
2050
2051 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2052   (vl_api_vnet_ip6_fib_counters_t * mp)
2053 {
2054   vat_main_t *vam = &vat_main;
2055   vl_api_ip6_fib_counter_t *v;
2056   ip6_fib_counter_t *counter;
2057   struct in6_addr ip6;
2058   u32 vrf_id;
2059   u32 vrf_index;
2060   u32 count;
2061   int i;
2062
2063   vrf_id = ntohl (mp->vrf_id);
2064   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2065   if (~0 == vrf_index)
2066     {
2067       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2068       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2069       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2070       vec_validate (vam->ip6_fib_counters, vrf_index);
2071       vam->ip6_fib_counters[vrf_index] = NULL;
2072     }
2073
2074   vec_free (vam->ip6_fib_counters[vrf_index]);
2075   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2076   count = ntohl (mp->count);
2077   for (i = 0; i < count; i++)
2078     {
2079       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2080       counter = &vam->ip6_fib_counters[vrf_index][i];
2081       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2082       counter->address = ip6;
2083       counter->address_length = v->address_length;
2084       counter->packets = clib_net_to_host_u64 (v->packets);
2085       counter->bytes = clib_net_to_host_u64 (v->bytes);
2086       v++;
2087     }
2088 }
2089
2090 static void vl_api_get_first_msg_id_reply_t_handler
2091   (vl_api_get_first_msg_id_reply_t * mp)
2092 {
2093   vat_main_t *vam = &vat_main;
2094   i32 retval = ntohl (mp->retval);
2095
2096   if (vam->async_mode)
2097     {
2098       vam->async_errors += (retval < 0);
2099     }
2100   else
2101     {
2102       vam->retval = retval;
2103       vam->result_ready = 1;
2104     }
2105   if (retval >= 0)
2106     {
2107       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2108     }
2109 }
2110
2111 static void vl_api_get_first_msg_id_reply_t_handler_json
2112   (vl_api_get_first_msg_id_reply_t * mp)
2113 {
2114   vat_main_t *vam = &vat_main;
2115   vat_json_node_t node;
2116
2117   vat_json_init_object (&node);
2118   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2119   vat_json_object_add_uint (&node, "first_msg_id",
2120                             (uint) ntohs (mp->first_msg_id));
2121
2122   vat_json_print (vam->ofp, &node);
2123   vat_json_free (&node);
2124
2125   vam->retval = ntohl (mp->retval);
2126   vam->result_ready = 1;
2127 }
2128
2129 static void vl_api_get_node_graph_reply_t_handler
2130   (vl_api_get_node_graph_reply_t * mp)
2131 {
2132   vat_main_t *vam = &vat_main;
2133   api_main_t *am = &api_main;
2134   i32 retval = ntohl (mp->retval);
2135   u8 *pvt_copy, *reply;
2136   void *oldheap;
2137   vlib_node_t *node;
2138   int i;
2139
2140   if (vam->async_mode)
2141     {
2142       vam->async_errors += (retval < 0);
2143     }
2144   else
2145     {
2146       vam->retval = retval;
2147       vam->result_ready = 1;
2148     }
2149
2150   /* "Should never happen..." */
2151   if (retval != 0)
2152     return;
2153
2154   reply = (u8 *) (mp->reply_in_shmem);
2155   pvt_copy = vec_dup (reply);
2156
2157   /* Toss the shared-memory original... */
2158   pthread_mutex_lock (&am->vlib_rp->mutex);
2159   oldheap = svm_push_data_heap (am->vlib_rp);
2160
2161   vec_free (reply);
2162
2163   svm_pop_heap (oldheap);
2164   pthread_mutex_unlock (&am->vlib_rp->mutex);
2165
2166   if (vam->graph_nodes)
2167     {
2168       hash_free (vam->graph_node_index_by_name);
2169
2170       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2171         {
2172           node = vam->graph_nodes[i];
2173           vec_free (node->name);
2174           vec_free (node->next_nodes);
2175           vec_free (node);
2176         }
2177       vec_free (vam->graph_nodes);
2178     }
2179
2180   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2181   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2182   vec_free (pvt_copy);
2183
2184   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2185     {
2186       node = vam->graph_nodes[i];
2187       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2188     }
2189 }
2190
2191 static void vl_api_get_node_graph_reply_t_handler_json
2192   (vl_api_get_node_graph_reply_t * mp)
2193 {
2194   vat_main_t *vam = &vat_main;
2195   api_main_t *am = &api_main;
2196   void *oldheap;
2197   vat_json_node_t node;
2198   u8 *reply;
2199
2200   /* $$$$ make this real? */
2201   vat_json_init_object (&node);
2202   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2203   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2204
2205   reply = (u8 *) (mp->reply_in_shmem);
2206
2207   /* Toss the shared-memory original... */
2208   pthread_mutex_lock (&am->vlib_rp->mutex);
2209   oldheap = svm_push_data_heap (am->vlib_rp);
2210
2211   vec_free (reply);
2212
2213   svm_pop_heap (oldheap);
2214   pthread_mutex_unlock (&am->vlib_rp->mutex);
2215
2216   vat_json_print (vam->ofp, &node);
2217   vat_json_free (&node);
2218
2219   vam->retval = ntohl (mp->retval);
2220   vam->result_ready = 1;
2221 }
2222
2223 static void
2224 vl_api_lisp_locator_details_t_handler (vl_api_lisp_locator_details_t * mp)
2225 {
2226   vat_main_t *vam = &vat_main;
2227   u8 *s = 0;
2228
2229   if (mp->local)
2230     {
2231       s = format (s, "%=16d%=16d%=16d",
2232                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2233     }
2234   else
2235     {
2236       s = format (s, "%=16U%=16d%=16d",
2237                   mp->is_ipv6 ? format_ip6_address :
2238                   format_ip4_address,
2239                   mp->ip_address, mp->priority, mp->weight);
2240     }
2241
2242   print (vam->ofp, "%v", s);
2243   vec_free (s);
2244 }
2245
2246 static void
2247 vl_api_lisp_locator_details_t_handler_json (vl_api_lisp_locator_details_t *
2248                                             mp)
2249 {
2250   vat_main_t *vam = &vat_main;
2251   vat_json_node_t *node = NULL;
2252   struct in6_addr ip6;
2253   struct in_addr ip4;
2254
2255   if (VAT_JSON_ARRAY != vam->json_tree.type)
2256     {
2257       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2258       vat_json_init_array (&vam->json_tree);
2259     }
2260   node = vat_json_array_add (&vam->json_tree);
2261   vat_json_init_object (node);
2262
2263   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2264   vat_json_object_add_uint (node, "priority", mp->priority);
2265   vat_json_object_add_uint (node, "weight", mp->weight);
2266
2267   if (mp->local)
2268     vat_json_object_add_uint (node, "sw_if_index",
2269                               clib_net_to_host_u32 (mp->sw_if_index));
2270   else
2271     {
2272       if (mp->is_ipv6)
2273         {
2274           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2275           vat_json_object_add_ip6 (node, "address", ip6);
2276         }
2277       else
2278         {
2279           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2280           vat_json_object_add_ip4 (node, "address", ip4);
2281         }
2282     }
2283 }
2284
2285 static void
2286 vl_api_lisp_locator_set_details_t_handler (vl_api_lisp_locator_set_details_t *
2287                                            mp)
2288 {
2289   vat_main_t *vam = &vat_main;
2290   u8 *ls_name = 0;
2291
2292   ls_name = format (0, "%s", mp->ls_name);
2293
2294   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2295          ls_name);
2296   vec_free (ls_name);
2297 }
2298
2299 static void
2300   vl_api_lisp_locator_set_details_t_handler_json
2301   (vl_api_lisp_locator_set_details_t * mp)
2302 {
2303   vat_main_t *vam = &vat_main;
2304   vat_json_node_t *node = 0;
2305   u8 *ls_name = 0;
2306
2307   ls_name = format (0, "%s", mp->ls_name);
2308   vec_add1 (ls_name, 0);
2309
2310   if (VAT_JSON_ARRAY != vam->json_tree.type)
2311     {
2312       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2313       vat_json_init_array (&vam->json_tree);
2314     }
2315   node = vat_json_array_add (&vam->json_tree);
2316
2317   vat_json_init_object (node);
2318   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2319   vat_json_object_add_uint (node, "ls_index",
2320                             clib_net_to_host_u32 (mp->ls_index));
2321   vec_free (ls_name);
2322 }
2323
2324 static u8 *
2325 format_lisp_flat_eid (u8 * s, va_list * args)
2326 {
2327   u32 type = va_arg (*args, u32);
2328   u8 *eid = va_arg (*args, u8 *);
2329   u32 eid_len = va_arg (*args, u32);
2330
2331   switch (type)
2332     {
2333     case 0:
2334       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2335     case 1:
2336       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2337     case 2:
2338       return format (s, "%U", format_ethernet_address, eid);
2339     }
2340   return 0;
2341 }
2342
2343 static u8 *
2344 format_lisp_eid_vat (u8 * s, va_list * args)
2345 {
2346   u32 type = va_arg (*args, u32);
2347   u8 *eid = va_arg (*args, u8 *);
2348   u32 eid_len = va_arg (*args, u32);
2349   u8 *seid = va_arg (*args, u8 *);
2350   u32 seid_len = va_arg (*args, u32);
2351   u32 is_src_dst = va_arg (*args, u32);
2352
2353   if (is_src_dst)
2354     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2355
2356   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2357
2358   return s;
2359 }
2360
2361 static void
2362 vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
2363 {
2364   vat_main_t *vam = &vat_main;
2365   u8 *s = 0, *eid = 0;
2366
2367   if (~0 == mp->locator_set_index)
2368     s = format (0, "action: %d", mp->action);
2369   else
2370     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2371
2372   eid = format (0, "%U", format_lisp_eid_vat,
2373                 mp->eid_type,
2374                 mp->eid,
2375                 mp->eid_prefix_len,
2376                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2377   vec_add1 (eid, 0);
2378
2379   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2380          clib_net_to_host_u32 (mp->vni),
2381          eid,
2382          mp->is_local ? "local" : "remote",
2383          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2384          clib_net_to_host_u16 (mp->key_id), mp->key);
2385
2386   vec_free (s);
2387   vec_free (eid);
2388 }
2389
2390 static void
2391 vl_api_lisp_eid_table_details_t_handler_json (vl_api_lisp_eid_table_details_t
2392                                               * mp)
2393 {
2394   vat_main_t *vam = &vat_main;
2395   vat_json_node_t *node = 0;
2396   u8 *eid = 0;
2397
2398   if (VAT_JSON_ARRAY != vam->json_tree.type)
2399     {
2400       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2401       vat_json_init_array (&vam->json_tree);
2402     }
2403   node = vat_json_array_add (&vam->json_tree);
2404
2405   vat_json_init_object (node);
2406   if (~0 == mp->locator_set_index)
2407     vat_json_object_add_uint (node, "action", mp->action);
2408   else
2409     vat_json_object_add_uint (node, "locator_set_index",
2410                               clib_net_to_host_u32 (mp->locator_set_index));
2411
2412   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2413   eid = format (0, "%U", format_lisp_eid_vat,
2414                 mp->eid_type,
2415                 mp->eid,
2416                 mp->eid_prefix_len,
2417                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2418   vec_add1 (eid, 0);
2419   vat_json_object_add_string_copy (node, "eid", eid);
2420   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2421   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2422   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2423
2424   if (mp->key_id)
2425     {
2426       vat_json_object_add_uint (node, "key_id",
2427                                 clib_net_to_host_u16 (mp->key_id));
2428       vat_json_object_add_string_copy (node, "key", mp->key);
2429     }
2430   vec_free (eid);
2431 }
2432
2433 static void
2434   vl_api_lisp_eid_table_map_details_t_handler
2435   (vl_api_lisp_eid_table_map_details_t * mp)
2436 {
2437   vat_main_t *vam = &vat_main;
2438
2439   u8 *line = format (0, "%=10d%=10d",
2440                      clib_net_to_host_u32 (mp->vni),
2441                      clib_net_to_host_u32 (mp->dp_table));
2442   print (vam->ofp, "%v", line);
2443   vec_free (line);
2444 }
2445
2446 static void
2447   vl_api_lisp_eid_table_map_details_t_handler_json
2448   (vl_api_lisp_eid_table_map_details_t * mp)
2449 {
2450   vat_main_t *vam = &vat_main;
2451   vat_json_node_t *node = NULL;
2452
2453   if (VAT_JSON_ARRAY != vam->json_tree.type)
2454     {
2455       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2456       vat_json_init_array (&vam->json_tree);
2457     }
2458   node = vat_json_array_add (&vam->json_tree);
2459   vat_json_init_object (node);
2460   vat_json_object_add_uint (node, "dp_table",
2461                             clib_net_to_host_u32 (mp->dp_table));
2462   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2463 }
2464
2465 static void
2466   vl_api_lisp_eid_table_vni_details_t_handler
2467   (vl_api_lisp_eid_table_vni_details_t * mp)
2468 {
2469   vat_main_t *vam = &vat_main;
2470
2471   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2472   print (vam->ofp, "%v", line);
2473   vec_free (line);
2474 }
2475
2476 static void
2477   vl_api_lisp_eid_table_vni_details_t_handler_json
2478   (vl_api_lisp_eid_table_vni_details_t * mp)
2479 {
2480   vat_main_t *vam = &vat_main;
2481   vat_json_node_t *node = NULL;
2482
2483   if (VAT_JSON_ARRAY != vam->json_tree.type)
2484     {
2485       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2486       vat_json_init_array (&vam->json_tree);
2487     }
2488   node = vat_json_array_add (&vam->json_tree);
2489   vat_json_init_object (node);
2490   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2491 }
2492
2493 static void
2494   vl_api_show_lisp_map_register_state_reply_t_handler
2495   (vl_api_show_lisp_map_register_state_reply_t * mp)
2496 {
2497   vat_main_t *vam = &vat_main;
2498   int retval = clib_net_to_host_u32 (mp->retval);
2499
2500   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2501
2502   vam->retval = retval;
2503   vam->result_ready = 1;
2504 }
2505
2506 static void
2507   vl_api_show_lisp_map_register_state_reply_t_handler_json
2508   (vl_api_show_lisp_map_register_state_reply_t * mp)
2509 {
2510   vat_main_t *vam = &vat_main;
2511   vat_json_node_t _node, *node = &_node;
2512   int retval = clib_net_to_host_u32 (mp->retval);
2513
2514   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2515
2516   vat_json_init_object (node);
2517   vat_json_object_add_string_copy (node, "state", s);
2518
2519   vat_json_print (vam->ofp, node);
2520   vat_json_free (node);
2521
2522   vam->retval = retval;
2523   vam->result_ready = 1;
2524   vec_free (s);
2525 }
2526
2527 static void
2528   vl_api_show_lisp_rloc_probe_state_reply_t_handler
2529   (vl_api_show_lisp_rloc_probe_state_reply_t * mp)
2530 {
2531   vat_main_t *vam = &vat_main;
2532   int retval = clib_net_to_host_u32 (mp->retval);
2533
2534   if (retval)
2535     goto end;
2536
2537   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2538 end:
2539   vam->retval = retval;
2540   vam->result_ready = 1;
2541 }
2542
2543 static void
2544   vl_api_show_lisp_rloc_probe_state_reply_t_handler_json
2545   (vl_api_show_lisp_rloc_probe_state_reply_t * mp)
2546 {
2547   vat_main_t *vam = &vat_main;
2548   vat_json_node_t _node, *node = &_node;
2549   int retval = clib_net_to_host_u32 (mp->retval);
2550
2551   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2552   vat_json_init_object (node);
2553   vat_json_object_add_string_copy (node, "state", s);
2554
2555   vat_json_print (vam->ofp, node);
2556   vat_json_free (node);
2557
2558   vam->retval = retval;
2559   vam->result_ready = 1;
2560   vec_free (s);
2561 }
2562
2563 static void
2564   vl_api_lisp_adjacencies_get_reply_t_handler
2565   (vl_api_lisp_adjacencies_get_reply_t * mp)
2566 {
2567   vat_main_t *vam = &vat_main;
2568   u32 i, n;
2569   int retval = clib_net_to_host_u32 (mp->retval);
2570   vl_api_lisp_adjacency_t *a;
2571
2572   if (retval)
2573     goto end;
2574
2575   n = clib_net_to_host_u32 (mp->count);
2576
2577   for (i = 0; i < n; i++)
2578     {
2579       a = &mp->adjacencies[i];
2580       print (vam->ofp, "%U %40U",
2581              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
2582              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
2583     }
2584
2585 end:
2586   vam->retval = retval;
2587   vam->result_ready = 1;
2588 }
2589
2590 static void
2591   vl_api_lisp_adjacencies_get_reply_t_handler_json
2592   (vl_api_lisp_adjacencies_get_reply_t * mp)
2593 {
2594   u8 *s = 0;
2595   vat_main_t *vam = &vat_main;
2596   vat_json_node_t *e = 0, root;
2597   u32 i, n;
2598   int retval = clib_net_to_host_u32 (mp->retval);
2599   vl_api_lisp_adjacency_t *a;
2600
2601   if (retval)
2602     goto end;
2603
2604   n = clib_net_to_host_u32 (mp->count);
2605   vat_json_init_array (&root);
2606
2607   for (i = 0; i < n; i++)
2608     {
2609       e = vat_json_array_add (&root);
2610       a = &mp->adjacencies[i];
2611
2612       vat_json_init_object (e);
2613       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
2614                   a->leid_prefix_len);
2615       vec_add1 (s, 0);
2616       vat_json_object_add_string_copy (e, "leid", s);
2617       vec_free (s);
2618
2619       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
2620                   a->reid_prefix_len);
2621       vec_add1 (s, 0);
2622       vat_json_object_add_string_copy (e, "reid", s);
2623       vec_free (s);
2624     }
2625
2626   vat_json_print (vam->ofp, &root);
2627   vat_json_free (&root);
2628
2629 end:
2630   vam->retval = retval;
2631   vam->result_ready = 1;
2632 }
2633
2634 static void
2635 vl_api_lisp_map_server_details_t_handler (vl_api_lisp_map_server_details_t
2636                                           * mp)
2637 {
2638   vat_main_t *vam = &vat_main;
2639
2640   print (vam->ofp, "%=20U",
2641          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2642          mp->ip_address);
2643 }
2644
2645 static void
2646   vl_api_lisp_map_server_details_t_handler_json
2647   (vl_api_lisp_map_server_details_t * mp)
2648 {
2649   vat_main_t *vam = &vat_main;
2650   vat_json_node_t *node = NULL;
2651   struct in6_addr ip6;
2652   struct in_addr ip4;
2653
2654   if (VAT_JSON_ARRAY != vam->json_tree.type)
2655     {
2656       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2657       vat_json_init_array (&vam->json_tree);
2658     }
2659   node = vat_json_array_add (&vam->json_tree);
2660
2661   vat_json_init_object (node);
2662   if (mp->is_ipv6)
2663     {
2664       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2665       vat_json_object_add_ip6 (node, "map-server", ip6);
2666     }
2667   else
2668     {
2669       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2670       vat_json_object_add_ip4 (node, "map-server", ip4);
2671     }
2672 }
2673
2674 static void
2675 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2676                                             * mp)
2677 {
2678   vat_main_t *vam = &vat_main;
2679
2680   print (vam->ofp, "%=20U",
2681          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2682          mp->ip_address);
2683 }
2684
2685 static void
2686   vl_api_lisp_map_resolver_details_t_handler_json
2687   (vl_api_lisp_map_resolver_details_t * mp)
2688 {
2689   vat_main_t *vam = &vat_main;
2690   vat_json_node_t *node = NULL;
2691   struct in6_addr ip6;
2692   struct in_addr ip4;
2693
2694   if (VAT_JSON_ARRAY != vam->json_tree.type)
2695     {
2696       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2697       vat_json_init_array (&vam->json_tree);
2698     }
2699   node = vat_json_array_add (&vam->json_tree);
2700
2701   vat_json_init_object (node);
2702   if (mp->is_ipv6)
2703     {
2704       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2705       vat_json_object_add_ip6 (node, "map resolver", ip6);
2706     }
2707   else
2708     {
2709       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2710       vat_json_object_add_ip4 (node, "map resolver", ip4);
2711     }
2712 }
2713
2714 static void
2715   vl_api_show_lisp_status_reply_t_handler
2716   (vl_api_show_lisp_status_reply_t * mp)
2717 {
2718   vat_main_t *vam = &vat_main;
2719   i32 retval = ntohl (mp->retval);
2720
2721   if (0 <= retval)
2722     {
2723       print (vam->ofp, "feature: %s\ngpe: %s",
2724              mp->feature_status ? "enabled" : "disabled",
2725              mp->gpe_status ? "enabled" : "disabled");
2726     }
2727
2728   vam->retval = retval;
2729   vam->result_ready = 1;
2730 }
2731
2732 static void
2733   vl_api_show_lisp_status_reply_t_handler_json
2734   (vl_api_show_lisp_status_reply_t * mp)
2735 {
2736   vat_main_t *vam = &vat_main;
2737   vat_json_node_t node;
2738   u8 *gpe_status = NULL;
2739   u8 *feature_status = NULL;
2740
2741   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2742   feature_status = format (0, "%s",
2743                            mp->feature_status ? "enabled" : "disabled");
2744   vec_add1 (gpe_status, 0);
2745   vec_add1 (feature_status, 0);
2746
2747   vat_json_init_object (&node);
2748   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
2749   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
2750
2751   vec_free (gpe_status);
2752   vec_free (feature_status);
2753
2754   vat_json_print (vam->ofp, &node);
2755   vat_json_free (&node);
2756
2757   vam->retval = ntohl (mp->retval);
2758   vam->result_ready = 1;
2759 }
2760
2761 static void
2762   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
2763   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2764 {
2765   vat_main_t *vam = &vat_main;
2766   i32 retval = ntohl (mp->retval);
2767
2768   if (retval >= 0)
2769     {
2770       print (vam->ofp, "%=20s", mp->locator_set_name);
2771     }
2772
2773   vam->retval = retval;
2774   vam->result_ready = 1;
2775 }
2776
2777 static void
2778   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
2779   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2780 {
2781   vat_main_t *vam = &vat_main;
2782   vat_json_node_t *node = NULL;
2783
2784   if (VAT_JSON_ARRAY != vam->json_tree.type)
2785     {
2786       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2787       vat_json_init_array (&vam->json_tree);
2788     }
2789   node = vat_json_array_add (&vam->json_tree);
2790
2791   vat_json_init_object (node);
2792   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
2793
2794   vat_json_print (vam->ofp, node);
2795   vat_json_free (node);
2796
2797   vam->retval = ntohl (mp->retval);
2798   vam->result_ready = 1;
2799 }
2800
2801 static u8 *
2802 format_lisp_map_request_mode (u8 * s, va_list * args)
2803 {
2804   u32 mode = va_arg (*args, u32);
2805
2806   switch (mode)
2807     {
2808     case 0:
2809       return format (0, "dst-only");
2810     case 1:
2811       return format (0, "src-dst");
2812     }
2813   return 0;
2814 }
2815
2816 static void
2817   vl_api_show_lisp_map_request_mode_reply_t_handler
2818   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2819 {
2820   vat_main_t *vam = &vat_main;
2821   i32 retval = ntohl (mp->retval);
2822
2823   if (0 <= retval)
2824     {
2825       u32 mode = mp->mode;
2826       print (vam->ofp, "map_request_mode: %U",
2827              format_lisp_map_request_mode, mode);
2828     }
2829
2830   vam->retval = retval;
2831   vam->result_ready = 1;
2832 }
2833
2834 static void
2835   vl_api_show_lisp_map_request_mode_reply_t_handler_json
2836   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2837 {
2838   vat_main_t *vam = &vat_main;
2839   vat_json_node_t node;
2840   u8 *s = 0;
2841   u32 mode;
2842
2843   mode = mp->mode;
2844   s = format (0, "%U", format_lisp_map_request_mode, mode);
2845   vec_add1 (s, 0);
2846
2847   vat_json_init_object (&node);
2848   vat_json_object_add_string_copy (&node, "map_request_mode", s);
2849   vat_json_print (vam->ofp, &node);
2850   vat_json_free (&node);
2851
2852   vec_free (s);
2853   vam->retval = ntohl (mp->retval);
2854   vam->result_ready = 1;
2855 }
2856
2857 static void
2858 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2859 {
2860   vat_main_t *vam = &vat_main;
2861   i32 retval = ntohl (mp->retval);
2862
2863   if (0 <= retval)
2864     {
2865       print (vam->ofp, "%-20s%-16s",
2866              mp->status ? "enabled" : "disabled",
2867              mp->status ? (char *) mp->locator_set_name : "");
2868     }
2869
2870   vam->retval = retval;
2871   vam->result_ready = 1;
2872 }
2873
2874 static void
2875 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
2876                                             mp)
2877 {
2878   vat_main_t *vam = &vat_main;
2879   vat_json_node_t node;
2880   u8 *status = 0;
2881
2882   status = format (0, "%s", mp->status ? "enabled" : "disabled");
2883   vec_add1 (status, 0);
2884
2885   vat_json_init_object (&node);
2886   vat_json_object_add_string_copy (&node, "status", status);
2887   if (mp->status)
2888     {
2889       vat_json_object_add_string_copy (&node, "locator_set",
2890                                        mp->locator_set_name);
2891     }
2892
2893   vec_free (status);
2894
2895   vat_json_print (vam->ofp, &node);
2896   vat_json_free (&node);
2897
2898   vam->retval = ntohl (mp->retval);
2899   vam->result_ready = 1;
2900 }
2901
2902 static u8 *
2903 format_policer_type (u8 * s, va_list * va)
2904 {
2905   u32 i = va_arg (*va, u32);
2906
2907   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2908     s = format (s, "1r2c");
2909   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2910     s = format (s, "1r3c");
2911   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2912     s = format (s, "2r3c-2698");
2913   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2914     s = format (s, "2r3c-4115");
2915   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2916     s = format (s, "2r3c-mef5cf1");
2917   else
2918     s = format (s, "ILLEGAL");
2919   return s;
2920 }
2921
2922 static u8 *
2923 format_policer_rate_type (u8 * s, va_list * va)
2924 {
2925   u32 i = va_arg (*va, u32);
2926
2927   if (i == SSE2_QOS_RATE_KBPS)
2928     s = format (s, "kbps");
2929   else if (i == SSE2_QOS_RATE_PPS)
2930     s = format (s, "pps");
2931   else
2932     s = format (s, "ILLEGAL");
2933   return s;
2934 }
2935
2936 static u8 *
2937 format_policer_round_type (u8 * s, va_list * va)
2938 {
2939   u32 i = va_arg (*va, u32);
2940
2941   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2942     s = format (s, "closest");
2943   else if (i == SSE2_QOS_ROUND_TO_UP)
2944     s = format (s, "up");
2945   else if (i == SSE2_QOS_ROUND_TO_DOWN)
2946     s = format (s, "down");
2947   else
2948     s = format (s, "ILLEGAL");
2949   return s;
2950 }
2951
2952 static u8 *
2953 format_policer_action_type (u8 * s, va_list * va)
2954 {
2955   u32 i = va_arg (*va, u32);
2956
2957   if (i == SSE2_QOS_ACTION_DROP)
2958     s = format (s, "drop");
2959   else if (i == SSE2_QOS_ACTION_TRANSMIT)
2960     s = format (s, "transmit");
2961   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2962     s = format (s, "mark-and-transmit");
2963   else
2964     s = format (s, "ILLEGAL");
2965   return s;
2966 }
2967
2968 static u8 *
2969 format_dscp (u8 * s, va_list * va)
2970 {
2971   u32 i = va_arg (*va, u32);
2972   char *t = 0;
2973
2974   switch (i)
2975     {
2976 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
2977       foreach_vnet_dscp
2978 #undef _
2979     default:
2980       return format (s, "ILLEGAL");
2981     }
2982   s = format (s, "%s", t);
2983   return s;
2984 }
2985
2986 static void
2987 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
2988 {
2989   vat_main_t *vam = &vat_main;
2990   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2991
2992   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2993     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2994   else
2995     conform_dscp_str = format (0, "");
2996
2997   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2998     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2999   else
3000     exceed_dscp_str = format (0, "");
3001
3002   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3003     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3004   else
3005     violate_dscp_str = format (0, "");
3006
3007   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
3008          "rate type %U, round type %U, %s rate, %s color-aware, "
3009          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
3010          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
3011          "conform action %U%s, exceed action %U%s, violate action %U%s",
3012          mp->name,
3013          format_policer_type, mp->type,
3014          ntohl (mp->cir),
3015          ntohl (mp->eir),
3016          clib_net_to_host_u64 (mp->cb),
3017          clib_net_to_host_u64 (mp->eb),
3018          format_policer_rate_type, mp->rate_type,
3019          format_policer_round_type, mp->round_type,
3020          mp->single_rate ? "single" : "dual",
3021          mp->color_aware ? "is" : "not",
3022          ntohl (mp->cir_tokens_per_period),
3023          ntohl (mp->pir_tokens_per_period),
3024          ntohl (mp->scale),
3025          ntohl (mp->current_limit),
3026          ntohl (mp->current_bucket),
3027          ntohl (mp->extended_limit),
3028          ntohl (mp->extended_bucket),
3029          clib_net_to_host_u64 (mp->last_update_time),
3030          format_policer_action_type, mp->conform_action_type,
3031          conform_dscp_str,
3032          format_policer_action_type, mp->exceed_action_type,
3033          exceed_dscp_str,
3034          format_policer_action_type, mp->violate_action_type,
3035          violate_dscp_str);
3036
3037   vec_free (conform_dscp_str);
3038   vec_free (exceed_dscp_str);
3039   vec_free (violate_dscp_str);
3040 }
3041
3042 static void vl_api_policer_details_t_handler_json
3043   (vl_api_policer_details_t * mp)
3044 {
3045   vat_main_t *vam = &vat_main;
3046   vat_json_node_t *node;
3047   u8 *rate_type_str, *round_type_str, *type_str;
3048   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3049
3050   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3051   round_type_str =
3052     format (0, "%U", format_policer_round_type, mp->round_type);
3053   type_str = format (0, "%U", format_policer_type, mp->type);
3054   conform_action_str = format (0, "%U", format_policer_action_type,
3055                                mp->conform_action_type);
3056   exceed_action_str = format (0, "%U", format_policer_action_type,
3057                               mp->exceed_action_type);
3058   violate_action_str = format (0, "%U", format_policer_action_type,
3059                                mp->violate_action_type);
3060
3061   if (VAT_JSON_ARRAY != vam->json_tree.type)
3062     {
3063       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3064       vat_json_init_array (&vam->json_tree);
3065     }
3066   node = vat_json_array_add (&vam->json_tree);
3067
3068   vat_json_init_object (node);
3069   vat_json_object_add_string_copy (node, "name", mp->name);
3070   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3071   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3072   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
3073   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
3074   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3075   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3076   vat_json_object_add_string_copy (node, "type", type_str);
3077   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3078   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3079   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3080   vat_json_object_add_uint (node, "cir_tokens_per_period",
3081                             ntohl (mp->cir_tokens_per_period));
3082   vat_json_object_add_uint (node, "eir_tokens_per_period",
3083                             ntohl (mp->pir_tokens_per_period));
3084   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3085   vat_json_object_add_uint (node, "current_bucket",
3086                             ntohl (mp->current_bucket));
3087   vat_json_object_add_uint (node, "extended_limit",
3088                             ntohl (mp->extended_limit));
3089   vat_json_object_add_uint (node, "extended_bucket",
3090                             ntohl (mp->extended_bucket));
3091   vat_json_object_add_uint (node, "last_update_time",
3092                             ntohl (mp->last_update_time));
3093   vat_json_object_add_string_copy (node, "conform_action",
3094                                    conform_action_str);
3095   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3096     {
3097       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3098       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3099       vec_free (dscp_str);
3100     }
3101   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3102   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3103     {
3104       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3105       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3106       vec_free (dscp_str);
3107     }
3108   vat_json_object_add_string_copy (node, "violate_action",
3109                                    violate_action_str);
3110   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3111     {
3112       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3113       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3114       vec_free (dscp_str);
3115     }
3116
3117   vec_free (rate_type_str);
3118   vec_free (round_type_str);
3119   vec_free (type_str);
3120   vec_free (conform_action_str);
3121   vec_free (exceed_action_str);
3122   vec_free (violate_action_str);
3123 }
3124
3125 static void
3126 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3127                                            mp)
3128 {
3129   vat_main_t *vam = &vat_main;
3130   int i, count = ntohl (mp->count);
3131
3132   if (count > 0)
3133     print (vam->ofp, "classify table ids (%d) : ", count);
3134   for (i = 0; i < count; i++)
3135     {
3136       print (vam->ofp, "%d", ntohl (mp->ids[i]));
3137       print (vam->ofp, (i < count - 1) ? "," : "");
3138     }
3139   vam->retval = ntohl (mp->retval);
3140   vam->result_ready = 1;
3141 }
3142
3143 static void
3144   vl_api_classify_table_ids_reply_t_handler_json
3145   (vl_api_classify_table_ids_reply_t * mp)
3146 {
3147   vat_main_t *vam = &vat_main;
3148   int i, count = ntohl (mp->count);
3149
3150   if (count > 0)
3151     {
3152       vat_json_node_t node;
3153
3154       vat_json_init_object (&node);
3155       for (i = 0; i < count; i++)
3156         {
3157           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3158         }
3159       vat_json_print (vam->ofp, &node);
3160       vat_json_free (&node);
3161     }
3162   vam->retval = ntohl (mp->retval);
3163   vam->result_ready = 1;
3164 }
3165
3166 static void
3167   vl_api_classify_table_by_interface_reply_t_handler
3168   (vl_api_classify_table_by_interface_reply_t * mp)
3169 {
3170   vat_main_t *vam = &vat_main;
3171   u32 table_id;
3172
3173   table_id = ntohl (mp->l2_table_id);
3174   if (table_id != ~0)
3175     print (vam->ofp, "l2 table id : %d", table_id);
3176   else
3177     print (vam->ofp, "l2 table id : No input ACL tables configured");
3178   table_id = ntohl (mp->ip4_table_id);
3179   if (table_id != ~0)
3180     print (vam->ofp, "ip4 table id : %d", table_id);
3181   else
3182     print (vam->ofp, "ip4 table id : No input ACL tables configured");
3183   table_id = ntohl (mp->ip6_table_id);
3184   if (table_id != ~0)
3185     print (vam->ofp, "ip6 table id : %d", table_id);
3186   else
3187     print (vam->ofp, "ip6 table id : No input ACL tables configured");
3188   vam->retval = ntohl (mp->retval);
3189   vam->result_ready = 1;
3190 }
3191
3192 static void
3193   vl_api_classify_table_by_interface_reply_t_handler_json
3194   (vl_api_classify_table_by_interface_reply_t * mp)
3195 {
3196   vat_main_t *vam = &vat_main;
3197   vat_json_node_t node;
3198
3199   vat_json_init_object (&node);
3200
3201   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3202   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3203   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3204
3205   vat_json_print (vam->ofp, &node);
3206   vat_json_free (&node);
3207
3208   vam->retval = ntohl (mp->retval);
3209   vam->result_ready = 1;
3210 }
3211
3212 static void vl_api_policer_add_del_reply_t_handler
3213   (vl_api_policer_add_del_reply_t * mp)
3214 {
3215   vat_main_t *vam = &vat_main;
3216   i32 retval = ntohl (mp->retval);
3217   if (vam->async_mode)
3218     {
3219       vam->async_errors += (retval < 0);
3220     }
3221   else
3222     {
3223       vam->retval = retval;
3224       vam->result_ready = 1;
3225       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3226         /*
3227          * Note: this is just barely thread-safe, depends on
3228          * the main thread spinning waiting for an answer...
3229          */
3230         errmsg ("policer index %d", ntohl (mp->policer_index));
3231     }
3232 }
3233
3234 static void vl_api_policer_add_del_reply_t_handler_json
3235   (vl_api_policer_add_del_reply_t * mp)
3236 {
3237   vat_main_t *vam = &vat_main;
3238   vat_json_node_t node;
3239
3240   vat_json_init_object (&node);
3241   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3242   vat_json_object_add_uint (&node, "policer_index",
3243                             ntohl (mp->policer_index));
3244
3245   vat_json_print (vam->ofp, &node);
3246   vat_json_free (&node);
3247
3248   vam->retval = ntohl (mp->retval);
3249   vam->result_ready = 1;
3250 }
3251
3252 /* Format hex dump. */
3253 u8 *
3254 format_hex_bytes (u8 * s, va_list * va)
3255 {
3256   u8 *bytes = va_arg (*va, u8 *);
3257   int n_bytes = va_arg (*va, int);
3258   uword i;
3259
3260   /* Print short or long form depending on byte count. */
3261   uword short_form = n_bytes <= 32;
3262   uword indent = format_get_indent (s);
3263
3264   if (n_bytes == 0)
3265     return s;
3266
3267   for (i = 0; i < n_bytes; i++)
3268     {
3269       if (!short_form && (i % 32) == 0)
3270         s = format (s, "%08x: ", i);
3271       s = format (s, "%02x", bytes[i]);
3272       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3273         s = format (s, "\n%U", format_white_space, indent);
3274     }
3275
3276   return s;
3277 }
3278
3279 static void
3280 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3281                                             * mp)
3282 {
3283   vat_main_t *vam = &vat_main;
3284   i32 retval = ntohl (mp->retval);
3285   if (retval == 0)
3286     {
3287       print (vam->ofp, "classify table info :");
3288       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
3289              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3290              ntohl (mp->miss_next_index));
3291       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
3292              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3293              ntohl (mp->match_n_vectors));
3294       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
3295              ntohl (mp->mask_length));
3296     }
3297   vam->retval = retval;
3298   vam->result_ready = 1;
3299 }
3300
3301 static void
3302   vl_api_classify_table_info_reply_t_handler_json
3303   (vl_api_classify_table_info_reply_t * mp)
3304 {
3305   vat_main_t *vam = &vat_main;
3306   vat_json_node_t node;
3307
3308   i32 retval = ntohl (mp->retval);
3309   if (retval == 0)
3310     {
3311       vat_json_init_object (&node);
3312
3313       vat_json_object_add_int (&node, "sessions",
3314                                ntohl (mp->active_sessions));
3315       vat_json_object_add_int (&node, "nexttbl",
3316                                ntohl (mp->next_table_index));
3317       vat_json_object_add_int (&node, "nextnode",
3318                                ntohl (mp->miss_next_index));
3319       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3320       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3321       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3322       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3323                       ntohl (mp->mask_length), 0);
3324       vat_json_object_add_string_copy (&node, "mask", s);
3325
3326       vat_json_print (vam->ofp, &node);
3327       vat_json_free (&node);
3328     }
3329   vam->retval = ntohl (mp->retval);
3330   vam->result_ready = 1;
3331 }
3332
3333 static void
3334 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3335                                            mp)
3336 {
3337   vat_main_t *vam = &vat_main;
3338
3339   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3340          ntohl (mp->hit_next_index), ntohl (mp->advance),
3341          ntohl (mp->opaque_index));
3342   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
3343          ntohl (mp->match_length));
3344 }
3345
3346 static void
3347   vl_api_classify_session_details_t_handler_json
3348   (vl_api_classify_session_details_t * mp)
3349 {
3350   vat_main_t *vam = &vat_main;
3351   vat_json_node_t *node = NULL;
3352
3353   if (VAT_JSON_ARRAY != vam->json_tree.type)
3354     {
3355       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3356       vat_json_init_array (&vam->json_tree);
3357     }
3358   node = vat_json_array_add (&vam->json_tree);
3359
3360   vat_json_init_object (node);
3361   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3362   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3363   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3364   u8 *s =
3365     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3366             0);
3367   vat_json_object_add_string_copy (node, "match", s);
3368 }
3369
3370 static void vl_api_pg_create_interface_reply_t_handler
3371   (vl_api_pg_create_interface_reply_t * mp)
3372 {
3373   vat_main_t *vam = &vat_main;
3374
3375   vam->retval = ntohl (mp->retval);
3376   vam->result_ready = 1;
3377 }
3378
3379 static void vl_api_pg_create_interface_reply_t_handler_json
3380   (vl_api_pg_create_interface_reply_t * mp)
3381 {
3382   vat_main_t *vam = &vat_main;
3383   vat_json_node_t node;
3384
3385   i32 retval = ntohl (mp->retval);
3386   if (retval == 0)
3387     {
3388       vat_json_init_object (&node);
3389
3390       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3391
3392       vat_json_print (vam->ofp, &node);
3393       vat_json_free (&node);
3394     }
3395   vam->retval = ntohl (mp->retval);
3396   vam->result_ready = 1;
3397 }
3398
3399 static void vl_api_policer_classify_details_t_handler
3400   (vl_api_policer_classify_details_t * mp)
3401 {
3402   vat_main_t *vam = &vat_main;
3403
3404   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3405          ntohl (mp->table_index));
3406 }
3407
3408 static void vl_api_policer_classify_details_t_handler_json
3409   (vl_api_policer_classify_details_t * mp)
3410 {
3411   vat_main_t *vam = &vat_main;
3412   vat_json_node_t *node;
3413
3414   if (VAT_JSON_ARRAY != vam->json_tree.type)
3415     {
3416       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3417       vat_json_init_array (&vam->json_tree);
3418     }
3419   node = vat_json_array_add (&vam->json_tree);
3420
3421   vat_json_init_object (node);
3422   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3423   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3424 }
3425
3426 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3427   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3428 {
3429   vat_main_t *vam = &vat_main;
3430   i32 retval = ntohl (mp->retval);
3431   if (vam->async_mode)
3432     {
3433       vam->async_errors += (retval < 0);
3434     }
3435   else
3436     {
3437       vam->retval = retval;
3438       vam->sw_if_index = ntohl (mp->sw_if_index);
3439       vam->result_ready = 1;
3440     }
3441 }
3442
3443 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3444   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3445 {
3446   vat_main_t *vam = &vat_main;
3447   vat_json_node_t node;
3448
3449   vat_json_init_object (&node);
3450   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3451   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3452
3453   vat_json_print (vam->ofp, &node);
3454   vat_json_free (&node);
3455
3456   vam->retval = ntohl (mp->retval);
3457   vam->result_ready = 1;
3458 }
3459
3460 static void vl_api_flow_classify_details_t_handler
3461   (vl_api_flow_classify_details_t * mp)
3462 {
3463   vat_main_t *vam = &vat_main;
3464
3465   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3466          ntohl (mp->table_index));
3467 }
3468
3469 static void vl_api_flow_classify_details_t_handler_json
3470   (vl_api_flow_classify_details_t * mp)
3471 {
3472   vat_main_t *vam = &vat_main;
3473   vat_json_node_t *node;
3474
3475   if (VAT_JSON_ARRAY != vam->json_tree.type)
3476     {
3477       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3478       vat_json_init_array (&vam->json_tree);
3479     }
3480   node = vat_json_array_add (&vam->json_tree);
3481
3482   vat_json_init_object (node);
3483   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3484   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3485 }
3486
3487
3488
3489 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3490 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3491 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3492 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3493 #define vl_api_lisp_adjacencies_get_reply_t_endian vl_noop_handler
3494 #define vl_api_lisp_adjacencies_get_reply_t_print vl_noop_handler
3495
3496 /*
3497  * Generate boilerplate reply handlers, which
3498  * dig the return value out of the xxx_reply_t API message,
3499  * stick it into vam->retval, and set vam->result_ready
3500  *
3501  * Could also do this by pointing N message decode slots at
3502  * a single function, but that could break in subtle ways.
3503  */
3504
3505 #define foreach_standard_reply_retval_handler           \
3506 _(sw_interface_set_flags_reply)                         \
3507 _(sw_interface_add_del_address_reply)                   \
3508 _(sw_interface_set_table_reply)                         \
3509 _(sw_interface_set_mpls_enable_reply)                   \
3510 _(sw_interface_set_vpath_reply)                         \
3511 _(sw_interface_set_vxlan_bypass_reply)                  \
3512 _(sw_interface_set_l2_bridge_reply)                     \
3513 _(bridge_domain_add_del_reply)                          \
3514 _(sw_interface_set_l2_xconnect_reply)                   \
3515 _(l2fib_add_del_reply)                                  \
3516 _(ip_add_del_route_reply)                               \
3517 _(mpls_route_add_del_reply)                             \
3518 _(mpls_ip_bind_unbind_reply)                            \
3519 _(proxy_arp_add_del_reply)                              \
3520 _(proxy_arp_intfc_enable_disable_reply)                 \
3521 _(sw_interface_set_unnumbered_reply)                    \
3522 _(ip_neighbor_add_del_reply)                            \
3523 _(reset_vrf_reply)                                      \
3524 _(oam_add_del_reply)                                    \
3525 _(reset_fib_reply)                                      \
3526 _(dhcp_proxy_config_reply)                              \
3527 _(dhcp_proxy_config_2_reply)                            \
3528 _(dhcp_proxy_set_vss_reply)                             \
3529 _(dhcp_client_config_reply)                             \
3530 _(set_ip_flow_hash_reply)                               \
3531 _(sw_interface_ip6_enable_disable_reply)                \
3532 _(sw_interface_ip6_set_link_local_address_reply)        \
3533 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3534 _(sw_interface_ip6nd_ra_config_reply)                   \
3535 _(set_arp_neighbor_limit_reply)                         \
3536 _(l2_patch_add_del_reply)                               \
3537 _(sr_tunnel_add_del_reply)                              \
3538 _(sr_policy_add_del_reply)                              \
3539 _(sr_multicast_map_add_del_reply)                       \
3540 _(classify_add_del_session_reply)                       \
3541 _(classify_set_interface_ip_table_reply)                \
3542 _(classify_set_interface_l2_tables_reply)               \
3543 _(l2tpv3_set_tunnel_cookies_reply)                      \
3544 _(l2tpv3_interface_enable_disable_reply)                \
3545 _(l2tpv3_set_lookup_key_reply)                          \
3546 _(l2_fib_clear_table_reply)                             \
3547 _(l2_interface_efp_filter_reply)                        \
3548 _(l2_interface_vlan_tag_rewrite_reply)                  \
3549 _(modify_vhost_user_if_reply)                           \
3550 _(delete_vhost_user_if_reply)                           \
3551 _(want_ip4_arp_events_reply)                            \
3552 _(want_ip6_nd_events_reply)                             \
3553 _(input_acl_set_interface_reply)                        \
3554 _(ipsec_spd_add_del_reply)                              \
3555 _(ipsec_interface_add_del_spd_reply)                    \
3556 _(ipsec_spd_add_del_entry_reply)                        \
3557 _(ipsec_sad_add_del_entry_reply)                        \
3558 _(ipsec_sa_set_key_reply)                               \
3559 _(ikev2_profile_add_del_reply)                          \
3560 _(ikev2_profile_set_auth_reply)                         \
3561 _(ikev2_profile_set_id_reply)                           \
3562 _(ikev2_profile_set_ts_reply)                           \
3563 _(ikev2_set_local_key_reply)                            \
3564 _(delete_loopback_reply)                                \
3565 _(bd_ip_mac_add_del_reply)                              \
3566 _(map_del_domain_reply)                                 \
3567 _(map_add_del_rule_reply)                               \
3568 _(want_interface_events_reply)                          \
3569 _(want_stats_reply)                                     \
3570 _(cop_interface_enable_disable_reply)                   \
3571 _(cop_whitelist_enable_disable_reply)                   \
3572 _(sw_interface_clear_stats_reply)                       \
3573 _(ioam_enable_reply)                              \
3574 _(ioam_disable_reply)                              \
3575 _(lisp_add_del_locator_reply)                           \
3576 _(lisp_add_del_local_eid_reply)                         \
3577 _(lisp_add_del_remote_mapping_reply)                    \
3578 _(lisp_add_del_adjacency_reply)                         \
3579 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3580 _(lisp_add_del_map_resolver_reply)                      \
3581 _(lisp_add_del_map_server_reply)                        \
3582 _(lisp_gpe_enable_disable_reply)                        \
3583 _(lisp_gpe_add_del_iface_reply)                         \
3584 _(lisp_enable_disable_reply)                            \
3585 _(lisp_rloc_probe_enable_disable_reply)                 \
3586 _(lisp_map_register_enable_disable_reply)               \
3587 _(lisp_pitr_set_locator_set_reply)                      \
3588 _(lisp_map_request_mode_reply)                          \
3589 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3590 _(lisp_eid_table_add_del_map_reply)                     \
3591 _(vxlan_gpe_add_del_tunnel_reply)                       \
3592 _(af_packet_delete_reply)                               \
3593 _(policer_classify_set_interface_reply)                 \
3594 _(netmap_create_reply)                                  \
3595 _(netmap_delete_reply)                                  \
3596 _(set_ipfix_exporter_reply)                             \
3597 _(set_ipfix_classify_stream_reply)                      \
3598 _(ipfix_classify_table_add_del_reply)                   \
3599 _(flow_classify_set_interface_reply)                    \
3600 _(sw_interface_span_enable_disable_reply)               \
3601 _(pg_capture_reply)                                     \
3602 _(pg_enable_disable_reply)                              \
3603 _(ip_source_and_port_range_check_add_del_reply)         \
3604 _(ip_source_and_port_range_check_interface_add_del_reply)\
3605 _(delete_subif_reply)                                   \
3606 _(l2_interface_pbb_tag_rewrite_reply)                   \
3607 _(punt_reply)                                           \
3608 _(feature_enable_disable_reply)                         \
3609 _(sw_interface_tag_add_del_reply)                       \
3610 _(sw_interface_set_mtu_reply)
3611
3612 #if DPDK > 0
3613 #define foreach_standard_dpdk_reply_retval_handler      \
3614 _(sw_interface_set_dpdk_hqos_pipe_reply)                \
3615 _(sw_interface_set_dpdk_hqos_subport_reply)             \
3616 _(sw_interface_set_dpdk_hqos_tctbl_reply)
3617 #endif
3618
3619 #define _(n)                                    \
3620     static void vl_api_##n##_t_handler          \
3621     (vl_api_##n##_t * mp)                       \
3622     {                                           \
3623         vat_main_t * vam = &vat_main;           \
3624         i32 retval = ntohl(mp->retval);         \
3625         if (vam->async_mode) {                  \
3626             vam->async_errors += (retval < 0);  \
3627         } else {                                \
3628             vam->retval = retval;               \
3629             vam->result_ready = 1;              \
3630         }                                       \
3631     }
3632 foreach_standard_reply_retval_handler;
3633 #undef _
3634
3635 #define _(n)                                    \
3636     static void vl_api_##n##_t_handler_json     \
3637     (vl_api_##n##_t * mp)                       \
3638     {                                           \
3639         vat_main_t * vam = &vat_main;           \
3640         vat_json_node_t node;                   \
3641         vat_json_init_object(&node);            \
3642         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3643         vat_json_print(vam->ofp, &node);        \
3644         vam->retval = ntohl(mp->retval);        \
3645         vam->result_ready = 1;                  \
3646     }
3647 foreach_standard_reply_retval_handler;
3648 #undef _
3649
3650 #if DPDK > 0
3651 #define _(n)                                    \
3652     static void vl_api_##n##_t_handler          \
3653     (vl_api_##n##_t * mp)                       \
3654     {                                           \
3655         vat_main_t * vam = &vat_main;           \
3656         i32 retval = ntohl(mp->retval);         \
3657         if (vam->async_mode) {                  \
3658             vam->async_errors += (retval < 0);  \
3659         } else {                                \
3660             vam->retval = retval;               \
3661             vam->result_ready = 1;              \
3662         }                                       \
3663     }
3664 foreach_standard_dpdk_reply_retval_handler;
3665 #undef _
3666
3667 #define _(n)                                    \
3668     static void vl_api_##n##_t_handler_json     \
3669     (vl_api_##n##_t * mp)                       \
3670     {                                           \
3671         vat_main_t * vam = &vat_main;           \
3672         vat_json_node_t node;                   \
3673         vat_json_init_object(&node);            \
3674         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3675         vat_json_print(vam->ofp, &node);        \
3676         vam->retval = ntohl(mp->retval);        \
3677         vam->result_ready = 1;                  \
3678     }
3679 foreach_standard_dpdk_reply_retval_handler;
3680 #undef _
3681 #endif
3682
3683 /*
3684  * Table of message reply handlers, must include boilerplate handlers
3685  * we just generated
3686  */
3687
3688 #define foreach_vpe_api_reply_msg                                       \
3689 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3690 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3691 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3692 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3693 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3694 _(CLI_REPLY, cli_reply)                                                 \
3695 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
3696 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3697   sw_interface_add_del_address_reply)                                   \
3698 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3699 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
3700 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3701 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
3702 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3703   sw_interface_set_l2_xconnect_reply)                                   \
3704 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3705   sw_interface_set_l2_bridge_reply)                                     \
3706 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3707 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3708 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3709 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3710 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3711 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3712 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3713 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3714 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3715 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3716 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3717 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
3718 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
3719 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
3720 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
3721   proxy_arp_intfc_enable_disable_reply)                                 \
3722 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
3723 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3724   sw_interface_set_unnumbered_reply)                                    \
3725 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
3726 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
3727 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3728 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3729 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
3730 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
3731 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
3732 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
3733 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
3734 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
3735 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3736 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3737   sw_interface_ip6_enable_disable_reply)                                \
3738 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
3739   sw_interface_ip6_set_link_local_address_reply)                        \
3740 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
3741   sw_interface_ip6nd_ra_prefix_reply)                                   \
3742 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
3743   sw_interface_ip6nd_ra_config_reply)                                   \
3744 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
3745 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3746 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
3747 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
3748 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
3749 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3750 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3751 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3752 classify_set_interface_ip_table_reply)                                  \
3753 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3754   classify_set_interface_l2_tables_reply)                               \
3755 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3756 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3757 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
3758 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
3759 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
3760   l2tpv3_interface_enable_disable_reply)                                \
3761 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
3762 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
3763 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3764 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3765 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
3766 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
3767 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3768 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3769 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3770 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3771 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3772 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3773 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3774 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3775 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
3776 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
3777 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3778 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3779 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
3780 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
3781 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
3782 _(IP6_ND_EVENT, ip6_nd_event)                                           \
3783 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3784 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3785 _(IP_DETAILS, ip_details)                                               \
3786 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3787 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3788 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
3789 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
3790 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
3791 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
3792 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
3793 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
3794 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
3795 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
3796 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3797 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3798 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
3799 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
3800 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
3801 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
3802 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
3803 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
3804 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
3805 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
3806 _(MAP_RULE_DETAILS, map_rule_details)                                   \
3807 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3808 _(WANT_STATS_REPLY, want_stats_reply)                                   \
3809 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3810 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3811 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3812 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3813 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3814 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
3815 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
3816 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
3817 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
3818 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
3819 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3820 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
3821 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
3822 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
3823 _(LISP_ADD_DEL_MAP_SERVER_REPLY, lisp_add_del_map_server_reply)         \
3824 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
3825 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
3826 _(LISP_MAP_REGISTER_ENABLE_DISABLE_REPLY,                               \
3827   lisp_map_register_enable_disable_reply)                               \
3828 _(LISP_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                 \
3829   lisp_rloc_probe_enable_disable_reply)                                 \
3830 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
3831 _(LISP_MAP_REQUEST_MODE_REPLY, lisp_map_request_mode_reply)             \
3832 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
3833 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
3834 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
3835 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
3836 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
3837 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
3838 _(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details)               \
3839 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
3840 _(LISP_MAP_SERVER_DETAILS, lisp_map_server_details)                     \
3841 _(LISP_ADJACENCIES_GET_REPLY, lisp_adjacencies_get_reply)               \
3842 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
3843 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
3844   lisp_add_del_map_request_itr_rlocs_reply)                             \
3845 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
3846   lisp_get_map_request_itr_rlocs_reply)                                 \
3847 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
3848 _(SHOW_LISP_MAP_REQUEST_MODE_REPLY, show_lisp_map_request_mode_reply)   \
3849 _(SHOW_LISP_RLOC_PROBE_STATE_REPLY, show_lisp_rloc_probe_state_reply)   \
3850 _(SHOW_LISP_MAP_REGISTER_STATE_REPLY,                                   \
3851   show_lisp_map_register_state_reply)                                   \
3852 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3853 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3854 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3855 _(POLICER_DETAILS, policer_details)                                     \
3856 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3857 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3858 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
3859 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
3860 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
3861 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
3862 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3863 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3864 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3865 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3866 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
3867 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
3868 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
3869 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
3870 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
3871 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
3872 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
3873 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
3874 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
3875 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
3876 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3877 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3878 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3879 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3880 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3881  ip_source_and_port_range_check_add_del_reply)                          \
3882 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3883  ip_source_and_port_range_check_interface_add_del_reply)                \
3884 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
3885 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
3886 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
3887 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
3888 _(PUNT_REPLY, punt_reply)                                               \
3889 _(IP_FIB_DETAILS, ip_fib_details)                                       \
3890 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
3891 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
3892 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
3893 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
3894 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
3895 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
3896 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)
3897
3898 #if DPDK > 0
3899 #define foreach_vpe_dpdk_api_reply_msg                                  \
3900 _(SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY,                                \
3901   sw_interface_set_dpdk_hqos_pipe_reply)                                \
3902 _(SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY,                             \
3903   sw_interface_set_dpdk_hqos_subport_reply)                             \
3904 _(SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY,                               \
3905   sw_interface_set_dpdk_hqos_tctbl_reply)
3906 #endif
3907
3908 typedef struct
3909 {
3910   u8 *name;
3911   u32 value;
3912 } name_sort_t;
3913
3914
3915 #define STR_VTR_OP_CASE(op)     \
3916     case L2_VTR_ ## op:         \
3917         return "" # op;
3918
3919 static const char *
3920 str_vtr_op (u32 vtr_op)
3921 {
3922   switch (vtr_op)
3923     {
3924       STR_VTR_OP_CASE (DISABLED);
3925       STR_VTR_OP_CASE (PUSH_1);
3926       STR_VTR_OP_CASE (PUSH_2);
3927       STR_VTR_OP_CASE (POP_1);
3928       STR_VTR_OP_CASE (POP_2);
3929       STR_VTR_OP_CASE (TRANSLATE_1_1);
3930       STR_VTR_OP_CASE (TRANSLATE_1_2);
3931       STR_VTR_OP_CASE (TRANSLATE_2_1);
3932       STR_VTR_OP_CASE (TRANSLATE_2_2);
3933     }
3934
3935   return "UNKNOWN";
3936 }
3937
3938 static int
3939 dump_sub_interface_table (vat_main_t * vam)
3940 {
3941   const sw_interface_subif_t *sub = NULL;
3942
3943   if (vam->json_output)
3944     {
3945       clib_warning
3946         ("JSON output supported only for VPE API calls and dump_stats_table");
3947       return -99;
3948     }
3949
3950   print (vam->ofp,
3951          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
3952          "Interface", "sw_if_index",
3953          "sub id", "dot1ad", "tags", "outer id",
3954          "inner id", "exact", "default", "outer any", "inner any");
3955
3956   vec_foreach (sub, vam->sw_if_subif_table)
3957   {
3958     print (vam->ofp,
3959            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
3960            sub->interface_name,
3961            sub->sw_if_index,
3962            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3963            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3964            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3965            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3966     if (sub->vtr_op != L2_VTR_DISABLED)
3967       {
3968         print (vam->ofp,
3969                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3970                "tag1: %d tag2: %d ]",
3971                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3972                sub->vtr_tag1, sub->vtr_tag2);
3973       }
3974   }
3975
3976   return 0;
3977 }
3978
3979 static int
3980 name_sort_cmp (void *a1, void *a2)
3981 {
3982   name_sort_t *n1 = a1;
3983   name_sort_t *n2 = a2;
3984
3985   return strcmp ((char *) n1->name, (char *) n2->name);
3986 }
3987
3988 static int
3989 dump_interface_table (vat_main_t * vam)
3990 {
3991   hash_pair_t *p;
3992   name_sort_t *nses = 0, *ns;
3993
3994   if (vam->json_output)
3995     {
3996       clib_warning
3997         ("JSON output supported only for VPE API calls and dump_stats_table");
3998       return -99;
3999     }
4000
4001   /* *INDENT-OFF* */
4002   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4003   ({
4004     vec_add2 (nses, ns, 1);
4005     ns->name = (u8 *)(p->key);
4006     ns->value = (u32) p->value[0];
4007   }));
4008   /* *INDENT-ON* */
4009
4010   vec_sort_with_function (nses, name_sort_cmp);
4011
4012   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
4013   vec_foreach (ns, nses)
4014   {
4015     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
4016   }
4017   vec_free (nses);
4018   return 0;
4019 }
4020
4021 static int
4022 dump_ip_table (vat_main_t * vam, int is_ipv6)
4023 {
4024   const ip_details_t *det = NULL;
4025   const ip_address_details_t *address = NULL;
4026   u32 i = ~0;
4027
4028   print (vam->ofp, "%-12s", "sw_if_index");
4029
4030   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
4031   {
4032     i++;
4033     if (!det->present)
4034       {
4035         continue;
4036       }
4037     print (vam->ofp, "%-12d", i);
4038     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
4039     if (!det->addr)
4040       {
4041         continue;
4042       }
4043     vec_foreach (address, det->addr)
4044     {
4045       print (vam->ofp,
4046              "            %-30U%-13d",
4047              is_ipv6 ? format_ip6_address : format_ip4_address,
4048              address->ip, address->prefix_length);
4049     }
4050   }
4051
4052   return 0;
4053 }
4054
4055 static int
4056 dump_ipv4_table (vat_main_t * vam)
4057 {
4058   if (vam->json_output)
4059     {
4060       clib_warning
4061         ("JSON output supported only for VPE API calls and dump_stats_table");
4062       return -99;
4063     }
4064
4065   return dump_ip_table (vam, 0);
4066 }
4067
4068 static int
4069 dump_ipv6_table (vat_main_t * vam)
4070 {
4071   if (vam->json_output)
4072     {
4073       clib_warning
4074         ("JSON output supported only for VPE API calls and dump_stats_table");
4075       return -99;
4076     }
4077
4078   return dump_ip_table (vam, 1);
4079 }
4080
4081 static char *
4082 counter_type_to_str (u8 counter_type, u8 is_combined)
4083 {
4084   if (!is_combined)
4085     {
4086       switch (counter_type)
4087         {
4088         case VNET_INTERFACE_COUNTER_DROP:
4089           return "drop";
4090         case VNET_INTERFACE_COUNTER_PUNT:
4091           return "punt";
4092         case VNET_INTERFACE_COUNTER_IP4:
4093           return "ip4";
4094         case VNET_INTERFACE_COUNTER_IP6:
4095           return "ip6";
4096         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4097           return "rx-no-buf";
4098         case VNET_INTERFACE_COUNTER_RX_MISS:
4099           return "rx-miss";
4100         case VNET_INTERFACE_COUNTER_RX_ERROR:
4101           return "rx-error";
4102         case VNET_INTERFACE_COUNTER_TX_ERROR:
4103           return "tx-error";
4104         default:
4105           return "INVALID-COUNTER-TYPE";
4106         }
4107     }
4108   else
4109     {
4110       switch (counter_type)
4111         {
4112         case VNET_INTERFACE_COUNTER_RX:
4113           return "rx";
4114         case VNET_INTERFACE_COUNTER_TX:
4115           return "tx";
4116         default:
4117           return "INVALID-COUNTER-TYPE";
4118         }
4119     }
4120 }
4121
4122 static int
4123 dump_stats_table (vat_main_t * vam)
4124 {
4125   vat_json_node_t node;
4126   vat_json_node_t *msg_array;
4127   vat_json_node_t *msg;
4128   vat_json_node_t *counter_array;
4129   vat_json_node_t *counter;
4130   interface_counter_t c;
4131   u64 packets;
4132   ip4_fib_counter_t *c4;
4133   ip6_fib_counter_t *c6;
4134   int i, j;
4135
4136   if (!vam->json_output)
4137     {
4138       clib_warning ("dump_stats_table supported only in JSON format");
4139       return -99;
4140     }
4141
4142   vat_json_init_object (&node);
4143
4144   /* interface counters */
4145   msg_array = vat_json_object_add (&node, "interface_counters");
4146   vat_json_init_array (msg_array);
4147   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4148     {
4149       msg = vat_json_array_add (msg_array);
4150       vat_json_init_object (msg);
4151       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4152                                        (u8 *) counter_type_to_str (i, 0));
4153       vat_json_object_add_int (msg, "is_combined", 0);
4154       counter_array = vat_json_object_add (msg, "data");
4155       vat_json_init_array (counter_array);
4156       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4157         {
4158           packets = vam->simple_interface_counters[i][j];
4159           vat_json_array_add_uint (counter_array, packets);
4160         }
4161     }
4162   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4163     {
4164       msg = vat_json_array_add (msg_array);
4165       vat_json_init_object (msg);
4166       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4167                                        (u8 *) counter_type_to_str (i, 1));
4168       vat_json_object_add_int (msg, "is_combined", 1);
4169       counter_array = vat_json_object_add (msg, "data");
4170       vat_json_init_array (counter_array);
4171       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4172         {
4173           c = vam->combined_interface_counters[i][j];
4174           counter = vat_json_array_add (counter_array);
4175           vat_json_init_object (counter);
4176           vat_json_object_add_uint (counter, "packets", c.packets);
4177           vat_json_object_add_uint (counter, "bytes", c.bytes);
4178         }
4179     }
4180
4181   /* ip4 fib counters */
4182   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4183   vat_json_init_array (msg_array);
4184   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4185     {
4186       msg = vat_json_array_add (msg_array);
4187       vat_json_init_object (msg);
4188       vat_json_object_add_uint (msg, "vrf_id",
4189                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4190       counter_array = vat_json_object_add (msg, "c");
4191       vat_json_init_array (counter_array);
4192       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4193         {
4194           counter = vat_json_array_add (counter_array);
4195           vat_json_init_object (counter);
4196           c4 = &vam->ip4_fib_counters[i][j];
4197           vat_json_object_add_ip4 (counter, "address", c4->address);
4198           vat_json_object_add_uint (counter, "address_length",
4199                                     c4->address_length);
4200           vat_json_object_add_uint (counter, "packets", c4->packets);
4201           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4202         }
4203     }
4204
4205   /* ip6 fib counters */
4206   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4207   vat_json_init_array (msg_array);
4208   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4209     {
4210       msg = vat_json_array_add (msg_array);
4211       vat_json_init_object (msg);
4212       vat_json_object_add_uint (msg, "vrf_id",
4213                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4214       counter_array = vat_json_object_add (msg, "c");
4215       vat_json_init_array (counter_array);
4216       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4217         {
4218           counter = vat_json_array_add (counter_array);
4219           vat_json_init_object (counter);
4220           c6 = &vam->ip6_fib_counters[i][j];
4221           vat_json_object_add_ip6 (counter, "address", c6->address);
4222           vat_json_object_add_uint (counter, "address_length",
4223                                     c6->address_length);
4224           vat_json_object_add_uint (counter, "packets", c6->packets);
4225           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4226         }
4227     }
4228
4229   vat_json_print (vam->ofp, &node);
4230   vat_json_free (&node);
4231
4232   return 0;
4233 }
4234
4235 int
4236 exec (vat_main_t * vam)
4237 {
4238   api_main_t *am = &api_main;
4239   vl_api_cli_request_t *mp;
4240   f64 timeout;
4241   void *oldheap;
4242   u8 *cmd = 0;
4243   unformat_input_t *i = vam->input;
4244
4245   if (vec_len (i->buffer) == 0)
4246     return -1;
4247
4248   if (vam->exec_mode == 0 && unformat (i, "mode"))
4249     {
4250       vam->exec_mode = 1;
4251       return 0;
4252     }
4253   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4254     {
4255       vam->exec_mode = 0;
4256       return 0;
4257     }
4258
4259
4260   M (CLI_REQUEST, cli_request);
4261
4262   /*
4263    * Copy cmd into shared memory.
4264    * In order for the CLI command to work, it
4265    * must be a vector ending in \n, not a C-string ending
4266    * in \n\0.
4267    */
4268   pthread_mutex_lock (&am->vlib_rp->mutex);
4269   oldheap = svm_push_data_heap (am->vlib_rp);
4270
4271   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4272   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4273
4274   svm_pop_heap (oldheap);
4275   pthread_mutex_unlock (&am->vlib_rp->mutex);
4276
4277   mp->cmd_in_shmem = (u64) cmd;
4278   S;
4279   timeout = vat_time_now (vam) + 10.0;
4280
4281   while (vat_time_now (vam) < timeout)
4282     {
4283       if (vam->result_ready == 1)
4284         {
4285           u8 *free_me;
4286           if (vam->shmem_result != NULL)
4287             print (vam->ofp, "%s", vam->shmem_result);
4288           pthread_mutex_lock (&am->vlib_rp->mutex);
4289           oldheap = svm_push_data_heap (am->vlib_rp);
4290
4291           free_me = (u8 *) vam->shmem_result;
4292           vec_free (free_me);
4293
4294           svm_pop_heap (oldheap);
4295           pthread_mutex_unlock (&am->vlib_rp->mutex);
4296           return 0;
4297         }
4298     }
4299   return -99;
4300 }
4301
4302 /*
4303  * Future replacement of exec() that passes CLI buffers directly in
4304  * the API messages instead of an additional shared memory area.
4305  */
4306 static int
4307 exec_inband (vat_main_t * vam)
4308 {
4309   vl_api_cli_inband_t *mp;
4310   f64 timeout;
4311   unformat_input_t *i = vam->input;
4312
4313   if (vec_len (i->buffer) == 0)
4314     return -1;
4315
4316   if (vam->exec_mode == 0 && unformat (i, "mode"))
4317     {
4318       vam->exec_mode = 1;
4319       return 0;
4320     }
4321   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4322     {
4323       vam->exec_mode = 0;
4324       return 0;
4325     }
4326
4327   /*
4328    * In order for the CLI command to work, it
4329    * must be a vector ending in \n, not a C-string ending
4330    * in \n\0.
4331    */
4332   u32 len = vec_len (vam->input->buffer);
4333   M2 (CLI_INBAND, cli_inband, len);
4334   clib_memcpy (mp->cmd, vam->input->buffer, len);
4335   mp->length = htonl (len);
4336
4337   S;
4338   W2 (print (vam->ofp, "%s", vam->cmd_reply));
4339 }
4340
4341 static int
4342 api_create_loopback (vat_main_t * vam)
4343 {
4344   unformat_input_t *i = vam->input;
4345   vl_api_create_loopback_t *mp;
4346   f64 timeout;
4347   u8 mac_address[6];
4348   u8 mac_set = 0;
4349
4350   memset (mac_address, 0, sizeof (mac_address));
4351
4352   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4353     {
4354       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4355         mac_set = 1;
4356       else
4357         break;
4358     }
4359
4360   /* Construct the API message */
4361   M (CREATE_LOOPBACK, create_loopback);
4362   if (mac_set)
4363     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4364
4365   S;
4366   W;
4367 }
4368
4369 static int
4370 api_delete_loopback (vat_main_t * vam)
4371 {
4372   unformat_input_t *i = vam->input;
4373   vl_api_delete_loopback_t *mp;
4374   f64 timeout;
4375   u32 sw_if_index = ~0;
4376
4377   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4378     {
4379       if (unformat (i, "sw_if_index %d", &sw_if_index))
4380         ;
4381       else
4382         break;
4383     }
4384
4385   if (sw_if_index == ~0)
4386     {
4387       errmsg ("missing sw_if_index");
4388       return -99;
4389     }
4390
4391   /* Construct the API message */
4392   M (DELETE_LOOPBACK, delete_loopback);
4393   mp->sw_if_index = ntohl (sw_if_index);
4394
4395   S;
4396   W;
4397 }
4398
4399 static int
4400 api_want_stats (vat_main_t * vam)
4401 {
4402   unformat_input_t *i = vam->input;
4403   vl_api_want_stats_t *mp;
4404   f64 timeout;
4405   int enable = -1;
4406
4407   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4408     {
4409       if (unformat (i, "enable"))
4410         enable = 1;
4411       else if (unformat (i, "disable"))
4412         enable = 0;
4413       else
4414         break;
4415     }
4416
4417   if (enable == -1)
4418     {
4419       errmsg ("missing enable|disable");
4420       return -99;
4421     }
4422
4423   M (WANT_STATS, want_stats);
4424   mp->enable_disable = enable;
4425
4426   S;
4427   W;
4428 }
4429
4430 static int
4431 api_want_interface_events (vat_main_t * vam)
4432 {
4433   unformat_input_t *i = vam->input;
4434   vl_api_want_interface_events_t *mp;
4435   f64 timeout;
4436   int enable = -1;
4437
4438   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4439     {
4440       if (unformat (i, "enable"))
4441         enable = 1;
4442       else if (unformat (i, "disable"))
4443         enable = 0;
4444       else
4445         break;
4446     }
4447
4448   if (enable == -1)
4449     {
4450       errmsg ("missing enable|disable");
4451       return -99;
4452     }
4453
4454   M (WANT_INTERFACE_EVENTS, want_interface_events);
4455   mp->enable_disable = enable;
4456
4457   vam->interface_event_display = enable;
4458
4459   S;
4460   W;
4461 }
4462
4463
4464 /* Note: non-static, called once to set up the initial intfc table */
4465 int
4466 api_sw_interface_dump (vat_main_t * vam)
4467 {
4468   vl_api_sw_interface_dump_t *mp;
4469   f64 timeout;
4470   hash_pair_t *p;
4471   name_sort_t *nses = 0, *ns;
4472   sw_interface_subif_t *sub = NULL;
4473
4474   /* Toss the old name table */
4475   /* *INDENT-OFF* */
4476   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4477   ({
4478     vec_add2 (nses, ns, 1);
4479     ns->name = (u8 *)(p->key);
4480     ns->value = (u32) p->value[0];
4481   }));
4482   /* *INDENT-ON* */
4483
4484   hash_free (vam->sw_if_index_by_interface_name);
4485
4486   vec_foreach (ns, nses) vec_free (ns->name);
4487
4488   vec_free (nses);
4489
4490   vec_foreach (sub, vam->sw_if_subif_table)
4491   {
4492     vec_free (sub->interface_name);
4493   }
4494   vec_free (vam->sw_if_subif_table);
4495
4496   /* recreate the interface name hash table */
4497   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4498
4499   /* Get list of ethernets */
4500   M (SW_INTERFACE_DUMP, sw_interface_dump);
4501   mp->name_filter_valid = 1;
4502   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4503   S;
4504
4505   /* and local / loopback interfaces */
4506   M (SW_INTERFACE_DUMP, sw_interface_dump);
4507   mp->name_filter_valid = 1;
4508   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4509   S;
4510
4511   /* and packet-generator interfaces */
4512   M (SW_INTERFACE_DUMP, sw_interface_dump);
4513   mp->name_filter_valid = 1;
4514   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
4515   S;
4516
4517   /* and vxlan-gpe tunnel interfaces */
4518   M (SW_INTERFACE_DUMP, sw_interface_dump);
4519   mp->name_filter_valid = 1;
4520   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4521            sizeof (mp->name_filter) - 1);
4522   S;
4523
4524   /* and vxlan tunnel interfaces */
4525   M (SW_INTERFACE_DUMP, sw_interface_dump);
4526   mp->name_filter_valid = 1;
4527   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4528   S;
4529
4530   /* and host (af_packet) interfaces */
4531   M (SW_INTERFACE_DUMP, sw_interface_dump);
4532   mp->name_filter_valid = 1;
4533   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4534   S;
4535
4536   /* and l2tpv3 tunnel interfaces */
4537   M (SW_INTERFACE_DUMP, sw_interface_dump);
4538   mp->name_filter_valid = 1;
4539   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4540            sizeof (mp->name_filter) - 1);
4541   S;
4542
4543   /* and GRE tunnel interfaces */
4544   M (SW_INTERFACE_DUMP, sw_interface_dump);
4545   mp->name_filter_valid = 1;
4546   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4547   S;
4548
4549   /* and LISP-GPE interfaces */
4550   M (SW_INTERFACE_DUMP, sw_interface_dump);
4551   mp->name_filter_valid = 1;
4552   strncpy ((char *) mp->name_filter, "lisp_gpe",
4553            sizeof (mp->name_filter) - 1);
4554   S;
4555
4556   /* and IPSEC tunnel interfaces */
4557   M (SW_INTERFACE_DUMP, sw_interface_dump);
4558   mp->name_filter_valid = 1;
4559   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4560   S;
4561
4562   /* Use a control ping for synchronization */
4563   {
4564     vl_api_control_ping_t *mp;
4565     M (CONTROL_PING, control_ping);
4566     S;
4567   }
4568   W;
4569 }
4570
4571 static int
4572 api_sw_interface_set_flags (vat_main_t * vam)
4573 {
4574   unformat_input_t *i = vam->input;
4575   vl_api_sw_interface_set_flags_t *mp;
4576   f64 timeout;
4577   u32 sw_if_index;
4578   u8 sw_if_index_set = 0;
4579   u8 admin_up = 0, link_up = 0;
4580
4581   /* Parse args required to build the message */
4582   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4583     {
4584       if (unformat (i, "admin-up"))
4585         admin_up = 1;
4586       else if (unformat (i, "admin-down"))
4587         admin_up = 0;
4588       else if (unformat (i, "link-up"))
4589         link_up = 1;
4590       else if (unformat (i, "link-down"))
4591         link_up = 0;
4592       else
4593         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4594         sw_if_index_set = 1;
4595       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4596         sw_if_index_set = 1;
4597       else
4598         break;
4599     }
4600
4601   if (sw_if_index_set == 0)
4602     {
4603       errmsg ("missing interface name or sw_if_index");
4604       return -99;
4605     }
4606
4607   /* Construct the API message */
4608   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4609   mp->sw_if_index = ntohl (sw_if_index);
4610   mp->admin_up_down = admin_up;
4611   mp->link_up_down = link_up;
4612
4613   /* send it... */
4614   S;
4615
4616   /* Wait for a reply, return the good/bad news... */
4617   W;
4618 }
4619
4620 static int
4621 api_sw_interface_clear_stats (vat_main_t * vam)
4622 {
4623   unformat_input_t *i = vam->input;
4624   vl_api_sw_interface_clear_stats_t *mp;
4625   f64 timeout;
4626   u32 sw_if_index;
4627   u8 sw_if_index_set = 0;
4628
4629   /* Parse args required to build the message */
4630   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4631     {
4632       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4633         sw_if_index_set = 1;
4634       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4635         sw_if_index_set = 1;
4636       else
4637         break;
4638     }
4639
4640   /* Construct the API message */
4641   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4642
4643   if (sw_if_index_set == 1)
4644     mp->sw_if_index = ntohl (sw_if_index);
4645   else
4646     mp->sw_if_index = ~0;
4647
4648   /* send it... */
4649   S;
4650
4651   /* Wait for a reply, return the good/bad news... */
4652   W;
4653 }
4654
4655 #if DPDK >0
4656 static int
4657 api_sw_interface_set_dpdk_hqos_pipe (vat_main_t * vam)
4658 {
4659   unformat_input_t *i = vam->input;
4660   vl_api_sw_interface_set_dpdk_hqos_pipe_t *mp;
4661   f64 timeout;
4662   u32 sw_if_index;
4663   u8 sw_if_index_set = 0;
4664   u32 subport;
4665   u8 subport_set = 0;
4666   u32 pipe;
4667   u8 pipe_set = 0;
4668   u32 profile;
4669   u8 profile_set = 0;
4670
4671   /* Parse args required to build the message */
4672   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4673     {
4674       if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
4675         sw_if_index_set = 1;
4676       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4677         sw_if_index_set = 1;
4678       else if (unformat (i, "subport %u", &subport))
4679         subport_set = 1;
4680       else
4681         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4682         sw_if_index_set = 1;
4683       else if (unformat (i, "pipe %u", &pipe))
4684         pipe_set = 1;
4685       else if (unformat (i, "profile %u", &profile))
4686         profile_set = 1;
4687       else
4688         break;
4689     }
4690
4691   if (sw_if_index_set == 0)
4692     {
4693       errmsg ("missing interface name or sw_if_index");
4694       return -99;
4695     }
4696
4697   if (subport_set == 0)
4698     {
4699       errmsg ("missing subport ");
4700       return -99;
4701     }
4702
4703   if (pipe_set == 0)
4704     {
4705       errmsg ("missing pipe");
4706       return -99;
4707     }
4708
4709   if (profile_set == 0)
4710     {
4711       errmsg ("missing profile");
4712       return -99;
4713     }
4714
4715   M (SW_INTERFACE_SET_DPDK_HQOS_PIPE, sw_interface_set_dpdk_hqos_pipe);
4716
4717   mp->sw_if_index = ntohl (sw_if_index);
4718   mp->subport = ntohl (subport);
4719   mp->pipe = ntohl (pipe);
4720   mp->profile = ntohl (profile);
4721
4722
4723   S;
4724   W;
4725   /* NOTREACHED */
4726   return 0;
4727 }
4728
4729 static int
4730 api_sw_interface_set_dpdk_hqos_subport (vat_main_t * vam)
4731 {
4732   unformat_input_t *i = vam->input;
4733   vl_api_sw_interface_set_dpdk_hqos_subport_t *mp;
4734   f64 timeout;
4735   u32 sw_if_index;
4736   u8 sw_if_index_set = 0;
4737   u32 subport;
4738   u8 subport_set = 0;
4739   u32 tb_rate = 1250000000;     /* 10GbE */
4740   u32 tb_size = 1000000;
4741   u32 tc_rate[] = { 1250000000, 1250000000, 1250000000, 1250000000 };
4742   u32 tc_period = 10;
4743
4744   /* Parse args required to build the message */
4745   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4746     {
4747       if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
4748         sw_if_index_set = 1;
4749       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4750         sw_if_index_set = 1;
4751       else if (unformat (i, "subport %u", &subport))
4752         subport_set = 1;
4753       else
4754         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4755         sw_if_index_set = 1;
4756       else if (unformat (i, "rate %u", &tb_rate))
4757         {
4758           u32 tc_id;
4759
4760           for (tc_id = 0; tc_id < (sizeof (tc_rate) / sizeof (tc_rate[0]));
4761                tc_id++)
4762             tc_rate[tc_id] = tb_rate;
4763         }
4764       else if (unformat (i, "bktsize %u", &tb_size))
4765         ;
4766       else if (unformat (i, "tc0 %u", &tc_rate[0]))
4767         ;
4768       else if (unformat (i, "tc1 %u", &tc_rate[1]))
4769         ;
4770       else if (unformat (i, "tc2 %u", &tc_rate[2]))
4771         ;
4772       else if (unformat (i, "tc3 %u", &tc_rate[3]))
4773         ;
4774       else if (unformat (i, "period %u", &tc_period))
4775         ;
4776       else
4777         break;
4778     }
4779
4780   if (sw_if_index_set == 0)
4781     {
4782       errmsg ("missing interface name or sw_if_index");
4783       return -99;
4784     }
4785
4786   if (subport_set == 0)
4787     {
4788       errmsg ("missing subport ");
4789       return -99;
4790     }
4791
4792   M (SW_INTERFACE_SET_DPDK_HQOS_SUBPORT, sw_interface_set_dpdk_hqos_subport);
4793
4794   mp->sw_if_index = ntohl (sw_if_index);
4795   mp->subport = ntohl (subport);
4796   mp->tb_rate = ntohl (tb_rate);
4797   mp->tb_size = ntohl (tb_size);
4798   mp->tc_rate[0] = ntohl (tc_rate[0]);
4799   mp->tc_rate[1] = ntohl (tc_rate[1]);
4800   mp->tc_rate[2] = ntohl (tc_rate[2]);
4801   mp->tc_rate[3] = ntohl (tc_rate[3]);
4802   mp->tc_period = ntohl (tc_period);
4803
4804   S;
4805   W;
4806   /* NOTREACHED */
4807   return 0;
4808 }
4809
4810 static int
4811 api_sw_interface_set_dpdk_hqos_tctbl (vat_main_t * vam)
4812 {
4813   unformat_input_t *i = vam->input;
4814   vl_api_sw_interface_set_dpdk_hqos_tctbl_t *mp;
4815   f64 timeout;
4816   u32 sw_if_index;
4817   u8 sw_if_index_set = 0;
4818   u8 entry_set = 0;
4819   u8 tc_set = 0;
4820   u8 queue_set = 0;
4821   u32 entry, tc, queue;
4822
4823   /* Parse args required to build the message */
4824   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4825     {
4826       if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
4827         sw_if_index_set = 1;
4828       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4829         sw_if_index_set = 1;
4830       else if (unformat (i, "entry %d", &entry))
4831         entry_set = 1;
4832       else if (unformat (i, "tc %d", &tc))
4833         tc_set = 1;
4834       else if (unformat (i, "queue %d", &queue))
4835         queue_set = 1;
4836       else
4837         break;
4838     }
4839
4840   if (sw_if_index_set == 0)
4841     {
4842       errmsg ("missing interface name or sw_if_index");
4843       return -99;
4844     }
4845
4846   if (entry_set == 0)
4847     {
4848       errmsg ("missing entry ");
4849       return -99;
4850     }
4851
4852   if (tc_set == 0)
4853     {
4854       errmsg ("missing traffic class ");
4855       return -99;
4856     }
4857
4858   if (queue_set == 0)
4859     {
4860       errmsg ("missing queue ");
4861       return -99;
4862     }
4863
4864   M (SW_INTERFACE_SET_DPDK_HQOS_TCTBL, sw_interface_set_dpdk_hqos_tctbl);
4865
4866   mp->sw_if_index = ntohl (sw_if_index);
4867   mp->entry = ntohl (entry);
4868   mp->tc = ntohl (tc);
4869   mp->queue = ntohl (queue);
4870
4871   S;
4872   W;
4873   /* NOTREACHED */
4874   return 0;
4875 }
4876 #endif
4877
4878 static int
4879 api_sw_interface_add_del_address (vat_main_t * vam)
4880 {
4881   unformat_input_t *i = vam->input;
4882   vl_api_sw_interface_add_del_address_t *mp;
4883   f64 timeout;
4884   u32 sw_if_index;
4885   u8 sw_if_index_set = 0;
4886   u8 is_add = 1, del_all = 0;
4887   u32 address_length = 0;
4888   u8 v4_address_set = 0;
4889   u8 v6_address_set = 0;
4890   ip4_address_t v4address;
4891   ip6_address_t v6address;
4892
4893   /* Parse args required to build the message */
4894   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4895     {
4896       if (unformat (i, "del-all"))
4897         del_all = 1;
4898       else if (unformat (i, "del"))
4899         is_add = 0;
4900       else
4901         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4902         sw_if_index_set = 1;
4903       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4904         sw_if_index_set = 1;
4905       else if (unformat (i, "%U/%d",
4906                          unformat_ip4_address, &v4address, &address_length))
4907         v4_address_set = 1;
4908       else if (unformat (i, "%U/%d",
4909                          unformat_ip6_address, &v6address, &address_length))
4910         v6_address_set = 1;
4911       else
4912         break;
4913     }
4914
4915   if (sw_if_index_set == 0)
4916     {
4917       errmsg ("missing interface name or sw_if_index");
4918       return -99;
4919     }
4920   if (v4_address_set && v6_address_set)
4921     {
4922       errmsg ("both v4 and v6 addresses set");
4923       return -99;
4924     }
4925   if (!v4_address_set && !v6_address_set && !del_all)
4926     {
4927       errmsg ("no addresses set");
4928       return -99;
4929     }
4930
4931   /* Construct the API message */
4932   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
4933
4934   mp->sw_if_index = ntohl (sw_if_index);
4935   mp->is_add = is_add;
4936   mp->del_all = del_all;
4937   if (v6_address_set)
4938     {
4939       mp->is_ipv6 = 1;
4940       clib_memcpy (mp->address, &v6address, sizeof (v6address));
4941     }
4942   else
4943     {
4944       clib_memcpy (mp->address, &v4address, sizeof (v4address));
4945     }
4946   mp->address_length = address_length;
4947
4948   /* send it... */
4949   S;
4950
4951   /* Wait for a reply, return good/bad news  */
4952   W;
4953 }
4954
4955 static int
4956 api_sw_interface_set_mpls_enable (vat_main_t * vam)
4957 {
4958   unformat_input_t *i = vam->input;
4959   vl_api_sw_interface_set_mpls_enable_t *mp;
4960   f64 timeout;
4961   u32 sw_if_index;
4962   u8 sw_if_index_set = 0;
4963   u8 enable = 1;
4964
4965   /* Parse args required to build the message */
4966   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4967     {
4968       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4969         sw_if_index_set = 1;
4970       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4971         sw_if_index_set = 1;
4972       else if (unformat (i, "disable"))
4973         enable = 0;
4974       else if (unformat (i, "dis"))
4975         enable = 0;
4976       else
4977         break;
4978     }
4979
4980   if (sw_if_index_set == 0)
4981     {
4982       errmsg ("missing interface name or sw_if_index");
4983       return -99;
4984     }
4985
4986   /* Construct the API message */
4987   M (SW_INTERFACE_SET_MPLS_ENABLE, sw_interface_set_mpls_enable);
4988
4989   mp->sw_if_index = ntohl (sw_if_index);
4990   mp->enable = enable;
4991
4992   /* send it... */
4993   S;
4994
4995   /* Wait for a reply... */
4996   W;
4997 }
4998
4999 static int
5000 api_sw_interface_set_table (vat_main_t * vam)
5001 {
5002   unformat_input_t *i = vam->input;
5003   vl_api_sw_interface_set_table_t *mp;
5004   f64 timeout;
5005   u32 sw_if_index, vrf_id = 0;
5006   u8 sw_if_index_set = 0;
5007   u8 is_ipv6 = 0;
5008
5009   /* Parse args required to build the message */
5010   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5011     {
5012       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5013         sw_if_index_set = 1;
5014       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5015         sw_if_index_set = 1;
5016       else if (unformat (i, "vrf %d", &vrf_id))
5017         ;
5018       else if (unformat (i, "ipv6"))
5019         is_ipv6 = 1;
5020       else
5021         break;
5022     }
5023
5024   if (sw_if_index_set == 0)
5025     {
5026       errmsg ("missing interface name or sw_if_index");
5027       return -99;
5028     }
5029
5030   /* Construct the API message */
5031   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
5032
5033   mp->sw_if_index = ntohl (sw_if_index);
5034   mp->is_ipv6 = is_ipv6;
5035   mp->vrf_id = ntohl (vrf_id);
5036
5037   /* send it... */
5038   S;
5039
5040   /* Wait for a reply... */
5041   W;
5042 }
5043
5044 static void vl_api_sw_interface_get_table_reply_t_handler
5045   (vl_api_sw_interface_get_table_reply_t * mp)
5046 {
5047   vat_main_t *vam = &vat_main;
5048
5049   print (vam->ofp, "%d", ntohl (mp->vrf_id));
5050
5051   vam->retval = ntohl (mp->retval);
5052   vam->result_ready = 1;
5053
5054 }
5055
5056 static void vl_api_sw_interface_get_table_reply_t_handler_json
5057   (vl_api_sw_interface_get_table_reply_t * mp)
5058 {
5059   vat_main_t *vam = &vat_main;
5060   vat_json_node_t node;
5061
5062   vat_json_init_object (&node);
5063   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5064   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5065
5066   vat_json_print (vam->ofp, &node);
5067   vat_json_free (&node);
5068
5069   vam->retval = ntohl (mp->retval);
5070   vam->result_ready = 1;
5071 }
5072
5073 static int
5074 api_sw_interface_get_table (vat_main_t * vam)
5075 {
5076   unformat_input_t *i = vam->input;
5077   vl_api_sw_interface_get_table_t *mp;
5078   u32 sw_if_index;
5079   u8 sw_if_index_set = 0;
5080   u8 is_ipv6 = 0;
5081   f64 timeout;
5082
5083   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5084     {
5085       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5086         sw_if_index_set = 1;
5087       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5088         sw_if_index_set = 1;
5089       else if (unformat (i, "ipv6"))
5090         is_ipv6 = 1;
5091       else
5092         break;
5093     }
5094
5095   if (sw_if_index_set == 0)
5096     {
5097       errmsg ("missing interface name or sw_if_index");
5098       return -99;
5099     }
5100
5101   M (SW_INTERFACE_GET_TABLE, sw_interface_get_table);
5102   mp->sw_if_index = htonl (sw_if_index);
5103   mp->is_ipv6 = is_ipv6;
5104
5105   S;
5106   W;
5107 }
5108
5109 static int
5110 api_sw_interface_set_vpath (vat_main_t * vam)
5111 {
5112   unformat_input_t *i = vam->input;
5113   vl_api_sw_interface_set_vpath_t *mp;
5114   f64 timeout;
5115   u32 sw_if_index = 0;
5116   u8 sw_if_index_set = 0;
5117   u8 is_enable = 0;
5118
5119   /* Parse args required to build the message */
5120   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5121     {
5122       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5123         sw_if_index_set = 1;
5124       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5125         sw_if_index_set = 1;
5126       else if (unformat (i, "enable"))
5127         is_enable = 1;
5128       else if (unformat (i, "disable"))
5129         is_enable = 0;
5130       else
5131         break;
5132     }
5133
5134   if (sw_if_index_set == 0)
5135     {
5136       errmsg ("missing interface name or sw_if_index");
5137       return -99;
5138     }
5139
5140   /* Construct the API message */
5141   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
5142
5143   mp->sw_if_index = ntohl (sw_if_index);
5144   mp->enable = is_enable;
5145
5146   /* send it... */
5147   S;
5148
5149   /* Wait for a reply... */
5150   W;
5151 }
5152
5153 static int
5154 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5155 {
5156   unformat_input_t *i = vam->input;
5157   vl_api_sw_interface_set_vxlan_bypass_t *mp;
5158   f64 timeout;
5159   u32 sw_if_index = 0;
5160   u8 sw_if_index_set = 0;
5161   u8 is_enable = 0;
5162   u8 is_ipv6 = 0;
5163
5164   /* Parse args required to build the message */
5165   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5166     {
5167       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5168         sw_if_index_set = 1;
5169       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5170         sw_if_index_set = 1;
5171       else if (unformat (i, "enable"))
5172         is_enable = 1;
5173       else if (unformat (i, "disable"))
5174         is_enable = 0;
5175       else if (unformat (i, "ip4"))
5176         is_ipv6 = 0;
5177       else if (unformat (i, "ip6"))
5178         is_ipv6 = 1;
5179       else
5180         break;
5181     }
5182
5183   if (sw_if_index_set == 0)
5184     {
5185       errmsg ("missing interface name or sw_if_index");
5186       return -99;
5187     }
5188
5189   /* Construct the API message */
5190   M (SW_INTERFACE_SET_VXLAN_BYPASS, sw_interface_set_vxlan_bypass);
5191
5192   mp->sw_if_index = ntohl (sw_if_index);
5193   mp->enable = is_enable;
5194   mp->is_ipv6 = is_ipv6;
5195
5196   /* send it... */
5197   S;
5198
5199   /* Wait for a reply... */
5200   W;
5201 }
5202
5203 static int
5204 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5205 {
5206   unformat_input_t *i = vam->input;
5207   vl_api_sw_interface_set_l2_xconnect_t *mp;
5208   f64 timeout;
5209   u32 rx_sw_if_index;
5210   u8 rx_sw_if_index_set = 0;
5211   u32 tx_sw_if_index;
5212   u8 tx_sw_if_index_set = 0;
5213   u8 enable = 1;
5214
5215   /* Parse args required to build the message */
5216   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5217     {
5218       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5219         rx_sw_if_index_set = 1;
5220       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5221         tx_sw_if_index_set = 1;
5222       else if (unformat (i, "rx"))
5223         {
5224           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5225             {
5226               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5227                             &rx_sw_if_index))
5228                 rx_sw_if_index_set = 1;
5229             }
5230           else
5231             break;
5232         }
5233       else if (unformat (i, "tx"))
5234         {
5235           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5236             {
5237               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5238                             &tx_sw_if_index))
5239                 tx_sw_if_index_set = 1;
5240             }
5241           else
5242             break;
5243         }
5244       else if (unformat (i, "enable"))
5245         enable = 1;
5246       else if (unformat (i, "disable"))
5247         enable = 0;
5248       else
5249         break;
5250     }
5251
5252   if (rx_sw_if_index_set == 0)
5253     {
5254       errmsg ("missing rx interface name or rx_sw_if_index");
5255       return -99;
5256     }
5257
5258   if (enable && (tx_sw_if_index_set == 0))
5259     {
5260       errmsg ("missing tx interface name or tx_sw_if_index");
5261       return -99;
5262     }
5263
5264   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
5265
5266   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5267   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5268   mp->enable = enable;
5269
5270   S;
5271   W;
5272   /* NOTREACHED */
5273   return 0;
5274 }
5275
5276 static int
5277 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5278 {
5279   unformat_input_t *i = vam->input;
5280   vl_api_sw_interface_set_l2_bridge_t *mp;
5281   f64 timeout;
5282   u32 rx_sw_if_index;
5283   u8 rx_sw_if_index_set = 0;
5284   u32 bd_id;
5285   u8 bd_id_set = 0;
5286   u8 bvi = 0;
5287   u32 shg = 0;
5288   u8 enable = 1;
5289
5290   /* Parse args required to build the message */
5291   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5292     {
5293       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5294         rx_sw_if_index_set = 1;
5295       else if (unformat (i, "bd_id %d", &bd_id))
5296         bd_id_set = 1;
5297       else
5298         if (unformat
5299             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
5300         rx_sw_if_index_set = 1;
5301       else if (unformat (i, "shg %d", &shg))
5302         ;
5303       else if (unformat (i, "bvi"))
5304         bvi = 1;
5305       else if (unformat (i, "enable"))
5306         enable = 1;
5307       else if (unformat (i, "disable"))
5308         enable = 0;
5309       else
5310         break;
5311     }
5312
5313   if (rx_sw_if_index_set == 0)
5314     {
5315       errmsg ("missing rx interface name or sw_if_index");
5316       return -99;
5317     }
5318
5319   if (enable && (bd_id_set == 0))
5320     {
5321       errmsg ("missing bridge domain");
5322       return -99;
5323     }
5324
5325   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
5326
5327   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5328   mp->bd_id = ntohl (bd_id);
5329   mp->shg = (u8) shg;
5330   mp->bvi = bvi;
5331   mp->enable = enable;
5332
5333   S;
5334   W;
5335   /* NOTREACHED */
5336   return 0;
5337 }
5338
5339 static int
5340 api_bridge_domain_dump (vat_main_t * vam)
5341 {
5342   unformat_input_t *i = vam->input;
5343   vl_api_bridge_domain_dump_t *mp;
5344   f64 timeout;
5345   u32 bd_id = ~0;
5346
5347   /* Parse args required to build the message */
5348   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5349     {
5350       if (unformat (i, "bd_id %d", &bd_id))
5351         ;
5352       else
5353         break;
5354     }
5355
5356   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
5357   mp->bd_id = ntohl (bd_id);
5358   S;
5359
5360   /* Use a control ping for synchronization */
5361   {
5362     vl_api_control_ping_t *mp;
5363     M (CONTROL_PING, control_ping);
5364     S;
5365   }
5366
5367   W;
5368   /* NOTREACHED */
5369   return 0;
5370 }
5371
5372 static int
5373 api_bridge_domain_add_del (vat_main_t * vam)
5374 {
5375   unformat_input_t *i = vam->input;
5376   vl_api_bridge_domain_add_del_t *mp;
5377   f64 timeout;
5378   u32 bd_id = ~0;
5379   u8 is_add = 1;
5380   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5381   u32 mac_age = 0;
5382
5383   /* Parse args required to build the message */
5384   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5385     {
5386       if (unformat (i, "bd_id %d", &bd_id))
5387         ;
5388       else if (unformat (i, "flood %d", &flood))
5389         ;
5390       else if (unformat (i, "uu-flood %d", &uu_flood))
5391         ;
5392       else if (unformat (i, "forward %d", &forward))
5393         ;
5394       else if (unformat (i, "learn %d", &learn))
5395         ;
5396       else if (unformat (i, "arp-term %d", &arp_term))
5397         ;
5398       else if (unformat (i, "mac-age %d", &mac_age))
5399         ;
5400       else if (unformat (i, "del"))
5401         {
5402           is_add = 0;
5403           flood = uu_flood = forward = learn = 0;
5404         }
5405       else
5406         break;
5407     }
5408
5409   if (bd_id == ~0)
5410     {
5411       errmsg ("missing bridge domain");
5412       return -99;
5413     }
5414
5415   if (mac_age > 255)
5416     {
5417       errmsg ("mac age must be less than 256 ");
5418       return -99;
5419     }
5420
5421   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
5422
5423   mp->bd_id = ntohl (bd_id);
5424   mp->flood = flood;
5425   mp->uu_flood = uu_flood;
5426   mp->forward = forward;
5427   mp->learn = learn;
5428   mp->arp_term = arp_term;
5429   mp->is_add = is_add;
5430   mp->mac_age = (u8) mac_age;
5431
5432   S;
5433   W;
5434   /* NOTREACHED */
5435   return 0;
5436 }
5437
5438 static int
5439 api_l2fib_add_del (vat_main_t * vam)
5440 {
5441   unformat_input_t *i = vam->input;
5442   vl_api_l2fib_add_del_t *mp;
5443   f64 timeout;
5444   u64 mac = 0;
5445   u8 mac_set = 0;
5446   u32 bd_id;
5447   u8 bd_id_set = 0;
5448   u32 sw_if_index = ~0;
5449   u8 sw_if_index_set = 0;
5450   u8 is_add = 1;
5451   u8 static_mac = 0;
5452   u8 filter_mac = 0;
5453   u8 bvi_mac = 0;
5454   int count = 1;
5455   f64 before = 0;
5456   int j;
5457
5458   /* Parse args required to build the message */
5459   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5460     {
5461       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5462         mac_set = 1;
5463       else if (unformat (i, "bd_id %d", &bd_id))
5464         bd_id_set = 1;
5465       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5466         sw_if_index_set = 1;
5467       else if (unformat (i, "sw_if"))
5468         {
5469           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5470             {
5471               if (unformat
5472                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5473                 sw_if_index_set = 1;
5474             }
5475           else
5476             break;
5477         }
5478       else if (unformat (i, "static"))
5479         static_mac = 1;
5480       else if (unformat (i, "filter"))
5481         {
5482           filter_mac = 1;
5483           static_mac = 1;
5484         }
5485       else if (unformat (i, "bvi"))
5486         {
5487           bvi_mac = 1;
5488           static_mac = 1;
5489         }
5490       else if (unformat (i, "del"))
5491         is_add = 0;
5492       else if (unformat (i, "count %d", &count))
5493         ;
5494       else
5495         break;
5496     }
5497
5498   if (mac_set == 0)
5499     {
5500       errmsg ("missing mac address");
5501       return -99;
5502     }
5503
5504   if (bd_id_set == 0)
5505     {
5506       errmsg ("missing bridge domain");
5507       return -99;
5508     }
5509
5510   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
5511     {
5512       errmsg ("missing interface name or sw_if_index");
5513       return -99;
5514     }
5515
5516   if (count > 1)
5517     {
5518       /* Turn on async mode */
5519       vam->async_mode = 1;
5520       vam->async_errors = 0;
5521       before = vat_time_now (vam);
5522     }
5523
5524   for (j = 0; j < count; j++)
5525     {
5526       M (L2FIB_ADD_DEL, l2fib_add_del);
5527
5528       mp->mac = mac;
5529       mp->bd_id = ntohl (bd_id);
5530       mp->is_add = is_add;
5531
5532       if (is_add)
5533         {
5534           mp->sw_if_index = ntohl (sw_if_index);
5535           mp->static_mac = static_mac;
5536           mp->filter_mac = filter_mac;
5537           mp->bvi_mac = bvi_mac;
5538         }
5539       increment_mac_address (&mac);
5540       /* send it... */
5541       S;
5542     }
5543
5544   if (count > 1)
5545     {
5546       vl_api_control_ping_t *mp;
5547       f64 after;
5548
5549       /* Shut off async mode */
5550       vam->async_mode = 0;
5551
5552       M (CONTROL_PING, control_ping);
5553       S;
5554
5555       timeout = vat_time_now (vam) + 1.0;
5556       while (vat_time_now (vam) < timeout)
5557         if (vam->result_ready == 1)
5558           goto out;
5559       vam->retval = -99;
5560
5561     out:
5562       if (vam->retval == -99)
5563         errmsg ("timeout");
5564
5565       if (vam->async_errors > 0)
5566         {
5567           errmsg ("%d asynchronous errors", vam->async_errors);
5568           vam->retval = -98;
5569         }
5570       vam->async_errors = 0;
5571       after = vat_time_now (vam);
5572
5573       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
5574              count, after - before, count / (after - before));
5575     }
5576   else
5577     {
5578       /* Wait for a reply... */
5579       W;
5580     }
5581   /* Return the good/bad news */
5582   return (vam->retval);
5583 }
5584
5585 static int
5586 api_l2_flags (vat_main_t * vam)
5587 {
5588   unformat_input_t *i = vam->input;
5589   vl_api_l2_flags_t *mp;
5590   f64 timeout;
5591   u32 sw_if_index;
5592   u32 feature_bitmap = 0;
5593   u8 sw_if_index_set = 0;
5594
5595   /* Parse args required to build the message */
5596   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5597     {
5598       if (unformat (i, "sw_if_index %d", &sw_if_index))
5599         sw_if_index_set = 1;
5600       else if (unformat (i, "sw_if"))
5601         {
5602           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5603             {
5604               if (unformat
5605                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5606                 sw_if_index_set = 1;
5607             }
5608           else
5609             break;
5610         }
5611       else if (unformat (i, "learn"))
5612         feature_bitmap |= L2INPUT_FEAT_LEARN;
5613       else if (unformat (i, "forward"))
5614         feature_bitmap |= L2INPUT_FEAT_FWD;
5615       else if (unformat (i, "flood"))
5616         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5617       else if (unformat (i, "uu-flood"))
5618         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5619       else
5620         break;
5621     }
5622
5623   if (sw_if_index_set == 0)
5624     {
5625       errmsg ("missing interface name or sw_if_index");
5626       return -99;
5627     }
5628
5629   M (L2_FLAGS, l2_flags);
5630
5631   mp->sw_if_index = ntohl (sw_if_index);
5632   mp->feature_bitmap = ntohl (feature_bitmap);
5633
5634   S;
5635   W;
5636   /* NOTREACHED */
5637   return 0;
5638 }
5639
5640 static int
5641 api_bridge_flags (vat_main_t * vam)
5642 {
5643   unformat_input_t *i = vam->input;
5644   vl_api_bridge_flags_t *mp;
5645   f64 timeout;
5646   u32 bd_id;
5647   u8 bd_id_set = 0;
5648   u8 is_set = 1;
5649   u32 flags = 0;
5650
5651   /* Parse args required to build the message */
5652   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5653     {
5654       if (unformat (i, "bd_id %d", &bd_id))
5655         bd_id_set = 1;
5656       else if (unformat (i, "learn"))
5657         flags |= L2_LEARN;
5658       else if (unformat (i, "forward"))
5659         flags |= L2_FWD;
5660       else if (unformat (i, "flood"))
5661         flags |= L2_FLOOD;
5662       else if (unformat (i, "uu-flood"))
5663         flags |= L2_UU_FLOOD;
5664       else if (unformat (i, "arp-term"))
5665         flags |= L2_ARP_TERM;
5666       else if (unformat (i, "off"))
5667         is_set = 0;
5668       else if (unformat (i, "disable"))
5669         is_set = 0;
5670       else
5671         break;
5672     }
5673
5674   if (bd_id_set == 0)
5675     {
5676       errmsg ("missing bridge domain");
5677       return -99;
5678     }
5679
5680   M (BRIDGE_FLAGS, bridge_flags);
5681
5682   mp->bd_id = ntohl (bd_id);
5683   mp->feature_bitmap = ntohl (flags);
5684   mp->is_set = is_set;
5685
5686   S;
5687   W;
5688   /* NOTREACHED */
5689   return 0;
5690 }
5691
5692 static int
5693 api_bd_ip_mac_add_del (vat_main_t * vam)
5694 {
5695   unformat_input_t *i = vam->input;
5696   vl_api_bd_ip_mac_add_del_t *mp;
5697   f64 timeout;
5698   u32 bd_id;
5699   u8 is_ipv6 = 0;
5700   u8 is_add = 1;
5701   u8 bd_id_set = 0;
5702   u8 ip_set = 0;
5703   u8 mac_set = 0;
5704   ip4_address_t v4addr;
5705   ip6_address_t v6addr;
5706   u8 macaddr[6];
5707
5708
5709   /* Parse args required to build the message */
5710   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5711     {
5712       if (unformat (i, "bd_id %d", &bd_id))
5713         {
5714           bd_id_set++;
5715         }
5716       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5717         {
5718           ip_set++;
5719         }
5720       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5721         {
5722           ip_set++;
5723           is_ipv6++;
5724         }
5725       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5726         {
5727           mac_set++;
5728         }
5729       else if (unformat (i, "del"))
5730         is_add = 0;
5731       else
5732         break;
5733     }
5734
5735   if (bd_id_set == 0)
5736     {
5737       errmsg ("missing bridge domain");
5738       return -99;
5739     }
5740   else if (ip_set == 0)
5741     {
5742       errmsg ("missing IP address");
5743       return -99;
5744     }
5745   else if (mac_set == 0)
5746     {
5747       errmsg ("missing MAC address");
5748       return -99;
5749     }
5750
5751   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5752
5753   mp->bd_id = ntohl (bd_id);
5754   mp->is_ipv6 = is_ipv6;
5755   mp->is_add = is_add;
5756   if (is_ipv6)
5757     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5758   else
5759     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5760   clib_memcpy (mp->mac_address, macaddr, 6);
5761   S;
5762   W;
5763   /* NOTREACHED */
5764   return 0;
5765 }
5766
5767 static int
5768 api_tap_connect (vat_main_t * vam)
5769 {
5770   unformat_input_t *i = vam->input;
5771   vl_api_tap_connect_t *mp;
5772   f64 timeout;
5773   u8 mac_address[6];
5774   u8 random_mac = 1;
5775   u8 name_set = 0;
5776   u8 *tap_name;
5777   u8 *tag = 0;
5778   ip4_address_t ip4_address;
5779   u32 ip4_mask_width;
5780   int ip4_address_set = 0;
5781   ip6_address_t ip6_address;
5782   u32 ip6_mask_width;
5783   int ip6_address_set = 0;
5784
5785   memset (mac_address, 0, sizeof (mac_address));
5786
5787   /* Parse args required to build the message */
5788   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5789     {
5790       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5791         {
5792           random_mac = 0;
5793         }
5794       else if (unformat (i, "random-mac"))
5795         random_mac = 1;
5796       else if (unformat (i, "tapname %s", &tap_name))
5797         name_set = 1;
5798       else if (unformat (i, "tag %s", &tag))
5799         ;
5800       else if (unformat (i, "address %U/%d",
5801                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
5802         ip4_address_set = 1;
5803       else if (unformat (i, "address %U/%d",
5804                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
5805         ip6_address_set = 1;
5806       else
5807         break;
5808     }
5809
5810   if (name_set == 0)
5811     {
5812       errmsg ("missing tap name");
5813       return -99;
5814     }
5815   if (vec_len (tap_name) > 63)
5816     {
5817       errmsg ("tap name too long");
5818       return -99;
5819     }
5820   vec_add1 (tap_name, 0);
5821
5822   if (vec_len (tag) > 63)
5823     {
5824       errmsg ("tag too long");
5825       return -99;
5826     }
5827
5828   /* Construct the API message */
5829   M (TAP_CONNECT, tap_connect);
5830
5831   mp->use_random_mac = random_mac;
5832   clib_memcpy (mp->mac_address, mac_address, 6);
5833   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5834   if (tag)
5835     clib_memcpy (mp->tag, tag, vec_len (tag));
5836
5837   if (ip4_address_set)
5838     {
5839       mp->ip4_address_set = 1;
5840       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
5841       mp->ip4_mask_width = ip4_mask_width;
5842     }
5843   if (ip6_address_set)
5844     {
5845       mp->ip6_address_set = 1;
5846       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
5847       mp->ip6_mask_width = ip6_mask_width;
5848     }
5849
5850   vec_free (tap_name);
5851   vec_free (tag);
5852
5853   /* send it... */
5854   S;
5855
5856   /* Wait for a reply... */
5857   W;
5858 }
5859
5860 static int
5861 api_tap_modify (vat_main_t * vam)
5862 {
5863   unformat_input_t *i = vam->input;
5864   vl_api_tap_modify_t *mp;
5865   f64 timeout;
5866   u8 mac_address[6];
5867   u8 random_mac = 1;
5868   u8 name_set = 0;
5869   u8 *tap_name;
5870   u32 sw_if_index = ~0;
5871   u8 sw_if_index_set = 0;
5872
5873   memset (mac_address, 0, sizeof (mac_address));
5874
5875   /* Parse args required to build the message */
5876   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5877     {
5878       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5879         sw_if_index_set = 1;
5880       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5881         sw_if_index_set = 1;
5882       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5883         {
5884           random_mac = 0;
5885         }
5886       else if (unformat (i, "random-mac"))
5887         random_mac = 1;
5888       else if (unformat (i, "tapname %s", &tap_name))
5889         name_set = 1;
5890       else
5891         break;
5892     }
5893
5894   if (sw_if_index_set == 0)
5895     {
5896       errmsg ("missing vpp interface name");
5897       return -99;
5898     }
5899   if (name_set == 0)
5900     {
5901       errmsg ("missing tap name");
5902       return -99;
5903     }
5904   if (vec_len (tap_name) > 63)
5905     {
5906       errmsg ("tap name too long");
5907     }
5908   vec_add1 (tap_name, 0);
5909
5910   /* Construct the API message */
5911   M (TAP_MODIFY, tap_modify);
5912
5913   mp->use_random_mac = random_mac;
5914   mp->sw_if_index = ntohl (sw_if_index);
5915   clib_memcpy (mp->mac_address, mac_address, 6);
5916   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5917   vec_free (tap_name);
5918
5919   /* send it... */
5920   S;
5921
5922   /* Wait for a reply... */
5923   W;
5924 }
5925
5926 static int
5927 api_tap_delete (vat_main_t * vam)
5928 {
5929   unformat_input_t *i = vam->input;
5930   vl_api_tap_delete_t *mp;
5931   f64 timeout;
5932   u32 sw_if_index = ~0;
5933   u8 sw_if_index_set = 0;
5934
5935   /* Parse args required to build the message */
5936   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5937     {
5938       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5939         sw_if_index_set = 1;
5940       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5941         sw_if_index_set = 1;
5942       else
5943         break;
5944     }
5945
5946   if (sw_if_index_set == 0)
5947     {
5948       errmsg ("missing vpp interface name");
5949       return -99;
5950     }
5951
5952   /* Construct the API message */
5953   M (TAP_DELETE, tap_delete);
5954
5955   mp->sw_if_index = ntohl (sw_if_index);
5956
5957   /* send it... */
5958   S;
5959
5960   /* Wait for a reply... */
5961   W;
5962 }
5963
5964 static int
5965 api_ip_add_del_route (vat_main_t * vam)
5966 {
5967   unformat_input_t *i = vam->input;
5968   vl_api_ip_add_del_route_t *mp;
5969   f64 timeout;
5970   u32 sw_if_index = ~0, vrf_id = 0;
5971   u8 is_ipv6 = 0;
5972   u8 is_local = 0, is_drop = 0;
5973   u8 is_unreach = 0, is_prohibit = 0;
5974   u8 create_vrf_if_needed = 0;
5975   u8 is_add = 1;
5976   u32 next_hop_weight = 1;
5977   u8 not_last = 0;
5978   u8 is_multipath = 0;
5979   u8 address_set = 0;
5980   u8 address_length_set = 0;
5981   u32 next_hop_table_id = 0;
5982   u32 resolve_attempts = 0;
5983   u32 dst_address_length = 0;
5984   u8 next_hop_set = 0;
5985   ip4_address_t v4_dst_address, v4_next_hop_address;
5986   ip6_address_t v6_dst_address, v6_next_hop_address;
5987   int count = 1;
5988   int j;
5989   f64 before = 0;
5990   u32 random_add_del = 0;
5991   u32 *random_vector = 0;
5992   uword *random_hash;
5993   u32 random_seed = 0xdeaddabe;
5994   u32 classify_table_index = ~0;
5995   u8 is_classify = 0;
5996   u8 resolve_host = 0, resolve_attached = 0;
5997   mpls_label_t *next_hop_out_label_stack = NULL;
5998   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
5999   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6000
6001   /* Parse args required to build the message */
6002   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6003     {
6004       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6005         ;
6006       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6007         ;
6008       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
6009         {
6010           address_set = 1;
6011           is_ipv6 = 0;
6012         }
6013       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6014         {
6015           address_set = 1;
6016           is_ipv6 = 1;
6017         }
6018       else if (unformat (i, "/%d", &dst_address_length))
6019         {
6020           address_length_set = 1;
6021         }
6022
6023       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
6024                                          &v4_next_hop_address))
6025         {
6026           next_hop_set = 1;
6027         }
6028       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
6029                                          &v6_next_hop_address))
6030         {
6031           next_hop_set = 1;
6032         }
6033       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6034         ;
6035       else if (unformat (i, "weight %d", &next_hop_weight))
6036         ;
6037       else if (unformat (i, "drop"))
6038         {
6039           is_drop = 1;
6040         }
6041       else if (unformat (i, "null-send-unreach"))
6042         {
6043           is_unreach = 1;
6044         }
6045       else if (unformat (i, "null-send-prohibit"))
6046         {
6047           is_prohibit = 1;
6048         }
6049       else if (unformat (i, "local"))
6050         {
6051           is_local = 1;
6052         }
6053       else if (unformat (i, "classify %d", &classify_table_index))
6054         {
6055           is_classify = 1;
6056         }
6057       else if (unformat (i, "del"))
6058         is_add = 0;
6059       else if (unformat (i, "add"))
6060         is_add = 1;
6061       else if (unformat (i, "not-last"))
6062         not_last = 1;
6063       else if (unformat (i, "resolve-via-host"))
6064         resolve_host = 1;
6065       else if (unformat (i, "resolve-via-attached"))
6066         resolve_attached = 1;
6067       else if (unformat (i, "multipath"))
6068         is_multipath = 1;
6069       else if (unformat (i, "vrf %d", &vrf_id))
6070         ;
6071       else if (unformat (i, "create-vrf"))
6072         create_vrf_if_needed = 1;
6073       else if (unformat (i, "count %d", &count))
6074         ;
6075       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
6076         ;
6077       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6078         ;
6079       else if (unformat (i, "out-label %d", &next_hop_out_label))
6080         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6081       else if (unformat (i, "via-label %d", &next_hop_via_label))
6082         ;
6083       else if (unformat (i, "random"))
6084         random_add_del = 1;
6085       else if (unformat (i, "seed %d", &random_seed))
6086         ;
6087       else
6088         {
6089           clib_warning ("parse error '%U'", format_unformat_error, i);
6090           return -99;
6091         }
6092     }
6093
6094   if (!next_hop_set && !is_drop && !is_local &&
6095       !is_classify && !is_unreach && !is_prohibit &&
6096       MPLS_LABEL_INVALID == next_hop_via_label)
6097     {
6098       errmsg
6099         ("next hop / local / drop / unreach / prohibit / classify not set");
6100       return -99;
6101     }
6102
6103   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
6104     {
6105       errmsg ("next hop and next-hop via label set");
6106       return -99;
6107     }
6108   if (address_set == 0)
6109     {
6110       errmsg ("missing addresses");
6111       return -99;
6112     }
6113
6114   if (address_length_set == 0)
6115     {
6116       errmsg ("missing address length");
6117       return -99;
6118     }
6119
6120   /* Generate a pile of unique, random routes */
6121   if (random_add_del)
6122     {
6123       u32 this_random_address;
6124       random_hash = hash_create (count, sizeof (uword));
6125
6126       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
6127       for (j = 0; j <= count; j++)
6128         {
6129           do
6130             {
6131               this_random_address = random_u32 (&random_seed);
6132               this_random_address =
6133                 clib_host_to_net_u32 (this_random_address);
6134             }
6135           while (hash_get (random_hash, this_random_address));
6136           vec_add1 (random_vector, this_random_address);
6137           hash_set (random_hash, this_random_address, 1);
6138         }
6139       hash_free (random_hash);
6140       v4_dst_address.as_u32 = random_vector[0];
6141     }
6142
6143   if (count > 1)
6144     {
6145       /* Turn on async mode */
6146       vam->async_mode = 1;
6147       vam->async_errors = 0;
6148       before = vat_time_now (vam);
6149     }
6150
6151   for (j = 0; j < count; j++)
6152     {
6153       /* Construct the API message */
6154       M2 (IP_ADD_DEL_ROUTE, ip_add_del_route,
6155           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6156
6157       mp->next_hop_sw_if_index = ntohl (sw_if_index);
6158       mp->table_id = ntohl (vrf_id);
6159       mp->create_vrf_if_needed = create_vrf_if_needed;
6160
6161       mp->is_add = is_add;
6162       mp->is_drop = is_drop;
6163       mp->is_unreach = is_unreach;
6164       mp->is_prohibit = is_prohibit;
6165       mp->is_ipv6 = is_ipv6;
6166       mp->is_local = is_local;
6167       mp->is_classify = is_classify;
6168       mp->is_multipath = is_multipath;
6169       mp->is_resolve_host = resolve_host;
6170       mp->is_resolve_attached = resolve_attached;
6171       mp->not_last = not_last;
6172       mp->next_hop_weight = next_hop_weight;
6173       mp->dst_address_length = dst_address_length;
6174       mp->next_hop_table_id = ntohl (next_hop_table_id);
6175       mp->classify_table_index = ntohl (classify_table_index);
6176       mp->next_hop_via_label = ntohl (next_hop_via_label);
6177       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6178       if (0 != mp->next_hop_n_out_labels)
6179         {
6180           memcpy (mp->next_hop_out_label_stack,
6181                   next_hop_out_label_stack,
6182                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6183           vec_free (next_hop_out_label_stack);
6184         }
6185
6186       if (is_ipv6)
6187         {
6188           clib_memcpy (mp->dst_address, &v6_dst_address,
6189                        sizeof (v6_dst_address));
6190           if (next_hop_set)
6191             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6192                          sizeof (v6_next_hop_address));
6193           increment_v6_address (&v6_dst_address);
6194         }
6195       else
6196         {
6197           clib_memcpy (mp->dst_address, &v4_dst_address,
6198                        sizeof (v4_dst_address));
6199           if (next_hop_set)
6200             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6201                          sizeof (v4_next_hop_address));
6202           if (random_add_del)
6203             v4_dst_address.as_u32 = random_vector[j + 1];
6204           else
6205             increment_v4_address (&v4_dst_address);
6206         }
6207       /* send it... */
6208       S;
6209       /* If we receive SIGTERM, stop now... */
6210       if (vam->do_exit)
6211         break;
6212     }
6213
6214   /* When testing multiple add/del ops, use a control-ping to sync */
6215   if (count > 1)
6216     {
6217       vl_api_control_ping_t *mp;
6218       f64 after;
6219
6220       /* Shut off async mode */
6221       vam->async_mode = 0;
6222
6223       M (CONTROL_PING, control_ping);
6224       S;
6225
6226       timeout = vat_time_now (vam) + 1.0;
6227       while (vat_time_now (vam) < timeout)
6228         if (vam->result_ready == 1)
6229           goto out;
6230       vam->retval = -99;
6231
6232     out:
6233       if (vam->retval == -99)
6234         errmsg ("timeout");
6235
6236       if (vam->async_errors > 0)
6237         {
6238           errmsg ("%d asynchronous errors", vam->async_errors);
6239           vam->retval = -98;
6240         }
6241       vam->async_errors = 0;
6242       after = vat_time_now (vam);
6243
6244       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6245       if (j > 0)
6246         count = j;
6247
6248       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6249              count, after - before, count / (after - before));
6250     }
6251   else
6252     {
6253       /* Wait for a reply... */
6254       W;
6255     }
6256
6257   /* Return the good/bad news */
6258   return (vam->retval);
6259 }
6260
6261 static int
6262 api_mpls_route_add_del (vat_main_t * vam)
6263 {
6264   unformat_input_t *i = vam->input;
6265   vl_api_mpls_route_add_del_t *mp;
6266   f64 timeout;
6267   u32 sw_if_index = ~0, table_id = 0;
6268   u8 create_table_if_needed = 0;
6269   u8 is_add = 1;
6270   u32 next_hop_weight = 1;
6271   u8 is_multipath = 0;
6272   u32 next_hop_table_id = 0;
6273   u8 next_hop_set = 0;
6274   ip4_address_t v4_next_hop_address = {
6275     .as_u32 = 0,
6276   };
6277   ip6_address_t v6_next_hop_address = { {0} };
6278   int count = 1;
6279   int j;
6280   f64 before = 0;
6281   u32 classify_table_index = ~0;
6282   u8 is_classify = 0;
6283   u8 resolve_host = 0, resolve_attached = 0;
6284   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6285   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6286   mpls_label_t *next_hop_out_label_stack = NULL;
6287   mpls_label_t local_label = MPLS_LABEL_INVALID;
6288   u8 is_eos = 0;
6289   u8 next_hop_proto_is_ip4 = 1;
6290
6291   /* Parse args required to build the message */
6292   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6293     {
6294       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6295         ;
6296       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6297         ;
6298       else if (unformat (i, "%d", &local_label))
6299         ;
6300       else if (unformat (i, "eos"))
6301         is_eos = 1;
6302       else if (unformat (i, "non-eos"))
6303         is_eos = 0;
6304       else if (unformat (i, "via %U", unformat_ip4_address,
6305                          &v4_next_hop_address))
6306         {
6307           next_hop_set = 1;
6308           next_hop_proto_is_ip4 = 1;
6309         }
6310       else if (unformat (i, "via %U", unformat_ip6_address,
6311                          &v6_next_hop_address))
6312         {
6313           next_hop_set = 1;
6314           next_hop_proto_is_ip4 = 0;
6315         }
6316       else if (unformat (i, "weight %d", &next_hop_weight))
6317         ;
6318       else if (unformat (i, "create-table"))
6319         create_table_if_needed = 1;
6320       else if (unformat (i, "classify %d", &classify_table_index))
6321         {
6322           is_classify = 1;
6323         }
6324       else if (unformat (i, "del"))
6325         is_add = 0;
6326       else if (unformat (i, "add"))
6327         is_add = 1;
6328       else if (unformat (i, "resolve-via-host"))
6329         resolve_host = 1;
6330       else if (unformat (i, "resolve-via-attached"))
6331         resolve_attached = 1;
6332       else if (unformat (i, "multipath"))
6333         is_multipath = 1;
6334       else if (unformat (i, "count %d", &count))
6335         ;
6336       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6337         {
6338           next_hop_set = 1;
6339           next_hop_proto_is_ip4 = 1;
6340         }
6341       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6342         {
6343           next_hop_set = 1;
6344           next_hop_proto_is_ip4 = 0;
6345         }
6346       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6347         ;
6348       else if (unformat (i, "via-label %d", &next_hop_via_label))
6349         ;
6350       else if (unformat (i, "out-label %d", &next_hop_out_label))
6351         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6352       else
6353         {
6354           clib_warning ("parse error '%U'", format_unformat_error, i);
6355           return -99;
6356         }
6357     }
6358
6359   if (!next_hop_set && !is_classify)
6360     {
6361       errmsg ("next hop / classify not set");
6362       return -99;
6363     }
6364
6365   if (MPLS_LABEL_INVALID == local_label)
6366     {
6367       errmsg ("missing label");
6368       return -99;
6369     }
6370
6371   if (count > 1)
6372     {
6373       /* Turn on async mode */
6374       vam->async_mode = 1;
6375       vam->async_errors = 0;
6376       before = vat_time_now (vam);
6377     }
6378
6379   for (j = 0; j < count; j++)
6380     {
6381       /* Construct the API message */
6382       M2 (MPLS_ROUTE_ADD_DEL, mpls_route_add_del,
6383           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6384
6385       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6386       mp->mr_table_id = ntohl (table_id);
6387       mp->mr_create_table_if_needed = create_table_if_needed;
6388
6389       mp->mr_is_add = is_add;
6390       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6391       mp->mr_is_classify = is_classify;
6392       mp->mr_is_multipath = is_multipath;
6393       mp->mr_is_resolve_host = resolve_host;
6394       mp->mr_is_resolve_attached = resolve_attached;
6395       mp->mr_next_hop_weight = next_hop_weight;
6396       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6397       mp->mr_classify_table_index = ntohl (classify_table_index);
6398       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
6399       mp->mr_label = ntohl (local_label);
6400       mp->mr_eos = is_eos;
6401
6402       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6403       if (0 != mp->mr_next_hop_n_out_labels)
6404         {
6405           memcpy (mp->mr_next_hop_out_label_stack,
6406                   next_hop_out_label_stack,
6407                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6408           vec_free (next_hop_out_label_stack);
6409         }
6410
6411       if (next_hop_set)
6412         {
6413           if (next_hop_proto_is_ip4)
6414             {
6415               clib_memcpy (mp->mr_next_hop,
6416                            &v4_next_hop_address,
6417                            sizeof (v4_next_hop_address));
6418             }
6419           else
6420             {
6421               clib_memcpy (mp->mr_next_hop,
6422                            &v6_next_hop_address,
6423                            sizeof (v6_next_hop_address));
6424             }
6425         }
6426       local_label++;
6427
6428       /* send it... */
6429       S;
6430       /* If we receive SIGTERM, stop now... */
6431       if (vam->do_exit)
6432         break;
6433     }
6434
6435   /* When testing multiple add/del ops, use a control-ping to sync */
6436   if (count > 1)
6437     {
6438       vl_api_control_ping_t *mp;
6439       f64 after;
6440
6441       /* Shut off async mode */
6442       vam->async_mode = 0;
6443
6444       M (CONTROL_PING, control_ping);
6445       S;
6446
6447       timeout = vat_time_now (vam) + 1.0;
6448       while (vat_time_now (vam) < timeout)
6449         if (vam->result_ready == 1)
6450           goto out;
6451       vam->retval = -99;
6452
6453     out:
6454       if (vam->retval == -99)
6455         errmsg ("timeout");
6456
6457       if (vam->async_errors > 0)
6458         {
6459           errmsg ("%d asynchronous errors", vam->async_errors);
6460           vam->retval = -98;
6461         }
6462       vam->async_errors = 0;
6463       after = vat_time_now (vam);
6464
6465       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6466       if (j > 0)
6467         count = j;
6468
6469       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6470              count, after - before, count / (after - before));
6471     }
6472   else
6473     {
6474       /* Wait for a reply... */
6475       W;
6476     }
6477
6478   /* Return the good/bad news */
6479   return (vam->retval);
6480 }
6481
6482 static int
6483 api_mpls_ip_bind_unbind (vat_main_t * vam)
6484 {
6485   unformat_input_t *i = vam->input;
6486   vl_api_mpls_ip_bind_unbind_t *mp;
6487   f64 timeout;
6488   u32 ip_table_id = 0;
6489   u8 create_table_if_needed = 0;
6490   u8 is_bind = 1;
6491   u8 is_ip4 = 1;
6492   ip4_address_t v4_address;
6493   ip6_address_t v6_address;
6494   u32 address_length;
6495   u8 address_set = 0;
6496   mpls_label_t local_label = MPLS_LABEL_INVALID;
6497
6498   /* Parse args required to build the message */
6499   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6500     {
6501       if (unformat (i, "%U/%d", unformat_ip4_address,
6502                     &v4_address, &address_length))
6503         {
6504           is_ip4 = 1;
6505           address_set = 1;
6506         }
6507       else if (unformat (i, "%U/%d", unformat_ip6_address,
6508                          &v6_address, &address_length))
6509         {
6510           is_ip4 = 0;
6511           address_set = 1;
6512         }
6513       else if (unformat (i, "%d", &local_label))
6514         ;
6515       else if (unformat (i, "create-table"))
6516         create_table_if_needed = 1;
6517       else if (unformat (i, "table-id %d", &ip_table_id))
6518         ;
6519       else if (unformat (i, "unbind"))
6520         is_bind = 0;
6521       else if (unformat (i, "bind"))
6522         is_bind = 1;
6523       else
6524         {
6525           clib_warning ("parse error '%U'", format_unformat_error, i);
6526           return -99;
6527         }
6528     }
6529
6530   if (!address_set)
6531     {
6532       errmsg ("IP addres not set");
6533       return -99;
6534     }
6535
6536   if (MPLS_LABEL_INVALID == local_label)
6537     {
6538       errmsg ("missing label");
6539       return -99;
6540     }
6541
6542   /* Construct the API message */
6543   M (MPLS_IP_BIND_UNBIND, mpls_ip_bind_unbind);
6544
6545   mp->mb_create_table_if_needed = create_table_if_needed;
6546   mp->mb_is_bind = is_bind;
6547   mp->mb_is_ip4 = is_ip4;
6548   mp->mb_ip_table_id = ntohl (ip_table_id);
6549   mp->mb_mpls_table_id = 0;
6550   mp->mb_label = ntohl (local_label);
6551   mp->mb_address_length = address_length;
6552
6553   if (is_ip4)
6554     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
6555   else
6556     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
6557
6558   /* send it... */
6559   S;
6560
6561   /* Wait for a reply... */
6562   W;
6563 }
6564
6565 static int
6566 api_proxy_arp_add_del (vat_main_t * vam)
6567 {
6568   unformat_input_t *i = vam->input;
6569   vl_api_proxy_arp_add_del_t *mp;
6570   f64 timeout;
6571   u32 vrf_id = 0;
6572   u8 is_add = 1;
6573   ip4_address_t lo, hi;
6574   u8 range_set = 0;
6575
6576   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6577     {
6578       if (unformat (i, "vrf %d", &vrf_id))
6579         ;
6580       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
6581                          unformat_ip4_address, &hi))
6582         range_set = 1;
6583       else if (unformat (i, "del"))
6584         is_add = 0;
6585       else
6586         {
6587           clib_warning ("parse error '%U'", format_unformat_error, i);
6588           return -99;
6589         }
6590     }
6591
6592   if (range_set == 0)
6593     {
6594       errmsg ("address range not set");
6595       return -99;
6596     }
6597
6598   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
6599
6600   mp->vrf_id = ntohl (vrf_id);
6601   mp->is_add = is_add;
6602   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
6603   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
6604
6605   S;
6606   W;
6607   /* NOTREACHED */
6608   return 0;
6609 }
6610
6611 static int
6612 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
6613 {
6614   unformat_input_t *i = vam->input;
6615   vl_api_proxy_arp_intfc_enable_disable_t *mp;
6616   f64 timeout;
6617   u32 sw_if_index;
6618   u8 enable = 1;
6619   u8 sw_if_index_set = 0;
6620
6621   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6622     {
6623       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6624         sw_if_index_set = 1;
6625       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6626         sw_if_index_set = 1;
6627       else if (unformat (i, "enable"))
6628         enable = 1;
6629       else if (unformat (i, "disable"))
6630         enable = 0;
6631       else
6632         {
6633           clib_warning ("parse error '%U'", format_unformat_error, i);
6634           return -99;
6635         }
6636     }
6637
6638   if (sw_if_index_set == 0)
6639     {
6640       errmsg ("missing interface name or sw_if_index");
6641       return -99;
6642     }
6643
6644   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
6645
6646   mp->sw_if_index = ntohl (sw_if_index);
6647   mp->enable_disable = enable;
6648
6649   S;
6650   W;
6651   /* NOTREACHED */
6652   return 0;
6653 }
6654
6655 static int
6656 api_mpls_tunnel_add_del (vat_main_t * vam)
6657 {
6658   unformat_input_t *i = vam->input;
6659   vl_api_mpls_tunnel_add_del_t *mp;
6660   f64 timeout;
6661
6662   u8 is_add = 1;
6663   u8 l2_only = 0;
6664   u32 sw_if_index = ~0;
6665   u32 next_hop_sw_if_index = ~0;
6666   u32 next_hop_proto_is_ip4 = 1;
6667
6668   u32 next_hop_table_id = 0;
6669   ip4_address_t v4_next_hop_address = {
6670     .as_u32 = 0,
6671   };
6672   ip6_address_t v6_next_hop_address = { {0} };
6673   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
6674
6675   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6676     {
6677       if (unformat (i, "add"))
6678         is_add = 1;
6679       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
6680         is_add = 0;
6681       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
6682         ;
6683       else if (unformat (i, "via %U",
6684                          unformat_ip4_address, &v4_next_hop_address))
6685         {
6686           next_hop_proto_is_ip4 = 1;
6687         }
6688       else if (unformat (i, "via %U",
6689                          unformat_ip6_address, &v6_next_hop_address))
6690         {
6691           next_hop_proto_is_ip4 = 0;
6692         }
6693       else if (unformat (i, "l2-only"))
6694         l2_only = 1;
6695       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6696         ;
6697       else if (unformat (i, "out-label %d", &next_hop_out_label))
6698         vec_add1 (labels, ntohl (next_hop_out_label));
6699       else
6700         {
6701           clib_warning ("parse error '%U'", format_unformat_error, i);
6702           return -99;
6703         }
6704     }
6705
6706   M2 (MPLS_TUNNEL_ADD_DEL, mpls_tunnel_add_del,
6707       sizeof (mpls_label_t) * vec_len (labels));
6708
6709   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
6710   mp->mt_sw_if_index = ntohl (sw_if_index);
6711   mp->mt_is_add = is_add;
6712   mp->mt_l2_only = l2_only;
6713   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
6714   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6715
6716   mp->mt_next_hop_n_out_labels = vec_len (labels);
6717
6718   if (0 != mp->mt_next_hop_n_out_labels)
6719     {
6720       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
6721                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
6722       vec_free (labels);
6723     }
6724
6725   if (next_hop_proto_is_ip4)
6726     {
6727       clib_memcpy (mp->mt_next_hop,
6728                    &v4_next_hop_address, sizeof (v4_next_hop_address));
6729     }
6730   else
6731     {
6732       clib_memcpy (mp->mt_next_hop,
6733                    &v6_next_hop_address, sizeof (v6_next_hop_address));
6734     }
6735
6736   S;
6737   W;
6738   /* NOTREACHED */
6739   return 0;
6740 }
6741
6742 static int
6743 api_sw_interface_set_unnumbered (vat_main_t * vam)
6744 {
6745   unformat_input_t *i = vam->input;
6746   vl_api_sw_interface_set_unnumbered_t *mp;
6747   f64 timeout;
6748   u32 sw_if_index;
6749   u32 unnum_sw_index = ~0;
6750   u8 is_add = 1;
6751   u8 sw_if_index_set = 0;
6752
6753   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6754     {
6755       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6756         sw_if_index_set = 1;
6757       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6758         sw_if_index_set = 1;
6759       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6760         ;
6761       else if (unformat (i, "del"))
6762         is_add = 0;
6763       else
6764         {
6765           clib_warning ("parse error '%U'", format_unformat_error, i);
6766           return -99;
6767         }
6768     }
6769
6770   if (sw_if_index_set == 0)
6771     {
6772       errmsg ("missing interface name or sw_if_index");
6773       return -99;
6774     }
6775
6776   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
6777
6778   mp->sw_if_index = ntohl (sw_if_index);
6779   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6780   mp->is_add = is_add;
6781
6782   S;
6783   W;
6784   /* NOTREACHED */
6785   return 0;
6786 }
6787
6788 static int
6789 api_ip_neighbor_add_del (vat_main_t * vam)
6790 {
6791   unformat_input_t *i = vam->input;
6792   vl_api_ip_neighbor_add_del_t *mp;
6793   f64 timeout;
6794   u32 sw_if_index;
6795   u8 sw_if_index_set = 0;
6796   u32 vrf_id = 0;
6797   u8 is_add = 1;
6798   u8 is_static = 0;
6799   u8 mac_address[6];
6800   u8 mac_set = 0;
6801   u8 v4_address_set = 0;
6802   u8 v6_address_set = 0;
6803   ip4_address_t v4address;
6804   ip6_address_t v6address;
6805
6806   memset (mac_address, 0, sizeof (mac_address));
6807
6808   /* Parse args required to build the message */
6809   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6810     {
6811       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6812         {
6813           mac_set = 1;
6814         }
6815       else if (unformat (i, "del"))
6816         is_add = 0;
6817       else
6818         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6819         sw_if_index_set = 1;
6820       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6821         sw_if_index_set = 1;
6822       else if (unformat (i, "is_static"))
6823         is_static = 1;
6824       else if (unformat (i, "vrf %d", &vrf_id))
6825         ;
6826       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
6827         v4_address_set = 1;
6828       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
6829         v6_address_set = 1;
6830       else
6831         {
6832           clib_warning ("parse error '%U'", format_unformat_error, i);
6833           return -99;
6834         }
6835     }
6836
6837   if (sw_if_index_set == 0)
6838     {
6839       errmsg ("missing interface name or sw_if_index");
6840       return -99;
6841     }
6842   if (v4_address_set && v6_address_set)
6843     {
6844       errmsg ("both v4 and v6 addresses set");
6845       return -99;
6846     }
6847   if (!v4_address_set && !v6_address_set)
6848     {
6849       errmsg ("no address set");
6850       return -99;
6851     }
6852
6853   /* Construct the API message */
6854   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6855
6856   mp->sw_if_index = ntohl (sw_if_index);
6857   mp->is_add = is_add;
6858   mp->vrf_id = ntohl (vrf_id);
6859   mp->is_static = is_static;
6860   if (mac_set)
6861     clib_memcpy (mp->mac_address, mac_address, 6);
6862   if (v6_address_set)
6863     {
6864       mp->is_ipv6 = 1;
6865       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6866     }
6867   else
6868     {
6869       /* mp->is_ipv6 = 0; via memset in M macro above */
6870       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6871     }
6872
6873   /* send it... */
6874   S;
6875
6876   /* Wait for a reply, return good/bad news  */
6877   W;
6878
6879   /* NOTREACHED */
6880   return 0;
6881 }
6882
6883 static int
6884 api_reset_vrf (vat_main_t * vam)
6885 {
6886   unformat_input_t *i = vam->input;
6887   vl_api_reset_vrf_t *mp;
6888   f64 timeout;
6889   u32 vrf_id = 0;
6890   u8 is_ipv6 = 0;
6891   u8 vrf_id_set = 0;
6892
6893   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6894     {
6895       if (unformat (i, "vrf %d", &vrf_id))
6896         vrf_id_set = 1;
6897       else if (unformat (i, "ipv6"))
6898         is_ipv6 = 1;
6899       else
6900         {
6901           clib_warning ("parse error '%U'", format_unformat_error, i);
6902           return -99;
6903         }
6904     }
6905
6906   if (vrf_id_set == 0)
6907     {
6908       errmsg ("missing vrf id");
6909       return -99;
6910     }
6911
6912   M (RESET_VRF, reset_vrf);
6913
6914   mp->vrf_id = ntohl (vrf_id);
6915   mp->is_ipv6 = is_ipv6;
6916
6917   S;
6918   W;
6919   /* NOTREACHED */
6920   return 0;
6921 }
6922
6923 static int
6924 api_create_vlan_subif (vat_main_t * vam)
6925 {
6926   unformat_input_t *i = vam->input;
6927   vl_api_create_vlan_subif_t *mp;
6928   f64 timeout;
6929   u32 sw_if_index;
6930   u8 sw_if_index_set = 0;
6931   u32 vlan_id;
6932   u8 vlan_id_set = 0;
6933
6934   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6935     {
6936       if (unformat (i, "sw_if_index %d", &sw_if_index))
6937         sw_if_index_set = 1;
6938       else
6939         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6940         sw_if_index_set = 1;
6941       else if (unformat (i, "vlan %d", &vlan_id))
6942         vlan_id_set = 1;
6943       else
6944         {
6945           clib_warning ("parse error '%U'", format_unformat_error, i);
6946           return -99;
6947         }
6948     }
6949
6950   if (sw_if_index_set == 0)
6951     {
6952       errmsg ("missing interface name or sw_if_index");
6953       return -99;
6954     }
6955
6956   if (vlan_id_set == 0)
6957     {
6958       errmsg ("missing vlan_id");
6959       return -99;
6960     }
6961   M (CREATE_VLAN_SUBIF, create_vlan_subif);
6962
6963   mp->sw_if_index = ntohl (sw_if_index);
6964   mp->vlan_id = ntohl (vlan_id);
6965
6966   S;
6967   W;
6968   /* NOTREACHED */
6969   return 0;
6970 }
6971
6972 #define foreach_create_subif_bit                \
6973 _(no_tags)                                      \
6974 _(one_tag)                                      \
6975 _(two_tags)                                     \
6976 _(dot1ad)                                       \
6977 _(exact_match)                                  \
6978 _(default_sub)                                  \
6979 _(outer_vlan_id_any)                            \
6980 _(inner_vlan_id_any)
6981
6982 static int
6983 api_create_subif (vat_main_t * vam)
6984 {
6985   unformat_input_t *i = vam->input;
6986   vl_api_create_subif_t *mp;
6987   f64 timeout;
6988   u32 sw_if_index;
6989   u8 sw_if_index_set = 0;
6990   u32 sub_id;
6991   u8 sub_id_set = 0;
6992   u32 no_tags = 0;
6993   u32 one_tag = 0;
6994   u32 two_tags = 0;
6995   u32 dot1ad = 0;
6996   u32 exact_match = 0;
6997   u32 default_sub = 0;
6998   u32 outer_vlan_id_any = 0;
6999   u32 inner_vlan_id_any = 0;
7000   u32 tmp;
7001   u16 outer_vlan_id = 0;
7002   u16 inner_vlan_id = 0;
7003
7004   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7005     {
7006       if (unformat (i, "sw_if_index %d", &sw_if_index))
7007         sw_if_index_set = 1;
7008       else
7009         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7010         sw_if_index_set = 1;
7011       else if (unformat (i, "sub_id %d", &sub_id))
7012         sub_id_set = 1;
7013       else if (unformat (i, "outer_vlan_id %d", &tmp))
7014         outer_vlan_id = tmp;
7015       else if (unformat (i, "inner_vlan_id %d", &tmp))
7016         inner_vlan_id = tmp;
7017
7018 #define _(a) else if (unformat (i, #a)) a = 1 ;
7019       foreach_create_subif_bit
7020 #undef _
7021         else
7022         {
7023           clib_warning ("parse error '%U'", format_unformat_error, i);
7024           return -99;
7025         }
7026     }
7027
7028   if (sw_if_index_set == 0)
7029     {
7030       errmsg ("missing interface name or sw_if_index");
7031       return -99;
7032     }
7033
7034   if (sub_id_set == 0)
7035     {
7036       errmsg ("missing sub_id");
7037       return -99;
7038     }
7039   M (CREATE_SUBIF, create_subif);
7040
7041   mp->sw_if_index = ntohl (sw_if_index);
7042   mp->sub_id = ntohl (sub_id);
7043
7044 #define _(a) mp->a = a;
7045   foreach_create_subif_bit;
7046 #undef _
7047
7048   mp->outer_vlan_id = ntohs (outer_vlan_id);
7049   mp->inner_vlan_id = ntohs (inner_vlan_id);
7050
7051   S;
7052   W;
7053   /* NOTREACHED */
7054   return 0;
7055 }
7056
7057 static int
7058 api_oam_add_del (vat_main_t * vam)
7059 {
7060   unformat_input_t *i = vam->input;
7061   vl_api_oam_add_del_t *mp;
7062   f64 timeout;
7063   u32 vrf_id = 0;
7064   u8 is_add = 1;
7065   ip4_address_t src, dst;
7066   u8 src_set = 0;
7067   u8 dst_set = 0;
7068
7069   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7070     {
7071       if (unformat (i, "vrf %d", &vrf_id))
7072         ;
7073       else if (unformat (i, "src %U", unformat_ip4_address, &src))
7074         src_set = 1;
7075       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
7076         dst_set = 1;
7077       else if (unformat (i, "del"))
7078         is_add = 0;
7079       else
7080         {
7081           clib_warning ("parse error '%U'", format_unformat_error, i);
7082           return -99;
7083         }
7084     }
7085
7086   if (src_set == 0)
7087     {
7088       errmsg ("missing src addr");
7089       return -99;
7090     }
7091
7092   if (dst_set == 0)
7093     {
7094       errmsg ("missing dst addr");
7095       return -99;
7096     }
7097
7098   M (OAM_ADD_DEL, oam_add_del);
7099
7100   mp->vrf_id = ntohl (vrf_id);
7101   mp->is_add = is_add;
7102   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
7103   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
7104
7105   S;
7106   W;
7107   /* NOTREACHED */
7108   return 0;
7109 }
7110
7111 static int
7112 api_reset_fib (vat_main_t * vam)
7113 {
7114   unformat_input_t *i = vam->input;
7115   vl_api_reset_fib_t *mp;
7116   f64 timeout;
7117   u32 vrf_id = 0;
7118   u8 is_ipv6 = 0;
7119   u8 vrf_id_set = 0;
7120
7121   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7122     {
7123       if (unformat (i, "vrf %d", &vrf_id))
7124         vrf_id_set = 1;
7125       else if (unformat (i, "ipv6"))
7126         is_ipv6 = 1;
7127       else
7128         {
7129           clib_warning ("parse error '%U'", format_unformat_error, i);
7130           return -99;
7131         }
7132     }
7133
7134   if (vrf_id_set == 0)
7135     {
7136       errmsg ("missing vrf id");
7137       return -99;
7138     }
7139
7140   M (RESET_FIB, reset_fib);
7141
7142   mp->vrf_id = ntohl (vrf_id);
7143   mp->is_ipv6 = is_ipv6;
7144
7145   S;
7146   W;
7147   /* NOTREACHED */
7148   return 0;
7149 }
7150
7151 static int
7152 api_dhcp_proxy_config (vat_main_t * vam)
7153 {
7154   unformat_input_t *i = vam->input;
7155   vl_api_dhcp_proxy_config_t *mp;
7156   f64 timeout;
7157   u32 vrf_id = 0;
7158   u8 is_add = 1;
7159   u8 insert_cid = 1;
7160   u8 v4_address_set = 0;
7161   u8 v6_address_set = 0;
7162   ip4_address_t v4address;
7163   ip6_address_t v6address;
7164   u8 v4_src_address_set = 0;
7165   u8 v6_src_address_set = 0;
7166   ip4_address_t v4srcaddress;
7167   ip6_address_t v6srcaddress;
7168
7169   /* Parse args required to build the message */
7170   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7171     {
7172       if (unformat (i, "del"))
7173         is_add = 0;
7174       else if (unformat (i, "vrf %d", &vrf_id))
7175         ;
7176       else if (unformat (i, "insert-cid %d", &insert_cid))
7177         ;
7178       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7179         v4_address_set = 1;
7180       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7181         v6_address_set = 1;
7182       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7183         v4_src_address_set = 1;
7184       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7185         v6_src_address_set = 1;
7186       else
7187         break;
7188     }
7189
7190   if (v4_address_set && v6_address_set)
7191     {
7192       errmsg ("both v4 and v6 server addresses set");
7193       return -99;
7194     }
7195   if (!v4_address_set && !v6_address_set)
7196     {
7197       errmsg ("no server addresses set");
7198       return -99;
7199     }
7200
7201   if (v4_src_address_set && v6_src_address_set)
7202     {
7203       errmsg ("both v4 and v6  src addresses set");
7204       return -99;
7205     }
7206   if (!v4_src_address_set && !v6_src_address_set)
7207     {
7208       errmsg ("no src addresses set");
7209       return -99;
7210     }
7211
7212   if (!(v4_src_address_set && v4_address_set) &&
7213       !(v6_src_address_set && v6_address_set))
7214     {
7215       errmsg ("no matching server and src addresses set");
7216       return -99;
7217     }
7218
7219   /* Construct the API message */
7220   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
7221
7222   mp->insert_circuit_id = insert_cid;
7223   mp->is_add = is_add;
7224   mp->vrf_id = ntohl (vrf_id);
7225   if (v6_address_set)
7226     {
7227       mp->is_ipv6 = 1;
7228       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7229       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7230     }
7231   else
7232     {
7233       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7234       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7235     }
7236
7237   /* send it... */
7238   S;
7239
7240   /* Wait for a reply, return good/bad news  */
7241   W;
7242   /* NOTREACHED */
7243   return 0;
7244 }
7245
7246 static int
7247 api_dhcp_proxy_config_2 (vat_main_t * vam)
7248 {
7249   unformat_input_t *i = vam->input;
7250   vl_api_dhcp_proxy_config_2_t *mp;
7251   f64 timeout;
7252   u32 rx_vrf_id = 0;
7253   u32 server_vrf_id = 0;
7254   u8 is_add = 1;
7255   u8 insert_cid = 1;
7256   u8 v4_address_set = 0;
7257   u8 v6_address_set = 0;
7258   ip4_address_t v4address;
7259   ip6_address_t v6address;
7260   u8 v4_src_address_set = 0;
7261   u8 v6_src_address_set = 0;
7262   ip4_address_t v4srcaddress;
7263   ip6_address_t v6srcaddress;
7264
7265   /* Parse args required to build the message */
7266   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7267     {
7268       if (unformat (i, "del"))
7269         is_add = 0;
7270       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7271         ;
7272       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7273         ;
7274       else if (unformat (i, "insert-cid %d", &insert_cid))
7275         ;
7276       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7277         v4_address_set = 1;
7278       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7279         v6_address_set = 1;
7280       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7281         v4_src_address_set = 1;
7282       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7283         v6_src_address_set = 1;
7284       else
7285         break;
7286     }
7287
7288   if (v4_address_set && v6_address_set)
7289     {
7290       errmsg ("both v4 and v6 server addresses set");
7291       return -99;
7292     }
7293   if (!v4_address_set && !v6_address_set)
7294     {
7295       errmsg ("no server addresses set");
7296       return -99;
7297     }
7298
7299   if (v4_src_address_set && v6_src_address_set)
7300     {
7301       errmsg ("both v4 and v6  src addresses set");
7302       return -99;
7303     }
7304   if (!v4_src_address_set && !v6_src_address_set)
7305     {
7306       errmsg ("no src addresses set");
7307       return -99;
7308     }
7309
7310   if (!(v4_src_address_set && v4_address_set) &&
7311       !(v6_src_address_set && v6_address_set))
7312     {
7313       errmsg ("no matching server and src addresses set");
7314       return -99;
7315     }
7316
7317   /* Construct the API message */
7318   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
7319
7320   mp->insert_circuit_id = insert_cid;
7321   mp->is_add = is_add;
7322   mp->rx_vrf_id = ntohl (rx_vrf_id);
7323   mp->server_vrf_id = ntohl (server_vrf_id);
7324   if (v6_address_set)
7325     {
7326       mp->is_ipv6 = 1;
7327       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7328       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7329     }
7330   else
7331     {
7332       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7333       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7334     }
7335
7336   /* send it... */
7337   S;
7338
7339   /* Wait for a reply, return good/bad news  */
7340   W;
7341   /* NOTREACHED */
7342   return 0;
7343 }
7344
7345 static int
7346 api_dhcp_proxy_set_vss (vat_main_t * vam)
7347 {
7348   unformat_input_t *i = vam->input;
7349   vl_api_dhcp_proxy_set_vss_t *mp;
7350   f64 timeout;
7351   u8 is_ipv6 = 0;
7352   u8 is_add = 1;
7353   u32 tbl_id;
7354   u8 tbl_id_set = 0;
7355   u32 oui;
7356   u8 oui_set = 0;
7357   u32 fib_id;
7358   u8 fib_id_set = 0;
7359
7360   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7361     {
7362       if (unformat (i, "tbl_id %d", &tbl_id))
7363         tbl_id_set = 1;
7364       if (unformat (i, "fib_id %d", &fib_id))
7365         fib_id_set = 1;
7366       if (unformat (i, "oui %d", &oui))
7367         oui_set = 1;
7368       else if (unformat (i, "ipv6"))
7369         is_ipv6 = 1;
7370       else if (unformat (i, "del"))
7371         is_add = 0;
7372       else
7373         {
7374           clib_warning ("parse error '%U'", format_unformat_error, i);
7375           return -99;
7376         }
7377     }
7378
7379   if (tbl_id_set == 0)
7380     {
7381       errmsg ("missing tbl id");
7382       return -99;
7383     }
7384
7385   if (fib_id_set == 0)
7386     {
7387       errmsg ("missing fib id");
7388       return -99;
7389     }
7390   if (oui_set == 0)
7391     {
7392       errmsg ("missing oui");
7393       return -99;
7394     }
7395
7396   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
7397   mp->tbl_id = ntohl (tbl_id);
7398   mp->fib_id = ntohl (fib_id);
7399   mp->oui = ntohl (oui);
7400   mp->is_ipv6 = is_ipv6;
7401   mp->is_add = is_add;
7402
7403   S;
7404   W;
7405   /* NOTREACHED */
7406   return 0;
7407 }
7408
7409 static int
7410 api_dhcp_client_config (vat_main_t * vam)
7411 {
7412   unformat_input_t *i = vam->input;
7413   vl_api_dhcp_client_config_t *mp;
7414   f64 timeout;
7415   u32 sw_if_index;
7416   u8 sw_if_index_set = 0;
7417   u8 is_add = 1;
7418   u8 *hostname = 0;
7419   u8 disable_event = 0;
7420
7421   /* Parse args required to build the message */
7422   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7423     {
7424       if (unformat (i, "del"))
7425         is_add = 0;
7426       else
7427         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7428         sw_if_index_set = 1;
7429       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7430         sw_if_index_set = 1;
7431       else if (unformat (i, "hostname %s", &hostname))
7432         ;
7433       else if (unformat (i, "disable_event"))
7434         disable_event = 1;
7435       else
7436         break;
7437     }
7438
7439   if (sw_if_index_set == 0)
7440     {
7441       errmsg ("missing interface name or sw_if_index");
7442       return -99;
7443     }
7444
7445   if (vec_len (hostname) > 63)
7446     {
7447       errmsg ("hostname too long");
7448     }
7449   vec_add1 (hostname, 0);
7450
7451   /* Construct the API message */
7452   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
7453
7454   mp->sw_if_index = ntohl (sw_if_index);
7455   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7456   vec_free (hostname);
7457   mp->is_add = is_add;
7458   mp->want_dhcp_event = disable_event ? 0 : 1;
7459   mp->pid = getpid ();
7460
7461   /* send it... */
7462   S;
7463
7464   /* Wait for a reply, return good/bad news  */
7465   W;
7466   /* NOTREACHED */
7467   return 0;
7468 }
7469
7470 static int
7471 api_set_ip_flow_hash (vat_main_t * vam)
7472 {
7473   unformat_input_t *i = vam->input;
7474   vl_api_set_ip_flow_hash_t *mp;
7475   f64 timeout;
7476   u32 vrf_id = 0;
7477   u8 is_ipv6 = 0;
7478   u8 vrf_id_set = 0;
7479   u8 src = 0;
7480   u8 dst = 0;
7481   u8 sport = 0;
7482   u8 dport = 0;
7483   u8 proto = 0;
7484   u8 reverse = 0;
7485
7486   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7487     {
7488       if (unformat (i, "vrf %d", &vrf_id))
7489         vrf_id_set = 1;
7490       else if (unformat (i, "ipv6"))
7491         is_ipv6 = 1;
7492       else if (unformat (i, "src"))
7493         src = 1;
7494       else if (unformat (i, "dst"))
7495         dst = 1;
7496       else if (unformat (i, "sport"))
7497         sport = 1;
7498       else if (unformat (i, "dport"))
7499         dport = 1;
7500       else if (unformat (i, "proto"))
7501         proto = 1;
7502       else if (unformat (i, "reverse"))
7503         reverse = 1;
7504
7505       else
7506         {
7507           clib_warning ("parse error '%U'", format_unformat_error, i);
7508           return -99;
7509         }
7510     }
7511
7512   if (vrf_id_set == 0)
7513     {
7514       errmsg ("missing vrf id");
7515       return -99;
7516     }
7517
7518   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
7519   mp->src = src;
7520   mp->dst = dst;
7521   mp->sport = sport;
7522   mp->dport = dport;
7523   mp->proto = proto;
7524   mp->reverse = reverse;
7525   mp->vrf_id = ntohl (vrf_id);
7526   mp->is_ipv6 = is_ipv6;
7527
7528   S;
7529   W;
7530   /* NOTREACHED */
7531   return 0;
7532 }
7533
7534 static int
7535 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7536 {
7537   unformat_input_t *i = vam->input;
7538   vl_api_sw_interface_ip6_enable_disable_t *mp;
7539   f64 timeout;
7540   u32 sw_if_index;
7541   u8 sw_if_index_set = 0;
7542   u8 enable = 0;
7543
7544   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7545     {
7546       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7547         sw_if_index_set = 1;
7548       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7549         sw_if_index_set = 1;
7550       else if (unformat (i, "enable"))
7551         enable = 1;
7552       else if (unformat (i, "disable"))
7553         enable = 0;
7554       else
7555         {
7556           clib_warning ("parse error '%U'", format_unformat_error, i);
7557           return -99;
7558         }
7559     }
7560
7561   if (sw_if_index_set == 0)
7562     {
7563       errmsg ("missing interface name or sw_if_index");
7564       return -99;
7565     }
7566
7567   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
7568
7569   mp->sw_if_index = ntohl (sw_if_index);
7570   mp->enable = enable;
7571
7572   S;
7573   W;
7574   /* NOTREACHED */
7575   return 0;
7576 }
7577
7578 static int
7579 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
7580 {
7581   unformat_input_t *i = vam->input;
7582   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
7583   f64 timeout;
7584   u32 sw_if_index;
7585   u8 sw_if_index_set = 0;
7586   u8 v6_address_set = 0;
7587   ip6_address_t v6address;
7588
7589   /* Parse args required to build the message */
7590   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7591     {
7592       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7593         sw_if_index_set = 1;
7594       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7595         sw_if_index_set = 1;
7596       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
7597         v6_address_set = 1;
7598       else
7599         break;
7600     }
7601
7602   if (sw_if_index_set == 0)
7603     {
7604       errmsg ("missing interface name or sw_if_index");
7605       return -99;
7606     }
7607   if (!v6_address_set)
7608     {
7609       errmsg ("no address set");
7610       return -99;
7611     }
7612
7613   /* Construct the API message */
7614   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
7615      sw_interface_ip6_set_link_local_address);
7616
7617   mp->sw_if_index = ntohl (sw_if_index);
7618   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7619
7620   /* send it... */
7621   S;
7622
7623   /* Wait for a reply, return good/bad news  */
7624   W;
7625
7626   /* NOTREACHED */
7627   return 0;
7628 }
7629
7630
7631 static int
7632 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
7633 {
7634   unformat_input_t *i = vam->input;
7635   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
7636   f64 timeout;
7637   u32 sw_if_index;
7638   u8 sw_if_index_set = 0;
7639   u32 address_length = 0;
7640   u8 v6_address_set = 0;
7641   ip6_address_t v6address;
7642   u8 use_default = 0;
7643   u8 no_advertise = 0;
7644   u8 off_link = 0;
7645   u8 no_autoconfig = 0;
7646   u8 no_onlink = 0;
7647   u8 is_no = 0;
7648   u32 val_lifetime = 0;
7649   u32 pref_lifetime = 0;
7650
7651   /* Parse args required to build the message */
7652   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7653     {
7654       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7655         sw_if_index_set = 1;
7656       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7657         sw_if_index_set = 1;
7658       else if (unformat (i, "%U/%d",
7659                          unformat_ip6_address, &v6address, &address_length))
7660         v6_address_set = 1;
7661       else if (unformat (i, "val_life %d", &val_lifetime))
7662         ;
7663       else if (unformat (i, "pref_life %d", &pref_lifetime))
7664         ;
7665       else if (unformat (i, "def"))
7666         use_default = 1;
7667       else if (unformat (i, "noadv"))
7668         no_advertise = 1;
7669       else if (unformat (i, "offl"))
7670         off_link = 1;
7671       else if (unformat (i, "noauto"))
7672         no_autoconfig = 1;
7673       else if (unformat (i, "nolink"))
7674         no_onlink = 1;
7675       else if (unformat (i, "isno"))
7676         is_no = 1;
7677       else
7678         {
7679           clib_warning ("parse error '%U'", format_unformat_error, i);
7680           return -99;
7681         }
7682     }
7683
7684   if (sw_if_index_set == 0)
7685     {
7686       errmsg ("missing interface name or sw_if_index");
7687       return -99;
7688     }
7689   if (!v6_address_set)
7690     {
7691       errmsg ("no address set");
7692       return -99;
7693     }
7694
7695   /* Construct the API message */
7696   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
7697
7698   mp->sw_if_index = ntohl (sw_if_index);
7699   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7700   mp->address_length = address_length;
7701   mp->use_default = use_default;
7702   mp->no_advertise = no_advertise;
7703   mp->off_link = off_link;
7704   mp->no_autoconfig = no_autoconfig;
7705   mp->no_onlink = no_onlink;
7706   mp->is_no = is_no;
7707   mp->val_lifetime = ntohl (val_lifetime);
7708   mp->pref_lifetime = ntohl (pref_lifetime);
7709
7710   /* send it... */
7711   S;
7712
7713   /* Wait for a reply, return good/bad news  */
7714   W;
7715
7716   /* NOTREACHED */
7717   return 0;
7718 }
7719
7720 static int
7721 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
7722 {
7723   unformat_input_t *i = vam->input;
7724   vl_api_sw_interface_ip6nd_ra_config_t *mp;
7725   f64 timeout;
7726   u32 sw_if_index;
7727   u8 sw_if_index_set = 0;
7728   u8 suppress = 0;
7729   u8 managed = 0;
7730   u8 other = 0;
7731   u8 ll_option = 0;
7732   u8 send_unicast = 0;
7733   u8 cease = 0;
7734   u8 is_no = 0;
7735   u8 default_router = 0;
7736   u32 max_interval = 0;
7737   u32 min_interval = 0;
7738   u32 lifetime = 0;
7739   u32 initial_count = 0;
7740   u32 initial_interval = 0;
7741
7742
7743   /* Parse args required to build the message */
7744   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7745     {
7746       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7747         sw_if_index_set = 1;
7748       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7749         sw_if_index_set = 1;
7750       else if (unformat (i, "maxint %d", &max_interval))
7751         ;
7752       else if (unformat (i, "minint %d", &min_interval))
7753         ;
7754       else if (unformat (i, "life %d", &lifetime))
7755         ;
7756       else if (unformat (i, "count %d", &initial_count))
7757         ;
7758       else if (unformat (i, "interval %d", &initial_interval))
7759         ;
7760       else if (unformat (i, "suppress") || unformat (i, "surpress"))
7761         suppress = 1;
7762       else if (unformat (i, "managed"))
7763         managed = 1;
7764       else if (unformat (i, "other"))
7765         other = 1;
7766       else if (unformat (i, "ll"))
7767         ll_option = 1;
7768       else if (unformat (i, "send"))
7769         send_unicast = 1;
7770       else if (unformat (i, "cease"))
7771         cease = 1;
7772       else if (unformat (i, "isno"))
7773         is_no = 1;
7774       else if (unformat (i, "def"))
7775         default_router = 1;
7776       else
7777         {
7778           clib_warning ("parse error '%U'", format_unformat_error, i);
7779           return -99;
7780         }
7781     }
7782
7783   if (sw_if_index_set == 0)
7784     {
7785       errmsg ("missing interface name or sw_if_index");
7786       return -99;
7787     }
7788
7789   /* Construct the API message */
7790   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
7791
7792   mp->sw_if_index = ntohl (sw_if_index);
7793   mp->max_interval = ntohl (max_interval);
7794   mp->min_interval = ntohl (min_interval);
7795   mp->lifetime = ntohl (lifetime);
7796   mp->initial_count = ntohl (initial_count);
7797   mp->initial_interval = ntohl (initial_interval);
7798   mp->suppress = suppress;
7799   mp->managed = managed;
7800   mp->other = other;
7801   mp->ll_option = ll_option;
7802   mp->send_unicast = send_unicast;
7803   mp->cease = cease;
7804   mp->is_no = is_no;
7805   mp->default_router = default_router;
7806
7807   /* send it... */
7808   S;
7809
7810   /* Wait for a reply, return good/bad news  */
7811   W;
7812
7813   /* NOTREACHED */
7814   return 0;
7815 }
7816
7817 static int
7818 api_set_arp_neighbor_limit (vat_main_t * vam)
7819 {
7820   unformat_input_t *i = vam->input;
7821   vl_api_set_arp_neighbor_limit_t *mp;
7822   f64 timeout;
7823   u32 arp_nbr_limit;
7824   u8 limit_set = 0;
7825   u8 is_ipv6 = 0;
7826
7827   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7828     {
7829       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
7830         limit_set = 1;
7831       else if (unformat (i, "ipv6"))
7832         is_ipv6 = 1;
7833       else
7834         {
7835           clib_warning ("parse error '%U'", format_unformat_error, i);
7836           return -99;
7837         }
7838     }
7839
7840   if (limit_set == 0)
7841     {
7842       errmsg ("missing limit value");
7843       return -99;
7844     }
7845
7846   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
7847
7848   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
7849   mp->is_ipv6 = is_ipv6;
7850
7851   S;
7852   W;
7853   /* NOTREACHED */
7854   return 0;
7855 }
7856
7857 static int
7858 api_l2_patch_add_del (vat_main_t * vam)
7859 {
7860   unformat_input_t *i = vam->input;
7861   vl_api_l2_patch_add_del_t *mp;
7862   f64 timeout;
7863   u32 rx_sw_if_index;
7864   u8 rx_sw_if_index_set = 0;
7865   u32 tx_sw_if_index;
7866   u8 tx_sw_if_index_set = 0;
7867   u8 is_add = 1;
7868
7869   /* Parse args required to build the message */
7870   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7871     {
7872       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7873         rx_sw_if_index_set = 1;
7874       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7875         tx_sw_if_index_set = 1;
7876       else if (unformat (i, "rx"))
7877         {
7878           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7879             {
7880               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7881                             &rx_sw_if_index))
7882                 rx_sw_if_index_set = 1;
7883             }
7884           else
7885             break;
7886         }
7887       else if (unformat (i, "tx"))
7888         {
7889           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7890             {
7891               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7892                             &tx_sw_if_index))
7893                 tx_sw_if_index_set = 1;
7894             }
7895           else
7896             break;
7897         }
7898       else if (unformat (i, "del"))
7899         is_add = 0;
7900       else
7901         break;
7902     }
7903
7904   if (rx_sw_if_index_set == 0)
7905     {
7906       errmsg ("missing rx interface name or rx_sw_if_index");
7907       return -99;
7908     }
7909
7910   if (tx_sw_if_index_set == 0)
7911     {
7912       errmsg ("missing tx interface name or tx_sw_if_index");
7913       return -99;
7914     }
7915
7916   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
7917
7918   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7919   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7920   mp->is_add = is_add;
7921
7922   S;
7923   W;
7924   /* NOTREACHED */
7925   return 0;
7926 }
7927
7928 static int
7929 api_ioam_enable (vat_main_t * vam)
7930 {
7931   unformat_input_t *input = vam->input;
7932   vl_api_ioam_enable_t *mp;
7933   f64 timeout;
7934   u32 id = 0;
7935   int has_trace_option = 0;
7936   int has_pot_option = 0;
7937   int has_seqno_option = 0;
7938   int has_analyse_option = 0;
7939
7940   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7941     {
7942       if (unformat (input, "trace"))
7943         has_trace_option = 1;
7944       else if (unformat (input, "pot"))
7945         has_pot_option = 1;
7946       else if (unformat (input, "seqno"))
7947         has_seqno_option = 1;
7948       else if (unformat (input, "analyse"))
7949         has_analyse_option = 1;
7950       else
7951         break;
7952     }
7953   M (IOAM_ENABLE, ioam_enable);
7954   mp->id = htons (id);
7955   mp->seqno = has_seqno_option;
7956   mp->analyse = has_analyse_option;
7957   mp->pot_enable = has_pot_option;
7958   mp->trace_enable = has_trace_option;
7959
7960   S;
7961   W;
7962
7963   return (0);
7964
7965 }
7966
7967
7968 static int
7969 api_ioam_disable (vat_main_t * vam)
7970 {
7971   vl_api_ioam_disable_t *mp;
7972   f64 timeout;
7973
7974   M (IOAM_DISABLE, ioam_disable);
7975   S;
7976   W;
7977   return 0;
7978 }
7979
7980 static int
7981 api_sr_tunnel_add_del (vat_main_t * vam)
7982 {
7983   unformat_input_t *i = vam->input;
7984   vl_api_sr_tunnel_add_del_t *mp;
7985   f64 timeout;
7986   int is_del = 0;
7987   int pl_index;
7988   ip6_address_t src_address;
7989   int src_address_set = 0;
7990   ip6_address_t dst_address;
7991   u32 dst_mask_width;
7992   int dst_address_set = 0;
7993   u16 flags = 0;
7994   u32 rx_table_id = 0;
7995   u32 tx_table_id = 0;
7996   ip6_address_t *segments = 0;
7997   ip6_address_t *this_seg;
7998   ip6_address_t *tags = 0;
7999   ip6_address_t *this_tag;
8000   ip6_address_t next_address, tag;
8001   u8 *name = 0;
8002   u8 *policy_name = 0;
8003
8004   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8005     {
8006       if (unformat (i, "del"))
8007         is_del = 1;
8008       else if (unformat (i, "name %s", &name))
8009         ;
8010       else if (unformat (i, "policy %s", &policy_name))
8011         ;
8012       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
8013         ;
8014       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
8015         ;
8016       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
8017         src_address_set = 1;
8018       else if (unformat (i, "dst %U/%d",
8019                          unformat_ip6_address, &dst_address, &dst_mask_width))
8020         dst_address_set = 1;
8021       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
8022         {
8023           vec_add2 (segments, this_seg, 1);
8024           clib_memcpy (this_seg->as_u8, next_address.as_u8,
8025                        sizeof (*this_seg));
8026         }
8027       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
8028         {
8029           vec_add2 (tags, this_tag, 1);
8030           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
8031         }
8032       else if (unformat (i, "clean"))
8033         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
8034       else if (unformat (i, "protected"))
8035         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
8036       else if (unformat (i, "InPE %d", &pl_index))
8037         {
8038           if (pl_index <= 0 || pl_index > 4)
8039             {
8040             pl_index_range_error:
8041               errmsg ("pl index %d out of range", pl_index);
8042               return -99;
8043             }
8044           flags |=
8045             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
8046         }
8047       else if (unformat (i, "EgPE %d", &pl_index))
8048         {
8049           if (pl_index <= 0 || pl_index > 4)
8050             goto pl_index_range_error;
8051           flags |=
8052             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
8053         }
8054       else if (unformat (i, "OrgSrc %d", &pl_index))
8055         {
8056           if (pl_index <= 0 || pl_index > 4)
8057             goto pl_index_range_error;
8058           flags |=
8059             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
8060         }
8061       else
8062         break;
8063     }
8064
8065   if (!src_address_set)
8066     {
8067       errmsg ("src address required");
8068       return -99;
8069     }
8070
8071   if (!dst_address_set)
8072     {
8073       errmsg ("dst address required");
8074       return -99;
8075     }
8076
8077   if (!segments)
8078     {
8079       errmsg ("at least one sr segment required");
8080       return -99;
8081     }
8082
8083   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
8084       vec_len (segments) * sizeof (ip6_address_t)
8085       + vec_len (tags) * sizeof (ip6_address_t));
8086
8087   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
8088   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
8089   mp->dst_mask_width = dst_mask_width;
8090   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
8091   mp->n_segments = vec_len (segments);
8092   mp->n_tags = vec_len (tags);
8093   mp->is_add = is_del == 0;
8094   clib_memcpy (mp->segs_and_tags, segments,
8095                vec_len (segments) * sizeof (ip6_address_t));
8096   clib_memcpy (mp->segs_and_tags +
8097                vec_len (segments) * sizeof (ip6_address_t), tags,
8098                vec_len (tags) * sizeof (ip6_address_t));
8099
8100   mp->outer_vrf_id = ntohl (rx_table_id);
8101   mp->inner_vrf_id = ntohl (tx_table_id);
8102   memcpy (mp->name, name, vec_len (name));
8103   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8104
8105   vec_free (segments);
8106   vec_free (tags);
8107
8108   S;
8109   W;
8110   /* NOTREACHED */
8111 }
8112
8113 static int
8114 api_sr_policy_add_del (vat_main_t * vam)
8115 {
8116   unformat_input_t *input = vam->input;
8117   vl_api_sr_policy_add_del_t *mp;
8118   f64 timeout;
8119   int is_del = 0;
8120   u8 *name = 0;
8121   u8 *tunnel_name = 0;
8122   u8 **tunnel_names = 0;
8123
8124   int name_set = 0;
8125   int tunnel_set = 0;
8126   int j = 0;
8127   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
8128   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
8129
8130   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8131     {
8132       if (unformat (input, "del"))
8133         is_del = 1;
8134       else if (unformat (input, "name %s", &name))
8135         name_set = 1;
8136       else if (unformat (input, "tunnel %s", &tunnel_name))
8137         {
8138           if (tunnel_name)
8139             {
8140               vec_add1 (tunnel_names, tunnel_name);
8141               /* For serializer:
8142                  - length = #bytes to store in serial vector
8143                  - +1 = byte to store that length
8144                */
8145               tunnel_names_length += (vec_len (tunnel_name) + 1);
8146               tunnel_set = 1;
8147               tunnel_name = 0;
8148             }
8149         }
8150       else
8151         break;
8152     }
8153
8154   if (!name_set)
8155     {
8156       errmsg ("policy name required");
8157       return -99;
8158     }
8159
8160   if ((!tunnel_set) && (!is_del))
8161     {
8162       errmsg ("tunnel name required");
8163       return -99;
8164     }
8165
8166   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
8167
8168
8169
8170   mp->is_add = !is_del;
8171
8172   memcpy (mp->name, name, vec_len (name));
8173   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
8174   u8 *serial_orig = 0;
8175   vec_validate (serial_orig, tunnel_names_length);
8176   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
8177   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
8178
8179   for (j = 0; j < vec_len (tunnel_names); j++)
8180     {
8181       tun_name_len = vec_len (tunnel_names[j]);
8182       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
8183       serial_orig += 1;         // Move along one byte to store the actual tunnel name
8184       memcpy (serial_orig, tunnel_names[j], tun_name_len);
8185       serial_orig += tun_name_len;      // Advance past the copy
8186     }
8187   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
8188
8189   vec_free (tunnel_names);
8190   vec_free (tunnel_name);
8191
8192   S;
8193   W;
8194   /* NOTREACHED */
8195 }
8196
8197 static int
8198 api_sr_multicast_map_add_del (vat_main_t * vam)
8199 {
8200   unformat_input_t *input = vam->input;
8201   vl_api_sr_multicast_map_add_del_t *mp;
8202   f64 timeout;
8203   int is_del = 0;
8204   ip6_address_t multicast_address;
8205   u8 *policy_name = 0;
8206   int multicast_address_set = 0;
8207
8208   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8209     {
8210       if (unformat (input, "del"))
8211         is_del = 1;
8212       else
8213         if (unformat
8214             (input, "address %U", unformat_ip6_address, &multicast_address))
8215         multicast_address_set = 1;
8216       else if (unformat (input, "sr-policy %s", &policy_name))
8217         ;
8218       else
8219         break;
8220     }
8221
8222   if (!is_del && !policy_name)
8223     {
8224       errmsg ("sr-policy name required");
8225       return -99;
8226     }
8227
8228
8229   if (!multicast_address_set)
8230     {
8231       errmsg ("address required");
8232       return -99;
8233     }
8234
8235   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
8236
8237   mp->is_add = !is_del;
8238   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8239   clib_memcpy (mp->multicast_address, &multicast_address,
8240                sizeof (mp->multicast_address));
8241
8242
8243   vec_free (policy_name);
8244
8245   S;
8246   W;
8247   /* NOTREACHED */
8248 }
8249
8250
8251 #define foreach_tcp_proto_field                 \
8252 _(src_port)                                     \
8253 _(dst_port)
8254
8255 #define foreach_udp_proto_field                 \
8256 _(src_port)                                     \
8257 _(dst_port)
8258
8259 #define foreach_ip4_proto_field                 \
8260 _(src_address)                                  \
8261 _(dst_address)                                  \
8262 _(tos)                                          \
8263 _(length)                                       \
8264 _(fragment_id)                                  \
8265 _(ttl)                                          \
8266 _(protocol)                                     \
8267 _(checksum)
8268
8269 uword
8270 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8271 {
8272   u8 **maskp = va_arg (*args, u8 **);
8273   u8 *mask = 0;
8274   u8 found_something = 0;
8275   tcp_header_t *tcp;
8276
8277 #define _(a) u8 a=0;
8278   foreach_tcp_proto_field;
8279 #undef _
8280
8281   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8282     {
8283       if (0);
8284 #define _(a) else if (unformat (input, #a)) a=1;
8285       foreach_tcp_proto_field
8286 #undef _
8287         else
8288         break;
8289     }
8290
8291 #define _(a) found_something += a;
8292   foreach_tcp_proto_field;
8293 #undef _
8294
8295   if (found_something == 0)
8296     return 0;
8297
8298   vec_validate (mask, sizeof (*tcp) - 1);
8299
8300   tcp = (tcp_header_t *) mask;
8301
8302 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8303   foreach_tcp_proto_field;
8304 #undef _
8305
8306   *maskp = mask;
8307   return 1;
8308 }
8309
8310 uword
8311 unformat_udp_mask (unformat_input_t * input, va_list * args)
8312 {
8313   u8 **maskp = va_arg (*args, u8 **);
8314   u8 *mask = 0;
8315   u8 found_something = 0;
8316   udp_header_t *udp;
8317
8318 #define _(a) u8 a=0;
8319   foreach_udp_proto_field;
8320 #undef _
8321
8322   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8323     {
8324       if (0);
8325 #define _(a) else if (unformat (input, #a)) a=1;
8326       foreach_udp_proto_field
8327 #undef _
8328         else
8329         break;
8330     }
8331
8332 #define _(a) found_something += a;
8333   foreach_udp_proto_field;
8334 #undef _
8335
8336   if (found_something == 0)
8337     return 0;
8338
8339   vec_validate (mask, sizeof (*udp) - 1);
8340
8341   udp = (udp_header_t *) mask;
8342
8343 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8344   foreach_udp_proto_field;
8345 #undef _
8346
8347   *maskp = mask;
8348   return 1;
8349 }
8350
8351 typedef struct
8352 {
8353   u16 src_port, dst_port;
8354 } tcpudp_header_t;
8355
8356 uword
8357 unformat_l4_mask (unformat_input_t * input, va_list * args)
8358 {
8359   u8 **maskp = va_arg (*args, u8 **);
8360   u16 src_port = 0, dst_port = 0;
8361   tcpudp_header_t *tcpudp;
8362
8363   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8364     {
8365       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8366         return 1;
8367       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8368         return 1;
8369       else if (unformat (input, "src_port"))
8370         src_port = 0xFFFF;
8371       else if (unformat (input, "dst_port"))
8372         dst_port = 0xFFFF;
8373       else
8374         return 0;
8375     }
8376
8377   if (!src_port && !dst_port)
8378     return 0;
8379
8380   u8 *mask = 0;
8381   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8382
8383   tcpudp = (tcpudp_header_t *) mask;
8384   tcpudp->src_port = src_port;
8385   tcpudp->dst_port = dst_port;
8386
8387   *maskp = mask;
8388
8389   return 1;
8390 }
8391
8392 uword
8393 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8394 {
8395   u8 **maskp = va_arg (*args, u8 **);
8396   u8 *mask = 0;
8397   u8 found_something = 0;
8398   ip4_header_t *ip;
8399
8400 #define _(a) u8 a=0;
8401   foreach_ip4_proto_field;
8402 #undef _
8403   u8 version = 0;
8404   u8 hdr_length = 0;
8405
8406
8407   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8408     {
8409       if (unformat (input, "version"))
8410         version = 1;
8411       else if (unformat (input, "hdr_length"))
8412         hdr_length = 1;
8413       else if (unformat (input, "src"))
8414         src_address = 1;
8415       else if (unformat (input, "dst"))
8416         dst_address = 1;
8417       else if (unformat (input, "proto"))
8418         protocol = 1;
8419
8420 #define _(a) else if (unformat (input, #a)) a=1;
8421       foreach_ip4_proto_field
8422 #undef _
8423         else
8424         break;
8425     }
8426
8427 #define _(a) found_something += a;
8428   foreach_ip4_proto_field;
8429 #undef _
8430
8431   if (found_something == 0)
8432     return 0;
8433
8434   vec_validate (mask, sizeof (*ip) - 1);
8435
8436   ip = (ip4_header_t *) mask;
8437
8438 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8439   foreach_ip4_proto_field;
8440 #undef _
8441
8442   ip->ip_version_and_header_length = 0;
8443
8444   if (version)
8445     ip->ip_version_and_header_length |= 0xF0;
8446
8447   if (hdr_length)
8448     ip->ip_version_and_header_length |= 0x0F;
8449
8450   *maskp = mask;
8451   return 1;
8452 }
8453
8454 #define foreach_ip6_proto_field                 \
8455 _(src_address)                                  \
8456 _(dst_address)                                  \
8457 _(payload_length)                               \
8458 _(hop_limit)                                    \
8459 _(protocol)
8460
8461 uword
8462 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8463 {
8464   u8 **maskp = va_arg (*args, u8 **);
8465   u8 *mask = 0;
8466   u8 found_something = 0;
8467   ip6_header_t *ip;
8468   u32 ip_version_traffic_class_and_flow_label;
8469
8470 #define _(a) u8 a=0;
8471   foreach_ip6_proto_field;
8472 #undef _
8473   u8 version = 0;
8474   u8 traffic_class = 0;
8475   u8 flow_label = 0;
8476
8477   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8478     {
8479       if (unformat (input, "version"))
8480         version = 1;
8481       else if (unformat (input, "traffic-class"))
8482         traffic_class = 1;
8483       else if (unformat (input, "flow-label"))
8484         flow_label = 1;
8485       else if (unformat (input, "src"))
8486         src_address = 1;
8487       else if (unformat (input, "dst"))
8488         dst_address = 1;
8489       else if (unformat (input, "proto"))
8490         protocol = 1;
8491
8492 #define _(a) else if (unformat (input, #a)) a=1;
8493       foreach_ip6_proto_field
8494 #undef _
8495         else
8496         break;
8497     }
8498
8499 #define _(a) found_something += a;
8500   foreach_ip6_proto_field;
8501 #undef _
8502
8503   if (found_something == 0)
8504     return 0;
8505
8506   vec_validate (mask, sizeof (*ip) - 1);
8507
8508   ip = (ip6_header_t *) mask;
8509
8510 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8511   foreach_ip6_proto_field;
8512 #undef _
8513
8514   ip_version_traffic_class_and_flow_label = 0;
8515
8516   if (version)
8517     ip_version_traffic_class_and_flow_label |= 0xF0000000;
8518
8519   if (traffic_class)
8520     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8521
8522   if (flow_label)
8523     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8524
8525   ip->ip_version_traffic_class_and_flow_label =
8526     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8527
8528   *maskp = mask;
8529   return 1;
8530 }
8531
8532 uword
8533 unformat_l3_mask (unformat_input_t * input, va_list * args)
8534 {
8535   u8 **maskp = va_arg (*args, u8 **);
8536
8537   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8538     {
8539       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
8540         return 1;
8541       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
8542         return 1;
8543       else
8544         break;
8545     }
8546   return 0;
8547 }
8548
8549 uword
8550 unformat_l2_mask (unformat_input_t * input, va_list * args)
8551 {
8552   u8 **maskp = va_arg (*args, u8 **);
8553   u8 *mask = 0;
8554   u8 src = 0;
8555   u8 dst = 0;
8556   u8 proto = 0;
8557   u8 tag1 = 0;
8558   u8 tag2 = 0;
8559   u8 ignore_tag1 = 0;
8560   u8 ignore_tag2 = 0;
8561   u8 cos1 = 0;
8562   u8 cos2 = 0;
8563   u8 dot1q = 0;
8564   u8 dot1ad = 0;
8565   int len = 14;
8566
8567   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8568     {
8569       if (unformat (input, "src"))
8570         src = 1;
8571       else if (unformat (input, "dst"))
8572         dst = 1;
8573       else if (unformat (input, "proto"))
8574         proto = 1;
8575       else if (unformat (input, "tag1"))
8576         tag1 = 1;
8577       else if (unformat (input, "tag2"))
8578         tag2 = 1;
8579       else if (unformat (input, "ignore-tag1"))
8580         ignore_tag1 = 1;
8581       else if (unformat (input, "ignore-tag2"))
8582         ignore_tag2 = 1;
8583       else if (unformat (input, "cos1"))
8584         cos1 = 1;
8585       else if (unformat (input, "cos2"))
8586         cos2 = 1;
8587       else if (unformat (input, "dot1q"))
8588         dot1q = 1;
8589       else if (unformat (input, "dot1ad"))
8590         dot1ad = 1;
8591       else
8592         break;
8593     }
8594   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
8595        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8596     return 0;
8597
8598   if (tag1 || ignore_tag1 || cos1 || dot1q)
8599     len = 18;
8600   if (tag2 || ignore_tag2 || cos2 || dot1ad)
8601     len = 22;
8602
8603   vec_validate (mask, len - 1);
8604
8605   if (dst)
8606     memset (mask, 0xff, 6);
8607
8608   if (src)
8609     memset (mask + 6, 0xff, 6);
8610
8611   if (tag2 || dot1ad)
8612     {
8613       /* inner vlan tag */
8614       if (tag2)
8615         {
8616           mask[19] = 0xff;
8617           mask[18] = 0x0f;
8618         }
8619       if (cos2)
8620         mask[18] |= 0xe0;
8621       if (proto)
8622         mask[21] = mask[20] = 0xff;
8623       if (tag1)
8624         {
8625           mask[15] = 0xff;
8626           mask[14] = 0x0f;
8627         }
8628       if (cos1)
8629         mask[14] |= 0xe0;
8630       *maskp = mask;
8631       return 1;
8632     }
8633   if (tag1 | dot1q)
8634     {
8635       if (tag1)
8636         {
8637           mask[15] = 0xff;
8638           mask[14] = 0x0f;
8639         }
8640       if (cos1)
8641         mask[14] |= 0xe0;
8642       if (proto)
8643         mask[16] = mask[17] = 0xff;
8644
8645       *maskp = mask;
8646       return 1;
8647     }
8648   if (cos2)
8649     mask[18] |= 0xe0;
8650   if (cos1)
8651     mask[14] |= 0xe0;
8652   if (proto)
8653     mask[12] = mask[13] = 0xff;
8654
8655   *maskp = mask;
8656   return 1;
8657 }
8658
8659 uword
8660 unformat_classify_mask (unformat_input_t * input, va_list * args)
8661 {
8662   u8 **maskp = va_arg (*args, u8 **);
8663   u32 *skipp = va_arg (*args, u32 *);
8664   u32 *matchp = va_arg (*args, u32 *);
8665   u32 match;
8666   u8 *mask = 0;
8667   u8 *l2 = 0;
8668   u8 *l3 = 0;
8669   u8 *l4 = 0;
8670   int i;
8671
8672   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8673     {
8674       if (unformat (input, "hex %U", unformat_hex_string, &mask))
8675         ;
8676       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
8677         ;
8678       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
8679         ;
8680       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
8681         ;
8682       else
8683         break;
8684     }
8685
8686   if (l4 && !l3)
8687     {
8688       vec_free (mask);
8689       vec_free (l2);
8690       vec_free (l4);
8691       return 0;
8692     }
8693
8694   if (mask || l2 || l3 || l4)
8695     {
8696       if (l2 || l3 || l4)
8697         {
8698           /* "With a free Ethernet header in every package" */
8699           if (l2 == 0)
8700             vec_validate (l2, 13);
8701           mask = l2;
8702           if (vec_len (l3))
8703             {
8704               vec_append (mask, l3);
8705               vec_free (l3);
8706             }
8707           if (vec_len (l4))
8708             {
8709               vec_append (mask, l4);
8710               vec_free (l4);
8711             }
8712         }
8713
8714       /* Scan forward looking for the first significant mask octet */
8715       for (i = 0; i < vec_len (mask); i++)
8716         if (mask[i])
8717           break;
8718
8719       /* compute (skip, match) params */
8720       *skipp = i / sizeof (u32x4);
8721       vec_delete (mask, *skipp * sizeof (u32x4), 0);
8722
8723       /* Pad mask to an even multiple of the vector size */
8724       while (vec_len (mask) % sizeof (u32x4))
8725         vec_add1 (mask, 0);
8726
8727       match = vec_len (mask) / sizeof (u32x4);
8728
8729       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
8730         {
8731           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
8732           if (*tmp || *(tmp + 1))
8733             break;
8734           match--;
8735         }
8736       if (match == 0)
8737         clib_warning ("BUG: match 0");
8738
8739       _vec_len (mask) = match * sizeof (u32x4);
8740
8741       *matchp = match;
8742       *maskp = mask;
8743
8744       return 1;
8745     }
8746
8747   return 0;
8748 }
8749
8750 #define foreach_l2_next                         \
8751 _(drop, DROP)                                   \
8752 _(ethernet, ETHERNET_INPUT)                     \
8753 _(ip4, IP4_INPUT)                               \
8754 _(ip6, IP6_INPUT)
8755
8756 uword
8757 unformat_l2_next_index (unformat_input_t * input, va_list * args)
8758 {
8759   u32 *miss_next_indexp = va_arg (*args, u32 *);
8760   u32 next_index = 0;
8761   u32 tmp;
8762
8763 #define _(n,N) \
8764   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8765   foreach_l2_next;
8766 #undef _
8767
8768   if (unformat (input, "%d", &tmp))
8769     {
8770       next_index = tmp;
8771       goto out;
8772     }
8773
8774   return 0;
8775
8776 out:
8777   *miss_next_indexp = next_index;
8778   return 1;
8779 }
8780
8781 #define foreach_ip_next                         \
8782 _(drop, DROP)                                   \
8783 _(local, LOCAL)                                 \
8784 _(rewrite, REWRITE)
8785
8786 uword
8787 unformat_ip_next_index (unformat_input_t * input, va_list * args)
8788 {
8789   u32 *miss_next_indexp = va_arg (*args, u32 *);
8790   u32 next_index = 0;
8791   u32 tmp;
8792
8793 #define _(n,N) \
8794   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
8795   foreach_ip_next;
8796 #undef _
8797
8798   if (unformat (input, "%d", &tmp))
8799     {
8800       next_index = tmp;
8801       goto out;
8802     }
8803
8804   return 0;
8805
8806 out:
8807   *miss_next_indexp = next_index;
8808   return 1;
8809 }
8810
8811 #define foreach_acl_next                        \
8812 _(deny, DENY)
8813
8814 uword
8815 unformat_acl_next_index (unformat_input_t * input, va_list * args)
8816 {
8817   u32 *miss_next_indexp = va_arg (*args, u32 *);
8818   u32 next_index = 0;
8819   u32 tmp;
8820
8821 #define _(n,N) \
8822   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
8823   foreach_acl_next;
8824 #undef _
8825
8826   if (unformat (input, "permit"))
8827     {
8828       next_index = ~0;
8829       goto out;
8830     }
8831   else if (unformat (input, "%d", &tmp))
8832     {
8833       next_index = tmp;
8834       goto out;
8835     }
8836
8837   return 0;
8838
8839 out:
8840   *miss_next_indexp = next_index;
8841   return 1;
8842 }
8843
8844 uword
8845 unformat_policer_precolor (unformat_input_t * input, va_list * args)
8846 {
8847   u32 *r = va_arg (*args, u32 *);
8848
8849   if (unformat (input, "conform-color"))
8850     *r = POLICE_CONFORM;
8851   else if (unformat (input, "exceed-color"))
8852     *r = POLICE_EXCEED;
8853   else
8854     return 0;
8855
8856   return 1;
8857 }
8858
8859 static int
8860 api_classify_add_del_table (vat_main_t * vam)
8861 {
8862   unformat_input_t *i = vam->input;
8863   vl_api_classify_add_del_table_t *mp;
8864
8865   u32 nbuckets = 2;
8866   u32 skip = ~0;
8867   u32 match = ~0;
8868   int is_add = 1;
8869   int del_chain = 0;
8870   u32 table_index = ~0;
8871   u32 next_table_index = ~0;
8872   u32 miss_next_index = ~0;
8873   u32 memory_size = 32 << 20;
8874   u8 *mask = 0;
8875   f64 timeout;
8876   u32 current_data_flag = 0;
8877   int current_data_offset = 0;
8878
8879   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8880     {
8881       if (unformat (i, "del"))
8882         is_add = 0;
8883       else if (unformat (i, "del-chain"))
8884         {
8885           is_add = 0;
8886           del_chain = 1;
8887         }
8888       else if (unformat (i, "buckets %d", &nbuckets))
8889         ;
8890       else if (unformat (i, "memory_size %d", &memory_size))
8891         ;
8892       else if (unformat (i, "skip %d", &skip))
8893         ;
8894       else if (unformat (i, "match %d", &match))
8895         ;
8896       else if (unformat (i, "table %d", &table_index))
8897         ;
8898       else if (unformat (i, "mask %U", unformat_classify_mask,
8899                          &mask, &skip, &match))
8900         ;
8901       else if (unformat (i, "next-table %d", &next_table_index))
8902         ;
8903       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
8904                          &miss_next_index))
8905         ;
8906       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8907                          &miss_next_index))
8908         ;
8909       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
8910                          &miss_next_index))
8911         ;
8912       else if (unformat (i, "current-data-flag %d", &current_data_flag))
8913         ;
8914       else if (unformat (i, "current-data-offset %d", &current_data_offset))
8915         ;
8916       else
8917         break;
8918     }
8919
8920   if (is_add && mask == 0)
8921     {
8922       errmsg ("Mask required");
8923       return -99;
8924     }
8925
8926   if (is_add && skip == ~0)
8927     {
8928       errmsg ("skip count required");
8929       return -99;
8930     }
8931
8932   if (is_add && match == ~0)
8933     {
8934       errmsg ("match count required");
8935       return -99;
8936     }
8937
8938   if (!is_add && table_index == ~0)
8939     {
8940       errmsg ("table index required for delete");
8941       return -99;
8942     }
8943
8944   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
8945
8946   mp->is_add = is_add;
8947   mp->del_chain = del_chain;
8948   mp->table_index = ntohl (table_index);
8949   mp->nbuckets = ntohl (nbuckets);
8950   mp->memory_size = ntohl (memory_size);
8951   mp->skip_n_vectors = ntohl (skip);
8952   mp->match_n_vectors = ntohl (match);
8953   mp->next_table_index = ntohl (next_table_index);
8954   mp->miss_next_index = ntohl (miss_next_index);
8955   mp->current_data_flag = ntohl (current_data_flag);
8956   mp->current_data_offset = ntohl (current_data_offset);
8957   clib_memcpy (mp->mask, mask, vec_len (mask));
8958
8959   vec_free (mask);
8960
8961   S;
8962   W;
8963   /* NOTREACHED */
8964 }
8965
8966 uword
8967 unformat_l4_match (unformat_input_t * input, va_list * args)
8968 {
8969   u8 **matchp = va_arg (*args, u8 **);
8970
8971   u8 *proto_header = 0;
8972   int src_port = 0;
8973   int dst_port = 0;
8974
8975   tcpudp_header_t h;
8976
8977   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8978     {
8979       if (unformat (input, "src_port %d", &src_port))
8980         ;
8981       else if (unformat (input, "dst_port %d", &dst_port))
8982         ;
8983       else
8984         return 0;
8985     }
8986
8987   h.src_port = clib_host_to_net_u16 (src_port);
8988   h.dst_port = clib_host_to_net_u16 (dst_port);
8989   vec_validate (proto_header, sizeof (h) - 1);
8990   memcpy (proto_header, &h, sizeof (h));
8991
8992   *matchp = proto_header;
8993
8994   return 1;
8995 }
8996
8997 uword
8998 unformat_ip4_match (unformat_input_t * input, va_list * args)
8999 {
9000   u8 **matchp = va_arg (*args, u8 **);
9001   u8 *match = 0;
9002   ip4_header_t *ip;
9003   int version = 0;
9004   u32 version_val;
9005   int hdr_length = 0;
9006   u32 hdr_length_val;
9007   int src = 0, dst = 0;
9008   ip4_address_t src_val, dst_val;
9009   int proto = 0;
9010   u32 proto_val;
9011   int tos = 0;
9012   u32 tos_val;
9013   int length = 0;
9014   u32 length_val;
9015   int fragment_id = 0;
9016   u32 fragment_id_val;
9017   int ttl = 0;
9018   int ttl_val;
9019   int checksum = 0;
9020   u32 checksum_val;
9021
9022   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9023     {
9024       if (unformat (input, "version %d", &version_val))
9025         version = 1;
9026       else if (unformat (input, "hdr_length %d", &hdr_length_val))
9027         hdr_length = 1;
9028       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
9029         src = 1;
9030       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
9031         dst = 1;
9032       else if (unformat (input, "proto %d", &proto_val))
9033         proto = 1;
9034       else if (unformat (input, "tos %d", &tos_val))
9035         tos = 1;
9036       else if (unformat (input, "length %d", &length_val))
9037         length = 1;
9038       else if (unformat (input, "fragment_id %d", &fragment_id_val))
9039         fragment_id = 1;
9040       else if (unformat (input, "ttl %d", &ttl_val))
9041         ttl = 1;
9042       else if (unformat (input, "checksum %d", &checksum_val))
9043         checksum = 1;
9044       else
9045         break;
9046     }
9047
9048   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
9049       + ttl + checksum == 0)
9050     return 0;
9051
9052   /*
9053    * Aligned because we use the real comparison functions
9054    */
9055   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9056
9057   ip = (ip4_header_t *) match;
9058
9059   /* These are realistically matched in practice */
9060   if (src)
9061     ip->src_address.as_u32 = src_val.as_u32;
9062
9063   if (dst)
9064     ip->dst_address.as_u32 = dst_val.as_u32;
9065
9066   if (proto)
9067     ip->protocol = proto_val;
9068
9069
9070   /* These are not, but they're included for completeness */
9071   if (version)
9072     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
9073
9074   if (hdr_length)
9075     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
9076
9077   if (tos)
9078     ip->tos = tos_val;
9079
9080   if (length)
9081     ip->length = clib_host_to_net_u16 (length_val);
9082
9083   if (ttl)
9084     ip->ttl = ttl_val;
9085
9086   if (checksum)
9087     ip->checksum = clib_host_to_net_u16 (checksum_val);
9088
9089   *matchp = match;
9090   return 1;
9091 }
9092
9093 uword
9094 unformat_ip6_match (unformat_input_t * input, va_list * args)
9095 {
9096   u8 **matchp = va_arg (*args, u8 **);
9097   u8 *match = 0;
9098   ip6_header_t *ip;
9099   int version = 0;
9100   u32 version_val;
9101   u8 traffic_class = 0;
9102   u32 traffic_class_val = 0;
9103   u8 flow_label = 0;
9104   u8 flow_label_val;
9105   int src = 0, dst = 0;
9106   ip6_address_t src_val, dst_val;
9107   int proto = 0;
9108   u32 proto_val;
9109   int payload_length = 0;
9110   u32 payload_length_val;
9111   int hop_limit = 0;
9112   int hop_limit_val;
9113   u32 ip_version_traffic_class_and_flow_label;
9114
9115   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9116     {
9117       if (unformat (input, "version %d", &version_val))
9118         version = 1;
9119       else if (unformat (input, "traffic_class %d", &traffic_class_val))
9120         traffic_class = 1;
9121       else if (unformat (input, "flow_label %d", &flow_label_val))
9122         flow_label = 1;
9123       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9124         src = 1;
9125       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9126         dst = 1;
9127       else if (unformat (input, "proto %d", &proto_val))
9128         proto = 1;
9129       else if (unformat (input, "payload_length %d", &payload_length_val))
9130         payload_length = 1;
9131       else if (unformat (input, "hop_limit %d", &hop_limit_val))
9132         hop_limit = 1;
9133       else
9134         break;
9135     }
9136
9137   if (version + traffic_class + flow_label + src + dst + proto +
9138       payload_length + hop_limit == 0)
9139     return 0;
9140
9141   /*
9142    * Aligned because we use the real comparison functions
9143    */
9144   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9145
9146   ip = (ip6_header_t *) match;
9147
9148   if (src)
9149     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9150
9151   if (dst)
9152     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9153
9154   if (proto)
9155     ip->protocol = proto_val;
9156
9157   ip_version_traffic_class_and_flow_label = 0;
9158
9159   if (version)
9160     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9161
9162   if (traffic_class)
9163     ip_version_traffic_class_and_flow_label |=
9164       (traffic_class_val & 0xFF) << 20;
9165
9166   if (flow_label)
9167     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9168
9169   ip->ip_version_traffic_class_and_flow_label =
9170     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9171
9172   if (payload_length)
9173     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9174
9175   if (hop_limit)
9176     ip->hop_limit = hop_limit_val;
9177
9178   *matchp = match;
9179   return 1;
9180 }
9181
9182 uword
9183 unformat_l3_match (unformat_input_t * input, va_list * args)
9184 {
9185   u8 **matchp = va_arg (*args, u8 **);
9186
9187   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9188     {
9189       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9190         return 1;
9191       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9192         return 1;
9193       else
9194         break;
9195     }
9196   return 0;
9197 }
9198
9199 uword
9200 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9201 {
9202   u8 *tagp = va_arg (*args, u8 *);
9203   u32 tag;
9204
9205   if (unformat (input, "%d", &tag))
9206     {
9207       tagp[0] = (tag >> 8) & 0x0F;
9208       tagp[1] = tag & 0xFF;
9209       return 1;
9210     }
9211
9212   return 0;
9213 }
9214
9215 uword
9216 unformat_l2_match (unformat_input_t * input, va_list * args)
9217 {
9218   u8 **matchp = va_arg (*args, u8 **);
9219   u8 *match = 0;
9220   u8 src = 0;
9221   u8 src_val[6];
9222   u8 dst = 0;
9223   u8 dst_val[6];
9224   u8 proto = 0;
9225   u16 proto_val;
9226   u8 tag1 = 0;
9227   u8 tag1_val[2];
9228   u8 tag2 = 0;
9229   u8 tag2_val[2];
9230   int len = 14;
9231   u8 ignore_tag1 = 0;
9232   u8 ignore_tag2 = 0;
9233   u8 cos1 = 0;
9234   u8 cos2 = 0;
9235   u32 cos1_val = 0;
9236   u32 cos2_val = 0;
9237
9238   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9239     {
9240       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9241         src = 1;
9242       else
9243         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9244         dst = 1;
9245       else if (unformat (input, "proto %U",
9246                          unformat_ethernet_type_host_byte_order, &proto_val))
9247         proto = 1;
9248       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9249         tag1 = 1;
9250       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9251         tag2 = 1;
9252       else if (unformat (input, "ignore-tag1"))
9253         ignore_tag1 = 1;
9254       else if (unformat (input, "ignore-tag2"))
9255         ignore_tag2 = 1;
9256       else if (unformat (input, "cos1 %d", &cos1_val))
9257         cos1 = 1;
9258       else if (unformat (input, "cos2 %d", &cos2_val))
9259         cos2 = 1;
9260       else
9261         break;
9262     }
9263   if ((src + dst + proto + tag1 + tag2 +
9264        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9265     return 0;
9266
9267   if (tag1 || ignore_tag1 || cos1)
9268     len = 18;
9269   if (tag2 || ignore_tag2 || cos2)
9270     len = 22;
9271
9272   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9273
9274   if (dst)
9275     clib_memcpy (match, dst_val, 6);
9276
9277   if (src)
9278     clib_memcpy (match + 6, src_val, 6);
9279
9280   if (tag2)
9281     {
9282       /* inner vlan tag */
9283       match[19] = tag2_val[1];
9284       match[18] = tag2_val[0];
9285       if (cos2)
9286         match[18] |= (cos2_val & 0x7) << 5;
9287       if (proto)
9288         {
9289           match[21] = proto_val & 0xff;
9290           match[20] = proto_val >> 8;
9291         }
9292       if (tag1)
9293         {
9294           match[15] = tag1_val[1];
9295           match[14] = tag1_val[0];
9296         }
9297       if (cos1)
9298         match[14] |= (cos1_val & 0x7) << 5;
9299       *matchp = match;
9300       return 1;
9301     }
9302   if (tag1)
9303     {
9304       match[15] = tag1_val[1];
9305       match[14] = tag1_val[0];
9306       if (proto)
9307         {
9308           match[17] = proto_val & 0xff;
9309           match[16] = proto_val >> 8;
9310         }
9311       if (cos1)
9312         match[14] |= (cos1_val & 0x7) << 5;
9313
9314       *matchp = match;
9315       return 1;
9316     }
9317   if (cos2)
9318     match[18] |= (cos2_val & 0x7) << 5;
9319   if (cos1)
9320     match[14] |= (cos1_val & 0x7) << 5;
9321   if (proto)
9322     {
9323       match[13] = proto_val & 0xff;
9324       match[12] = proto_val >> 8;
9325     }
9326
9327   *matchp = match;
9328   return 1;
9329 }
9330
9331
9332 uword
9333 unformat_classify_match (unformat_input_t * input, va_list * args)
9334 {
9335   u8 **matchp = va_arg (*args, u8 **);
9336   u32 skip_n_vectors = va_arg (*args, u32);
9337   u32 match_n_vectors = va_arg (*args, u32);
9338
9339   u8 *match = 0;
9340   u8 *l2 = 0;
9341   u8 *l3 = 0;
9342   u8 *l4 = 0;
9343
9344   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9345     {
9346       if (unformat (input, "hex %U", unformat_hex_string, &match))
9347         ;
9348       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9349         ;
9350       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9351         ;
9352       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9353         ;
9354       else
9355         break;
9356     }
9357
9358   if (l4 && !l3)
9359     {
9360       vec_free (match);
9361       vec_free (l2);
9362       vec_free (l4);
9363       return 0;
9364     }
9365
9366   if (match || l2 || l3 || l4)
9367     {
9368       if (l2 || l3 || l4)
9369         {
9370           /* "Win a free Ethernet header in every packet" */
9371           if (l2 == 0)
9372             vec_validate_aligned (l2, 13, sizeof (u32x4));
9373           match = l2;
9374           if (vec_len (l3))
9375             {
9376               vec_append_aligned (match, l3, sizeof (u32x4));
9377               vec_free (l3);
9378             }
9379           if (vec_len (l4))
9380             {
9381               vec_append_aligned (match, l4, sizeof (u32x4));
9382               vec_free (l4);
9383             }
9384         }
9385
9386       /* Make sure the vector is big enough even if key is all 0's */
9387       vec_validate_aligned
9388         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9389          sizeof (u32x4));
9390
9391       /* Set size, include skipped vectors */
9392       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9393
9394       *matchp = match;
9395
9396       return 1;
9397     }
9398
9399   return 0;
9400 }
9401
9402 static int
9403 api_classify_add_del_session (vat_main_t * vam)
9404 {
9405   unformat_input_t *i = vam->input;
9406   vl_api_classify_add_del_session_t *mp;
9407   int is_add = 1;
9408   u32 table_index = ~0;
9409   u32 hit_next_index = ~0;
9410   u32 opaque_index = ~0;
9411   u8 *match = 0;
9412   i32 advance = 0;
9413   f64 timeout;
9414   u32 skip_n_vectors = 0;
9415   u32 match_n_vectors = 0;
9416   u32 action = 0;
9417   u32 metadata = 0;
9418
9419   /*
9420    * Warning: you have to supply skip_n and match_n
9421    * because the API client cant simply look at the classify
9422    * table object.
9423    */
9424
9425   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9426     {
9427       if (unformat (i, "del"))
9428         is_add = 0;
9429       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
9430                          &hit_next_index))
9431         ;
9432       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9433                          &hit_next_index))
9434         ;
9435       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
9436                          &hit_next_index))
9437         ;
9438       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9439         ;
9440       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9441         ;
9442       else if (unformat (i, "opaque-index %d", &opaque_index))
9443         ;
9444       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9445         ;
9446       else if (unformat (i, "match_n %d", &match_n_vectors))
9447         ;
9448       else if (unformat (i, "match %U", unformat_classify_match,
9449                          &match, skip_n_vectors, match_n_vectors))
9450         ;
9451       else if (unformat (i, "advance %d", &advance))
9452         ;
9453       else if (unformat (i, "table-index %d", &table_index))
9454         ;
9455       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
9456         action = 1;
9457       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
9458         action = 2;
9459       else if (unformat (i, "action %d", &action))
9460         ;
9461       else if (unformat (i, "metadata %d", &metadata))
9462         ;
9463       else
9464         break;
9465     }
9466
9467   if (table_index == ~0)
9468     {
9469       errmsg ("Table index required");
9470       return -99;
9471     }
9472
9473   if (is_add && match == 0)
9474     {
9475       errmsg ("Match value required");
9476       return -99;
9477     }
9478
9479   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
9480
9481   mp->is_add = is_add;
9482   mp->table_index = ntohl (table_index);
9483   mp->hit_next_index = ntohl (hit_next_index);
9484   mp->opaque_index = ntohl (opaque_index);
9485   mp->advance = ntohl (advance);
9486   mp->action = action;
9487   mp->metadata = ntohl (metadata);
9488   clib_memcpy (mp->match, match, vec_len (match));
9489   vec_free (match);
9490
9491   S;
9492   W;
9493   /* NOTREACHED */
9494 }
9495
9496 static int
9497 api_classify_set_interface_ip_table (vat_main_t * vam)
9498 {
9499   unformat_input_t *i = vam->input;
9500   vl_api_classify_set_interface_ip_table_t *mp;
9501   f64 timeout;
9502   u32 sw_if_index;
9503   int sw_if_index_set;
9504   u32 table_index = ~0;
9505   u8 is_ipv6 = 0;
9506
9507   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9508     {
9509       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9510         sw_if_index_set = 1;
9511       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9512         sw_if_index_set = 1;
9513       else if (unformat (i, "table %d", &table_index))
9514         ;
9515       else
9516         {
9517           clib_warning ("parse error '%U'", format_unformat_error, i);
9518           return -99;
9519         }
9520     }
9521
9522   if (sw_if_index_set == 0)
9523     {
9524       errmsg ("missing interface name or sw_if_index");
9525       return -99;
9526     }
9527
9528
9529   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
9530
9531   mp->sw_if_index = ntohl (sw_if_index);
9532   mp->table_index = ntohl (table_index);
9533   mp->is_ipv6 = is_ipv6;
9534
9535   S;
9536   W;
9537   /* NOTREACHED */
9538   return 0;
9539 }
9540
9541 static int
9542 api_classify_set_interface_l2_tables (vat_main_t * vam)
9543 {
9544   unformat_input_t *i = vam->input;
9545   vl_api_classify_set_interface_l2_tables_t *mp;
9546   f64 timeout;
9547   u32 sw_if_index;
9548   int sw_if_index_set;
9549   u32 ip4_table_index = ~0;
9550   u32 ip6_table_index = ~0;
9551   u32 other_table_index = ~0;
9552   u32 is_input = 1;
9553
9554   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9555     {
9556       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9557         sw_if_index_set = 1;
9558       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9559         sw_if_index_set = 1;
9560       else if (unformat (i, "ip4-table %d", &ip4_table_index))
9561         ;
9562       else if (unformat (i, "ip6-table %d", &ip6_table_index))
9563         ;
9564       else if (unformat (i, "other-table %d", &other_table_index))
9565         ;
9566       else if (unformat (i, "is-input %d", &is_input))
9567         ;
9568       else
9569         {
9570           clib_warning ("parse error '%U'", format_unformat_error, i);
9571           return -99;
9572         }
9573     }
9574
9575   if (sw_if_index_set == 0)
9576     {
9577       errmsg ("missing interface name or sw_if_index");
9578       return -99;
9579     }
9580
9581
9582   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
9583
9584   mp->sw_if_index = ntohl (sw_if_index);
9585   mp->ip4_table_index = ntohl (ip4_table_index);
9586   mp->ip6_table_index = ntohl (ip6_table_index);
9587   mp->other_table_index = ntohl (other_table_index);
9588   mp->is_input = (u8) is_input;
9589
9590   S;
9591   W;
9592   /* NOTREACHED */
9593   return 0;
9594 }
9595
9596 static int
9597 api_set_ipfix_exporter (vat_main_t * vam)
9598 {
9599   unformat_input_t *i = vam->input;
9600   vl_api_set_ipfix_exporter_t *mp;
9601   ip4_address_t collector_address;
9602   u8 collector_address_set = 0;
9603   u32 collector_port = ~0;
9604   ip4_address_t src_address;
9605   u8 src_address_set = 0;
9606   u32 vrf_id = ~0;
9607   u32 path_mtu = ~0;
9608   u32 template_interval = ~0;
9609   u8 udp_checksum = 0;
9610   f64 timeout;
9611
9612   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9613     {
9614       if (unformat (i, "collector_address %U", unformat_ip4_address,
9615                     &collector_address))
9616         collector_address_set = 1;
9617       else if (unformat (i, "collector_port %d", &collector_port))
9618         ;
9619       else if (unformat (i, "src_address %U", unformat_ip4_address,
9620                          &src_address))
9621         src_address_set = 1;
9622       else if (unformat (i, "vrf_id %d", &vrf_id))
9623         ;
9624       else if (unformat (i, "path_mtu %d", &path_mtu))
9625         ;
9626       else if (unformat (i, "template_interval %d", &template_interval))
9627         ;
9628       else if (unformat (i, "udp_checksum"))
9629         udp_checksum = 1;
9630       else
9631         break;
9632     }
9633
9634   if (collector_address_set == 0)
9635     {
9636       errmsg ("collector_address required");
9637       return -99;
9638     }
9639
9640   if (src_address_set == 0)
9641     {
9642       errmsg ("src_address required");
9643       return -99;
9644     }
9645
9646   M (SET_IPFIX_EXPORTER, set_ipfix_exporter);
9647
9648   memcpy (mp->collector_address, collector_address.data,
9649           sizeof (collector_address.data));
9650   mp->collector_port = htons ((u16) collector_port);
9651   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
9652   mp->vrf_id = htonl (vrf_id);
9653   mp->path_mtu = htonl (path_mtu);
9654   mp->template_interval = htonl (template_interval);
9655   mp->udp_checksum = udp_checksum;
9656
9657   S;
9658   W;
9659   /* NOTREACHED */
9660 }
9661
9662 static int
9663 api_set_ipfix_classify_stream (vat_main_t * vam)
9664 {
9665   unformat_input_t *i = vam->input;
9666   vl_api_set_ipfix_classify_stream_t *mp;
9667   u32 domain_id = 0;
9668   u32 src_port = UDP_DST_PORT_ipfix;
9669   f64 timeout;
9670
9671   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9672     {
9673       if (unformat (i, "domain %d", &domain_id))
9674         ;
9675       else if (unformat (i, "src_port %d", &src_port))
9676         ;
9677       else
9678         {
9679           errmsg ("unknown input `%U'", format_unformat_error, i);
9680           return -99;
9681         }
9682     }
9683
9684   M (SET_IPFIX_CLASSIFY_STREAM, set_ipfix_classify_stream);
9685
9686   mp->domain_id = htonl (domain_id);
9687   mp->src_port = htons ((u16) src_port);
9688
9689   S;
9690   W;
9691   /* NOTREACHED */
9692 }
9693
9694 static int
9695 api_ipfix_classify_table_add_del (vat_main_t * vam)
9696 {
9697   unformat_input_t *i = vam->input;
9698   vl_api_ipfix_classify_table_add_del_t *mp;
9699   int is_add = -1;
9700   u32 classify_table_index = ~0;
9701   u8 ip_version = 0;
9702   u8 transport_protocol = 255;
9703   f64 timeout;
9704
9705   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9706     {
9707       if (unformat (i, "add"))
9708         is_add = 1;
9709       else if (unformat (i, "del"))
9710         is_add = 0;
9711       else if (unformat (i, "table %d", &classify_table_index))
9712         ;
9713       else if (unformat (i, "ip4"))
9714         ip_version = 4;
9715       else if (unformat (i, "ip6"))
9716         ip_version = 6;
9717       else if (unformat (i, "tcp"))
9718         transport_protocol = 6;
9719       else if (unformat (i, "udp"))
9720         transport_protocol = 17;
9721       else
9722         {
9723           errmsg ("unknown input `%U'", format_unformat_error, i);
9724           return -99;
9725         }
9726     }
9727
9728   if (is_add == -1)
9729     {
9730       errmsg ("expecting: add|del");
9731       return -99;
9732     }
9733   if (classify_table_index == ~0)
9734     {
9735       errmsg ("classifier table not specified");
9736       return -99;
9737     }
9738   if (ip_version == 0)
9739     {
9740       errmsg ("IP version not specified");
9741       return -99;
9742     }
9743
9744   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del);
9745
9746   mp->is_add = is_add;
9747   mp->table_id = htonl (classify_table_index);
9748   mp->ip_version = ip_version;
9749   mp->transport_protocol = transport_protocol;
9750
9751   S;
9752   W;
9753   /* NOTREACHED */
9754 }
9755
9756 static int
9757 api_get_node_index (vat_main_t * vam)
9758 {
9759   unformat_input_t *i = vam->input;
9760   vl_api_get_node_index_t *mp;
9761   f64 timeout;
9762   u8 *name = 0;
9763
9764   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9765     {
9766       if (unformat (i, "node %s", &name))
9767         ;
9768       else
9769         break;
9770     }
9771   if (name == 0)
9772     {
9773       errmsg ("node name required");
9774       return -99;
9775     }
9776   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9777     {
9778       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9779       return -99;
9780     }
9781
9782   M (GET_NODE_INDEX, get_node_index);
9783   clib_memcpy (mp->node_name, name, vec_len (name));
9784   vec_free (name);
9785
9786   S;
9787   W;
9788   /* NOTREACHED */
9789   return 0;
9790 }
9791
9792 static int
9793 api_get_next_index (vat_main_t * vam)
9794 {
9795   unformat_input_t *i = vam->input;
9796   vl_api_get_next_index_t *mp;
9797   f64 timeout;
9798   u8 *node_name = 0, *next_node_name = 0;
9799
9800   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9801     {
9802       if (unformat (i, "node-name %s", &node_name))
9803         ;
9804       else if (unformat (i, "next-node-name %s", &next_node_name))
9805         break;
9806     }
9807
9808   if (node_name == 0)
9809     {
9810       errmsg ("node name required");
9811       return -99;
9812     }
9813   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
9814     {
9815       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9816       return -99;
9817     }
9818
9819   if (next_node_name == 0)
9820     {
9821       errmsg ("next node name required");
9822       return -99;
9823     }
9824   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
9825     {
9826       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
9827       return -99;
9828     }
9829
9830   M (GET_NEXT_INDEX, get_next_index);
9831   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
9832   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
9833   vec_free (node_name);
9834   vec_free (next_node_name);
9835
9836   S;
9837   W;
9838   /* NOTREACHED */
9839   return 0;
9840 }
9841
9842 static int
9843 api_add_node_next (vat_main_t * vam)
9844 {
9845   unformat_input_t *i = vam->input;
9846   vl_api_add_node_next_t *mp;
9847   f64 timeout;
9848   u8 *name = 0;
9849   u8 *next = 0;
9850
9851   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9852     {
9853       if (unformat (i, "node %s", &name))
9854         ;
9855       else if (unformat (i, "next %s", &next))
9856         ;
9857       else
9858         break;
9859     }
9860   if (name == 0)
9861     {
9862       errmsg ("node name required");
9863       return -99;
9864     }
9865   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9866     {
9867       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9868       return -99;
9869     }
9870   if (next == 0)
9871     {
9872       errmsg ("next node required");
9873       return -99;
9874     }
9875   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
9876     {
9877       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
9878       return -99;
9879     }
9880
9881   M (ADD_NODE_NEXT, add_node_next);
9882   clib_memcpy (mp->node_name, name, vec_len (name));
9883   clib_memcpy (mp->next_name, next, vec_len (next));
9884   vec_free (name);
9885   vec_free (next);
9886
9887   S;
9888   W;
9889   /* NOTREACHED */
9890   return 0;
9891 }
9892
9893 static int
9894 api_l2tpv3_create_tunnel (vat_main_t * vam)
9895 {
9896   unformat_input_t *i = vam->input;
9897   ip6_address_t client_address, our_address;
9898   int client_address_set = 0;
9899   int our_address_set = 0;
9900   u32 local_session_id = 0;
9901   u32 remote_session_id = 0;
9902   u64 local_cookie = 0;
9903   u64 remote_cookie = 0;
9904   u8 l2_sublayer_present = 0;
9905   vl_api_l2tpv3_create_tunnel_t *mp;
9906   f64 timeout;
9907
9908   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9909     {
9910       if (unformat (i, "client_address %U", unformat_ip6_address,
9911                     &client_address))
9912         client_address_set = 1;
9913       else if (unformat (i, "our_address %U", unformat_ip6_address,
9914                          &our_address))
9915         our_address_set = 1;
9916       else if (unformat (i, "local_session_id %d", &local_session_id))
9917         ;
9918       else if (unformat (i, "remote_session_id %d", &remote_session_id))
9919         ;
9920       else if (unformat (i, "local_cookie %lld", &local_cookie))
9921         ;
9922       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
9923         ;
9924       else if (unformat (i, "l2-sublayer-present"))
9925         l2_sublayer_present = 1;
9926       else
9927         break;
9928     }
9929
9930   if (client_address_set == 0)
9931     {
9932       errmsg ("client_address required");
9933       return -99;
9934     }
9935
9936   if (our_address_set == 0)
9937     {
9938       errmsg ("our_address required");
9939       return -99;
9940     }
9941
9942   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
9943
9944   clib_memcpy (mp->client_address, client_address.as_u8,
9945                sizeof (mp->client_address));
9946
9947   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
9948
9949   mp->local_session_id = ntohl (local_session_id);
9950   mp->remote_session_id = ntohl (remote_session_id);
9951   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
9952   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
9953   mp->l2_sublayer_present = l2_sublayer_present;
9954   mp->is_ipv6 = 1;
9955
9956   S;
9957   W;
9958   /* NOTREACHED */
9959   return 0;
9960 }
9961
9962 static int
9963 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
9964 {
9965   unformat_input_t *i = vam->input;
9966   u32 sw_if_index;
9967   u8 sw_if_index_set = 0;
9968   u64 new_local_cookie = 0;
9969   u64 new_remote_cookie = 0;
9970   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
9971   f64 timeout;
9972
9973   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9974     {
9975       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9976         sw_if_index_set = 1;
9977       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9978         sw_if_index_set = 1;
9979       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
9980         ;
9981       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
9982         ;
9983       else
9984         break;
9985     }
9986
9987   if (sw_if_index_set == 0)
9988     {
9989       errmsg ("missing interface name or sw_if_index");
9990       return -99;
9991     }
9992
9993   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
9994
9995   mp->sw_if_index = ntohl (sw_if_index);
9996   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
9997   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
9998
9999   S;
10000   W;
10001   /* NOTREACHED */
10002   return 0;
10003 }
10004
10005 static int
10006 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
10007 {
10008   unformat_input_t *i = vam->input;
10009   vl_api_l2tpv3_interface_enable_disable_t *mp;
10010   f64 timeout;
10011   u32 sw_if_index;
10012   u8 sw_if_index_set = 0;
10013   u8 enable_disable = 1;
10014
10015   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10016     {
10017       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10018         sw_if_index_set = 1;
10019       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10020         sw_if_index_set = 1;
10021       else if (unformat (i, "enable"))
10022         enable_disable = 1;
10023       else if (unformat (i, "disable"))
10024         enable_disable = 0;
10025       else
10026         break;
10027     }
10028
10029   if (sw_if_index_set == 0)
10030     {
10031       errmsg ("missing interface name or sw_if_index");
10032       return -99;
10033     }
10034
10035   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
10036
10037   mp->sw_if_index = ntohl (sw_if_index);
10038   mp->enable_disable = enable_disable;
10039
10040   S;
10041   W;
10042   /* NOTREACHED */
10043   return 0;
10044 }
10045
10046 static int
10047 api_l2tpv3_set_lookup_key (vat_main_t * vam)
10048 {
10049   unformat_input_t *i = vam->input;
10050   vl_api_l2tpv3_set_lookup_key_t *mp;
10051   f64 timeout;
10052   u8 key = ~0;
10053
10054   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10055     {
10056       if (unformat (i, "lookup_v6_src"))
10057         key = L2T_LOOKUP_SRC_ADDRESS;
10058       else if (unformat (i, "lookup_v6_dst"))
10059         key = L2T_LOOKUP_DST_ADDRESS;
10060       else if (unformat (i, "lookup_session_id"))
10061         key = L2T_LOOKUP_SESSION_ID;
10062       else
10063         break;
10064     }
10065
10066   if (key == (u8) ~ 0)
10067     {
10068       errmsg ("l2tp session lookup key unset");
10069       return -99;
10070     }
10071
10072   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
10073
10074   mp->key = key;
10075
10076   S;
10077   W;
10078   /* NOTREACHED */
10079   return 0;
10080 }
10081
10082 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
10083   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10084 {
10085   vat_main_t *vam = &vat_main;
10086
10087   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
10088          format_ip6_address, mp->our_address,
10089          format_ip6_address, mp->client_address,
10090          clib_net_to_host_u32 (mp->sw_if_index));
10091
10092   print (vam->ofp,
10093          "   local cookies %016llx %016llx remote cookie %016llx",
10094          clib_net_to_host_u64 (mp->local_cookie[0]),
10095          clib_net_to_host_u64 (mp->local_cookie[1]),
10096          clib_net_to_host_u64 (mp->remote_cookie));
10097
10098   print (vam->ofp, "   local session-id %d remote session-id %d",
10099          clib_net_to_host_u32 (mp->local_session_id),
10100          clib_net_to_host_u32 (mp->remote_session_id));
10101
10102   print (vam->ofp, "   l2 specific sublayer %s\n",
10103          mp->l2_sublayer_present ? "preset" : "absent");
10104
10105 }
10106
10107 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10108   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10109 {
10110   vat_main_t *vam = &vat_main;
10111   vat_json_node_t *node = NULL;
10112   struct in6_addr addr;
10113
10114   if (VAT_JSON_ARRAY != vam->json_tree.type)
10115     {
10116       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10117       vat_json_init_array (&vam->json_tree);
10118     }
10119   node = vat_json_array_add (&vam->json_tree);
10120
10121   vat_json_init_object (node);
10122
10123   clib_memcpy (&addr, mp->our_address, sizeof (addr));
10124   vat_json_object_add_ip6 (node, "our_address", addr);
10125   clib_memcpy (&addr, mp->client_address, sizeof (addr));
10126   vat_json_object_add_ip6 (node, "client_address", addr);
10127
10128   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10129   vat_json_init_array (lc);
10130   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10131   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10132   vat_json_object_add_uint (node, "remote_cookie",
10133                             clib_net_to_host_u64 (mp->remote_cookie));
10134
10135   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10136   vat_json_object_add_uint (node, "local_session_id",
10137                             clib_net_to_host_u32 (mp->local_session_id));
10138   vat_json_object_add_uint (node, "remote_session_id",
10139                             clib_net_to_host_u32 (mp->remote_session_id));
10140   vat_json_object_add_string_copy (node, "l2_sublayer",
10141                                    mp->l2_sublayer_present ? (u8 *) "present"
10142                                    : (u8 *) "absent");
10143 }
10144
10145 static int
10146 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10147 {
10148   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10149   f64 timeout;
10150
10151   /* Get list of l2tpv3-tunnel interfaces */
10152   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
10153   S;
10154
10155   /* Use a control ping for synchronization */
10156   {
10157     vl_api_control_ping_t *mp;
10158     M (CONTROL_PING, control_ping);
10159     S;
10160   }
10161   W;
10162 }
10163
10164
10165 static void vl_api_sw_interface_tap_details_t_handler
10166   (vl_api_sw_interface_tap_details_t * mp)
10167 {
10168   vat_main_t *vam = &vat_main;
10169
10170   print (vam->ofp, "%-16s %d",
10171          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10172 }
10173
10174 static void vl_api_sw_interface_tap_details_t_handler_json
10175   (vl_api_sw_interface_tap_details_t * mp)
10176 {
10177   vat_main_t *vam = &vat_main;
10178   vat_json_node_t *node = NULL;
10179
10180   if (VAT_JSON_ARRAY != vam->json_tree.type)
10181     {
10182       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10183       vat_json_init_array (&vam->json_tree);
10184     }
10185   node = vat_json_array_add (&vam->json_tree);
10186
10187   vat_json_init_object (node);
10188   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10189   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10190 }
10191
10192 static int
10193 api_sw_interface_tap_dump (vat_main_t * vam)
10194 {
10195   vl_api_sw_interface_tap_dump_t *mp;
10196   f64 timeout;
10197
10198   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
10199   /* Get list of tap interfaces */
10200   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
10201   S;
10202
10203   /* Use a control ping for synchronization */
10204   {
10205     vl_api_control_ping_t *mp;
10206     M (CONTROL_PING, control_ping);
10207     S;
10208   }
10209   W;
10210 }
10211
10212 static uword unformat_vxlan_decap_next
10213   (unformat_input_t * input, va_list * args)
10214 {
10215   u32 *result = va_arg (*args, u32 *);
10216   u32 tmp;
10217
10218   if (unformat (input, "l2"))
10219     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10220   else if (unformat (input, "%d", &tmp))
10221     *result = tmp;
10222   else
10223     return 0;
10224   return 1;
10225 }
10226
10227 static int
10228 api_vxlan_add_del_tunnel (vat_main_t * vam)
10229 {
10230   unformat_input_t *line_input = vam->input;
10231   vl_api_vxlan_add_del_tunnel_t *mp;
10232   f64 timeout;
10233   ip46_address_t src, dst;
10234   u8 is_add = 1;
10235   u8 ipv4_set = 0, ipv6_set = 0;
10236   u8 src_set = 0;
10237   u8 dst_set = 0;
10238   u8 grp_set = 0;
10239   u32 mcast_sw_if_index = ~0;
10240   u32 encap_vrf_id = 0;
10241   u32 decap_next_index = ~0;
10242   u32 vni = 0;
10243
10244   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10245   memset (&src, 0, sizeof src);
10246   memset (&dst, 0, sizeof dst);
10247
10248   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10249     {
10250       if (unformat (line_input, "del"))
10251         is_add = 0;
10252       else
10253         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10254         {
10255           ipv4_set = 1;
10256           src_set = 1;
10257         }
10258       else
10259         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10260         {
10261           ipv4_set = 1;
10262           dst_set = 1;
10263         }
10264       else
10265         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10266         {
10267           ipv6_set = 1;
10268           src_set = 1;
10269         }
10270       else
10271         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10272         {
10273           ipv6_set = 1;
10274           dst_set = 1;
10275         }
10276       else if (unformat (line_input, "group %U %U",
10277                          unformat_ip4_address, &dst.ip4,
10278                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10279         {
10280           grp_set = dst_set = 1;
10281           ipv4_set = 1;
10282         }
10283       else if (unformat (line_input, "group %U",
10284                          unformat_ip4_address, &dst.ip4))
10285         {
10286           grp_set = dst_set = 1;
10287           ipv4_set = 1;
10288         }
10289       else if (unformat (line_input, "group %U %U",
10290                          unformat_ip6_address, &dst.ip6,
10291                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10292         {
10293           grp_set = dst_set = 1;
10294           ipv6_set = 1;
10295         }
10296       else if (unformat (line_input, "group %U",
10297                          unformat_ip6_address, &dst.ip6))
10298         {
10299           grp_set = dst_set = 1;
10300           ipv6_set = 1;
10301         }
10302       else
10303         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10304         ;
10305       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10306         ;
10307       else if (unformat (line_input, "decap-next %U",
10308                          unformat_vxlan_decap_next, &decap_next_index))
10309         ;
10310       else if (unformat (line_input, "vni %d", &vni))
10311         ;
10312       else
10313         {
10314           errmsg ("parse error '%U'", format_unformat_error, line_input);
10315           return -99;
10316         }
10317     }
10318
10319   if (src_set == 0)
10320     {
10321       errmsg ("tunnel src address not specified");
10322       return -99;
10323     }
10324   if (dst_set == 0)
10325     {
10326       errmsg ("tunnel dst address not specified");
10327       return -99;
10328     }
10329
10330   if (grp_set && !ip46_address_is_multicast (&dst))
10331     {
10332       errmsg ("tunnel group address not multicast");
10333       return -99;
10334     }
10335   if (grp_set && mcast_sw_if_index == ~0)
10336     {
10337       errmsg ("tunnel nonexistent multicast device");
10338       return -99;
10339     }
10340   if (grp_set == 0 && ip46_address_is_multicast (&dst))
10341     {
10342       errmsg ("tunnel dst address must be unicast");
10343       return -99;
10344     }
10345
10346
10347   if (ipv4_set && ipv6_set)
10348     {
10349       errmsg ("both IPv4 and IPv6 addresses specified");
10350       return -99;
10351     }
10352
10353   if ((vni == 0) || (vni >> 24))
10354     {
10355       errmsg ("vni not specified or out of range");
10356       return -99;
10357     }
10358
10359   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
10360
10361   if (ipv6_set)
10362     {
10363       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
10364       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
10365     }
10366   else
10367     {
10368       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
10369       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
10370     }
10371   mp->encap_vrf_id = ntohl (encap_vrf_id);
10372   mp->decap_next_index = ntohl (decap_next_index);
10373   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10374   mp->vni = ntohl (vni);
10375   mp->is_add = is_add;
10376   mp->is_ipv6 = ipv6_set;
10377
10378   S;
10379   W;
10380   /* NOTREACHED */
10381   return 0;
10382 }
10383
10384 static void vl_api_vxlan_tunnel_details_t_handler
10385   (vl_api_vxlan_tunnel_details_t * mp)
10386 {
10387   vat_main_t *vam = &vat_main;
10388   ip46_address_t src, dst;
10389
10390   ip46_from_addr_buf (mp->is_ipv6, mp->src_address, &src);
10391   ip46_from_addr_buf (mp->is_ipv6, mp->dst_address, &dst);
10392
10393   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
10394          ntohl (mp->sw_if_index),
10395          format_ip46_address, &src, IP46_TYPE_ANY,
10396          format_ip46_address, &dst, IP46_TYPE_ANY,
10397          ntohl (mp->encap_vrf_id),
10398          ntohl (mp->decap_next_index), ntohl (mp->vni),
10399          ntohl (mp->mcast_sw_if_index));
10400 }
10401
10402 static void vl_api_vxlan_tunnel_details_t_handler_json
10403   (vl_api_vxlan_tunnel_details_t * mp)
10404 {
10405   vat_main_t *vam = &vat_main;
10406   vat_json_node_t *node = NULL;
10407
10408   if (VAT_JSON_ARRAY != vam->json_tree.type)
10409     {
10410       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10411       vat_json_init_array (&vam->json_tree);
10412     }
10413   node = vat_json_array_add (&vam->json_tree);
10414
10415   vat_json_init_object (node);
10416   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10417   if (mp->is_ipv6)
10418     {
10419       struct in6_addr ip6;
10420
10421       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
10422       vat_json_object_add_ip6 (node, "src_address", ip6);
10423       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
10424       vat_json_object_add_ip6 (node, "dst_address", ip6);
10425     }
10426   else
10427     {
10428       struct in_addr ip4;
10429
10430       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
10431       vat_json_object_add_ip4 (node, "src_address", ip4);
10432       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
10433       vat_json_object_add_ip4 (node, "dst_address", ip4);
10434     }
10435   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10436   vat_json_object_add_uint (node, "decap_next_index",
10437                             ntohl (mp->decap_next_index));
10438   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10439   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10440   vat_json_object_add_uint (node, "mcast_sw_if_index",
10441                             ntohl (mp->mcast_sw_if_index));
10442 }
10443
10444 static int
10445 api_vxlan_tunnel_dump (vat_main_t * vam)
10446 {
10447   unformat_input_t *i = vam->input;
10448   vl_api_vxlan_tunnel_dump_t *mp;
10449   f64 timeout;
10450   u32 sw_if_index;
10451   u8 sw_if_index_set = 0;
10452
10453   /* Parse args required to build the message */
10454   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10455     {
10456       if (unformat (i, "sw_if_index %d", &sw_if_index))
10457         sw_if_index_set = 1;
10458       else
10459         break;
10460     }
10461
10462   if (sw_if_index_set == 0)
10463     {
10464       sw_if_index = ~0;
10465     }
10466
10467   if (!vam->json_output)
10468     {
10469       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
10470              "sw_if_index", "src_address", "dst_address",
10471              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
10472     }
10473
10474   /* Get list of vxlan-tunnel interfaces */
10475   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
10476
10477   mp->sw_if_index = htonl (sw_if_index);
10478
10479   S;
10480
10481   /* Use a control ping for synchronization */
10482   {
10483     vl_api_control_ping_t *mp;
10484     M (CONTROL_PING, control_ping);
10485     S;
10486   }
10487   W;
10488 }
10489
10490 static int
10491 api_gre_add_del_tunnel (vat_main_t * vam)
10492 {
10493   unformat_input_t *line_input = vam->input;
10494   vl_api_gre_add_del_tunnel_t *mp;
10495   f64 timeout;
10496   ip4_address_t src4, dst4;
10497   u8 is_add = 1;
10498   u8 teb = 0;
10499   u8 src_set = 0;
10500   u8 dst_set = 0;
10501   u32 outer_fib_id = 0;
10502
10503   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10504     {
10505       if (unformat (line_input, "del"))
10506         is_add = 0;
10507       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10508         src_set = 1;
10509       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10510         dst_set = 1;
10511       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10512         ;
10513       else if (unformat (line_input, "teb"))
10514         teb = 1;
10515       else
10516         {
10517           errmsg ("parse error '%U'", format_unformat_error, line_input);
10518           return -99;
10519         }
10520     }
10521
10522   if (src_set == 0)
10523     {
10524       errmsg ("tunnel src address not specified");
10525       return -99;
10526     }
10527   if (dst_set == 0)
10528     {
10529       errmsg ("tunnel dst address not specified");
10530       return -99;
10531     }
10532
10533
10534   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
10535
10536   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10537   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10538   mp->outer_fib_id = ntohl (outer_fib_id);
10539   mp->is_add = is_add;
10540   mp->teb = teb;
10541
10542   S;
10543   W;
10544   /* NOTREACHED */
10545   return 0;
10546 }
10547
10548 static void vl_api_gre_tunnel_details_t_handler
10549   (vl_api_gre_tunnel_details_t * mp)
10550 {
10551   vat_main_t *vam = &vat_main;
10552
10553   print (vam->ofp, "%11d%15U%15U%6d%14d",
10554          ntohl (mp->sw_if_index),
10555          format_ip4_address, &mp->src_address,
10556          format_ip4_address, &mp->dst_address,
10557          mp->teb, ntohl (mp->outer_fib_id));
10558 }
10559
10560 static void vl_api_gre_tunnel_details_t_handler_json
10561   (vl_api_gre_tunnel_details_t * mp)
10562 {
10563   vat_main_t *vam = &vat_main;
10564   vat_json_node_t *node = NULL;
10565   struct in_addr ip4;
10566
10567   if (VAT_JSON_ARRAY != vam->json_tree.type)
10568     {
10569       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10570       vat_json_init_array (&vam->json_tree);
10571     }
10572   node = vat_json_array_add (&vam->json_tree);
10573
10574   vat_json_init_object (node);
10575   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10576   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
10577   vat_json_object_add_ip4 (node, "src_address", ip4);
10578   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
10579   vat_json_object_add_ip4 (node, "dst_address", ip4);
10580   vat_json_object_add_uint (node, "teb", mp->teb);
10581   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
10582 }
10583
10584 static int
10585 api_gre_tunnel_dump (vat_main_t * vam)
10586 {
10587   unformat_input_t *i = vam->input;
10588   vl_api_gre_tunnel_dump_t *mp;
10589   f64 timeout;
10590   u32 sw_if_index;
10591   u8 sw_if_index_set = 0;
10592
10593   /* Parse args required to build the message */
10594   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10595     {
10596       if (unformat (i, "sw_if_index %d", &sw_if_index))
10597         sw_if_index_set = 1;
10598       else
10599         break;
10600     }
10601
10602   if (sw_if_index_set == 0)
10603     {
10604       sw_if_index = ~0;
10605     }
10606
10607   if (!vam->json_output)
10608     {
10609       print (vam->ofp, "%11s%15s%15s%6s%14s",
10610              "sw_if_index", "src_address", "dst_address", "teb",
10611              "outer_fib_id");
10612     }
10613
10614   /* Get list of gre-tunnel interfaces */
10615   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
10616
10617   mp->sw_if_index = htonl (sw_if_index);
10618
10619   S;
10620
10621   /* Use a control ping for synchronization */
10622   {
10623     vl_api_control_ping_t *mp;
10624     M (CONTROL_PING, control_ping);
10625     S;
10626   }
10627   W;
10628 }
10629
10630 static int
10631 api_l2_fib_clear_table (vat_main_t * vam)
10632 {
10633 //  unformat_input_t * i = vam->input;
10634   vl_api_l2_fib_clear_table_t *mp;
10635   f64 timeout;
10636
10637   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
10638
10639   S;
10640   W;
10641   /* NOTREACHED */
10642   return 0;
10643 }
10644
10645 static int
10646 api_l2_interface_efp_filter (vat_main_t * vam)
10647 {
10648   unformat_input_t *i = vam->input;
10649   vl_api_l2_interface_efp_filter_t *mp;
10650   f64 timeout;
10651   u32 sw_if_index;
10652   u8 enable = 1;
10653   u8 sw_if_index_set = 0;
10654
10655   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10656     {
10657       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10658         sw_if_index_set = 1;
10659       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10660         sw_if_index_set = 1;
10661       else if (unformat (i, "enable"))
10662         enable = 1;
10663       else if (unformat (i, "disable"))
10664         enable = 0;
10665       else
10666         {
10667           clib_warning ("parse error '%U'", format_unformat_error, i);
10668           return -99;
10669         }
10670     }
10671
10672   if (sw_if_index_set == 0)
10673     {
10674       errmsg ("missing sw_if_index");
10675       return -99;
10676     }
10677
10678   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
10679
10680   mp->sw_if_index = ntohl (sw_if_index);
10681   mp->enable_disable = enable;
10682
10683   S;
10684   W;
10685   /* NOTREACHED */
10686   return 0;
10687 }
10688
10689 #define foreach_vtr_op                          \
10690 _("disable",  L2_VTR_DISABLED)                  \
10691 _("push-1",  L2_VTR_PUSH_1)                     \
10692 _("push-2",  L2_VTR_PUSH_2)                     \
10693 _("pop-1",  L2_VTR_POP_1)                       \
10694 _("pop-2",  L2_VTR_POP_2)                       \
10695 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
10696 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
10697 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
10698 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
10699
10700 static int
10701 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
10702 {
10703   unformat_input_t *i = vam->input;
10704   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
10705   f64 timeout;
10706   u32 sw_if_index;
10707   u8 sw_if_index_set = 0;
10708   u8 vtr_op_set = 0;
10709   u32 vtr_op = 0;
10710   u32 push_dot1q = 1;
10711   u32 tag1 = ~0;
10712   u32 tag2 = ~0;
10713
10714   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10715     {
10716       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10717         sw_if_index_set = 1;
10718       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10719         sw_if_index_set = 1;
10720       else if (unformat (i, "vtr_op %d", &vtr_op))
10721         vtr_op_set = 1;
10722 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
10723       foreach_vtr_op
10724 #undef _
10725         else if (unformat (i, "push_dot1q %d", &push_dot1q))
10726         ;
10727       else if (unformat (i, "tag1 %d", &tag1))
10728         ;
10729       else if (unformat (i, "tag2 %d", &tag2))
10730         ;
10731       else
10732         {
10733           clib_warning ("parse error '%U'", format_unformat_error, i);
10734           return -99;
10735         }
10736     }
10737
10738   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
10739     {
10740       errmsg ("missing vtr operation or sw_if_index");
10741       return -99;
10742     }
10743
10744   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
10745     mp->sw_if_index = ntohl (sw_if_index);
10746   mp->vtr_op = ntohl (vtr_op);
10747   mp->push_dot1q = ntohl (push_dot1q);
10748   mp->tag1 = ntohl (tag1);
10749   mp->tag2 = ntohl (tag2);
10750
10751   S;
10752   W;
10753   /* NOTREACHED */
10754   return 0;
10755 }
10756
10757 static int
10758 api_create_vhost_user_if (vat_main_t * vam)
10759 {
10760   unformat_input_t *i = vam->input;
10761   vl_api_create_vhost_user_if_t *mp;
10762   f64 timeout;
10763   u8 *file_name;
10764   u8 is_server = 0;
10765   u8 file_name_set = 0;
10766   u32 custom_dev_instance = ~0;
10767   u8 hwaddr[6];
10768   u8 use_custom_mac = 0;
10769   u8 *tag = 0;
10770
10771   /* Shut up coverity */
10772   memset (hwaddr, 0, sizeof (hwaddr));
10773
10774   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10775     {
10776       if (unformat (i, "socket %s", &file_name))
10777         {
10778           file_name_set = 1;
10779         }
10780       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10781         ;
10782       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
10783         use_custom_mac = 1;
10784       else if (unformat (i, "server"))
10785         is_server = 1;
10786       else if (unformat (i, "tag %s", &tag))
10787         ;
10788       else
10789         break;
10790     }
10791
10792   if (file_name_set == 0)
10793     {
10794       errmsg ("missing socket file name");
10795       return -99;
10796     }
10797
10798   if (vec_len (file_name) > 255)
10799     {
10800       errmsg ("socket file name too long");
10801       return -99;
10802     }
10803   vec_add1 (file_name, 0);
10804
10805   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
10806
10807   mp->is_server = is_server;
10808   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10809   vec_free (file_name);
10810   if (custom_dev_instance != ~0)
10811     {
10812       mp->renumber = 1;
10813       mp->custom_dev_instance = ntohl (custom_dev_instance);
10814     }
10815   mp->use_custom_mac = use_custom_mac;
10816   clib_memcpy (mp->mac_address, hwaddr, 6);
10817   if (tag)
10818     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
10819   vec_free (tag);
10820
10821   S;
10822   W;
10823   /* NOTREACHED */
10824   return 0;
10825 }
10826
10827 static int
10828 api_modify_vhost_user_if (vat_main_t * vam)
10829 {
10830   unformat_input_t *i = vam->input;
10831   vl_api_modify_vhost_user_if_t *mp;
10832   f64 timeout;
10833   u8 *file_name;
10834   u8 is_server = 0;
10835   u8 file_name_set = 0;
10836   u32 custom_dev_instance = ~0;
10837   u8 sw_if_index_set = 0;
10838   u32 sw_if_index = (u32) ~ 0;
10839
10840   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10841     {
10842       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10843         sw_if_index_set = 1;
10844       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10845         sw_if_index_set = 1;
10846       else if (unformat (i, "socket %s", &file_name))
10847         {
10848           file_name_set = 1;
10849         }
10850       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10851         ;
10852       else if (unformat (i, "server"))
10853         is_server = 1;
10854       else
10855         break;
10856     }
10857
10858   if (sw_if_index_set == 0)
10859     {
10860       errmsg ("missing sw_if_index or interface name");
10861       return -99;
10862     }
10863
10864   if (file_name_set == 0)
10865     {
10866       errmsg ("missing socket file name");
10867       return -99;
10868     }
10869
10870   if (vec_len (file_name) > 255)
10871     {
10872       errmsg ("socket file name too long");
10873       return -99;
10874     }
10875   vec_add1 (file_name, 0);
10876
10877   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
10878
10879   mp->sw_if_index = ntohl (sw_if_index);
10880   mp->is_server = is_server;
10881   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10882   vec_free (file_name);
10883   if (custom_dev_instance != ~0)
10884     {
10885       mp->renumber = 1;
10886       mp->custom_dev_instance = ntohl (custom_dev_instance);
10887     }
10888
10889   S;
10890   W;
10891   /* NOTREACHED */
10892   return 0;
10893 }
10894
10895 static int
10896 api_delete_vhost_user_if (vat_main_t * vam)
10897 {
10898   unformat_input_t *i = vam->input;
10899   vl_api_delete_vhost_user_if_t *mp;
10900   f64 timeout;
10901   u32 sw_if_index = ~0;
10902   u8 sw_if_index_set = 0;
10903
10904   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10905     {
10906       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10907         sw_if_index_set = 1;
10908       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10909         sw_if_index_set = 1;
10910       else
10911         break;
10912     }
10913
10914   if (sw_if_index_set == 0)
10915     {
10916       errmsg ("missing sw_if_index or interface name");
10917       return -99;
10918     }
10919
10920
10921   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
10922
10923   mp->sw_if_index = ntohl (sw_if_index);
10924
10925   S;
10926   W;
10927   /* NOTREACHED */
10928   return 0;
10929 }
10930
10931 static void vl_api_sw_interface_vhost_user_details_t_handler
10932   (vl_api_sw_interface_vhost_user_details_t * mp)
10933 {
10934   vat_main_t *vam = &vat_main;
10935
10936   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
10937          (char *) mp->interface_name,
10938          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
10939          clib_net_to_host_u64 (mp->features), mp->is_server,
10940          ntohl (mp->num_regions), (char *) mp->sock_filename);
10941   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
10942 }
10943
10944 static void vl_api_sw_interface_vhost_user_details_t_handler_json
10945   (vl_api_sw_interface_vhost_user_details_t * mp)
10946 {
10947   vat_main_t *vam = &vat_main;
10948   vat_json_node_t *node = NULL;
10949
10950   if (VAT_JSON_ARRAY != vam->json_tree.type)
10951     {
10952       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10953       vat_json_init_array (&vam->json_tree);
10954     }
10955   node = vat_json_array_add (&vam->json_tree);
10956
10957   vat_json_init_object (node);
10958   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10959   vat_json_object_add_string_copy (node, "interface_name",
10960                                    mp->interface_name);
10961   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
10962                             ntohl (mp->virtio_net_hdr_sz));
10963   vat_json_object_add_uint (node, "features",
10964                             clib_net_to_host_u64 (mp->features));
10965   vat_json_object_add_uint (node, "is_server", mp->is_server);
10966   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
10967   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
10968   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
10969 }
10970
10971 static int
10972 api_sw_interface_vhost_user_dump (vat_main_t * vam)
10973 {
10974   vl_api_sw_interface_vhost_user_dump_t *mp;
10975   f64 timeout;
10976   print (vam->ofp,
10977          "Interface name           idx hdr_sz features server regions filename");
10978
10979   /* Get list of vhost-user interfaces */
10980   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
10981   S;
10982
10983   /* Use a control ping for synchronization */
10984   {
10985     vl_api_control_ping_t *mp;
10986     M (CONTROL_PING, control_ping);
10987     S;
10988   }
10989   W;
10990 }
10991
10992 static int
10993 api_show_version (vat_main_t * vam)
10994 {
10995   vl_api_show_version_t *mp;
10996   f64 timeout;
10997
10998   M (SHOW_VERSION, show_version);
10999
11000   S;
11001   W;
11002   /* NOTREACHED */
11003   return 0;
11004 }
11005
11006
11007 static int
11008 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
11009 {
11010   unformat_input_t *line_input = vam->input;
11011   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
11012   f64 timeout;
11013   ip4_address_t local4, remote4;
11014   ip6_address_t local6, remote6;
11015   u8 is_add = 1;
11016   u8 ipv4_set = 0, ipv6_set = 0;
11017   u8 local_set = 0;
11018   u8 remote_set = 0;
11019   u32 encap_vrf_id = 0;
11020   u32 decap_vrf_id = 0;
11021   u8 protocol = ~0;
11022   u32 vni;
11023   u8 vni_set = 0;
11024
11025   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11026     {
11027       if (unformat (line_input, "del"))
11028         is_add = 0;
11029       else if (unformat (line_input, "local %U",
11030                          unformat_ip4_address, &local4))
11031         {
11032           local_set = 1;
11033           ipv4_set = 1;
11034         }
11035       else if (unformat (line_input, "remote %U",
11036                          unformat_ip4_address, &remote4))
11037         {
11038           remote_set = 1;
11039           ipv4_set = 1;
11040         }
11041       else if (unformat (line_input, "local %U",
11042                          unformat_ip6_address, &local6))
11043         {
11044           local_set = 1;
11045           ipv6_set = 1;
11046         }
11047       else if (unformat (line_input, "remote %U",
11048                          unformat_ip6_address, &remote6))
11049         {
11050           remote_set = 1;
11051           ipv6_set = 1;
11052         }
11053       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11054         ;
11055       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
11056         ;
11057       else if (unformat (line_input, "vni %d", &vni))
11058         vni_set = 1;
11059       else if (unformat (line_input, "next-ip4"))
11060         protocol = 1;
11061       else if (unformat (line_input, "next-ip6"))
11062         protocol = 2;
11063       else if (unformat (line_input, "next-ethernet"))
11064         protocol = 3;
11065       else if (unformat (line_input, "next-nsh"))
11066         protocol = 4;
11067       else
11068         {
11069           errmsg ("parse error '%U'", format_unformat_error, line_input);
11070           return -99;
11071         }
11072     }
11073
11074   if (local_set == 0)
11075     {
11076       errmsg ("tunnel local address not specified");
11077       return -99;
11078     }
11079   if (remote_set == 0)
11080     {
11081       errmsg ("tunnel remote address not specified");
11082       return -99;
11083     }
11084   if (ipv4_set && ipv6_set)
11085     {
11086       errmsg ("both IPv4 and IPv6 addresses specified");
11087       return -99;
11088     }
11089
11090   if (vni_set == 0)
11091     {
11092       errmsg ("vni not specified");
11093       return -99;
11094     }
11095
11096   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
11097
11098
11099   if (ipv6_set)
11100     {
11101       clib_memcpy (&mp->local, &local6, sizeof (local6));
11102       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
11103     }
11104   else
11105     {
11106       clib_memcpy (&mp->local, &local4, sizeof (local4));
11107       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11108     }
11109
11110   mp->encap_vrf_id = ntohl (encap_vrf_id);
11111   mp->decap_vrf_id = ntohl (decap_vrf_id);
11112   mp->protocol = protocol;
11113   mp->vni = ntohl (vni);
11114   mp->is_add = is_add;
11115   mp->is_ipv6 = ipv6_set;
11116
11117   S;
11118   W;
11119   /* NOTREACHED */
11120   return 0;
11121 }
11122
11123 static void vl_api_vxlan_gpe_tunnel_details_t_handler
11124   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11125 {
11126   vat_main_t *vam = &vat_main;
11127
11128   print (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d",
11129          ntohl (mp->sw_if_index),
11130          format_ip46_address, &(mp->local[0]),
11131          format_ip46_address, &(mp->remote[0]),
11132          ntohl (mp->vni),
11133          ntohl (mp->protocol),
11134          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11135 }
11136
11137 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11138   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11139 {
11140   vat_main_t *vam = &vat_main;
11141   vat_json_node_t *node = NULL;
11142   struct in_addr ip4;
11143   struct in6_addr ip6;
11144
11145   if (VAT_JSON_ARRAY != vam->json_tree.type)
11146     {
11147       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11148       vat_json_init_array (&vam->json_tree);
11149     }
11150   node = vat_json_array_add (&vam->json_tree);
11151
11152   vat_json_init_object (node);
11153   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11154   if (mp->is_ipv6)
11155     {
11156       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11157       vat_json_object_add_ip6 (node, "local", ip6);
11158       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11159       vat_json_object_add_ip6 (node, "remote", ip6);
11160     }
11161   else
11162     {
11163       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11164       vat_json_object_add_ip4 (node, "local", ip4);
11165       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11166       vat_json_object_add_ip4 (node, "remote", ip4);
11167     }
11168   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11169   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11170   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11171   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11172   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11173 }
11174
11175 static int
11176 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11177 {
11178   unformat_input_t *i = vam->input;
11179   vl_api_vxlan_gpe_tunnel_dump_t *mp;
11180   f64 timeout;
11181   u32 sw_if_index;
11182   u8 sw_if_index_set = 0;
11183
11184   /* Parse args required to build the message */
11185   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11186     {
11187       if (unformat (i, "sw_if_index %d", &sw_if_index))
11188         sw_if_index_set = 1;
11189       else
11190         break;
11191     }
11192
11193   if (sw_if_index_set == 0)
11194     {
11195       sw_if_index = ~0;
11196     }
11197
11198   if (!vam->json_output)
11199     {
11200       print (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s",
11201              "sw_if_index", "local", "remote", "vni",
11202              "protocol", "encap_vrf_id", "decap_vrf_id");
11203     }
11204
11205   /* Get list of vxlan-tunnel interfaces */
11206   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
11207
11208   mp->sw_if_index = htonl (sw_if_index);
11209
11210   S;
11211
11212   /* Use a control ping for synchronization */
11213   {
11214     vl_api_control_ping_t *mp;
11215     M (CONTROL_PING, control_ping);
11216     S;
11217   }
11218   W;
11219 }
11220
11221 u8 *
11222 format_l2_fib_mac_address (u8 * s, va_list * args)
11223 {
11224   u8 *a = va_arg (*args, u8 *);
11225
11226   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11227                  a[2], a[3], a[4], a[5], a[6], a[7]);
11228 }
11229
11230 static void vl_api_l2_fib_table_entry_t_handler
11231   (vl_api_l2_fib_table_entry_t * mp)
11232 {
11233   vat_main_t *vam = &vat_main;
11234
11235   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11236          "       %d       %d     %d",
11237          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11238          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11239          mp->bvi_mac);
11240 }
11241
11242 static void vl_api_l2_fib_table_entry_t_handler_json
11243   (vl_api_l2_fib_table_entry_t * mp)
11244 {
11245   vat_main_t *vam = &vat_main;
11246   vat_json_node_t *node = NULL;
11247
11248   if (VAT_JSON_ARRAY != vam->json_tree.type)
11249     {
11250       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11251       vat_json_init_array (&vam->json_tree);
11252     }
11253   node = vat_json_array_add (&vam->json_tree);
11254
11255   vat_json_init_object (node);
11256   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11257   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11258   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11259   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11260   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11261   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11262 }
11263
11264 static int
11265 api_l2_fib_table_dump (vat_main_t * vam)
11266 {
11267   unformat_input_t *i = vam->input;
11268   vl_api_l2_fib_table_dump_t *mp;
11269   f64 timeout;
11270   u32 bd_id;
11271   u8 bd_id_set = 0;
11272
11273   /* Parse args required to build the message */
11274   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11275     {
11276       if (unformat (i, "bd_id %d", &bd_id))
11277         bd_id_set = 1;
11278       else
11279         break;
11280     }
11281
11282   if (bd_id_set == 0)
11283     {
11284       errmsg ("missing bridge domain");
11285       return -99;
11286     }
11287
11288   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
11289
11290   /* Get list of l2 fib entries */
11291   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
11292
11293   mp->bd_id = ntohl (bd_id);
11294   S;
11295
11296   /* Use a control ping for synchronization */
11297   {
11298     vl_api_control_ping_t *mp;
11299     M (CONTROL_PING, control_ping);
11300     S;
11301   }
11302   W;
11303 }
11304
11305
11306 static int
11307 api_interface_name_renumber (vat_main_t * vam)
11308 {
11309   unformat_input_t *line_input = vam->input;
11310   vl_api_interface_name_renumber_t *mp;
11311   u32 sw_if_index = ~0;
11312   f64 timeout;
11313   u32 new_show_dev_instance = ~0;
11314
11315   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11316     {
11317       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
11318                     &sw_if_index))
11319         ;
11320       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11321         ;
11322       else if (unformat (line_input, "new_show_dev_instance %d",
11323                          &new_show_dev_instance))
11324         ;
11325       else
11326         break;
11327     }
11328
11329   if (sw_if_index == ~0)
11330     {
11331       errmsg ("missing interface name or sw_if_index");
11332       return -99;
11333     }
11334
11335   if (new_show_dev_instance == ~0)
11336     {
11337       errmsg ("missing new_show_dev_instance");
11338       return -99;
11339     }
11340
11341   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
11342
11343   mp->sw_if_index = ntohl (sw_if_index);
11344   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11345
11346   S;
11347   W;
11348 }
11349
11350 static int
11351 api_want_ip4_arp_events (vat_main_t * vam)
11352 {
11353   unformat_input_t *line_input = vam->input;
11354   vl_api_want_ip4_arp_events_t *mp;
11355   f64 timeout;
11356   ip4_address_t address;
11357   int address_set = 0;
11358   u32 enable_disable = 1;
11359
11360   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11361     {
11362       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11363         address_set = 1;
11364       else if (unformat (line_input, "del"))
11365         enable_disable = 0;
11366       else
11367         break;
11368     }
11369
11370   if (address_set == 0)
11371     {
11372       errmsg ("missing addresses");
11373       return -99;
11374     }
11375
11376   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
11377   mp->enable_disable = enable_disable;
11378   mp->pid = getpid ();
11379   mp->address = address.as_u32;
11380
11381   S;
11382   W;
11383 }
11384
11385 static int
11386 api_want_ip6_nd_events (vat_main_t * vam)
11387 {
11388   unformat_input_t *line_input = vam->input;
11389   vl_api_want_ip6_nd_events_t *mp;
11390   f64 timeout;
11391   ip6_address_t address;
11392   int address_set = 0;
11393   u32 enable_disable = 1;
11394
11395   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11396     {
11397       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11398         address_set = 1;
11399       else if (unformat (line_input, "del"))
11400         enable_disable = 0;
11401       else
11402         break;
11403     }
11404
11405   if (address_set == 0)
11406     {
11407       errmsg ("missing addresses");
11408       return -99;
11409     }
11410
11411   M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
11412   mp->enable_disable = enable_disable;
11413   mp->pid = getpid ();
11414   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11415
11416   S;
11417   W;
11418 }
11419
11420 static int
11421 api_input_acl_set_interface (vat_main_t * vam)
11422 {
11423   unformat_input_t *i = vam->input;
11424   vl_api_input_acl_set_interface_t *mp;
11425   f64 timeout;
11426   u32 sw_if_index;
11427   int sw_if_index_set;
11428   u32 ip4_table_index = ~0;
11429   u32 ip6_table_index = ~0;
11430   u32 l2_table_index = ~0;
11431   u8 is_add = 1;
11432
11433   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11434     {
11435       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11436         sw_if_index_set = 1;
11437       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11438         sw_if_index_set = 1;
11439       else if (unformat (i, "del"))
11440         is_add = 0;
11441       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11442         ;
11443       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11444         ;
11445       else if (unformat (i, "l2-table %d", &l2_table_index))
11446         ;
11447       else
11448         {
11449           clib_warning ("parse error '%U'", format_unformat_error, i);
11450           return -99;
11451         }
11452     }
11453
11454   if (sw_if_index_set == 0)
11455     {
11456       errmsg ("missing interface name or sw_if_index");
11457       return -99;
11458     }
11459
11460   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
11461
11462   mp->sw_if_index = ntohl (sw_if_index);
11463   mp->ip4_table_index = ntohl (ip4_table_index);
11464   mp->ip6_table_index = ntohl (ip6_table_index);
11465   mp->l2_table_index = ntohl (l2_table_index);
11466   mp->is_add = is_add;
11467
11468   S;
11469   W;
11470   /* NOTREACHED */
11471   return 0;
11472 }
11473
11474 static int
11475 api_ip_address_dump (vat_main_t * vam)
11476 {
11477   unformat_input_t *i = vam->input;
11478   vl_api_ip_address_dump_t *mp;
11479   u32 sw_if_index = ~0;
11480   u8 sw_if_index_set = 0;
11481   u8 ipv4_set = 0;
11482   u8 ipv6_set = 0;
11483   f64 timeout;
11484
11485   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11486     {
11487       if (unformat (i, "sw_if_index %d", &sw_if_index))
11488         sw_if_index_set = 1;
11489       else
11490         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11491         sw_if_index_set = 1;
11492       else if (unformat (i, "ipv4"))
11493         ipv4_set = 1;
11494       else if (unformat (i, "ipv6"))
11495         ipv6_set = 1;
11496       else
11497         break;
11498     }
11499
11500   if (ipv4_set && ipv6_set)
11501     {
11502       errmsg ("ipv4 and ipv6 flags cannot be both set");
11503       return -99;
11504     }
11505
11506   if ((!ipv4_set) && (!ipv6_set))
11507     {
11508       errmsg ("no ipv4 nor ipv6 flag set");
11509       return -99;
11510     }
11511
11512   if (sw_if_index_set == 0)
11513     {
11514       errmsg ("missing interface name or sw_if_index");
11515       return -99;
11516     }
11517
11518   vam->current_sw_if_index = sw_if_index;
11519   vam->is_ipv6 = ipv6_set;
11520
11521   M (IP_ADDRESS_DUMP, ip_address_dump);
11522   mp->sw_if_index = ntohl (sw_if_index);
11523   mp->is_ipv6 = ipv6_set;
11524   S;
11525
11526   /* Use a control ping for synchronization */
11527   {
11528     vl_api_control_ping_t *mp;
11529     M (CONTROL_PING, control_ping);
11530     S;
11531   }
11532   W;
11533 }
11534
11535 static int
11536 api_ip_dump (vat_main_t * vam)
11537 {
11538   vl_api_ip_dump_t *mp;
11539   unformat_input_t *in = vam->input;
11540   int ipv4_set = 0;
11541   int ipv6_set = 0;
11542   int is_ipv6;
11543   f64 timeout;
11544   int i;
11545
11546   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
11547     {
11548       if (unformat (in, "ipv4"))
11549         ipv4_set = 1;
11550       else if (unformat (in, "ipv6"))
11551         ipv6_set = 1;
11552       else
11553         break;
11554     }
11555
11556   if (ipv4_set && ipv6_set)
11557     {
11558       errmsg ("ipv4 and ipv6 flags cannot be both set");
11559       return -99;
11560     }
11561
11562   if ((!ipv4_set) && (!ipv6_set))
11563     {
11564       errmsg ("no ipv4 nor ipv6 flag set");
11565       return -99;
11566     }
11567
11568   is_ipv6 = ipv6_set;
11569   vam->is_ipv6 = is_ipv6;
11570
11571   /* free old data */
11572   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
11573     {
11574       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
11575     }
11576   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
11577
11578   M (IP_DUMP, ip_dump);
11579   mp->is_ipv6 = ipv6_set;
11580   S;
11581
11582   /* Use a control ping for synchronization */
11583   {
11584     vl_api_control_ping_t *mp;
11585     M (CONTROL_PING, control_ping);
11586     S;
11587   }
11588   W;
11589 }
11590
11591 static int
11592 api_ipsec_spd_add_del (vat_main_t * vam)
11593 {
11594   unformat_input_t *i = vam->input;
11595   vl_api_ipsec_spd_add_del_t *mp;
11596   f64 timeout;
11597   u32 spd_id = ~0;
11598   u8 is_add = 1;
11599
11600   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11601     {
11602       if (unformat (i, "spd_id %d", &spd_id))
11603         ;
11604       else if (unformat (i, "del"))
11605         is_add = 0;
11606       else
11607         {
11608           clib_warning ("parse error '%U'", format_unformat_error, i);
11609           return -99;
11610         }
11611     }
11612   if (spd_id == ~0)
11613     {
11614       errmsg ("spd_id must be set");
11615       return -99;
11616     }
11617
11618   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
11619
11620   mp->spd_id = ntohl (spd_id);
11621   mp->is_add = is_add;
11622
11623   S;
11624   W;
11625   /* NOTREACHED */
11626   return 0;
11627 }
11628
11629 static int
11630 api_ipsec_interface_add_del_spd (vat_main_t * vam)
11631 {
11632   unformat_input_t *i = vam->input;
11633   vl_api_ipsec_interface_add_del_spd_t *mp;
11634   f64 timeout;
11635   u32 sw_if_index;
11636   u8 sw_if_index_set = 0;
11637   u32 spd_id = (u32) ~ 0;
11638   u8 is_add = 1;
11639
11640   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11641     {
11642       if (unformat (i, "del"))
11643         is_add = 0;
11644       else if (unformat (i, "spd_id %d", &spd_id))
11645         ;
11646       else
11647         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11648         sw_if_index_set = 1;
11649       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11650         sw_if_index_set = 1;
11651       else
11652         {
11653           clib_warning ("parse error '%U'", format_unformat_error, i);
11654           return -99;
11655         }
11656
11657     }
11658
11659   if (spd_id == (u32) ~ 0)
11660     {
11661       errmsg ("spd_id must be set");
11662       return -99;
11663     }
11664
11665   if (sw_if_index_set == 0)
11666     {
11667       errmsg ("missing interface name or sw_if_index");
11668       return -99;
11669     }
11670
11671   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
11672
11673   mp->spd_id = ntohl (spd_id);
11674   mp->sw_if_index = ntohl (sw_if_index);
11675   mp->is_add = is_add;
11676
11677   S;
11678   W;
11679   /* NOTREACHED */
11680   return 0;
11681 }
11682
11683 static int
11684 api_ipsec_spd_add_del_entry (vat_main_t * vam)
11685 {
11686   unformat_input_t *i = vam->input;
11687   vl_api_ipsec_spd_add_del_entry_t *mp;
11688   f64 timeout;
11689   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
11690   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
11691   i32 priority = 0;
11692   u32 rport_start = 0, rport_stop = (u32) ~ 0;
11693   u32 lport_start = 0, lport_stop = (u32) ~ 0;
11694   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
11695   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
11696
11697   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
11698   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
11699   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
11700   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
11701   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
11702   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
11703
11704   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11705     {
11706       if (unformat (i, "del"))
11707         is_add = 0;
11708       if (unformat (i, "outbound"))
11709         is_outbound = 1;
11710       if (unformat (i, "inbound"))
11711         is_outbound = 0;
11712       else if (unformat (i, "spd_id %d", &spd_id))
11713         ;
11714       else if (unformat (i, "sa_id %d", &sa_id))
11715         ;
11716       else if (unformat (i, "priority %d", &priority))
11717         ;
11718       else if (unformat (i, "protocol %d", &protocol))
11719         ;
11720       else if (unformat (i, "lport_start %d", &lport_start))
11721         ;
11722       else if (unformat (i, "lport_stop %d", &lport_stop))
11723         ;
11724       else if (unformat (i, "rport_start %d", &rport_start))
11725         ;
11726       else if (unformat (i, "rport_stop %d", &rport_stop))
11727         ;
11728       else
11729         if (unformat
11730             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
11731         {
11732           is_ipv6 = 0;
11733           is_ip_any = 0;
11734         }
11735       else
11736         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
11737         {
11738           is_ipv6 = 0;
11739           is_ip_any = 0;
11740         }
11741       else
11742         if (unformat
11743             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
11744         {
11745           is_ipv6 = 0;
11746           is_ip_any = 0;
11747         }
11748       else
11749         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
11750         {
11751           is_ipv6 = 0;
11752           is_ip_any = 0;
11753         }
11754       else
11755         if (unformat
11756             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
11757         {
11758           is_ipv6 = 1;
11759           is_ip_any = 0;
11760         }
11761       else
11762         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
11763         {
11764           is_ipv6 = 1;
11765           is_ip_any = 0;
11766         }
11767       else
11768         if (unformat
11769             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
11770         {
11771           is_ipv6 = 1;
11772           is_ip_any = 0;
11773         }
11774       else
11775         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
11776         {
11777           is_ipv6 = 1;
11778           is_ip_any = 0;
11779         }
11780       else
11781         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
11782         {
11783           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
11784             {
11785               clib_warning ("unsupported action: 'resolve'");
11786               return -99;
11787             }
11788         }
11789       else
11790         {
11791           clib_warning ("parse error '%U'", format_unformat_error, i);
11792           return -99;
11793         }
11794
11795     }
11796
11797   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
11798
11799   mp->spd_id = ntohl (spd_id);
11800   mp->priority = ntohl (priority);
11801   mp->is_outbound = is_outbound;
11802
11803   mp->is_ipv6 = is_ipv6;
11804   if (is_ipv6 || is_ip_any)
11805     {
11806       clib_memcpy (mp->remote_address_start, &raddr6_start,
11807                    sizeof (ip6_address_t));
11808       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
11809                    sizeof (ip6_address_t));
11810       clib_memcpy (mp->local_address_start, &laddr6_start,
11811                    sizeof (ip6_address_t));
11812       clib_memcpy (mp->local_address_stop, &laddr6_stop,
11813                    sizeof (ip6_address_t));
11814     }
11815   else
11816     {
11817       clib_memcpy (mp->remote_address_start, &raddr4_start,
11818                    sizeof (ip4_address_t));
11819       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
11820                    sizeof (ip4_address_t));
11821       clib_memcpy (mp->local_address_start, &laddr4_start,
11822                    sizeof (ip4_address_t));
11823       clib_memcpy (mp->local_address_stop, &laddr4_stop,
11824                    sizeof (ip4_address_t));
11825     }
11826   mp->protocol = (u8) protocol;
11827   mp->local_port_start = ntohs ((u16) lport_start);
11828   mp->local_port_stop = ntohs ((u16) lport_stop);
11829   mp->remote_port_start = ntohs ((u16) rport_start);
11830   mp->remote_port_stop = ntohs ((u16) rport_stop);
11831   mp->policy = (u8) policy;
11832   mp->sa_id = ntohl (sa_id);
11833   mp->is_add = is_add;
11834   mp->is_ip_any = is_ip_any;
11835   S;
11836   W;
11837   /* NOTREACHED */
11838   return 0;
11839 }
11840
11841 static int
11842 api_ipsec_sad_add_del_entry (vat_main_t * vam)
11843 {
11844   unformat_input_t *i = vam->input;
11845   vl_api_ipsec_sad_add_del_entry_t *mp;
11846   f64 timeout;
11847   u32 sad_id = 0, spi = 0;
11848   u8 *ck = 0, *ik = 0;
11849   u8 is_add = 1;
11850
11851   u8 protocol = IPSEC_PROTOCOL_AH;
11852   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
11853   u32 crypto_alg = 0, integ_alg = 0;
11854   ip4_address_t tun_src4;
11855   ip4_address_t tun_dst4;
11856   ip6_address_t tun_src6;
11857   ip6_address_t tun_dst6;
11858
11859   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11860     {
11861       if (unformat (i, "del"))
11862         is_add = 0;
11863       else if (unformat (i, "sad_id %d", &sad_id))
11864         ;
11865       else if (unformat (i, "spi %d", &spi))
11866         ;
11867       else if (unformat (i, "esp"))
11868         protocol = IPSEC_PROTOCOL_ESP;
11869       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
11870         {
11871           is_tunnel = 1;
11872           is_tunnel_ipv6 = 0;
11873         }
11874       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
11875         {
11876           is_tunnel = 1;
11877           is_tunnel_ipv6 = 0;
11878         }
11879       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
11880         {
11881           is_tunnel = 1;
11882           is_tunnel_ipv6 = 1;
11883         }
11884       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
11885         {
11886           is_tunnel = 1;
11887           is_tunnel_ipv6 = 1;
11888         }
11889       else
11890         if (unformat
11891             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
11892         {
11893           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
11894               crypto_alg >= IPSEC_CRYPTO_N_ALG)
11895             {
11896               clib_warning ("unsupported crypto-alg: '%U'",
11897                             format_ipsec_crypto_alg, crypto_alg);
11898               return -99;
11899             }
11900         }
11901       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11902         ;
11903       else
11904         if (unformat
11905             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
11906         {
11907 #if DPDK_CRYPTO==1
11908           if (integ_alg < IPSEC_INTEG_ALG_NONE ||
11909 #else
11910           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
11911 #endif
11912               integ_alg >= IPSEC_INTEG_N_ALG)
11913             {
11914               clib_warning ("unsupported integ-alg: '%U'",
11915                             format_ipsec_integ_alg, integ_alg);
11916               return -99;
11917             }
11918         }
11919       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11920         ;
11921       else
11922         {
11923           clib_warning ("parse error '%U'", format_unformat_error, i);
11924           return -99;
11925         }
11926
11927     }
11928
11929 #if DPDK_CRYPTO==1
11930   /*Special cases, aes-gcm-128 encryption */
11931   if (crypto_alg == IPSEC_CRYPTO_ALG_AES_GCM_128)
11932     {
11933       if (integ_alg != IPSEC_INTEG_ALG_NONE
11934           && integ_alg != IPSEC_INTEG_ALG_AES_GCM_128)
11935         {
11936           clib_warning
11937             ("unsupported: aes-gcm-128 crypto-alg needs none as integ-alg");
11938           return -99;
11939         }
11940       else                      /*set integ-alg internally to aes-gcm-128 */
11941         integ_alg = IPSEC_INTEG_ALG_AES_GCM_128;
11942     }
11943   else if (integ_alg == IPSEC_INTEG_ALG_AES_GCM_128)
11944     {
11945       clib_warning ("unsupported integ-alg: aes-gcm-128");
11946       return -99;
11947     }
11948   else if (integ_alg == IPSEC_INTEG_ALG_NONE)
11949     {
11950       clib_warning ("unsupported integ-alg: none");
11951       return -99;
11952     }
11953 #endif
11954
11955
11956   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
11957
11958   mp->sad_id = ntohl (sad_id);
11959   mp->is_add = is_add;
11960   mp->protocol = protocol;
11961   mp->spi = ntohl (spi);
11962   mp->is_tunnel = is_tunnel;
11963   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
11964   mp->crypto_algorithm = crypto_alg;
11965   mp->integrity_algorithm = integ_alg;
11966   mp->crypto_key_length = vec_len (ck);
11967   mp->integrity_key_length = vec_len (ik);
11968
11969   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11970     mp->crypto_key_length = sizeof (mp->crypto_key);
11971
11972   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11973     mp->integrity_key_length = sizeof (mp->integrity_key);
11974
11975   if (ck)
11976     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11977   if (ik)
11978     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11979
11980   if (is_tunnel)
11981     {
11982       if (is_tunnel_ipv6)
11983         {
11984           clib_memcpy (mp->tunnel_src_address, &tun_src6,
11985                        sizeof (ip6_address_t));
11986           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
11987                        sizeof (ip6_address_t));
11988         }
11989       else
11990         {
11991           clib_memcpy (mp->tunnel_src_address, &tun_src4,
11992                        sizeof (ip4_address_t));
11993           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
11994                        sizeof (ip4_address_t));
11995         }
11996     }
11997
11998   S;
11999   W;
12000   /* NOTREACHED */
12001   return 0;
12002 }
12003
12004 static int
12005 api_ipsec_sa_set_key (vat_main_t * vam)
12006 {
12007   unformat_input_t *i = vam->input;
12008   vl_api_ipsec_sa_set_key_t *mp;
12009   f64 timeout;
12010   u32 sa_id;
12011   u8 *ck = 0, *ik = 0;
12012
12013   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12014     {
12015       if (unformat (i, "sa_id %d", &sa_id))
12016         ;
12017       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12018         ;
12019       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12020         ;
12021       else
12022         {
12023           clib_warning ("parse error '%U'", format_unformat_error, i);
12024           return -99;
12025         }
12026     }
12027
12028   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
12029
12030   mp->sa_id = ntohl (sa_id);
12031   mp->crypto_key_length = vec_len (ck);
12032   mp->integrity_key_length = vec_len (ik);
12033
12034   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12035     mp->crypto_key_length = sizeof (mp->crypto_key);
12036
12037   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12038     mp->integrity_key_length = sizeof (mp->integrity_key);
12039
12040   if (ck)
12041     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12042   if (ik)
12043     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12044
12045   S;
12046   W;
12047   /* NOTREACHED */
12048   return 0;
12049 }
12050
12051 static int
12052 api_ikev2_profile_add_del (vat_main_t * vam)
12053 {
12054   unformat_input_t *i = vam->input;
12055   vl_api_ikev2_profile_add_del_t *mp;
12056   f64 timeout;
12057   u8 is_add = 1;
12058   u8 *name = 0;
12059
12060   const char *valid_chars = "a-zA-Z0-9_";
12061
12062   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12063     {
12064       if (unformat (i, "del"))
12065         is_add = 0;
12066       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12067         vec_add1 (name, 0);
12068       else
12069         {
12070           errmsg ("parse error '%U'", format_unformat_error, i);
12071           return -99;
12072         }
12073     }
12074
12075   if (!vec_len (name))
12076     {
12077       errmsg ("profile name must be specified");
12078       return -99;
12079     }
12080
12081   if (vec_len (name) > 64)
12082     {
12083       errmsg ("profile name too long");
12084       return -99;
12085     }
12086
12087   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
12088
12089   clib_memcpy (mp->name, name, vec_len (name));
12090   mp->is_add = is_add;
12091   vec_free (name);
12092
12093   S;
12094   W;
12095   /* NOTREACHED */
12096   return 0;
12097 }
12098
12099 static int
12100 api_ikev2_profile_set_auth (vat_main_t * vam)
12101 {
12102   unformat_input_t *i = vam->input;
12103   vl_api_ikev2_profile_set_auth_t *mp;
12104   f64 timeout;
12105   u8 *name = 0;
12106   u8 *data = 0;
12107   u32 auth_method = 0;
12108   u8 is_hex = 0;
12109
12110   const char *valid_chars = "a-zA-Z0-9_";
12111
12112   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12113     {
12114       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12115         vec_add1 (name, 0);
12116       else if (unformat (i, "auth_method %U",
12117                          unformat_ikev2_auth_method, &auth_method))
12118         ;
12119       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
12120         is_hex = 1;
12121       else if (unformat (i, "auth_data %v", &data))
12122         ;
12123       else
12124         {
12125           errmsg ("parse error '%U'", format_unformat_error, i);
12126           return -99;
12127         }
12128     }
12129
12130   if (!vec_len (name))
12131     {
12132       errmsg ("profile name must be specified");
12133       return -99;
12134     }
12135
12136   if (vec_len (name) > 64)
12137     {
12138       errmsg ("profile name too long");
12139       return -99;
12140     }
12141
12142   if (!vec_len (data))
12143     {
12144       errmsg ("auth_data must be specified");
12145       return -99;
12146     }
12147
12148   if (!auth_method)
12149     {
12150       errmsg ("auth_method must be specified");
12151       return -99;
12152     }
12153
12154   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
12155
12156   mp->is_hex = is_hex;
12157   mp->auth_method = (u8) auth_method;
12158   mp->data_len = vec_len (data);
12159   clib_memcpy (mp->name, name, vec_len (name));
12160   clib_memcpy (mp->data, data, vec_len (data));
12161   vec_free (name);
12162   vec_free (data);
12163
12164   S;
12165   W;
12166   /* NOTREACHED */
12167   return 0;
12168 }
12169
12170 static int
12171 api_ikev2_profile_set_id (vat_main_t * vam)
12172 {
12173   unformat_input_t *i = vam->input;
12174   vl_api_ikev2_profile_set_id_t *mp;
12175   f64 timeout;
12176   u8 *name = 0;
12177   u8 *data = 0;
12178   u8 is_local = 0;
12179   u32 id_type = 0;
12180   ip4_address_t ip4;
12181
12182   const char *valid_chars = "a-zA-Z0-9_";
12183
12184   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12185     {
12186       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12187         vec_add1 (name, 0);
12188       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12189         ;
12190       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12191         {
12192           data = vec_new (u8, 4);
12193           clib_memcpy (data, ip4.as_u8, 4);
12194         }
12195       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12196         ;
12197       else if (unformat (i, "id_data %v", &data))
12198         ;
12199       else if (unformat (i, "local"))
12200         is_local = 1;
12201       else if (unformat (i, "remote"))
12202         is_local = 0;
12203       else
12204         {
12205           errmsg ("parse error '%U'", format_unformat_error, i);
12206           return -99;
12207         }
12208     }
12209
12210   if (!vec_len (name))
12211     {
12212       errmsg ("profile name must be specified");
12213       return -99;
12214     }
12215
12216   if (vec_len (name) > 64)
12217     {
12218       errmsg ("profile name too long");
12219       return -99;
12220     }
12221
12222   if (!vec_len (data))
12223     {
12224       errmsg ("id_data must be specified");
12225       return -99;
12226     }
12227
12228   if (!id_type)
12229     {
12230       errmsg ("id_type must be specified");
12231       return -99;
12232     }
12233
12234   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
12235
12236   mp->is_local = is_local;
12237   mp->id_type = (u8) id_type;
12238   mp->data_len = vec_len (data);
12239   clib_memcpy (mp->name, name, vec_len (name));
12240   clib_memcpy (mp->data, data, vec_len (data));
12241   vec_free (name);
12242   vec_free (data);
12243
12244   S;
12245   W;
12246   /* NOTREACHED */
12247   return 0;
12248 }
12249
12250 static int
12251 api_ikev2_profile_set_ts (vat_main_t * vam)
12252 {
12253   unformat_input_t *i = vam->input;
12254   vl_api_ikev2_profile_set_ts_t *mp;
12255   f64 timeout;
12256   u8 *name = 0;
12257   u8 is_local = 0;
12258   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12259   ip4_address_t start_addr, end_addr;
12260
12261   const char *valid_chars = "a-zA-Z0-9_";
12262
12263   start_addr.as_u32 = 0;
12264   end_addr.as_u32 = (u32) ~ 0;
12265
12266   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12267     {
12268       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12269         vec_add1 (name, 0);
12270       else if (unformat (i, "protocol %d", &proto))
12271         ;
12272       else if (unformat (i, "start_port %d", &start_port))
12273         ;
12274       else if (unformat (i, "end_port %d", &end_port))
12275         ;
12276       else
12277         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12278         ;
12279       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12280         ;
12281       else if (unformat (i, "local"))
12282         is_local = 1;
12283       else if (unformat (i, "remote"))
12284         is_local = 0;
12285       else
12286         {
12287           errmsg ("parse error '%U'", format_unformat_error, i);
12288           return -99;
12289         }
12290     }
12291
12292   if (!vec_len (name))
12293     {
12294       errmsg ("profile name must be specified");
12295       return -99;
12296     }
12297
12298   if (vec_len (name) > 64)
12299     {
12300       errmsg ("profile name too long");
12301       return -99;
12302     }
12303
12304   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
12305
12306   mp->is_local = is_local;
12307   mp->proto = (u8) proto;
12308   mp->start_port = (u16) start_port;
12309   mp->end_port = (u16) end_port;
12310   mp->start_addr = start_addr.as_u32;
12311   mp->end_addr = end_addr.as_u32;
12312   clib_memcpy (mp->name, name, vec_len (name));
12313   vec_free (name);
12314
12315   S;
12316   W;
12317   /* NOTREACHED */
12318   return 0;
12319 }
12320
12321 static int
12322 api_ikev2_set_local_key (vat_main_t * vam)
12323 {
12324   unformat_input_t *i = vam->input;
12325   vl_api_ikev2_set_local_key_t *mp;
12326   f64 timeout;
12327   u8 *file = 0;
12328
12329   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12330     {
12331       if (unformat (i, "file %v", &file))
12332         vec_add1 (file, 0);
12333       else
12334         {
12335           errmsg ("parse error '%U'", format_unformat_error, i);
12336           return -99;
12337         }
12338     }
12339
12340   if (!vec_len (file))
12341     {
12342       errmsg ("RSA key file must be specified");
12343       return -99;
12344     }
12345
12346   if (vec_len (file) > 256)
12347     {
12348       errmsg ("file name too long");
12349       return -99;
12350     }
12351
12352   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
12353
12354   clib_memcpy (mp->key_file, file, vec_len (file));
12355   vec_free (file);
12356
12357   S;
12358   W;
12359   /* NOTREACHED */
12360   return 0;
12361 }
12362
12363 /*
12364  * MAP
12365  */
12366 static int
12367 api_map_add_domain (vat_main_t * vam)
12368 {
12369   unformat_input_t *i = vam->input;
12370   vl_api_map_add_domain_t *mp;
12371   f64 timeout;
12372
12373   ip4_address_t ip4_prefix;
12374   ip6_address_t ip6_prefix;
12375   ip6_address_t ip6_src;
12376   u32 num_m_args = 0;
12377   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
12378     0, psid_length = 0;
12379   u8 is_translation = 0;
12380   u32 mtu = 0;
12381   u32 ip6_src_len = 128;
12382
12383   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12384     {
12385       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
12386                     &ip4_prefix, &ip4_prefix_len))
12387         num_m_args++;
12388       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
12389                          &ip6_prefix, &ip6_prefix_len))
12390         num_m_args++;
12391       else
12392         if (unformat
12393             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
12394              &ip6_src_len))
12395         num_m_args++;
12396       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
12397         num_m_args++;
12398       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
12399         num_m_args++;
12400       else if (unformat (i, "psid-offset %d", &psid_offset))
12401         num_m_args++;
12402       else if (unformat (i, "psid-len %d", &psid_length))
12403         num_m_args++;
12404       else if (unformat (i, "mtu %d", &mtu))
12405         num_m_args++;
12406       else if (unformat (i, "map-t"))
12407         is_translation = 1;
12408       else
12409         {
12410           clib_warning ("parse error '%U'", format_unformat_error, i);
12411           return -99;
12412         }
12413     }
12414
12415   if (num_m_args < 3)
12416     {
12417       errmsg ("mandatory argument(s) missing");
12418       return -99;
12419     }
12420
12421   /* Construct the API message */
12422   M (MAP_ADD_DOMAIN, map_add_domain);
12423
12424   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
12425   mp->ip4_prefix_len = ip4_prefix_len;
12426
12427   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
12428   mp->ip6_prefix_len = ip6_prefix_len;
12429
12430   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
12431   mp->ip6_src_prefix_len = ip6_src_len;
12432
12433   mp->ea_bits_len = ea_bits_len;
12434   mp->psid_offset = psid_offset;
12435   mp->psid_length = psid_length;
12436   mp->is_translation = is_translation;
12437   mp->mtu = htons (mtu);
12438
12439   /* send it... */
12440   S;
12441
12442   /* Wait for a reply, return good/bad news  */
12443   W;
12444 }
12445
12446 static int
12447 api_map_del_domain (vat_main_t * vam)
12448 {
12449   unformat_input_t *i = vam->input;
12450   vl_api_map_del_domain_t *mp;
12451   f64 timeout;
12452
12453   u32 num_m_args = 0;
12454   u32 index;
12455
12456   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12457     {
12458       if (unformat (i, "index %d", &index))
12459         num_m_args++;
12460       else
12461         {
12462           clib_warning ("parse error '%U'", format_unformat_error, i);
12463           return -99;
12464         }
12465     }
12466
12467   if (num_m_args != 1)
12468     {
12469       errmsg ("mandatory argument(s) missing");
12470       return -99;
12471     }
12472
12473   /* Construct the API message */
12474   M (MAP_DEL_DOMAIN, map_del_domain);
12475
12476   mp->index = ntohl (index);
12477
12478   /* send it... */
12479   S;
12480
12481   /* Wait for a reply, return good/bad news  */
12482   W;
12483 }
12484
12485 static int
12486 api_map_add_del_rule (vat_main_t * vam)
12487 {
12488   unformat_input_t *i = vam->input;
12489   vl_api_map_add_del_rule_t *mp;
12490   f64 timeout;
12491   u8 is_add = 1;
12492   ip6_address_t ip6_dst;
12493   u32 num_m_args = 0, index, psid = 0;
12494
12495   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12496     {
12497       if (unformat (i, "index %d", &index))
12498         num_m_args++;
12499       else if (unformat (i, "psid %d", &psid))
12500         num_m_args++;
12501       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
12502         num_m_args++;
12503       else if (unformat (i, "del"))
12504         {
12505           is_add = 0;
12506         }
12507       else
12508         {
12509           clib_warning ("parse error '%U'", format_unformat_error, i);
12510           return -99;
12511         }
12512     }
12513
12514   /* Construct the API message */
12515   M (MAP_ADD_DEL_RULE, map_add_del_rule);
12516
12517   mp->index = ntohl (index);
12518   mp->is_add = is_add;
12519   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
12520   mp->psid = ntohs (psid);
12521
12522   /* send it... */
12523   S;
12524
12525   /* Wait for a reply, return good/bad news  */
12526   W;
12527 }
12528
12529 static int
12530 api_map_domain_dump (vat_main_t * vam)
12531 {
12532   vl_api_map_domain_dump_t *mp;
12533   f64 timeout;
12534
12535   /* Construct the API message */
12536   M (MAP_DOMAIN_DUMP, map_domain_dump);
12537
12538   /* send it... */
12539   S;
12540
12541   /* Use a control ping for synchronization */
12542   {
12543     vl_api_control_ping_t *mp;
12544     M (CONTROL_PING, control_ping);
12545     S;
12546   }
12547   W;
12548 }
12549
12550 static int
12551 api_map_rule_dump (vat_main_t * vam)
12552 {
12553   unformat_input_t *i = vam->input;
12554   vl_api_map_rule_dump_t *mp;
12555   f64 timeout;
12556   u32 domain_index = ~0;
12557
12558   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12559     {
12560       if (unformat (i, "index %u", &domain_index))
12561         ;
12562       else
12563         break;
12564     }
12565
12566   if (domain_index == ~0)
12567     {
12568       clib_warning ("parse error: domain index expected");
12569       return -99;
12570     }
12571
12572   /* Construct the API message */
12573   M (MAP_RULE_DUMP, map_rule_dump);
12574
12575   mp->domain_index = htonl (domain_index);
12576
12577   /* send it... */
12578   S;
12579
12580   /* Use a control ping for synchronization */
12581   {
12582     vl_api_control_ping_t *mp;
12583     M (CONTROL_PING, control_ping);
12584     S;
12585   }
12586   W;
12587 }
12588
12589 static void vl_api_map_add_domain_reply_t_handler
12590   (vl_api_map_add_domain_reply_t * mp)
12591 {
12592   vat_main_t *vam = &vat_main;
12593   i32 retval = ntohl (mp->retval);
12594
12595   if (vam->async_mode)
12596     {
12597       vam->async_errors += (retval < 0);
12598     }
12599   else
12600     {
12601       vam->retval = retval;
12602       vam->result_ready = 1;
12603     }
12604 }
12605
12606 static void vl_api_map_add_domain_reply_t_handler_json
12607   (vl_api_map_add_domain_reply_t * mp)
12608 {
12609   vat_main_t *vam = &vat_main;
12610   vat_json_node_t node;
12611
12612   vat_json_init_object (&node);
12613   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
12614   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
12615
12616   vat_json_print (vam->ofp, &node);
12617   vat_json_free (&node);
12618
12619   vam->retval = ntohl (mp->retval);
12620   vam->result_ready = 1;
12621 }
12622
12623 static int
12624 api_get_first_msg_id (vat_main_t * vam)
12625 {
12626   vl_api_get_first_msg_id_t *mp;
12627   f64 timeout;
12628   unformat_input_t *i = vam->input;
12629   u8 *name;
12630   u8 name_set = 0;
12631
12632   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12633     {
12634       if (unformat (i, "client %s", &name))
12635         name_set = 1;
12636       else
12637         break;
12638     }
12639
12640   if (name_set == 0)
12641     {
12642       errmsg ("missing client name");
12643       return -99;
12644     }
12645   vec_add1 (name, 0);
12646
12647   if (vec_len (name) > 63)
12648     {
12649       errmsg ("client name too long");
12650       return -99;
12651     }
12652
12653   M (GET_FIRST_MSG_ID, get_first_msg_id);
12654   clib_memcpy (mp->name, name, vec_len (name));
12655   S;
12656   W;
12657   /* NOTREACHED */
12658   return 0;
12659 }
12660
12661 static int
12662 api_cop_interface_enable_disable (vat_main_t * vam)
12663 {
12664   unformat_input_t *line_input = vam->input;
12665   vl_api_cop_interface_enable_disable_t *mp;
12666   f64 timeout;
12667   u32 sw_if_index = ~0;
12668   u8 enable_disable = 1;
12669
12670   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12671     {
12672       if (unformat (line_input, "disable"))
12673         enable_disable = 0;
12674       if (unformat (line_input, "enable"))
12675         enable_disable = 1;
12676       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
12677                          vam, &sw_if_index))
12678         ;
12679       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12680         ;
12681       else
12682         break;
12683     }
12684
12685   if (sw_if_index == ~0)
12686     {
12687       errmsg ("missing interface name or sw_if_index");
12688       return -99;
12689     }
12690
12691   /* Construct the API message */
12692   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
12693   mp->sw_if_index = ntohl (sw_if_index);
12694   mp->enable_disable = enable_disable;
12695
12696   /* send it... */
12697   S;
12698   /* Wait for the reply */
12699   W;
12700 }
12701
12702 static int
12703 api_cop_whitelist_enable_disable (vat_main_t * vam)
12704 {
12705   unformat_input_t *line_input = vam->input;
12706   vl_api_cop_whitelist_enable_disable_t *mp;
12707   f64 timeout;
12708   u32 sw_if_index = ~0;
12709   u8 ip4 = 0, ip6 = 0, default_cop = 0;
12710   u32 fib_id = 0;
12711
12712   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12713     {
12714       if (unformat (line_input, "ip4"))
12715         ip4 = 1;
12716       else if (unformat (line_input, "ip6"))
12717         ip6 = 1;
12718       else if (unformat (line_input, "default"))
12719         default_cop = 1;
12720       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
12721                          vam, &sw_if_index))
12722         ;
12723       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12724         ;
12725       else if (unformat (line_input, "fib-id %d", &fib_id))
12726         ;
12727       else
12728         break;
12729     }
12730
12731   if (sw_if_index == ~0)
12732     {
12733       errmsg ("missing interface name or sw_if_index");
12734       return -99;
12735     }
12736
12737   /* Construct the API message */
12738   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
12739   mp->sw_if_index = ntohl (sw_if_index);
12740   mp->fib_id = ntohl (fib_id);
12741   mp->ip4 = ip4;
12742   mp->ip6 = ip6;
12743   mp->default_cop = default_cop;
12744
12745   /* send it... */
12746   S;
12747   /* Wait for the reply */
12748   W;
12749 }
12750
12751 static int
12752 api_get_node_graph (vat_main_t * vam)
12753 {
12754   vl_api_get_node_graph_t *mp;
12755   f64 timeout;
12756
12757   M (GET_NODE_GRAPH, get_node_graph);
12758
12759   /* send it... */
12760   S;
12761   /* Wait for the reply */
12762   W;
12763 }
12764
12765 /* *INDENT-OFF* */
12766 /** Used for parsing LISP eids */
12767 typedef CLIB_PACKED(struct{
12768   u8 addr[16];   /**< eid address */
12769   u32 len;       /**< prefix length if IP */
12770   u8 type;      /**< type of eid */
12771 }) lisp_eid_vat_t;
12772 /* *INDENT-ON* */
12773
12774 static uword
12775 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
12776 {
12777   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
12778
12779   memset (a, 0, sizeof (a[0]));
12780
12781   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
12782     {
12783       a->type = 0;              /* ipv4 type */
12784     }
12785   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
12786     {
12787       a->type = 1;              /* ipv6 type */
12788     }
12789   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
12790     {
12791       a->type = 2;              /* mac type */
12792     }
12793   else
12794     {
12795       return 0;
12796     }
12797
12798   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
12799     {
12800       return 0;
12801     }
12802
12803   return 1;
12804 }
12805
12806 static int
12807 lisp_eid_size_vat (u8 type)
12808 {
12809   switch (type)
12810     {
12811     case 0:
12812       return 4;
12813     case 1:
12814       return 16;
12815     case 2:
12816       return 6;
12817     }
12818   return 0;
12819 }
12820
12821 static void
12822 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
12823 {
12824   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
12825 }
12826
12827 /* *INDENT-OFF* */
12828 /** Used for transferring locators via VPP API */
12829 typedef CLIB_PACKED(struct
12830 {
12831   u32 sw_if_index; /**< locator sw_if_index */
12832   u8 priority; /**< locator priority */
12833   u8 weight;   /**< locator weight */
12834 }) ls_locator_t;
12835 /* *INDENT-ON* */
12836
12837 static int
12838 api_lisp_add_del_locator_set (vat_main_t * vam)
12839 {
12840   unformat_input_t *input = vam->input;
12841   vl_api_lisp_add_del_locator_set_t *mp;
12842   f64 timeout = ~0;
12843   u8 is_add = 1;
12844   u8 *locator_set_name = NULL;
12845   u8 locator_set_name_set = 0;
12846   ls_locator_t locator, *locators = 0;
12847   u32 sw_if_index, priority, weight;
12848   u32 data_len = 0;
12849
12850   /* Parse args required to build the message */
12851   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12852     {
12853       if (unformat (input, "del"))
12854         {
12855           is_add = 0;
12856         }
12857       else if (unformat (input, "locator-set %s", &locator_set_name))
12858         {
12859           locator_set_name_set = 1;
12860         }
12861       else if (unformat (input, "sw_if_index %u p %u w %u",
12862                          &sw_if_index, &priority, &weight))
12863         {
12864           locator.sw_if_index = htonl (sw_if_index);
12865           locator.priority = priority;
12866           locator.weight = weight;
12867           vec_add1 (locators, locator);
12868         }
12869       else
12870         if (unformat
12871             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
12872              &sw_if_index, &priority, &weight))
12873         {
12874           locator.sw_if_index = htonl (sw_if_index);
12875           locator.priority = priority;
12876           locator.weight = weight;
12877           vec_add1 (locators, locator);
12878         }
12879       else
12880         break;
12881     }
12882
12883   if (locator_set_name_set == 0)
12884     {
12885       errmsg ("missing locator-set name");
12886       vec_free (locators);
12887       return -99;
12888     }
12889
12890   if (vec_len (locator_set_name) > 64)
12891     {
12892       errmsg ("locator-set name too long");
12893       vec_free (locator_set_name);
12894       vec_free (locators);
12895       return -99;
12896     }
12897   vec_add1 (locator_set_name, 0);
12898
12899   data_len = sizeof (ls_locator_t) * vec_len (locators);
12900
12901   /* Construct the API message */
12902   M2 (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set, data_len);
12903
12904   mp->is_add = is_add;
12905   clib_memcpy (mp->locator_set_name, locator_set_name,
12906                vec_len (locator_set_name));
12907   vec_free (locator_set_name);
12908
12909   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
12910   if (locators)
12911     clib_memcpy (mp->locators, locators, data_len);
12912   vec_free (locators);
12913
12914   /* send it... */
12915   S;
12916
12917   /* Wait for a reply... */
12918   W;
12919
12920   /* NOTREACHED */
12921   return 0;
12922 }
12923
12924 static int
12925 api_lisp_add_del_locator (vat_main_t * vam)
12926 {
12927   unformat_input_t *input = vam->input;
12928   vl_api_lisp_add_del_locator_t *mp;
12929   f64 timeout = ~0;
12930   u32 tmp_if_index = ~0;
12931   u32 sw_if_index = ~0;
12932   u8 sw_if_index_set = 0;
12933   u8 sw_if_index_if_name_set = 0;
12934   u32 priority = ~0;
12935   u8 priority_set = 0;
12936   u32 weight = ~0;
12937   u8 weight_set = 0;
12938   u8 is_add = 1;
12939   u8 *locator_set_name = NULL;
12940   u8 locator_set_name_set = 0;
12941
12942   /* Parse args required to build the message */
12943   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12944     {
12945       if (unformat (input, "del"))
12946         {
12947           is_add = 0;
12948         }
12949       else if (unformat (input, "locator-set %s", &locator_set_name))
12950         {
12951           locator_set_name_set = 1;
12952         }
12953       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
12954                          &tmp_if_index))
12955         {
12956           sw_if_index_if_name_set = 1;
12957           sw_if_index = tmp_if_index;
12958         }
12959       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
12960         {
12961           sw_if_index_set = 1;
12962           sw_if_index = tmp_if_index;
12963         }
12964       else if (unformat (input, "p %d", &priority))
12965         {
12966           priority_set = 1;
12967         }
12968       else if (unformat (input, "w %d", &weight))
12969         {
12970           weight_set = 1;
12971         }
12972       else
12973         break;
12974     }
12975
12976   if (locator_set_name_set == 0)
12977     {
12978       errmsg ("missing locator-set name");
12979       return -99;
12980     }
12981
12982   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
12983     {
12984       errmsg ("missing sw_if_index");
12985       vec_free (locator_set_name);
12986       return -99;
12987     }
12988
12989   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
12990     {
12991       errmsg ("cannot use both params interface name and sw_if_index");
12992       vec_free (locator_set_name);
12993       return -99;
12994     }
12995
12996   if (priority_set == 0)
12997     {
12998       errmsg ("missing locator-set priority");
12999       vec_free (locator_set_name);
13000       return -99;
13001     }
13002
13003   if (weight_set == 0)
13004     {
13005       errmsg ("missing locator-set weight");
13006       vec_free (locator_set_name);
13007       return -99;
13008     }
13009
13010   if (vec_len (locator_set_name) > 64)
13011     {
13012       errmsg ("locator-set name too long");
13013       vec_free (locator_set_name);
13014       return -99;
13015     }
13016   vec_add1 (locator_set_name, 0);
13017
13018   /* Construct the API message */
13019   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
13020
13021   mp->is_add = is_add;
13022   mp->sw_if_index = ntohl (sw_if_index);
13023   mp->priority = priority;
13024   mp->weight = weight;
13025   clib_memcpy (mp->locator_set_name, locator_set_name,
13026                vec_len (locator_set_name));
13027   vec_free (locator_set_name);
13028
13029   /* send it... */
13030   S;
13031
13032   /* Wait for a reply... */
13033   W;
13034
13035   /* NOTREACHED */
13036   return 0;
13037 }
13038
13039 uword
13040 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
13041 {
13042   u32 *key_id = va_arg (*args, u32 *);
13043   u8 *s = 0;
13044
13045   if (unformat (input, "%s", &s))
13046     {
13047       if (!strcmp ((char *) s, "sha1"))
13048         key_id[0] = HMAC_SHA_1_96;
13049       else if (!strcmp ((char *) s, "sha256"))
13050         key_id[0] = HMAC_SHA_256_128;
13051       else
13052         {
13053           clib_warning ("invalid key_id: '%s'", s);
13054           key_id[0] = HMAC_NO_KEY;
13055         }
13056     }
13057   else
13058     return 0;
13059
13060   vec_free (s);
13061   return 1;
13062 }
13063
13064 static int
13065 api_lisp_add_del_local_eid (vat_main_t * vam)
13066 {
13067   unformat_input_t *input = vam->input;
13068   vl_api_lisp_add_del_local_eid_t *mp;
13069   f64 timeout = ~0;
13070   u8 is_add = 1;
13071   u8 eid_set = 0;
13072   lisp_eid_vat_t _eid, *eid = &_eid;
13073   u8 *locator_set_name = 0;
13074   u8 locator_set_name_set = 0;
13075   u32 vni = 0;
13076   u16 key_id = 0;
13077   u8 *key = 0;
13078
13079   /* Parse args required to build the message */
13080   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13081     {
13082       if (unformat (input, "del"))
13083         {
13084           is_add = 0;
13085         }
13086       else if (unformat (input, "vni %d", &vni))
13087         {
13088           ;
13089         }
13090       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13091         {
13092           eid_set = 1;
13093         }
13094       else if (unformat (input, "locator-set %s", &locator_set_name))
13095         {
13096           locator_set_name_set = 1;
13097         }
13098       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
13099         ;
13100       else if (unformat (input, "secret-key %_%v%_", &key))
13101         ;
13102       else
13103         break;
13104     }
13105
13106   if (locator_set_name_set == 0)
13107     {
13108       errmsg ("missing locator-set name");
13109       return -99;
13110     }
13111
13112   if (0 == eid_set)
13113     {
13114       errmsg ("EID address not set!");
13115       vec_free (locator_set_name);
13116       return -99;
13117     }
13118
13119   if (key && (0 == key_id))
13120     {
13121       errmsg ("invalid key_id!");
13122       return -99;
13123     }
13124
13125   if (vec_len (key) > 64)
13126     {
13127       errmsg ("key too long");
13128       vec_free (key);
13129       return -99;
13130     }
13131
13132   if (vec_len (locator_set_name) > 64)
13133     {
13134       errmsg ("locator-set name too long");
13135       vec_free (locator_set_name);
13136       return -99;
13137     }
13138   vec_add1 (locator_set_name, 0);
13139
13140   /* Construct the API message */
13141   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
13142
13143   mp->is_add = is_add;
13144   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13145   mp->eid_type = eid->type;
13146   mp->prefix_len = eid->len;
13147   mp->vni = clib_host_to_net_u32 (vni);
13148   mp->key_id = clib_host_to_net_u16 (key_id);
13149   clib_memcpy (mp->locator_set_name, locator_set_name,
13150                vec_len (locator_set_name));
13151   clib_memcpy (mp->key, key, vec_len (key));
13152
13153   vec_free (locator_set_name);
13154   vec_free (key);
13155
13156   /* send it... */
13157   S;
13158
13159   /* Wait for a reply... */
13160   W;
13161
13162   /* NOTREACHED */
13163   return 0;
13164 }
13165
13166 /* *INDENT-OFF* */
13167 /** Used for transferring locators via VPP API */
13168 typedef CLIB_PACKED(struct
13169 {
13170   u8 is_ip4; /**< is locator an IPv4 address? */
13171   u8 priority; /**< locator priority */
13172   u8 weight;   /**< locator weight */
13173   u8 addr[16]; /**< IPv4/IPv6 address */
13174 }) rloc_t;
13175 /* *INDENT-ON* */
13176
13177 static int
13178 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
13179 {
13180   u32 dp_table = 0, vni = 0;;
13181   unformat_input_t *input = vam->input;
13182   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
13183   f64 timeout = ~0;
13184   u8 is_add = 1;
13185   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
13186   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
13187   u8 rmt_eid_set = 0, lcl_eid_set = 0;
13188   u32 action = ~0, w;
13189   ip4_address_t rmt_rloc4, lcl_rloc4;
13190   ip6_address_t rmt_rloc6, lcl_rloc6;
13191   vl_api_lisp_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc =
13192     0;
13193
13194   memset (&rloc, 0, sizeof (rloc));
13195
13196   /* Parse args required to build the message */
13197   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13198     {
13199       if (unformat (input, "del"))
13200         is_add = 0;
13201       else if (unformat (input, "add"))
13202         is_add = 1;
13203       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
13204         {
13205           rmt_eid_set = 1;
13206         }
13207       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
13208         {
13209           lcl_eid_set = 1;
13210         }
13211       else if (unformat (input, "vrf %d", &dp_table))
13212         ;
13213       else if (unformat (input, "bd %d", &dp_table))
13214         ;
13215       else if (unformat (input, "vni %d", &vni))
13216         ;
13217       else if (unformat (input, "w %d", &w))
13218         {
13219           if (!curr_rloc)
13220             {
13221               errmsg ("No RLOC configured for setting priority/weight!");
13222               return -99;
13223             }
13224           curr_rloc->weight = w;
13225         }
13226       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
13227                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
13228         {
13229           rloc.is_ip4 = 1;
13230
13231           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
13232           rloc.weight = 0;
13233           vec_add1 (lcl_locs, rloc);
13234
13235           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
13236           vec_add1 (rmt_locs, rloc);
13237           /* weight saved in rmt loc */
13238           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13239         }
13240       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
13241                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
13242         {
13243           rloc.is_ip4 = 0;
13244           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
13245           rloc.weight = 0;
13246           vec_add1 (lcl_locs, rloc);
13247
13248           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
13249           vec_add1 (rmt_locs, rloc);
13250           /* weight saved in rmt loc */
13251           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13252         }
13253       else if (unformat (input, "action %d", &action))
13254         {
13255           ;
13256         }
13257       else
13258         {
13259           clib_warning ("parse error '%U'", format_unformat_error, input);
13260           return -99;
13261         }
13262     }
13263
13264   if (!rmt_eid_set)
13265     {
13266       errmsg ("remote eid addresses not set");
13267       return -99;
13268     }
13269
13270   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
13271     {
13272       errmsg ("eid types don't match");
13273       return -99;
13274     }
13275
13276   if (0 == rmt_locs && (u32) ~ 0 == action)
13277     {
13278       errmsg ("action not set for negative mapping");
13279       return -99;
13280     }
13281
13282   /* Construct the API message */
13283   M2 (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry,
13284       sizeof (vl_api_lisp_gpe_locator_t) * vec_len (rmt_locs) * 2);
13285
13286   mp->is_add = is_add;
13287   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
13288   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
13289   mp->eid_type = rmt_eid->type;
13290   mp->dp_table = clib_host_to_net_u32 (dp_table);
13291   mp->vni = clib_host_to_net_u32 (vni);
13292   mp->rmt_len = rmt_eid->len;
13293   mp->lcl_len = lcl_eid->len;
13294   mp->action = action;
13295
13296   if (0 != rmt_locs && 0 != lcl_locs)
13297     {
13298       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
13299       clib_memcpy (mp->locs, lcl_locs,
13300                    (sizeof (vl_api_lisp_gpe_locator_t) * vec_len (lcl_locs)));
13301
13302       u32 offset = sizeof (vl_api_lisp_gpe_locator_t) * vec_len (lcl_locs);
13303       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
13304                    (sizeof (vl_api_lisp_gpe_locator_t) * vec_len (rmt_locs)));
13305     }
13306   vec_free (lcl_locs);
13307   vec_free (rmt_locs);
13308
13309   /* send it... */
13310   S;
13311
13312   /* Wait for a reply... */
13313   W;
13314
13315   /* NOTREACHED */
13316   return 0;
13317 }
13318
13319 static int
13320 api_lisp_add_del_map_server (vat_main_t * vam)
13321 {
13322   unformat_input_t *input = vam->input;
13323   vl_api_lisp_add_del_map_server_t *mp;
13324   f64 timeout = ~0;
13325   u8 is_add = 1;
13326   u8 ipv4_set = 0;
13327   u8 ipv6_set = 0;
13328   ip4_address_t ipv4;
13329   ip6_address_t ipv6;
13330
13331   /* Parse args required to build the message */
13332   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13333     {
13334       if (unformat (input, "del"))
13335         {
13336           is_add = 0;
13337         }
13338       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13339         {
13340           ipv4_set = 1;
13341         }
13342       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13343         {
13344           ipv6_set = 1;
13345         }
13346       else
13347         break;
13348     }
13349
13350   if (ipv4_set && ipv6_set)
13351     {
13352       errmsg ("both eid v4 and v6 addresses set");
13353       return -99;
13354     }
13355
13356   if (!ipv4_set && !ipv6_set)
13357     {
13358       errmsg ("eid addresses not set");
13359       return -99;
13360     }
13361
13362   /* Construct the API message */
13363   M (LISP_ADD_DEL_MAP_SERVER, lisp_add_del_map_server);
13364
13365   mp->is_add = is_add;
13366   if (ipv6_set)
13367     {
13368       mp->is_ipv6 = 1;
13369       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13370     }
13371   else
13372     {
13373       mp->is_ipv6 = 0;
13374       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13375     }
13376
13377   /* send it... */
13378   S;
13379
13380   /* Wait for a reply... */
13381   W;
13382
13383   /* NOTREACHED */
13384   return 0;
13385 }
13386
13387 static int
13388 api_lisp_add_del_map_resolver (vat_main_t * vam)
13389 {
13390   unformat_input_t *input = vam->input;
13391   vl_api_lisp_add_del_map_resolver_t *mp;
13392   f64 timeout = ~0;
13393   u8 is_add = 1;
13394   u8 ipv4_set = 0;
13395   u8 ipv6_set = 0;
13396   ip4_address_t ipv4;
13397   ip6_address_t ipv6;
13398
13399   /* Parse args required to build the message */
13400   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13401     {
13402       if (unformat (input, "del"))
13403         {
13404           is_add = 0;
13405         }
13406       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13407         {
13408           ipv4_set = 1;
13409         }
13410       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13411         {
13412           ipv6_set = 1;
13413         }
13414       else
13415         break;
13416     }
13417
13418   if (ipv4_set && ipv6_set)
13419     {
13420       errmsg ("both eid v4 and v6 addresses set");
13421       return -99;
13422     }
13423
13424   if (!ipv4_set && !ipv6_set)
13425     {
13426       errmsg ("eid addresses not set");
13427       return -99;
13428     }
13429
13430   /* Construct the API message */
13431   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
13432
13433   mp->is_add = is_add;
13434   if (ipv6_set)
13435     {
13436       mp->is_ipv6 = 1;
13437       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13438     }
13439   else
13440     {
13441       mp->is_ipv6 = 0;
13442       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13443     }
13444
13445   /* send it... */
13446   S;
13447
13448   /* Wait for a reply... */
13449   W;
13450
13451   /* NOTREACHED */
13452   return 0;
13453 }
13454
13455 static int
13456 api_lisp_gpe_enable_disable (vat_main_t * vam)
13457 {
13458   unformat_input_t *input = vam->input;
13459   vl_api_lisp_gpe_enable_disable_t *mp;
13460   f64 timeout = ~0;
13461   u8 is_set = 0;
13462   u8 is_en = 1;
13463
13464   /* Parse args required to build the message */
13465   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13466     {
13467       if (unformat (input, "enable"))
13468         {
13469           is_set = 1;
13470           is_en = 1;
13471         }
13472       else if (unformat (input, "disable"))
13473         {
13474           is_set = 1;
13475           is_en = 0;
13476         }
13477       else
13478         break;
13479     }
13480
13481   if (is_set == 0)
13482     {
13483       errmsg ("Value not set");
13484       return -99;
13485     }
13486
13487   /* Construct the API message */
13488   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
13489
13490   mp->is_en = is_en;
13491
13492   /* send it... */
13493   S;
13494
13495   /* Wait for a reply... */
13496   W;
13497
13498   /* NOTREACHED */
13499   return 0;
13500 }
13501
13502 static int
13503 api_lisp_rloc_probe_enable_disable (vat_main_t * vam)
13504 {
13505   unformat_input_t *input = vam->input;
13506   vl_api_lisp_rloc_probe_enable_disable_t *mp;
13507   f64 timeout = ~0;
13508   u8 is_set = 0;
13509   u8 is_en = 0;
13510
13511   /* Parse args required to build the message */
13512   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13513     {
13514       if (unformat (input, "enable"))
13515         {
13516           is_set = 1;
13517           is_en = 1;
13518         }
13519       else if (unformat (input, "disable"))
13520         is_set = 1;
13521       else
13522         break;
13523     }
13524
13525   if (!is_set)
13526     {
13527       errmsg ("Value not set");
13528       return -99;
13529     }
13530
13531   /* Construct the API message */
13532   M (LISP_RLOC_PROBE_ENABLE_DISABLE, lisp_rloc_probe_enable_disable);
13533
13534   mp->is_enabled = is_en;
13535
13536   /* send it... */
13537   S;
13538
13539   /* Wait for a reply... */
13540   W;
13541
13542   /* NOTREACHED */
13543   return 0;
13544 }
13545
13546 static int
13547 api_lisp_map_register_enable_disable (vat_main_t * vam)
13548 {
13549   unformat_input_t *input = vam->input;
13550   vl_api_lisp_map_register_enable_disable_t *mp;
13551   f64 timeout = ~0;
13552   u8 is_set = 0;
13553   u8 is_en = 0;
13554
13555   /* Parse args required to build the message */
13556   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13557     {
13558       if (unformat (input, "enable"))
13559         {
13560           is_set = 1;
13561           is_en = 1;
13562         }
13563       else if (unformat (input, "disable"))
13564         is_set = 1;
13565       else
13566         break;
13567     }
13568
13569   if (!is_set)
13570     {
13571       errmsg ("Value not set");
13572       return -99;
13573     }
13574
13575   /* Construct the API message */
13576   M (LISP_MAP_REGISTER_ENABLE_DISABLE, lisp_map_register_enable_disable);
13577
13578   mp->is_enabled = is_en;
13579
13580   /* send it... */
13581   S;
13582
13583   /* Wait for a reply... */
13584   W;
13585
13586   /* NOTREACHED */
13587   return 0;
13588 }
13589
13590 static int
13591 api_lisp_enable_disable (vat_main_t * vam)
13592 {
13593   unformat_input_t *input = vam->input;
13594   vl_api_lisp_enable_disable_t *mp;
13595   f64 timeout = ~0;
13596   u8 is_set = 0;
13597   u8 is_en = 0;
13598
13599   /* Parse args required to build the message */
13600   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13601     {
13602       if (unformat (input, "enable"))
13603         {
13604           is_set = 1;
13605           is_en = 1;
13606         }
13607       else if (unformat (input, "disable"))
13608         {
13609           is_set = 1;
13610         }
13611       else
13612         break;
13613     }
13614
13615   if (!is_set)
13616     {
13617       errmsg ("Value not set");
13618       return -99;
13619     }
13620
13621   /* Construct the API message */
13622   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
13623
13624   mp->is_en = is_en;
13625
13626   /* send it... */
13627   S;
13628
13629   /* Wait for a reply... */
13630   W;
13631
13632   /* NOTREACHED */
13633   return 0;
13634 }
13635
13636 static int
13637 api_show_lisp_map_register_state (vat_main_t * vam)
13638 {
13639   f64 timeout = ~0;
13640   vl_api_show_lisp_map_register_state_t *mp;
13641
13642   M (SHOW_LISP_MAP_REGISTER_STATE, show_lisp_map_register_state);
13643
13644   /* send */
13645   S;
13646
13647   /* wait for reply */
13648   W;
13649
13650   return 0;
13651 }
13652
13653 static int
13654 api_show_lisp_rloc_probe_state (vat_main_t * vam)
13655 {
13656   f64 timeout = ~0;
13657   vl_api_show_lisp_rloc_probe_state_t *mp;
13658
13659   M (SHOW_LISP_RLOC_PROBE_STATE, show_lisp_rloc_probe_state);
13660
13661   /* send */
13662   S;
13663
13664   /* wait for reply */
13665   W;
13666
13667   return 0;
13668 }
13669
13670 static int
13671 api_show_lisp_map_request_mode (vat_main_t * vam)
13672 {
13673   f64 timeout = ~0;
13674   vl_api_show_lisp_map_request_mode_t *mp;
13675
13676   M (SHOW_LISP_MAP_REQUEST_MODE, show_lisp_map_request_mode);
13677
13678   /* send */
13679   S;
13680
13681   /* wait for reply */
13682   W;
13683
13684   return 0;
13685 }
13686
13687 static int
13688 api_lisp_map_request_mode (vat_main_t * vam)
13689 {
13690   f64 timeout = ~0;
13691   unformat_input_t *input = vam->input;
13692   vl_api_lisp_map_request_mode_t *mp;
13693   u8 mode = 0;
13694
13695   /* Parse args required to build the message */
13696   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13697     {
13698       if (unformat (input, "dst-only"))
13699         mode = 0;
13700       else if (unformat (input, "src-dst"))
13701         mode = 1;
13702       else
13703         {
13704           errmsg ("parse error '%U'", format_unformat_error, input);
13705           return -99;
13706         }
13707     }
13708
13709   M (LISP_MAP_REQUEST_MODE, lisp_map_request_mode);
13710
13711   mp->mode = mode;
13712
13713   /* send */
13714   S;
13715
13716   /* wait for reply */
13717   W;
13718
13719   /* notreached */
13720   return 0;
13721 }
13722
13723 /**
13724  * Enable/disable LISP proxy ITR.
13725  *
13726  * @param vam vpp API test context
13727  * @return return code
13728  */
13729 static int
13730 api_lisp_pitr_set_locator_set (vat_main_t * vam)
13731 {
13732   f64 timeout = ~0;
13733   u8 ls_name_set = 0;
13734   unformat_input_t *input = vam->input;
13735   vl_api_lisp_pitr_set_locator_set_t *mp;
13736   u8 is_add = 1;
13737   u8 *ls_name = 0;
13738
13739   /* Parse args required to build the message */
13740   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13741     {
13742       if (unformat (input, "del"))
13743         is_add = 0;
13744       else if (unformat (input, "locator-set %s", &ls_name))
13745         ls_name_set = 1;
13746       else
13747         {
13748           errmsg ("parse error '%U'", format_unformat_error, input);
13749           return -99;
13750         }
13751     }
13752
13753   if (!ls_name_set)
13754     {
13755       errmsg ("locator-set name not set!");
13756       return -99;
13757     }
13758
13759   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
13760
13761   mp->is_add = is_add;
13762   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
13763   vec_free (ls_name);
13764
13765   /* send */
13766   S;
13767
13768   /* wait for reply */
13769   W;
13770
13771   /* notreached */
13772   return 0;
13773 }
13774
13775 static int
13776 api_show_lisp_pitr (vat_main_t * vam)
13777 {
13778   vl_api_show_lisp_pitr_t *mp;
13779   f64 timeout = ~0;
13780
13781   if (!vam->json_output)
13782     {
13783       print (vam->ofp, "%=20s", "lisp status:");
13784     }
13785
13786   M (SHOW_LISP_PITR, show_lisp_pitr);
13787   /* send it... */
13788   S;
13789
13790   /* Wait for a reply... */
13791   W;
13792
13793   /* NOTREACHED */
13794   return 0;
13795 }
13796
13797 /**
13798  * Add/delete mapping between vni and vrf
13799  */
13800 static int
13801 api_lisp_eid_table_add_del_map (vat_main_t * vam)
13802 {
13803   f64 timeout = ~0;
13804   unformat_input_t *input = vam->input;
13805   vl_api_lisp_eid_table_add_del_map_t *mp;
13806   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
13807   u32 vni, vrf, bd_index;
13808
13809   /* Parse args required to build the message */
13810   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13811     {
13812       if (unformat (input, "del"))
13813         is_add = 0;
13814       else if (unformat (input, "vrf %d", &vrf))
13815         vrf_set = 1;
13816       else if (unformat (input, "bd_index %d", &bd_index))
13817         bd_index_set = 1;
13818       else if (unformat (input, "vni %d", &vni))
13819         vni_set = 1;
13820       else
13821         break;
13822     }
13823
13824   if (!vni_set || (!vrf_set && !bd_index_set))
13825     {
13826       errmsg ("missing arguments!");
13827       return -99;
13828     }
13829
13830   if (vrf_set && bd_index_set)
13831     {
13832       errmsg ("error: both vrf and bd entered!");
13833       return -99;
13834     }
13835
13836   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
13837
13838   mp->is_add = is_add;
13839   mp->vni = htonl (vni);
13840   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
13841   mp->is_l2 = bd_index_set;
13842
13843   /* send */
13844   S;
13845
13846   /* wait for reply */
13847   W;
13848
13849   /* notreached */
13850   return 0;
13851 }
13852
13853 uword
13854 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
13855 {
13856   u32 *action = va_arg (*args, u32 *);
13857   u8 *s = 0;
13858
13859   if (unformat (input, "%s", &s))
13860     {
13861       if (!strcmp ((char *) s, "no-action"))
13862         action[0] = 0;
13863       else if (!strcmp ((char *) s, "natively-forward"))
13864         action[0] = 1;
13865       else if (!strcmp ((char *) s, "send-map-request"))
13866         action[0] = 2;
13867       else if (!strcmp ((char *) s, "drop"))
13868         action[0] = 3;
13869       else
13870         {
13871           clib_warning ("invalid action: '%s'", s);
13872           action[0] = 3;
13873         }
13874     }
13875   else
13876     return 0;
13877
13878   vec_free (s);
13879   return 1;
13880 }
13881
13882 /**
13883  * Add/del remote mapping to/from LISP control plane
13884  *
13885  * @param vam vpp API test context
13886  * @return return code
13887  */
13888 static int
13889 api_lisp_add_del_remote_mapping (vat_main_t * vam)
13890 {
13891   unformat_input_t *input = vam->input;
13892   vl_api_lisp_add_del_remote_mapping_t *mp;
13893   f64 timeout = ~0;
13894   u32 vni = 0;
13895   lisp_eid_vat_t _eid, *eid = &_eid;
13896   lisp_eid_vat_t _seid, *seid = &_seid;
13897   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
13898   u32 action = ~0, p, w, data_len;
13899   ip4_address_t rloc4;
13900   ip6_address_t rloc6;
13901   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
13902
13903   memset (&rloc, 0, sizeof (rloc));
13904
13905   /* Parse args required to build the message */
13906   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13907     {
13908       if (unformat (input, "del-all"))
13909         {
13910           del_all = 1;
13911         }
13912       else if (unformat (input, "del"))
13913         {
13914           is_add = 0;
13915         }
13916       else if (unformat (input, "add"))
13917         {
13918           is_add = 1;
13919         }
13920       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13921         {
13922           eid_set = 1;
13923         }
13924       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
13925         {
13926           seid_set = 1;
13927         }
13928       else if (unformat (input, "vni %d", &vni))
13929         {
13930           ;
13931         }
13932       else if (unformat (input, "p %d w %d", &p, &w))
13933         {
13934           if (!curr_rloc)
13935             {
13936               errmsg ("No RLOC configured for setting priority/weight!");
13937               return -99;
13938             }
13939           curr_rloc->priority = p;
13940           curr_rloc->weight = w;
13941         }
13942       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
13943         {
13944           rloc.is_ip4 = 1;
13945           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
13946           vec_add1 (rlocs, rloc);
13947           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13948         }
13949       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
13950         {
13951           rloc.is_ip4 = 0;
13952           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
13953           vec_add1 (rlocs, rloc);
13954           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13955         }
13956       else if (unformat (input, "action %U",
13957                          unformat_negative_mapping_action, &action))
13958         {
13959           ;
13960         }
13961       else
13962         {
13963           clib_warning ("parse error '%U'", format_unformat_error, input);
13964           return -99;
13965         }
13966     }
13967
13968   if (0 == eid_set)
13969     {
13970       errmsg ("missing params!");
13971       return -99;
13972     }
13973
13974   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
13975     {
13976       errmsg ("no action set for negative map-reply!");
13977       return -99;
13978     }
13979
13980   data_len = vec_len (rlocs) * sizeof (rloc_t);
13981
13982   M2 (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping, data_len);
13983   mp->is_add = is_add;
13984   mp->vni = htonl (vni);
13985   mp->action = (u8) action;
13986   mp->is_src_dst = seid_set;
13987   mp->eid_len = eid->len;
13988   mp->seid_len = seid->len;
13989   mp->del_all = del_all;
13990   mp->eid_type = eid->type;
13991   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13992   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
13993
13994   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
13995   clib_memcpy (mp->rlocs, rlocs, data_len);
13996   vec_free (rlocs);
13997
13998   /* send it... */
13999   S;
14000
14001   /* Wait for a reply... */
14002   W;
14003
14004   /* NOTREACHED */
14005   return 0;
14006 }
14007
14008 /**
14009  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
14010  * forwarding entries in data-plane accordingly.
14011  *
14012  * @param vam vpp API test context
14013  * @return return code
14014  */
14015 static int
14016 api_lisp_add_del_adjacency (vat_main_t * vam)
14017 {
14018   unformat_input_t *input = vam->input;
14019   vl_api_lisp_add_del_adjacency_t *mp;
14020   f64 timeout = ~0;
14021   u32 vni = 0;
14022   ip4_address_t leid4, reid4;
14023   ip6_address_t leid6, reid6;
14024   u8 reid_mac[6] = { 0 };
14025   u8 leid_mac[6] = { 0 };
14026   u8 reid_type, leid_type;
14027   u32 leid_len = 0, reid_len = 0, len;
14028   u8 is_add = 1;
14029
14030   leid_type = reid_type = (u8) ~ 0;
14031
14032   /* Parse args required to build the message */
14033   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14034     {
14035       if (unformat (input, "del"))
14036         {
14037           is_add = 0;
14038         }
14039       else if (unformat (input, "add"))
14040         {
14041           is_add = 1;
14042         }
14043       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
14044                          &reid4, &len))
14045         {
14046           reid_type = 0;        /* ipv4 */
14047           reid_len = len;
14048         }
14049       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
14050                          &reid6, &len))
14051         {
14052           reid_type = 1;        /* ipv6 */
14053           reid_len = len;
14054         }
14055       else if (unformat (input, "reid %U", unformat_ethernet_address,
14056                          reid_mac))
14057         {
14058           reid_type = 2;        /* mac */
14059         }
14060       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
14061                          &leid4, &len))
14062         {
14063           leid_type = 0;        /* ipv4 */
14064           leid_len = len;
14065         }
14066       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
14067                          &leid6, &len))
14068         {
14069           leid_type = 1;        /* ipv6 */
14070           leid_len = len;
14071         }
14072       else if (unformat (input, "leid %U", unformat_ethernet_address,
14073                          leid_mac))
14074         {
14075           leid_type = 2;        /* mac */
14076         }
14077       else if (unformat (input, "vni %d", &vni))
14078         {
14079           ;
14080         }
14081       else
14082         {
14083           errmsg ("parse error '%U'", format_unformat_error, input);
14084           return -99;
14085         }
14086     }
14087
14088   if ((u8) ~ 0 == reid_type)
14089     {
14090       errmsg ("missing params!");
14091       return -99;
14092     }
14093
14094   if (leid_type != reid_type)
14095     {
14096       errmsg ("remote and local EIDs are of different types!");
14097       return -99;
14098     }
14099
14100   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
14101   mp->is_add = is_add;
14102   mp->vni = htonl (vni);
14103   mp->leid_len = leid_len;
14104   mp->reid_len = reid_len;
14105   mp->eid_type = reid_type;
14106
14107   switch (mp->eid_type)
14108     {
14109     case 0:
14110       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
14111       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
14112       break;
14113     case 1:
14114       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
14115       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
14116       break;
14117     case 2:
14118       clib_memcpy (mp->leid, leid_mac, 6);
14119       clib_memcpy (mp->reid, reid_mac, 6);
14120       break;
14121     default:
14122       errmsg ("unknown EID type %d!", mp->eid_type);
14123       return 0;
14124     }
14125
14126   /* send it... */
14127   S;
14128
14129   /* Wait for a reply... */
14130   W;
14131
14132   /* NOTREACHED */
14133   return 0;
14134 }
14135
14136 static int
14137 api_lisp_gpe_add_del_iface (vat_main_t * vam)
14138 {
14139   unformat_input_t *input = vam->input;
14140   vl_api_lisp_gpe_add_del_iface_t *mp;
14141   f64 timeout = ~0;
14142   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
14143   u32 dp_table = 0, vni = 0;
14144
14145   /* Parse args required to build the message */
14146   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14147     {
14148       if (unformat (input, "up"))
14149         {
14150           action_set = 1;
14151           is_add = 1;
14152         }
14153       else if (unformat (input, "down"))
14154         {
14155           action_set = 1;
14156           is_add = 0;
14157         }
14158       else if (unformat (input, "table_id %d", &dp_table))
14159         {
14160           dp_table_set = 1;
14161         }
14162       else if (unformat (input, "bd_id %d", &dp_table))
14163         {
14164           dp_table_set = 1;
14165           is_l2 = 1;
14166         }
14167       else if (unformat (input, "vni %d", &vni))
14168         {
14169           vni_set = 1;
14170         }
14171       else
14172         break;
14173     }
14174
14175   if (action_set == 0)
14176     {
14177       errmsg ("Action not set");
14178       return -99;
14179     }
14180   if (dp_table_set == 0 || vni_set == 0)
14181     {
14182       errmsg ("vni and dp_table must be set");
14183       return -99;
14184     }
14185
14186   /* Construct the API message */
14187   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
14188
14189   mp->is_add = is_add;
14190   mp->dp_table = dp_table;
14191   mp->is_l2 = is_l2;
14192   mp->vni = vni;
14193
14194   /* send it... */
14195   S;
14196
14197   /* Wait for a reply... */
14198   W;
14199
14200   /* NOTREACHED */
14201   return 0;
14202 }
14203
14204 /**
14205  * Add/del map request itr rlocs from LISP control plane and updates
14206  *
14207  * @param vam vpp API test context
14208  * @return return code
14209  */
14210 static int
14211 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
14212 {
14213   unformat_input_t *input = vam->input;
14214   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
14215   f64 timeout = ~0;
14216   u8 *locator_set_name = 0;
14217   u8 locator_set_name_set = 0;
14218   u8 is_add = 1;
14219
14220   /* Parse args required to build the message */
14221   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14222     {
14223       if (unformat (input, "del"))
14224         {
14225           is_add = 0;
14226         }
14227       else if (unformat (input, "%_%v%_", &locator_set_name))
14228         {
14229           locator_set_name_set = 1;
14230         }
14231       else
14232         {
14233           clib_warning ("parse error '%U'", format_unformat_error, input);
14234           return -99;
14235         }
14236     }
14237
14238   if (is_add && !locator_set_name_set)
14239     {
14240       errmsg ("itr-rloc is not set!");
14241       return -99;
14242     }
14243
14244   if (is_add && vec_len (locator_set_name) > 64)
14245     {
14246       errmsg ("itr-rloc locator-set name too long");
14247       vec_free (locator_set_name);
14248       return -99;
14249     }
14250
14251   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
14252   mp->is_add = is_add;
14253   if (is_add)
14254     {
14255       clib_memcpy (mp->locator_set_name, locator_set_name,
14256                    vec_len (locator_set_name));
14257     }
14258   else
14259     {
14260       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
14261     }
14262   vec_free (locator_set_name);
14263
14264   /* send it... */
14265   S;
14266
14267   /* Wait for a reply... */
14268   W;
14269
14270   /* NOTREACHED */
14271   return 0;
14272 }
14273
14274 static int
14275 api_lisp_locator_dump (vat_main_t * vam)
14276 {
14277   unformat_input_t *input = vam->input;
14278   vl_api_lisp_locator_dump_t *mp;
14279   f64 timeout = ~0;
14280   u8 is_index_set = 0, is_name_set = 0;
14281   u8 *ls_name = 0;
14282   u32 ls_index = ~0;
14283
14284   /* Parse args required to build the message */
14285   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14286     {
14287       if (unformat (input, "ls_name %_%v%_", &ls_name))
14288         {
14289           is_name_set = 1;
14290         }
14291       else if (unformat (input, "ls_index %d", &ls_index))
14292         {
14293           is_index_set = 1;
14294         }
14295       else
14296         {
14297           errmsg ("parse error '%U'", format_unformat_error, input);
14298           return -99;
14299         }
14300     }
14301
14302   if (!is_index_set && !is_name_set)
14303     {
14304       errmsg ("error: expected one of index or name!");
14305       return -99;
14306     }
14307
14308   if (is_index_set && is_name_set)
14309     {
14310       errmsg ("error: only one param expected!");
14311       return -99;
14312     }
14313
14314   if (vec_len (ls_name) > 62)
14315     {
14316       errmsg ("error: locator set name too long!");
14317       return -99;
14318     }
14319
14320   if (!vam->json_output)
14321     {
14322       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
14323     }
14324
14325   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
14326   mp->is_index_set = is_index_set;
14327
14328   if (is_index_set)
14329     mp->ls_index = clib_host_to_net_u32 (ls_index);
14330   else
14331     {
14332       vec_add1 (ls_name, 0);
14333       strncpy ((char *) mp->ls_name, (char *) ls_name,
14334                sizeof (mp->ls_name) - 1);
14335     }
14336
14337   /* send it... */
14338   S;
14339
14340   /* Use a control ping for synchronization */
14341   {
14342     vl_api_control_ping_t *mp;
14343     M (CONTROL_PING, control_ping);
14344     S;
14345   }
14346   /* Wait for a reply... */
14347   W;
14348
14349   /* NOTREACHED */
14350   return 0;
14351 }
14352
14353 static int
14354 api_lisp_locator_set_dump (vat_main_t * vam)
14355 {
14356   vl_api_lisp_locator_set_dump_t *mp;
14357   unformat_input_t *input = vam->input;
14358   f64 timeout = ~0;
14359   u8 filter = 0;
14360
14361   /* Parse args required to build the message */
14362   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14363     {
14364       if (unformat (input, "local"))
14365         {
14366           filter = 1;
14367         }
14368       else if (unformat (input, "remote"))
14369         {
14370           filter = 2;
14371         }
14372       else
14373         {
14374           errmsg ("parse error '%U'", format_unformat_error, input);
14375           return -99;
14376         }
14377     }
14378
14379   if (!vam->json_output)
14380     {
14381       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
14382     }
14383
14384   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
14385
14386   mp->filter = filter;
14387
14388   /* send it... */
14389   S;
14390
14391   /* Use a control ping for synchronization */
14392   {
14393     vl_api_control_ping_t *mp;
14394     M (CONTROL_PING, control_ping);
14395     S;
14396   }
14397   /* Wait for a reply... */
14398   W;
14399
14400   /* NOTREACHED */
14401   return 0;
14402 }
14403
14404 static int
14405 api_lisp_eid_table_map_dump (vat_main_t * vam)
14406 {
14407   u8 is_l2 = 0;
14408   u8 mode_set = 0;
14409   unformat_input_t *input = vam->input;
14410   vl_api_lisp_eid_table_map_dump_t *mp;
14411   f64 timeout = ~0;
14412
14413   /* Parse args required to build the message */
14414   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14415     {
14416       if (unformat (input, "l2"))
14417         {
14418           is_l2 = 1;
14419           mode_set = 1;
14420         }
14421       else if (unformat (input, "l3"))
14422         {
14423           is_l2 = 0;
14424           mode_set = 1;
14425         }
14426       else
14427         {
14428           errmsg ("parse error '%U'", format_unformat_error, input);
14429           return -99;
14430         }
14431     }
14432
14433   if (!mode_set)
14434     {
14435       errmsg ("expected one of 'l2' or 'l3' parameter!");
14436       return -99;
14437     }
14438
14439   if (!vam->json_output)
14440     {
14441       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
14442     }
14443
14444   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
14445   mp->is_l2 = is_l2;
14446
14447   /* send it... */
14448   S;
14449
14450   /* Use a control ping for synchronization */
14451   {
14452     vl_api_control_ping_t *mp;
14453     M (CONTROL_PING, control_ping);
14454     S;
14455   }
14456   /* Wait for a reply... */
14457   W;
14458
14459   /* NOTREACHED */
14460   return 0;
14461 }
14462
14463 static int
14464 api_lisp_eid_table_vni_dump (vat_main_t * vam)
14465 {
14466   vl_api_lisp_eid_table_vni_dump_t *mp;
14467   f64 timeout = ~0;
14468
14469   if (!vam->json_output)
14470     {
14471       print (vam->ofp, "VNI");
14472     }
14473
14474   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
14475
14476   /* send it... */
14477   S;
14478
14479   /* Use a control ping for synchronization */
14480   {
14481     vl_api_control_ping_t *mp;
14482     M (CONTROL_PING, control_ping);
14483     S;
14484   }
14485   /* Wait for a reply... */
14486   W;
14487
14488   /* NOTREACHED */
14489   return 0;
14490 }
14491
14492 static int
14493 api_lisp_eid_table_dump (vat_main_t * vam)
14494 {
14495   unformat_input_t *i = vam->input;
14496   vl_api_lisp_eid_table_dump_t *mp;
14497   f64 timeout = ~0;
14498   struct in_addr ip4;
14499   struct in6_addr ip6;
14500   u8 mac[6];
14501   u8 eid_type = ~0, eid_set = 0;
14502   u32 prefix_length = ~0, t, vni = 0;
14503   u8 filter = 0;
14504
14505   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14506     {
14507       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
14508         {
14509           eid_set = 1;
14510           eid_type = 0;
14511           prefix_length = t;
14512         }
14513       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
14514         {
14515           eid_set = 1;
14516           eid_type = 1;
14517           prefix_length = t;
14518         }
14519       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
14520         {
14521           eid_set = 1;
14522           eid_type = 2;
14523         }
14524       else if (unformat (i, "vni %d", &t))
14525         {
14526           vni = t;
14527         }
14528       else if (unformat (i, "local"))
14529         {
14530           filter = 1;
14531         }
14532       else if (unformat (i, "remote"))
14533         {
14534           filter = 2;
14535         }
14536       else
14537         {
14538           errmsg ("parse error '%U'", format_unformat_error, i);
14539           return -99;
14540         }
14541     }
14542
14543   if (!vam->json_output)
14544     {
14545       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
14546              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
14547     }
14548
14549   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
14550
14551   mp->filter = filter;
14552   if (eid_set)
14553     {
14554       mp->eid_set = 1;
14555       mp->vni = htonl (vni);
14556       mp->eid_type = eid_type;
14557       switch (eid_type)
14558         {
14559         case 0:
14560           mp->prefix_length = prefix_length;
14561           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
14562           break;
14563         case 1:
14564           mp->prefix_length = prefix_length;
14565           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
14566           break;
14567         case 2:
14568           clib_memcpy (mp->eid, mac, sizeof (mac));
14569           break;
14570         default:
14571           errmsg ("unknown EID type %d!", eid_type);
14572           return -99;
14573         }
14574     }
14575
14576   /* send it... */
14577   S;
14578
14579   /* Use a control ping for synchronization */
14580   {
14581     vl_api_control_ping_t *mp;
14582     M (CONTROL_PING, control_ping);
14583     S;
14584   }
14585
14586   /* Wait for a reply... */
14587   W;
14588
14589   /* NOTREACHED */
14590   return 0;
14591 }
14592
14593 static int
14594 api_lisp_adjacencies_get (vat_main_t * vam)
14595 {
14596   unformat_input_t *i = vam->input;
14597   vl_api_lisp_adjacencies_get_t *mp;
14598   f64 timeout = ~0;
14599   u8 vni_set = 0;
14600   u32 vni = ~0;
14601
14602   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14603     {
14604       if (unformat (i, "vni %d", &vni))
14605         {
14606           vni_set = 1;
14607         }
14608       else
14609         {
14610           errmsg ("parse error '%U'", format_unformat_error, i);
14611           return -99;
14612         }
14613     }
14614
14615   if (!vni_set)
14616     {
14617       errmsg ("vni not set!");
14618       return -99;
14619     }
14620
14621   if (!vam->json_output)
14622     {
14623       print (vam->ofp, "%s %40s", "leid", "reid");
14624     }
14625
14626   M (LISP_ADJACENCIES_GET, lisp_adjacencies_get);
14627   mp->vni = clib_host_to_net_u32 (vni);
14628
14629   /* send it... */
14630   S;
14631
14632   /* Wait for a reply... */
14633   W;
14634
14635   /* NOTREACHED */
14636   return 0;
14637 }
14638
14639 static int
14640 api_lisp_map_server_dump (vat_main_t * vam)
14641 {
14642   vl_api_lisp_map_server_dump_t *mp;
14643   f64 timeout = ~0;
14644
14645   if (!vam->json_output)
14646     {
14647       print (vam->ofp, "%=20s", "Map server");
14648     }
14649
14650   M (LISP_MAP_SERVER_DUMP, lisp_map_server_dump);
14651   /* send it... */
14652   S;
14653
14654   /* Use a control ping for synchronization */
14655   {
14656     vl_api_control_ping_t *mp;
14657     M (CONTROL_PING, control_ping);
14658     S;
14659   }
14660   /* Wait for a reply... */
14661   W;
14662
14663   /* NOTREACHED */
14664   return 0;
14665 }
14666
14667 static int
14668 api_lisp_map_resolver_dump (vat_main_t * vam)
14669 {
14670   vl_api_lisp_map_resolver_dump_t *mp;
14671   f64 timeout = ~0;
14672
14673   if (!vam->json_output)
14674     {
14675       print (vam->ofp, "%=20s", "Map resolver");
14676     }
14677
14678   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
14679   /* send it... */
14680   S;
14681
14682   /* Use a control ping for synchronization */
14683   {
14684     vl_api_control_ping_t *mp;
14685     M (CONTROL_PING, control_ping);
14686     S;
14687   }
14688   /* Wait for a reply... */
14689   W;
14690
14691   /* NOTREACHED */
14692   return 0;
14693 }
14694
14695 static int
14696 api_show_lisp_status (vat_main_t * vam)
14697 {
14698   vl_api_show_lisp_status_t *mp;
14699   f64 timeout = ~0;
14700
14701   if (!vam->json_output)
14702     {
14703       print (vam->ofp, "%-20s%-16s", "lisp status", "locator-set");
14704     }
14705
14706   M (SHOW_LISP_STATUS, show_lisp_status);
14707   /* send it... */
14708   S;
14709   /* Wait for a reply... */
14710   W;
14711
14712   /* NOTREACHED */
14713   return 0;
14714 }
14715
14716 static int
14717 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
14718 {
14719   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
14720   f64 timeout = ~0;
14721
14722   if (!vam->json_output)
14723     {
14724       print (vam->ofp, "%=20s", "itr-rlocs:");
14725     }
14726
14727   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
14728   /* send it... */
14729   S;
14730   /* Wait for a reply... */
14731   W;
14732
14733   /* NOTREACHED */
14734   return 0;
14735 }
14736
14737 static int
14738 api_af_packet_create (vat_main_t * vam)
14739 {
14740   unformat_input_t *i = vam->input;
14741   vl_api_af_packet_create_t *mp;
14742   f64 timeout;
14743   u8 *host_if_name = 0;
14744   u8 hw_addr[6];
14745   u8 random_hw_addr = 1;
14746
14747   memset (hw_addr, 0, sizeof (hw_addr));
14748
14749   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14750     {
14751       if (unformat (i, "name %s", &host_if_name))
14752         vec_add1 (host_if_name, 0);
14753       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14754         random_hw_addr = 0;
14755       else
14756         break;
14757     }
14758
14759   if (!vec_len (host_if_name))
14760     {
14761       errmsg ("host-interface name must be specified");
14762       return -99;
14763     }
14764
14765   if (vec_len (host_if_name) > 64)
14766     {
14767       errmsg ("host-interface name too long");
14768       return -99;
14769     }
14770
14771   M (AF_PACKET_CREATE, af_packet_create);
14772
14773   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14774   clib_memcpy (mp->hw_addr, hw_addr, 6);
14775   mp->use_random_hw_addr = random_hw_addr;
14776   vec_free (host_if_name);
14777
14778   S;
14779   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
14780   /* NOTREACHED */
14781   return 0;
14782 }
14783
14784 static int
14785 api_af_packet_delete (vat_main_t * vam)
14786 {
14787   unformat_input_t *i = vam->input;
14788   vl_api_af_packet_delete_t *mp;
14789   f64 timeout;
14790   u8 *host_if_name = 0;
14791
14792   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14793     {
14794       if (unformat (i, "name %s", &host_if_name))
14795         vec_add1 (host_if_name, 0);
14796       else
14797         break;
14798     }
14799
14800   if (!vec_len (host_if_name))
14801     {
14802       errmsg ("host-interface name must be specified");
14803       return -99;
14804     }
14805
14806   if (vec_len (host_if_name) > 64)
14807     {
14808       errmsg ("host-interface name too long");
14809       return -99;
14810     }
14811
14812   M (AF_PACKET_DELETE, af_packet_delete);
14813
14814   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14815   vec_free (host_if_name);
14816
14817   S;
14818   W;
14819   /* NOTREACHED */
14820   return 0;
14821 }
14822
14823 static int
14824 api_policer_add_del (vat_main_t * vam)
14825 {
14826   unformat_input_t *i = vam->input;
14827   vl_api_policer_add_del_t *mp;
14828   f64 timeout;
14829   u8 is_add = 1;
14830   u8 *name = 0;
14831   u32 cir = 0;
14832   u32 eir = 0;
14833   u64 cb = 0;
14834   u64 eb = 0;
14835   u8 rate_type = 0;
14836   u8 round_type = 0;
14837   u8 type = 0;
14838   u8 color_aware = 0;
14839   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
14840
14841   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
14842   conform_action.dscp = 0;
14843   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
14844   exceed_action.dscp = 0;
14845   violate_action.action_type = SSE2_QOS_ACTION_DROP;
14846   violate_action.dscp = 0;
14847
14848   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14849     {
14850       if (unformat (i, "del"))
14851         is_add = 0;
14852       else if (unformat (i, "name %s", &name))
14853         vec_add1 (name, 0);
14854       else if (unformat (i, "cir %u", &cir))
14855         ;
14856       else if (unformat (i, "eir %u", &eir))
14857         ;
14858       else if (unformat (i, "cb %u", &cb))
14859         ;
14860       else if (unformat (i, "eb %u", &eb))
14861         ;
14862       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
14863                          &rate_type))
14864         ;
14865       else if (unformat (i, "round_type %U", unformat_policer_round_type,
14866                          &round_type))
14867         ;
14868       else if (unformat (i, "type %U", unformat_policer_type, &type))
14869         ;
14870       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
14871                          &conform_action))
14872         ;
14873       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
14874                          &exceed_action))
14875         ;
14876       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
14877                          &violate_action))
14878         ;
14879       else if (unformat (i, "color-aware"))
14880         color_aware = 1;
14881       else
14882         break;
14883     }
14884
14885   if (!vec_len (name))
14886     {
14887       errmsg ("policer name must be specified");
14888       return -99;
14889     }
14890
14891   if (vec_len (name) > 64)
14892     {
14893       errmsg ("policer name too long");
14894       return -99;
14895     }
14896
14897   M (POLICER_ADD_DEL, policer_add_del);
14898
14899   clib_memcpy (mp->name, name, vec_len (name));
14900   vec_free (name);
14901   mp->is_add = is_add;
14902   mp->cir = cir;
14903   mp->eir = eir;
14904   mp->cb = cb;
14905   mp->eb = eb;
14906   mp->rate_type = rate_type;
14907   mp->round_type = round_type;
14908   mp->type = type;
14909   mp->conform_action_type = conform_action.action_type;
14910   mp->conform_dscp = conform_action.dscp;
14911   mp->exceed_action_type = exceed_action.action_type;
14912   mp->exceed_dscp = exceed_action.dscp;
14913   mp->violate_action_type = violate_action.action_type;
14914   mp->violate_dscp = violate_action.dscp;
14915   mp->color_aware = color_aware;
14916
14917   S;
14918   W;
14919   /* NOTREACHED */
14920   return 0;
14921 }
14922
14923 static int
14924 api_policer_dump (vat_main_t * vam)
14925 {
14926   unformat_input_t *i = vam->input;
14927   vl_api_policer_dump_t *mp;
14928   f64 timeout = ~0;
14929   u8 *match_name = 0;
14930   u8 match_name_valid = 0;
14931
14932   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14933     {
14934       if (unformat (i, "name %s", &match_name))
14935         {
14936           vec_add1 (match_name, 0);
14937           match_name_valid = 1;
14938         }
14939       else
14940         break;
14941     }
14942
14943   M (POLICER_DUMP, policer_dump);
14944   mp->match_name_valid = match_name_valid;
14945   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
14946   vec_free (match_name);
14947   /* send it... */
14948   S;
14949
14950   /* Use a control ping for synchronization */
14951   {
14952     vl_api_control_ping_t *mp;
14953     M (CONTROL_PING, control_ping);
14954     S;
14955   }
14956   /* Wait for a reply... */
14957   W;
14958
14959   /* NOTREACHED */
14960   return 0;
14961 }
14962
14963 static int
14964 api_policer_classify_set_interface (vat_main_t * vam)
14965 {
14966   unformat_input_t *i = vam->input;
14967   vl_api_policer_classify_set_interface_t *mp;
14968   f64 timeout;
14969   u32 sw_if_index;
14970   int sw_if_index_set;
14971   u32 ip4_table_index = ~0;
14972   u32 ip6_table_index = ~0;
14973   u32 l2_table_index = ~0;
14974   u8 is_add = 1;
14975
14976   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14977     {
14978       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14979         sw_if_index_set = 1;
14980       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14981         sw_if_index_set = 1;
14982       else if (unformat (i, "del"))
14983         is_add = 0;
14984       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14985         ;
14986       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14987         ;
14988       else if (unformat (i, "l2-table %d", &l2_table_index))
14989         ;
14990       else
14991         {
14992           clib_warning ("parse error '%U'", format_unformat_error, i);
14993           return -99;
14994         }
14995     }
14996
14997   if (sw_if_index_set == 0)
14998     {
14999       errmsg ("missing interface name or sw_if_index");
15000       return -99;
15001     }
15002
15003   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
15004
15005   mp->sw_if_index = ntohl (sw_if_index);
15006   mp->ip4_table_index = ntohl (ip4_table_index);
15007   mp->ip6_table_index = ntohl (ip6_table_index);
15008   mp->l2_table_index = ntohl (l2_table_index);
15009   mp->is_add = is_add;
15010
15011   S;
15012   W;
15013   /* NOTREACHED */
15014   return 0;
15015 }
15016
15017 static int
15018 api_policer_classify_dump (vat_main_t * vam)
15019 {
15020   unformat_input_t *i = vam->input;
15021   vl_api_policer_classify_dump_t *mp;
15022   f64 timeout = ~0;
15023   u8 type = POLICER_CLASSIFY_N_TABLES;
15024
15025   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
15026     ;
15027   else
15028     {
15029       errmsg ("classify table type must be specified");
15030       return -99;
15031     }
15032
15033   if (!vam->json_output)
15034     {
15035       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
15036     }
15037
15038   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
15039   mp->type = type;
15040   /* send it... */
15041   S;
15042
15043   /* Use a control ping for synchronization */
15044   {
15045     vl_api_control_ping_t *mp;
15046     M (CONTROL_PING, control_ping);
15047     S;
15048   }
15049   /* Wait for a reply... */
15050   W;
15051
15052   /* NOTREACHED */
15053   return 0;
15054 }
15055
15056 static int
15057 api_netmap_create (vat_main_t * vam)
15058 {
15059   unformat_input_t *i = vam->input;
15060   vl_api_netmap_create_t *mp;
15061   f64 timeout;
15062   u8 *if_name = 0;
15063   u8 hw_addr[6];
15064   u8 random_hw_addr = 1;
15065   u8 is_pipe = 0;
15066   u8 is_master = 0;
15067
15068   memset (hw_addr, 0, sizeof (hw_addr));
15069
15070   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15071     {
15072       if (unformat (i, "name %s", &if_name))
15073         vec_add1 (if_name, 0);
15074       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15075         random_hw_addr = 0;
15076       else if (unformat (i, "pipe"))
15077         is_pipe = 1;
15078       else if (unformat (i, "master"))
15079         is_master = 1;
15080       else if (unformat (i, "slave"))
15081         is_master = 0;
15082       else
15083         break;
15084     }
15085
15086   if (!vec_len (if_name))
15087     {
15088       errmsg ("interface name must be specified");
15089       return -99;
15090     }
15091
15092   if (vec_len (if_name) > 64)
15093     {
15094       errmsg ("interface name too long");
15095       return -99;
15096     }
15097
15098   M (NETMAP_CREATE, netmap_create);
15099
15100   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15101   clib_memcpy (mp->hw_addr, hw_addr, 6);
15102   mp->use_random_hw_addr = random_hw_addr;
15103   mp->is_pipe = is_pipe;
15104   mp->is_master = is_master;
15105   vec_free (if_name);
15106
15107   S;
15108   W;
15109   /* NOTREACHED */
15110   return 0;
15111 }
15112
15113 static int
15114 api_netmap_delete (vat_main_t * vam)
15115 {
15116   unformat_input_t *i = vam->input;
15117   vl_api_netmap_delete_t *mp;
15118   f64 timeout;
15119   u8 *if_name = 0;
15120
15121   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15122     {
15123       if (unformat (i, "name %s", &if_name))
15124         vec_add1 (if_name, 0);
15125       else
15126         break;
15127     }
15128
15129   if (!vec_len (if_name))
15130     {
15131       errmsg ("interface name must be specified");
15132       return -99;
15133     }
15134
15135   if (vec_len (if_name) > 64)
15136     {
15137       errmsg ("interface name too long");
15138       return -99;
15139     }
15140
15141   M (NETMAP_DELETE, netmap_delete);
15142
15143   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15144   vec_free (if_name);
15145
15146   S;
15147   W;
15148   /* NOTREACHED */
15149   return 0;
15150 }
15151
15152 static void vl_api_mpls_tunnel_details_t_handler
15153   (vl_api_mpls_tunnel_details_t * mp)
15154 {
15155   vat_main_t *vam = &vat_main;
15156   i32 len = mp->mt_next_hop_n_labels;
15157   i32 i;
15158
15159   print (vam->ofp, "[%d]: via %U %d labels ",
15160          mp->tunnel_index,
15161          format_ip4_address, mp->mt_next_hop,
15162          ntohl (mp->mt_next_hop_sw_if_index));
15163   for (i = 0; i < len; i++)
15164     {
15165       print (vam->ofp, "%u ", ntohl (mp->mt_next_hop_out_labels[i]));
15166     }
15167   print (vam->ofp, "");
15168 }
15169
15170 static void vl_api_mpls_tunnel_details_t_handler_json
15171   (vl_api_mpls_tunnel_details_t * mp)
15172 {
15173   vat_main_t *vam = &vat_main;
15174   vat_json_node_t *node = NULL;
15175   struct in_addr ip4;
15176   i32 i;
15177   i32 len = mp->mt_next_hop_n_labels;
15178
15179   if (VAT_JSON_ARRAY != vam->json_tree.type)
15180     {
15181       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15182       vat_json_init_array (&vam->json_tree);
15183     }
15184   node = vat_json_array_add (&vam->json_tree);
15185
15186   vat_json_init_object (node);
15187   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
15188   clib_memcpy (&ip4, &(mp->mt_next_hop), sizeof (ip4));
15189   vat_json_object_add_ip4 (node, "next_hop", ip4);
15190   vat_json_object_add_uint (node, "next_hop_sw_if_index",
15191                             ntohl (mp->mt_next_hop_sw_if_index));
15192   vat_json_object_add_uint (node, "l2_only", ntohl (mp->mt_l2_only));
15193   vat_json_object_add_uint (node, "label_count", len);
15194   for (i = 0; i < len; i++)
15195     {
15196       vat_json_object_add_uint (node, "label",
15197                                 ntohl (mp->mt_next_hop_out_labels[i]));
15198     }
15199 }
15200
15201 static int
15202 api_mpls_tunnel_dump (vat_main_t * vam)
15203 {
15204   vl_api_mpls_tunnel_dump_t *mp;
15205   f64 timeout;
15206   i32 index = -1;
15207
15208   /* Parse args required to build the message */
15209   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
15210     {
15211       if (!unformat (vam->input, "tunnel_index %d", &index))
15212         {
15213           index = -1;
15214           break;
15215         }
15216     }
15217
15218   print (vam->ofp, "  tunnel_index %d", index);
15219
15220   M (MPLS_TUNNEL_DUMP, mpls_tunnel_dump);
15221   mp->tunnel_index = htonl (index);
15222   S;
15223
15224   /* Use a control ping for synchronization */
15225   {
15226     vl_api_control_ping_t *mp;
15227     M (CONTROL_PING, control_ping);
15228     S;
15229   }
15230   W;
15231 }
15232
15233 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
15234 #define vl_api_mpls_fib_details_t_print vl_noop_handler
15235
15236 static void
15237 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
15238 {
15239   vat_main_t *vam = &vat_main;
15240   int count = ntohl (mp->count);
15241   vl_api_fib_path2_t *fp;
15242   int i;
15243
15244   print (vam->ofp,
15245          "table-id %d, label %u, ess_bit %u",
15246          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
15247   fp = mp->path;
15248   for (i = 0; i < count; i++)
15249     {
15250       if (fp->afi == IP46_TYPE_IP6)
15251         print (vam->ofp,
15252                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15253                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15254                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15255                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15256                format_ip6_address, fp->next_hop);
15257       else if (fp->afi == IP46_TYPE_IP4)
15258         print (vam->ofp,
15259                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15260                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15261                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15262                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15263                format_ip4_address, fp->next_hop);
15264       fp++;
15265     }
15266 }
15267
15268 static void vl_api_mpls_fib_details_t_handler_json
15269   (vl_api_mpls_fib_details_t * mp)
15270 {
15271   vat_main_t *vam = &vat_main;
15272   int count = ntohl (mp->count);
15273   vat_json_node_t *node = NULL;
15274   struct in_addr ip4;
15275   struct in6_addr ip6;
15276   vl_api_fib_path2_t *fp;
15277   int i;
15278
15279   if (VAT_JSON_ARRAY != vam->json_tree.type)
15280     {
15281       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15282       vat_json_init_array (&vam->json_tree);
15283     }
15284   node = vat_json_array_add (&vam->json_tree);
15285
15286   vat_json_init_object (node);
15287   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15288   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
15289   vat_json_object_add_uint (node, "label", ntohl (mp->label));
15290   vat_json_object_add_uint (node, "path_count", count);
15291   fp = mp->path;
15292   for (i = 0; i < count; i++)
15293     {
15294       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15295       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15296       vat_json_object_add_uint (node, "is_local", fp->is_local);
15297       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15298       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15299       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15300       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15301       if (fp->afi == IP46_TYPE_IP4)
15302         {
15303           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15304           vat_json_object_add_ip4 (node, "next_hop", ip4);
15305         }
15306       else if (fp->afi == IP46_TYPE_IP6)
15307         {
15308           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15309           vat_json_object_add_ip6 (node, "next_hop", ip6);
15310         }
15311     }
15312 }
15313
15314 static int
15315 api_mpls_fib_dump (vat_main_t * vam)
15316 {
15317   vl_api_mpls_fib_dump_t *mp;
15318   f64 timeout;
15319
15320   M (MPLS_FIB_DUMP, mpls_fib_dump);
15321   S;
15322
15323   /* Use a control ping for synchronization */
15324   {
15325     vl_api_control_ping_t *mp;
15326     M (CONTROL_PING, control_ping);
15327     S;
15328   }
15329   W;
15330 }
15331
15332 #define vl_api_ip_fib_details_t_endian vl_noop_handler
15333 #define vl_api_ip_fib_details_t_print vl_noop_handler
15334
15335 static void
15336 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
15337 {
15338   vat_main_t *vam = &vat_main;
15339   int count = ntohl (mp->count);
15340   vl_api_fib_path_t *fp;
15341   int i;
15342
15343   print (vam->ofp,
15344          "table-id %d, prefix %U/%d",
15345          ntohl (mp->table_id), format_ip4_address, mp->address,
15346          mp->address_length);
15347   fp = mp->path;
15348   for (i = 0; i < count; i++)
15349     {
15350       if (fp->afi == IP46_TYPE_IP6)
15351         print (vam->ofp,
15352                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15353                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15354                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15355                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15356                format_ip6_address, fp->next_hop);
15357       else if (fp->afi == IP46_TYPE_IP4)
15358         print (vam->ofp,
15359                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15360                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15361                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15362                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15363                format_ip4_address, fp->next_hop);
15364       fp++;
15365     }
15366 }
15367
15368 static void vl_api_ip_fib_details_t_handler_json
15369   (vl_api_ip_fib_details_t * mp)
15370 {
15371   vat_main_t *vam = &vat_main;
15372   int count = ntohl (mp->count);
15373   vat_json_node_t *node = NULL;
15374   struct in_addr ip4;
15375   struct in6_addr ip6;
15376   vl_api_fib_path_t *fp;
15377   int i;
15378
15379   if (VAT_JSON_ARRAY != vam->json_tree.type)
15380     {
15381       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15382       vat_json_init_array (&vam->json_tree);
15383     }
15384   node = vat_json_array_add (&vam->json_tree);
15385
15386   vat_json_init_object (node);
15387   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15388   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
15389   vat_json_object_add_ip4 (node, "prefix", ip4);
15390   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15391   vat_json_object_add_uint (node, "path_count", count);
15392   fp = mp->path;
15393   for (i = 0; i < count; i++)
15394     {
15395       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15396       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15397       vat_json_object_add_uint (node, "is_local", fp->is_local);
15398       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15399       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15400       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15401       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15402       if (fp->afi == IP46_TYPE_IP4)
15403         {
15404           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15405           vat_json_object_add_ip4 (node, "next_hop", ip4);
15406         }
15407       else if (fp->afi == IP46_TYPE_IP6)
15408         {
15409           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15410           vat_json_object_add_ip6 (node, "next_hop", ip6);
15411         }
15412     }
15413 }
15414
15415 static int
15416 api_ip_fib_dump (vat_main_t * vam)
15417 {
15418   vl_api_ip_fib_dump_t *mp;
15419   f64 timeout;
15420
15421   M (IP_FIB_DUMP, ip_fib_dump);
15422   S;
15423
15424   /* Use a control ping for synchronization */
15425   {
15426     vl_api_control_ping_t *mp;
15427     M (CONTROL_PING, control_ping);
15428     S;
15429   }
15430   W;
15431 }
15432
15433 static void vl_api_ip_neighbor_details_t_handler
15434   (vl_api_ip_neighbor_details_t * mp)
15435 {
15436   vat_main_t *vam = &vat_main;
15437
15438   print (vam->ofp, "%c %U %U",
15439          (mp->is_static) ? 'S' : 'D',
15440          format_ethernet_address, &mp->mac_address,
15441          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
15442          &mp->ip_address);
15443 }
15444
15445 static void vl_api_ip_neighbor_details_t_handler_json
15446   (vl_api_ip_neighbor_details_t * mp)
15447 {
15448
15449   vat_main_t *vam = &vat_main;
15450   vat_json_node_t *node;
15451   struct in_addr ip4;
15452   struct in6_addr ip6;
15453
15454   if (VAT_JSON_ARRAY != vam->json_tree.type)
15455     {
15456       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15457       vat_json_init_array (&vam->json_tree);
15458     }
15459   node = vat_json_array_add (&vam->json_tree);
15460
15461   vat_json_init_object (node);
15462   vat_json_object_add_string_copy (node, "flag",
15463                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
15464                                    "dynamic");
15465
15466   vat_json_object_add_string_copy (node, "link_layer",
15467                                    format (0, "%U", format_ethernet_address,
15468                                            &mp->mac_address));
15469
15470   if (mp->is_ipv6)
15471     {
15472       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
15473       vat_json_object_add_ip6 (node, "ip_address", ip6);
15474     }
15475   else
15476     {
15477       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
15478       vat_json_object_add_ip4 (node, "ip_address", ip4);
15479     }
15480 }
15481
15482 static int
15483 api_ip_neighbor_dump (vat_main_t * vam)
15484 {
15485   unformat_input_t *i = vam->input;
15486   vl_api_ip_neighbor_dump_t *mp;
15487   f64 timeout;
15488   u8 is_ipv6 = 0;
15489   u32 sw_if_index = ~0;
15490
15491   /* Parse args required to build the message */
15492   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15493     {
15494       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15495         ;
15496       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15497         ;
15498       else if (unformat (i, "ip6"))
15499         is_ipv6 = 1;
15500       else
15501         break;
15502     }
15503
15504   if (sw_if_index == ~0)
15505     {
15506       errmsg ("missing interface name or sw_if_index");
15507       return -99;
15508     }
15509
15510   M (IP_NEIGHBOR_DUMP, ip_neighbor_dump);
15511   mp->is_ipv6 = (u8) is_ipv6;
15512   mp->sw_if_index = ntohl (sw_if_index);
15513   S;
15514
15515   /* Use a control ping for synchronization */
15516   {
15517     vl_api_control_ping_t *mp;
15518     M (CONTROL_PING, control_ping);
15519     S;
15520   }
15521   W;
15522 }
15523
15524 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
15525 #define vl_api_ip6_fib_details_t_print vl_noop_handler
15526
15527 static void
15528 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
15529 {
15530   vat_main_t *vam = &vat_main;
15531   int count = ntohl (mp->count);
15532   vl_api_fib_path_t *fp;
15533   int i;
15534
15535   print (vam->ofp,
15536          "table-id %d, prefix %U/%d",
15537          ntohl (mp->table_id), format_ip6_address, mp->address,
15538          mp->address_length);
15539   fp = mp->path;
15540   for (i = 0; i < count; i++)
15541     {
15542       if (fp->afi == IP46_TYPE_IP6)
15543         print (vam->ofp,
15544                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15545                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15546                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15547                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15548                format_ip6_address, fp->next_hop);
15549       else if (fp->afi == IP46_TYPE_IP4)
15550         print (vam->ofp,
15551                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15552                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15553                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15554                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15555                format_ip4_address, fp->next_hop);
15556       fp++;
15557     }
15558 }
15559
15560 static void vl_api_ip6_fib_details_t_handler_json
15561   (vl_api_ip6_fib_details_t * mp)
15562 {
15563   vat_main_t *vam = &vat_main;
15564   int count = ntohl (mp->count);
15565   vat_json_node_t *node = NULL;
15566   struct in_addr ip4;
15567   struct in6_addr ip6;
15568   vl_api_fib_path_t *fp;
15569   int i;
15570
15571   if (VAT_JSON_ARRAY != vam->json_tree.type)
15572     {
15573       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15574       vat_json_init_array (&vam->json_tree);
15575     }
15576   node = vat_json_array_add (&vam->json_tree);
15577
15578   vat_json_init_object (node);
15579   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15580   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
15581   vat_json_object_add_ip6 (node, "prefix", ip6);
15582   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15583   vat_json_object_add_uint (node, "path_count", count);
15584   fp = mp->path;
15585   for (i = 0; i < count; i++)
15586     {
15587       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15588       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15589       vat_json_object_add_uint (node, "is_local", fp->is_local);
15590       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15591       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15592       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15593       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15594       if (fp->afi == IP46_TYPE_IP4)
15595         {
15596           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15597           vat_json_object_add_ip4 (node, "next_hop", ip4);
15598         }
15599       else if (fp->afi == IP46_TYPE_IP6)
15600         {
15601           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15602           vat_json_object_add_ip6 (node, "next_hop", ip6);
15603         }
15604     }
15605 }
15606
15607 static int
15608 api_ip6_fib_dump (vat_main_t * vam)
15609 {
15610   vl_api_ip6_fib_dump_t *mp;
15611   f64 timeout;
15612
15613   M (IP6_FIB_DUMP, ip6_fib_dump);
15614   S;
15615
15616   /* Use a control ping for synchronization */
15617   {
15618     vl_api_control_ping_t *mp;
15619     M (CONTROL_PING, control_ping);
15620     S;
15621   }
15622   W;
15623 }
15624
15625 int
15626 api_classify_table_ids (vat_main_t * vam)
15627 {
15628   vl_api_classify_table_ids_t *mp;
15629   f64 timeout;
15630
15631   /* Construct the API message */
15632   M (CLASSIFY_TABLE_IDS, classify_table_ids);
15633   mp->context = 0;
15634
15635   S;
15636   W;
15637   /* NOTREACHED */
15638   return 0;
15639 }
15640
15641 int
15642 api_classify_table_by_interface (vat_main_t * vam)
15643 {
15644   unformat_input_t *input = vam->input;
15645   vl_api_classify_table_by_interface_t *mp;
15646   f64 timeout;
15647
15648   u32 sw_if_index = ~0;
15649   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15650     {
15651       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15652         ;
15653       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15654         ;
15655       else
15656         break;
15657     }
15658   if (sw_if_index == ~0)
15659     {
15660       errmsg ("missing interface name or sw_if_index");
15661       return -99;
15662     }
15663
15664   /* Construct the API message */
15665   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
15666   mp->context = 0;
15667   mp->sw_if_index = ntohl (sw_if_index);
15668
15669   S;
15670   W;
15671   /* NOTREACHED */
15672   return 0;
15673 }
15674
15675 int
15676 api_classify_table_info (vat_main_t * vam)
15677 {
15678   unformat_input_t *input = vam->input;
15679   vl_api_classify_table_info_t *mp;
15680   f64 timeout;
15681
15682   u32 table_id = ~0;
15683   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15684     {
15685       if (unformat (input, "table_id %d", &table_id))
15686         ;
15687       else
15688         break;
15689     }
15690   if (table_id == ~0)
15691     {
15692       errmsg ("missing table id");
15693       return -99;
15694     }
15695
15696   /* Construct the API message */
15697   M (CLASSIFY_TABLE_INFO, classify_table_info);
15698   mp->context = 0;
15699   mp->table_id = ntohl (table_id);
15700
15701   S;
15702   W;
15703   /* NOTREACHED */
15704   return 0;
15705 }
15706
15707 int
15708 api_classify_session_dump (vat_main_t * vam)
15709 {
15710   unformat_input_t *input = vam->input;
15711   vl_api_classify_session_dump_t *mp;
15712   f64 timeout;
15713
15714   u32 table_id = ~0;
15715   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15716     {
15717       if (unformat (input, "table_id %d", &table_id))
15718         ;
15719       else
15720         break;
15721     }
15722   if (table_id == ~0)
15723     {
15724       errmsg ("missing table id");
15725       return -99;
15726     }
15727
15728   /* Construct the API message */
15729   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
15730   mp->context = 0;
15731   mp->table_id = ntohl (table_id);
15732   S;
15733
15734   /* Use a control ping for synchronization */
15735   {
15736     vl_api_control_ping_t *mp;
15737     M (CONTROL_PING, control_ping);
15738     S;
15739   }
15740   W;
15741   /* NOTREACHED */
15742   return 0;
15743 }
15744
15745 static void
15746 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
15747 {
15748   vat_main_t *vam = &vat_main;
15749
15750   print (vam->ofp, "collector_address %U, collector_port %d, "
15751          "src_address %U, vrf_id %d, path_mtu %u, "
15752          "template_interval %u, udp_checksum %d",
15753          format_ip4_address, mp->collector_address,
15754          ntohs (mp->collector_port),
15755          format_ip4_address, mp->src_address,
15756          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
15757          ntohl (mp->template_interval), mp->udp_checksum);
15758
15759   vam->retval = 0;
15760   vam->result_ready = 1;
15761 }
15762
15763 static void
15764   vl_api_ipfix_exporter_details_t_handler_json
15765   (vl_api_ipfix_exporter_details_t * mp)
15766 {
15767   vat_main_t *vam = &vat_main;
15768   vat_json_node_t node;
15769   struct in_addr collector_address;
15770   struct in_addr src_address;
15771
15772   vat_json_init_object (&node);
15773   clib_memcpy (&collector_address, &mp->collector_address,
15774                sizeof (collector_address));
15775   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
15776   vat_json_object_add_uint (&node, "collector_port",
15777                             ntohs (mp->collector_port));
15778   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
15779   vat_json_object_add_ip4 (&node, "src_address", src_address);
15780   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
15781   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
15782   vat_json_object_add_uint (&node, "template_interval",
15783                             ntohl (mp->template_interval));
15784   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
15785
15786   vat_json_print (vam->ofp, &node);
15787   vat_json_free (&node);
15788   vam->retval = 0;
15789   vam->result_ready = 1;
15790 }
15791
15792 int
15793 api_ipfix_exporter_dump (vat_main_t * vam)
15794 {
15795   vl_api_ipfix_exporter_dump_t *mp;
15796   f64 timeout;
15797
15798   /* Construct the API message */
15799   M (IPFIX_EXPORTER_DUMP, ipfix_exporter_dump);
15800   mp->context = 0;
15801
15802   S;
15803   W;
15804   /* NOTREACHED */
15805   return 0;
15806 }
15807
15808 static int
15809 api_ipfix_classify_stream_dump (vat_main_t * vam)
15810 {
15811   vl_api_ipfix_classify_stream_dump_t *mp;
15812   f64 timeout;
15813
15814   /* Construct the API message */
15815   M (IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump);
15816   mp->context = 0;
15817
15818   S;
15819   W;
15820   /* NOTREACHED */
15821   return 0;
15822 }
15823
15824 static void
15825   vl_api_ipfix_classify_stream_details_t_handler
15826   (vl_api_ipfix_classify_stream_details_t * mp)
15827 {
15828   vat_main_t *vam = &vat_main;
15829   print (vam->ofp, "domain_id %d, src_port %d",
15830          ntohl (mp->domain_id), ntohs (mp->src_port));
15831   vam->retval = 0;
15832   vam->result_ready = 1;
15833 }
15834
15835 static void
15836   vl_api_ipfix_classify_stream_details_t_handler_json
15837   (vl_api_ipfix_classify_stream_details_t * mp)
15838 {
15839   vat_main_t *vam = &vat_main;
15840   vat_json_node_t node;
15841
15842   vat_json_init_object (&node);
15843   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
15844   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
15845
15846   vat_json_print (vam->ofp, &node);
15847   vat_json_free (&node);
15848   vam->retval = 0;
15849   vam->result_ready = 1;
15850 }
15851
15852 static int
15853 api_ipfix_classify_table_dump (vat_main_t * vam)
15854 {
15855   vl_api_ipfix_classify_table_dump_t *mp;
15856   f64 timeout;
15857
15858   if (!vam->json_output)
15859     {
15860       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
15861              "transport_protocol");
15862     }
15863
15864   /* Construct the API message */
15865   M (IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump);
15866
15867   /* send it... */
15868   S;
15869
15870   /* Use a control ping for synchronization */
15871   {
15872     vl_api_control_ping_t *mp;
15873     M (CONTROL_PING, control_ping);
15874     S;
15875   }
15876   W;
15877 }
15878
15879 static void
15880   vl_api_ipfix_classify_table_details_t_handler
15881   (vl_api_ipfix_classify_table_details_t * mp)
15882 {
15883   vat_main_t *vam = &vat_main;
15884   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
15885          mp->transport_protocol);
15886 }
15887
15888 static void
15889   vl_api_ipfix_classify_table_details_t_handler_json
15890   (vl_api_ipfix_classify_table_details_t * mp)
15891 {
15892   vat_json_node_t *node = NULL;
15893   vat_main_t *vam = &vat_main;
15894
15895   if (VAT_JSON_ARRAY != vam->json_tree.type)
15896     {
15897       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15898       vat_json_init_array (&vam->json_tree);
15899     }
15900
15901   node = vat_json_array_add (&vam->json_tree);
15902   vat_json_init_object (node);
15903
15904   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
15905   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
15906   vat_json_object_add_uint (node, "transport_protocol",
15907                             mp->transport_protocol);
15908 }
15909
15910 static int
15911 api_sw_interface_span_enable_disable (vat_main_t * vam)
15912 {
15913   unformat_input_t *i = vam->input;
15914   vl_api_sw_interface_span_enable_disable_t *mp;
15915   f64 timeout;
15916   u32 src_sw_if_index = ~0;
15917   u32 dst_sw_if_index = ~0;
15918   u8 state = 3;
15919
15920   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15921     {
15922       if (unformat
15923           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
15924         ;
15925       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
15926         ;
15927       else
15928         if (unformat
15929             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
15930         ;
15931       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
15932         ;
15933       else if (unformat (i, "disable"))
15934         state = 0;
15935       else if (unformat (i, "rx"))
15936         state = 1;
15937       else if (unformat (i, "tx"))
15938         state = 2;
15939       else if (unformat (i, "both"))
15940         state = 3;
15941       else
15942         break;
15943     }
15944
15945   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, sw_interface_span_enable_disable);
15946
15947   mp->sw_if_index_from = htonl (src_sw_if_index);
15948   mp->sw_if_index_to = htonl (dst_sw_if_index);
15949   mp->state = state;
15950
15951   S;
15952   W;
15953   /* NOTREACHED */
15954   return 0;
15955 }
15956
15957 static void
15958 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
15959                                             * mp)
15960 {
15961   vat_main_t *vam = &vat_main;
15962   u8 *sw_if_from_name = 0;
15963   u8 *sw_if_to_name = 0;
15964   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
15965   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
15966   char *states[] = { "none", "rx", "tx", "both" };
15967   hash_pair_t *p;
15968
15969   /* *INDENT-OFF* */
15970   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
15971   ({
15972     if ((u32) p->value[0] == sw_if_index_from)
15973       {
15974         sw_if_from_name = (u8 *)(p->key);
15975         if (sw_if_to_name)
15976           break;
15977       }
15978     if ((u32) p->value[0] == sw_if_index_to)
15979       {
15980         sw_if_to_name = (u8 *)(p->key);
15981         if (sw_if_from_name)
15982           break;
15983       }
15984   }));
15985   /* *INDENT-ON* */
15986   print (vam->ofp, "%20s => %20s (%s)",
15987          sw_if_from_name, sw_if_to_name, states[mp->state]);
15988 }
15989
15990 static void
15991   vl_api_sw_interface_span_details_t_handler_json
15992   (vl_api_sw_interface_span_details_t * mp)
15993 {
15994   vat_main_t *vam = &vat_main;
15995   vat_json_node_t *node = NULL;
15996   u8 *sw_if_from_name = 0;
15997   u8 *sw_if_to_name = 0;
15998   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
15999   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16000   hash_pair_t *p;
16001
16002   /* *INDENT-OFF* */
16003   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16004   ({
16005     if ((u32) p->value[0] == sw_if_index_from)
16006       {
16007         sw_if_from_name = (u8 *)(p->key);
16008         if (sw_if_to_name)
16009           break;
16010       }
16011     if ((u32) p->value[0] == sw_if_index_to)
16012       {
16013         sw_if_to_name = (u8 *)(p->key);
16014         if (sw_if_from_name)
16015           break;
16016       }
16017   }));
16018   /* *INDENT-ON* */
16019
16020   if (VAT_JSON_ARRAY != vam->json_tree.type)
16021     {
16022       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16023       vat_json_init_array (&vam->json_tree);
16024     }
16025   node = vat_json_array_add (&vam->json_tree);
16026
16027   vat_json_init_object (node);
16028   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
16029   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
16030   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
16031   vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
16032   vat_json_object_add_uint (node, "state", mp->state);
16033 }
16034
16035 static int
16036 api_sw_interface_span_dump (vat_main_t * vam)
16037 {
16038   vl_api_sw_interface_span_dump_t *mp;
16039   f64 timeout;
16040
16041   M (SW_INTERFACE_SPAN_DUMP, sw_interface_span_dump);
16042   S;
16043
16044   /* Use a control ping for synchronization */
16045   {
16046     vl_api_control_ping_t *mp;
16047     M (CONTROL_PING, control_ping);
16048     S;
16049   }
16050   W;
16051 }
16052
16053 int
16054 api_pg_create_interface (vat_main_t * vam)
16055 {
16056   unformat_input_t *input = vam->input;
16057   vl_api_pg_create_interface_t *mp;
16058   f64 timeout;
16059
16060   u32 if_id = ~0;
16061   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16062     {
16063       if (unformat (input, "if_id %d", &if_id))
16064         ;
16065       else
16066         break;
16067     }
16068   if (if_id == ~0)
16069     {
16070       errmsg ("missing pg interface index");
16071       return -99;
16072     }
16073
16074   /* Construct the API message */
16075   M (PG_CREATE_INTERFACE, pg_create_interface);
16076   mp->context = 0;
16077   mp->interface_id = ntohl (if_id);
16078
16079   S;
16080   W;
16081   /* NOTREACHED */
16082   return 0;
16083 }
16084
16085 int
16086 api_pg_capture (vat_main_t * vam)
16087 {
16088   unformat_input_t *input = vam->input;
16089   vl_api_pg_capture_t *mp;
16090   f64 timeout;
16091
16092   u32 if_id = ~0;
16093   u8 enable = 1;
16094   u32 count = 1;
16095   u8 pcap_file_set = 0;
16096   u8 *pcap_file = 0;
16097   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16098     {
16099       if (unformat (input, "if_id %d", &if_id))
16100         ;
16101       else if (unformat (input, "pcap %s", &pcap_file))
16102         pcap_file_set = 1;
16103       else if (unformat (input, "count %d", &count))
16104         ;
16105       else if (unformat (input, "disable"))
16106         enable = 0;
16107       else
16108         break;
16109     }
16110   if (if_id == ~0)
16111     {
16112       errmsg ("missing pg interface index");
16113       return -99;
16114     }
16115   if (pcap_file_set > 0)
16116     {
16117       if (vec_len (pcap_file) > 255)
16118         {
16119           errmsg ("pcap file name is too long");
16120           return -99;
16121         }
16122     }
16123
16124   u32 name_len = vec_len (pcap_file);
16125   /* Construct the API message */
16126   M (PG_CAPTURE, pg_capture);
16127   mp->context = 0;
16128   mp->interface_id = ntohl (if_id);
16129   mp->is_enabled = enable;
16130   mp->count = ntohl (count);
16131   mp->pcap_name_length = ntohl (name_len);
16132   if (pcap_file_set != 0)
16133     {
16134       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
16135     }
16136   vec_free (pcap_file);
16137
16138   S;
16139   W;
16140   /* NOTREACHED */
16141   return 0;
16142 }
16143
16144 int
16145 api_pg_enable_disable (vat_main_t * vam)
16146 {
16147   unformat_input_t *input = vam->input;
16148   vl_api_pg_enable_disable_t *mp;
16149   f64 timeout;
16150
16151   u8 enable = 1;
16152   u8 stream_name_set = 0;
16153   u8 *stream_name = 0;
16154   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16155     {
16156       if (unformat (input, "stream %s", &stream_name))
16157         stream_name_set = 1;
16158       else if (unformat (input, "disable"))
16159         enable = 0;
16160       else
16161         break;
16162     }
16163
16164   if (stream_name_set > 0)
16165     {
16166       if (vec_len (stream_name) > 255)
16167         {
16168           errmsg ("stream name too long");
16169           return -99;
16170         }
16171     }
16172
16173   u32 name_len = vec_len (stream_name);
16174   /* Construct the API message */
16175   M (PG_ENABLE_DISABLE, pg_enable_disable);
16176   mp->context = 0;
16177   mp->is_enabled = enable;
16178   if (stream_name_set != 0)
16179     {
16180       mp->stream_name_length = ntohl (name_len);
16181       clib_memcpy (mp->stream_name, stream_name, name_len);
16182     }
16183   vec_free (stream_name);
16184
16185   S;
16186   W;
16187   /* NOTREACHED */
16188   return 0;
16189 }
16190
16191 int
16192 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
16193 {
16194   unformat_input_t *input = vam->input;
16195   vl_api_ip_source_and_port_range_check_add_del_t *mp;
16196   f64 timeout;
16197
16198   u16 *low_ports = 0;
16199   u16 *high_ports = 0;
16200   u16 this_low;
16201   u16 this_hi;
16202   ip4_address_t ip4_addr;
16203   ip6_address_t ip6_addr;
16204   u32 length;
16205   u32 tmp, tmp2;
16206   u8 prefix_set = 0;
16207   u32 vrf_id = ~0;
16208   u8 is_add = 1;
16209   u8 is_ipv6 = 0;
16210
16211   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16212     {
16213       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
16214         {
16215           prefix_set = 1;
16216         }
16217       else
16218         if (unformat
16219             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
16220         {
16221           prefix_set = 1;
16222           is_ipv6 = 1;
16223         }
16224       else if (unformat (input, "vrf %d", &vrf_id))
16225         ;
16226       else if (unformat (input, "del"))
16227         is_add = 0;
16228       else if (unformat (input, "port %d", &tmp))
16229         {
16230           if (tmp == 0 || tmp > 65535)
16231             {
16232               errmsg ("port %d out of range", tmp);
16233               return -99;
16234             }
16235           this_low = tmp;
16236           this_hi = this_low + 1;
16237           vec_add1 (low_ports, this_low);
16238           vec_add1 (high_ports, this_hi);
16239         }
16240       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
16241         {
16242           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
16243             {
16244               errmsg ("incorrect range parameters");
16245               return -99;
16246             }
16247           this_low = tmp;
16248           /* Note: in debug CLI +1 is added to high before
16249              passing to real fn that does "the work"
16250              (ip_source_and_port_range_check_add_del).
16251              This fn is a wrapper around the binary API fn a
16252              control plane will call, which expects this increment
16253              to have occurred. Hence letting the binary API control
16254              plane fn do the increment for consistency between VAT
16255              and other control planes.
16256            */
16257           this_hi = tmp2;
16258           vec_add1 (low_ports, this_low);
16259           vec_add1 (high_ports, this_hi);
16260         }
16261       else
16262         break;
16263     }
16264
16265   if (prefix_set == 0)
16266     {
16267       errmsg ("<address>/<mask> not specified");
16268       return -99;
16269     }
16270
16271   if (vrf_id == ~0)
16272     {
16273       errmsg ("VRF ID required, not specified");
16274       return -99;
16275     }
16276
16277   if (vrf_id == 0)
16278     {
16279       errmsg
16280         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
16281       return -99;
16282     }
16283
16284   if (vec_len (low_ports) == 0)
16285     {
16286       errmsg ("At least one port or port range required");
16287       return -99;
16288     }
16289
16290   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
16291      ip_source_and_port_range_check_add_del);
16292
16293   mp->is_add = is_add;
16294
16295   if (is_ipv6)
16296     {
16297       mp->is_ipv6 = 1;
16298       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
16299     }
16300   else
16301     {
16302       mp->is_ipv6 = 0;
16303       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
16304     }
16305
16306   mp->mask_length = length;
16307   mp->number_of_ranges = vec_len (low_ports);
16308
16309   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
16310   vec_free (low_ports);
16311
16312   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
16313   vec_free (high_ports);
16314
16315   mp->vrf_id = ntohl (vrf_id);
16316
16317   S;
16318   W;
16319   /* NOTREACHED */
16320   return 0;
16321 }
16322
16323 int
16324 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
16325 {
16326   unformat_input_t *input = vam->input;
16327   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
16328   f64 timeout;
16329   u32 sw_if_index = ~0;
16330   int vrf_set = 0;
16331   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
16332   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
16333   u8 is_add = 1;
16334
16335   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16336     {
16337       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16338         ;
16339       else if (unformat (input, "sw_if_index %d", &sw_if_index))
16340         ;
16341       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
16342         vrf_set = 1;
16343       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
16344         vrf_set = 1;
16345       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
16346         vrf_set = 1;
16347       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
16348         vrf_set = 1;
16349       else if (unformat (input, "del"))
16350         is_add = 0;
16351       else
16352         break;
16353     }
16354
16355   if (sw_if_index == ~0)
16356     {
16357       errmsg ("Interface required but not specified");
16358       return -99;
16359     }
16360
16361   if (vrf_set == 0)
16362     {
16363       errmsg ("VRF ID required but not specified");
16364       return -99;
16365     }
16366
16367   if (tcp_out_vrf_id == 0
16368       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
16369     {
16370       errmsg
16371         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
16372       return -99;
16373     }
16374
16375   /* Construct the API message */
16376   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
16377      ip_source_and_port_range_check_interface_add_del);
16378
16379   mp->sw_if_index = ntohl (sw_if_index);
16380   mp->is_add = is_add;
16381   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
16382   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
16383   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
16384   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
16385
16386   /* send it... */
16387   S;
16388
16389   /* Wait for a reply... */
16390   W;
16391 }
16392
16393 static int
16394 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
16395 {
16396   unformat_input_t *i = vam->input;
16397   vl_api_ipsec_gre_add_del_tunnel_t *mp;
16398   f64 timeout;
16399   u32 local_sa_id = 0;
16400   u32 remote_sa_id = 0;
16401   ip4_address_t src_address;
16402   ip4_address_t dst_address;
16403   u8 is_add = 1;
16404
16405   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16406     {
16407       if (unformat (i, "local_sa %d", &local_sa_id))
16408         ;
16409       else if (unformat (i, "remote_sa %d", &remote_sa_id))
16410         ;
16411       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
16412         ;
16413       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
16414         ;
16415       else if (unformat (i, "del"))
16416         is_add = 0;
16417       else
16418         {
16419           clib_warning ("parse error '%U'", format_unformat_error, i);
16420           return -99;
16421         }
16422     }
16423
16424   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
16425
16426   mp->local_sa_id = ntohl (local_sa_id);
16427   mp->remote_sa_id = ntohl (remote_sa_id);
16428   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
16429   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
16430   mp->is_add = is_add;
16431
16432   S;
16433   W;
16434   /* NOTREACHED */
16435   return 0;
16436 }
16437
16438 static int
16439 api_punt (vat_main_t * vam)
16440 {
16441   unformat_input_t *i = vam->input;
16442   vl_api_punt_t *mp;
16443   f64 timeout;
16444   u32 ipv = ~0;
16445   u32 protocol = ~0;
16446   u32 port = ~0;
16447   int is_add = 1;
16448
16449   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16450     {
16451       if (unformat (i, "ip %d", &ipv))
16452         ;
16453       else if (unformat (i, "protocol %d", &protocol))
16454         ;
16455       else if (unformat (i, "port %d", &port))
16456         ;
16457       else if (unformat (i, "del"))
16458         is_add = 0;
16459       else
16460         {
16461           clib_warning ("parse error '%U'", format_unformat_error, i);
16462           return -99;
16463         }
16464     }
16465
16466   M (PUNT, punt);
16467
16468   mp->is_add = (u8) is_add;
16469   mp->ipv = (u8) ipv;
16470   mp->l4_protocol = (u8) protocol;
16471   mp->l4_port = htons ((u16) port);
16472
16473   S;
16474   W;
16475   /* NOTREACHED */
16476   return 0;
16477 }
16478
16479 static void vl_api_ipsec_gre_tunnel_details_t_handler
16480   (vl_api_ipsec_gre_tunnel_details_t * mp)
16481 {
16482   vat_main_t *vam = &vat_main;
16483
16484   print (vam->ofp, "%11d%15U%15U%14d%14d",
16485          ntohl (mp->sw_if_index),
16486          format_ip4_address, &mp->src_address,
16487          format_ip4_address, &mp->dst_address,
16488          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
16489 }
16490
16491 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
16492   (vl_api_ipsec_gre_tunnel_details_t * mp)
16493 {
16494   vat_main_t *vam = &vat_main;
16495   vat_json_node_t *node = NULL;
16496   struct in_addr ip4;
16497
16498   if (VAT_JSON_ARRAY != vam->json_tree.type)
16499     {
16500       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16501       vat_json_init_array (&vam->json_tree);
16502     }
16503   node = vat_json_array_add (&vam->json_tree);
16504
16505   vat_json_init_object (node);
16506   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
16507   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
16508   vat_json_object_add_ip4 (node, "src_address", ip4);
16509   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
16510   vat_json_object_add_ip4 (node, "dst_address", ip4);
16511   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
16512   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
16513 }
16514
16515 static int
16516 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
16517 {
16518   unformat_input_t *i = vam->input;
16519   vl_api_ipsec_gre_tunnel_dump_t *mp;
16520   f64 timeout;
16521   u32 sw_if_index;
16522   u8 sw_if_index_set = 0;
16523
16524   /* Parse args required to build the message */
16525   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16526     {
16527       if (unformat (i, "sw_if_index %d", &sw_if_index))
16528         sw_if_index_set = 1;
16529       else
16530         break;
16531     }
16532
16533   if (sw_if_index_set == 0)
16534     {
16535       sw_if_index = ~0;
16536     }
16537
16538   if (!vam->json_output)
16539     {
16540       print (vam->ofp, "%11s%15s%15s%14s%14s",
16541              "sw_if_index", "src_address", "dst_address",
16542              "local_sa_id", "remote_sa_id");
16543     }
16544
16545   /* Get list of gre-tunnel interfaces */
16546   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
16547
16548   mp->sw_if_index = htonl (sw_if_index);
16549
16550   S;
16551
16552   /* Use a control ping for synchronization */
16553   {
16554     vl_api_control_ping_t *mp;
16555     M (CONTROL_PING, control_ping);
16556     S;
16557   }
16558   W;
16559 }
16560
16561 static int
16562 api_delete_subif (vat_main_t * vam)
16563 {
16564   unformat_input_t *i = vam->input;
16565   vl_api_delete_subif_t *mp;
16566   f64 timeout;
16567   u32 sw_if_index = ~0;
16568
16569   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16570     {
16571       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16572         ;
16573       if (unformat (i, "sw_if_index %d", &sw_if_index))
16574         ;
16575       else
16576         break;
16577     }
16578
16579   if (sw_if_index == ~0)
16580     {
16581       errmsg ("missing sw_if_index");
16582       return -99;
16583     }
16584
16585   /* Construct the API message */
16586   M (DELETE_SUBIF, delete_subif);
16587   mp->sw_if_index = ntohl (sw_if_index);
16588
16589   S;
16590   W;
16591 }
16592
16593 #define foreach_pbb_vtr_op      \
16594 _("disable",  L2_VTR_DISABLED)  \
16595 _("pop",  L2_VTR_POP_2)         \
16596 _("push",  L2_VTR_PUSH_2)
16597
16598 static int
16599 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
16600 {
16601   unformat_input_t *i = vam->input;
16602   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
16603   f64 timeout;
16604   u32 sw_if_index = ~0, vtr_op = ~0;
16605   u16 outer_tag = ~0;
16606   u8 dmac[6], smac[6];
16607   u8 dmac_set = 0, smac_set = 0;
16608   u16 vlanid = 0;
16609   u32 sid = ~0;
16610   u32 tmp;
16611
16612   /* Shut up coverity */
16613   memset (dmac, 0, sizeof (dmac));
16614   memset (smac, 0, sizeof (smac));
16615
16616   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16617     {
16618       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16619         ;
16620       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16621         ;
16622       else if (unformat (i, "vtr_op %d", &vtr_op))
16623         ;
16624 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
16625       foreach_pbb_vtr_op
16626 #undef _
16627         else if (unformat (i, "translate_pbb_stag"))
16628         {
16629           if (unformat (i, "%d", &tmp))
16630             {
16631               vtr_op = L2_VTR_TRANSLATE_2_1;
16632               outer_tag = tmp;
16633             }
16634           else
16635             {
16636               errmsg
16637                 ("translate_pbb_stag operation requires outer tag definition");
16638               return -99;
16639             }
16640         }
16641       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
16642         dmac_set++;
16643       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
16644         smac_set++;
16645       else if (unformat (i, "sid %d", &sid))
16646         ;
16647       else if (unformat (i, "vlanid %d", &tmp))
16648         vlanid = tmp;
16649       else
16650         {
16651           clib_warning ("parse error '%U'", format_unformat_error, i);
16652           return -99;
16653         }
16654     }
16655
16656   if ((sw_if_index == ~0) || (vtr_op == ~0))
16657     {
16658       errmsg ("missing sw_if_index or vtr operation");
16659       return -99;
16660     }
16661   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
16662       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
16663     {
16664       errmsg
16665         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
16666       return -99;
16667     }
16668
16669   M (L2_INTERFACE_PBB_TAG_REWRITE, l2_interface_pbb_tag_rewrite);
16670   mp->sw_if_index = ntohl (sw_if_index);
16671   mp->vtr_op = ntohl (vtr_op);
16672   mp->outer_tag = ntohs (outer_tag);
16673   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
16674   clib_memcpy (mp->b_smac, smac, sizeof (smac));
16675   mp->b_vlanid = ntohs (vlanid);
16676   mp->i_sid = ntohl (sid);
16677
16678   S;
16679   W;
16680   /* NOTREACHED */
16681   return 0;
16682 }
16683
16684 static int
16685 api_flow_classify_set_interface (vat_main_t * vam)
16686 {
16687   unformat_input_t *i = vam->input;
16688   vl_api_flow_classify_set_interface_t *mp;
16689   f64 timeout;
16690   u32 sw_if_index;
16691   int sw_if_index_set;
16692   u32 ip4_table_index = ~0;
16693   u32 ip6_table_index = ~0;
16694   u8 is_add = 1;
16695
16696   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16697     {
16698       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16699         sw_if_index_set = 1;
16700       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16701         sw_if_index_set = 1;
16702       else if (unformat (i, "del"))
16703         is_add = 0;
16704       else if (unformat (i, "ip4-table %d", &ip4_table_index))
16705         ;
16706       else if (unformat (i, "ip6-table %d", &ip6_table_index))
16707         ;
16708       else
16709         {
16710           clib_warning ("parse error '%U'", format_unformat_error, i);
16711           return -99;
16712         }
16713     }
16714
16715   if (sw_if_index_set == 0)
16716     {
16717       errmsg ("missing interface name or sw_if_index");
16718       return -99;
16719     }
16720
16721   M (FLOW_CLASSIFY_SET_INTERFACE, flow_classify_set_interface);
16722
16723   mp->sw_if_index = ntohl (sw_if_index);
16724   mp->ip4_table_index = ntohl (ip4_table_index);
16725   mp->ip6_table_index = ntohl (ip6_table_index);
16726   mp->is_add = is_add;
16727
16728   S;
16729   W;
16730   /* NOTREACHED */
16731   return 0;
16732 }
16733
16734 static int
16735 api_flow_classify_dump (vat_main_t * vam)
16736 {
16737   unformat_input_t *i = vam->input;
16738   vl_api_flow_classify_dump_t *mp;
16739   f64 timeout = ~0;
16740   u8 type = FLOW_CLASSIFY_N_TABLES;
16741
16742   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
16743     ;
16744   else
16745     {
16746       errmsg ("classify table type must be specified");
16747       return -99;
16748     }
16749
16750   if (!vam->json_output)
16751     {
16752       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
16753     }
16754
16755   M (FLOW_CLASSIFY_DUMP, flow_classify_dump);
16756   mp->type = type;
16757   /* send it... */
16758   S;
16759
16760   /* Use a control ping for synchronization */
16761   {
16762     vl_api_control_ping_t *mp;
16763     M (CONTROL_PING, control_ping);
16764     S;
16765   }
16766   /* Wait for a reply... */
16767   W;
16768
16769   /* NOTREACHED */
16770   return 0;
16771 }
16772
16773 static int
16774 api_feature_enable_disable (vat_main_t * vam)
16775 {
16776   unformat_input_t *i = vam->input;
16777   vl_api_feature_enable_disable_t *mp;
16778   f64 timeout;
16779   u8 *arc_name = 0;
16780   u8 *feature_name = 0;
16781   u32 sw_if_index = ~0;
16782   u8 enable = 1;
16783
16784   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16785     {
16786       if (unformat (i, "arc_name %s", &arc_name))
16787         ;
16788       else if (unformat (i, "feature_name %s", &feature_name))
16789         ;
16790       else
16791         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16792         ;
16793       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16794         ;
16795       else if (unformat (i, "disable"))
16796         enable = 0;
16797       else
16798         break;
16799     }
16800
16801   if (arc_name == 0)
16802     {
16803       errmsg ("missing arc name");
16804       return -99;
16805     }
16806   if (vec_len (arc_name) > 63)
16807     {
16808       errmsg ("arc name too long");
16809     }
16810
16811   if (feature_name == 0)
16812     {
16813       errmsg ("missing feature name");
16814       return -99;
16815     }
16816   if (vec_len (feature_name) > 63)
16817     {
16818       errmsg ("feature name too long");
16819     }
16820
16821   if (sw_if_index == ~0)
16822     {
16823       errmsg ("missing interface name or sw_if_index");
16824       return -99;
16825     }
16826
16827   /* Construct the API message */
16828   M (FEATURE_ENABLE_DISABLE, feature_enable_disable);
16829   mp->sw_if_index = ntohl (sw_if_index);
16830   mp->enable = enable;
16831   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
16832   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
16833   vec_free (arc_name);
16834   vec_free (feature_name);
16835
16836   S;
16837   W;
16838 }
16839
16840 static int
16841 api_sw_interface_tag_add_del (vat_main_t * vam)
16842 {
16843   unformat_input_t *i = vam->input;
16844   vl_api_sw_interface_tag_add_del_t *mp;
16845   f64 timeout;
16846   u32 sw_if_index = ~0;
16847   u8 *tag = 0;
16848   u8 enable = 1;
16849
16850   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16851     {
16852       if (unformat (i, "tag %s", &tag))
16853         ;
16854       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16855         ;
16856       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16857         ;
16858       else if (unformat (i, "del"))
16859         enable = 0;
16860       else
16861         break;
16862     }
16863
16864   if (sw_if_index == ~0)
16865     {
16866       errmsg ("missing interface name or sw_if_index");
16867       return -99;
16868     }
16869
16870   if (enable && (tag == 0))
16871     {
16872       errmsg ("no tag specified");
16873       return -99;
16874     }
16875
16876   /* Construct the API message */
16877   M (SW_INTERFACE_TAG_ADD_DEL, sw_interface_tag_add_del);
16878   mp->sw_if_index = ntohl (sw_if_index);
16879   mp->is_add = enable;
16880   if (enable)
16881     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
16882   vec_free (tag);
16883
16884   S;
16885   W;
16886 }
16887
16888 static void vl_api_l2_xconnect_details_t_handler
16889   (vl_api_l2_xconnect_details_t * mp)
16890 {
16891   vat_main_t *vam = &vat_main;
16892
16893   print (vam->ofp, "%15d%15d",
16894          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
16895 }
16896
16897 static void vl_api_l2_xconnect_details_t_handler_json
16898   (vl_api_l2_xconnect_details_t * mp)
16899 {
16900   vat_main_t *vam = &vat_main;
16901   vat_json_node_t *node = NULL;
16902
16903   if (VAT_JSON_ARRAY != vam->json_tree.type)
16904     {
16905       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16906       vat_json_init_array (&vam->json_tree);
16907     }
16908   node = vat_json_array_add (&vam->json_tree);
16909
16910   vat_json_init_object (node);
16911   vat_json_object_add_uint (node, "rx_sw_if_index",
16912                             ntohl (mp->rx_sw_if_index));
16913   vat_json_object_add_uint (node, "tx_sw_if_index",
16914                             ntohl (mp->tx_sw_if_index));
16915 }
16916
16917 static int
16918 api_l2_xconnect_dump (vat_main_t * vam)
16919 {
16920   vl_api_l2_xconnect_dump_t *mp;
16921   f64 timeout;
16922
16923   if (!vam->json_output)
16924     {
16925       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
16926     }
16927
16928   M (L2_XCONNECT_DUMP, l2_xconnect_dump);
16929
16930   S;
16931
16932   /* Use a control ping for synchronization */
16933   {
16934     vl_api_control_ping_t *mp;
16935     M (CONTROL_PING, control_ping);
16936     S;
16937   }
16938   W;
16939 }
16940
16941 static int
16942 api_sw_interface_set_mtu (vat_main_t * vam)
16943 {
16944   unformat_input_t *i = vam->input;
16945   vl_api_sw_interface_set_mtu_t *mp;
16946   f64 timeout;
16947   u32 sw_if_index = ~0;
16948   u32 mtu = 0;
16949
16950   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16951     {
16952       if (unformat (i, "mtu %d", &mtu))
16953         ;
16954       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16955         ;
16956       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16957         ;
16958       else
16959         break;
16960     }
16961
16962   if (sw_if_index == ~0)
16963     {
16964       errmsg ("missing interface name or sw_if_index");
16965       return -99;
16966     }
16967
16968   if (mtu == 0)
16969     {
16970       errmsg ("no mtu specified");
16971       return -99;
16972     }
16973
16974   /* Construct the API message */
16975   M (SW_INTERFACE_SET_MTU, sw_interface_set_mtu);
16976   mp->sw_if_index = ntohl (sw_if_index);
16977   mp->mtu = ntohs ((u16) mtu);
16978
16979   S;
16980   W;
16981 }
16982
16983
16984 static int
16985 q_or_quit (vat_main_t * vam)
16986 {
16987   longjmp (vam->jump_buf, 1);
16988   return 0;                     /* not so much */
16989 }
16990
16991 static int
16992 q (vat_main_t * vam)
16993 {
16994   return q_or_quit (vam);
16995 }
16996
16997 static int
16998 quit (vat_main_t * vam)
16999 {
17000   return q_or_quit (vam);
17001 }
17002
17003 static int
17004 comment (vat_main_t * vam)
17005 {
17006   return 0;
17007 }
17008
17009 static int
17010 cmd_cmp (void *a1, void *a2)
17011 {
17012   u8 **c1 = a1;
17013   u8 **c2 = a2;
17014
17015   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
17016 }
17017
17018 static int
17019 help (vat_main_t * vam)
17020 {
17021   u8 **cmds = 0;
17022   u8 *name = 0;
17023   hash_pair_t *p;
17024   unformat_input_t *i = vam->input;
17025   int j;
17026
17027   if (unformat (i, "%s", &name))
17028     {
17029       uword *hs;
17030
17031       vec_add1 (name, 0);
17032
17033       hs = hash_get_mem (vam->help_by_name, name);
17034       if (hs)
17035         print (vam->ofp, "usage: %s %s", name, hs[0]);
17036       else
17037         print (vam->ofp, "No such msg / command '%s'", name);
17038       vec_free (name);
17039       return 0;
17040     }
17041
17042   print (vam->ofp, "Help is available for the following:");
17043
17044     /* *INDENT-OFF* */
17045     hash_foreach_pair (p, vam->function_by_name,
17046     ({
17047       vec_add1 (cmds, (u8 *)(p->key));
17048     }));
17049     /* *INDENT-ON* */
17050
17051   vec_sort_with_function (cmds, cmd_cmp);
17052
17053   for (j = 0; j < vec_len (cmds); j++)
17054     print (vam->ofp, "%s", cmds[j]);
17055
17056   vec_free (cmds);
17057   return 0;
17058 }
17059
17060 static int
17061 set (vat_main_t * vam)
17062 {
17063   u8 *name = 0, *value = 0;
17064   unformat_input_t *i = vam->input;
17065
17066   if (unformat (i, "%s", &name))
17067     {
17068       /* The input buffer is a vector, not a string. */
17069       value = vec_dup (i->buffer);
17070       vec_delete (value, i->index, 0);
17071       /* Almost certainly has a trailing newline */
17072       if (value[vec_len (value) - 1] == '\n')
17073         value[vec_len (value) - 1] = 0;
17074       /* Make sure it's a proper string, one way or the other */
17075       vec_add1 (value, 0);
17076       (void) clib_macro_set_value (&vam->macro_main,
17077                                    (char *) name, (char *) value);
17078     }
17079   else
17080     errmsg ("usage: set <name> <value>");
17081
17082   vec_free (name);
17083   vec_free (value);
17084   return 0;
17085 }
17086
17087 static int
17088 unset (vat_main_t * vam)
17089 {
17090   u8 *name = 0;
17091
17092   if (unformat (vam->input, "%s", &name))
17093     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
17094       errmsg ("unset: %s wasn't set", name);
17095   vec_free (name);
17096   return 0;
17097 }
17098
17099 typedef struct
17100 {
17101   u8 *name;
17102   u8 *value;
17103 } macro_sort_t;
17104
17105
17106 static int
17107 macro_sort_cmp (void *a1, void *a2)
17108 {
17109   macro_sort_t *s1 = a1;
17110   macro_sort_t *s2 = a2;
17111
17112   return strcmp ((char *) (s1->name), (char *) (s2->name));
17113 }
17114
17115 static int
17116 dump_macro_table (vat_main_t * vam)
17117 {
17118   macro_sort_t *sort_me = 0, *sm;
17119   int i;
17120   hash_pair_t *p;
17121
17122     /* *INDENT-OFF* */
17123     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
17124     ({
17125       vec_add2 (sort_me, sm, 1);
17126       sm->name = (u8 *)(p->key);
17127       sm->value = (u8 *) (p->value[0]);
17128     }));
17129     /* *INDENT-ON* */
17130
17131   vec_sort_with_function (sort_me, macro_sort_cmp);
17132
17133   if (vec_len (sort_me))
17134     print (vam->ofp, "%-15s%s", "Name", "Value");
17135   else
17136     print (vam->ofp, "The macro table is empty...");
17137
17138   for (i = 0; i < vec_len (sort_me); i++)
17139     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
17140   return 0;
17141 }
17142
17143 static int
17144 dump_node_table (vat_main_t * vam)
17145 {
17146   int i, j;
17147   vlib_node_t *node, *next_node;
17148
17149   if (vec_len (vam->graph_nodes) == 0)
17150     {
17151       print (vam->ofp, "Node table empty, issue get_node_graph...");
17152       return 0;
17153     }
17154
17155   for (i = 0; i < vec_len (vam->graph_nodes); i++)
17156     {
17157       node = vam->graph_nodes[i];
17158       print (vam->ofp, "[%d] %s", i, node->name);
17159       for (j = 0; j < vec_len (node->next_nodes); j++)
17160         {
17161           if (node->next_nodes[j] != ~0)
17162             {
17163               next_node = vam->graph_nodes[node->next_nodes[j]];
17164               print (vam->ofp, "  [%d] %s", j, next_node->name);
17165             }
17166         }
17167     }
17168   return 0;
17169 }
17170
17171 static int
17172 value_sort_cmp (void *a1, void *a2)
17173 {
17174   name_sort_t *n1 = a1;
17175   name_sort_t *n2 = a2;
17176
17177   if (n1->value < n2->value)
17178     return -1;
17179   if (n1->value > n2->value)
17180     return 1;
17181   return 0;
17182 }
17183
17184
17185 static int
17186 dump_msg_api_table (vat_main_t * vam)
17187 {
17188   api_main_t *am = &api_main;
17189   name_sort_t *nses = 0, *ns;
17190   hash_pair_t *hp;
17191   int i;
17192
17193   /* *INDENT-OFF* */
17194   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
17195   ({
17196     vec_add2 (nses, ns, 1);
17197     ns->name = (u8 *)(hp->key);
17198     ns->value = (u32) hp->value[0];
17199   }));
17200   /* *INDENT-ON* */
17201
17202   vec_sort_with_function (nses, value_sort_cmp);
17203
17204   for (i = 0; i < vec_len (nses); i++)
17205     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
17206   vec_free (nses);
17207   return 0;
17208 }
17209
17210 static int
17211 get_msg_id (vat_main_t * vam)
17212 {
17213   u8 *name_and_crc;
17214   u32 message_index;
17215
17216   if (unformat (vam->input, "%s", &name_and_crc))
17217     {
17218       message_index = vl_api_get_msg_index (name_and_crc);
17219       if (message_index == ~0)
17220         {
17221           print (vam->ofp, " '%s' not found", name_and_crc);
17222           return 0;
17223         }
17224       print (vam->ofp, " '%s' has message index %d",
17225              name_and_crc, message_index);
17226       return 0;
17227     }
17228   errmsg ("name_and_crc required...");
17229   return 0;
17230 }
17231
17232 static int
17233 search_node_table (vat_main_t * vam)
17234 {
17235   unformat_input_t *line_input = vam->input;
17236   u8 *node_to_find;
17237   int j;
17238   vlib_node_t *node, *next_node;
17239   uword *p;
17240
17241   if (vam->graph_node_index_by_name == 0)
17242     {
17243       print (vam->ofp, "Node table empty, issue get_node_graph...");
17244       return 0;
17245     }
17246
17247   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
17248     {
17249       if (unformat (line_input, "%s", &node_to_find))
17250         {
17251           vec_add1 (node_to_find, 0);
17252           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
17253           if (p == 0)
17254             {
17255               print (vam->ofp, "%s not found...", node_to_find);
17256               goto out;
17257             }
17258           node = vam->graph_nodes[p[0]];
17259           print (vam->ofp, "[%d] %s", p[0], node->name);
17260           for (j = 0; j < vec_len (node->next_nodes); j++)
17261             {
17262               if (node->next_nodes[j] != ~0)
17263                 {
17264                   next_node = vam->graph_nodes[node->next_nodes[j]];
17265                   print (vam->ofp, "  [%d] %s", j, next_node->name);
17266                 }
17267             }
17268         }
17269
17270       else
17271         {
17272           clib_warning ("parse error '%U'", format_unformat_error,
17273                         line_input);
17274           return -99;
17275         }
17276
17277     out:
17278       vec_free (node_to_find);
17279
17280     }
17281
17282   return 0;
17283 }
17284
17285
17286 static int
17287 script (vat_main_t * vam)
17288 {
17289 #if (VPP_API_TEST_BUILTIN==0)
17290   u8 *s = 0;
17291   char *save_current_file;
17292   unformat_input_t save_input;
17293   jmp_buf save_jump_buf;
17294   u32 save_line_number;
17295
17296   FILE *new_fp, *save_ifp;
17297
17298   if (unformat (vam->input, "%s", &s))
17299     {
17300       new_fp = fopen ((char *) s, "r");
17301       if (new_fp == 0)
17302         {
17303           errmsg ("Couldn't open script file %s", s);
17304           vec_free (s);
17305           return -99;
17306         }
17307     }
17308   else
17309     {
17310       errmsg ("Missing script name");
17311       return -99;
17312     }
17313
17314   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
17315   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
17316   save_ifp = vam->ifp;
17317   save_line_number = vam->input_line_number;
17318   save_current_file = (char *) vam->current_file;
17319
17320   vam->input_line_number = 0;
17321   vam->ifp = new_fp;
17322   vam->current_file = s;
17323   do_one_file (vam);
17324
17325   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
17326   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
17327   vam->ifp = save_ifp;
17328   vam->input_line_number = save_line_number;
17329   vam->current_file = (u8 *) save_current_file;
17330   vec_free (s);
17331
17332   return 0;
17333 #else
17334   clib_warning ("use the exec command...");
17335   return -99;
17336 #endif
17337 }
17338
17339 static int
17340 echo (vat_main_t * vam)
17341 {
17342   print (vam->ofp, "%v", vam->input->buffer);
17343   return 0;
17344 }
17345
17346 /* List of API message constructors, CLI names map to api_xxx */
17347 #define foreach_vpe_api_msg                                             \
17348 _(create_loopback,"[mac <mac-addr>]")                                   \
17349 _(sw_interface_dump,"")                                                 \
17350 _(sw_interface_set_flags,                                               \
17351   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
17352 _(sw_interface_add_del_address,                                         \
17353   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
17354 _(sw_interface_set_table,                                               \
17355   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
17356 _(sw_interface_set_mpls_enable,                                         \
17357   "<intfc> | sw_if_index [disable | dis]")                              \
17358 _(sw_interface_set_vpath,                                               \
17359   "<intfc> | sw_if_index <id> enable | disable")                        \
17360 _(sw_interface_set_vxlan_bypass,                                        \
17361   "<intfc> | sw_if_index <id> [ip4 | ip6] enable | disable")            \
17362 _(sw_interface_set_l2_xconnect,                                         \
17363   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
17364   "enable | disable")                                                   \
17365 _(sw_interface_set_l2_bridge,                                           \
17366   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"               \
17367   "[shg <split-horizon-group>] [bvi]\n"                                 \
17368   "enable | disable")                                                   \
17369 _(bridge_domain_add_del,                                                \
17370   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n") \
17371 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
17372 _(l2fib_add_del,                                                        \
17373   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
17374 _(l2_flags,                                                             \
17375   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
17376 _(bridge_flags,                                                         \
17377   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
17378 _(tap_connect,                                                          \
17379   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
17380 _(tap_modify,                                                           \
17381   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
17382 _(tap_delete,                                                           \
17383   "<vpp-if-name> | sw_if_index <id>")                                   \
17384 _(sw_interface_tap_dump, "")                                            \
17385 _(ip_add_del_route,                                                     \
17386   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
17387   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
17388   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
17389   "[multipath] [count <n>]")                                            \
17390 _(mpls_route_add_del,                                                   \
17391   "<label> <eos> via <addr> [table-id <n>]\n"                           \
17392   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
17393   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
17394   "[multipath] [count <n>]")                                            \
17395 _(mpls_ip_bind_unbind,                                                  \
17396   "<label> <addr/len>")                                                 \
17397 _(mpls_tunnel_add_del,                                                  \
17398   " via <addr> [table-id <n>]\n"                                        \
17399   "sw_if_index <id>] [l2]  [del]")                                      \
17400 _(proxy_arp_add_del,                                                    \
17401   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
17402 _(proxy_arp_intfc_enable_disable,                                       \
17403   "<intfc> | sw_if_index <id> enable | disable")                        \
17404 _(sw_interface_set_unnumbered,                                          \
17405   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
17406 _(ip_neighbor_add_del,                                                  \
17407   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
17408   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
17409 _(reset_vrf, "vrf <id> [ipv6]")                                         \
17410 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
17411 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
17412   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
17413   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
17414   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
17415 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
17416 _(reset_fib, "vrf <n> [ipv6]")                                          \
17417 _(dhcp_proxy_config,                                                    \
17418   "svr <v46-address> src <v46-address>\n"                               \
17419    "insert-cid <n> [del]")                                              \
17420 _(dhcp_proxy_config_2,                                                  \
17421   "svr <v46-address> src <v46-address>\n"                               \
17422    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
17423 _(dhcp_proxy_set_vss,                                                   \
17424   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
17425 _(dhcp_client_config,                                                   \
17426   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
17427 _(set_ip_flow_hash,                                                     \
17428   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
17429 _(sw_interface_ip6_enable_disable,                                      \
17430   "<intfc> | sw_if_index <id> enable | disable")                        \
17431 _(sw_interface_ip6_set_link_local_address,                              \
17432   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
17433 _(sw_interface_ip6nd_ra_prefix,                                         \
17434   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
17435   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
17436   "[nolink] [isno]")                                                    \
17437 _(sw_interface_ip6nd_ra_config,                                         \
17438   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
17439   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
17440   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
17441 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
17442 _(l2_patch_add_del,                                                     \
17443   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
17444   "enable | disable")                                                   \
17445 _(sr_tunnel_add_del,                                                    \
17446   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
17447   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
17448   "[policy <policy_name>]")                                             \
17449 _(sr_policy_add_del,                                                    \
17450   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
17451 _(sr_multicast_map_add_del,                                             \
17452   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
17453 _(classify_add_del_table,                                               \
17454   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
17455   " [del] [del-chain] mask <mask-value>\n"                              \
17456   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
17457   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
17458 _(classify_add_del_session,                                             \
17459   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
17460   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
17461   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
17462   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
17463 _(classify_set_interface_ip_table,                                      \
17464   "<intfc> | sw_if_index <nn> table <nn>")                              \
17465 _(classify_set_interface_l2_tables,                                     \
17466   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17467   "  [other-table <nn>]")                                               \
17468 _(get_node_index, "node <node-name")                                    \
17469 _(add_node_next, "node <node-name> next <next-node-name>")              \
17470 _(l2tpv3_create_tunnel,                                                 \
17471   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
17472   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
17473   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
17474 _(l2tpv3_set_tunnel_cookies,                                            \
17475   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
17476   "[new_remote_cookie <nn>]\n")                                         \
17477 _(l2tpv3_interface_enable_disable,                                      \
17478   "<intfc> | sw_if_index <nn> enable | disable")                        \
17479 _(l2tpv3_set_lookup_key,                                                \
17480   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
17481 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
17482 _(vxlan_add_del_tunnel,                                                 \
17483   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
17484   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
17485   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
17486 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
17487 _(gre_add_del_tunnel,                                                   \
17488   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
17489 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
17490 _(l2_fib_clear_table, "")                                               \
17491 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
17492 _(l2_interface_vlan_tag_rewrite,                                        \
17493   "<intfc> | sw_if_index <nn> \n"                                       \
17494   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
17495   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
17496 _(create_vhost_user_if,                                                 \
17497         "socket <filename> [server] [renumber <dev_instance>] "         \
17498         "[mac <mac_address>]")                                          \
17499 _(modify_vhost_user_if,                                                 \
17500         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
17501         "[server] [renumber <dev_instance>]")                           \
17502 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
17503 _(sw_interface_vhost_user_dump, "")                                     \
17504 _(show_version, "")                                                     \
17505 _(vxlan_gpe_add_del_tunnel,                                             \
17506   "local <addr> remote <addr> vni <nn>\n"                               \
17507     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
17508   "[next-ethernet] [next-nsh]\n")                                       \
17509 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
17510 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
17511 _(interface_name_renumber,                                              \
17512   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
17513 _(input_acl_set_interface,                                              \
17514   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17515   "  [l2-table <nn>] [del]")                                            \
17516 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
17517 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
17518 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
17519 _(ip_dump, "ipv4 | ipv6")                                               \
17520 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
17521 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
17522   "  spid_id <n> ")                                                     \
17523 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
17524   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
17525   "  integ_alg <alg> integ_key <hex>")                                  \
17526 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
17527   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
17528   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
17529   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
17530 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
17531 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
17532 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
17533   "(auth_data 0x<data> | auth_data <data>)")                            \
17534 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
17535   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
17536 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
17537   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
17538   "(local|remote)")                                                     \
17539 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
17540 _(delete_loopback,"sw_if_index <nn>")                                   \
17541 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
17542 _(map_add_domain,                                                       \
17543   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
17544   "ip6-src <ip6addr> "                                                  \
17545   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
17546 _(map_del_domain, "index <n>")                                          \
17547 _(map_add_del_rule,                                                     \
17548   "index <n> psid <n> dst <ip6addr> [del]")                             \
17549 _(map_domain_dump, "")                                                  \
17550 _(map_rule_dump, "index <map-domain>")                                  \
17551 _(want_interface_events,  "enable|disable")                             \
17552 _(want_stats,"enable|disable")                                          \
17553 _(get_first_msg_id, "client <name>")                                    \
17554 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
17555 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
17556   "fib-id <nn> [ip4][ip6][default]")                                    \
17557 _(get_node_graph, " ")                                                  \
17558 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
17559 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
17560 _(ioam_disable, "")                                                     \
17561 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
17562                             " sw_if_index <sw_if_index> p <priority> "  \
17563                             "w <weight>] [del]")                        \
17564 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
17565                         "iface <intf> | sw_if_index <sw_if_index> "     \
17566                         "p <priority> w <weight> [del]")                \
17567 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
17568                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
17569                          "locator-set <locator_name> [del]"             \
17570                          "[key-id sha1|sha256 secret-key <secret-key>]") \
17571 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
17572   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
17573 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
17574 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
17575 _(lisp_gpe_enable_disable, "enable|disable")                            \
17576 _(lisp_enable_disable, "enable|disable")                                \
17577 _(lisp_map_register_enable_disable, "enable|disable")                   \
17578 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
17579 _(lisp_gpe_add_del_iface, "up|down")                                    \
17580 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
17581                                "[seid <seid>] "                         \
17582                                "rloc <locator> p <prio> "               \
17583                                "w <weight> [rloc <loc> ... ] "          \
17584                                "action <action> [del-all]")             \
17585 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
17586                           "<local-eid>")                                \
17587 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
17588 _(lisp_map_request_mode, "src-dst|dst-only")                            \
17589 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
17590 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
17591 _(lisp_locator_set_dump, "[local | remote]")                            \
17592 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
17593 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
17594                        "[local] | [remote]")                            \
17595 _(lisp_eid_table_vni_dump, "")                                          \
17596 _(lisp_eid_table_map_dump, "l2|l3")                                     \
17597 _(lisp_map_resolver_dump, "")                                           \
17598 _(lisp_map_server_dump, "")                                             \
17599 _(lisp_adjacencies_get, "vni <vni>")                                    \
17600 _(show_lisp_rloc_probe_state, "")                                       \
17601 _(show_lisp_map_register_state, "")                                     \
17602 _(show_lisp_status, "")                                                 \
17603 _(lisp_get_map_request_itr_rlocs, "")                                   \
17604 _(show_lisp_pitr, "")                                                   \
17605 _(show_lisp_map_request_mode, "")                                       \
17606 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
17607 _(af_packet_delete, "name <host interface name>")                       \
17608 _(policer_add_del, "name <policer name> <params> [del]")                \
17609 _(policer_dump, "[name <policer name>]")                                \
17610 _(policer_classify_set_interface,                                       \
17611   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17612   "  [l2-table <nn>] [del]")                                            \
17613 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
17614 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
17615     "[master|slave]")                                                   \
17616 _(netmap_delete, "name <interface name>")                               \
17617 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
17618 _(mpls_fib_dump, "")                                                    \
17619 _(classify_table_ids, "")                                               \
17620 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
17621 _(classify_table_info, "table_id <nn>")                                 \
17622 _(classify_session_dump, "table_id <nn>")                               \
17623 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
17624     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
17625     "[template_interval <nn>] [udp_checksum]")                          \
17626 _(ipfix_exporter_dump, "")                                              \
17627 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
17628 _(ipfix_classify_stream_dump, "")                                       \
17629 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
17630 _(ipfix_classify_table_dump, "")                                        \
17631 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
17632 _(sw_interface_span_dump, "")                                           \
17633 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
17634 _(pg_create_interface, "if_id <nn>")                                    \
17635 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
17636 _(pg_enable_disable, "[stream <id>] disable")                           \
17637 _(ip_source_and_port_range_check_add_del,                               \
17638   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
17639 _(ip_source_and_port_range_check_interface_add_del,                     \
17640   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
17641   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
17642 _(ipsec_gre_add_del_tunnel,                                             \
17643   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
17644 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
17645 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
17646 _(l2_interface_pbb_tag_rewrite,                                         \
17647   "<intfc> | sw_if_index <nn> \n"                                       \
17648   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
17649   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
17650 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
17651 _(flow_classify_set_interface,                                          \
17652   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
17653 _(flow_classify_dump, "type [ip4|ip6]")                                 \
17654 _(ip_fib_dump, "")                                                      \
17655 _(ip6_fib_dump, "")                                                     \
17656 _(feature_enable_disable, "arc_name <arc_name> "                        \
17657   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
17658 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
17659 "[disable]")                                                            \
17660 _(l2_xconnect_dump, "")                                                 \
17661 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
17662 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
17663 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")
17664
17665 #if DPDK > 0
17666 #define foreach_vpe_dpdk_api_msg                                        \
17667 _(sw_interface_set_dpdk_hqos_pipe,                                      \
17668   "rx <intfc> | sw_if_index <id> subport <subport-id> pipe <pipe-id>\n" \
17669   "profile <profile-id>\n")                                             \
17670 _(sw_interface_set_dpdk_hqos_subport,                                   \
17671   "rx <intfc> | sw_if_index <id> subport <subport-id> [rate <n>]\n"     \
17672   "[bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]\n") \
17673 _(sw_interface_set_dpdk_hqos_tctbl,                                     \
17674   "rx <intfc> | sw_if_index <id> entry <n> tc <n> queue <n>\n")
17675 #endif
17676
17677 /* List of command functions, CLI names map directly to functions */
17678 #define foreach_cli_function                                    \
17679 _(comment, "usage: comment <ignore-rest-of-line>")              \
17680 _(dump_interface_table, "usage: dump_interface_table")          \
17681 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
17682 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
17683 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
17684 _(dump_stats_table, "usage: dump_stats_table")                  \
17685 _(dump_macro_table, "usage: dump_macro_table ")                 \
17686 _(dump_node_table, "usage: dump_node_table")                    \
17687 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
17688 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
17689 _(echo, "usage: echo <message>")                                \
17690 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
17691 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
17692 _(help, "usage: help")                                          \
17693 _(q, "usage: quit")                                             \
17694 _(quit, "usage: quit")                                          \
17695 _(search_node_table, "usage: search_node_table <name>...")      \
17696 _(set, "usage: set <variable-name> <value>")                    \
17697 _(script, "usage: script <file-name>")                          \
17698 _(unset, "usage: unset <variable-name>")
17699
17700 #define _(N,n)                                  \
17701     static void vl_api_##n##_t_handler_uni      \
17702     (vl_api_##n##_t * mp)                       \
17703     {                                           \
17704         vat_main_t * vam = &vat_main;           \
17705         if (vam->json_output) {                 \
17706             vl_api_##n##_t_handler_json(mp);    \
17707         } else {                                \
17708             vl_api_##n##_t_handler(mp);         \
17709         }                                       \
17710     }
17711 foreach_vpe_api_reply_msg;
17712 #undef _
17713
17714 #if DPDK > 0
17715 #define _(N,n)                                  \
17716     static void vl_api_##n##_t_handler_uni      \
17717     (vl_api_##n##_t * mp)                       \
17718     {                                           \
17719         vat_main_t * vam = &vat_main;           \
17720         if (vam->json_output) {                 \
17721             vl_api_##n##_t_handler_json(mp);    \
17722         } else {                                \
17723             vl_api_##n##_t_handler(mp);         \
17724         }                                       \
17725     }
17726 foreach_vpe_dpdk_api_reply_msg;
17727 #undef _
17728 #endif
17729
17730 void
17731 vat_api_hookup (vat_main_t * vam)
17732 {
17733 #define _(N,n)                                                  \
17734     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
17735                            vl_api_##n##_t_handler_uni,          \
17736                            vl_noop_handler,                     \
17737                            vl_api_##n##_t_endian,               \
17738                            vl_api_##n##_t_print,                \
17739                            sizeof(vl_api_##n##_t), 1);
17740   foreach_vpe_api_reply_msg;
17741 #undef _
17742
17743 #if DPDK > 0
17744 #define _(N,n)                                                  \
17745     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
17746                            vl_api_##n##_t_handler_uni,          \
17747                            vl_noop_handler,                     \
17748                            vl_api_##n##_t_endian,               \
17749                            vl_api_##n##_t_print,                \
17750                            sizeof(vl_api_##n##_t), 1);
17751   foreach_vpe_dpdk_api_reply_msg;
17752 #undef _
17753 #endif
17754
17755 #if (VPP_API_TEST_BUILTIN==0)
17756   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
17757 #endif
17758
17759   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
17760
17761   vam->function_by_name = hash_create_string (0, sizeof (uword));
17762
17763   vam->help_by_name = hash_create_string (0, sizeof (uword));
17764
17765   /* API messages we can send */
17766 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
17767   foreach_vpe_api_msg;
17768 #undef _
17769 #if DPDK >0
17770 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
17771   foreach_vpe_dpdk_api_msg;
17772 #undef _
17773 #endif
17774
17775   /* Help strings */
17776 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17777   foreach_vpe_api_msg;
17778 #undef _
17779 #if DPDK >0
17780 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17781   foreach_vpe_dpdk_api_msg;
17782 #undef _
17783 #endif
17784
17785   /* CLI functions */
17786 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
17787   foreach_cli_function;
17788 #undef _
17789
17790   /* Help strings */
17791 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17792   foreach_cli_function;
17793 #undef _
17794 }
17795
17796 /*
17797  * fd.io coding-style-patch-verification: ON
17798  *
17799  * Local Variables:
17800  * eval: (c-set-style "gnu")
17801  * End:
17802  */