api: string type to convert to vector
[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 <vpp/api/types.h>
22 #include <vppinfra/socket.h>
23 #include <vlibapi/api.h>
24 #include <vlibmemory/api.h>
25 #include <vnet/ip/ip.h>
26 #include <vnet/ip/ip_neighbor.h>
27 #include <vnet/ip/ip_types_api.h>
28 #include <vnet/l2/l2_input.h>
29 #include <vnet/l2tp/l2tp.h>
30 #include <vnet/vxlan/vxlan.h>
31 #include <vnet/geneve/geneve.h>
32 #include <vnet/gre/gre.h>
33 #include <vnet/vxlan-gpe/vxlan_gpe.h>
34 #include <vnet/lisp-gpe/lisp_gpe.h>
35
36 #include <vpp/api/vpe_msg_enum.h>
37 #include <vnet/l2/l2_classify.h>
38 #include <vnet/l2/l2_vtr.h>
39 #include <vnet/classify/in_out_acl.h>
40 #include <vnet/classify/policer_classify.h>
41 #include <vnet/classify/flow_classify.h>
42 #include <vnet/mpls/mpls.h>
43 #include <vnet/ipsec/ipsec.h>
44 #include <inttypes.h>
45 #include <vnet/cop/cop.h>
46 #include <vnet/ip/ip6_hop_by_hop.h>
47 #include <vnet/ip/ip_source_and_port_range_check.h>
48 #include <vnet/policer/xlate.h>
49 #include <vnet/span/span.h>
50 #include <vnet/policer/policer.h>
51 #include <vnet/policer/police.h>
52 #include <vnet/mfib/mfib_types.h>
53 #include <vnet/dhcp/dhcp_proxy.h>
54 #include <vnet/bonding/node.h>
55 #include <vnet/qos/qos_types.h>
56 #include <vnet/ethernet/ethernet_types_api.h>
57 #include <vnet/ip/ip_types_api.h>
58 #include "vat/json_format.h"
59 #include <vnet/ip/ip_types_api.h>
60 #include <vnet/ethernet/ethernet_types_api.h>
61 #include <vlibapi/api_types_inlines.h>
62
63 #include <inttypes.h>
64 #include <sys/stat.h>
65
66 #define vl_typedefs             /* define message structures */
67 #include <vpp/api/vpe_all_api_h.h>
68 #undef vl_typedefs
69
70 /* declare message handlers for each api */
71
72 #define vl_endianfun            /* define message structures */
73 #include <vpp/api/vpe_all_api_h.h>
74 #undef vl_endianfun
75
76 /* instantiate all the print functions we know about */
77 #if VPP_API_TEST_BUILTIN == 0
78 #define vl_print(handle, ...)
79 #else
80 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
81 #endif
82 #define vl_printfun
83 #include <vpp/api/vpe_all_api_h.h>
84 #undef vl_printfun
85
86 #define __plugin_msg_base 0
87 #include <vlibapi/vat_helper_macros.h>
88
89 #if VPP_API_TEST_BUILTIN == 0
90 #include <netdb.h>
91
92 u32
93 vl (void *p)
94 {
95   return vec_len (p);
96 }
97
98 int
99 vat_socket_connect (vat_main_t * vam)
100 {
101   int rv;
102   vam->socket_client_main = &socket_client_main;
103   if ((rv = vl_socket_client_connect ((char *) vam->socket_name,
104                                       "vpp_api_test",
105                                       0 /* default socket rx, tx buffer */ )))
106     return rv;
107   /* vpp expects the client index in network order */
108   vam->my_client_index = htonl (socket_client_main.client_index);
109   return 0;
110 }
111 #else /* vpp built-in case, we don't do sockets... */
112 int
113 vat_socket_connect (vat_main_t * vam)
114 {
115   return 0;
116 }
117
118 int
119 vl_socket_client_read (int wait)
120 {
121   return -1;
122 };
123
124 int
125 vl_socket_client_write ()
126 {
127   return -1;
128 };
129
130 void *
131 vl_socket_client_msg_alloc (int nbytes)
132 {
133   return 0;
134 }
135 #endif
136
137
138 f64
139 vat_time_now (vat_main_t * vam)
140 {
141 #if VPP_API_TEST_BUILTIN
142   return vlib_time_now (vam->vlib_main);
143 #else
144   return clib_time_now (&vam->clib_time);
145 #endif
146 }
147
148 void
149 errmsg (char *fmt, ...)
150 {
151   vat_main_t *vam = &vat_main;
152   va_list va;
153   u8 *s;
154
155   va_start (va, fmt);
156   s = va_format (0, fmt, &va);
157   va_end (va);
158
159   vec_add1 (s, 0);
160
161 #if VPP_API_TEST_BUILTIN
162   vlib_cli_output (vam->vlib_main, (char *) s);
163 #else
164   {
165     if (vam->ifp != stdin)
166       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
167                vam->input_line_number);
168     fformat (vam->ofp, (char *) s);
169     fflush (vam->ofp);
170   }
171 #endif
172
173   vec_free (s);
174 }
175
176 #if VPP_API_TEST_BUILTIN == 0
177 static uword
178 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
179 {
180   vat_main_t *vam = va_arg (*args, vat_main_t *);
181   u32 *result = va_arg (*args, u32 *);
182   u8 *if_name;
183   uword *p;
184
185   if (!unformat (input, "%s", &if_name))
186     return 0;
187
188   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
189   if (p == 0)
190     return 0;
191   *result = p[0];
192   return 1;
193 }
194
195 static uword
196 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
197 {
198   return 0;
199 }
200
201 /* Parse an IP4 address %d.%d.%d.%d. */
202 uword
203 unformat_ip4_address (unformat_input_t * input, va_list * args)
204 {
205   u8 *result = va_arg (*args, u8 *);
206   unsigned a[4];
207
208   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
209     return 0;
210
211   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
212     return 0;
213
214   result[0] = a[0];
215   result[1] = a[1];
216   result[2] = a[2];
217   result[3] = a[3];
218
219   return 1;
220 }
221
222 uword
223 unformat_ethernet_address (unformat_input_t * input, va_list * args)
224 {
225   u8 *result = va_arg (*args, u8 *);
226   u32 i, a[6];
227
228   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
229                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
230     return 0;
231
232   /* Check range. */
233   for (i = 0; i < 6; i++)
234     if (a[i] >= (1 << 8))
235       return 0;
236
237   for (i = 0; i < 6; i++)
238     result[i] = a[i];
239
240   return 1;
241 }
242
243 /* Returns ethernet type as an int in host byte order. */
244 uword
245 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
246                                         va_list * args)
247 {
248   u16 *result = va_arg (*args, u16 *);
249   int type;
250
251   /* Numeric type. */
252   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
253     {
254       if (type >= (1 << 16))
255         return 0;
256       *result = type;
257       return 1;
258     }
259   return 0;
260 }
261
262 /* Parse an IP6 address. */
263 uword
264 unformat_ip6_address (unformat_input_t * input, va_list * args)
265 {
266   ip6_address_t *result = va_arg (*args, ip6_address_t *);
267   u16 hex_quads[8];
268   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
269   uword c, n_colon, double_colon_index;
270
271   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
272   double_colon_index = ARRAY_LEN (hex_quads);
273   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
274     {
275       hex_digit = 16;
276       if (c >= '0' && c <= '9')
277         hex_digit = c - '0';
278       else if (c >= 'a' && c <= 'f')
279         hex_digit = c + 10 - 'a';
280       else if (c >= 'A' && c <= 'F')
281         hex_digit = c + 10 - 'A';
282       else if (c == ':' && n_colon < 2)
283         n_colon++;
284       else
285         {
286           unformat_put_input (input);
287           break;
288         }
289
290       /* Too many hex quads. */
291       if (n_hex_quads >= ARRAY_LEN (hex_quads))
292         return 0;
293
294       if (hex_digit < 16)
295         {
296           hex_quad = (hex_quad << 4) | hex_digit;
297
298           /* Hex quad must fit in 16 bits. */
299           if (n_hex_digits >= 4)
300             return 0;
301
302           n_colon = 0;
303           n_hex_digits++;
304         }
305
306       /* Save position of :: */
307       if (n_colon == 2)
308         {
309           /* More than one :: ? */
310           if (double_colon_index < ARRAY_LEN (hex_quads))
311             return 0;
312           double_colon_index = n_hex_quads;
313         }
314
315       if (n_colon > 0 && n_hex_digits > 0)
316         {
317           hex_quads[n_hex_quads++] = hex_quad;
318           hex_quad = 0;
319           n_hex_digits = 0;
320         }
321     }
322
323   if (n_hex_digits > 0)
324     hex_quads[n_hex_quads++] = hex_quad;
325
326   {
327     word i;
328
329     /* Expand :: to appropriate number of zero hex quads. */
330     if (double_colon_index < ARRAY_LEN (hex_quads))
331       {
332         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
333
334         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
335           hex_quads[n_zero + i] = hex_quads[i];
336
337         for (i = 0; i < n_zero; i++)
338           hex_quads[double_colon_index + i] = 0;
339
340         n_hex_quads = ARRAY_LEN (hex_quads);
341       }
342
343     /* Too few hex quads given. */
344     if (n_hex_quads < ARRAY_LEN (hex_quads))
345       return 0;
346
347     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
348       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
349
350     return 1;
351   }
352 }
353
354 uword
355 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
356 {
357   u32 *r = va_arg (*args, u32 *);
358
359   if (0);
360 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
361   foreach_ipsec_policy_action
362 #undef _
363     else
364     return 0;
365   return 1;
366 }
367
368 u8 *
369 format_ipsec_crypto_alg (u8 * s, va_list * args)
370 {
371   u32 i = va_arg (*args, u32);
372   u8 *t = 0;
373
374   switch (i)
375     {
376 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
377       foreach_ipsec_crypto_alg
378 #undef _
379     default:
380       return format (s, "unknown");
381     }
382   return format (s, "%s", t);
383 }
384
385 u8 *
386 format_ipsec_integ_alg (u8 * s, va_list * args)
387 {
388   u32 i = va_arg (*args, u32);
389   u8 *t = 0;
390
391   switch (i)
392     {
393 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
394       foreach_ipsec_integ_alg
395 #undef _
396     default:
397       return format (s, "unknown");
398     }
399   return format (s, "%s", t);
400 }
401
402 #else /* VPP_API_TEST_BUILTIN == 1 */
403 static uword
404 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
405 {
406   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
407   vnet_main_t *vnm = vnet_get_main ();
408   u32 *result = va_arg (*args, u32 *);
409
410   return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
411 }
412
413 static uword
414 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
415 {
416   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
417   vnet_main_t *vnm = vnet_get_main ();
418   u32 *result = va_arg (*args, u32 *);
419
420   return unformat (input, "%U", unformat_vnet_hw_interface, vnm, result);
421 }
422
423 #endif /* VPP_API_TEST_BUILTIN */
424
425 uword
426 unformat_ipsec_api_crypto_alg (unformat_input_t * input, va_list * args)
427 {
428   u32 *r = va_arg (*args, u32 *);
429
430   if (0);
431 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_CRYPTO_ALG_##f;
432   foreach_ipsec_crypto_alg
433 #undef _
434     else
435     return 0;
436   return 1;
437 }
438
439 uword
440 unformat_ipsec_api_integ_alg (unformat_input_t * input, va_list * args)
441 {
442   u32 *r = va_arg (*args, u32 *);
443
444   if (0);
445 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_INTEG_ALG_##f;
446   foreach_ipsec_integ_alg
447 #undef _
448     else
449     return 0;
450   return 1;
451 }
452
453 static uword
454 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
455 {
456   u8 *r = va_arg (*args, u8 *);
457
458   if (unformat (input, "kbps"))
459     *r = SSE2_QOS_RATE_KBPS;
460   else if (unformat (input, "pps"))
461     *r = SSE2_QOS_RATE_PPS;
462   else
463     return 0;
464   return 1;
465 }
466
467 static uword
468 unformat_policer_round_type (unformat_input_t * input, va_list * args)
469 {
470   u8 *r = va_arg (*args, u8 *);
471
472   if (unformat (input, "closest"))
473     *r = SSE2_QOS_ROUND_TO_CLOSEST;
474   else if (unformat (input, "up"))
475     *r = SSE2_QOS_ROUND_TO_UP;
476   else if (unformat (input, "down"))
477     *r = SSE2_QOS_ROUND_TO_DOWN;
478   else
479     return 0;
480   return 1;
481 }
482
483 static uword
484 unformat_policer_type (unformat_input_t * input, va_list * args)
485 {
486   u8 *r = va_arg (*args, u8 *);
487
488   if (unformat (input, "1r2c"))
489     *r = SSE2_QOS_POLICER_TYPE_1R2C;
490   else if (unformat (input, "1r3c"))
491     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
492   else if (unformat (input, "2r3c-2698"))
493     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
494   else if (unformat (input, "2r3c-4115"))
495     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
496   else if (unformat (input, "2r3c-mef5cf1"))
497     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
498   else
499     return 0;
500   return 1;
501 }
502
503 static uword
504 unformat_dscp (unformat_input_t * input, va_list * va)
505 {
506   u8 *r = va_arg (*va, u8 *);
507
508   if (0);
509 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
510   foreach_vnet_dscp
511 #undef _
512     else
513     return 0;
514   return 1;
515 }
516
517 static uword
518 unformat_policer_action_type (unformat_input_t * input, va_list * va)
519 {
520   sse2_qos_pol_action_params_st *a
521     = va_arg (*va, sse2_qos_pol_action_params_st *);
522
523   if (unformat (input, "drop"))
524     a->action_type = SSE2_QOS_ACTION_DROP;
525   else if (unformat (input, "transmit"))
526     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
527   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
528     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
529   else
530     return 0;
531   return 1;
532 }
533
534 static uword
535 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
536 {
537   u32 *r = va_arg (*va, u32 *);
538   u32 tid;
539
540   if (unformat (input, "ip4"))
541     tid = POLICER_CLASSIFY_TABLE_IP4;
542   else if (unformat (input, "ip6"))
543     tid = POLICER_CLASSIFY_TABLE_IP6;
544   else if (unformat (input, "l2"))
545     tid = POLICER_CLASSIFY_TABLE_L2;
546   else
547     return 0;
548
549   *r = tid;
550   return 1;
551 }
552
553 static uword
554 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
555 {
556   u32 *r = va_arg (*va, u32 *);
557   u32 tid;
558
559   if (unformat (input, "ip4"))
560     tid = FLOW_CLASSIFY_TABLE_IP4;
561   else if (unformat (input, "ip6"))
562     tid = FLOW_CLASSIFY_TABLE_IP6;
563   else
564     return 0;
565
566   *r = tid;
567   return 1;
568 }
569
570 #if (VPP_API_TEST_BUILTIN==0)
571
572 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
573 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
574 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
575 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
576
577 uword
578 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
579 {
580   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
581   mfib_itf_attribute_t attr;
582
583   old = *iflags;
584   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
585   {
586     if (unformat (input, mfib_itf_flag_long_names[attr]))
587       *iflags |= (1 << attr);
588   }
589   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
590   {
591     if (unformat (input, mfib_itf_flag_names[attr]))
592       *iflags |= (1 << attr);
593   }
594
595   return (old == *iflags ? 0 : 1);
596 }
597
598 uword
599 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
600 {
601   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
602   mfib_entry_attribute_t attr;
603
604   old = *eflags;
605   FOR_EACH_MFIB_ATTRIBUTE (attr)
606   {
607     if (unformat (input, mfib_flag_long_names[attr]))
608       *eflags |= (1 << attr);
609   }
610   FOR_EACH_MFIB_ATTRIBUTE (attr)
611   {
612     if (unformat (input, mfib_flag_names[attr]))
613       *eflags |= (1 << attr);
614   }
615
616   return (old == *eflags ? 0 : 1);
617 }
618
619 u8 *
620 format_ip4_address (u8 * s, va_list * args)
621 {
622   u8 *a = va_arg (*args, u8 *);
623   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
624 }
625
626 u8 *
627 format_ip6_address (u8 * s, va_list * args)
628 {
629   ip6_address_t *a = va_arg (*args, ip6_address_t *);
630   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
631
632   i_max_n_zero = ARRAY_LEN (a->as_u16);
633   max_n_zeros = 0;
634   i_first_zero = i_max_n_zero;
635   n_zeros = 0;
636   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
637     {
638       u32 is_zero = a->as_u16[i] == 0;
639       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
640         {
641           i_first_zero = i;
642           n_zeros = 0;
643         }
644       n_zeros += is_zero;
645       if ((!is_zero && n_zeros > max_n_zeros)
646           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
647         {
648           i_max_n_zero = i_first_zero;
649           max_n_zeros = n_zeros;
650           i_first_zero = ARRAY_LEN (a->as_u16);
651           n_zeros = 0;
652         }
653     }
654
655   last_double_colon = 0;
656   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
657     {
658       if (i == i_max_n_zero && max_n_zeros > 1)
659         {
660           s = format (s, "::");
661           i += max_n_zeros - 1;
662           last_double_colon = 1;
663         }
664       else
665         {
666           s = format (s, "%s%x",
667                       (last_double_colon || i == 0) ? "" : ":",
668                       clib_net_to_host_u16 (a->as_u16[i]));
669           last_double_colon = 0;
670         }
671     }
672
673   return s;
674 }
675
676 /* Format an IP46 address. */
677 u8 *
678 format_ip46_address (u8 * s, va_list * args)
679 {
680   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
681   ip46_type_t type = va_arg (*args, ip46_type_t);
682   int is_ip4 = 1;
683
684   switch (type)
685     {
686     case IP46_TYPE_ANY:
687       is_ip4 = ip46_address_is_ip4 (ip46);
688       break;
689     case IP46_TYPE_IP4:
690       is_ip4 = 1;
691       break;
692     case IP46_TYPE_IP6:
693       is_ip4 = 0;
694       break;
695     }
696
697   return is_ip4 ?
698     format (s, "%U", format_ip4_address, &ip46->ip4) :
699     format (s, "%U", format_ip6_address, &ip46->ip6);
700 }
701
702 u8 *
703 format_ethernet_address (u8 * s, va_list * args)
704 {
705   u8 *a = va_arg (*args, u8 *);
706
707   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
708                  a[0], a[1], a[2], a[3], a[4], a[5]);
709 }
710 #endif
711
712 static void
713 increment_v4_address (ip4_address_t * a)
714 {
715   u32 v;
716
717   v = ntohl (a->as_u32) + 1;
718   a->as_u32 = ntohl (v);
719 }
720
721 static void
722 increment_vl_v4_address (vl_api_ip4_address_t * a)
723 {
724   u32 v;
725
726   v = *(u32 *) a;
727   v = ntohl (v);
728   v++;
729   v = ntohl (v);
730   clib_memcpy (a, &v, sizeof (v));
731 }
732
733 static void
734 increment_vl_address (vl_api_address_t * a)
735 {
736   if (ADDRESS_IP4 == a->af)
737     increment_vl_v4_address (&a->un.ip4);
738 }
739
740 static void
741 increment_v6_address (ip6_address_t * a)
742 {
743   u64 v0, v1;
744
745   v0 = clib_net_to_host_u64 (a->as_u64[0]);
746   v1 = clib_net_to_host_u64 (a->as_u64[1]);
747
748   v1 += 1;
749   if (v1 == 0)
750     v0 += 1;
751   a->as_u64[0] = clib_net_to_host_u64 (v0);
752   a->as_u64[1] = clib_net_to_host_u64 (v1);
753 }
754
755 static void
756 increment_mac_address (u8 * mac)
757 {
758   u64 tmp = *((u64 *) mac);
759   tmp = clib_net_to_host_u64 (tmp);
760   tmp += 1 << 16;               /* skip unused (least significant) octets */
761   tmp = clib_host_to_net_u64 (tmp);
762
763   clib_memcpy (mac, &tmp, 6);
764 }
765
766 static void vl_api_create_loopback_reply_t_handler
767   (vl_api_create_loopback_reply_t * mp)
768 {
769   vat_main_t *vam = &vat_main;
770   i32 retval = ntohl (mp->retval);
771
772   vam->retval = retval;
773   vam->regenerate_interface_table = 1;
774   vam->sw_if_index = ntohl (mp->sw_if_index);
775   vam->result_ready = 1;
776 }
777
778 static void vl_api_create_loopback_reply_t_handler_json
779   (vl_api_create_loopback_reply_t * mp)
780 {
781   vat_main_t *vam = &vat_main;
782   vat_json_node_t node;
783
784   vat_json_init_object (&node);
785   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
786   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
787
788   vat_json_print (vam->ofp, &node);
789   vat_json_free (&node);
790   vam->retval = ntohl (mp->retval);
791   vam->result_ready = 1;
792 }
793
794 static void vl_api_create_loopback_instance_reply_t_handler
795   (vl_api_create_loopback_instance_reply_t * mp)
796 {
797   vat_main_t *vam = &vat_main;
798   i32 retval = ntohl (mp->retval);
799
800   vam->retval = retval;
801   vam->regenerate_interface_table = 1;
802   vam->sw_if_index = ntohl (mp->sw_if_index);
803   vam->result_ready = 1;
804 }
805
806 static void vl_api_create_loopback_instance_reply_t_handler_json
807   (vl_api_create_loopback_instance_reply_t * mp)
808 {
809   vat_main_t *vam = &vat_main;
810   vat_json_node_t node;
811
812   vat_json_init_object (&node);
813   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
814   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
815
816   vat_json_print (vam->ofp, &node);
817   vat_json_free (&node);
818   vam->retval = ntohl (mp->retval);
819   vam->result_ready = 1;
820 }
821
822 static void vl_api_af_packet_create_reply_t_handler
823   (vl_api_af_packet_create_reply_t * mp)
824 {
825   vat_main_t *vam = &vat_main;
826   i32 retval = ntohl (mp->retval);
827
828   vam->retval = retval;
829   vam->regenerate_interface_table = 1;
830   vam->sw_if_index = ntohl (mp->sw_if_index);
831   vam->result_ready = 1;
832 }
833
834 static void vl_api_af_packet_create_reply_t_handler_json
835   (vl_api_af_packet_create_reply_t * mp)
836 {
837   vat_main_t *vam = &vat_main;
838   vat_json_node_t node;
839
840   vat_json_init_object (&node);
841   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
842   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
843
844   vat_json_print (vam->ofp, &node);
845   vat_json_free (&node);
846
847   vam->retval = ntohl (mp->retval);
848   vam->result_ready = 1;
849 }
850
851 static void vl_api_create_vlan_subif_reply_t_handler
852   (vl_api_create_vlan_subif_reply_t * mp)
853 {
854   vat_main_t *vam = &vat_main;
855   i32 retval = ntohl (mp->retval);
856
857   vam->retval = retval;
858   vam->regenerate_interface_table = 1;
859   vam->sw_if_index = ntohl (mp->sw_if_index);
860   vam->result_ready = 1;
861 }
862
863 static void vl_api_create_vlan_subif_reply_t_handler_json
864   (vl_api_create_vlan_subif_reply_t * mp)
865 {
866   vat_main_t *vam = &vat_main;
867   vat_json_node_t node;
868
869   vat_json_init_object (&node);
870   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
871   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
872
873   vat_json_print (vam->ofp, &node);
874   vat_json_free (&node);
875
876   vam->retval = ntohl (mp->retval);
877   vam->result_ready = 1;
878 }
879
880 static void vl_api_create_subif_reply_t_handler
881   (vl_api_create_subif_reply_t * mp)
882 {
883   vat_main_t *vam = &vat_main;
884   i32 retval = ntohl (mp->retval);
885
886   vam->retval = retval;
887   vam->regenerate_interface_table = 1;
888   vam->sw_if_index = ntohl (mp->sw_if_index);
889   vam->result_ready = 1;
890 }
891
892 static void vl_api_create_subif_reply_t_handler_json
893   (vl_api_create_subif_reply_t * mp)
894 {
895   vat_main_t *vam = &vat_main;
896   vat_json_node_t node;
897
898   vat_json_init_object (&node);
899   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
900   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
901
902   vat_json_print (vam->ofp, &node);
903   vat_json_free (&node);
904
905   vam->retval = ntohl (mp->retval);
906   vam->result_ready = 1;
907 }
908
909 static void vl_api_interface_name_renumber_reply_t_handler
910   (vl_api_interface_name_renumber_reply_t * mp)
911 {
912   vat_main_t *vam = &vat_main;
913   i32 retval = ntohl (mp->retval);
914
915   vam->retval = retval;
916   vam->regenerate_interface_table = 1;
917   vam->result_ready = 1;
918 }
919
920 static void vl_api_interface_name_renumber_reply_t_handler_json
921   (vl_api_interface_name_renumber_reply_t * mp)
922 {
923   vat_main_t *vam = &vat_main;
924   vat_json_node_t node;
925
926   vat_json_init_object (&node);
927   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
928
929   vat_json_print (vam->ofp, &node);
930   vat_json_free (&node);
931
932   vam->retval = ntohl (mp->retval);
933   vam->result_ready = 1;
934 }
935
936 /*
937  * Special-case: build the interface table, maintain
938  * the next loopback sw_if_index vbl.
939  */
940 static void vl_api_sw_interface_details_t_handler
941   (vl_api_sw_interface_details_t * mp)
942 {
943   vat_main_t *vam = &vat_main;
944   u8 *s = format (0, "%s%c", mp->interface_name, 0);
945
946   hash_set_mem (vam->sw_if_index_by_interface_name, s,
947                 ntohl (mp->sw_if_index));
948
949   /* In sub interface case, fill the sub interface table entry */
950   if (mp->sw_if_index != mp->sup_sw_if_index)
951     {
952       sw_interface_subif_t *sub = NULL;
953
954       vec_add2 (vam->sw_if_subif_table, sub, 1);
955
956       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
957       strncpy ((char *) sub->interface_name, (char *) s,
958                vec_len (sub->interface_name));
959       sub->sw_if_index = ntohl (mp->sw_if_index);
960       sub->sub_id = ntohl (mp->sub_id);
961
962       sub->sub_dot1ad = mp->sub_dot1ad;
963       sub->sub_number_of_tags = mp->sub_number_of_tags;
964       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
965       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
966       sub->sub_exact_match = mp->sub_exact_match;
967       sub->sub_default = mp->sub_default;
968       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
969       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
970
971       /* vlan tag rewrite */
972       sub->vtr_op = ntohl (mp->vtr_op);
973       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
974       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
975       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
976     }
977 }
978
979 static void vl_api_sw_interface_details_t_handler_json
980   (vl_api_sw_interface_details_t * mp)
981 {
982   vat_main_t *vam = &vat_main;
983   vat_json_node_t *node = NULL;
984
985   if (VAT_JSON_ARRAY != vam->json_tree.type)
986     {
987       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
988       vat_json_init_array (&vam->json_tree);
989     }
990   node = vat_json_array_add (&vam->json_tree);
991
992   vat_json_init_object (node);
993   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
994   vat_json_object_add_uint (node, "sup_sw_if_index",
995                             ntohl (mp->sup_sw_if_index));
996   vat_json_object_add_uint (node, "l2_address_length",
997                             ntohl (mp->l2_address_length));
998   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
999                              sizeof (mp->l2_address));
1000   vat_json_object_add_string_copy (node, "interface_name",
1001                                    mp->interface_name);
1002   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
1003   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
1004   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
1005   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
1006   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
1007   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
1008   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
1009   vat_json_object_add_uint (node, "sub_number_of_tags",
1010                             mp->sub_number_of_tags);
1011   vat_json_object_add_uint (node, "sub_outer_vlan_id",
1012                             ntohs (mp->sub_outer_vlan_id));
1013   vat_json_object_add_uint (node, "sub_inner_vlan_id",
1014                             ntohs (mp->sub_inner_vlan_id));
1015   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
1016   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
1017   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
1018                             mp->sub_outer_vlan_id_any);
1019   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
1020                             mp->sub_inner_vlan_id_any);
1021   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1022   vat_json_object_add_uint (node, "vtr_push_dot1q",
1023                             ntohl (mp->vtr_push_dot1q));
1024   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1025   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1026   if (mp->sub_dot1ah)
1027     {
1028       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1029                                        format (0, "%U",
1030                                                format_ethernet_address,
1031                                                &mp->b_dmac));
1032       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1033                                        format (0, "%U",
1034                                                format_ethernet_address,
1035                                                &mp->b_smac));
1036       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1037       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1038     }
1039 }
1040
1041 #if VPP_API_TEST_BUILTIN == 0
1042 static void vl_api_sw_interface_event_t_handler
1043   (vl_api_sw_interface_event_t * mp)
1044 {
1045   vat_main_t *vam = &vat_main;
1046   if (vam->interface_event_display)
1047     errmsg ("interface flags: sw_if_index %d %s %s",
1048             ntohl (mp->sw_if_index),
1049             mp->admin_up_down ? "admin-up" : "admin-down",
1050             mp->link_up_down ? "link-up" : "link-down");
1051 }
1052 #endif
1053
1054 __clib_unused static void
1055 vl_api_sw_interface_event_t_handler_json (vl_api_sw_interface_event_t * mp)
1056 {
1057   /* JSON output not supported */
1058 }
1059
1060 static void
1061 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1062 {
1063   vat_main_t *vam = &vat_main;
1064   i32 retval = ntohl (mp->retval);
1065
1066   vam->retval = retval;
1067   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1068   vam->result_ready = 1;
1069 }
1070
1071 static void
1072 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1073 {
1074   vat_main_t *vam = &vat_main;
1075   vat_json_node_t node;
1076   api_main_t *am = &api_main;
1077   void *oldheap;
1078   u8 *reply;
1079
1080   vat_json_init_object (&node);
1081   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1082   vat_json_object_add_uint (&node, "reply_in_shmem",
1083                             ntohl (mp->reply_in_shmem));
1084   /* Toss the shared-memory original... */
1085   pthread_mutex_lock (&am->vlib_rp->mutex);
1086   oldheap = svm_push_data_heap (am->vlib_rp);
1087
1088   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1089   vec_free (reply);
1090
1091   svm_pop_heap (oldheap);
1092   pthread_mutex_unlock (&am->vlib_rp->mutex);
1093
1094   vat_json_print (vam->ofp, &node);
1095   vat_json_free (&node);
1096
1097   vam->retval = ntohl (mp->retval);
1098   vam->result_ready = 1;
1099 }
1100
1101 static void
1102 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1103 {
1104   vat_main_t *vam = &vat_main;
1105   i32 retval = ntohl (mp->retval);
1106   u32 length = vl_api_string_len (&mp->reply);
1107
1108   vec_reset_length (vam->cmd_reply);
1109
1110   vam->retval = retval;
1111   if (retval == 0)
1112     {
1113       vec_validate (vam->cmd_reply, length);
1114       clib_memcpy ((char *) (vam->cmd_reply),
1115                    vl_api_from_api_string (&mp->reply), length);
1116       vam->cmd_reply[length] = 0;
1117     }
1118   vam->result_ready = 1;
1119 }
1120
1121 static void
1122 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1123 {
1124   vat_main_t *vam = &vat_main;
1125   vat_json_node_t node;
1126
1127   vec_reset_length (vam->cmd_reply);
1128
1129   vat_json_init_object (&node);
1130   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1131   vat_json_object_add_string_copy (&node, "reply",
1132                                    vl_api_from_api_string (&mp->reply));
1133
1134   vat_json_print (vam->ofp, &node);
1135   vat_json_free (&node);
1136
1137   vam->retval = ntohl (mp->retval);
1138   vam->result_ready = 1;
1139 }
1140
1141 static void vl_api_classify_add_del_table_reply_t_handler
1142   (vl_api_classify_add_del_table_reply_t * mp)
1143 {
1144   vat_main_t *vam = &vat_main;
1145   i32 retval = ntohl (mp->retval);
1146   if (vam->async_mode)
1147     {
1148       vam->async_errors += (retval < 0);
1149     }
1150   else
1151     {
1152       vam->retval = retval;
1153       if (retval == 0 &&
1154           ((mp->new_table_index != 0xFFFFFFFF) ||
1155            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1156            (mp->match_n_vectors != 0xFFFFFFFF)))
1157         /*
1158          * Note: this is just barely thread-safe, depends on
1159          * the main thread spinning waiting for an answer...
1160          */
1161         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1162                 ntohl (mp->new_table_index),
1163                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1164       vam->result_ready = 1;
1165     }
1166 }
1167
1168 static void vl_api_classify_add_del_table_reply_t_handler_json
1169   (vl_api_classify_add_del_table_reply_t * mp)
1170 {
1171   vat_main_t *vam = &vat_main;
1172   vat_json_node_t node;
1173
1174   vat_json_init_object (&node);
1175   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1176   vat_json_object_add_uint (&node, "new_table_index",
1177                             ntohl (mp->new_table_index));
1178   vat_json_object_add_uint (&node, "skip_n_vectors",
1179                             ntohl (mp->skip_n_vectors));
1180   vat_json_object_add_uint (&node, "match_n_vectors",
1181                             ntohl (mp->match_n_vectors));
1182
1183   vat_json_print (vam->ofp, &node);
1184   vat_json_free (&node);
1185
1186   vam->retval = ntohl (mp->retval);
1187   vam->result_ready = 1;
1188 }
1189
1190 static void vl_api_get_node_index_reply_t_handler
1191   (vl_api_get_node_index_reply_t * mp)
1192 {
1193   vat_main_t *vam = &vat_main;
1194   i32 retval = ntohl (mp->retval);
1195   if (vam->async_mode)
1196     {
1197       vam->async_errors += (retval < 0);
1198     }
1199   else
1200     {
1201       vam->retval = retval;
1202       if (retval == 0)
1203         errmsg ("node index %d", ntohl (mp->node_index));
1204       vam->result_ready = 1;
1205     }
1206 }
1207
1208 static void vl_api_get_node_index_reply_t_handler_json
1209   (vl_api_get_node_index_reply_t * mp)
1210 {
1211   vat_main_t *vam = &vat_main;
1212   vat_json_node_t node;
1213
1214   vat_json_init_object (&node);
1215   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1216   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1217
1218   vat_json_print (vam->ofp, &node);
1219   vat_json_free (&node);
1220
1221   vam->retval = ntohl (mp->retval);
1222   vam->result_ready = 1;
1223 }
1224
1225 static void vl_api_get_next_index_reply_t_handler
1226   (vl_api_get_next_index_reply_t * mp)
1227 {
1228   vat_main_t *vam = &vat_main;
1229   i32 retval = ntohl (mp->retval);
1230   if (vam->async_mode)
1231     {
1232       vam->async_errors += (retval < 0);
1233     }
1234   else
1235     {
1236       vam->retval = retval;
1237       if (retval == 0)
1238         errmsg ("next node index %d", ntohl (mp->next_index));
1239       vam->result_ready = 1;
1240     }
1241 }
1242
1243 static void vl_api_get_next_index_reply_t_handler_json
1244   (vl_api_get_next_index_reply_t * mp)
1245 {
1246   vat_main_t *vam = &vat_main;
1247   vat_json_node_t node;
1248
1249   vat_json_init_object (&node);
1250   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1251   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1252
1253   vat_json_print (vam->ofp, &node);
1254   vat_json_free (&node);
1255
1256   vam->retval = ntohl (mp->retval);
1257   vam->result_ready = 1;
1258 }
1259
1260 static void vl_api_add_node_next_reply_t_handler
1261   (vl_api_add_node_next_reply_t * mp)
1262 {
1263   vat_main_t *vam = &vat_main;
1264   i32 retval = ntohl (mp->retval);
1265   if (vam->async_mode)
1266     {
1267       vam->async_errors += (retval < 0);
1268     }
1269   else
1270     {
1271       vam->retval = retval;
1272       if (retval == 0)
1273         errmsg ("next index %d", ntohl (mp->next_index));
1274       vam->result_ready = 1;
1275     }
1276 }
1277
1278 static void vl_api_add_node_next_reply_t_handler_json
1279   (vl_api_add_node_next_reply_t * mp)
1280 {
1281   vat_main_t *vam = &vat_main;
1282   vat_json_node_t node;
1283
1284   vat_json_init_object (&node);
1285   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1286   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1287
1288   vat_json_print (vam->ofp, &node);
1289   vat_json_free (&node);
1290
1291   vam->retval = ntohl (mp->retval);
1292   vam->result_ready = 1;
1293 }
1294
1295 static void vl_api_show_version_reply_t_handler
1296   (vl_api_show_version_reply_t * mp)
1297 {
1298   vat_main_t *vam = &vat_main;
1299   i32 retval = ntohl (mp->retval);
1300
1301   if (retval >= 0)
1302     {
1303       u8 *s = 0;
1304       char *p = (char *) &mp->program;
1305
1306       s = vl_api_from_api_to_vec ((vl_api_string_t *) p);
1307       errmsg ("        program: %v\n", s);
1308       vec_free (s);
1309
1310       p +=
1311         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1312       s = vl_api_from_api_to_vec ((vl_api_string_t *) p);
1313       errmsg ("        version: %v\n", s);
1314       vec_free (s);
1315
1316       p +=
1317         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1318       s = vl_api_from_api_to_vec ((vl_api_string_t *) p);
1319       errmsg ("     build date: %v\n", s);
1320       vec_free (s);
1321
1322       p +=
1323         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1324       s = vl_api_from_api_to_vec ((vl_api_string_t *) p);
1325       vec_free (s);
1326
1327       errmsg ("build directory: %v\n", s);
1328     }
1329   vam->retval = retval;
1330   vam->result_ready = 1;
1331 }
1332
1333 static void vl_api_show_version_reply_t_handler_json
1334   (vl_api_show_version_reply_t * mp)
1335 {
1336   vat_main_t *vam = &vat_main;
1337   vat_json_node_t node;
1338
1339   vat_json_init_object (&node);
1340   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1341   char *p = (char *) &mp->program;
1342   vat_json_object_add_string_copy (&node, "program",
1343                                    vl_api_from_api_string ((vl_api_string_t *)
1344                                                            p));
1345   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1346   vat_json_object_add_string_copy (&node, "version",
1347                                    vl_api_from_api_string ((vl_api_string_t *)
1348                                                            p));
1349   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1350   vat_json_object_add_string_copy (&node, "build_date",
1351                                    vl_api_from_api_string ((vl_api_string_t *)
1352                                                            p));
1353   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1354   vat_json_object_add_string_copy (&node, "build_directory",
1355                                    vl_api_from_api_string ((vl_api_string_t *)
1356                                                            p));
1357
1358   vat_json_print (vam->ofp, &node);
1359   vat_json_free (&node);
1360
1361   vam->retval = ntohl (mp->retval);
1362   vam->result_ready = 1;
1363 }
1364
1365 static void vl_api_show_threads_reply_t_handler
1366   (vl_api_show_threads_reply_t * mp)
1367 {
1368   vat_main_t *vam = &vat_main;
1369   i32 retval = ntohl (mp->retval);
1370   int i, count = 0;
1371
1372   if (retval >= 0)
1373     count = ntohl (mp->count);
1374
1375   for (i = 0; i < count; i++)
1376     print (vam->ofp,
1377            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1378            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1379            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1380            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1381            ntohl (mp->thread_data[i].cpu_socket));
1382
1383   vam->retval = retval;
1384   vam->result_ready = 1;
1385 }
1386
1387 static void vl_api_show_threads_reply_t_handler_json
1388   (vl_api_show_threads_reply_t * mp)
1389 {
1390   vat_main_t *vam = &vat_main;
1391   vat_json_node_t node;
1392   vl_api_thread_data_t *td;
1393   i32 retval = ntohl (mp->retval);
1394   int i, count = 0;
1395
1396   if (retval >= 0)
1397     count = ntohl (mp->count);
1398
1399   vat_json_init_object (&node);
1400   vat_json_object_add_int (&node, "retval", retval);
1401   vat_json_object_add_uint (&node, "count", count);
1402
1403   for (i = 0; i < count; i++)
1404     {
1405       td = &mp->thread_data[i];
1406       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1407       vat_json_object_add_string_copy (&node, "name", td->name);
1408       vat_json_object_add_string_copy (&node, "type", td->type);
1409       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1410       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1411       vat_json_object_add_int (&node, "core", ntohl (td->id));
1412       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1413     }
1414
1415   vat_json_print (vam->ofp, &node);
1416   vat_json_free (&node);
1417
1418   vam->retval = retval;
1419   vam->result_ready = 1;
1420 }
1421
1422 static int
1423 api_show_threads (vat_main_t * vam)
1424 {
1425   vl_api_show_threads_t *mp;
1426   int ret;
1427
1428   print (vam->ofp,
1429          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1430          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1431
1432   M (SHOW_THREADS, mp);
1433
1434   S (mp);
1435   W (ret);
1436   return ret;
1437 }
1438
1439 static void
1440 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1441 {
1442   u32 sw_if_index = ntohl (mp->sw_if_index);
1443   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1444           mp->mac_ip ? "mac/ip binding" : "address resolution",
1445           ntohl (mp->pid), format_ip4_address, mp->ip,
1446           format_vl_api_mac_address, &mp->mac, sw_if_index);
1447 }
1448
1449 static void
1450 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1451 {
1452   /* JSON output not supported */
1453 }
1454
1455 static void
1456 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1457 {
1458   u32 sw_if_index = ntohl (mp->sw_if_index);
1459   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1460           mp->mac_ip ? "mac/ip binding" : "address resolution",
1461           ntohl (mp->pid), format_vl_api_ip6_address, mp->ip,
1462           format_vl_api_mac_address, mp->mac, sw_if_index);
1463 }
1464
1465 static void
1466 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1467 {
1468   /* JSON output not supported */
1469 }
1470
1471 static void
1472 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1473 {
1474   u32 n_macs = ntohl (mp->n_macs);
1475   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1476           ntohl (mp->pid), mp->client_index, n_macs);
1477   int i;
1478   for (i = 0; i < n_macs; i++)
1479     {
1480       vl_api_mac_entry_t *mac = &mp->mac[i];
1481       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1482               i + 1, ntohl (mac->sw_if_index),
1483               format_ethernet_address, mac->mac_addr, mac->action);
1484       if (i == 1000)
1485         break;
1486     }
1487 }
1488
1489 static void
1490 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1491 {
1492   /* JSON output not supported */
1493 }
1494
1495 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1496 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1497
1498 /*
1499  * Special-case: build the bridge domain table, maintain
1500  * the next bd id vbl.
1501  */
1502 static void vl_api_bridge_domain_details_t_handler
1503   (vl_api_bridge_domain_details_t * mp)
1504 {
1505   vat_main_t *vam = &vat_main;
1506   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1507   int i;
1508
1509   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1510          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1511
1512   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1513          ntohl (mp->bd_id), mp->learn, mp->forward,
1514          mp->flood, ntohl (mp->bvi_sw_if_index),
1515          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1516
1517   if (n_sw_ifs)
1518     {
1519       vl_api_bridge_domain_sw_if_t *sw_ifs;
1520       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1521              "Interface Name");
1522
1523       sw_ifs = mp->sw_if_details;
1524       for (i = 0; i < n_sw_ifs; i++)
1525         {
1526           u8 *sw_if_name = 0;
1527           u32 sw_if_index;
1528           hash_pair_t *p;
1529
1530           sw_if_index = ntohl (sw_ifs->sw_if_index);
1531
1532           /* *INDENT-OFF* */
1533           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1534                              ({
1535                                if ((u32) p->value[0] == sw_if_index)
1536                                  {
1537                                    sw_if_name = (u8 *)(p->key);
1538                                    break;
1539                                  }
1540                              }));
1541           /* *INDENT-ON* */
1542           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1543                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1544                  "sw_if_index not found!");
1545
1546           sw_ifs++;
1547         }
1548     }
1549 }
1550
1551 static void vl_api_bridge_domain_details_t_handler_json
1552   (vl_api_bridge_domain_details_t * mp)
1553 {
1554   vat_main_t *vam = &vat_main;
1555   vat_json_node_t *node, *array = NULL;
1556   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1557
1558   if (VAT_JSON_ARRAY != vam->json_tree.type)
1559     {
1560       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1561       vat_json_init_array (&vam->json_tree);
1562     }
1563   node = vat_json_array_add (&vam->json_tree);
1564
1565   vat_json_init_object (node);
1566   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1567   vat_json_object_add_uint (node, "flood", mp->flood);
1568   vat_json_object_add_uint (node, "forward", mp->forward);
1569   vat_json_object_add_uint (node, "learn", mp->learn);
1570   vat_json_object_add_uint (node, "bvi_sw_if_index",
1571                             ntohl (mp->bvi_sw_if_index));
1572   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1573   array = vat_json_object_add (node, "sw_if");
1574   vat_json_init_array (array);
1575
1576
1577
1578   if (n_sw_ifs)
1579     {
1580       vl_api_bridge_domain_sw_if_t *sw_ifs;
1581       int i;
1582
1583       sw_ifs = mp->sw_if_details;
1584       for (i = 0; i < n_sw_ifs; i++)
1585         {
1586           node = vat_json_array_add (array);
1587           vat_json_init_object (node);
1588           vat_json_object_add_uint (node, "sw_if_index",
1589                                     ntohl (sw_ifs->sw_if_index));
1590           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1591           sw_ifs++;
1592         }
1593     }
1594 }
1595
1596 static void vl_api_control_ping_reply_t_handler
1597   (vl_api_control_ping_reply_t * mp)
1598 {
1599   vat_main_t *vam = &vat_main;
1600   i32 retval = ntohl (mp->retval);
1601   if (vam->async_mode)
1602     {
1603       vam->async_errors += (retval < 0);
1604     }
1605   else
1606     {
1607       vam->retval = retval;
1608       vam->result_ready = 1;
1609     }
1610   if (vam->socket_client_main)
1611     vam->socket_client_main->control_pings_outstanding--;
1612 }
1613
1614 static void vl_api_control_ping_reply_t_handler_json
1615   (vl_api_control_ping_reply_t * mp)
1616 {
1617   vat_main_t *vam = &vat_main;
1618   i32 retval = ntohl (mp->retval);
1619
1620   if (VAT_JSON_NONE != vam->json_tree.type)
1621     {
1622       vat_json_print (vam->ofp, &vam->json_tree);
1623       vat_json_free (&vam->json_tree);
1624       vam->json_tree.type = VAT_JSON_NONE;
1625     }
1626   else
1627     {
1628       /* just print [] */
1629       vat_json_init_array (&vam->json_tree);
1630       vat_json_print (vam->ofp, &vam->json_tree);
1631       vam->json_tree.type = VAT_JSON_NONE;
1632     }
1633
1634   vam->retval = retval;
1635   vam->result_ready = 1;
1636 }
1637
1638 static void
1639   vl_api_bridge_domain_set_mac_age_reply_t_handler
1640   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1641 {
1642   vat_main_t *vam = &vat_main;
1643   i32 retval = ntohl (mp->retval);
1644   if (vam->async_mode)
1645     {
1646       vam->async_errors += (retval < 0);
1647     }
1648   else
1649     {
1650       vam->retval = retval;
1651       vam->result_ready = 1;
1652     }
1653 }
1654
1655 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1656   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1657 {
1658   vat_main_t *vam = &vat_main;
1659   vat_json_node_t node;
1660
1661   vat_json_init_object (&node);
1662   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1663
1664   vat_json_print (vam->ofp, &node);
1665   vat_json_free (&node);
1666
1667   vam->retval = ntohl (mp->retval);
1668   vam->result_ready = 1;
1669 }
1670
1671 static void
1672 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1673 {
1674   vat_main_t *vam = &vat_main;
1675   i32 retval = ntohl (mp->retval);
1676   if (vam->async_mode)
1677     {
1678       vam->async_errors += (retval < 0);
1679     }
1680   else
1681     {
1682       vam->retval = retval;
1683       vam->result_ready = 1;
1684     }
1685 }
1686
1687 static void vl_api_l2_flags_reply_t_handler_json
1688   (vl_api_l2_flags_reply_t * mp)
1689 {
1690   vat_main_t *vam = &vat_main;
1691   vat_json_node_t node;
1692
1693   vat_json_init_object (&node);
1694   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1695   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1696                             ntohl (mp->resulting_feature_bitmap));
1697
1698   vat_json_print (vam->ofp, &node);
1699   vat_json_free (&node);
1700
1701   vam->retval = ntohl (mp->retval);
1702   vam->result_ready = 1;
1703 }
1704
1705 static void vl_api_bridge_flags_reply_t_handler
1706   (vl_api_bridge_flags_reply_t * mp)
1707 {
1708   vat_main_t *vam = &vat_main;
1709   i32 retval = ntohl (mp->retval);
1710   if (vam->async_mode)
1711     {
1712       vam->async_errors += (retval < 0);
1713     }
1714   else
1715     {
1716       vam->retval = retval;
1717       vam->result_ready = 1;
1718     }
1719 }
1720
1721 static void vl_api_bridge_flags_reply_t_handler_json
1722   (vl_api_bridge_flags_reply_t * mp)
1723 {
1724   vat_main_t *vam = &vat_main;
1725   vat_json_node_t node;
1726
1727   vat_json_init_object (&node);
1728   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1729   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1730                             ntohl (mp->resulting_feature_bitmap));
1731
1732   vat_json_print (vam->ofp, &node);
1733   vat_json_free (&node);
1734
1735   vam->retval = ntohl (mp->retval);
1736   vam->result_ready = 1;
1737 }
1738
1739 static void
1740 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1741 {
1742   vat_main_t *vam = &vat_main;
1743   i32 retval = ntohl (mp->retval);
1744   if (vam->async_mode)
1745     {
1746       vam->async_errors += (retval < 0);
1747     }
1748   else
1749     {
1750       vam->retval = retval;
1751       vam->sw_if_index = ntohl (mp->sw_if_index);
1752       vam->result_ready = 1;
1753     }
1754
1755 }
1756
1757 static void vl_api_tap_create_v2_reply_t_handler_json
1758   (vl_api_tap_create_v2_reply_t * mp)
1759 {
1760   vat_main_t *vam = &vat_main;
1761   vat_json_node_t node;
1762
1763   vat_json_init_object (&node);
1764   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1765   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1766
1767   vat_json_print (vam->ofp, &node);
1768   vat_json_free (&node);
1769
1770   vam->retval = ntohl (mp->retval);
1771   vam->result_ready = 1;
1772
1773 }
1774
1775 static void
1776 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1777 {
1778   vat_main_t *vam = &vat_main;
1779   i32 retval = ntohl (mp->retval);
1780   if (vam->async_mode)
1781     {
1782       vam->async_errors += (retval < 0);
1783     }
1784   else
1785     {
1786       vam->retval = retval;
1787       vam->result_ready = 1;
1788     }
1789 }
1790
1791 static void vl_api_tap_delete_v2_reply_t_handler_json
1792   (vl_api_tap_delete_v2_reply_t * mp)
1793 {
1794   vat_main_t *vam = &vat_main;
1795   vat_json_node_t node;
1796
1797   vat_json_init_object (&node);
1798   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1799
1800   vat_json_print (vam->ofp, &node);
1801   vat_json_free (&node);
1802
1803   vam->retval = ntohl (mp->retval);
1804   vam->result_ready = 1;
1805 }
1806
1807 static void
1808 vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1809                                           mp)
1810 {
1811   vat_main_t *vam = &vat_main;
1812   i32 retval = ntohl (mp->retval);
1813   if (vam->async_mode)
1814     {
1815       vam->async_errors += (retval < 0);
1816     }
1817   else
1818     {
1819       vam->retval = retval;
1820       vam->sw_if_index = ntohl (mp->sw_if_index);
1821       vam->result_ready = 1;
1822     }
1823 }
1824
1825 static void vl_api_virtio_pci_create_reply_t_handler_json
1826   (vl_api_virtio_pci_create_reply_t * mp)
1827 {
1828   vat_main_t *vam = &vat_main;
1829   vat_json_node_t node;
1830
1831   vat_json_init_object (&node);
1832   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1833   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1834
1835   vat_json_print (vam->ofp, &node);
1836   vat_json_free (&node);
1837
1838   vam->retval = ntohl (mp->retval);
1839   vam->result_ready = 1;
1840
1841 }
1842
1843 static void
1844 vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1845                                           mp)
1846 {
1847   vat_main_t *vam = &vat_main;
1848   i32 retval = ntohl (mp->retval);
1849   if (vam->async_mode)
1850     {
1851       vam->async_errors += (retval < 0);
1852     }
1853   else
1854     {
1855       vam->retval = retval;
1856       vam->result_ready = 1;
1857     }
1858 }
1859
1860 static void vl_api_virtio_pci_delete_reply_t_handler_json
1861   (vl_api_virtio_pci_delete_reply_t * mp)
1862 {
1863   vat_main_t *vam = &vat_main;
1864   vat_json_node_t node;
1865
1866   vat_json_init_object (&node);
1867   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1868
1869   vat_json_print (vam->ofp, &node);
1870   vat_json_free (&node);
1871
1872   vam->retval = ntohl (mp->retval);
1873   vam->result_ready = 1;
1874 }
1875
1876 static void
1877 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1878 {
1879   vat_main_t *vam = &vat_main;
1880   i32 retval = ntohl (mp->retval);
1881
1882   if (vam->async_mode)
1883     {
1884       vam->async_errors += (retval < 0);
1885     }
1886   else
1887     {
1888       vam->retval = retval;
1889       vam->sw_if_index = ntohl (mp->sw_if_index);
1890       vam->result_ready = 1;
1891     }
1892 }
1893
1894 static void vl_api_bond_create_reply_t_handler_json
1895   (vl_api_bond_create_reply_t * mp)
1896 {
1897   vat_main_t *vam = &vat_main;
1898   vat_json_node_t node;
1899
1900   vat_json_init_object (&node);
1901   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1902   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1903
1904   vat_json_print (vam->ofp, &node);
1905   vat_json_free (&node);
1906
1907   vam->retval = ntohl (mp->retval);
1908   vam->result_ready = 1;
1909 }
1910
1911 static void
1912 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1913 {
1914   vat_main_t *vam = &vat_main;
1915   i32 retval = ntohl (mp->retval);
1916
1917   if (vam->async_mode)
1918     {
1919       vam->async_errors += (retval < 0);
1920     }
1921   else
1922     {
1923       vam->retval = retval;
1924       vam->result_ready = 1;
1925     }
1926 }
1927
1928 static void vl_api_bond_delete_reply_t_handler_json
1929   (vl_api_bond_delete_reply_t * mp)
1930 {
1931   vat_main_t *vam = &vat_main;
1932   vat_json_node_t node;
1933
1934   vat_json_init_object (&node);
1935   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1936
1937   vat_json_print (vam->ofp, &node);
1938   vat_json_free (&node);
1939
1940   vam->retval = ntohl (mp->retval);
1941   vam->result_ready = 1;
1942 }
1943
1944 static void
1945 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1946 {
1947   vat_main_t *vam = &vat_main;
1948   i32 retval = ntohl (mp->retval);
1949
1950   if (vam->async_mode)
1951     {
1952       vam->async_errors += (retval < 0);
1953     }
1954   else
1955     {
1956       vam->retval = retval;
1957       vam->result_ready = 1;
1958     }
1959 }
1960
1961 static void vl_api_bond_enslave_reply_t_handler_json
1962   (vl_api_bond_enslave_reply_t * mp)
1963 {
1964   vat_main_t *vam = &vat_main;
1965   vat_json_node_t node;
1966
1967   vat_json_init_object (&node);
1968   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1969
1970   vat_json_print (vam->ofp, &node);
1971   vat_json_free (&node);
1972
1973   vam->retval = ntohl (mp->retval);
1974   vam->result_ready = 1;
1975 }
1976
1977 static void
1978 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
1979                                           mp)
1980 {
1981   vat_main_t *vam = &vat_main;
1982   i32 retval = ntohl (mp->retval);
1983
1984   if (vam->async_mode)
1985     {
1986       vam->async_errors += (retval < 0);
1987     }
1988   else
1989     {
1990       vam->retval = retval;
1991       vam->result_ready = 1;
1992     }
1993 }
1994
1995 static void vl_api_bond_detach_slave_reply_t_handler_json
1996   (vl_api_bond_detach_slave_reply_t * mp)
1997 {
1998   vat_main_t *vam = &vat_main;
1999   vat_json_node_t node;
2000
2001   vat_json_init_object (&node);
2002   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2003
2004   vat_json_print (vam->ofp, &node);
2005   vat_json_free (&node);
2006
2007   vam->retval = ntohl (mp->retval);
2008   vam->result_ready = 1;
2009 }
2010
2011 static void vl_api_sw_interface_bond_details_t_handler
2012   (vl_api_sw_interface_bond_details_t * mp)
2013 {
2014   vat_main_t *vam = &vat_main;
2015
2016   print (vam->ofp,
2017          "%-16s %-12d %-12U %-13U %-14u %-14u",
2018          mp->interface_name, ntohl (mp->sw_if_index),
2019          format_bond_mode, mp->mode, format_bond_load_balance, mp->lb,
2020          ntohl (mp->active_slaves), ntohl (mp->slaves));
2021 }
2022
2023 static void vl_api_sw_interface_bond_details_t_handler_json
2024   (vl_api_sw_interface_bond_details_t * mp)
2025 {
2026   vat_main_t *vam = &vat_main;
2027   vat_json_node_t *node = NULL;
2028
2029   if (VAT_JSON_ARRAY != vam->json_tree.type)
2030     {
2031       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2032       vat_json_init_array (&vam->json_tree);
2033     }
2034   node = vat_json_array_add (&vam->json_tree);
2035
2036   vat_json_init_object (node);
2037   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2038   vat_json_object_add_string_copy (node, "interface_name",
2039                                    mp->interface_name);
2040   vat_json_object_add_uint (node, "mode", mp->mode);
2041   vat_json_object_add_uint (node, "load_balance", mp->lb);
2042   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
2043   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
2044 }
2045
2046 static int
2047 api_sw_interface_bond_dump (vat_main_t * vam)
2048 {
2049   vl_api_sw_interface_bond_dump_t *mp;
2050   vl_api_control_ping_t *mp_ping;
2051   int ret;
2052
2053   print (vam->ofp,
2054          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2055          "interface name", "sw_if_index", "mode", "load balance",
2056          "active slaves", "slaves");
2057
2058   /* Get list of bond interfaces */
2059   M (SW_INTERFACE_BOND_DUMP, mp);
2060   S (mp);
2061
2062   /* Use a control ping for synchronization */
2063   MPING (CONTROL_PING, mp_ping);
2064   S (mp_ping);
2065
2066   W (ret);
2067   return ret;
2068 }
2069
2070 static void vl_api_sw_interface_slave_details_t_handler
2071   (vl_api_sw_interface_slave_details_t * mp)
2072 {
2073   vat_main_t *vam = &vat_main;
2074
2075   print (vam->ofp,
2076          "%-25s %-12d %-12d %d", mp->interface_name,
2077          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout);
2078 }
2079
2080 static void vl_api_sw_interface_slave_details_t_handler_json
2081   (vl_api_sw_interface_slave_details_t * mp)
2082 {
2083   vat_main_t *vam = &vat_main;
2084   vat_json_node_t *node = NULL;
2085
2086   if (VAT_JSON_ARRAY != vam->json_tree.type)
2087     {
2088       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2089       vat_json_init_array (&vam->json_tree);
2090     }
2091   node = vat_json_array_add (&vam->json_tree);
2092
2093   vat_json_init_object (node);
2094   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2095   vat_json_object_add_string_copy (node, "interface_name",
2096                                    mp->interface_name);
2097   vat_json_object_add_uint (node, "passive", mp->is_passive);
2098   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2099 }
2100
2101 static int
2102 api_sw_interface_slave_dump (vat_main_t * vam)
2103 {
2104   unformat_input_t *i = vam->input;
2105   vl_api_sw_interface_slave_dump_t *mp;
2106   vl_api_control_ping_t *mp_ping;
2107   u32 sw_if_index = ~0;
2108   u8 sw_if_index_set = 0;
2109   int ret;
2110
2111   /* Parse args required to build the message */
2112   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2113     {
2114       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2115         sw_if_index_set = 1;
2116       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2117         sw_if_index_set = 1;
2118       else
2119         break;
2120     }
2121
2122   if (sw_if_index_set == 0)
2123     {
2124       errmsg ("missing vpp interface name. ");
2125       return -99;
2126     }
2127
2128   print (vam->ofp,
2129          "\n%-25s %-12s %-12s %s",
2130          "slave interface name", "sw_if_index", "passive", "long_timeout");
2131
2132   /* Get list of bond interfaces */
2133   M (SW_INTERFACE_SLAVE_DUMP, mp);
2134   mp->sw_if_index = ntohl (sw_if_index);
2135   S (mp);
2136
2137   /* Use a control ping for synchronization */
2138   MPING (CONTROL_PING, mp_ping);
2139   S (mp_ping);
2140
2141   W (ret);
2142   return ret;
2143 }
2144
2145 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2146   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2147 {
2148   vat_main_t *vam = &vat_main;
2149   i32 retval = ntohl (mp->retval);
2150   if (vam->async_mode)
2151     {
2152       vam->async_errors += (retval < 0);
2153     }
2154   else
2155     {
2156       vam->retval = retval;
2157       vam->sw_if_index = ntohl (mp->sw_if_index);
2158       vam->result_ready = 1;
2159     }
2160   vam->regenerate_interface_table = 1;
2161 }
2162
2163 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2164   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2165 {
2166   vat_main_t *vam = &vat_main;
2167   vat_json_node_t node;
2168
2169   vat_json_init_object (&node);
2170   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2171   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2172                             ntohl (mp->sw_if_index));
2173
2174   vat_json_print (vam->ofp, &node);
2175   vat_json_free (&node);
2176
2177   vam->retval = ntohl (mp->retval);
2178   vam->result_ready = 1;
2179 }
2180
2181 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2182   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2183 {
2184   vat_main_t *vam = &vat_main;
2185   i32 retval = ntohl (mp->retval);
2186   if (vam->async_mode)
2187     {
2188       vam->async_errors += (retval < 0);
2189     }
2190   else
2191     {
2192       vam->retval = retval;
2193       vam->sw_if_index = ntohl (mp->sw_if_index);
2194       vam->result_ready = 1;
2195     }
2196 }
2197
2198 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2199   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2200 {
2201   vat_main_t *vam = &vat_main;
2202   vat_json_node_t node;
2203
2204   vat_json_init_object (&node);
2205   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2206   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2207
2208   vat_json_print (vam->ofp, &node);
2209   vat_json_free (&node);
2210
2211   vam->retval = ntohl (mp->retval);
2212   vam->result_ready = 1;
2213 }
2214
2215 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2216   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2217 {
2218   vat_main_t *vam = &vat_main;
2219   i32 retval = ntohl (mp->retval);
2220   if (vam->async_mode)
2221     {
2222       vam->async_errors += (retval < 0);
2223     }
2224   else
2225     {
2226       vam->retval = retval;
2227       vam->result_ready = 1;
2228     }
2229 }
2230
2231 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2232   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2233 {
2234   vat_main_t *vam = &vat_main;
2235   vat_json_node_t node;
2236
2237   vat_json_init_object (&node);
2238   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2239   vat_json_object_add_uint (&node, "fwd_entry_index",
2240                             clib_net_to_host_u32 (mp->fwd_entry_index));
2241
2242   vat_json_print (vam->ofp, &node);
2243   vat_json_free (&node);
2244
2245   vam->retval = ntohl (mp->retval);
2246   vam->result_ready = 1;
2247 }
2248
2249 u8 *
2250 format_lisp_transport_protocol (u8 * s, va_list * args)
2251 {
2252   u32 proto = va_arg (*args, u32);
2253
2254   switch (proto)
2255     {
2256     case 1:
2257       return format (s, "udp");
2258     case 2:
2259       return format (s, "api");
2260     default:
2261       return 0;
2262     }
2263   return 0;
2264 }
2265
2266 static void vl_api_one_get_transport_protocol_reply_t_handler
2267   (vl_api_one_get_transport_protocol_reply_t * mp)
2268 {
2269   vat_main_t *vam = &vat_main;
2270   i32 retval = ntohl (mp->retval);
2271   if (vam->async_mode)
2272     {
2273       vam->async_errors += (retval < 0);
2274     }
2275   else
2276     {
2277       u32 proto = mp->protocol;
2278       print (vam->ofp, "Transport protocol: %U",
2279              format_lisp_transport_protocol, proto);
2280       vam->retval = retval;
2281       vam->result_ready = 1;
2282     }
2283 }
2284
2285 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2286   (vl_api_one_get_transport_protocol_reply_t * mp)
2287 {
2288   vat_main_t *vam = &vat_main;
2289   vat_json_node_t node;
2290   u8 *s;
2291
2292   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2293   vec_add1 (s, 0);
2294
2295   vat_json_init_object (&node);
2296   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2297   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2298
2299   vec_free (s);
2300   vat_json_print (vam->ofp, &node);
2301   vat_json_free (&node);
2302
2303   vam->retval = ntohl (mp->retval);
2304   vam->result_ready = 1;
2305 }
2306
2307 static void vl_api_one_add_del_locator_set_reply_t_handler
2308   (vl_api_one_add_del_locator_set_reply_t * mp)
2309 {
2310   vat_main_t *vam = &vat_main;
2311   i32 retval = ntohl (mp->retval);
2312   if (vam->async_mode)
2313     {
2314       vam->async_errors += (retval < 0);
2315     }
2316   else
2317     {
2318       vam->retval = retval;
2319       vam->result_ready = 1;
2320     }
2321 }
2322
2323 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2324   (vl_api_one_add_del_locator_set_reply_t * mp)
2325 {
2326   vat_main_t *vam = &vat_main;
2327   vat_json_node_t node;
2328
2329   vat_json_init_object (&node);
2330   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2331   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2332
2333   vat_json_print (vam->ofp, &node);
2334   vat_json_free (&node);
2335
2336   vam->retval = ntohl (mp->retval);
2337   vam->result_ready = 1;
2338 }
2339
2340 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2341   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2342 {
2343   vat_main_t *vam = &vat_main;
2344   i32 retval = ntohl (mp->retval);
2345   if (vam->async_mode)
2346     {
2347       vam->async_errors += (retval < 0);
2348     }
2349   else
2350     {
2351       vam->retval = retval;
2352       vam->sw_if_index = ntohl (mp->sw_if_index);
2353       vam->result_ready = 1;
2354     }
2355   vam->regenerate_interface_table = 1;
2356 }
2357
2358 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2359   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2360 {
2361   vat_main_t *vam = &vat_main;
2362   vat_json_node_t node;
2363
2364   vat_json_init_object (&node);
2365   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2366   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2367
2368   vat_json_print (vam->ofp, &node);
2369   vat_json_free (&node);
2370
2371   vam->retval = ntohl (mp->retval);
2372   vam->result_ready = 1;
2373 }
2374
2375 static void vl_api_vxlan_offload_rx_reply_t_handler
2376   (vl_api_vxlan_offload_rx_reply_t * mp)
2377 {
2378   vat_main_t *vam = &vat_main;
2379   i32 retval = ntohl (mp->retval);
2380   if (vam->async_mode)
2381     {
2382       vam->async_errors += (retval < 0);
2383     }
2384   else
2385     {
2386       vam->retval = retval;
2387       vam->result_ready = 1;
2388     }
2389 }
2390
2391 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2392   (vl_api_vxlan_offload_rx_reply_t * mp)
2393 {
2394   vat_main_t *vam = &vat_main;
2395   vat_json_node_t node;
2396
2397   vat_json_init_object (&node);
2398   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2399
2400   vat_json_print (vam->ofp, &node);
2401   vat_json_free (&node);
2402
2403   vam->retval = ntohl (mp->retval);
2404   vam->result_ready = 1;
2405 }
2406
2407 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2408   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2409 {
2410   vat_main_t *vam = &vat_main;
2411   i32 retval = ntohl (mp->retval);
2412   if (vam->async_mode)
2413     {
2414       vam->async_errors += (retval < 0);
2415     }
2416   else
2417     {
2418       vam->retval = retval;
2419       vam->sw_if_index = ntohl (mp->sw_if_index);
2420       vam->result_ready = 1;
2421     }
2422 }
2423
2424 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2425   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2426 {
2427   vat_main_t *vam = &vat_main;
2428   vat_json_node_t node;
2429
2430   vat_json_init_object (&node);
2431   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2432   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2433
2434   vat_json_print (vam->ofp, &node);
2435   vat_json_free (&node);
2436
2437   vam->retval = ntohl (mp->retval);
2438   vam->result_ready = 1;
2439 }
2440
2441 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2442   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2443 {
2444   vat_main_t *vam = &vat_main;
2445   i32 retval = ntohl (mp->retval);
2446   if (vam->async_mode)
2447     {
2448       vam->async_errors += (retval < 0);
2449     }
2450   else
2451     {
2452       vam->retval = retval;
2453       vam->sw_if_index = ntohl (mp->sw_if_index);
2454       vam->result_ready = 1;
2455     }
2456   vam->regenerate_interface_table = 1;
2457 }
2458
2459 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2460   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2461 {
2462   vat_main_t *vam = &vat_main;
2463   vat_json_node_t node;
2464
2465   vat_json_init_object (&node);
2466   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2467   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2468
2469   vat_json_print (vam->ofp, &node);
2470   vat_json_free (&node);
2471
2472   vam->retval = ntohl (mp->retval);
2473   vam->result_ready = 1;
2474 }
2475
2476 static void vl_api_gre_tunnel_add_del_reply_t_handler
2477   (vl_api_gre_tunnel_add_del_reply_t * mp)
2478 {
2479   vat_main_t *vam = &vat_main;
2480   i32 retval = ntohl (mp->retval);
2481   if (vam->async_mode)
2482     {
2483       vam->async_errors += (retval < 0);
2484     }
2485   else
2486     {
2487       vam->retval = retval;
2488       vam->sw_if_index = ntohl (mp->sw_if_index);
2489       vam->result_ready = 1;
2490     }
2491 }
2492
2493 static void vl_api_gre_tunnel_add_del_reply_t_handler_json
2494   (vl_api_gre_tunnel_add_del_reply_t * mp)
2495 {
2496   vat_main_t *vam = &vat_main;
2497   vat_json_node_t node;
2498
2499   vat_json_init_object (&node);
2500   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2501   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2502
2503   vat_json_print (vam->ofp, &node);
2504   vat_json_free (&node);
2505
2506   vam->retval = ntohl (mp->retval);
2507   vam->result_ready = 1;
2508 }
2509
2510 static void vl_api_create_vhost_user_if_reply_t_handler
2511   (vl_api_create_vhost_user_if_reply_t * mp)
2512 {
2513   vat_main_t *vam = &vat_main;
2514   i32 retval = ntohl (mp->retval);
2515   if (vam->async_mode)
2516     {
2517       vam->async_errors += (retval < 0);
2518     }
2519   else
2520     {
2521       vam->retval = retval;
2522       vam->sw_if_index = ntohl (mp->sw_if_index);
2523       vam->result_ready = 1;
2524     }
2525   vam->regenerate_interface_table = 1;
2526 }
2527
2528 static void vl_api_create_vhost_user_if_reply_t_handler_json
2529   (vl_api_create_vhost_user_if_reply_t * mp)
2530 {
2531   vat_main_t *vam = &vat_main;
2532   vat_json_node_t node;
2533
2534   vat_json_init_object (&node);
2535   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2536   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2537
2538   vat_json_print (vam->ofp, &node);
2539   vat_json_free (&node);
2540
2541   vam->retval = ntohl (mp->retval);
2542   vam->result_ready = 1;
2543 }
2544
2545 static void vl_api_dns_resolve_name_reply_t_handler
2546   (vl_api_dns_resolve_name_reply_t * mp)
2547 {
2548   vat_main_t *vam = &vat_main;
2549   i32 retval = ntohl (mp->retval);
2550   if (vam->async_mode)
2551     {
2552       vam->async_errors += (retval < 0);
2553     }
2554   else
2555     {
2556       vam->retval = retval;
2557       vam->result_ready = 1;
2558
2559       if (retval == 0)
2560         {
2561           if (mp->ip4_set)
2562             clib_warning ("ip4 address %U", format_ip4_address,
2563                           (ip4_address_t *) mp->ip4_address);
2564           if (mp->ip6_set)
2565             clib_warning ("ip6 address %U", format_ip6_address,
2566                           (ip6_address_t *) mp->ip6_address);
2567         }
2568       else
2569         clib_warning ("retval %d", retval);
2570     }
2571 }
2572
2573 static void vl_api_dns_resolve_name_reply_t_handler_json
2574   (vl_api_dns_resolve_name_reply_t * mp)
2575 {
2576   clib_warning ("not implemented");
2577 }
2578
2579 static void vl_api_dns_resolve_ip_reply_t_handler
2580   (vl_api_dns_resolve_ip_reply_t * mp)
2581 {
2582   vat_main_t *vam = &vat_main;
2583   i32 retval = ntohl (mp->retval);
2584   if (vam->async_mode)
2585     {
2586       vam->async_errors += (retval < 0);
2587     }
2588   else
2589     {
2590       vam->retval = retval;
2591       vam->result_ready = 1;
2592
2593       if (retval == 0)
2594         {
2595           clib_warning ("canonical name %s", mp->name);
2596         }
2597       else
2598         clib_warning ("retval %d", retval);
2599     }
2600 }
2601
2602 static void vl_api_dns_resolve_ip_reply_t_handler_json
2603   (vl_api_dns_resolve_ip_reply_t * mp)
2604 {
2605   clib_warning ("not implemented");
2606 }
2607
2608
2609 static void vl_api_ip_address_details_t_handler
2610   (vl_api_ip_address_details_t * mp)
2611 {
2612   vat_main_t *vam = &vat_main;
2613   static ip_address_details_t empty_ip_address_details = { {0} };
2614   ip_address_details_t *address = NULL;
2615   ip_details_t *current_ip_details = NULL;
2616   ip_details_t *details = NULL;
2617
2618   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2619
2620   if (!details || vam->current_sw_if_index >= vec_len (details)
2621       || !details[vam->current_sw_if_index].present)
2622     {
2623       errmsg ("ip address details arrived but not stored");
2624       errmsg ("ip_dump should be called first");
2625       return;
2626     }
2627
2628   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2629
2630 #define addresses (current_ip_details->addr)
2631
2632   vec_validate_init_empty (addresses, vec_len (addresses),
2633                            empty_ip_address_details);
2634
2635   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2636
2637   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2638   address->prefix_length = mp->prefix_length;
2639 #undef addresses
2640 }
2641
2642 static void vl_api_ip_address_details_t_handler_json
2643   (vl_api_ip_address_details_t * mp)
2644 {
2645   vat_main_t *vam = &vat_main;
2646   vat_json_node_t *node = NULL;
2647   struct in6_addr ip6;
2648   struct in_addr ip4;
2649
2650   if (VAT_JSON_ARRAY != vam->json_tree.type)
2651     {
2652       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2653       vat_json_init_array (&vam->json_tree);
2654     }
2655   node = vat_json_array_add (&vam->json_tree);
2656
2657   vat_json_init_object (node);
2658   if (vam->is_ipv6)
2659     {
2660       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2661       vat_json_object_add_ip6 (node, "ip", ip6);
2662     }
2663   else
2664     {
2665       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2666       vat_json_object_add_ip4 (node, "ip", ip4);
2667     }
2668   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2669 }
2670
2671 static void
2672 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2673 {
2674   vat_main_t *vam = &vat_main;
2675   static ip_details_t empty_ip_details = { 0 };
2676   ip_details_t *ip = NULL;
2677   u32 sw_if_index = ~0;
2678
2679   sw_if_index = ntohl (mp->sw_if_index);
2680
2681   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2682                            sw_if_index, empty_ip_details);
2683
2684   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2685                          sw_if_index);
2686
2687   ip->present = 1;
2688 }
2689
2690 static void
2691 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2692 {
2693   vat_main_t *vam = &vat_main;
2694
2695   if (VAT_JSON_ARRAY != vam->json_tree.type)
2696     {
2697       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2698       vat_json_init_array (&vam->json_tree);
2699     }
2700   vat_json_array_add_uint (&vam->json_tree,
2701                            clib_net_to_host_u32 (mp->sw_if_index));
2702 }
2703
2704 static void
2705 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2706 {
2707   u8 *s, i;
2708
2709   s = format (0, "DHCP compl event: pid %d %s hostname %s host_addr %U "
2710               "host_mac %U router_addr %U",
2711               ntohl (mp->pid), mp->lease.is_ipv6 ? "ipv6" : "ipv4",
2712               mp->lease.hostname,
2713               format_ip4_address, mp->lease.host_address,
2714               format_ethernet_address, mp->lease.host_mac,
2715               format_ip4_address, mp->lease.router_address);
2716
2717   for (i = 0; i < mp->lease.count; i++)
2718     s =
2719       format (s, " domain_server_addr %U", format_ip4_address,
2720               mp->lease.domain_server[i].address);
2721
2722   errmsg ((char *) s);
2723   vec_free (s);
2724 }
2725
2726 static void vl_api_dhcp_compl_event_t_handler_json
2727   (vl_api_dhcp_compl_event_t * mp)
2728 {
2729   /* JSON output not supported */
2730 }
2731
2732 static void vl_api_get_first_msg_id_reply_t_handler
2733   (vl_api_get_first_msg_id_reply_t * mp)
2734 {
2735   vat_main_t *vam = &vat_main;
2736   i32 retval = ntohl (mp->retval);
2737
2738   if (vam->async_mode)
2739     {
2740       vam->async_errors += (retval < 0);
2741     }
2742   else
2743     {
2744       vam->retval = retval;
2745       vam->result_ready = 1;
2746     }
2747   if (retval >= 0)
2748     {
2749       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2750     }
2751 }
2752
2753 static void vl_api_get_first_msg_id_reply_t_handler_json
2754   (vl_api_get_first_msg_id_reply_t * mp)
2755 {
2756   vat_main_t *vam = &vat_main;
2757   vat_json_node_t node;
2758
2759   vat_json_init_object (&node);
2760   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2761   vat_json_object_add_uint (&node, "first_msg_id",
2762                             (uint) ntohs (mp->first_msg_id));
2763
2764   vat_json_print (vam->ofp, &node);
2765   vat_json_free (&node);
2766
2767   vam->retval = ntohl (mp->retval);
2768   vam->result_ready = 1;
2769 }
2770
2771 static void vl_api_get_node_graph_reply_t_handler
2772   (vl_api_get_node_graph_reply_t * mp)
2773 {
2774   vat_main_t *vam = &vat_main;
2775   api_main_t *am = &api_main;
2776   i32 retval = ntohl (mp->retval);
2777   u8 *pvt_copy, *reply;
2778   void *oldheap;
2779   vlib_node_t *node;
2780   int i;
2781
2782   if (vam->async_mode)
2783     {
2784       vam->async_errors += (retval < 0);
2785     }
2786   else
2787     {
2788       vam->retval = retval;
2789       vam->result_ready = 1;
2790     }
2791
2792   /* "Should never happen..." */
2793   if (retval != 0)
2794     return;
2795
2796   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2797   pvt_copy = vec_dup (reply);
2798
2799   /* Toss the shared-memory original... */
2800   pthread_mutex_lock (&am->vlib_rp->mutex);
2801   oldheap = svm_push_data_heap (am->vlib_rp);
2802
2803   vec_free (reply);
2804
2805   svm_pop_heap (oldheap);
2806   pthread_mutex_unlock (&am->vlib_rp->mutex);
2807
2808   if (vam->graph_nodes)
2809     {
2810       hash_free (vam->graph_node_index_by_name);
2811
2812       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2813         {
2814           node = vam->graph_nodes[0][i];
2815           vec_free (node->name);
2816           vec_free (node->next_nodes);
2817           vec_free (node);
2818         }
2819       vec_free (vam->graph_nodes[0]);
2820       vec_free (vam->graph_nodes);
2821     }
2822
2823   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2824   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2825   vec_free (pvt_copy);
2826
2827   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2828     {
2829       node = vam->graph_nodes[0][i];
2830       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2831     }
2832 }
2833
2834 static void vl_api_get_node_graph_reply_t_handler_json
2835   (vl_api_get_node_graph_reply_t * mp)
2836 {
2837   vat_main_t *vam = &vat_main;
2838   api_main_t *am = &api_main;
2839   void *oldheap;
2840   vat_json_node_t node;
2841   u8 *reply;
2842
2843   /* $$$$ make this real? */
2844   vat_json_init_object (&node);
2845   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2846   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2847
2848   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2849
2850   /* Toss the shared-memory original... */
2851   pthread_mutex_lock (&am->vlib_rp->mutex);
2852   oldheap = svm_push_data_heap (am->vlib_rp);
2853
2854   vec_free (reply);
2855
2856   svm_pop_heap (oldheap);
2857   pthread_mutex_unlock (&am->vlib_rp->mutex);
2858
2859   vat_json_print (vam->ofp, &node);
2860   vat_json_free (&node);
2861
2862   vam->retval = ntohl (mp->retval);
2863   vam->result_ready = 1;
2864 }
2865
2866 static void
2867 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2868 {
2869   vat_main_t *vam = &vat_main;
2870   u8 *s = 0;
2871
2872   if (mp->local)
2873     {
2874       s = format (s, "%=16d%=16d%=16d",
2875                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2876     }
2877   else
2878     {
2879       s = format (s, "%=16U%=16d%=16d",
2880                   mp->is_ipv6 ? format_ip6_address :
2881                   format_ip4_address,
2882                   mp->ip_address, mp->priority, mp->weight);
2883     }
2884
2885   print (vam->ofp, "%v", s);
2886   vec_free (s);
2887 }
2888
2889 static void
2890 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2891 {
2892   vat_main_t *vam = &vat_main;
2893   vat_json_node_t *node = NULL;
2894   struct in6_addr ip6;
2895   struct in_addr ip4;
2896
2897   if (VAT_JSON_ARRAY != vam->json_tree.type)
2898     {
2899       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2900       vat_json_init_array (&vam->json_tree);
2901     }
2902   node = vat_json_array_add (&vam->json_tree);
2903   vat_json_init_object (node);
2904
2905   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2906   vat_json_object_add_uint (node, "priority", mp->priority);
2907   vat_json_object_add_uint (node, "weight", mp->weight);
2908
2909   if (mp->local)
2910     vat_json_object_add_uint (node, "sw_if_index",
2911                               clib_net_to_host_u32 (mp->sw_if_index));
2912   else
2913     {
2914       if (mp->is_ipv6)
2915         {
2916           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2917           vat_json_object_add_ip6 (node, "address", ip6);
2918         }
2919       else
2920         {
2921           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2922           vat_json_object_add_ip4 (node, "address", ip4);
2923         }
2924     }
2925 }
2926
2927 static void
2928 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2929                                           mp)
2930 {
2931   vat_main_t *vam = &vat_main;
2932   u8 *ls_name = 0;
2933
2934   ls_name = format (0, "%s", mp->ls_name);
2935
2936   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2937          ls_name);
2938   vec_free (ls_name);
2939 }
2940
2941 static void
2942   vl_api_one_locator_set_details_t_handler_json
2943   (vl_api_one_locator_set_details_t * mp)
2944 {
2945   vat_main_t *vam = &vat_main;
2946   vat_json_node_t *node = 0;
2947   u8 *ls_name = 0;
2948
2949   ls_name = format (0, "%s", mp->ls_name);
2950   vec_add1 (ls_name, 0);
2951
2952   if (VAT_JSON_ARRAY != vam->json_tree.type)
2953     {
2954       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2955       vat_json_init_array (&vam->json_tree);
2956     }
2957   node = vat_json_array_add (&vam->json_tree);
2958
2959   vat_json_init_object (node);
2960   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2961   vat_json_object_add_uint (node, "ls_index",
2962                             clib_net_to_host_u32 (mp->ls_index));
2963   vec_free (ls_name);
2964 }
2965
2966 typedef struct
2967 {
2968   u32 spi;
2969   u8 si;
2970 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2971
2972 uword
2973 unformat_nsh_address (unformat_input_t * input, va_list * args)
2974 {
2975   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2976   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2977 }
2978
2979 u8 *
2980 format_nsh_address_vat (u8 * s, va_list * args)
2981 {
2982   nsh_t *a = va_arg (*args, nsh_t *);
2983   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2984 }
2985
2986 static u8 *
2987 format_lisp_flat_eid (u8 * s, va_list * args)
2988 {
2989   u32 type = va_arg (*args, u32);
2990   u8 *eid = va_arg (*args, u8 *);
2991   u32 eid_len = va_arg (*args, u32);
2992
2993   switch (type)
2994     {
2995     case 0:
2996       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2997     case 1:
2998       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2999     case 2:
3000       return format (s, "%U", format_ethernet_address, eid);
3001     case 3:
3002       return format (s, "%U", format_nsh_address_vat, eid);
3003     }
3004   return 0;
3005 }
3006
3007 static u8 *
3008 format_lisp_eid_vat (u8 * s, va_list * args)
3009 {
3010   u32 type = va_arg (*args, u32);
3011   u8 *eid = va_arg (*args, u8 *);
3012   u32 eid_len = va_arg (*args, u32);
3013   u8 *seid = va_arg (*args, u8 *);
3014   u32 seid_len = va_arg (*args, u32);
3015   u32 is_src_dst = va_arg (*args, u32);
3016
3017   if (is_src_dst)
3018     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3019
3020   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3021
3022   return s;
3023 }
3024
3025 static void
3026 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3027 {
3028   vat_main_t *vam = &vat_main;
3029   u8 *s = 0, *eid = 0;
3030
3031   if (~0 == mp->locator_set_index)
3032     s = format (0, "action: %d", mp->action);
3033   else
3034     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3035
3036   eid = format (0, "%U", format_lisp_eid_vat,
3037                 mp->eid_type,
3038                 mp->eid,
3039                 mp->eid_prefix_len,
3040                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3041   vec_add1 (eid, 0);
3042
3043   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3044          clib_net_to_host_u32 (mp->vni),
3045          eid,
3046          mp->is_local ? "local" : "remote",
3047          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3048          clib_net_to_host_u16 (mp->key_id), mp->key);
3049
3050   vec_free (s);
3051   vec_free (eid);
3052 }
3053
3054 static void
3055 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3056                                              * mp)
3057 {
3058   vat_main_t *vam = &vat_main;
3059   vat_json_node_t *node = 0;
3060   u8 *eid = 0;
3061
3062   if (VAT_JSON_ARRAY != vam->json_tree.type)
3063     {
3064       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3065       vat_json_init_array (&vam->json_tree);
3066     }
3067   node = vat_json_array_add (&vam->json_tree);
3068
3069   vat_json_init_object (node);
3070   if (~0 == mp->locator_set_index)
3071     vat_json_object_add_uint (node, "action", mp->action);
3072   else
3073     vat_json_object_add_uint (node, "locator_set_index",
3074                               clib_net_to_host_u32 (mp->locator_set_index));
3075
3076   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3077   if (mp->eid_type == 3)
3078     {
3079       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3080       vat_json_init_object (nsh_json);
3081       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3082       vat_json_object_add_uint (nsh_json, "spi",
3083                                 clib_net_to_host_u32 (nsh->spi));
3084       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3085     }
3086   else
3087     {
3088       eid = format (0, "%U", format_lisp_eid_vat,
3089                     mp->eid_type,
3090                     mp->eid,
3091                     mp->eid_prefix_len,
3092                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3093       vec_add1 (eid, 0);
3094       vat_json_object_add_string_copy (node, "eid", eid);
3095       vec_free (eid);
3096     }
3097   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3098   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3099   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3100
3101   if (mp->key_id)
3102     {
3103       vat_json_object_add_uint (node, "key_id",
3104                                 clib_net_to_host_u16 (mp->key_id));
3105       vat_json_object_add_string_copy (node, "key", mp->key);
3106     }
3107 }
3108
3109 static void
3110 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3111 {
3112   vat_main_t *vam = &vat_main;
3113   u8 *seid = 0, *deid = 0;
3114   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3115
3116   deid = format (0, "%U", format_lisp_eid_vat,
3117                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3118
3119   seid = format (0, "%U", format_lisp_eid_vat,
3120                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3121
3122   vec_add1 (deid, 0);
3123   vec_add1 (seid, 0);
3124
3125   if (mp->is_ip4)
3126     format_ip_address_fcn = format_ip4_address;
3127   else
3128     format_ip_address_fcn = format_ip6_address;
3129
3130
3131   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3132          clib_net_to_host_u32 (mp->vni),
3133          seid, deid,
3134          format_ip_address_fcn, mp->lloc,
3135          format_ip_address_fcn, mp->rloc,
3136          clib_net_to_host_u32 (mp->pkt_count),
3137          clib_net_to_host_u32 (mp->bytes));
3138
3139   vec_free (deid);
3140   vec_free (seid);
3141 }
3142
3143 static void
3144 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3145 {
3146   struct in6_addr ip6;
3147   struct in_addr ip4;
3148   vat_main_t *vam = &vat_main;
3149   vat_json_node_t *node = 0;
3150   u8 *deid = 0, *seid = 0;
3151
3152   if (VAT_JSON_ARRAY != vam->json_tree.type)
3153     {
3154       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3155       vat_json_init_array (&vam->json_tree);
3156     }
3157   node = vat_json_array_add (&vam->json_tree);
3158
3159   vat_json_init_object (node);
3160   deid = format (0, "%U", format_lisp_eid_vat,
3161                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3162
3163   seid = format (0, "%U", format_lisp_eid_vat,
3164                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3165
3166   vec_add1 (deid, 0);
3167   vec_add1 (seid, 0);
3168
3169   vat_json_object_add_string_copy (node, "seid", seid);
3170   vat_json_object_add_string_copy (node, "deid", deid);
3171   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3172
3173   if (mp->is_ip4)
3174     {
3175       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3176       vat_json_object_add_ip4 (node, "lloc", ip4);
3177       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3178       vat_json_object_add_ip4 (node, "rloc", ip4);
3179     }
3180   else
3181     {
3182       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3183       vat_json_object_add_ip6 (node, "lloc", ip6);
3184       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3185       vat_json_object_add_ip6 (node, "rloc", ip6);
3186     }
3187   vat_json_object_add_uint (node, "pkt_count",
3188                             clib_net_to_host_u32 (mp->pkt_count));
3189   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3190
3191   vec_free (deid);
3192   vec_free (seid);
3193 }
3194
3195 static void
3196   vl_api_one_eid_table_map_details_t_handler
3197   (vl_api_one_eid_table_map_details_t * mp)
3198 {
3199   vat_main_t *vam = &vat_main;
3200
3201   u8 *line = format (0, "%=10d%=10d",
3202                      clib_net_to_host_u32 (mp->vni),
3203                      clib_net_to_host_u32 (mp->dp_table));
3204   print (vam->ofp, "%v", line);
3205   vec_free (line);
3206 }
3207
3208 static void
3209   vl_api_one_eid_table_map_details_t_handler_json
3210   (vl_api_one_eid_table_map_details_t * mp)
3211 {
3212   vat_main_t *vam = &vat_main;
3213   vat_json_node_t *node = NULL;
3214
3215   if (VAT_JSON_ARRAY != vam->json_tree.type)
3216     {
3217       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3218       vat_json_init_array (&vam->json_tree);
3219     }
3220   node = vat_json_array_add (&vam->json_tree);
3221   vat_json_init_object (node);
3222   vat_json_object_add_uint (node, "dp_table",
3223                             clib_net_to_host_u32 (mp->dp_table));
3224   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3225 }
3226
3227 static void
3228   vl_api_one_eid_table_vni_details_t_handler
3229   (vl_api_one_eid_table_vni_details_t * mp)
3230 {
3231   vat_main_t *vam = &vat_main;
3232
3233   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3234   print (vam->ofp, "%v", line);
3235   vec_free (line);
3236 }
3237
3238 static void
3239   vl_api_one_eid_table_vni_details_t_handler_json
3240   (vl_api_one_eid_table_vni_details_t * mp)
3241 {
3242   vat_main_t *vam = &vat_main;
3243   vat_json_node_t *node = NULL;
3244
3245   if (VAT_JSON_ARRAY != vam->json_tree.type)
3246     {
3247       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3248       vat_json_init_array (&vam->json_tree);
3249     }
3250   node = vat_json_array_add (&vam->json_tree);
3251   vat_json_init_object (node);
3252   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3253 }
3254
3255 static void
3256   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3257   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3258 {
3259   vat_main_t *vam = &vat_main;
3260   int retval = clib_net_to_host_u32 (mp->retval);
3261
3262   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3263   print (vam->ofp, "fallback threshold value: %d", mp->value);
3264
3265   vam->retval = retval;
3266   vam->result_ready = 1;
3267 }
3268
3269 static void
3270   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3271   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3272 {
3273   vat_main_t *vam = &vat_main;
3274   vat_json_node_t _node, *node = &_node;
3275   int retval = clib_net_to_host_u32 (mp->retval);
3276
3277   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3278   vat_json_init_object (node);
3279   vat_json_object_add_uint (node, "value", mp->value);
3280
3281   vat_json_print (vam->ofp, node);
3282   vat_json_free (node);
3283
3284   vam->retval = retval;
3285   vam->result_ready = 1;
3286 }
3287
3288 static void
3289   vl_api_show_one_map_register_state_reply_t_handler
3290   (vl_api_show_one_map_register_state_reply_t * mp)
3291 {
3292   vat_main_t *vam = &vat_main;
3293   int retval = clib_net_to_host_u32 (mp->retval);
3294
3295   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3296
3297   vam->retval = retval;
3298   vam->result_ready = 1;
3299 }
3300
3301 static void
3302   vl_api_show_one_map_register_state_reply_t_handler_json
3303   (vl_api_show_one_map_register_state_reply_t * mp)
3304 {
3305   vat_main_t *vam = &vat_main;
3306   vat_json_node_t _node, *node = &_node;
3307   int retval = clib_net_to_host_u32 (mp->retval);
3308
3309   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3310
3311   vat_json_init_object (node);
3312   vat_json_object_add_string_copy (node, "state", s);
3313
3314   vat_json_print (vam->ofp, node);
3315   vat_json_free (node);
3316
3317   vam->retval = retval;
3318   vam->result_ready = 1;
3319   vec_free (s);
3320 }
3321
3322 static void
3323   vl_api_show_one_rloc_probe_state_reply_t_handler
3324   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3325 {
3326   vat_main_t *vam = &vat_main;
3327   int retval = clib_net_to_host_u32 (mp->retval);
3328
3329   if (retval)
3330     goto end;
3331
3332   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3333 end:
3334   vam->retval = retval;
3335   vam->result_ready = 1;
3336 }
3337
3338 static void
3339   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3340   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3341 {
3342   vat_main_t *vam = &vat_main;
3343   vat_json_node_t _node, *node = &_node;
3344   int retval = clib_net_to_host_u32 (mp->retval);
3345
3346   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3347   vat_json_init_object (node);
3348   vat_json_object_add_string_copy (node, "state", s);
3349
3350   vat_json_print (vam->ofp, node);
3351   vat_json_free (node);
3352
3353   vam->retval = retval;
3354   vam->result_ready = 1;
3355   vec_free (s);
3356 }
3357
3358 static void
3359   vl_api_show_one_stats_enable_disable_reply_t_handler
3360   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3361 {
3362   vat_main_t *vam = &vat_main;
3363   int retval = clib_net_to_host_u32 (mp->retval);
3364
3365   if (retval)
3366     goto end;
3367
3368   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3369 end:
3370   vam->retval = retval;
3371   vam->result_ready = 1;
3372 }
3373
3374 static void
3375   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3376   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3377 {
3378   vat_main_t *vam = &vat_main;
3379   vat_json_node_t _node, *node = &_node;
3380   int retval = clib_net_to_host_u32 (mp->retval);
3381
3382   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3383   vat_json_init_object (node);
3384   vat_json_object_add_string_copy (node, "state", s);
3385
3386   vat_json_print (vam->ofp, node);
3387   vat_json_free (node);
3388
3389   vam->retval = retval;
3390   vam->result_ready = 1;
3391   vec_free (s);
3392 }
3393
3394 static void
3395 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3396 {
3397   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3398   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3399   e->vni = clib_net_to_host_u32 (e->vni);
3400 }
3401
3402 static void
3403   gpe_fwd_entries_get_reply_t_net_to_host
3404   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3405 {
3406   u32 i;
3407
3408   mp->count = clib_net_to_host_u32 (mp->count);
3409   for (i = 0; i < mp->count; i++)
3410     {
3411       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3412     }
3413 }
3414
3415 static u8 *
3416 format_gpe_encap_mode (u8 * s, va_list * args)
3417 {
3418   u32 mode = va_arg (*args, u32);
3419
3420   switch (mode)
3421     {
3422     case 0:
3423       return format (s, "lisp");
3424     case 1:
3425       return format (s, "vxlan");
3426     }
3427   return 0;
3428 }
3429
3430 static void
3431   vl_api_gpe_get_encap_mode_reply_t_handler
3432   (vl_api_gpe_get_encap_mode_reply_t * mp)
3433 {
3434   vat_main_t *vam = &vat_main;
3435
3436   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3437   vam->retval = ntohl (mp->retval);
3438   vam->result_ready = 1;
3439 }
3440
3441 static void
3442   vl_api_gpe_get_encap_mode_reply_t_handler_json
3443   (vl_api_gpe_get_encap_mode_reply_t * mp)
3444 {
3445   vat_main_t *vam = &vat_main;
3446   vat_json_node_t node;
3447
3448   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3449   vec_add1 (encap_mode, 0);
3450
3451   vat_json_init_object (&node);
3452   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3453
3454   vec_free (encap_mode);
3455   vat_json_print (vam->ofp, &node);
3456   vat_json_free (&node);
3457
3458   vam->retval = ntohl (mp->retval);
3459   vam->result_ready = 1;
3460 }
3461
3462 static void
3463   vl_api_gpe_fwd_entry_path_details_t_handler
3464   (vl_api_gpe_fwd_entry_path_details_t * mp)
3465 {
3466   vat_main_t *vam = &vat_main;
3467   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3468
3469   if (mp->lcl_loc.is_ip4)
3470     format_ip_address_fcn = format_ip4_address;
3471   else
3472     format_ip_address_fcn = format_ip6_address;
3473
3474   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3475          format_ip_address_fcn, &mp->lcl_loc,
3476          format_ip_address_fcn, &mp->rmt_loc);
3477 }
3478
3479 static void
3480 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3481 {
3482   struct in6_addr ip6;
3483   struct in_addr ip4;
3484
3485   if (loc->is_ip4)
3486     {
3487       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3488       vat_json_object_add_ip4 (n, "address", ip4);
3489     }
3490   else
3491     {
3492       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3493       vat_json_object_add_ip6 (n, "address", ip6);
3494     }
3495   vat_json_object_add_uint (n, "weight", loc->weight);
3496 }
3497
3498 static void
3499   vl_api_gpe_fwd_entry_path_details_t_handler_json
3500   (vl_api_gpe_fwd_entry_path_details_t * mp)
3501 {
3502   vat_main_t *vam = &vat_main;
3503   vat_json_node_t *node = NULL;
3504   vat_json_node_t *loc_node;
3505
3506   if (VAT_JSON_ARRAY != vam->json_tree.type)
3507     {
3508       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3509       vat_json_init_array (&vam->json_tree);
3510     }
3511   node = vat_json_array_add (&vam->json_tree);
3512   vat_json_init_object (node);
3513
3514   loc_node = vat_json_object_add (node, "local_locator");
3515   vat_json_init_object (loc_node);
3516   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3517
3518   loc_node = vat_json_object_add (node, "remote_locator");
3519   vat_json_init_object (loc_node);
3520   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3521 }
3522
3523 static void
3524   vl_api_gpe_fwd_entries_get_reply_t_handler
3525   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3526 {
3527   vat_main_t *vam = &vat_main;
3528   u32 i;
3529   int retval = clib_net_to_host_u32 (mp->retval);
3530   vl_api_gpe_fwd_entry_t *e;
3531
3532   if (retval)
3533     goto end;
3534
3535   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3536
3537   for (i = 0; i < mp->count; i++)
3538     {
3539       e = &mp->entries[i];
3540       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3541              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3542              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3543     }
3544
3545 end:
3546   vam->retval = retval;
3547   vam->result_ready = 1;
3548 }
3549
3550 static void
3551   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3552   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3553 {
3554   u8 *s = 0;
3555   vat_main_t *vam = &vat_main;
3556   vat_json_node_t *e = 0, root;
3557   u32 i;
3558   int retval = clib_net_to_host_u32 (mp->retval);
3559   vl_api_gpe_fwd_entry_t *fwd;
3560
3561   if (retval)
3562     goto end;
3563
3564   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3565   vat_json_init_array (&root);
3566
3567   for (i = 0; i < mp->count; i++)
3568     {
3569       e = vat_json_array_add (&root);
3570       fwd = &mp->entries[i];
3571
3572       vat_json_init_object (e);
3573       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3574       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3575       vat_json_object_add_int (e, "vni", fwd->vni);
3576       vat_json_object_add_int (e, "action", fwd->action);
3577
3578       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3579                   fwd->leid_prefix_len);
3580       vec_add1 (s, 0);
3581       vat_json_object_add_string_copy (e, "leid", s);
3582       vec_free (s);
3583
3584       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3585                   fwd->reid_prefix_len);
3586       vec_add1 (s, 0);
3587       vat_json_object_add_string_copy (e, "reid", s);
3588       vec_free (s);
3589     }
3590
3591   vat_json_print (vam->ofp, &root);
3592   vat_json_free (&root);
3593
3594 end:
3595   vam->retval = retval;
3596   vam->result_ready = 1;
3597 }
3598
3599 static void
3600   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3601   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3602 {
3603   vat_main_t *vam = &vat_main;
3604   u32 i, n;
3605   int retval = clib_net_to_host_u32 (mp->retval);
3606   vl_api_gpe_native_fwd_rpath_t *r;
3607
3608   if (retval)
3609     goto end;
3610
3611   n = clib_net_to_host_u32 (mp->count);
3612
3613   for (i = 0; i < n; i++)
3614     {
3615       r = &mp->entries[i];
3616       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3617              clib_net_to_host_u32 (r->fib_index),
3618              clib_net_to_host_u32 (r->nh_sw_if_index),
3619              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3620     }
3621
3622 end:
3623   vam->retval = retval;
3624   vam->result_ready = 1;
3625 }
3626
3627 static void
3628   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3629   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3630 {
3631   vat_main_t *vam = &vat_main;
3632   vat_json_node_t root, *e;
3633   u32 i, n;
3634   int retval = clib_net_to_host_u32 (mp->retval);
3635   vl_api_gpe_native_fwd_rpath_t *r;
3636   u8 *s;
3637
3638   if (retval)
3639     goto end;
3640
3641   n = clib_net_to_host_u32 (mp->count);
3642   vat_json_init_array (&root);
3643
3644   for (i = 0; i < n; i++)
3645     {
3646       e = vat_json_array_add (&root);
3647       vat_json_init_object (e);
3648       r = &mp->entries[i];
3649       s =
3650         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3651                 r->nh_addr);
3652       vec_add1 (s, 0);
3653       vat_json_object_add_string_copy (e, "ip4", s);
3654       vec_free (s);
3655
3656       vat_json_object_add_uint (e, "fib_index",
3657                                 clib_net_to_host_u32 (r->fib_index));
3658       vat_json_object_add_uint (e, "nh_sw_if_index",
3659                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3660     }
3661
3662   vat_json_print (vam->ofp, &root);
3663   vat_json_free (&root);
3664
3665 end:
3666   vam->retval = retval;
3667   vam->result_ready = 1;
3668 }
3669
3670 static void
3671   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3672   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3673 {
3674   vat_main_t *vam = &vat_main;
3675   u32 i, n;
3676   int retval = clib_net_to_host_u32 (mp->retval);
3677
3678   if (retval)
3679     goto end;
3680
3681   n = clib_net_to_host_u32 (mp->count);
3682
3683   for (i = 0; i < n; i++)
3684     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3685
3686 end:
3687   vam->retval = retval;
3688   vam->result_ready = 1;
3689 }
3690
3691 static void
3692   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3693   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3694 {
3695   vat_main_t *vam = &vat_main;
3696   vat_json_node_t root;
3697   u32 i, n;
3698   int retval = clib_net_to_host_u32 (mp->retval);
3699
3700   if (retval)
3701     goto end;
3702
3703   n = clib_net_to_host_u32 (mp->count);
3704   vat_json_init_array (&root);
3705
3706   for (i = 0; i < n; i++)
3707     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3708
3709   vat_json_print (vam->ofp, &root);
3710   vat_json_free (&root);
3711
3712 end:
3713   vam->retval = retval;
3714   vam->result_ready = 1;
3715 }
3716
3717 static void
3718   vl_api_one_ndp_entries_get_reply_t_handler
3719   (vl_api_one_ndp_entries_get_reply_t * mp)
3720 {
3721   vat_main_t *vam = &vat_main;
3722   u32 i, n;
3723   int retval = clib_net_to_host_u32 (mp->retval);
3724
3725   if (retval)
3726     goto end;
3727
3728   n = clib_net_to_host_u32 (mp->count);
3729
3730   for (i = 0; i < n; i++)
3731     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3732            format_ethernet_address, mp->entries[i].mac);
3733
3734 end:
3735   vam->retval = retval;
3736   vam->result_ready = 1;
3737 }
3738
3739 static void
3740   vl_api_one_ndp_entries_get_reply_t_handler_json
3741   (vl_api_one_ndp_entries_get_reply_t * mp)
3742 {
3743   u8 *s = 0;
3744   vat_main_t *vam = &vat_main;
3745   vat_json_node_t *e = 0, root;
3746   u32 i, n;
3747   int retval = clib_net_to_host_u32 (mp->retval);
3748   vl_api_one_ndp_entry_t *arp_entry;
3749
3750   if (retval)
3751     goto end;
3752
3753   n = clib_net_to_host_u32 (mp->count);
3754   vat_json_init_array (&root);
3755
3756   for (i = 0; i < n; i++)
3757     {
3758       e = vat_json_array_add (&root);
3759       arp_entry = &mp->entries[i];
3760
3761       vat_json_init_object (e);
3762       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3763       vec_add1 (s, 0);
3764
3765       vat_json_object_add_string_copy (e, "mac", s);
3766       vec_free (s);
3767
3768       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3769       vec_add1 (s, 0);
3770       vat_json_object_add_string_copy (e, "ip6", s);
3771       vec_free (s);
3772     }
3773
3774   vat_json_print (vam->ofp, &root);
3775   vat_json_free (&root);
3776
3777 end:
3778   vam->retval = retval;
3779   vam->result_ready = 1;
3780 }
3781
3782 static void
3783   vl_api_one_l2_arp_entries_get_reply_t_handler
3784   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3785 {
3786   vat_main_t *vam = &vat_main;
3787   u32 i, n;
3788   int retval = clib_net_to_host_u32 (mp->retval);
3789
3790   if (retval)
3791     goto end;
3792
3793   n = clib_net_to_host_u32 (mp->count);
3794
3795   for (i = 0; i < n; i++)
3796     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3797            format_ethernet_address, mp->entries[i].mac);
3798
3799 end:
3800   vam->retval = retval;
3801   vam->result_ready = 1;
3802 }
3803
3804 static void
3805   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3806   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3807 {
3808   u8 *s = 0;
3809   vat_main_t *vam = &vat_main;
3810   vat_json_node_t *e = 0, root;
3811   u32 i, n;
3812   int retval = clib_net_to_host_u32 (mp->retval);
3813   vl_api_one_l2_arp_entry_t *arp_entry;
3814
3815   if (retval)
3816     goto end;
3817
3818   n = clib_net_to_host_u32 (mp->count);
3819   vat_json_init_array (&root);
3820
3821   for (i = 0; i < n; i++)
3822     {
3823       e = vat_json_array_add (&root);
3824       arp_entry = &mp->entries[i];
3825
3826       vat_json_init_object (e);
3827       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3828       vec_add1 (s, 0);
3829
3830       vat_json_object_add_string_copy (e, "mac", s);
3831       vec_free (s);
3832
3833       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3834       vec_add1 (s, 0);
3835       vat_json_object_add_string_copy (e, "ip4", s);
3836       vec_free (s);
3837     }
3838
3839   vat_json_print (vam->ofp, &root);
3840   vat_json_free (&root);
3841
3842 end:
3843   vam->retval = retval;
3844   vam->result_ready = 1;
3845 }
3846
3847 static void
3848 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3849 {
3850   vat_main_t *vam = &vat_main;
3851   u32 i, n;
3852   int retval = clib_net_to_host_u32 (mp->retval);
3853
3854   if (retval)
3855     goto end;
3856
3857   n = clib_net_to_host_u32 (mp->count);
3858
3859   for (i = 0; i < n; i++)
3860     {
3861       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3862     }
3863
3864 end:
3865   vam->retval = retval;
3866   vam->result_ready = 1;
3867 }
3868
3869 static void
3870   vl_api_one_ndp_bd_get_reply_t_handler_json
3871   (vl_api_one_ndp_bd_get_reply_t * mp)
3872 {
3873   vat_main_t *vam = &vat_main;
3874   vat_json_node_t root;
3875   u32 i, n;
3876   int retval = clib_net_to_host_u32 (mp->retval);
3877
3878   if (retval)
3879     goto end;
3880
3881   n = clib_net_to_host_u32 (mp->count);
3882   vat_json_init_array (&root);
3883
3884   for (i = 0; i < n; i++)
3885     {
3886       vat_json_array_add_uint (&root,
3887                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3888     }
3889
3890   vat_json_print (vam->ofp, &root);
3891   vat_json_free (&root);
3892
3893 end:
3894   vam->retval = retval;
3895   vam->result_ready = 1;
3896 }
3897
3898 static void
3899   vl_api_one_l2_arp_bd_get_reply_t_handler
3900   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3901 {
3902   vat_main_t *vam = &vat_main;
3903   u32 i, n;
3904   int retval = clib_net_to_host_u32 (mp->retval);
3905
3906   if (retval)
3907     goto end;
3908
3909   n = clib_net_to_host_u32 (mp->count);
3910
3911   for (i = 0; i < n; i++)
3912     {
3913       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3914     }
3915
3916 end:
3917   vam->retval = retval;
3918   vam->result_ready = 1;
3919 }
3920
3921 static void
3922   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3923   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3924 {
3925   vat_main_t *vam = &vat_main;
3926   vat_json_node_t root;
3927   u32 i, n;
3928   int retval = clib_net_to_host_u32 (mp->retval);
3929
3930   if (retval)
3931     goto end;
3932
3933   n = clib_net_to_host_u32 (mp->count);
3934   vat_json_init_array (&root);
3935
3936   for (i = 0; i < n; i++)
3937     {
3938       vat_json_array_add_uint (&root,
3939                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3940     }
3941
3942   vat_json_print (vam->ofp, &root);
3943   vat_json_free (&root);
3944
3945 end:
3946   vam->retval = retval;
3947   vam->result_ready = 1;
3948 }
3949
3950 static void
3951   vl_api_one_adjacencies_get_reply_t_handler
3952   (vl_api_one_adjacencies_get_reply_t * mp)
3953 {
3954   vat_main_t *vam = &vat_main;
3955   u32 i, n;
3956   int retval = clib_net_to_host_u32 (mp->retval);
3957   vl_api_one_adjacency_t *a;
3958
3959   if (retval)
3960     goto end;
3961
3962   n = clib_net_to_host_u32 (mp->count);
3963
3964   for (i = 0; i < n; i++)
3965     {
3966       a = &mp->adjacencies[i];
3967       print (vam->ofp, "%U %40U",
3968              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3969              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3970     }
3971
3972 end:
3973   vam->retval = retval;
3974   vam->result_ready = 1;
3975 }
3976
3977 static void
3978   vl_api_one_adjacencies_get_reply_t_handler_json
3979   (vl_api_one_adjacencies_get_reply_t * mp)
3980 {
3981   u8 *s = 0;
3982   vat_main_t *vam = &vat_main;
3983   vat_json_node_t *e = 0, root;
3984   u32 i, n;
3985   int retval = clib_net_to_host_u32 (mp->retval);
3986   vl_api_one_adjacency_t *a;
3987
3988   if (retval)
3989     goto end;
3990
3991   n = clib_net_to_host_u32 (mp->count);
3992   vat_json_init_array (&root);
3993
3994   for (i = 0; i < n; i++)
3995     {
3996       e = vat_json_array_add (&root);
3997       a = &mp->adjacencies[i];
3998
3999       vat_json_init_object (e);
4000       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
4001                   a->leid_prefix_len);
4002       vec_add1 (s, 0);
4003       vat_json_object_add_string_copy (e, "leid", s);
4004       vec_free (s);
4005
4006       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4007                   a->reid_prefix_len);
4008       vec_add1 (s, 0);
4009       vat_json_object_add_string_copy (e, "reid", s);
4010       vec_free (s);
4011     }
4012
4013   vat_json_print (vam->ofp, &root);
4014   vat_json_free (&root);
4015
4016 end:
4017   vam->retval = retval;
4018   vam->result_ready = 1;
4019 }
4020
4021 static void
4022 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4023 {
4024   vat_main_t *vam = &vat_main;
4025
4026   print (vam->ofp, "%=20U",
4027          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4028          mp->ip_address);
4029 }
4030
4031 static void
4032   vl_api_one_map_server_details_t_handler_json
4033   (vl_api_one_map_server_details_t * mp)
4034 {
4035   vat_main_t *vam = &vat_main;
4036   vat_json_node_t *node = NULL;
4037   struct in6_addr ip6;
4038   struct in_addr ip4;
4039
4040   if (VAT_JSON_ARRAY != vam->json_tree.type)
4041     {
4042       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4043       vat_json_init_array (&vam->json_tree);
4044     }
4045   node = vat_json_array_add (&vam->json_tree);
4046
4047   vat_json_init_object (node);
4048   if (mp->is_ipv6)
4049     {
4050       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4051       vat_json_object_add_ip6 (node, "map-server", ip6);
4052     }
4053   else
4054     {
4055       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4056       vat_json_object_add_ip4 (node, "map-server", ip4);
4057     }
4058 }
4059
4060 static void
4061 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4062                                            * mp)
4063 {
4064   vat_main_t *vam = &vat_main;
4065
4066   print (vam->ofp, "%=20U",
4067          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4068          mp->ip_address);
4069 }
4070
4071 static void
4072   vl_api_one_map_resolver_details_t_handler_json
4073   (vl_api_one_map_resolver_details_t * mp)
4074 {
4075   vat_main_t *vam = &vat_main;
4076   vat_json_node_t *node = NULL;
4077   struct in6_addr ip6;
4078   struct in_addr ip4;
4079
4080   if (VAT_JSON_ARRAY != vam->json_tree.type)
4081     {
4082       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4083       vat_json_init_array (&vam->json_tree);
4084     }
4085   node = vat_json_array_add (&vam->json_tree);
4086
4087   vat_json_init_object (node);
4088   if (mp->is_ipv6)
4089     {
4090       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4091       vat_json_object_add_ip6 (node, "map resolver", ip6);
4092     }
4093   else
4094     {
4095       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4096       vat_json_object_add_ip4 (node, "map resolver", ip4);
4097     }
4098 }
4099
4100 static void
4101 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4102 {
4103   vat_main_t *vam = &vat_main;
4104   i32 retval = ntohl (mp->retval);
4105
4106   if (0 <= retval)
4107     {
4108       print (vam->ofp, "feature: %s\ngpe: %s",
4109              mp->feature_status ? "enabled" : "disabled",
4110              mp->gpe_status ? "enabled" : "disabled");
4111     }
4112
4113   vam->retval = retval;
4114   vam->result_ready = 1;
4115 }
4116
4117 static void
4118   vl_api_show_one_status_reply_t_handler_json
4119   (vl_api_show_one_status_reply_t * mp)
4120 {
4121   vat_main_t *vam = &vat_main;
4122   vat_json_node_t node;
4123   u8 *gpe_status = NULL;
4124   u8 *feature_status = NULL;
4125
4126   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4127   feature_status = format (0, "%s",
4128                            mp->feature_status ? "enabled" : "disabled");
4129   vec_add1 (gpe_status, 0);
4130   vec_add1 (feature_status, 0);
4131
4132   vat_json_init_object (&node);
4133   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4134   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4135
4136   vec_free (gpe_status);
4137   vec_free (feature_status);
4138
4139   vat_json_print (vam->ofp, &node);
4140   vat_json_free (&node);
4141
4142   vam->retval = ntohl (mp->retval);
4143   vam->result_ready = 1;
4144 }
4145
4146 static void
4147   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4148   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4149 {
4150   vat_main_t *vam = &vat_main;
4151   i32 retval = ntohl (mp->retval);
4152
4153   if (retval >= 0)
4154     {
4155       print (vam->ofp, "%=20s", mp->locator_set_name);
4156     }
4157
4158   vam->retval = retval;
4159   vam->result_ready = 1;
4160 }
4161
4162 static void
4163   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4164   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4165 {
4166   vat_main_t *vam = &vat_main;
4167   vat_json_node_t *node = NULL;
4168
4169   if (VAT_JSON_ARRAY != vam->json_tree.type)
4170     {
4171       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4172       vat_json_init_array (&vam->json_tree);
4173     }
4174   node = vat_json_array_add (&vam->json_tree);
4175
4176   vat_json_init_object (node);
4177   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4178
4179   vat_json_print (vam->ofp, node);
4180   vat_json_free (node);
4181
4182   vam->retval = ntohl (mp->retval);
4183   vam->result_ready = 1;
4184 }
4185
4186 static u8 *
4187 format_lisp_map_request_mode (u8 * s, va_list * args)
4188 {
4189   u32 mode = va_arg (*args, u32);
4190
4191   switch (mode)
4192     {
4193     case 0:
4194       return format (0, "dst-only");
4195     case 1:
4196       return format (0, "src-dst");
4197     }
4198   return 0;
4199 }
4200
4201 static void
4202   vl_api_show_one_map_request_mode_reply_t_handler
4203   (vl_api_show_one_map_request_mode_reply_t * mp)
4204 {
4205   vat_main_t *vam = &vat_main;
4206   i32 retval = ntohl (mp->retval);
4207
4208   if (0 <= retval)
4209     {
4210       u32 mode = mp->mode;
4211       print (vam->ofp, "map_request_mode: %U",
4212              format_lisp_map_request_mode, mode);
4213     }
4214
4215   vam->retval = retval;
4216   vam->result_ready = 1;
4217 }
4218
4219 static void
4220   vl_api_show_one_map_request_mode_reply_t_handler_json
4221   (vl_api_show_one_map_request_mode_reply_t * mp)
4222 {
4223   vat_main_t *vam = &vat_main;
4224   vat_json_node_t node;
4225   u8 *s = 0;
4226   u32 mode;
4227
4228   mode = mp->mode;
4229   s = format (0, "%U", format_lisp_map_request_mode, mode);
4230   vec_add1 (s, 0);
4231
4232   vat_json_init_object (&node);
4233   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4234   vat_json_print (vam->ofp, &node);
4235   vat_json_free (&node);
4236
4237   vec_free (s);
4238   vam->retval = ntohl (mp->retval);
4239   vam->result_ready = 1;
4240 }
4241
4242 static void
4243   vl_api_one_show_xtr_mode_reply_t_handler
4244   (vl_api_one_show_xtr_mode_reply_t * mp)
4245 {
4246   vat_main_t *vam = &vat_main;
4247   i32 retval = ntohl (mp->retval);
4248
4249   if (0 <= retval)
4250     {
4251       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4252     }
4253
4254   vam->retval = retval;
4255   vam->result_ready = 1;
4256 }
4257
4258 static void
4259   vl_api_one_show_xtr_mode_reply_t_handler_json
4260   (vl_api_one_show_xtr_mode_reply_t * mp)
4261 {
4262   vat_main_t *vam = &vat_main;
4263   vat_json_node_t node;
4264   u8 *status = 0;
4265
4266   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4267   vec_add1 (status, 0);
4268
4269   vat_json_init_object (&node);
4270   vat_json_object_add_string_copy (&node, "status", status);
4271
4272   vec_free (status);
4273
4274   vat_json_print (vam->ofp, &node);
4275   vat_json_free (&node);
4276
4277   vam->retval = ntohl (mp->retval);
4278   vam->result_ready = 1;
4279 }
4280
4281 static void
4282   vl_api_one_show_pitr_mode_reply_t_handler
4283   (vl_api_one_show_pitr_mode_reply_t * mp)
4284 {
4285   vat_main_t *vam = &vat_main;
4286   i32 retval = ntohl (mp->retval);
4287
4288   if (0 <= retval)
4289     {
4290       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4291     }
4292
4293   vam->retval = retval;
4294   vam->result_ready = 1;
4295 }
4296
4297 static void
4298   vl_api_one_show_pitr_mode_reply_t_handler_json
4299   (vl_api_one_show_pitr_mode_reply_t * mp)
4300 {
4301   vat_main_t *vam = &vat_main;
4302   vat_json_node_t node;
4303   u8 *status = 0;
4304
4305   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4306   vec_add1 (status, 0);
4307
4308   vat_json_init_object (&node);
4309   vat_json_object_add_string_copy (&node, "status", status);
4310
4311   vec_free (status);
4312
4313   vat_json_print (vam->ofp, &node);
4314   vat_json_free (&node);
4315
4316   vam->retval = ntohl (mp->retval);
4317   vam->result_ready = 1;
4318 }
4319
4320 static void
4321   vl_api_one_show_petr_mode_reply_t_handler
4322   (vl_api_one_show_petr_mode_reply_t * mp)
4323 {
4324   vat_main_t *vam = &vat_main;
4325   i32 retval = ntohl (mp->retval);
4326
4327   if (0 <= retval)
4328     {
4329       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4330     }
4331
4332   vam->retval = retval;
4333   vam->result_ready = 1;
4334 }
4335
4336 static void
4337   vl_api_one_show_petr_mode_reply_t_handler_json
4338   (vl_api_one_show_petr_mode_reply_t * mp)
4339 {
4340   vat_main_t *vam = &vat_main;
4341   vat_json_node_t node;
4342   u8 *status = 0;
4343
4344   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4345   vec_add1 (status, 0);
4346
4347   vat_json_init_object (&node);
4348   vat_json_object_add_string_copy (&node, "status", status);
4349
4350   vec_free (status);
4351
4352   vat_json_print (vam->ofp, &node);
4353   vat_json_free (&node);
4354
4355   vam->retval = ntohl (mp->retval);
4356   vam->result_ready = 1;
4357 }
4358
4359 static void
4360   vl_api_show_one_use_petr_reply_t_handler
4361   (vl_api_show_one_use_petr_reply_t * mp)
4362 {
4363   vat_main_t *vam = &vat_main;
4364   i32 retval = ntohl (mp->retval);
4365
4366   if (0 <= retval)
4367     {
4368       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4369       if (mp->status)
4370         {
4371           print (vam->ofp, "Proxy-ETR address; %U",
4372                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4373                  mp->address);
4374         }
4375     }
4376
4377   vam->retval = retval;
4378   vam->result_ready = 1;
4379 }
4380
4381 static void
4382   vl_api_show_one_use_petr_reply_t_handler_json
4383   (vl_api_show_one_use_petr_reply_t * mp)
4384 {
4385   vat_main_t *vam = &vat_main;
4386   vat_json_node_t node;
4387   u8 *status = 0;
4388   struct in_addr ip4;
4389   struct in6_addr ip6;
4390
4391   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4392   vec_add1 (status, 0);
4393
4394   vat_json_init_object (&node);
4395   vat_json_object_add_string_copy (&node, "status", status);
4396   if (mp->status)
4397     {
4398       if (mp->is_ip4)
4399         {
4400           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4401           vat_json_object_add_ip6 (&node, "address", ip6);
4402         }
4403       else
4404         {
4405           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4406           vat_json_object_add_ip4 (&node, "address", ip4);
4407         }
4408     }
4409
4410   vec_free (status);
4411
4412   vat_json_print (vam->ofp, &node);
4413   vat_json_free (&node);
4414
4415   vam->retval = ntohl (mp->retval);
4416   vam->result_ready = 1;
4417 }
4418
4419 static void
4420   vl_api_show_one_nsh_mapping_reply_t_handler
4421   (vl_api_show_one_nsh_mapping_reply_t * mp)
4422 {
4423   vat_main_t *vam = &vat_main;
4424   i32 retval = ntohl (mp->retval);
4425
4426   if (0 <= retval)
4427     {
4428       print (vam->ofp, "%-20s%-16s",
4429              mp->is_set ? "set" : "not-set",
4430              mp->is_set ? (char *) mp->locator_set_name : "");
4431     }
4432
4433   vam->retval = retval;
4434   vam->result_ready = 1;
4435 }
4436
4437 static void
4438   vl_api_show_one_nsh_mapping_reply_t_handler_json
4439   (vl_api_show_one_nsh_mapping_reply_t * mp)
4440 {
4441   vat_main_t *vam = &vat_main;
4442   vat_json_node_t node;
4443   u8 *status = 0;
4444
4445   status = format (0, "%s", mp->is_set ? "yes" : "no");
4446   vec_add1 (status, 0);
4447
4448   vat_json_init_object (&node);
4449   vat_json_object_add_string_copy (&node, "is_set", status);
4450   if (mp->is_set)
4451     {
4452       vat_json_object_add_string_copy (&node, "locator_set",
4453                                        mp->locator_set_name);
4454     }
4455
4456   vec_free (status);
4457
4458   vat_json_print (vam->ofp, &node);
4459   vat_json_free (&node);
4460
4461   vam->retval = ntohl (mp->retval);
4462   vam->result_ready = 1;
4463 }
4464
4465 static void
4466   vl_api_show_one_map_register_ttl_reply_t_handler
4467   (vl_api_show_one_map_register_ttl_reply_t * mp)
4468 {
4469   vat_main_t *vam = &vat_main;
4470   i32 retval = ntohl (mp->retval);
4471
4472   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4473
4474   if (0 <= retval)
4475     {
4476       print (vam->ofp, "ttl: %u", mp->ttl);
4477     }
4478
4479   vam->retval = retval;
4480   vam->result_ready = 1;
4481 }
4482
4483 static void
4484   vl_api_show_one_map_register_ttl_reply_t_handler_json
4485   (vl_api_show_one_map_register_ttl_reply_t * mp)
4486 {
4487   vat_main_t *vam = &vat_main;
4488   vat_json_node_t node;
4489
4490   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4491   vat_json_init_object (&node);
4492   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4493
4494   vat_json_print (vam->ofp, &node);
4495   vat_json_free (&node);
4496
4497   vam->retval = ntohl (mp->retval);
4498   vam->result_ready = 1;
4499 }
4500
4501 static void
4502 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4503 {
4504   vat_main_t *vam = &vat_main;
4505   i32 retval = ntohl (mp->retval);
4506
4507   if (0 <= retval)
4508     {
4509       print (vam->ofp, "%-20s%-16s",
4510              mp->status ? "enabled" : "disabled",
4511              mp->status ? (char *) mp->locator_set_name : "");
4512     }
4513
4514   vam->retval = retval;
4515   vam->result_ready = 1;
4516 }
4517
4518 static void
4519 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4520 {
4521   vat_main_t *vam = &vat_main;
4522   vat_json_node_t node;
4523   u8 *status = 0;
4524
4525   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4526   vec_add1 (status, 0);
4527
4528   vat_json_init_object (&node);
4529   vat_json_object_add_string_copy (&node, "status", status);
4530   if (mp->status)
4531     {
4532       vat_json_object_add_string_copy (&node, "locator_set",
4533                                        mp->locator_set_name);
4534     }
4535
4536   vec_free (status);
4537
4538   vat_json_print (vam->ofp, &node);
4539   vat_json_free (&node);
4540
4541   vam->retval = ntohl (mp->retval);
4542   vam->result_ready = 1;
4543 }
4544
4545 static u8 *
4546 format_policer_type (u8 * s, va_list * va)
4547 {
4548   u32 i = va_arg (*va, u32);
4549
4550   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4551     s = format (s, "1r2c");
4552   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4553     s = format (s, "1r3c");
4554   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4555     s = format (s, "2r3c-2698");
4556   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4557     s = format (s, "2r3c-4115");
4558   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4559     s = format (s, "2r3c-mef5cf1");
4560   else
4561     s = format (s, "ILLEGAL");
4562   return s;
4563 }
4564
4565 static u8 *
4566 format_policer_rate_type (u8 * s, va_list * va)
4567 {
4568   u32 i = va_arg (*va, u32);
4569
4570   if (i == SSE2_QOS_RATE_KBPS)
4571     s = format (s, "kbps");
4572   else if (i == SSE2_QOS_RATE_PPS)
4573     s = format (s, "pps");
4574   else
4575     s = format (s, "ILLEGAL");
4576   return s;
4577 }
4578
4579 static u8 *
4580 format_policer_round_type (u8 * s, va_list * va)
4581 {
4582   u32 i = va_arg (*va, u32);
4583
4584   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4585     s = format (s, "closest");
4586   else if (i == SSE2_QOS_ROUND_TO_UP)
4587     s = format (s, "up");
4588   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4589     s = format (s, "down");
4590   else
4591     s = format (s, "ILLEGAL");
4592   return s;
4593 }
4594
4595 static u8 *
4596 format_policer_action_type (u8 * s, va_list * va)
4597 {
4598   u32 i = va_arg (*va, u32);
4599
4600   if (i == SSE2_QOS_ACTION_DROP)
4601     s = format (s, "drop");
4602   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4603     s = format (s, "transmit");
4604   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4605     s = format (s, "mark-and-transmit");
4606   else
4607     s = format (s, "ILLEGAL");
4608   return s;
4609 }
4610
4611 static u8 *
4612 format_dscp (u8 * s, va_list * va)
4613 {
4614   u32 i = va_arg (*va, u32);
4615   char *t = 0;
4616
4617   switch (i)
4618     {
4619 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4620       foreach_vnet_dscp
4621 #undef _
4622     default:
4623       return format (s, "ILLEGAL");
4624     }
4625   s = format (s, "%s", t);
4626   return s;
4627 }
4628
4629 static void
4630 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4631 {
4632   vat_main_t *vam = &vat_main;
4633   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4634
4635   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4636     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4637   else
4638     conform_dscp_str = format (0, "");
4639
4640   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4641     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4642   else
4643     exceed_dscp_str = format (0, "");
4644
4645   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4646     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4647   else
4648     violate_dscp_str = format (0, "");
4649
4650   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4651          "rate type %U, round type %U, %s rate, %s color-aware, "
4652          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4653          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4654          "conform action %U%s, exceed action %U%s, violate action %U%s",
4655          mp->name,
4656          format_policer_type, mp->type,
4657          ntohl (mp->cir),
4658          ntohl (mp->eir),
4659          clib_net_to_host_u64 (mp->cb),
4660          clib_net_to_host_u64 (mp->eb),
4661          format_policer_rate_type, mp->rate_type,
4662          format_policer_round_type, mp->round_type,
4663          mp->single_rate ? "single" : "dual",
4664          mp->color_aware ? "is" : "not",
4665          ntohl (mp->cir_tokens_per_period),
4666          ntohl (mp->pir_tokens_per_period),
4667          ntohl (mp->scale),
4668          ntohl (mp->current_limit),
4669          ntohl (mp->current_bucket),
4670          ntohl (mp->extended_limit),
4671          ntohl (mp->extended_bucket),
4672          clib_net_to_host_u64 (mp->last_update_time),
4673          format_policer_action_type, mp->conform_action_type,
4674          conform_dscp_str,
4675          format_policer_action_type, mp->exceed_action_type,
4676          exceed_dscp_str,
4677          format_policer_action_type, mp->violate_action_type,
4678          violate_dscp_str);
4679
4680   vec_free (conform_dscp_str);
4681   vec_free (exceed_dscp_str);
4682   vec_free (violate_dscp_str);
4683 }
4684
4685 static void vl_api_policer_details_t_handler_json
4686   (vl_api_policer_details_t * mp)
4687 {
4688   vat_main_t *vam = &vat_main;
4689   vat_json_node_t *node;
4690   u8 *rate_type_str, *round_type_str, *type_str;
4691   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4692
4693   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4694   round_type_str =
4695     format (0, "%U", format_policer_round_type, mp->round_type);
4696   type_str = format (0, "%U", format_policer_type, mp->type);
4697   conform_action_str = format (0, "%U", format_policer_action_type,
4698                                mp->conform_action_type);
4699   exceed_action_str = format (0, "%U", format_policer_action_type,
4700                               mp->exceed_action_type);
4701   violate_action_str = format (0, "%U", format_policer_action_type,
4702                                mp->violate_action_type);
4703
4704   if (VAT_JSON_ARRAY != vam->json_tree.type)
4705     {
4706       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4707       vat_json_init_array (&vam->json_tree);
4708     }
4709   node = vat_json_array_add (&vam->json_tree);
4710
4711   vat_json_init_object (node);
4712   vat_json_object_add_string_copy (node, "name", mp->name);
4713   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4714   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4715   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4716   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4717   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4718   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4719   vat_json_object_add_string_copy (node, "type", type_str);
4720   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4721   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4722   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4723   vat_json_object_add_uint (node, "cir_tokens_per_period",
4724                             ntohl (mp->cir_tokens_per_period));
4725   vat_json_object_add_uint (node, "eir_tokens_per_period",
4726                             ntohl (mp->pir_tokens_per_period));
4727   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4728   vat_json_object_add_uint (node, "current_bucket",
4729                             ntohl (mp->current_bucket));
4730   vat_json_object_add_uint (node, "extended_limit",
4731                             ntohl (mp->extended_limit));
4732   vat_json_object_add_uint (node, "extended_bucket",
4733                             ntohl (mp->extended_bucket));
4734   vat_json_object_add_uint (node, "last_update_time",
4735                             ntohl (mp->last_update_time));
4736   vat_json_object_add_string_copy (node, "conform_action",
4737                                    conform_action_str);
4738   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4739     {
4740       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4741       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4742       vec_free (dscp_str);
4743     }
4744   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4745   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4746     {
4747       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4748       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4749       vec_free (dscp_str);
4750     }
4751   vat_json_object_add_string_copy (node, "violate_action",
4752                                    violate_action_str);
4753   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4754     {
4755       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4756       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4757       vec_free (dscp_str);
4758     }
4759
4760   vec_free (rate_type_str);
4761   vec_free (round_type_str);
4762   vec_free (type_str);
4763   vec_free (conform_action_str);
4764   vec_free (exceed_action_str);
4765   vec_free (violate_action_str);
4766 }
4767
4768 static void
4769 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4770                                            mp)
4771 {
4772   vat_main_t *vam = &vat_main;
4773   int i, count = ntohl (mp->count);
4774
4775   if (count > 0)
4776     print (vam->ofp, "classify table ids (%d) : ", count);
4777   for (i = 0; i < count; i++)
4778     {
4779       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4780       print (vam->ofp, (i < count - 1) ? "," : "");
4781     }
4782   vam->retval = ntohl (mp->retval);
4783   vam->result_ready = 1;
4784 }
4785
4786 static void
4787   vl_api_classify_table_ids_reply_t_handler_json
4788   (vl_api_classify_table_ids_reply_t * mp)
4789 {
4790   vat_main_t *vam = &vat_main;
4791   int i, count = ntohl (mp->count);
4792
4793   if (count > 0)
4794     {
4795       vat_json_node_t node;
4796
4797       vat_json_init_object (&node);
4798       for (i = 0; i < count; i++)
4799         {
4800           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4801         }
4802       vat_json_print (vam->ofp, &node);
4803       vat_json_free (&node);
4804     }
4805   vam->retval = ntohl (mp->retval);
4806   vam->result_ready = 1;
4807 }
4808
4809 static void
4810   vl_api_classify_table_by_interface_reply_t_handler
4811   (vl_api_classify_table_by_interface_reply_t * mp)
4812 {
4813   vat_main_t *vam = &vat_main;
4814   u32 table_id;
4815
4816   table_id = ntohl (mp->l2_table_id);
4817   if (table_id != ~0)
4818     print (vam->ofp, "l2 table id : %d", table_id);
4819   else
4820     print (vam->ofp, "l2 table id : No input ACL tables configured");
4821   table_id = ntohl (mp->ip4_table_id);
4822   if (table_id != ~0)
4823     print (vam->ofp, "ip4 table id : %d", table_id);
4824   else
4825     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4826   table_id = ntohl (mp->ip6_table_id);
4827   if (table_id != ~0)
4828     print (vam->ofp, "ip6 table id : %d", table_id);
4829   else
4830     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4831   vam->retval = ntohl (mp->retval);
4832   vam->result_ready = 1;
4833 }
4834
4835 static void
4836   vl_api_classify_table_by_interface_reply_t_handler_json
4837   (vl_api_classify_table_by_interface_reply_t * mp)
4838 {
4839   vat_main_t *vam = &vat_main;
4840   vat_json_node_t node;
4841
4842   vat_json_init_object (&node);
4843
4844   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4845   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4846   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4847
4848   vat_json_print (vam->ofp, &node);
4849   vat_json_free (&node);
4850
4851   vam->retval = ntohl (mp->retval);
4852   vam->result_ready = 1;
4853 }
4854
4855 static void vl_api_policer_add_del_reply_t_handler
4856   (vl_api_policer_add_del_reply_t * mp)
4857 {
4858   vat_main_t *vam = &vat_main;
4859   i32 retval = ntohl (mp->retval);
4860   if (vam->async_mode)
4861     {
4862       vam->async_errors += (retval < 0);
4863     }
4864   else
4865     {
4866       vam->retval = retval;
4867       vam->result_ready = 1;
4868       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4869         /*
4870          * Note: this is just barely thread-safe, depends on
4871          * the main thread spinning waiting for an answer...
4872          */
4873         errmsg ("policer index %d", ntohl (mp->policer_index));
4874     }
4875 }
4876
4877 static void vl_api_policer_add_del_reply_t_handler_json
4878   (vl_api_policer_add_del_reply_t * mp)
4879 {
4880   vat_main_t *vam = &vat_main;
4881   vat_json_node_t node;
4882
4883   vat_json_init_object (&node);
4884   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4885   vat_json_object_add_uint (&node, "policer_index",
4886                             ntohl (mp->policer_index));
4887
4888   vat_json_print (vam->ofp, &node);
4889   vat_json_free (&node);
4890
4891   vam->retval = ntohl (mp->retval);
4892   vam->result_ready = 1;
4893 }
4894
4895 /* Format hex dump. */
4896 u8 *
4897 format_hex_bytes (u8 * s, va_list * va)
4898 {
4899   u8 *bytes = va_arg (*va, u8 *);
4900   int n_bytes = va_arg (*va, int);
4901   uword i;
4902
4903   /* Print short or long form depending on byte count. */
4904   uword short_form = n_bytes <= 32;
4905   u32 indent = format_get_indent (s);
4906
4907   if (n_bytes == 0)
4908     return s;
4909
4910   for (i = 0; i < n_bytes; i++)
4911     {
4912       if (!short_form && (i % 32) == 0)
4913         s = format (s, "%08x: ", i);
4914       s = format (s, "%02x", bytes[i]);
4915       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4916         s = format (s, "\n%U", format_white_space, indent);
4917     }
4918
4919   return s;
4920 }
4921
4922 static void
4923 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4924                                             * mp)
4925 {
4926   vat_main_t *vam = &vat_main;
4927   i32 retval = ntohl (mp->retval);
4928   if (retval == 0)
4929     {
4930       print (vam->ofp, "classify table info :");
4931       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4932              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4933              ntohl (mp->miss_next_index));
4934       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4935              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4936              ntohl (mp->match_n_vectors));
4937       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4938              ntohl (mp->mask_length));
4939     }
4940   vam->retval = retval;
4941   vam->result_ready = 1;
4942 }
4943
4944 static void
4945   vl_api_classify_table_info_reply_t_handler_json
4946   (vl_api_classify_table_info_reply_t * mp)
4947 {
4948   vat_main_t *vam = &vat_main;
4949   vat_json_node_t node;
4950
4951   i32 retval = ntohl (mp->retval);
4952   if (retval == 0)
4953     {
4954       vat_json_init_object (&node);
4955
4956       vat_json_object_add_int (&node, "sessions",
4957                                ntohl (mp->active_sessions));
4958       vat_json_object_add_int (&node, "nexttbl",
4959                                ntohl (mp->next_table_index));
4960       vat_json_object_add_int (&node, "nextnode",
4961                                ntohl (mp->miss_next_index));
4962       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4963       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4964       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4965       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4966                       ntohl (mp->mask_length), 0);
4967       vat_json_object_add_string_copy (&node, "mask", s);
4968
4969       vat_json_print (vam->ofp, &node);
4970       vat_json_free (&node);
4971     }
4972   vam->retval = ntohl (mp->retval);
4973   vam->result_ready = 1;
4974 }
4975
4976 static void
4977 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4978                                            mp)
4979 {
4980   vat_main_t *vam = &vat_main;
4981
4982   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4983          ntohl (mp->hit_next_index), ntohl (mp->advance),
4984          ntohl (mp->opaque_index));
4985   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4986          ntohl (mp->match_length));
4987 }
4988
4989 static void
4990   vl_api_classify_session_details_t_handler_json
4991   (vl_api_classify_session_details_t * mp)
4992 {
4993   vat_main_t *vam = &vat_main;
4994   vat_json_node_t *node = NULL;
4995
4996   if (VAT_JSON_ARRAY != vam->json_tree.type)
4997     {
4998       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4999       vat_json_init_array (&vam->json_tree);
5000     }
5001   node = vat_json_array_add (&vam->json_tree);
5002
5003   vat_json_init_object (node);
5004   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
5005   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5006   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5007   u8 *s =
5008     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5009             0);
5010   vat_json_object_add_string_copy (node, "match", s);
5011 }
5012
5013 static void vl_api_pg_create_interface_reply_t_handler
5014   (vl_api_pg_create_interface_reply_t * mp)
5015 {
5016   vat_main_t *vam = &vat_main;
5017
5018   vam->retval = ntohl (mp->retval);
5019   vam->result_ready = 1;
5020 }
5021
5022 static void vl_api_pg_create_interface_reply_t_handler_json
5023   (vl_api_pg_create_interface_reply_t * mp)
5024 {
5025   vat_main_t *vam = &vat_main;
5026   vat_json_node_t node;
5027
5028   i32 retval = ntohl (mp->retval);
5029   if (retval == 0)
5030     {
5031       vat_json_init_object (&node);
5032
5033       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5034
5035       vat_json_print (vam->ofp, &node);
5036       vat_json_free (&node);
5037     }
5038   vam->retval = ntohl (mp->retval);
5039   vam->result_ready = 1;
5040 }
5041
5042 static void vl_api_policer_classify_details_t_handler
5043   (vl_api_policer_classify_details_t * mp)
5044 {
5045   vat_main_t *vam = &vat_main;
5046
5047   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5048          ntohl (mp->table_index));
5049 }
5050
5051 static void vl_api_policer_classify_details_t_handler_json
5052   (vl_api_policer_classify_details_t * mp)
5053 {
5054   vat_main_t *vam = &vat_main;
5055   vat_json_node_t *node;
5056
5057   if (VAT_JSON_ARRAY != vam->json_tree.type)
5058     {
5059       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5060       vat_json_init_array (&vam->json_tree);
5061     }
5062   node = vat_json_array_add (&vam->json_tree);
5063
5064   vat_json_init_object (node);
5065   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5066   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5067 }
5068
5069 static void vl_api_ipsec_gre_tunnel_add_del_reply_t_handler
5070   (vl_api_ipsec_gre_tunnel_add_del_reply_t * mp)
5071 {
5072   vat_main_t *vam = &vat_main;
5073   i32 retval = ntohl (mp->retval);
5074   if (vam->async_mode)
5075     {
5076       vam->async_errors += (retval < 0);
5077     }
5078   else
5079     {
5080       vam->retval = retval;
5081       vam->sw_if_index = ntohl (mp->sw_if_index);
5082       vam->result_ready = 1;
5083     }
5084   vam->regenerate_interface_table = 1;
5085 }
5086
5087 static void vl_api_ipsec_gre_tunnel_add_del_reply_t_handler_json
5088   (vl_api_ipsec_gre_tunnel_add_del_reply_t * mp)
5089 {
5090   vat_main_t *vam = &vat_main;
5091   vat_json_node_t node;
5092
5093   vat_json_init_object (&node);
5094   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5095   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5096
5097   vat_json_print (vam->ofp, &node);
5098   vat_json_free (&node);
5099
5100   vam->retval = ntohl (mp->retval);
5101   vam->result_ready = 1;
5102 }
5103
5104 static void vl_api_flow_classify_details_t_handler
5105   (vl_api_flow_classify_details_t * mp)
5106 {
5107   vat_main_t *vam = &vat_main;
5108
5109   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5110          ntohl (mp->table_index));
5111 }
5112
5113 static void vl_api_flow_classify_details_t_handler_json
5114   (vl_api_flow_classify_details_t * mp)
5115 {
5116   vat_main_t *vam = &vat_main;
5117   vat_json_node_t *node;
5118
5119   if (VAT_JSON_ARRAY != vam->json_tree.type)
5120     {
5121       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5122       vat_json_init_array (&vam->json_tree);
5123     }
5124   node = vat_json_array_add (&vam->json_tree);
5125
5126   vat_json_init_object (node);
5127   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5128   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5129 }
5130
5131 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5132 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5133 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5134 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5135 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5136 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5137 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5138 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5139 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5140 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5141
5142 /*
5143  * Generate boilerplate reply handlers, which
5144  * dig the return value out of the xxx_reply_t API message,
5145  * stick it into vam->retval, and set vam->result_ready
5146  *
5147  * Could also do this by pointing N message decode slots at
5148  * a single function, but that could break in subtle ways.
5149  */
5150
5151 #define foreach_standard_reply_retval_handler           \
5152 _(sw_interface_set_flags_reply)                         \
5153 _(sw_interface_add_del_address_reply)                   \
5154 _(sw_interface_set_rx_mode_reply)                       \
5155 _(sw_interface_set_rx_placement_reply)                  \
5156 _(sw_interface_set_table_reply)                         \
5157 _(sw_interface_set_mpls_enable_reply)                   \
5158 _(sw_interface_set_vpath_reply)                         \
5159 _(sw_interface_set_vxlan_bypass_reply)                  \
5160 _(sw_interface_set_geneve_bypass_reply)                 \
5161 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5162 _(sw_interface_set_l2_bridge_reply)                     \
5163 _(bridge_domain_add_del_reply)                          \
5164 _(sw_interface_set_l2_xconnect_reply)                   \
5165 _(l2fib_add_del_reply)                                  \
5166 _(l2fib_flush_int_reply)                                \
5167 _(l2fib_flush_bd_reply)                                 \
5168 _(ip_add_del_route_reply)                               \
5169 _(ip_table_add_del_reply)                               \
5170 _(ip_mroute_add_del_reply)                              \
5171 _(mpls_route_add_del_reply)                             \
5172 _(mpls_table_add_del_reply)                             \
5173 _(mpls_ip_bind_unbind_reply)                            \
5174 _(bier_route_add_del_reply)                             \
5175 _(bier_table_add_del_reply)                             \
5176 _(proxy_arp_add_del_reply)                              \
5177 _(proxy_arp_intfc_enable_disable_reply)                 \
5178 _(sw_interface_set_unnumbered_reply)                    \
5179 _(ip_neighbor_add_del_reply)                            \
5180 _(reset_fib_reply)                                      \
5181 _(dhcp_proxy_config_reply)                              \
5182 _(dhcp_proxy_set_vss_reply)                             \
5183 _(dhcp_client_config_reply)                             \
5184 _(set_ip_flow_hash_reply)                               \
5185 _(sw_interface_ip6_enable_disable_reply)                \
5186 _(ip6nd_proxy_add_del_reply)                            \
5187 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5188 _(sw_interface_ip6nd_ra_config_reply)                   \
5189 _(set_arp_neighbor_limit_reply)                         \
5190 _(l2_patch_add_del_reply)                               \
5191 _(sr_mpls_policy_add_reply)                             \
5192 _(sr_mpls_policy_mod_reply)                             \
5193 _(sr_mpls_policy_del_reply)                             \
5194 _(sr_policy_add_reply)                                  \
5195 _(sr_policy_mod_reply)                                  \
5196 _(sr_policy_del_reply)                                  \
5197 _(sr_localsid_add_del_reply)                            \
5198 _(sr_steering_add_del_reply)                            \
5199 _(classify_add_del_session_reply)                       \
5200 _(classify_set_interface_ip_table_reply)                \
5201 _(classify_set_interface_l2_tables_reply)               \
5202 _(l2tpv3_set_tunnel_cookies_reply)                      \
5203 _(l2tpv3_interface_enable_disable_reply)                \
5204 _(l2tpv3_set_lookup_key_reply)                          \
5205 _(l2_fib_clear_table_reply)                             \
5206 _(l2_interface_efp_filter_reply)                        \
5207 _(l2_interface_vlan_tag_rewrite_reply)                  \
5208 _(modify_vhost_user_if_reply)                           \
5209 _(delete_vhost_user_if_reply)                           \
5210 _(ip_probe_neighbor_reply)                              \
5211 _(ip_scan_neighbor_enable_disable_reply)                \
5212 _(want_ip4_arp_events_reply)                            \
5213 _(want_ip6_nd_events_reply)                             \
5214 _(want_l2_macs_events_reply)                            \
5215 _(input_acl_set_interface_reply)                        \
5216 _(ipsec_spd_add_del_reply)                              \
5217 _(ipsec_interface_add_del_spd_reply)                    \
5218 _(ipsec_spd_entry_add_del_reply)                        \
5219 _(ipsec_sad_entry_add_del_reply)                        \
5220 _(ipsec_tunnel_if_add_del_reply)                        \
5221 _(ipsec_tunnel_if_set_sa_reply)                         \
5222 _(delete_loopback_reply)                                \
5223 _(bd_ip_mac_add_del_reply)                              \
5224 _(bd_ip_mac_flush_reply)                                \
5225 _(want_interface_events_reply)                          \
5226 _(cop_interface_enable_disable_reply)                   \
5227 _(cop_whitelist_enable_disable_reply)                   \
5228 _(sw_interface_clear_stats_reply)                       \
5229 _(ioam_enable_reply)                                    \
5230 _(ioam_disable_reply)                                   \
5231 _(one_add_del_locator_reply)                            \
5232 _(one_add_del_local_eid_reply)                          \
5233 _(one_add_del_remote_mapping_reply)                     \
5234 _(one_add_del_adjacency_reply)                          \
5235 _(one_add_del_map_resolver_reply)                       \
5236 _(one_add_del_map_server_reply)                         \
5237 _(one_enable_disable_reply)                             \
5238 _(one_rloc_probe_enable_disable_reply)                  \
5239 _(one_map_register_enable_disable_reply)                \
5240 _(one_map_register_set_ttl_reply)                       \
5241 _(one_set_transport_protocol_reply)                     \
5242 _(one_map_register_fallback_threshold_reply)            \
5243 _(one_pitr_set_locator_set_reply)                       \
5244 _(one_map_request_mode_reply)                           \
5245 _(one_add_del_map_request_itr_rlocs_reply)              \
5246 _(one_eid_table_add_del_map_reply)                      \
5247 _(one_use_petr_reply)                                   \
5248 _(one_stats_enable_disable_reply)                       \
5249 _(one_add_del_l2_arp_entry_reply)                       \
5250 _(one_add_del_ndp_entry_reply)                          \
5251 _(one_stats_flush_reply)                                \
5252 _(one_enable_disable_xtr_mode_reply)                    \
5253 _(one_enable_disable_pitr_mode_reply)                   \
5254 _(one_enable_disable_petr_mode_reply)                   \
5255 _(gpe_enable_disable_reply)                             \
5256 _(gpe_set_encap_mode_reply)                             \
5257 _(gpe_add_del_iface_reply)                              \
5258 _(gpe_add_del_native_fwd_rpath_reply)                   \
5259 _(af_packet_delete_reply)                               \
5260 _(policer_classify_set_interface_reply)                 \
5261 _(netmap_create_reply)                                  \
5262 _(netmap_delete_reply)                                  \
5263 _(set_ipfix_exporter_reply)                             \
5264 _(set_ipfix_classify_stream_reply)                      \
5265 _(ipfix_classify_table_add_del_reply)                   \
5266 _(flow_classify_set_interface_reply)                    \
5267 _(sw_interface_span_enable_disable_reply)               \
5268 _(pg_capture_reply)                                     \
5269 _(pg_enable_disable_reply)                              \
5270 _(ip_source_and_port_range_check_add_del_reply)         \
5271 _(ip_source_and_port_range_check_interface_add_del_reply)\
5272 _(delete_subif_reply)                                   \
5273 _(l2_interface_pbb_tag_rewrite_reply)                   \
5274 _(set_punt_reply)                                       \
5275 _(feature_enable_disable_reply)                         \
5276 _(sw_interface_tag_add_del_reply)                       \
5277 _(hw_interface_set_mtu_reply)                           \
5278 _(p2p_ethernet_add_reply)                               \
5279 _(p2p_ethernet_del_reply)                               \
5280 _(lldp_config_reply)                                    \
5281 _(sw_interface_set_lldp_reply)                          \
5282 _(tcp_configure_src_addresses_reply)                    \
5283 _(dns_enable_disable_reply)                             \
5284 _(dns_name_server_add_del_reply)                        \
5285 _(session_rule_add_del_reply)                           \
5286 _(ip_container_proxy_add_del_reply)                     \
5287 _(output_acl_set_interface_reply)                       \
5288 _(qos_record_enable_disable_reply)
5289
5290 #define _(n)                                    \
5291     static void vl_api_##n##_t_handler          \
5292     (vl_api_##n##_t * mp)                       \
5293     {                                           \
5294         vat_main_t * vam = &vat_main;           \
5295         i32 retval = ntohl(mp->retval);         \
5296         if (vam->async_mode) {                  \
5297             vam->async_errors += (retval < 0);  \
5298         } else {                                \
5299             vam->retval = retval;               \
5300             vam->result_ready = 1;              \
5301         }                                       \
5302     }
5303 foreach_standard_reply_retval_handler;
5304 #undef _
5305
5306 #define _(n)                                    \
5307     static void vl_api_##n##_t_handler_json     \
5308     (vl_api_##n##_t * mp)                       \
5309     {                                           \
5310         vat_main_t * vam = &vat_main;           \
5311         vat_json_node_t node;                   \
5312         vat_json_init_object(&node);            \
5313         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5314         vat_json_print(vam->ofp, &node);        \
5315         vam->retval = ntohl(mp->retval);        \
5316         vam->result_ready = 1;                  \
5317     }
5318 foreach_standard_reply_retval_handler;
5319 #undef _
5320
5321 /*
5322  * Table of message reply handlers, must include boilerplate handlers
5323  * we just generated
5324  */
5325
5326 #define foreach_vpe_api_reply_msg                                       \
5327 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5328 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5329 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5330 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5331 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5332 _(CLI_REPLY, cli_reply)                                                 \
5333 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5334 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5335   sw_interface_add_del_address_reply)                                   \
5336 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5337 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5338 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5339 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5340 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5341 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5342 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5343 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5344 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5345 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5346   sw_interface_set_l2_xconnect_reply)                                   \
5347 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5348   sw_interface_set_l2_bridge_reply)                                     \
5349 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5350 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5351 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5352 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5353 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5354 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5355 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5356 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5357 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5358 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5359 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5360 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5361 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5362 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5363 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5364 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5365 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5366 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5367 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5368 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5369 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5370 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5371 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5372 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5373 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5374 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5375 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5376 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5377 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5378 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5379   proxy_arp_intfc_enable_disable_reply)                                 \
5380 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5381 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5382   sw_interface_set_unnumbered_reply)                                    \
5383 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5384 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5385 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5386 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5387 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5388 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5389 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5390 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5391 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5392 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5393   sw_interface_ip6_enable_disable_reply)                                \
5394 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5395 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5396 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5397   sw_interface_ip6nd_ra_prefix_reply)                                   \
5398 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5399   sw_interface_ip6nd_ra_config_reply)                                   \
5400 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5401 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5402 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5403 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5404 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5405 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5406 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5407 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5408 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5409 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5410 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5411 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5412 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5413 classify_set_interface_ip_table_reply)                                  \
5414 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5415   classify_set_interface_l2_tables_reply)                               \
5416 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5417 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5418 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5419 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5420 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5421   l2tpv3_interface_enable_disable_reply)                                \
5422 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5423 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5424 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5425 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5426 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5427 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5428 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5429 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5430 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5431 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5432 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5433 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5434 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5435 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5436 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5437 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5438 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5439 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5440 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5441 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5442 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5443 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5444 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5445 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5446 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5447 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5448 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5449 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5450 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5451 _(L2_MACS_EVENT, l2_macs_event)                                         \
5452 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5453 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5454 _(IP_DETAILS, ip_details)                                               \
5455 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5456 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5457 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5458 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5459 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5460 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5461 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5462 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5463 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5464 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5465 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5466 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5467 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5468 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5469 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5470 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5471 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5472 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5473 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5474 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5475 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5476 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5477 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5478 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5479 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5480 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5481 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5482 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5483 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5484   one_map_register_enable_disable_reply)                                \
5485 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5486 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5487 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5488 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5489   one_map_register_fallback_threshold_reply)                            \
5490 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5491   one_rloc_probe_enable_disable_reply)                                  \
5492 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5493 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5494 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5495 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5496 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5497 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5498 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5499 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5500 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5501 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5502 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5503 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5504 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5505 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5506 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5507 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5508   show_one_stats_enable_disable_reply)                                  \
5509 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5510 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5511 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5512 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5513 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5514 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5515 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5516 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5517   one_enable_disable_pitr_mode_reply)                                   \
5518 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5519   one_enable_disable_petr_mode_reply)                                   \
5520 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5521 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5522 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5523 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5524 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5525 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5526 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5527 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5528 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5529 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5530 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5531 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5532   gpe_add_del_native_fwd_rpath_reply)                                   \
5533 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5534   gpe_fwd_entry_path_details)                                           \
5535 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5536 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5537   one_add_del_map_request_itr_rlocs_reply)                              \
5538 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5539   one_get_map_request_itr_rlocs_reply)                                  \
5540 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5541 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5542 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5543 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5544 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5545 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5546   show_one_map_register_state_reply)                                    \
5547 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5548 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5549   show_one_map_register_fallback_threshold_reply)                       \
5550 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5551 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5552 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5553 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5554 _(POLICER_DETAILS, policer_details)                                     \
5555 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5556 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5557 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5558 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5559 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5560 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5561 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5562 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5563 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5564 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5565 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5566 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5567 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5568 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5569 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5570 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5571 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5572 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5573 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5574 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5575 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5576 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5577 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5578 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5579 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5580  ip_source_and_port_range_check_add_del_reply)                          \
5581 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5582  ip_source_and_port_range_check_interface_add_del_reply)                \
5583 _(IPSEC_GRE_TUNNEL_ADD_DEL_REPLY, ipsec_gre_tunnel_add_del_reply)       \
5584 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5585 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5586 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5587 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5588 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5589 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5590 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5591 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5592 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5593 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5594 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5595 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5596 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5597 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5598 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5599 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5600 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5601 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5602 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5603 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5604 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5605 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5606 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5607 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5608 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5609 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5610 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5611
5612 #define foreach_standalone_reply_msg                                    \
5613 _(SW_INTERFACE_EVENT, sw_interface_event)
5614
5615 typedef struct
5616 {
5617   u8 *name;
5618   u32 value;
5619 } name_sort_t;
5620
5621 #define STR_VTR_OP_CASE(op)     \
5622     case L2_VTR_ ## op:         \
5623         return "" # op;
5624
5625 static const char *
5626 str_vtr_op (u32 vtr_op)
5627 {
5628   switch (vtr_op)
5629     {
5630       STR_VTR_OP_CASE (DISABLED);
5631       STR_VTR_OP_CASE (PUSH_1);
5632       STR_VTR_OP_CASE (PUSH_2);
5633       STR_VTR_OP_CASE (POP_1);
5634       STR_VTR_OP_CASE (POP_2);
5635       STR_VTR_OP_CASE (TRANSLATE_1_1);
5636       STR_VTR_OP_CASE (TRANSLATE_1_2);
5637       STR_VTR_OP_CASE (TRANSLATE_2_1);
5638       STR_VTR_OP_CASE (TRANSLATE_2_2);
5639     }
5640
5641   return "UNKNOWN";
5642 }
5643
5644 static int
5645 dump_sub_interface_table (vat_main_t * vam)
5646 {
5647   const sw_interface_subif_t *sub = NULL;
5648
5649   if (vam->json_output)
5650     {
5651       clib_warning
5652         ("JSON output supported only for VPE API calls and dump_stats_table");
5653       return -99;
5654     }
5655
5656   print (vam->ofp,
5657          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5658          "Interface", "sw_if_index",
5659          "sub id", "dot1ad", "tags", "outer id",
5660          "inner id", "exact", "default", "outer any", "inner any");
5661
5662   vec_foreach (sub, vam->sw_if_subif_table)
5663   {
5664     print (vam->ofp,
5665            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5666            sub->interface_name,
5667            sub->sw_if_index,
5668            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5669            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5670            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5671            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5672     if (sub->vtr_op != L2_VTR_DISABLED)
5673       {
5674         print (vam->ofp,
5675                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5676                "tag1: %d tag2: %d ]",
5677                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5678                sub->vtr_tag1, sub->vtr_tag2);
5679       }
5680   }
5681
5682   return 0;
5683 }
5684
5685 static int
5686 name_sort_cmp (void *a1, void *a2)
5687 {
5688   name_sort_t *n1 = a1;
5689   name_sort_t *n2 = a2;
5690
5691   return strcmp ((char *) n1->name, (char *) n2->name);
5692 }
5693
5694 static int
5695 dump_interface_table (vat_main_t * vam)
5696 {
5697   hash_pair_t *p;
5698   name_sort_t *nses = 0, *ns;
5699
5700   if (vam->json_output)
5701     {
5702       clib_warning
5703         ("JSON output supported only for VPE API calls and dump_stats_table");
5704       return -99;
5705     }
5706
5707   /* *INDENT-OFF* */
5708   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5709   ({
5710     vec_add2 (nses, ns, 1);
5711     ns->name = (u8 *)(p->key);
5712     ns->value = (u32) p->value[0];
5713   }));
5714   /* *INDENT-ON* */
5715
5716   vec_sort_with_function (nses, name_sort_cmp);
5717
5718   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5719   vec_foreach (ns, nses)
5720   {
5721     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5722   }
5723   vec_free (nses);
5724   return 0;
5725 }
5726
5727 static int
5728 dump_ip_table (vat_main_t * vam, int is_ipv6)
5729 {
5730   const ip_details_t *det = NULL;
5731   const ip_address_details_t *address = NULL;
5732   u32 i = ~0;
5733
5734   print (vam->ofp, "%-12s", "sw_if_index");
5735
5736   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5737   {
5738     i++;
5739     if (!det->present)
5740       {
5741         continue;
5742       }
5743     print (vam->ofp, "%-12d", i);
5744     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5745     if (!det->addr)
5746       {
5747         continue;
5748       }
5749     vec_foreach (address, det->addr)
5750     {
5751       print (vam->ofp,
5752              "            %-30U%-13d",
5753              is_ipv6 ? format_ip6_address : format_ip4_address,
5754              address->ip, address->prefix_length);
5755     }
5756   }
5757
5758   return 0;
5759 }
5760
5761 static int
5762 dump_ipv4_table (vat_main_t * vam)
5763 {
5764   if (vam->json_output)
5765     {
5766       clib_warning
5767         ("JSON output supported only for VPE API calls and dump_stats_table");
5768       return -99;
5769     }
5770
5771   return dump_ip_table (vam, 0);
5772 }
5773
5774 static int
5775 dump_ipv6_table (vat_main_t * vam)
5776 {
5777   if (vam->json_output)
5778     {
5779       clib_warning
5780         ("JSON output supported only for VPE API calls and dump_stats_table");
5781       return -99;
5782     }
5783
5784   return dump_ip_table (vam, 1);
5785 }
5786
5787 /*
5788  * Pass CLI buffers directly in the CLI_INBAND API message,
5789  * instead of an additional shared memory area.
5790  */
5791 static int
5792 exec_inband (vat_main_t * vam)
5793 {
5794   vl_api_cli_inband_t *mp;
5795   unformat_input_t *i = vam->input;
5796   int ret;
5797
5798   if (vec_len (i->buffer) == 0)
5799     return -1;
5800
5801   if (vam->exec_mode == 0 && unformat (i, "mode"))
5802     {
5803       vam->exec_mode = 1;
5804       return 0;
5805     }
5806   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5807     {
5808       vam->exec_mode = 0;
5809       return 0;
5810     }
5811
5812   /*
5813    * In order for the CLI command to work, it
5814    * must be a vector ending in \n, not a C-string ending
5815    * in \n\0.
5816    */
5817   u32 len = vec_len (vam->input->buffer);
5818   M2 (CLI_INBAND, mp, len);
5819   vl_api_to_api_string (len - 1, (const char *) vam->input->buffer, &mp->cmd);
5820
5821   S (mp);
5822   W (ret);
5823   /* json responses may or may not include a useful reply... */
5824   if (vec_len (vam->cmd_reply))
5825     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5826   return ret;
5827 }
5828
5829 int
5830 exec (vat_main_t * vam)
5831 {
5832   return exec_inband (vam);
5833 }
5834
5835 static int
5836 api_create_loopback (vat_main_t * vam)
5837 {
5838   unformat_input_t *i = vam->input;
5839   vl_api_create_loopback_t *mp;
5840   vl_api_create_loopback_instance_t *mp_lbi;
5841   u8 mac_address[6];
5842   u8 mac_set = 0;
5843   u8 is_specified = 0;
5844   u32 user_instance = 0;
5845   int ret;
5846
5847   clib_memset (mac_address, 0, sizeof (mac_address));
5848
5849   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5850     {
5851       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5852         mac_set = 1;
5853       if (unformat (i, "instance %d", &user_instance))
5854         is_specified = 1;
5855       else
5856         break;
5857     }
5858
5859   if (is_specified)
5860     {
5861       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5862       mp_lbi->is_specified = is_specified;
5863       if (is_specified)
5864         mp_lbi->user_instance = htonl (user_instance);
5865       if (mac_set)
5866         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5867       S (mp_lbi);
5868     }
5869   else
5870     {
5871       /* Construct the API message */
5872       M (CREATE_LOOPBACK, mp);
5873       if (mac_set)
5874         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5875       S (mp);
5876     }
5877
5878   W (ret);
5879   return ret;
5880 }
5881
5882 static int
5883 api_delete_loopback (vat_main_t * vam)
5884 {
5885   unformat_input_t *i = vam->input;
5886   vl_api_delete_loopback_t *mp;
5887   u32 sw_if_index = ~0;
5888   int ret;
5889
5890   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5891     {
5892       if (unformat (i, "sw_if_index %d", &sw_if_index))
5893         ;
5894       else
5895         break;
5896     }
5897
5898   if (sw_if_index == ~0)
5899     {
5900       errmsg ("missing sw_if_index");
5901       return -99;
5902     }
5903
5904   /* Construct the API message */
5905   M (DELETE_LOOPBACK, mp);
5906   mp->sw_if_index = ntohl (sw_if_index);
5907
5908   S (mp);
5909   W (ret);
5910   return ret;
5911 }
5912
5913 static int
5914 api_want_interface_events (vat_main_t * vam)
5915 {
5916   unformat_input_t *i = vam->input;
5917   vl_api_want_interface_events_t *mp;
5918   int enable = -1;
5919   int ret;
5920
5921   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5922     {
5923       if (unformat (i, "enable"))
5924         enable = 1;
5925       else if (unformat (i, "disable"))
5926         enable = 0;
5927       else
5928         break;
5929     }
5930
5931   if (enable == -1)
5932     {
5933       errmsg ("missing enable|disable");
5934       return -99;
5935     }
5936
5937   M (WANT_INTERFACE_EVENTS, mp);
5938   mp->enable_disable = enable;
5939
5940   vam->interface_event_display = enable;
5941
5942   S (mp);
5943   W (ret);
5944   return ret;
5945 }
5946
5947
5948 /* Note: non-static, called once to set up the initial intfc table */
5949 int
5950 api_sw_interface_dump (vat_main_t * vam)
5951 {
5952   vl_api_sw_interface_dump_t *mp;
5953   vl_api_control_ping_t *mp_ping;
5954   hash_pair_t *p;
5955   name_sort_t *nses = 0, *ns;
5956   sw_interface_subif_t *sub = NULL;
5957   int ret;
5958
5959   /* Toss the old name table */
5960   /* *INDENT-OFF* */
5961   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5962   ({
5963     vec_add2 (nses, ns, 1);
5964     ns->name = (u8 *)(p->key);
5965     ns->value = (u32) p->value[0];
5966   }));
5967   /* *INDENT-ON* */
5968
5969   hash_free (vam->sw_if_index_by_interface_name);
5970
5971   vec_foreach (ns, nses) vec_free (ns->name);
5972
5973   vec_free (nses);
5974
5975   vec_foreach (sub, vam->sw_if_subif_table)
5976   {
5977     vec_free (sub->interface_name);
5978   }
5979   vec_free (vam->sw_if_subif_table);
5980
5981   /* recreate the interface name hash table */
5982   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5983
5984   /*
5985    * Ask for all interface names. Otherwise, the epic catalog of
5986    * name filters becomes ridiculously long, and vat ends up needing
5987    * to be taught about new interface types.
5988    */
5989   M (SW_INTERFACE_DUMP, mp);
5990   S (mp);
5991
5992   /* Use a control ping for synchronization */
5993   MPING (CONTROL_PING, mp_ping);
5994   S (mp_ping);
5995
5996   W (ret);
5997   return ret;
5998 }
5999
6000 static int
6001 api_sw_interface_set_flags (vat_main_t * vam)
6002 {
6003   unformat_input_t *i = vam->input;
6004   vl_api_sw_interface_set_flags_t *mp;
6005   u32 sw_if_index;
6006   u8 sw_if_index_set = 0;
6007   u8 admin_up = 0;
6008   int ret;
6009
6010   /* Parse args required to build the message */
6011   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6012     {
6013       if (unformat (i, "admin-up"))
6014         admin_up = 1;
6015       else if (unformat (i, "admin-down"))
6016         admin_up = 0;
6017       else
6018         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6019         sw_if_index_set = 1;
6020       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6021         sw_if_index_set = 1;
6022       else
6023         break;
6024     }
6025
6026   if (sw_if_index_set == 0)
6027     {
6028       errmsg ("missing interface name or sw_if_index");
6029       return -99;
6030     }
6031
6032   /* Construct the API message */
6033   M (SW_INTERFACE_SET_FLAGS, mp);
6034   mp->sw_if_index = ntohl (sw_if_index);
6035   mp->admin_up_down = admin_up;
6036
6037   /* send it... */
6038   S (mp);
6039
6040   /* Wait for a reply, return the good/bad news... */
6041   W (ret);
6042   return ret;
6043 }
6044
6045 static int
6046 api_sw_interface_set_rx_mode (vat_main_t * vam)
6047 {
6048   unformat_input_t *i = vam->input;
6049   vl_api_sw_interface_set_rx_mode_t *mp;
6050   u32 sw_if_index;
6051   u8 sw_if_index_set = 0;
6052   int ret;
6053   u8 queue_id_valid = 0;
6054   u32 queue_id;
6055   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6056
6057   /* Parse args required to build the message */
6058   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6059     {
6060       if (unformat (i, "queue %d", &queue_id))
6061         queue_id_valid = 1;
6062       else if (unformat (i, "polling"))
6063         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6064       else if (unformat (i, "interrupt"))
6065         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6066       else if (unformat (i, "adaptive"))
6067         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6068       else
6069         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6070         sw_if_index_set = 1;
6071       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6072         sw_if_index_set = 1;
6073       else
6074         break;
6075     }
6076
6077   if (sw_if_index_set == 0)
6078     {
6079       errmsg ("missing interface name or sw_if_index");
6080       return -99;
6081     }
6082   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6083     {
6084       errmsg ("missing rx-mode");
6085       return -99;
6086     }
6087
6088   /* Construct the API message */
6089   M (SW_INTERFACE_SET_RX_MODE, mp);
6090   mp->sw_if_index = ntohl (sw_if_index);
6091   mp->mode = mode;
6092   mp->queue_id_valid = queue_id_valid;
6093   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6094
6095   /* send it... */
6096   S (mp);
6097
6098   /* Wait for a reply, return the good/bad news... */
6099   W (ret);
6100   return ret;
6101 }
6102
6103 static int
6104 api_sw_interface_set_rx_placement (vat_main_t * vam)
6105 {
6106   unformat_input_t *i = vam->input;
6107   vl_api_sw_interface_set_rx_placement_t *mp;
6108   u32 sw_if_index;
6109   u8 sw_if_index_set = 0;
6110   int ret;
6111   u8 is_main = 0;
6112   u32 queue_id, thread_index;
6113
6114   /* Parse args required to build the message */
6115   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6116     {
6117       if (unformat (i, "queue %d", &queue_id))
6118         ;
6119       else if (unformat (i, "main"))
6120         is_main = 1;
6121       else if (unformat (i, "worker %d", &thread_index))
6122         ;
6123       else
6124         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6125         sw_if_index_set = 1;
6126       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6127         sw_if_index_set = 1;
6128       else
6129         break;
6130     }
6131
6132   if (sw_if_index_set == 0)
6133     {
6134       errmsg ("missing interface name or sw_if_index");
6135       return -99;
6136     }
6137
6138   if (is_main)
6139     thread_index = 0;
6140   /* Construct the API message */
6141   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6142   mp->sw_if_index = ntohl (sw_if_index);
6143   mp->worker_id = ntohl (thread_index);
6144   mp->queue_id = ntohl (queue_id);
6145   mp->is_main = is_main;
6146
6147   /* send it... */
6148   S (mp);
6149   /* Wait for a reply, return the good/bad news... */
6150   W (ret);
6151   return ret;
6152 }
6153
6154 static void vl_api_sw_interface_rx_placement_details_t_handler
6155   (vl_api_sw_interface_rx_placement_details_t * mp)
6156 {
6157   vat_main_t *vam = &vat_main;
6158   u32 worker_id = ntohl (mp->worker_id);
6159
6160   print (vam->ofp,
6161          "\n%-11d %-11s %-6d %-5d %-9s",
6162          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6163          worker_id, ntohl (mp->queue_id),
6164          (mp->mode ==
6165           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6166 }
6167
6168 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6169   (vl_api_sw_interface_rx_placement_details_t * mp)
6170 {
6171   vat_main_t *vam = &vat_main;
6172   vat_json_node_t *node = NULL;
6173
6174   if (VAT_JSON_ARRAY != vam->json_tree.type)
6175     {
6176       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6177       vat_json_init_array (&vam->json_tree);
6178     }
6179   node = vat_json_array_add (&vam->json_tree);
6180
6181   vat_json_init_object (node);
6182   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6183   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6184   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6185   vat_json_object_add_uint (node, "mode", mp->mode);
6186 }
6187
6188 static int
6189 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6190 {
6191   unformat_input_t *i = vam->input;
6192   vl_api_sw_interface_rx_placement_dump_t *mp;
6193   vl_api_control_ping_t *mp_ping;
6194   int ret;
6195   u32 sw_if_index;
6196   u8 sw_if_index_set = 0;
6197
6198   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6199     {
6200       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6201         sw_if_index_set++;
6202       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6203         sw_if_index_set++;
6204       else
6205         break;
6206     }
6207
6208   print (vam->ofp,
6209          "\n%-11s %-11s %-6s %-5s %-4s",
6210          "sw_if_index", "main/worker", "thread", "queue", "mode");
6211
6212   /* Dump Interface rx placement */
6213   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6214
6215   if (sw_if_index_set)
6216     mp->sw_if_index = htonl (sw_if_index);
6217   else
6218     mp->sw_if_index = ~0;
6219
6220   S (mp);
6221
6222   /* Use a control ping for synchronization */
6223   MPING (CONTROL_PING, mp_ping);
6224   S (mp_ping);
6225
6226   W (ret);
6227   return ret;
6228 }
6229
6230 static int
6231 api_sw_interface_clear_stats (vat_main_t * vam)
6232 {
6233   unformat_input_t *i = vam->input;
6234   vl_api_sw_interface_clear_stats_t *mp;
6235   u32 sw_if_index;
6236   u8 sw_if_index_set = 0;
6237   int ret;
6238
6239   /* Parse args required to build the message */
6240   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6241     {
6242       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6243         sw_if_index_set = 1;
6244       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6245         sw_if_index_set = 1;
6246       else
6247         break;
6248     }
6249
6250   /* Construct the API message */
6251   M (SW_INTERFACE_CLEAR_STATS, mp);
6252
6253   if (sw_if_index_set == 1)
6254     mp->sw_if_index = ntohl (sw_if_index);
6255   else
6256     mp->sw_if_index = ~0;
6257
6258   /* send it... */
6259   S (mp);
6260
6261   /* Wait for a reply, return the good/bad news... */
6262   W (ret);
6263   return ret;
6264 }
6265
6266 static int
6267 api_sw_interface_add_del_address (vat_main_t * vam)
6268 {
6269   unformat_input_t *i = vam->input;
6270   vl_api_sw_interface_add_del_address_t *mp;
6271   u32 sw_if_index;
6272   u8 sw_if_index_set = 0;
6273   u8 is_add = 1, del_all = 0;
6274   u32 address_length = 0;
6275   u8 v4_address_set = 0;
6276   u8 v6_address_set = 0;
6277   ip4_address_t v4address;
6278   ip6_address_t v6address;
6279   int ret;
6280
6281   /* Parse args required to build the message */
6282   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6283     {
6284       if (unformat (i, "del-all"))
6285         del_all = 1;
6286       else if (unformat (i, "del"))
6287         is_add = 0;
6288       else
6289         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6290         sw_if_index_set = 1;
6291       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6292         sw_if_index_set = 1;
6293       else if (unformat (i, "%U/%d",
6294                          unformat_ip4_address, &v4address, &address_length))
6295         v4_address_set = 1;
6296       else if (unformat (i, "%U/%d",
6297                          unformat_ip6_address, &v6address, &address_length))
6298         v6_address_set = 1;
6299       else
6300         break;
6301     }
6302
6303   if (sw_if_index_set == 0)
6304     {
6305       errmsg ("missing interface name or sw_if_index");
6306       return -99;
6307     }
6308   if (v4_address_set && v6_address_set)
6309     {
6310       errmsg ("both v4 and v6 addresses set");
6311       return -99;
6312     }
6313   if (!v4_address_set && !v6_address_set && !del_all)
6314     {
6315       errmsg ("no addresses set");
6316       return -99;
6317     }
6318
6319   /* Construct the API message */
6320   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6321
6322   mp->sw_if_index = ntohl (sw_if_index);
6323   mp->is_add = is_add;
6324   mp->del_all = del_all;
6325   if (v6_address_set)
6326     {
6327       mp->is_ipv6 = 1;
6328       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6329     }
6330   else
6331     {
6332       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6333     }
6334   mp->address_length = address_length;
6335
6336   /* send it... */
6337   S (mp);
6338
6339   /* Wait for a reply, return good/bad news  */
6340   W (ret);
6341   return ret;
6342 }
6343
6344 static int
6345 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6346 {
6347   unformat_input_t *i = vam->input;
6348   vl_api_sw_interface_set_mpls_enable_t *mp;
6349   u32 sw_if_index;
6350   u8 sw_if_index_set = 0;
6351   u8 enable = 1;
6352   int ret;
6353
6354   /* Parse args required to build the message */
6355   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6356     {
6357       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6358         sw_if_index_set = 1;
6359       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6360         sw_if_index_set = 1;
6361       else if (unformat (i, "disable"))
6362         enable = 0;
6363       else if (unformat (i, "dis"))
6364         enable = 0;
6365       else
6366         break;
6367     }
6368
6369   if (sw_if_index_set == 0)
6370     {
6371       errmsg ("missing interface name or sw_if_index");
6372       return -99;
6373     }
6374
6375   /* Construct the API message */
6376   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6377
6378   mp->sw_if_index = ntohl (sw_if_index);
6379   mp->enable = enable;
6380
6381   /* send it... */
6382   S (mp);
6383
6384   /* Wait for a reply... */
6385   W (ret);
6386   return ret;
6387 }
6388
6389 static int
6390 api_sw_interface_set_table (vat_main_t * vam)
6391 {
6392   unformat_input_t *i = vam->input;
6393   vl_api_sw_interface_set_table_t *mp;
6394   u32 sw_if_index, vrf_id = 0;
6395   u8 sw_if_index_set = 0;
6396   u8 is_ipv6 = 0;
6397   int ret;
6398
6399   /* Parse args required to build the message */
6400   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6401     {
6402       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6403         sw_if_index_set = 1;
6404       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6405         sw_if_index_set = 1;
6406       else if (unformat (i, "vrf %d", &vrf_id))
6407         ;
6408       else if (unformat (i, "ipv6"))
6409         is_ipv6 = 1;
6410       else
6411         break;
6412     }
6413
6414   if (sw_if_index_set == 0)
6415     {
6416       errmsg ("missing interface name or sw_if_index");
6417       return -99;
6418     }
6419
6420   /* Construct the API message */
6421   M (SW_INTERFACE_SET_TABLE, mp);
6422
6423   mp->sw_if_index = ntohl (sw_if_index);
6424   mp->is_ipv6 = is_ipv6;
6425   mp->vrf_id = ntohl (vrf_id);
6426
6427   /* send it... */
6428   S (mp);
6429
6430   /* Wait for a reply... */
6431   W (ret);
6432   return ret;
6433 }
6434
6435 static void vl_api_sw_interface_get_table_reply_t_handler
6436   (vl_api_sw_interface_get_table_reply_t * mp)
6437 {
6438   vat_main_t *vam = &vat_main;
6439
6440   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6441
6442   vam->retval = ntohl (mp->retval);
6443   vam->result_ready = 1;
6444
6445 }
6446
6447 static void vl_api_sw_interface_get_table_reply_t_handler_json
6448   (vl_api_sw_interface_get_table_reply_t * mp)
6449 {
6450   vat_main_t *vam = &vat_main;
6451   vat_json_node_t node;
6452
6453   vat_json_init_object (&node);
6454   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6455   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6456
6457   vat_json_print (vam->ofp, &node);
6458   vat_json_free (&node);
6459
6460   vam->retval = ntohl (mp->retval);
6461   vam->result_ready = 1;
6462 }
6463
6464 static int
6465 api_sw_interface_get_table (vat_main_t * vam)
6466 {
6467   unformat_input_t *i = vam->input;
6468   vl_api_sw_interface_get_table_t *mp;
6469   u32 sw_if_index;
6470   u8 sw_if_index_set = 0;
6471   u8 is_ipv6 = 0;
6472   int ret;
6473
6474   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6475     {
6476       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6477         sw_if_index_set = 1;
6478       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6479         sw_if_index_set = 1;
6480       else if (unformat (i, "ipv6"))
6481         is_ipv6 = 1;
6482       else
6483         break;
6484     }
6485
6486   if (sw_if_index_set == 0)
6487     {
6488       errmsg ("missing interface name or sw_if_index");
6489       return -99;
6490     }
6491
6492   M (SW_INTERFACE_GET_TABLE, mp);
6493   mp->sw_if_index = htonl (sw_if_index);
6494   mp->is_ipv6 = is_ipv6;
6495
6496   S (mp);
6497   W (ret);
6498   return ret;
6499 }
6500
6501 static int
6502 api_sw_interface_set_vpath (vat_main_t * vam)
6503 {
6504   unformat_input_t *i = vam->input;
6505   vl_api_sw_interface_set_vpath_t *mp;
6506   u32 sw_if_index = 0;
6507   u8 sw_if_index_set = 0;
6508   u8 is_enable = 0;
6509   int ret;
6510
6511   /* Parse args required to build the message */
6512   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6513     {
6514       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6515         sw_if_index_set = 1;
6516       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6517         sw_if_index_set = 1;
6518       else if (unformat (i, "enable"))
6519         is_enable = 1;
6520       else if (unformat (i, "disable"))
6521         is_enable = 0;
6522       else
6523         break;
6524     }
6525
6526   if (sw_if_index_set == 0)
6527     {
6528       errmsg ("missing interface name or sw_if_index");
6529       return -99;
6530     }
6531
6532   /* Construct the API message */
6533   M (SW_INTERFACE_SET_VPATH, mp);
6534
6535   mp->sw_if_index = ntohl (sw_if_index);
6536   mp->enable = is_enable;
6537
6538   /* send it... */
6539   S (mp);
6540
6541   /* Wait for a reply... */
6542   W (ret);
6543   return ret;
6544 }
6545
6546 static int
6547 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6548 {
6549   unformat_input_t *i = vam->input;
6550   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6551   u32 sw_if_index = 0;
6552   u8 sw_if_index_set = 0;
6553   u8 is_enable = 1;
6554   u8 is_ipv6 = 0;
6555   int ret;
6556
6557   /* Parse args required to build the message */
6558   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6559     {
6560       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6561         sw_if_index_set = 1;
6562       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6563         sw_if_index_set = 1;
6564       else if (unformat (i, "enable"))
6565         is_enable = 1;
6566       else if (unformat (i, "disable"))
6567         is_enable = 0;
6568       else if (unformat (i, "ip4"))
6569         is_ipv6 = 0;
6570       else if (unformat (i, "ip6"))
6571         is_ipv6 = 1;
6572       else
6573         break;
6574     }
6575
6576   if (sw_if_index_set == 0)
6577     {
6578       errmsg ("missing interface name or sw_if_index");
6579       return -99;
6580     }
6581
6582   /* Construct the API message */
6583   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6584
6585   mp->sw_if_index = ntohl (sw_if_index);
6586   mp->enable = is_enable;
6587   mp->is_ipv6 = is_ipv6;
6588
6589   /* send it... */
6590   S (mp);
6591
6592   /* Wait for a reply... */
6593   W (ret);
6594   return ret;
6595 }
6596
6597 static int
6598 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6599 {
6600   unformat_input_t *i = vam->input;
6601   vl_api_sw_interface_set_geneve_bypass_t *mp;
6602   u32 sw_if_index = 0;
6603   u8 sw_if_index_set = 0;
6604   u8 is_enable = 1;
6605   u8 is_ipv6 = 0;
6606   int ret;
6607
6608   /* Parse args required to build the message */
6609   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6610     {
6611       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6612         sw_if_index_set = 1;
6613       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6614         sw_if_index_set = 1;
6615       else if (unformat (i, "enable"))
6616         is_enable = 1;
6617       else if (unformat (i, "disable"))
6618         is_enable = 0;
6619       else if (unformat (i, "ip4"))
6620         is_ipv6 = 0;
6621       else if (unformat (i, "ip6"))
6622         is_ipv6 = 1;
6623       else
6624         break;
6625     }
6626
6627   if (sw_if_index_set == 0)
6628     {
6629       errmsg ("missing interface name or sw_if_index");
6630       return -99;
6631     }
6632
6633   /* Construct the API message */
6634   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6635
6636   mp->sw_if_index = ntohl (sw_if_index);
6637   mp->enable = is_enable;
6638   mp->is_ipv6 = is_ipv6;
6639
6640   /* send it... */
6641   S (mp);
6642
6643   /* Wait for a reply... */
6644   W (ret);
6645   return ret;
6646 }
6647
6648 static int
6649 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6650 {
6651   unformat_input_t *i = vam->input;
6652   vl_api_sw_interface_set_l2_xconnect_t *mp;
6653   u32 rx_sw_if_index;
6654   u8 rx_sw_if_index_set = 0;
6655   u32 tx_sw_if_index;
6656   u8 tx_sw_if_index_set = 0;
6657   u8 enable = 1;
6658   int ret;
6659
6660   /* Parse args required to build the message */
6661   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6662     {
6663       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6664         rx_sw_if_index_set = 1;
6665       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6666         tx_sw_if_index_set = 1;
6667       else if (unformat (i, "rx"))
6668         {
6669           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6670             {
6671               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6672                             &rx_sw_if_index))
6673                 rx_sw_if_index_set = 1;
6674             }
6675           else
6676             break;
6677         }
6678       else if (unformat (i, "tx"))
6679         {
6680           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6681             {
6682               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6683                             &tx_sw_if_index))
6684                 tx_sw_if_index_set = 1;
6685             }
6686           else
6687             break;
6688         }
6689       else if (unformat (i, "enable"))
6690         enable = 1;
6691       else if (unformat (i, "disable"))
6692         enable = 0;
6693       else
6694         break;
6695     }
6696
6697   if (rx_sw_if_index_set == 0)
6698     {
6699       errmsg ("missing rx interface name or rx_sw_if_index");
6700       return -99;
6701     }
6702
6703   if (enable && (tx_sw_if_index_set == 0))
6704     {
6705       errmsg ("missing tx interface name or tx_sw_if_index");
6706       return -99;
6707     }
6708
6709   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6710
6711   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6712   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6713   mp->enable = enable;
6714
6715   S (mp);
6716   W (ret);
6717   return ret;
6718 }
6719
6720 static int
6721 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6722 {
6723   unformat_input_t *i = vam->input;
6724   vl_api_sw_interface_set_l2_bridge_t *mp;
6725   vl_api_l2_port_type_t port_type;
6726   u32 rx_sw_if_index;
6727   u8 rx_sw_if_index_set = 0;
6728   u32 bd_id;
6729   u8 bd_id_set = 0;
6730   u32 shg = 0;
6731   u8 enable = 1;
6732   int ret;
6733
6734   port_type = L2_API_PORT_TYPE_NORMAL;
6735
6736   /* Parse args required to build the message */
6737   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6738     {
6739       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6740         rx_sw_if_index_set = 1;
6741       else if (unformat (i, "bd_id %d", &bd_id))
6742         bd_id_set = 1;
6743       else
6744         if (unformat
6745             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6746         rx_sw_if_index_set = 1;
6747       else if (unformat (i, "shg %d", &shg))
6748         ;
6749       else if (unformat (i, "bvi"))
6750         port_type = L2_API_PORT_TYPE_BVI;
6751       else if (unformat (i, "uu-fwd"))
6752         port_type = L2_API_PORT_TYPE_UU_FWD;
6753       else if (unformat (i, "enable"))
6754         enable = 1;
6755       else if (unformat (i, "disable"))
6756         enable = 0;
6757       else
6758         break;
6759     }
6760
6761   if (rx_sw_if_index_set == 0)
6762     {
6763       errmsg ("missing rx interface name or sw_if_index");
6764       return -99;
6765     }
6766
6767   if (enable && (bd_id_set == 0))
6768     {
6769       errmsg ("missing bridge domain");
6770       return -99;
6771     }
6772
6773   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6774
6775   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6776   mp->bd_id = ntohl (bd_id);
6777   mp->shg = (u8) shg;
6778   mp->port_type = ntohl (port_type);
6779   mp->enable = enable;
6780
6781   S (mp);
6782   W (ret);
6783   return ret;
6784 }
6785
6786 static int
6787 api_bridge_domain_dump (vat_main_t * vam)
6788 {
6789   unformat_input_t *i = vam->input;
6790   vl_api_bridge_domain_dump_t *mp;
6791   vl_api_control_ping_t *mp_ping;
6792   u32 bd_id = ~0;
6793   int ret;
6794
6795   /* Parse args required to build the message */
6796   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6797     {
6798       if (unformat (i, "bd_id %d", &bd_id))
6799         ;
6800       else
6801         break;
6802     }
6803
6804   M (BRIDGE_DOMAIN_DUMP, mp);
6805   mp->bd_id = ntohl (bd_id);
6806   S (mp);
6807
6808   /* Use a control ping for synchronization */
6809   MPING (CONTROL_PING, mp_ping);
6810   S (mp_ping);
6811
6812   W (ret);
6813   return ret;
6814 }
6815
6816 static int
6817 api_bridge_domain_add_del (vat_main_t * vam)
6818 {
6819   unformat_input_t *i = vam->input;
6820   vl_api_bridge_domain_add_del_t *mp;
6821   u32 bd_id = ~0;
6822   u8 is_add = 1;
6823   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6824   u8 *bd_tag = NULL;
6825   u32 mac_age = 0;
6826   int ret;
6827
6828   /* Parse args required to build the message */
6829   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6830     {
6831       if (unformat (i, "bd_id %d", &bd_id))
6832         ;
6833       else if (unformat (i, "flood %d", &flood))
6834         ;
6835       else if (unformat (i, "uu-flood %d", &uu_flood))
6836         ;
6837       else if (unformat (i, "forward %d", &forward))
6838         ;
6839       else if (unformat (i, "learn %d", &learn))
6840         ;
6841       else if (unformat (i, "arp-term %d", &arp_term))
6842         ;
6843       else if (unformat (i, "mac-age %d", &mac_age))
6844         ;
6845       else if (unformat (i, "bd-tag %s", &bd_tag))
6846         ;
6847       else if (unformat (i, "del"))
6848         {
6849           is_add = 0;
6850           flood = uu_flood = forward = learn = 0;
6851         }
6852       else
6853         break;
6854     }
6855
6856   if (bd_id == ~0)
6857     {
6858       errmsg ("missing bridge domain");
6859       ret = -99;
6860       goto done;
6861     }
6862
6863   if (mac_age > 255)
6864     {
6865       errmsg ("mac age must be less than 256 ");
6866       ret = -99;
6867       goto done;
6868     }
6869
6870   if ((bd_tag) && (vec_len (bd_tag) > 63))
6871     {
6872       errmsg ("bd-tag cannot be longer than 63");
6873       ret = -99;
6874       goto done;
6875     }
6876
6877   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6878
6879   mp->bd_id = ntohl (bd_id);
6880   mp->flood = flood;
6881   mp->uu_flood = uu_flood;
6882   mp->forward = forward;
6883   mp->learn = learn;
6884   mp->arp_term = arp_term;
6885   mp->is_add = is_add;
6886   mp->mac_age = (u8) mac_age;
6887   if (bd_tag)
6888     {
6889       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6890       mp->bd_tag[vec_len (bd_tag)] = 0;
6891     }
6892   S (mp);
6893   W (ret);
6894
6895 done:
6896   vec_free (bd_tag);
6897   return ret;
6898 }
6899
6900 static int
6901 api_l2fib_flush_bd (vat_main_t * vam)
6902 {
6903   unformat_input_t *i = vam->input;
6904   vl_api_l2fib_flush_bd_t *mp;
6905   u32 bd_id = ~0;
6906   int ret;
6907
6908   /* Parse args required to build the message */
6909   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6910     {
6911       if (unformat (i, "bd_id %d", &bd_id));
6912       else
6913         break;
6914     }
6915
6916   if (bd_id == ~0)
6917     {
6918       errmsg ("missing bridge domain");
6919       return -99;
6920     }
6921
6922   M (L2FIB_FLUSH_BD, mp);
6923
6924   mp->bd_id = htonl (bd_id);
6925
6926   S (mp);
6927   W (ret);
6928   return ret;
6929 }
6930
6931 static int
6932 api_l2fib_flush_int (vat_main_t * vam)
6933 {
6934   unformat_input_t *i = vam->input;
6935   vl_api_l2fib_flush_int_t *mp;
6936   u32 sw_if_index = ~0;
6937   int ret;
6938
6939   /* Parse args required to build the message */
6940   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6941     {
6942       if (unformat (i, "sw_if_index %d", &sw_if_index));
6943       else
6944         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6945       else
6946         break;
6947     }
6948
6949   if (sw_if_index == ~0)
6950     {
6951       errmsg ("missing interface name or sw_if_index");
6952       return -99;
6953     }
6954
6955   M (L2FIB_FLUSH_INT, mp);
6956
6957   mp->sw_if_index = ntohl (sw_if_index);
6958
6959   S (mp);
6960   W (ret);
6961   return ret;
6962 }
6963
6964 static int
6965 api_l2fib_add_del (vat_main_t * vam)
6966 {
6967   unformat_input_t *i = vam->input;
6968   vl_api_l2fib_add_del_t *mp;
6969   f64 timeout;
6970   u8 mac[6] = { 0 };
6971   u8 mac_set = 0;
6972   u32 bd_id;
6973   u8 bd_id_set = 0;
6974   u32 sw_if_index = 0;
6975   u8 sw_if_index_set = 0;
6976   u8 is_add = 1;
6977   u8 static_mac = 0;
6978   u8 filter_mac = 0;
6979   u8 bvi_mac = 0;
6980   int count = 1;
6981   f64 before = 0;
6982   int j;
6983
6984   /* Parse args required to build the message */
6985   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6986     {
6987       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6988         mac_set = 1;
6989       else if (unformat (i, "bd_id %d", &bd_id))
6990         bd_id_set = 1;
6991       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6992         sw_if_index_set = 1;
6993       else if (unformat (i, "sw_if"))
6994         {
6995           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6996             {
6997               if (unformat
6998                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6999                 sw_if_index_set = 1;
7000             }
7001           else
7002             break;
7003         }
7004       else if (unformat (i, "static"))
7005         static_mac = 1;
7006       else if (unformat (i, "filter"))
7007         {
7008           filter_mac = 1;
7009           static_mac = 1;
7010         }
7011       else if (unformat (i, "bvi"))
7012         {
7013           bvi_mac = 1;
7014           static_mac = 1;
7015         }
7016       else if (unformat (i, "del"))
7017         is_add = 0;
7018       else if (unformat (i, "count %d", &count))
7019         ;
7020       else
7021         break;
7022     }
7023
7024   if (mac_set == 0)
7025     {
7026       errmsg ("missing mac address");
7027       return -99;
7028     }
7029
7030   if (bd_id_set == 0)
7031     {
7032       errmsg ("missing bridge domain");
7033       return -99;
7034     }
7035
7036   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7037     {
7038       errmsg ("missing interface name or sw_if_index");
7039       return -99;
7040     }
7041
7042   if (count > 1)
7043     {
7044       /* Turn on async mode */
7045       vam->async_mode = 1;
7046       vam->async_errors = 0;
7047       before = vat_time_now (vam);
7048     }
7049
7050   for (j = 0; j < count; j++)
7051     {
7052       M (L2FIB_ADD_DEL, mp);
7053
7054       clib_memcpy (mp->mac, mac, 6);
7055       mp->bd_id = ntohl (bd_id);
7056       mp->is_add = is_add;
7057       mp->sw_if_index = ntohl (sw_if_index);
7058
7059       if (is_add)
7060         {
7061           mp->static_mac = static_mac;
7062           mp->filter_mac = filter_mac;
7063           mp->bvi_mac = bvi_mac;
7064         }
7065       increment_mac_address (mac);
7066       /* send it... */
7067       S (mp);
7068     }
7069
7070   if (count > 1)
7071     {
7072       vl_api_control_ping_t *mp_ping;
7073       f64 after;
7074
7075       /* Shut off async mode */
7076       vam->async_mode = 0;
7077
7078       MPING (CONTROL_PING, mp_ping);
7079       S (mp_ping);
7080
7081       timeout = vat_time_now (vam) + 1.0;
7082       while (vat_time_now (vam) < timeout)
7083         if (vam->result_ready == 1)
7084           goto out;
7085       vam->retval = -99;
7086
7087     out:
7088       if (vam->retval == -99)
7089         errmsg ("timeout");
7090
7091       if (vam->async_errors > 0)
7092         {
7093           errmsg ("%d asynchronous errors", vam->async_errors);
7094           vam->retval = -98;
7095         }
7096       vam->async_errors = 0;
7097       after = vat_time_now (vam);
7098
7099       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7100              count, after - before, count / (after - before));
7101     }
7102   else
7103     {
7104       int ret;
7105
7106       /* Wait for a reply... */
7107       W (ret);
7108       return ret;
7109     }
7110   /* Return the good/bad news */
7111   return (vam->retval);
7112 }
7113
7114 static int
7115 api_bridge_domain_set_mac_age (vat_main_t * vam)
7116 {
7117   unformat_input_t *i = vam->input;
7118   vl_api_bridge_domain_set_mac_age_t *mp;
7119   u32 bd_id = ~0;
7120   u32 mac_age = 0;
7121   int ret;
7122
7123   /* Parse args required to build the message */
7124   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7125     {
7126       if (unformat (i, "bd_id %d", &bd_id));
7127       else if (unformat (i, "mac-age %d", &mac_age));
7128       else
7129         break;
7130     }
7131
7132   if (bd_id == ~0)
7133     {
7134       errmsg ("missing bridge domain");
7135       return -99;
7136     }
7137
7138   if (mac_age > 255)
7139     {
7140       errmsg ("mac age must be less than 256 ");
7141       return -99;
7142     }
7143
7144   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7145
7146   mp->bd_id = htonl (bd_id);
7147   mp->mac_age = (u8) mac_age;
7148
7149   S (mp);
7150   W (ret);
7151   return ret;
7152 }
7153
7154 static int
7155 api_l2_flags (vat_main_t * vam)
7156 {
7157   unformat_input_t *i = vam->input;
7158   vl_api_l2_flags_t *mp;
7159   u32 sw_if_index;
7160   u32 flags = 0;
7161   u8 sw_if_index_set = 0;
7162   u8 is_set = 0;
7163   int ret;
7164
7165   /* Parse args required to build the message */
7166   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7167     {
7168       if (unformat (i, "sw_if_index %d", &sw_if_index))
7169         sw_if_index_set = 1;
7170       else if (unformat (i, "sw_if"))
7171         {
7172           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7173             {
7174               if (unformat
7175                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7176                 sw_if_index_set = 1;
7177             }
7178           else
7179             break;
7180         }
7181       else if (unformat (i, "learn"))
7182         flags |= L2_LEARN;
7183       else if (unformat (i, "forward"))
7184         flags |= L2_FWD;
7185       else if (unformat (i, "flood"))
7186         flags |= L2_FLOOD;
7187       else if (unformat (i, "uu-flood"))
7188         flags |= L2_UU_FLOOD;
7189       else if (unformat (i, "arp-term"))
7190         flags |= L2_ARP_TERM;
7191       else if (unformat (i, "off"))
7192         is_set = 0;
7193       else if (unformat (i, "disable"))
7194         is_set = 0;
7195       else
7196         break;
7197     }
7198
7199   if (sw_if_index_set == 0)
7200     {
7201       errmsg ("missing interface name or sw_if_index");
7202       return -99;
7203     }
7204
7205   M (L2_FLAGS, mp);
7206
7207   mp->sw_if_index = ntohl (sw_if_index);
7208   mp->feature_bitmap = ntohl (flags);
7209   mp->is_set = is_set;
7210
7211   S (mp);
7212   W (ret);
7213   return ret;
7214 }
7215
7216 static int
7217 api_bridge_flags (vat_main_t * vam)
7218 {
7219   unformat_input_t *i = vam->input;
7220   vl_api_bridge_flags_t *mp;
7221   u32 bd_id;
7222   u8 bd_id_set = 0;
7223   u8 is_set = 1;
7224   bd_flags_t flags = 0;
7225   int ret;
7226
7227   /* Parse args required to build the message */
7228   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7229     {
7230       if (unformat (i, "bd_id %d", &bd_id))
7231         bd_id_set = 1;
7232       else if (unformat (i, "learn"))
7233         flags |= BRIDGE_API_FLAG_LEARN;
7234       else if (unformat (i, "forward"))
7235         flags |= BRIDGE_API_FLAG_FWD;
7236       else if (unformat (i, "flood"))
7237         flags |= BRIDGE_API_FLAG_FLOOD;
7238       else if (unformat (i, "uu-flood"))
7239         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7240       else if (unformat (i, "arp-term"))
7241         flags |= BRIDGE_API_FLAG_ARP_TERM;
7242       else if (unformat (i, "off"))
7243         is_set = 0;
7244       else if (unformat (i, "disable"))
7245         is_set = 0;
7246       else
7247         break;
7248     }
7249
7250   if (bd_id_set == 0)
7251     {
7252       errmsg ("missing bridge domain");
7253       return -99;
7254     }
7255
7256   M (BRIDGE_FLAGS, mp);
7257
7258   mp->bd_id = ntohl (bd_id);
7259   mp->flags = ntohl (flags);
7260   mp->is_set = is_set;
7261
7262   S (mp);
7263   W (ret);
7264   return ret;
7265 }
7266
7267 static int
7268 api_bd_ip_mac_add_del (vat_main_t * vam)
7269 {
7270   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7271   vl_api_mac_address_t mac = { 0 };
7272   unformat_input_t *i = vam->input;
7273   vl_api_bd_ip_mac_add_del_t *mp;
7274   u32 bd_id;
7275   u8 is_add = 1;
7276   u8 bd_id_set = 0;
7277   u8 ip_set = 0;
7278   u8 mac_set = 0;
7279   int ret;
7280
7281
7282   /* Parse args required to build the message */
7283   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7284     {
7285       if (unformat (i, "bd_id %d", &bd_id))
7286         {
7287           bd_id_set++;
7288         }
7289       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7290         {
7291           ip_set++;
7292         }
7293       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7294         {
7295           mac_set++;
7296         }
7297       else if (unformat (i, "del"))
7298         is_add = 0;
7299       else
7300         break;
7301     }
7302
7303   if (bd_id_set == 0)
7304     {
7305       errmsg ("missing bridge domain");
7306       return -99;
7307     }
7308   else if (ip_set == 0)
7309     {
7310       errmsg ("missing IP address");
7311       return -99;
7312     }
7313   else if (mac_set == 0)
7314     {
7315       errmsg ("missing MAC address");
7316       return -99;
7317     }
7318
7319   M (BD_IP_MAC_ADD_DEL, mp);
7320
7321   mp->bd_id = ntohl (bd_id);
7322   mp->is_add = is_add;
7323
7324   clib_memcpy (&mp->ip, &ip, sizeof (ip));
7325   clib_memcpy (&mp->mac, &mac, sizeof (mac));
7326
7327   S (mp);
7328   W (ret);
7329   return ret;
7330 }
7331
7332 static int
7333 api_bd_ip_mac_flush (vat_main_t * vam)
7334 {
7335   unformat_input_t *i = vam->input;
7336   vl_api_bd_ip_mac_flush_t *mp;
7337   u32 bd_id;
7338   u8 bd_id_set = 0;
7339   int ret;
7340
7341   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7342     {
7343       if (unformat (i, "bd_id %d", &bd_id))
7344         {
7345           bd_id_set++;
7346         }
7347       else
7348         break;
7349     }
7350
7351   if (bd_id_set == 0)
7352     {
7353       errmsg ("missing bridge domain");
7354       return -99;
7355     }
7356
7357   M (BD_IP_MAC_FLUSH, mp);
7358
7359   mp->bd_id = ntohl (bd_id);
7360
7361   S (mp);
7362   W (ret);
7363   return ret;
7364 }
7365
7366 static void vl_api_bd_ip_mac_details_t_handler
7367   (vl_api_bd_ip_mac_details_t * mp)
7368 {
7369   vat_main_t *vam = &vat_main;
7370   u8 *ip = 0;
7371
7372   if (!mp->is_ipv6)
7373     ip =
7374       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7375   else
7376     ip =
7377       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7378
7379   print (vam->ofp,
7380          "\n%-5d %-7s %-20U %-30s",
7381          ntohl (mp->bd_id), mp->is_ipv6 ? "ip6" : "ip4",
7382          format_ethernet_address, mp->mac_address, ip);
7383
7384   vec_free (ip);
7385 }
7386
7387 static void vl_api_bd_ip_mac_details_t_handler_json
7388   (vl_api_bd_ip_mac_details_t * mp)
7389 {
7390   vat_main_t *vam = &vat_main;
7391   vat_json_node_t *node = NULL;
7392
7393   if (VAT_JSON_ARRAY != vam->json_tree.type)
7394     {
7395       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7396       vat_json_init_array (&vam->json_tree);
7397     }
7398   node = vat_json_array_add (&vam->json_tree);
7399
7400   vat_json_init_object (node);
7401   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
7402   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
7403   vat_json_object_add_string_copy (node, "mac_address",
7404                                    format (0, "%U", format_ethernet_address,
7405                                            &mp->mac_address));
7406   u8 *ip = 0;
7407
7408   if (!mp->is_ipv6)
7409     ip =
7410       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7411   else
7412     ip =
7413       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7414   vat_json_object_add_string_copy (node, "ip_address", ip);
7415   vec_free (ip);
7416 }
7417
7418 static int
7419 api_bd_ip_mac_dump (vat_main_t * vam)
7420 {
7421   unformat_input_t *i = vam->input;
7422   vl_api_bd_ip_mac_dump_t *mp;
7423   vl_api_control_ping_t *mp_ping;
7424   int ret;
7425   u32 bd_id;
7426   u8 bd_id_set = 0;
7427
7428   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7429     {
7430       if (unformat (i, "bd_id %d", &bd_id))
7431         {
7432           bd_id_set++;
7433         }
7434       else
7435         break;
7436     }
7437
7438   print (vam->ofp,
7439          "\n%-5s %-7s %-20s %-30s",
7440          "bd_id", "is_ipv6", "mac_address", "ip_address");
7441
7442   /* Dump Bridge Domain Ip to Mac entries */
7443   M (BD_IP_MAC_DUMP, mp);
7444
7445   if (bd_id_set)
7446     mp->bd_id = htonl (bd_id);
7447   else
7448     mp->bd_id = ~0;
7449
7450   S (mp);
7451
7452   /* Use a control ping for synchronization */
7453   MPING (CONTROL_PING, mp_ping);
7454   S (mp_ping);
7455
7456   W (ret);
7457   return ret;
7458 }
7459
7460 static int
7461 api_tap_create_v2 (vat_main_t * vam)
7462 {
7463   unformat_input_t *i = vam->input;
7464   vl_api_tap_create_v2_t *mp;
7465   u8 mac_address[6];
7466   u8 random_mac = 1;
7467   u32 id = ~0;
7468   u8 *host_if_name = 0;
7469   u8 *host_ns = 0;
7470   u8 host_mac_addr[6];
7471   u8 host_mac_addr_set = 0;
7472   u8 *host_bridge = 0;
7473   ip4_address_t host_ip4_addr;
7474   ip4_address_t host_ip4_gw;
7475   u8 host_ip4_gw_set = 0;
7476   u32 host_ip4_prefix_len = 0;
7477   ip6_address_t host_ip6_addr;
7478   ip6_address_t host_ip6_gw;
7479   u8 host_ip6_gw_set = 0;
7480   u32 host_ip6_prefix_len = 0;
7481   int ret;
7482   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7483
7484   clib_memset (mac_address, 0, sizeof (mac_address));
7485
7486   /* Parse args required to build the message */
7487   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7488     {
7489       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7490         {
7491           random_mac = 0;
7492         }
7493       else if (unformat (i, "id %u", &id))
7494         ;
7495       else if (unformat (i, "host-if-name %s", &host_if_name))
7496         ;
7497       else if (unformat (i, "host-ns %s", &host_ns))
7498         ;
7499       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7500                          host_mac_addr))
7501         host_mac_addr_set = 1;
7502       else if (unformat (i, "host-bridge %s", &host_bridge))
7503         ;
7504       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7505                          &host_ip4_addr, &host_ip4_prefix_len))
7506         ;
7507       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7508                          &host_ip6_addr, &host_ip6_prefix_len))
7509         ;
7510       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7511                          &host_ip4_gw))
7512         host_ip4_gw_set = 1;
7513       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7514                          &host_ip6_gw))
7515         host_ip6_gw_set = 1;
7516       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7517         ;
7518       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7519         ;
7520       else
7521         break;
7522     }
7523
7524   if (vec_len (host_if_name) > 63)
7525     {
7526       errmsg ("tap name too long. ");
7527       return -99;
7528     }
7529   if (vec_len (host_ns) > 63)
7530     {
7531       errmsg ("host name space too long. ");
7532       return -99;
7533     }
7534   if (vec_len (host_bridge) > 63)
7535     {
7536       errmsg ("host bridge name too long. ");
7537       return -99;
7538     }
7539   if (host_ip4_prefix_len > 32)
7540     {
7541       errmsg ("host ip4 prefix length not valid. ");
7542       return -99;
7543     }
7544   if (host_ip6_prefix_len > 128)
7545     {
7546       errmsg ("host ip6 prefix length not valid. ");
7547       return -99;
7548     }
7549   if (!is_pow2 (rx_ring_sz))
7550     {
7551       errmsg ("rx ring size must be power of 2. ");
7552       return -99;
7553     }
7554   if (rx_ring_sz > 32768)
7555     {
7556       errmsg ("rx ring size must be 32768 or lower. ");
7557       return -99;
7558     }
7559   if (!is_pow2 (tx_ring_sz))
7560     {
7561       errmsg ("tx ring size must be power of 2. ");
7562       return -99;
7563     }
7564   if (tx_ring_sz > 32768)
7565     {
7566       errmsg ("tx ring size must be 32768 or lower. ");
7567       return -99;
7568     }
7569
7570   /* Construct the API message */
7571   M (TAP_CREATE_V2, mp);
7572
7573   mp->use_random_mac = random_mac;
7574
7575   mp->id = ntohl (id);
7576   mp->host_namespace_set = host_ns != 0;
7577   mp->host_bridge_set = host_bridge != 0;
7578   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7579   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7580   mp->rx_ring_sz = ntohs (rx_ring_sz);
7581   mp->tx_ring_sz = ntohs (tx_ring_sz);
7582
7583   if (random_mac == 0)
7584     clib_memcpy (mp->mac_address, mac_address, 6);
7585   if (host_mac_addr_set)
7586     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7587   if (host_if_name)
7588     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7589   if (host_ns)
7590     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7591   if (host_bridge)
7592     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7593   if (host_ip4_prefix_len)
7594     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
7595   if (host_ip6_prefix_len)
7596     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
7597   if (host_ip4_gw_set)
7598     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7599   if (host_ip6_gw_set)
7600     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7601
7602   vec_free (host_ns);
7603   vec_free (host_if_name);
7604   vec_free (host_bridge);
7605
7606   /* send it... */
7607   S (mp);
7608
7609   /* Wait for a reply... */
7610   W (ret);
7611   return ret;
7612 }
7613
7614 static int
7615 api_tap_delete_v2 (vat_main_t * vam)
7616 {
7617   unformat_input_t *i = vam->input;
7618   vl_api_tap_delete_v2_t *mp;
7619   u32 sw_if_index = ~0;
7620   u8 sw_if_index_set = 0;
7621   int ret;
7622
7623   /* Parse args required to build the message */
7624   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7625     {
7626       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7627         sw_if_index_set = 1;
7628       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7629         sw_if_index_set = 1;
7630       else
7631         break;
7632     }
7633
7634   if (sw_if_index_set == 0)
7635     {
7636       errmsg ("missing vpp interface name. ");
7637       return -99;
7638     }
7639
7640   /* Construct the API message */
7641   M (TAP_DELETE_V2, mp);
7642
7643   mp->sw_if_index = ntohl (sw_if_index);
7644
7645   /* send it... */
7646   S (mp);
7647
7648   /* Wait for a reply... */
7649   W (ret);
7650   return ret;
7651 }
7652
7653 uword
7654 unformat_pci_addr (unformat_input_t * input, va_list * args)
7655 {
7656   struct pci_addr_t
7657   {
7658     u16 domain;
7659     u8 bus;
7660     u8 slot:5;
7661     u8 function:3;
7662   } *addr;
7663   addr = va_arg (*args, struct pci_addr_t *);
7664   u32 x[4];
7665
7666   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7667     return 0;
7668
7669   addr->domain = x[0];
7670   addr->bus = x[1];
7671   addr->slot = x[2];
7672   addr->function = x[3];
7673
7674   return 1;
7675 }
7676
7677 static int
7678 api_virtio_pci_create (vat_main_t * vam)
7679 {
7680   unformat_input_t *i = vam->input;
7681   vl_api_virtio_pci_create_t *mp;
7682   u8 mac_address[6];
7683   u8 random_mac = 1;
7684   u8 gso_enabled = 0;
7685   u32 pci_addr = 0;
7686   u64 features = (u64) ~ (0ULL);
7687   int ret;
7688
7689   clib_memset (mac_address, 0, sizeof (mac_address));
7690
7691   /* Parse args required to build the message */
7692   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7693     {
7694       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7695         {
7696           random_mac = 0;
7697         }
7698       else if (unformat (i, "pci-addr %U", unformat_pci_addr, &pci_addr))
7699         ;
7700       else if (unformat (i, "features 0x%llx", &features))
7701         ;
7702       else if (unformat (i, "gso-enabled"))
7703         gso_enabled = 1;
7704       else
7705         break;
7706     }
7707
7708   if (pci_addr == 0)
7709     {
7710       errmsg ("pci address must be non zero. ");
7711       return -99;
7712     }
7713
7714   /* Construct the API message */
7715   M (VIRTIO_PCI_CREATE, mp);
7716
7717   mp->use_random_mac = random_mac;
7718
7719   mp->pci_addr = htonl (pci_addr);
7720   mp->features = clib_host_to_net_u64 (features);
7721   mp->gso_enabled = gso_enabled;
7722
7723   if (random_mac == 0)
7724     clib_memcpy (mp->mac_address, mac_address, 6);
7725
7726   /* send it... */
7727   S (mp);
7728
7729   /* Wait for a reply... */
7730   W (ret);
7731   return ret;
7732 }
7733
7734 static int
7735 api_virtio_pci_delete (vat_main_t * vam)
7736 {
7737   unformat_input_t *i = vam->input;
7738   vl_api_virtio_pci_delete_t *mp;
7739   u32 sw_if_index = ~0;
7740   u8 sw_if_index_set = 0;
7741   int ret;
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
7751         break;
7752     }
7753
7754   if (sw_if_index_set == 0)
7755     {
7756       errmsg ("missing vpp interface name. ");
7757       return -99;
7758     }
7759
7760   /* Construct the API message */
7761   M (VIRTIO_PCI_DELETE, mp);
7762
7763   mp->sw_if_index = htonl (sw_if_index);
7764
7765   /* send it... */
7766   S (mp);
7767
7768   /* Wait for a reply... */
7769   W (ret);
7770   return ret;
7771 }
7772
7773 static int
7774 api_bond_create (vat_main_t * vam)
7775 {
7776   unformat_input_t *i = vam->input;
7777   vl_api_bond_create_t *mp;
7778   u8 mac_address[6];
7779   u8 custom_mac = 0;
7780   int ret;
7781   u8 mode;
7782   u8 lb;
7783   u8 mode_is_set = 0;
7784   u32 id = ~0;
7785
7786   clib_memset (mac_address, 0, sizeof (mac_address));
7787   lb = BOND_LB_L2;
7788
7789   /* Parse args required to build the message */
7790   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7791     {
7792       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7793         mode_is_set = 1;
7794       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7795                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7796         ;
7797       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7798                          mac_address))
7799         custom_mac = 1;
7800       else if (unformat (i, "id %u", &id))
7801         ;
7802       else
7803         break;
7804     }
7805
7806   if (mode_is_set == 0)
7807     {
7808       errmsg ("Missing bond mode. ");
7809       return -99;
7810     }
7811
7812   /* Construct the API message */
7813   M (BOND_CREATE, mp);
7814
7815   mp->use_custom_mac = custom_mac;
7816
7817   mp->mode = mode;
7818   mp->lb = lb;
7819   mp->id = htonl (id);
7820
7821   if (custom_mac)
7822     clib_memcpy (mp->mac_address, mac_address, 6);
7823
7824   /* send it... */
7825   S (mp);
7826
7827   /* Wait for a reply... */
7828   W (ret);
7829   return ret;
7830 }
7831
7832 static int
7833 api_bond_delete (vat_main_t * vam)
7834 {
7835   unformat_input_t *i = vam->input;
7836   vl_api_bond_delete_t *mp;
7837   u32 sw_if_index = ~0;
7838   u8 sw_if_index_set = 0;
7839   int ret;
7840
7841   /* Parse args required to build the message */
7842   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7843     {
7844       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7845         sw_if_index_set = 1;
7846       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7847         sw_if_index_set = 1;
7848       else
7849         break;
7850     }
7851
7852   if (sw_if_index_set == 0)
7853     {
7854       errmsg ("missing vpp interface name. ");
7855       return -99;
7856     }
7857
7858   /* Construct the API message */
7859   M (BOND_DELETE, mp);
7860
7861   mp->sw_if_index = ntohl (sw_if_index);
7862
7863   /* send it... */
7864   S (mp);
7865
7866   /* Wait for a reply... */
7867   W (ret);
7868   return ret;
7869 }
7870
7871 static int
7872 api_bond_enslave (vat_main_t * vam)
7873 {
7874   unformat_input_t *i = vam->input;
7875   vl_api_bond_enslave_t *mp;
7876   u32 bond_sw_if_index;
7877   int ret;
7878   u8 is_passive;
7879   u8 is_long_timeout;
7880   u32 bond_sw_if_index_is_set = 0;
7881   u32 sw_if_index;
7882   u8 sw_if_index_is_set = 0;
7883
7884   /* Parse args required to build the message */
7885   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7886     {
7887       if (unformat (i, "sw_if_index %d", &sw_if_index))
7888         sw_if_index_is_set = 1;
7889       else if (unformat (i, "bond %u", &bond_sw_if_index))
7890         bond_sw_if_index_is_set = 1;
7891       else if (unformat (i, "passive %d", &is_passive))
7892         ;
7893       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7894         ;
7895       else
7896         break;
7897     }
7898
7899   if (bond_sw_if_index_is_set == 0)
7900     {
7901       errmsg ("Missing bond sw_if_index. ");
7902       return -99;
7903     }
7904   if (sw_if_index_is_set == 0)
7905     {
7906       errmsg ("Missing slave sw_if_index. ");
7907       return -99;
7908     }
7909
7910   /* Construct the API message */
7911   M (BOND_ENSLAVE, mp);
7912
7913   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7914   mp->sw_if_index = ntohl (sw_if_index);
7915   mp->is_long_timeout = is_long_timeout;
7916   mp->is_passive = is_passive;
7917
7918   /* send it... */
7919   S (mp);
7920
7921   /* Wait for a reply... */
7922   W (ret);
7923   return ret;
7924 }
7925
7926 static int
7927 api_bond_detach_slave (vat_main_t * vam)
7928 {
7929   unformat_input_t *i = vam->input;
7930   vl_api_bond_detach_slave_t *mp;
7931   u32 sw_if_index = ~0;
7932   u8 sw_if_index_set = 0;
7933   int ret;
7934
7935   /* Parse args required to build the message */
7936   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7937     {
7938       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7939         sw_if_index_set = 1;
7940       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7941         sw_if_index_set = 1;
7942       else
7943         break;
7944     }
7945
7946   if (sw_if_index_set == 0)
7947     {
7948       errmsg ("missing vpp interface name. ");
7949       return -99;
7950     }
7951
7952   /* Construct the API message */
7953   M (BOND_DETACH_SLAVE, mp);
7954
7955   mp->sw_if_index = ntohl (sw_if_index);
7956
7957   /* send it... */
7958   S (mp);
7959
7960   /* Wait for a reply... */
7961   W (ret);
7962   return ret;
7963 }
7964
7965 static int
7966 api_ip_table_add_del (vat_main_t * vam)
7967 {
7968   unformat_input_t *i = vam->input;
7969   vl_api_ip_table_add_del_t *mp;
7970   u32 table_id = ~0;
7971   u8 is_ipv6 = 0;
7972   u8 is_add = 1;
7973   int ret = 0;
7974
7975   /* Parse args required to build the message */
7976   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7977     {
7978       if (unformat (i, "ipv6"))
7979         is_ipv6 = 1;
7980       else if (unformat (i, "del"))
7981         is_add = 0;
7982       else if (unformat (i, "add"))
7983         is_add = 1;
7984       else if (unformat (i, "table %d", &table_id))
7985         ;
7986       else
7987         {
7988           clib_warning ("parse error '%U'", format_unformat_error, i);
7989           return -99;
7990         }
7991     }
7992
7993   if (~0 == table_id)
7994     {
7995       errmsg ("missing table-ID");
7996       return -99;
7997     }
7998
7999   /* Construct the API message */
8000   M (IP_TABLE_ADD_DEL, mp);
8001
8002   mp->table_id = ntohl (table_id);
8003   mp->is_ipv6 = is_ipv6;
8004   mp->is_add = is_add;
8005
8006   /* send it... */
8007   S (mp);
8008
8009   /* Wait for a reply... */
8010   W (ret);
8011
8012   return ret;
8013 }
8014
8015 static int
8016 api_ip_add_del_route (vat_main_t * vam)
8017 {
8018   unformat_input_t *i = vam->input;
8019   vl_api_ip_add_del_route_t *mp;
8020   u32 sw_if_index = ~0, vrf_id = 0;
8021   u8 is_ipv6 = 0;
8022   u8 is_local = 0, is_drop = 0;
8023   u8 is_unreach = 0, is_prohibit = 0;
8024   u8 is_add = 1;
8025   u32 next_hop_weight = 1;
8026   u8 is_multipath = 0;
8027   u8 address_set = 0;
8028   u8 address_length_set = 0;
8029   u32 next_hop_table_id = 0;
8030   u32 resolve_attempts = 0;
8031   u32 dst_address_length = 0;
8032   u8 next_hop_set = 0;
8033   ip4_address_t v4_dst_address, v4_next_hop_address;
8034   ip6_address_t v6_dst_address, v6_next_hop_address;
8035   int count = 1;
8036   int j;
8037   f64 before = 0;
8038   u32 random_add_del = 0;
8039   u32 *random_vector = 0;
8040   uword *random_hash;
8041   u32 random_seed = 0xdeaddabe;
8042   u32 classify_table_index = ~0;
8043   u8 is_classify = 0;
8044   u8 resolve_host = 0, resolve_attached = 0;
8045   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8046   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8047   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8048
8049   clib_memset (&v4_next_hop_address, 0, sizeof (ip4_address_t));
8050   clib_memset (&v6_next_hop_address, 0, sizeof (ip6_address_t));
8051   /* Parse args required to build the message */
8052   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8053     {
8054       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8055         ;
8056       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8057         ;
8058       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8059         {
8060           address_set = 1;
8061           is_ipv6 = 0;
8062         }
8063       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8064         {
8065           address_set = 1;
8066           is_ipv6 = 1;
8067         }
8068       else if (unformat (i, "/%d", &dst_address_length))
8069         {
8070           address_length_set = 1;
8071         }
8072
8073       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8074                                          &v4_next_hop_address))
8075         {
8076           next_hop_set = 1;
8077         }
8078       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8079                                          &v6_next_hop_address))
8080         {
8081           next_hop_set = 1;
8082         }
8083       else
8084         if (unformat
8085             (i, "via %U", api_unformat_sw_if_index, vam, &sw_if_index))
8086         {
8087           next_hop_set = 1;
8088         }
8089       else if (unformat (i, "via sw_if_index %d", &sw_if_index))
8090         {
8091           next_hop_set = 1;
8092         }
8093       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8094         ;
8095       else if (unformat (i, "weight %d", &next_hop_weight))
8096         ;
8097       else if (unformat (i, "drop"))
8098         {
8099           is_drop = 1;
8100         }
8101       else if (unformat (i, "null-send-unreach"))
8102         {
8103           is_unreach = 1;
8104         }
8105       else if (unformat (i, "null-send-prohibit"))
8106         {
8107           is_prohibit = 1;
8108         }
8109       else if (unformat (i, "local"))
8110         {
8111           is_local = 1;
8112         }
8113       else if (unformat (i, "classify %d", &classify_table_index))
8114         {
8115           is_classify = 1;
8116         }
8117       else if (unformat (i, "del"))
8118         is_add = 0;
8119       else if (unformat (i, "add"))
8120         is_add = 1;
8121       else if (unformat (i, "resolve-via-host"))
8122         resolve_host = 1;
8123       else if (unformat (i, "resolve-via-attached"))
8124         resolve_attached = 1;
8125       else if (unformat (i, "multipath"))
8126         is_multipath = 1;
8127       else if (unformat (i, "vrf %d", &vrf_id))
8128         ;
8129       else if (unformat (i, "count %d", &count))
8130         ;
8131       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8132         ;
8133       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8134         ;
8135       else if (unformat (i, "out-label %d", &next_hop_out_label))
8136         {
8137           vl_api_fib_mpls_label_t fib_label = {
8138             .label = ntohl (next_hop_out_label),
8139             .ttl = 64,
8140             .exp = 0,
8141           };
8142           vec_add1 (next_hop_out_label_stack, fib_label);
8143         }
8144       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8145         ;
8146       else if (unformat (i, "random"))
8147         random_add_del = 1;
8148       else if (unformat (i, "seed %d", &random_seed))
8149         ;
8150       else
8151         {
8152           clib_warning ("parse error '%U'", format_unformat_error, i);
8153           return -99;
8154         }
8155     }
8156
8157   if (!next_hop_set && !is_drop && !is_local &&
8158       !is_classify && !is_unreach && !is_prohibit &&
8159       MPLS_LABEL_INVALID == next_hop_via_label)
8160     {
8161       errmsg
8162         ("next hop / local / drop / unreach / prohibit / classify not set");
8163       return -99;
8164     }
8165
8166   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8167     {
8168       errmsg ("next hop and next-hop via label set");
8169       return -99;
8170     }
8171   if (address_set == 0)
8172     {
8173       errmsg ("missing addresses");
8174       return -99;
8175     }
8176
8177   if (address_length_set == 0)
8178     {
8179       errmsg ("missing address length");
8180       return -99;
8181     }
8182
8183   /* Generate a pile of unique, random routes */
8184   if (random_add_del)
8185     {
8186       u32 this_random_address;
8187       random_hash = hash_create (count, sizeof (uword));
8188
8189       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8190       for (j = 0; j <= count; j++)
8191         {
8192           do
8193             {
8194               this_random_address = random_u32 (&random_seed);
8195               this_random_address =
8196                 clib_host_to_net_u32 (this_random_address);
8197             }
8198           while (hash_get (random_hash, this_random_address));
8199           vec_add1 (random_vector, this_random_address);
8200           hash_set (random_hash, this_random_address, 1);
8201         }
8202       hash_free (random_hash);
8203       v4_dst_address.as_u32 = random_vector[0];
8204     }
8205
8206   if (count > 1)
8207     {
8208       /* Turn on async mode */
8209       vam->async_mode = 1;
8210       vam->async_errors = 0;
8211       before = vat_time_now (vam);
8212     }
8213
8214   for (j = 0; j < count; j++)
8215     {
8216       /* Construct the API message */
8217       M2 (IP_ADD_DEL_ROUTE, mp, sizeof (vl_api_fib_mpls_label_t) *
8218           vec_len (next_hop_out_label_stack));
8219
8220       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8221       mp->table_id = ntohl (vrf_id);
8222
8223       mp->is_add = is_add;
8224       mp->is_drop = is_drop;
8225       mp->is_unreach = is_unreach;
8226       mp->is_prohibit = is_prohibit;
8227       mp->is_ipv6 = is_ipv6;
8228       mp->is_local = is_local;
8229       mp->is_classify = is_classify;
8230       mp->is_multipath = is_multipath;
8231       mp->is_resolve_host = resolve_host;
8232       mp->is_resolve_attached = resolve_attached;
8233       mp->next_hop_weight = next_hop_weight;
8234       mp->next_hop_preference = 0;
8235       mp->dst_address_length = dst_address_length;
8236       mp->next_hop_table_id = ntohl (next_hop_table_id);
8237       mp->classify_table_index = ntohl (classify_table_index);
8238       mp->next_hop_via_label = ntohl (next_hop_via_label);
8239       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8240       if (0 != mp->next_hop_n_out_labels)
8241         {
8242           memcpy (mp->next_hop_out_label_stack,
8243                   next_hop_out_label_stack,
8244                   (vec_len (next_hop_out_label_stack) *
8245                    sizeof (vl_api_fib_mpls_label_t)));
8246           vec_free (next_hop_out_label_stack);
8247         }
8248
8249       if (is_ipv6)
8250         {
8251           clib_memcpy (mp->dst_address, &v6_dst_address,
8252                        sizeof (v6_dst_address));
8253           if (next_hop_set)
8254             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8255                          sizeof (v6_next_hop_address));
8256           increment_v6_address (&v6_dst_address);
8257         }
8258       else
8259         {
8260           clib_memcpy (mp->dst_address, &v4_dst_address,
8261                        sizeof (v4_dst_address));
8262           if (next_hop_set)
8263             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8264                          sizeof (v4_next_hop_address));
8265           if (random_add_del)
8266             v4_dst_address.as_u32 = random_vector[j + 1];
8267           else
8268             increment_v4_address (&v4_dst_address);
8269         }
8270       /* send it... */
8271       S (mp);
8272       /* If we receive SIGTERM, stop now... */
8273       if (vam->do_exit)
8274         break;
8275     }
8276
8277   /* When testing multiple add/del ops, use a control-ping to sync */
8278   if (count > 1)
8279     {
8280       vl_api_control_ping_t *mp_ping;
8281       f64 after;
8282       f64 timeout;
8283
8284       /* Shut off async mode */
8285       vam->async_mode = 0;
8286
8287       MPING (CONTROL_PING, mp_ping);
8288       S (mp_ping);
8289
8290       timeout = vat_time_now (vam) + 1.0;
8291       while (vat_time_now (vam) < timeout)
8292         if (vam->result_ready == 1)
8293           goto out;
8294       vam->retval = -99;
8295
8296     out:
8297       if (vam->retval == -99)
8298         errmsg ("timeout");
8299
8300       if (vam->async_errors > 0)
8301         {
8302           errmsg ("%d asynchronous errors", vam->async_errors);
8303           vam->retval = -98;
8304         }
8305       vam->async_errors = 0;
8306       after = vat_time_now (vam);
8307
8308       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8309       if (j > 0)
8310         count = j;
8311
8312       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8313              count, after - before, count / (after - before));
8314     }
8315   else
8316     {
8317       int ret;
8318
8319       /* Wait for a reply... */
8320       W (ret);
8321       return ret;
8322     }
8323
8324   /* Return the good/bad news */
8325   return (vam->retval);
8326 }
8327
8328 static int
8329 api_ip_mroute_add_del (vat_main_t * vam)
8330 {
8331   unformat_input_t *i = vam->input;
8332   vl_api_ip_mroute_add_del_t *mp;
8333   u32 sw_if_index = ~0, vrf_id = 0;
8334   u8 is_ipv6 = 0;
8335   u8 is_local = 0;
8336   u8 is_add = 1;
8337   u8 address_set = 0;
8338   u32 grp_address_length = 0;
8339   ip4_address_t v4_grp_address, v4_src_address;
8340   ip6_address_t v6_grp_address, v6_src_address;
8341   mfib_itf_flags_t iflags = 0;
8342   mfib_entry_flags_t eflags = 0;
8343   int ret;
8344
8345   /* Parse args required to build the message */
8346   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8347     {
8348       if (unformat (i, "sw_if_index %d", &sw_if_index))
8349         ;
8350       else if (unformat (i, "%U %U",
8351                          unformat_ip4_address, &v4_src_address,
8352                          unformat_ip4_address, &v4_grp_address))
8353         {
8354           grp_address_length = 64;
8355           address_set = 1;
8356           is_ipv6 = 0;
8357         }
8358       else if (unformat (i, "%U %U",
8359                          unformat_ip6_address, &v6_src_address,
8360                          unformat_ip6_address, &v6_grp_address))
8361         {
8362           grp_address_length = 256;
8363           address_set = 1;
8364           is_ipv6 = 1;
8365         }
8366       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8367         {
8368           clib_memset (&v4_src_address, 0, sizeof (v4_src_address));
8369           grp_address_length = 32;
8370           address_set = 1;
8371           is_ipv6 = 0;
8372         }
8373       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8374         {
8375           clib_memset (&v6_src_address, 0, sizeof (v6_src_address));
8376           grp_address_length = 128;
8377           address_set = 1;
8378           is_ipv6 = 1;
8379         }
8380       else if (unformat (i, "/%d", &grp_address_length))
8381         ;
8382       else if (unformat (i, "local"))
8383         {
8384           is_local = 1;
8385         }
8386       else if (unformat (i, "del"))
8387         is_add = 0;
8388       else if (unformat (i, "add"))
8389         is_add = 1;
8390       else if (unformat (i, "vrf %d", &vrf_id))
8391         ;
8392       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8393         ;
8394       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8395         ;
8396       else
8397         {
8398           clib_warning ("parse error '%U'", format_unformat_error, i);
8399           return -99;
8400         }
8401     }
8402
8403   if (address_set == 0)
8404     {
8405       errmsg ("missing addresses\n");
8406       return -99;
8407     }
8408
8409   /* Construct the API message */
8410   M (IP_MROUTE_ADD_DEL, mp);
8411
8412   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8413   mp->table_id = ntohl (vrf_id);
8414
8415   mp->is_add = is_add;
8416   mp->is_ipv6 = is_ipv6;
8417   mp->is_local = is_local;
8418   mp->itf_flags = ntohl (iflags);
8419   mp->entry_flags = ntohl (eflags);
8420   mp->grp_address_length = grp_address_length;
8421   mp->grp_address_length = ntohs (mp->grp_address_length);
8422
8423   if (is_ipv6)
8424     {
8425       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8426       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8427     }
8428   else
8429     {
8430       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8431       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8432
8433     }
8434
8435   /* send it... */
8436   S (mp);
8437   /* Wait for a reply... */
8438   W (ret);
8439   return ret;
8440 }
8441
8442 static int
8443 api_mpls_table_add_del (vat_main_t * vam)
8444 {
8445   unformat_input_t *i = vam->input;
8446   vl_api_mpls_table_add_del_t *mp;
8447   u32 table_id = ~0;
8448   u8 is_add = 1;
8449   int ret = 0;
8450
8451   /* Parse args required to build the message */
8452   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8453     {
8454       if (unformat (i, "table %d", &table_id))
8455         ;
8456       else if (unformat (i, "del"))
8457         is_add = 0;
8458       else if (unformat (i, "add"))
8459         is_add = 1;
8460       else
8461         {
8462           clib_warning ("parse error '%U'", format_unformat_error, i);
8463           return -99;
8464         }
8465     }
8466
8467   if (~0 == table_id)
8468     {
8469       errmsg ("missing table-ID");
8470       return -99;
8471     }
8472
8473   /* Construct the API message */
8474   M (MPLS_TABLE_ADD_DEL, mp);
8475
8476   mp->mt_table_id = ntohl (table_id);
8477   mp->mt_is_add = is_add;
8478
8479   /* send it... */
8480   S (mp);
8481
8482   /* Wait for a reply... */
8483   W (ret);
8484
8485   return ret;
8486 }
8487
8488 static int
8489 api_mpls_route_add_del (vat_main_t * vam)
8490 {
8491   unformat_input_t *i = vam->input;
8492   vl_api_mpls_route_add_del_t *mp;
8493   u32 sw_if_index = ~0, table_id = 0;
8494   u8 is_add = 1;
8495   u32 next_hop_weight = 1;
8496   u8 is_multipath = 0;
8497   u32 next_hop_table_id = 0;
8498   u8 next_hop_set = 0;
8499   ip4_address_t v4_next_hop_address = {
8500     .as_u32 = 0,
8501   };
8502   ip6_address_t v6_next_hop_address = { {0} };
8503   int count = 1;
8504   int j;
8505   f64 before = 0;
8506   u32 classify_table_index = ~0;
8507   u8 is_classify = 0;
8508   u8 resolve_host = 0, resolve_attached = 0;
8509   u8 is_interface_rx = 0;
8510   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8511   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8512   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8513   mpls_label_t local_label = MPLS_LABEL_INVALID;
8514   u8 is_eos = 0;
8515   dpo_proto_t next_hop_proto = DPO_PROTO_MPLS;
8516
8517   /* Parse args required to build the message */
8518   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8519     {
8520       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8521         ;
8522       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8523         ;
8524       else if (unformat (i, "%d", &local_label))
8525         ;
8526       else if (unformat (i, "eos"))
8527         is_eos = 1;
8528       else if (unformat (i, "non-eos"))
8529         is_eos = 0;
8530       else if (unformat (i, "via %U", unformat_ip4_address,
8531                          &v4_next_hop_address))
8532         {
8533           next_hop_set = 1;
8534           next_hop_proto = DPO_PROTO_IP4;
8535         }
8536       else if (unformat (i, "via %U", unformat_ip6_address,
8537                          &v6_next_hop_address))
8538         {
8539           next_hop_set = 1;
8540           next_hop_proto = DPO_PROTO_IP6;
8541         }
8542       else if (unformat (i, "weight %d", &next_hop_weight))
8543         ;
8544       else if (unformat (i, "classify %d", &classify_table_index))
8545         {
8546           is_classify = 1;
8547         }
8548       else if (unformat (i, "del"))
8549         is_add = 0;
8550       else if (unformat (i, "add"))
8551         is_add = 1;
8552       else if (unformat (i, "resolve-via-host"))
8553         resolve_host = 1;
8554       else if (unformat (i, "resolve-via-attached"))
8555         resolve_attached = 1;
8556       else if (unformat (i, "multipath"))
8557         is_multipath = 1;
8558       else if (unformat (i, "count %d", &count))
8559         ;
8560       else if (unformat (i, "via lookup-in-ip4-table %d", &next_hop_table_id))
8561         {
8562           next_hop_set = 1;
8563           next_hop_proto = DPO_PROTO_IP4;
8564         }
8565       else if (unformat (i, "via lookup-in-ip6-table %d", &next_hop_table_id))
8566         {
8567           next_hop_set = 1;
8568           next_hop_proto = DPO_PROTO_IP6;
8569         }
8570       else
8571         if (unformat
8572             (i, "via l2-input-on %U", api_unformat_sw_if_index, vam,
8573              &sw_if_index))
8574         {
8575           next_hop_set = 1;
8576           next_hop_proto = DPO_PROTO_ETHERNET;
8577           is_interface_rx = 1;
8578         }
8579       else if (unformat (i, "via l2-input-on sw_if_index %d", &sw_if_index))
8580         {
8581           next_hop_set = 1;
8582           next_hop_proto = DPO_PROTO_ETHERNET;
8583           is_interface_rx = 1;
8584         }
8585       else if (unformat (i, "via next-hop-table %d", &next_hop_table_id))
8586         next_hop_set = 1;
8587       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8588         next_hop_set = 1;
8589       else if (unformat (i, "out-label %d", &next_hop_out_label))
8590         {
8591           vl_api_fib_mpls_label_t fib_label = {
8592             .label = ntohl (next_hop_out_label),
8593             .ttl = 64,
8594             .exp = 0,
8595           };
8596           vec_add1 (next_hop_out_label_stack, fib_label);
8597         }
8598       else
8599         {
8600           clib_warning ("parse error '%U'", format_unformat_error, i);
8601           return -99;
8602         }
8603     }
8604
8605   if (!next_hop_set && !is_classify)
8606     {
8607       errmsg ("next hop / classify not set");
8608       return -99;
8609     }
8610
8611   if (MPLS_LABEL_INVALID == local_label)
8612     {
8613       errmsg ("missing label");
8614       return -99;
8615     }
8616
8617   if (count > 1)
8618     {
8619       /* Turn on async mode */
8620       vam->async_mode = 1;
8621       vam->async_errors = 0;
8622       before = vat_time_now (vam);
8623     }
8624
8625   for (j = 0; j < count; j++)
8626     {
8627       /* Construct the API message */
8628       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
8629           vec_len (next_hop_out_label_stack));
8630
8631       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8632       mp->mr_table_id = ntohl (table_id);
8633
8634       mp->mr_is_add = is_add;
8635       mp->mr_next_hop_proto = next_hop_proto;
8636       mp->mr_is_classify = is_classify;
8637       mp->mr_is_multipath = is_multipath;
8638       mp->mr_is_resolve_host = resolve_host;
8639       mp->mr_is_resolve_attached = resolve_attached;
8640       mp->mr_is_interface_rx = is_interface_rx;
8641       mp->mr_next_hop_weight = next_hop_weight;
8642       mp->mr_next_hop_preference = 0;
8643       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8644       mp->mr_classify_table_index = ntohl (classify_table_index);
8645       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8646       mp->mr_label = ntohl (local_label);
8647       mp->mr_eos = is_eos;
8648
8649       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8650       if (0 != mp->mr_next_hop_n_out_labels)
8651         {
8652           memcpy (mp->mr_next_hop_out_label_stack,
8653                   next_hop_out_label_stack,
8654                   vec_len (next_hop_out_label_stack) *
8655                   sizeof (vl_api_fib_mpls_label_t));
8656           vec_free (next_hop_out_label_stack);
8657         }
8658
8659       if (next_hop_set)
8660         {
8661           if (DPO_PROTO_IP4 == next_hop_proto)
8662             {
8663               clib_memcpy (mp->mr_next_hop,
8664                            &v4_next_hop_address,
8665                            sizeof (v4_next_hop_address));
8666             }
8667           else if (DPO_PROTO_IP6 == next_hop_proto)
8668
8669             {
8670               clib_memcpy (mp->mr_next_hop,
8671                            &v6_next_hop_address,
8672                            sizeof (v6_next_hop_address));
8673             }
8674         }
8675       local_label++;
8676
8677       /* send it... */
8678       S (mp);
8679       /* If we receive SIGTERM, stop now... */
8680       if (vam->do_exit)
8681         break;
8682     }
8683
8684   /* When testing multiple add/del ops, use a control-ping to sync */
8685   if (count > 1)
8686     {
8687       vl_api_control_ping_t *mp_ping;
8688       f64 after;
8689       f64 timeout;
8690
8691       /* Shut off async mode */
8692       vam->async_mode = 0;
8693
8694       MPING (CONTROL_PING, mp_ping);
8695       S (mp_ping);
8696
8697       timeout = vat_time_now (vam) + 1.0;
8698       while (vat_time_now (vam) < timeout)
8699         if (vam->result_ready == 1)
8700           goto out;
8701       vam->retval = -99;
8702
8703     out:
8704       if (vam->retval == -99)
8705         errmsg ("timeout");
8706
8707       if (vam->async_errors > 0)
8708         {
8709           errmsg ("%d asynchronous errors", vam->async_errors);
8710           vam->retval = -98;
8711         }
8712       vam->async_errors = 0;
8713       after = vat_time_now (vam);
8714
8715       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8716       if (j > 0)
8717         count = j;
8718
8719       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8720              count, after - before, count / (after - before));
8721     }
8722   else
8723     {
8724       int ret;
8725
8726       /* Wait for a reply... */
8727       W (ret);
8728       return ret;
8729     }
8730
8731   /* Return the good/bad news */
8732   return (vam->retval);
8733 }
8734
8735 static int
8736 api_mpls_ip_bind_unbind (vat_main_t * vam)
8737 {
8738   unformat_input_t *i = vam->input;
8739   vl_api_mpls_ip_bind_unbind_t *mp;
8740   u32 ip_table_id = 0;
8741   u8 is_bind = 1;
8742   u8 is_ip4 = 1;
8743   ip4_address_t v4_address;
8744   ip6_address_t v6_address;
8745   u32 address_length;
8746   u8 address_set = 0;
8747   mpls_label_t local_label = MPLS_LABEL_INVALID;
8748   int ret;
8749
8750   /* Parse args required to build the message */
8751   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8752     {
8753       if (unformat (i, "%U/%d", unformat_ip4_address,
8754                     &v4_address, &address_length))
8755         {
8756           is_ip4 = 1;
8757           address_set = 1;
8758         }
8759       else if (unformat (i, "%U/%d", unformat_ip6_address,
8760                          &v6_address, &address_length))
8761         {
8762           is_ip4 = 0;
8763           address_set = 1;
8764         }
8765       else if (unformat (i, "%d", &local_label))
8766         ;
8767       else if (unformat (i, "table-id %d", &ip_table_id))
8768         ;
8769       else if (unformat (i, "unbind"))
8770         is_bind = 0;
8771       else if (unformat (i, "bind"))
8772         is_bind = 1;
8773       else
8774         {
8775           clib_warning ("parse error '%U'", format_unformat_error, i);
8776           return -99;
8777         }
8778     }
8779
8780   if (!address_set)
8781     {
8782       errmsg ("IP address not set");
8783       return -99;
8784     }
8785
8786   if (MPLS_LABEL_INVALID == local_label)
8787     {
8788       errmsg ("missing label");
8789       return -99;
8790     }
8791
8792   /* Construct the API message */
8793   M (MPLS_IP_BIND_UNBIND, mp);
8794
8795   mp->mb_is_bind = is_bind;
8796   mp->mb_is_ip4 = is_ip4;
8797   mp->mb_ip_table_id = ntohl (ip_table_id);
8798   mp->mb_mpls_table_id = 0;
8799   mp->mb_label = ntohl (local_label);
8800   mp->mb_address_length = address_length;
8801
8802   if (is_ip4)
8803     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8804   else
8805     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8806
8807   /* send it... */
8808   S (mp);
8809
8810   /* Wait for a reply... */
8811   W (ret);
8812   return ret;
8813 }
8814
8815 static int
8816 api_sr_mpls_policy_add (vat_main_t * vam)
8817 {
8818   unformat_input_t *i = vam->input;
8819   vl_api_sr_mpls_policy_add_t *mp;
8820   u32 bsid = 0;
8821   u32 weight = 1;
8822   u8 type = 0;
8823   u8 n_segments = 0;
8824   u32 sid;
8825   u32 *segments = NULL;
8826   int ret;
8827
8828   /* Parse args required to build the message */
8829   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8830     {
8831       if (unformat (i, "bsid %d", &bsid))
8832         ;
8833       else if (unformat (i, "weight %d", &weight))
8834         ;
8835       else if (unformat (i, "spray"))
8836         type = 1;
8837       else if (unformat (i, "next %d", &sid))
8838         {
8839           n_segments += 1;
8840           vec_add1 (segments, htonl (sid));
8841         }
8842       else
8843         {
8844           clib_warning ("parse error '%U'", format_unformat_error, i);
8845           return -99;
8846         }
8847     }
8848
8849   if (bsid == 0)
8850     {
8851       errmsg ("bsid not set");
8852       return -99;
8853     }
8854
8855   if (n_segments == 0)
8856     {
8857       errmsg ("no sid in segment stack");
8858       return -99;
8859     }
8860
8861   /* Construct the API message */
8862   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8863
8864   mp->bsid = htonl (bsid);
8865   mp->weight = htonl (weight);
8866   mp->type = type;
8867   mp->n_segments = n_segments;
8868   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8869   vec_free (segments);
8870
8871   /* send it... */
8872   S (mp);
8873
8874   /* Wait for a reply... */
8875   W (ret);
8876   return ret;
8877 }
8878
8879 static int
8880 api_sr_mpls_policy_del (vat_main_t * vam)
8881 {
8882   unformat_input_t *i = vam->input;
8883   vl_api_sr_mpls_policy_del_t *mp;
8884   u32 bsid = 0;
8885   int ret;
8886
8887   /* Parse args required to build the message */
8888   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8889     {
8890       if (unformat (i, "bsid %d", &bsid))
8891         ;
8892       else
8893         {
8894           clib_warning ("parse error '%U'", format_unformat_error, i);
8895           return -99;
8896         }
8897     }
8898
8899   if (bsid == 0)
8900     {
8901       errmsg ("bsid not set");
8902       return -99;
8903     }
8904
8905   /* Construct the API message */
8906   M (SR_MPLS_POLICY_DEL, mp);
8907
8908   mp->bsid = htonl (bsid);
8909
8910   /* send it... */
8911   S (mp);
8912
8913   /* Wait for a reply... */
8914   W (ret);
8915   return ret;
8916 }
8917
8918 static int
8919 api_bier_table_add_del (vat_main_t * vam)
8920 {
8921   unformat_input_t *i = vam->input;
8922   vl_api_bier_table_add_del_t *mp;
8923   u8 is_add = 1;
8924   u32 set = 0, sub_domain = 0, hdr_len = 3;
8925   mpls_label_t local_label = MPLS_LABEL_INVALID;
8926   int ret;
8927
8928   /* Parse args required to build the message */
8929   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8930     {
8931       if (unformat (i, "sub-domain %d", &sub_domain))
8932         ;
8933       else if (unformat (i, "set %d", &set))
8934         ;
8935       else if (unformat (i, "label %d", &local_label))
8936         ;
8937       else if (unformat (i, "hdr-len %d", &hdr_len))
8938         ;
8939       else if (unformat (i, "add"))
8940         is_add = 1;
8941       else if (unformat (i, "del"))
8942         is_add = 0;
8943       else
8944         {
8945           clib_warning ("parse error '%U'", format_unformat_error, i);
8946           return -99;
8947         }
8948     }
8949
8950   if (MPLS_LABEL_INVALID == local_label)
8951     {
8952       errmsg ("missing label\n");
8953       return -99;
8954     }
8955
8956   /* Construct the API message */
8957   M (BIER_TABLE_ADD_DEL, mp);
8958
8959   mp->bt_is_add = is_add;
8960   mp->bt_label = ntohl (local_label);
8961   mp->bt_tbl_id.bt_set = set;
8962   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8963   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8964
8965   /* send it... */
8966   S (mp);
8967
8968   /* Wait for a reply... */
8969   W (ret);
8970
8971   return (ret);
8972 }
8973
8974 static int
8975 api_bier_route_add_del (vat_main_t * vam)
8976 {
8977   unformat_input_t *i = vam->input;
8978   vl_api_bier_route_add_del_t *mp;
8979   u8 is_add = 1;
8980   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8981   ip4_address_t v4_next_hop_address;
8982   ip6_address_t v6_next_hop_address;
8983   u8 next_hop_set = 0;
8984   u8 next_hop_proto_is_ip4 = 1;
8985   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8986   int ret;
8987
8988   /* Parse args required to build the message */
8989   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8990     {
8991       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8992         {
8993           next_hop_proto_is_ip4 = 1;
8994           next_hop_set = 1;
8995         }
8996       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8997         {
8998           next_hop_proto_is_ip4 = 0;
8999           next_hop_set = 1;
9000         }
9001       if (unformat (i, "sub-domain %d", &sub_domain))
9002         ;
9003       else if (unformat (i, "set %d", &set))
9004         ;
9005       else if (unformat (i, "hdr-len %d", &hdr_len))
9006         ;
9007       else if (unformat (i, "bp %d", &bp))
9008         ;
9009       else if (unformat (i, "add"))
9010         is_add = 1;
9011       else if (unformat (i, "del"))
9012         is_add = 0;
9013       else if (unformat (i, "out-label %d", &next_hop_out_label))
9014         ;
9015       else
9016         {
9017           clib_warning ("parse error '%U'", format_unformat_error, i);
9018           return -99;
9019         }
9020     }
9021
9022   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
9023     {
9024       errmsg ("next hop / label set\n");
9025       return -99;
9026     }
9027   if (0 == bp)
9028     {
9029       errmsg ("bit=position not set\n");
9030       return -99;
9031     }
9032
9033   /* Construct the API message */
9034   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
9035
9036   mp->br_is_add = is_add;
9037   mp->br_tbl_id.bt_set = set;
9038   mp->br_tbl_id.bt_sub_domain = sub_domain;
9039   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
9040   mp->br_bp = ntohs (bp);
9041   mp->br_n_paths = 1;
9042   mp->br_paths[0].n_labels = 1;
9043   mp->br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
9044   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
9045
9046   if (next_hop_proto_is_ip4)
9047     {
9048       clib_memcpy (mp->br_paths[0].next_hop,
9049                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9050     }
9051   else
9052     {
9053       clib_memcpy (mp->br_paths[0].next_hop,
9054                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9055     }
9056
9057   /* send it... */
9058   S (mp);
9059
9060   /* Wait for a reply... */
9061   W (ret);
9062
9063   return (ret);
9064 }
9065
9066 static int
9067 api_proxy_arp_add_del (vat_main_t * vam)
9068 {
9069   unformat_input_t *i = vam->input;
9070   vl_api_proxy_arp_add_del_t *mp;
9071   u32 vrf_id = 0;
9072   u8 is_add = 1;
9073   vl_api_ip4_address_t lo, hi;
9074   u8 range_set = 0;
9075   int ret;
9076
9077   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9078     {
9079       if (unformat (i, "vrf %d", &vrf_id))
9080         ;
9081       else if (unformat (i, "%U - %U", unformat_vl_api_ip4_address, &lo,
9082                          unformat_vl_api_ip4_address, &hi))
9083         range_set = 1;
9084       else if (unformat (i, "del"))
9085         is_add = 0;
9086       else
9087         {
9088           clib_warning ("parse error '%U'", format_unformat_error, i);
9089           return -99;
9090         }
9091     }
9092
9093   if (range_set == 0)
9094     {
9095       errmsg ("address range not set");
9096       return -99;
9097     }
9098
9099   M (PROXY_ARP_ADD_DEL, mp);
9100
9101   mp->proxy.table_id = ntohl (vrf_id);
9102   mp->is_add = is_add;
9103   clib_memcpy (mp->proxy.low, &lo, sizeof (lo));
9104   clib_memcpy (mp->proxy.hi, &hi, sizeof (hi));
9105
9106   S (mp);
9107   W (ret);
9108   return ret;
9109 }
9110
9111 static int
9112 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
9113 {
9114   unformat_input_t *i = vam->input;
9115   vl_api_proxy_arp_intfc_enable_disable_t *mp;
9116   u32 sw_if_index;
9117   u8 enable = 1;
9118   u8 sw_if_index_set = 0;
9119   int ret;
9120
9121   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9122     {
9123       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9124         sw_if_index_set = 1;
9125       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9126         sw_if_index_set = 1;
9127       else if (unformat (i, "enable"))
9128         enable = 1;
9129       else if (unformat (i, "disable"))
9130         enable = 0;
9131       else
9132         {
9133           clib_warning ("parse error '%U'", format_unformat_error, i);
9134           return -99;
9135         }
9136     }
9137
9138   if (sw_if_index_set == 0)
9139     {
9140       errmsg ("missing interface name or sw_if_index");
9141       return -99;
9142     }
9143
9144   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9145
9146   mp->sw_if_index = ntohl (sw_if_index);
9147   mp->enable_disable = enable;
9148
9149   S (mp);
9150   W (ret);
9151   return ret;
9152 }
9153
9154 static int
9155 api_mpls_tunnel_add_del (vat_main_t * vam)
9156 {
9157   unformat_input_t *i = vam->input;
9158   vl_api_mpls_tunnel_add_del_t *mp;
9159
9160   u8 is_add = 1;
9161   u8 l2_only = 0;
9162   u32 sw_if_index = ~0;
9163   u32 next_hop_sw_if_index = ~0;
9164   u32 next_hop_proto_is_ip4 = 1;
9165
9166   u32 next_hop_table_id = 0;
9167   ip4_address_t v4_next_hop_address = {
9168     .as_u32 = 0,
9169   };
9170   ip6_address_t v6_next_hop_address = { {0} };
9171   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
9172   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
9173   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9174   int ret;
9175
9176   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9177     {
9178       if (unformat (i, "add"))
9179         is_add = 1;
9180       else
9181         if (unformat
9182             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
9183         is_add = 0;
9184       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9185         is_add = 0;
9186       else if (unformat (i, "via %U",
9187                          unformat_ip4_address, &v4_next_hop_address))
9188         {
9189           next_hop_proto_is_ip4 = 1;
9190         }
9191       else if (unformat (i, "via %U",
9192                          unformat_ip6_address, &v6_next_hop_address))
9193         {
9194           next_hop_proto_is_ip4 = 0;
9195         }
9196       else if (unformat (i, "via-label %d", &next_hop_via_label))
9197         ;
9198       else
9199         if (unformat
9200             (i, "%U", api_unformat_sw_if_index, vam, &next_hop_sw_if_index))
9201         ;
9202       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9203         ;
9204       else if (unformat (i, "l2-only"))
9205         l2_only = 1;
9206       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9207         ;
9208       else if (unformat (i, "out-label %d", &next_hop_out_label))
9209         {
9210           vl_api_fib_mpls_label_t fib_label = {
9211             .label = ntohl (next_hop_out_label),
9212             .ttl = 64,
9213             .exp = 0,
9214           };
9215           vec_add1 (next_hop_out_label_stack, fib_label);
9216         }
9217       else
9218         {
9219           clib_warning ("parse error '%U'", format_unformat_error, i);
9220           return -99;
9221         }
9222     }
9223
9224   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
9225       vec_len (next_hop_out_label_stack));
9226
9227   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9228   mp->mt_sw_if_index = ntohl (sw_if_index);
9229   mp->mt_is_add = is_add;
9230   mp->mt_l2_only = l2_only;
9231   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9232   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9233   mp->mt_next_hop_via_label = ntohl (next_hop_via_label);
9234   mp->mt_next_hop_weight = 1;
9235   mp->mt_next_hop_preference = 0;
9236
9237   mp->mt_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
9238
9239   if (0 != mp->mt_next_hop_n_out_labels)
9240     {
9241       clib_memcpy (mp->mt_next_hop_out_label_stack,
9242                    next_hop_out_label_stack,
9243                    (vec_len (next_hop_out_label_stack) *
9244                     sizeof (vl_api_fib_mpls_label_t)));
9245       vec_free (next_hop_out_label_stack);
9246     }
9247
9248   if (next_hop_proto_is_ip4)
9249     {
9250       clib_memcpy (mp->mt_next_hop,
9251                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9252     }
9253   else
9254     {
9255       clib_memcpy (mp->mt_next_hop,
9256                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9257     }
9258
9259   S (mp);
9260   W (ret);
9261   return ret;
9262 }
9263
9264 static int
9265 api_sw_interface_set_unnumbered (vat_main_t * vam)
9266 {
9267   unformat_input_t *i = vam->input;
9268   vl_api_sw_interface_set_unnumbered_t *mp;
9269   u32 sw_if_index;
9270   u32 unnum_sw_index = ~0;
9271   u8 is_add = 1;
9272   u8 sw_if_index_set = 0;
9273   int ret;
9274
9275   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9276     {
9277       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9278         sw_if_index_set = 1;
9279       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9280         sw_if_index_set = 1;
9281       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9282         ;
9283       else if (unformat (i, "del"))
9284         is_add = 0;
9285       else
9286         {
9287           clib_warning ("parse error '%U'", format_unformat_error, i);
9288           return -99;
9289         }
9290     }
9291
9292   if (sw_if_index_set == 0)
9293     {
9294       errmsg ("missing interface name or sw_if_index");
9295       return -99;
9296     }
9297
9298   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9299
9300   mp->sw_if_index = ntohl (sw_if_index);
9301   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9302   mp->is_add = is_add;
9303
9304   S (mp);
9305   W (ret);
9306   return ret;
9307 }
9308
9309 static int
9310 api_ip_neighbor_add_del (vat_main_t * vam)
9311 {
9312   vl_api_mac_address_t mac_address;
9313   unformat_input_t *i = vam->input;
9314   vl_api_ip_neighbor_add_del_t *mp;
9315   vl_api_address_t ip_address;
9316   u32 sw_if_index;
9317   u8 sw_if_index_set = 0;
9318   u8 is_add = 1;
9319   u8 mac_set = 0;
9320   u8 address_set = 0;
9321   int ret;
9322   ip_neighbor_flags_t flags;
9323
9324   flags = IP_NEIGHBOR_FLAG_NONE;
9325   clib_memset (&ip_address, 0, sizeof (ip_address));
9326   clib_memset (&mac_address, 0, sizeof (mac_address));
9327   /* Parse args required to build the message */
9328   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9329     {
9330       if (unformat (i, "mac %U", unformat_vl_api_mac_address, &mac_address))
9331         {
9332           mac_set = 1;
9333         }
9334       else if (unformat (i, "del"))
9335         is_add = 0;
9336       else
9337         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9338         sw_if_index_set = 1;
9339       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9340         sw_if_index_set = 1;
9341       else if (unformat (i, "static"))
9342         flags |= IP_NEIGHBOR_FLAG_STATIC;
9343       else if (unformat (i, "no-fib-entry"))
9344         flags |= IP_NEIGHBOR_FLAG_NO_FIB_ENTRY;
9345       else if (unformat (i, "dst %U", unformat_vl_api_address, &ip_address))
9346         address_set = 1;
9347       else
9348         {
9349           clib_warning ("parse error '%U'", format_unformat_error, i);
9350           return -99;
9351         }
9352     }
9353
9354   if (sw_if_index_set == 0)
9355     {
9356       errmsg ("missing interface name or sw_if_index");
9357       return -99;
9358     }
9359   if (!address_set)
9360     {
9361       errmsg ("no address set");
9362       return -99;
9363     }
9364
9365   /* Construct the API message */
9366   M (IP_NEIGHBOR_ADD_DEL, mp);
9367
9368   mp->neighbor.sw_if_index = ntohl (sw_if_index);
9369   mp->is_add = is_add;
9370   mp->neighbor.flags = htonl (flags);
9371   if (mac_set)
9372     clib_memcpy (&mp->neighbor.mac_address, &mac_address,
9373                  sizeof (mac_address));
9374   if (address_set)
9375     clib_memcpy (&mp->neighbor.ip_address, &ip_address, sizeof (ip_address));
9376
9377   /* send it... */
9378   S (mp);
9379
9380   /* Wait for a reply, return good/bad news  */
9381   W (ret);
9382   return ret;
9383 }
9384
9385 static int
9386 api_create_vlan_subif (vat_main_t * vam)
9387 {
9388   unformat_input_t *i = vam->input;
9389   vl_api_create_vlan_subif_t *mp;
9390   u32 sw_if_index;
9391   u8 sw_if_index_set = 0;
9392   u32 vlan_id;
9393   u8 vlan_id_set = 0;
9394   int ret;
9395
9396   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9397     {
9398       if (unformat (i, "sw_if_index %d", &sw_if_index))
9399         sw_if_index_set = 1;
9400       else
9401         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9402         sw_if_index_set = 1;
9403       else if (unformat (i, "vlan %d", &vlan_id))
9404         vlan_id_set = 1;
9405       else
9406         {
9407           clib_warning ("parse error '%U'", format_unformat_error, i);
9408           return -99;
9409         }
9410     }
9411
9412   if (sw_if_index_set == 0)
9413     {
9414       errmsg ("missing interface name or sw_if_index");
9415       return -99;
9416     }
9417
9418   if (vlan_id_set == 0)
9419     {
9420       errmsg ("missing vlan_id");
9421       return -99;
9422     }
9423   M (CREATE_VLAN_SUBIF, mp);
9424
9425   mp->sw_if_index = ntohl (sw_if_index);
9426   mp->vlan_id = ntohl (vlan_id);
9427
9428   S (mp);
9429   W (ret);
9430   return ret;
9431 }
9432
9433 #define foreach_create_subif_bit                \
9434 _(no_tags)                                      \
9435 _(one_tag)                                      \
9436 _(two_tags)                                     \
9437 _(dot1ad)                                       \
9438 _(exact_match)                                  \
9439 _(default_sub)                                  \
9440 _(outer_vlan_id_any)                            \
9441 _(inner_vlan_id_any)
9442
9443 static int
9444 api_create_subif (vat_main_t * vam)
9445 {
9446   unformat_input_t *i = vam->input;
9447   vl_api_create_subif_t *mp;
9448   u32 sw_if_index;
9449   u8 sw_if_index_set = 0;
9450   u32 sub_id;
9451   u8 sub_id_set = 0;
9452   u32 no_tags = 0;
9453   u32 one_tag = 0;
9454   u32 two_tags = 0;
9455   u32 dot1ad = 0;
9456   u32 exact_match = 0;
9457   u32 default_sub = 0;
9458   u32 outer_vlan_id_any = 0;
9459   u32 inner_vlan_id_any = 0;
9460   u32 tmp;
9461   u16 outer_vlan_id = 0;
9462   u16 inner_vlan_id = 0;
9463   int ret;
9464
9465   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9466     {
9467       if (unformat (i, "sw_if_index %d", &sw_if_index))
9468         sw_if_index_set = 1;
9469       else
9470         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9471         sw_if_index_set = 1;
9472       else if (unformat (i, "sub_id %d", &sub_id))
9473         sub_id_set = 1;
9474       else if (unformat (i, "outer_vlan_id %d", &tmp))
9475         outer_vlan_id = tmp;
9476       else if (unformat (i, "inner_vlan_id %d", &tmp))
9477         inner_vlan_id = tmp;
9478
9479 #define _(a) else if (unformat (i, #a)) a = 1 ;
9480       foreach_create_subif_bit
9481 #undef _
9482         else
9483         {
9484           clib_warning ("parse error '%U'", format_unformat_error, i);
9485           return -99;
9486         }
9487     }
9488
9489   if (sw_if_index_set == 0)
9490     {
9491       errmsg ("missing interface name or sw_if_index");
9492       return -99;
9493     }
9494
9495   if (sub_id_set == 0)
9496     {
9497       errmsg ("missing sub_id");
9498       return -99;
9499     }
9500   M (CREATE_SUBIF, mp);
9501
9502   mp->sw_if_index = ntohl (sw_if_index);
9503   mp->sub_id = ntohl (sub_id);
9504
9505 #define _(a) mp->a = a;
9506   foreach_create_subif_bit;
9507 #undef _
9508
9509   mp->outer_vlan_id = ntohs (outer_vlan_id);
9510   mp->inner_vlan_id = ntohs (inner_vlan_id);
9511
9512   S (mp);
9513   W (ret);
9514   return ret;
9515 }
9516
9517 static int
9518 api_reset_fib (vat_main_t * vam)
9519 {
9520   unformat_input_t *i = vam->input;
9521   vl_api_reset_fib_t *mp;
9522   u32 vrf_id = 0;
9523   u8 is_ipv6 = 0;
9524   u8 vrf_id_set = 0;
9525
9526   int ret;
9527   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9528     {
9529       if (unformat (i, "vrf %d", &vrf_id))
9530         vrf_id_set = 1;
9531       else if (unformat (i, "ipv6"))
9532         is_ipv6 = 1;
9533       else
9534         {
9535           clib_warning ("parse error '%U'", format_unformat_error, i);
9536           return -99;
9537         }
9538     }
9539
9540   if (vrf_id_set == 0)
9541     {
9542       errmsg ("missing vrf id");
9543       return -99;
9544     }
9545
9546   M (RESET_FIB, mp);
9547
9548   mp->vrf_id = ntohl (vrf_id);
9549   mp->is_ipv6 = is_ipv6;
9550
9551   S (mp);
9552   W (ret);
9553   return ret;
9554 }
9555
9556 static int
9557 api_dhcp_proxy_config (vat_main_t * vam)
9558 {
9559   unformat_input_t *i = vam->input;
9560   vl_api_dhcp_proxy_config_t *mp;
9561   u32 rx_vrf_id = 0;
9562   u32 server_vrf_id = 0;
9563   u8 is_add = 1;
9564   u8 v4_address_set = 0;
9565   u8 v6_address_set = 0;
9566   ip4_address_t v4address;
9567   ip6_address_t v6address;
9568   u8 v4_src_address_set = 0;
9569   u8 v6_src_address_set = 0;
9570   ip4_address_t v4srcaddress;
9571   ip6_address_t v6srcaddress;
9572   int ret;
9573
9574   /* Parse args required to build the message */
9575   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9576     {
9577       if (unformat (i, "del"))
9578         is_add = 0;
9579       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9580         ;
9581       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9582         ;
9583       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9584         v4_address_set = 1;
9585       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9586         v6_address_set = 1;
9587       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9588         v4_src_address_set = 1;
9589       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9590         v6_src_address_set = 1;
9591       else
9592         break;
9593     }
9594
9595   if (v4_address_set && v6_address_set)
9596     {
9597       errmsg ("both v4 and v6 server addresses set");
9598       return -99;
9599     }
9600   if (!v4_address_set && !v6_address_set)
9601     {
9602       errmsg ("no server addresses set");
9603       return -99;
9604     }
9605
9606   if (v4_src_address_set && v6_src_address_set)
9607     {
9608       errmsg ("both v4 and v6  src addresses set");
9609       return -99;
9610     }
9611   if (!v4_src_address_set && !v6_src_address_set)
9612     {
9613       errmsg ("no src addresses set");
9614       return -99;
9615     }
9616
9617   if (!(v4_src_address_set && v4_address_set) &&
9618       !(v6_src_address_set && v6_address_set))
9619     {
9620       errmsg ("no matching server and src addresses set");
9621       return -99;
9622     }
9623
9624   /* Construct the API message */
9625   M (DHCP_PROXY_CONFIG, mp);
9626
9627   mp->is_add = is_add;
9628   mp->rx_vrf_id = ntohl (rx_vrf_id);
9629   mp->server_vrf_id = ntohl (server_vrf_id);
9630   if (v6_address_set)
9631     {
9632       mp->is_ipv6 = 1;
9633       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9634       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9635     }
9636   else
9637     {
9638       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9639       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9640     }
9641
9642   /* send it... */
9643   S (mp);
9644
9645   /* Wait for a reply, return good/bad news  */
9646   W (ret);
9647   return ret;
9648 }
9649
9650 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9651 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9652
9653 static void
9654 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9655 {
9656   vat_main_t *vam = &vat_main;
9657   u32 i, count = mp->count;
9658   vl_api_dhcp_server_t *s;
9659
9660   if (mp->is_ipv6)
9661     print (vam->ofp,
9662            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9663            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9664            ntohl (mp->rx_vrf_id),
9665            format_ip6_address, mp->dhcp_src_address,
9666            mp->vss_type, mp->vss_vpn_ascii_id,
9667            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9668   else
9669     print (vam->ofp,
9670            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9671            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9672            ntohl (mp->rx_vrf_id),
9673            format_ip4_address, mp->dhcp_src_address,
9674            mp->vss_type, mp->vss_vpn_ascii_id,
9675            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9676
9677   for (i = 0; i < count; i++)
9678     {
9679       s = &mp->servers[i];
9680
9681       if (mp->is_ipv6)
9682         print (vam->ofp,
9683                " Server Table-ID %d, Server Address %U",
9684                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9685       else
9686         print (vam->ofp,
9687                " Server Table-ID %d, Server Address %U",
9688                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9689     }
9690 }
9691
9692 static void vl_api_dhcp_proxy_details_t_handler_json
9693   (vl_api_dhcp_proxy_details_t * mp)
9694 {
9695   vat_main_t *vam = &vat_main;
9696   vat_json_node_t *node = NULL;
9697   u32 i, count = mp->count;
9698   struct in_addr ip4;
9699   struct in6_addr ip6;
9700   vl_api_dhcp_server_t *s;
9701
9702   if (VAT_JSON_ARRAY != vam->json_tree.type)
9703     {
9704       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9705       vat_json_init_array (&vam->json_tree);
9706     }
9707   node = vat_json_array_add (&vam->json_tree);
9708
9709   vat_json_init_object (node);
9710   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9711   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9712                              sizeof (mp->vss_type));
9713   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9714                                    mp->vss_vpn_ascii_id);
9715   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9716   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9717
9718   if (mp->is_ipv6)
9719     {
9720       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9721       vat_json_object_add_ip6 (node, "src_address", ip6);
9722     }
9723   else
9724     {
9725       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9726       vat_json_object_add_ip4 (node, "src_address", ip4);
9727     }
9728
9729   for (i = 0; i < count; i++)
9730     {
9731       s = &mp->servers[i];
9732
9733       vat_json_object_add_uint (node, "server-table-id",
9734                                 ntohl (s->server_vrf_id));
9735
9736       if (mp->is_ipv6)
9737         {
9738           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9739           vat_json_object_add_ip4 (node, "src_address", ip4);
9740         }
9741       else
9742         {
9743           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9744           vat_json_object_add_ip6 (node, "server_address", ip6);
9745         }
9746     }
9747 }
9748
9749 static int
9750 api_dhcp_proxy_dump (vat_main_t * vam)
9751 {
9752   unformat_input_t *i = vam->input;
9753   vl_api_control_ping_t *mp_ping;
9754   vl_api_dhcp_proxy_dump_t *mp;
9755   u8 is_ipv6 = 0;
9756   int ret;
9757
9758   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9759     {
9760       if (unformat (i, "ipv6"))
9761         is_ipv6 = 1;
9762       else
9763         {
9764           clib_warning ("parse error '%U'", format_unformat_error, i);
9765           return -99;
9766         }
9767     }
9768
9769   M (DHCP_PROXY_DUMP, mp);
9770
9771   mp->is_ip6 = is_ipv6;
9772   S (mp);
9773
9774   /* Use a control ping for synchronization */
9775   MPING (CONTROL_PING, mp_ping);
9776   S (mp_ping);
9777
9778   W (ret);
9779   return ret;
9780 }
9781
9782 static int
9783 api_dhcp_proxy_set_vss (vat_main_t * vam)
9784 {
9785   unformat_input_t *i = vam->input;
9786   vl_api_dhcp_proxy_set_vss_t *mp;
9787   u8 is_ipv6 = 0;
9788   u8 is_add = 1;
9789   u32 tbl_id = ~0;
9790   u8 vss_type = VSS_TYPE_DEFAULT;
9791   u8 *vpn_ascii_id = 0;
9792   u32 oui = 0;
9793   u32 fib_id = 0;
9794   int ret;
9795
9796   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9797     {
9798       if (unformat (i, "tbl_id %d", &tbl_id))
9799         ;
9800       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
9801         vss_type = VSS_TYPE_ASCII;
9802       else if (unformat (i, "fib_id %d", &fib_id))
9803         vss_type = VSS_TYPE_VPN_ID;
9804       else if (unformat (i, "oui %d", &oui))
9805         vss_type = VSS_TYPE_VPN_ID;
9806       else if (unformat (i, "ipv6"))
9807         is_ipv6 = 1;
9808       else if (unformat (i, "del"))
9809         is_add = 0;
9810       else
9811         break;
9812     }
9813
9814   if (tbl_id == ~0)
9815     {
9816       errmsg ("missing tbl_id ");
9817       vec_free (vpn_ascii_id);
9818       return -99;
9819     }
9820
9821   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
9822     {
9823       errmsg ("vpn_ascii_id cannot be longer than 128 ");
9824       vec_free (vpn_ascii_id);
9825       return -99;
9826     }
9827
9828   M (DHCP_PROXY_SET_VSS, mp);
9829   mp->tbl_id = ntohl (tbl_id);
9830   mp->vss_type = vss_type;
9831   if (vpn_ascii_id)
9832     {
9833       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
9834       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
9835     }
9836   mp->vpn_index = ntohl (fib_id);
9837   mp->oui = ntohl (oui);
9838   mp->is_ipv6 = is_ipv6;
9839   mp->is_add = is_add;
9840
9841   S (mp);
9842   W (ret);
9843
9844   vec_free (vpn_ascii_id);
9845   return ret;
9846 }
9847
9848 static int
9849 api_dhcp_client_config (vat_main_t * vam)
9850 {
9851   unformat_input_t *i = vam->input;
9852   vl_api_dhcp_client_config_t *mp;
9853   u32 sw_if_index;
9854   u8 sw_if_index_set = 0;
9855   u8 is_add = 1;
9856   u8 *hostname = 0;
9857   u8 disable_event = 0;
9858   int ret;
9859
9860   /* Parse args required to build the message */
9861   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9862     {
9863       if (unformat (i, "del"))
9864         is_add = 0;
9865       else
9866         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9867         sw_if_index_set = 1;
9868       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9869         sw_if_index_set = 1;
9870       else if (unformat (i, "hostname %s", &hostname))
9871         ;
9872       else if (unformat (i, "disable_event"))
9873         disable_event = 1;
9874       else
9875         break;
9876     }
9877
9878   if (sw_if_index_set == 0)
9879     {
9880       errmsg ("missing interface name or sw_if_index");
9881       return -99;
9882     }
9883
9884   if (vec_len (hostname) > 63)
9885     {
9886       errmsg ("hostname too long");
9887     }
9888   vec_add1 (hostname, 0);
9889
9890   /* Construct the API message */
9891   M (DHCP_CLIENT_CONFIG, mp);
9892
9893   mp->is_add = is_add;
9894   mp->client.sw_if_index = htonl (sw_if_index);
9895   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
9896   vec_free (hostname);
9897   mp->client.want_dhcp_event = disable_event ? 0 : 1;
9898   mp->client.pid = htonl (getpid ());
9899
9900   /* send it... */
9901   S (mp);
9902
9903   /* Wait for a reply, return good/bad news  */
9904   W (ret);
9905   return ret;
9906 }
9907
9908 static int
9909 api_set_ip_flow_hash (vat_main_t * vam)
9910 {
9911   unformat_input_t *i = vam->input;
9912   vl_api_set_ip_flow_hash_t *mp;
9913   u32 vrf_id = 0;
9914   u8 is_ipv6 = 0;
9915   u8 vrf_id_set = 0;
9916   u8 src = 0;
9917   u8 dst = 0;
9918   u8 sport = 0;
9919   u8 dport = 0;
9920   u8 proto = 0;
9921   u8 reverse = 0;
9922   int ret;
9923
9924   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9925     {
9926       if (unformat (i, "vrf %d", &vrf_id))
9927         vrf_id_set = 1;
9928       else if (unformat (i, "ipv6"))
9929         is_ipv6 = 1;
9930       else if (unformat (i, "src"))
9931         src = 1;
9932       else if (unformat (i, "dst"))
9933         dst = 1;
9934       else if (unformat (i, "sport"))
9935         sport = 1;
9936       else if (unformat (i, "dport"))
9937         dport = 1;
9938       else if (unformat (i, "proto"))
9939         proto = 1;
9940       else if (unformat (i, "reverse"))
9941         reverse = 1;
9942
9943       else
9944         {
9945           clib_warning ("parse error '%U'", format_unformat_error, i);
9946           return -99;
9947         }
9948     }
9949
9950   if (vrf_id_set == 0)
9951     {
9952       errmsg ("missing vrf id");
9953       return -99;
9954     }
9955
9956   M (SET_IP_FLOW_HASH, mp);
9957   mp->src = src;
9958   mp->dst = dst;
9959   mp->sport = sport;
9960   mp->dport = dport;
9961   mp->proto = proto;
9962   mp->reverse = reverse;
9963   mp->vrf_id = ntohl (vrf_id);
9964   mp->is_ipv6 = is_ipv6;
9965
9966   S (mp);
9967   W (ret);
9968   return ret;
9969 }
9970
9971 static int
9972 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9973 {
9974   unformat_input_t *i = vam->input;
9975   vl_api_sw_interface_ip6_enable_disable_t *mp;
9976   u32 sw_if_index;
9977   u8 sw_if_index_set = 0;
9978   u8 enable = 0;
9979   int ret;
9980
9981   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9982     {
9983       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9984         sw_if_index_set = 1;
9985       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9986         sw_if_index_set = 1;
9987       else if (unformat (i, "enable"))
9988         enable = 1;
9989       else if (unformat (i, "disable"))
9990         enable = 0;
9991       else
9992         {
9993           clib_warning ("parse error '%U'", format_unformat_error, i);
9994           return -99;
9995         }
9996     }
9997
9998   if (sw_if_index_set == 0)
9999     {
10000       errmsg ("missing interface name or sw_if_index");
10001       return -99;
10002     }
10003
10004   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
10005
10006   mp->sw_if_index = ntohl (sw_if_index);
10007   mp->enable = enable;
10008
10009   S (mp);
10010   W (ret);
10011   return ret;
10012 }
10013
10014 static int
10015 api_ip6nd_proxy_add_del (vat_main_t * vam)
10016 {
10017   unformat_input_t *i = vam->input;
10018   vl_api_ip6nd_proxy_add_del_t *mp;
10019   u32 sw_if_index = ~0;
10020   u8 v6_address_set = 0;
10021   vl_api_ip6_address_t v6address;
10022   u8 is_del = 0;
10023   int ret;
10024
10025   /* Parse args required to build the message */
10026   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10027     {
10028       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10029         ;
10030       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10031         ;
10032       else if (unformat (i, "%U", unformat_vl_api_ip6_address, &v6address))
10033         v6_address_set = 1;
10034       if (unformat (i, "del"))
10035         is_del = 1;
10036       else
10037         {
10038           clib_warning ("parse error '%U'", format_unformat_error, i);
10039           return -99;
10040         }
10041     }
10042
10043   if (sw_if_index == ~0)
10044     {
10045       errmsg ("missing interface name or sw_if_index");
10046       return -99;
10047     }
10048   if (!v6_address_set)
10049     {
10050       errmsg ("no address set");
10051       return -99;
10052     }
10053
10054   /* Construct the API message */
10055   M (IP6ND_PROXY_ADD_DEL, mp);
10056
10057   mp->is_del = is_del;
10058   mp->sw_if_index = ntohl (sw_if_index);
10059   clib_memcpy (mp->ip, v6address, sizeof (v6address));
10060
10061   /* send it... */
10062   S (mp);
10063
10064   /* Wait for a reply, return good/bad news  */
10065   W (ret);
10066   return ret;
10067 }
10068
10069 static int
10070 api_ip6nd_proxy_dump (vat_main_t * vam)
10071 {
10072   vl_api_ip6nd_proxy_dump_t *mp;
10073   vl_api_control_ping_t *mp_ping;
10074   int ret;
10075
10076   M (IP6ND_PROXY_DUMP, mp);
10077
10078   S (mp);
10079
10080   /* Use a control ping for synchronization */
10081   MPING (CONTROL_PING, mp_ping);
10082   S (mp_ping);
10083
10084   W (ret);
10085   return ret;
10086 }
10087
10088 static void vl_api_ip6nd_proxy_details_t_handler
10089   (vl_api_ip6nd_proxy_details_t * mp)
10090 {
10091   vat_main_t *vam = &vat_main;
10092
10093   print (vam->ofp, "host %U sw_if_index %d",
10094          format_vl_api_ip6_address, mp->ip, ntohl (mp->sw_if_index));
10095 }
10096
10097 static void vl_api_ip6nd_proxy_details_t_handler_json
10098   (vl_api_ip6nd_proxy_details_t * mp)
10099 {
10100   vat_main_t *vam = &vat_main;
10101   struct in6_addr ip6;
10102   vat_json_node_t *node = NULL;
10103
10104   if (VAT_JSON_ARRAY != vam->json_tree.type)
10105     {
10106       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10107       vat_json_init_array (&vam->json_tree);
10108     }
10109   node = vat_json_array_add (&vam->json_tree);
10110
10111   vat_json_init_object (node);
10112   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10113
10114   clib_memcpy (&ip6, mp->ip, sizeof (ip6));
10115   vat_json_object_add_ip6 (node, "host", ip6);
10116 }
10117
10118 static int
10119 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10120 {
10121   unformat_input_t *i = vam->input;
10122   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10123   u32 sw_if_index;
10124   u8 sw_if_index_set = 0;
10125   u8 v6_address_set = 0;
10126   vl_api_prefix_t pfx;
10127   u8 use_default = 0;
10128   u8 no_advertise = 0;
10129   u8 off_link = 0;
10130   u8 no_autoconfig = 0;
10131   u8 no_onlink = 0;
10132   u8 is_no = 0;
10133   u32 val_lifetime = 0;
10134   u32 pref_lifetime = 0;
10135   int ret;
10136
10137   /* Parse args required to build the message */
10138   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10139     {
10140       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10141         sw_if_index_set = 1;
10142       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10143         sw_if_index_set = 1;
10144       else if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
10145         v6_address_set = 1;
10146       else if (unformat (i, "val_life %d", &val_lifetime))
10147         ;
10148       else if (unformat (i, "pref_life %d", &pref_lifetime))
10149         ;
10150       else if (unformat (i, "def"))
10151         use_default = 1;
10152       else if (unformat (i, "noadv"))
10153         no_advertise = 1;
10154       else if (unformat (i, "offl"))
10155         off_link = 1;
10156       else if (unformat (i, "noauto"))
10157         no_autoconfig = 1;
10158       else if (unformat (i, "nolink"))
10159         no_onlink = 1;
10160       else if (unformat (i, "isno"))
10161         is_no = 1;
10162       else
10163         {
10164           clib_warning ("parse error '%U'", format_unformat_error, i);
10165           return -99;
10166         }
10167     }
10168
10169   if (sw_if_index_set == 0)
10170     {
10171       errmsg ("missing interface name or sw_if_index");
10172       return -99;
10173     }
10174   if (!v6_address_set)
10175     {
10176       errmsg ("no address set");
10177       return -99;
10178     }
10179
10180   /* Construct the API message */
10181   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10182
10183   mp->sw_if_index = ntohl (sw_if_index);
10184   clib_memcpy (&mp->prefix, &pfx, sizeof (pfx));
10185   mp->use_default = use_default;
10186   mp->no_advertise = no_advertise;
10187   mp->off_link = off_link;
10188   mp->no_autoconfig = no_autoconfig;
10189   mp->no_onlink = no_onlink;
10190   mp->is_no = is_no;
10191   mp->val_lifetime = ntohl (val_lifetime);
10192   mp->pref_lifetime = ntohl (pref_lifetime);
10193
10194   /* send it... */
10195   S (mp);
10196
10197   /* Wait for a reply, return good/bad news  */
10198   W (ret);
10199   return ret;
10200 }
10201
10202 static int
10203 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10204 {
10205   unformat_input_t *i = vam->input;
10206   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10207   u32 sw_if_index;
10208   u8 sw_if_index_set = 0;
10209   u8 suppress = 0;
10210   u8 managed = 0;
10211   u8 other = 0;
10212   u8 ll_option = 0;
10213   u8 send_unicast = 0;
10214   u8 cease = 0;
10215   u8 is_no = 0;
10216   u8 default_router = 0;
10217   u32 max_interval = 0;
10218   u32 min_interval = 0;
10219   u32 lifetime = 0;
10220   u32 initial_count = 0;
10221   u32 initial_interval = 0;
10222   int ret;
10223
10224
10225   /* Parse args required to build the message */
10226   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10227     {
10228       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10229         sw_if_index_set = 1;
10230       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10231         sw_if_index_set = 1;
10232       else if (unformat (i, "maxint %d", &max_interval))
10233         ;
10234       else if (unformat (i, "minint %d", &min_interval))
10235         ;
10236       else if (unformat (i, "life %d", &lifetime))
10237         ;
10238       else if (unformat (i, "count %d", &initial_count))
10239         ;
10240       else if (unformat (i, "interval %d", &initial_interval))
10241         ;
10242       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10243         suppress = 1;
10244       else if (unformat (i, "managed"))
10245         managed = 1;
10246       else if (unformat (i, "other"))
10247         other = 1;
10248       else if (unformat (i, "ll"))
10249         ll_option = 1;
10250       else if (unformat (i, "send"))
10251         send_unicast = 1;
10252       else if (unformat (i, "cease"))
10253         cease = 1;
10254       else if (unformat (i, "isno"))
10255         is_no = 1;
10256       else if (unformat (i, "def"))
10257         default_router = 1;
10258       else
10259         {
10260           clib_warning ("parse error '%U'", format_unformat_error, i);
10261           return -99;
10262         }
10263     }
10264
10265   if (sw_if_index_set == 0)
10266     {
10267       errmsg ("missing interface name or sw_if_index");
10268       return -99;
10269     }
10270
10271   /* Construct the API message */
10272   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10273
10274   mp->sw_if_index = ntohl (sw_if_index);
10275   mp->max_interval = ntohl (max_interval);
10276   mp->min_interval = ntohl (min_interval);
10277   mp->lifetime = ntohl (lifetime);
10278   mp->initial_count = ntohl (initial_count);
10279   mp->initial_interval = ntohl (initial_interval);
10280   mp->suppress = suppress;
10281   mp->managed = managed;
10282   mp->other = other;
10283   mp->ll_option = ll_option;
10284   mp->send_unicast = send_unicast;
10285   mp->cease = cease;
10286   mp->is_no = is_no;
10287   mp->default_router = default_router;
10288
10289   /* send it... */
10290   S (mp);
10291
10292   /* Wait for a reply, return good/bad news  */
10293   W (ret);
10294   return ret;
10295 }
10296
10297 static int
10298 api_set_arp_neighbor_limit (vat_main_t * vam)
10299 {
10300   unformat_input_t *i = vam->input;
10301   vl_api_set_arp_neighbor_limit_t *mp;
10302   u32 arp_nbr_limit;
10303   u8 limit_set = 0;
10304   u8 is_ipv6 = 0;
10305   int ret;
10306
10307   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10308     {
10309       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10310         limit_set = 1;
10311       else if (unformat (i, "ipv6"))
10312         is_ipv6 = 1;
10313       else
10314         {
10315           clib_warning ("parse error '%U'", format_unformat_error, i);
10316           return -99;
10317         }
10318     }
10319
10320   if (limit_set == 0)
10321     {
10322       errmsg ("missing limit value");
10323       return -99;
10324     }
10325
10326   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10327
10328   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10329   mp->is_ipv6 = is_ipv6;
10330
10331   S (mp);
10332   W (ret);
10333   return ret;
10334 }
10335
10336 static int
10337 api_l2_patch_add_del (vat_main_t * vam)
10338 {
10339   unformat_input_t *i = vam->input;
10340   vl_api_l2_patch_add_del_t *mp;
10341   u32 rx_sw_if_index;
10342   u8 rx_sw_if_index_set = 0;
10343   u32 tx_sw_if_index;
10344   u8 tx_sw_if_index_set = 0;
10345   u8 is_add = 1;
10346   int ret;
10347
10348   /* Parse args required to build the message */
10349   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10350     {
10351       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10352         rx_sw_if_index_set = 1;
10353       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10354         tx_sw_if_index_set = 1;
10355       else if (unformat (i, "rx"))
10356         {
10357           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10358             {
10359               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10360                             &rx_sw_if_index))
10361                 rx_sw_if_index_set = 1;
10362             }
10363           else
10364             break;
10365         }
10366       else if (unformat (i, "tx"))
10367         {
10368           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10369             {
10370               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10371                             &tx_sw_if_index))
10372                 tx_sw_if_index_set = 1;
10373             }
10374           else
10375             break;
10376         }
10377       else if (unformat (i, "del"))
10378         is_add = 0;
10379       else
10380         break;
10381     }
10382
10383   if (rx_sw_if_index_set == 0)
10384     {
10385       errmsg ("missing rx interface name or rx_sw_if_index");
10386       return -99;
10387     }
10388
10389   if (tx_sw_if_index_set == 0)
10390     {
10391       errmsg ("missing tx interface name or tx_sw_if_index");
10392       return -99;
10393     }
10394
10395   M (L2_PATCH_ADD_DEL, mp);
10396
10397   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10398   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10399   mp->is_add = is_add;
10400
10401   S (mp);
10402   W (ret);
10403   return ret;
10404 }
10405
10406 u8 is_del;
10407 u8 localsid_addr[16];
10408 u8 end_psp;
10409 u8 behavior;
10410 u32 sw_if_index;
10411 u32 vlan_index;
10412 u32 fib_table;
10413 u8 nh_addr[16];
10414
10415 static int
10416 api_sr_localsid_add_del (vat_main_t * vam)
10417 {
10418   unformat_input_t *i = vam->input;
10419   vl_api_sr_localsid_add_del_t *mp;
10420
10421   u8 is_del;
10422   ip6_address_t localsid;
10423   u8 end_psp = 0;
10424   u8 behavior = ~0;
10425   u32 sw_if_index;
10426   u32 fib_table = ~(u32) 0;
10427   ip6_address_t nh_addr6;
10428   ip4_address_t nh_addr4;
10429   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
10430   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
10431
10432   bool nexthop_set = 0;
10433
10434   int ret;
10435
10436   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10437     {
10438       if (unformat (i, "del"))
10439         is_del = 1;
10440       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10441       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
10442         nexthop_set = 1;
10443       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
10444         nexthop_set = 1;
10445       else if (unformat (i, "behavior %u", &behavior));
10446       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10447       else if (unformat (i, "fib-table %u", &fib_table));
10448       else if (unformat (i, "end.psp %u", &behavior));
10449       else
10450         break;
10451     }
10452
10453   M (SR_LOCALSID_ADD_DEL, mp);
10454
10455   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
10456   if (nexthop_set)
10457     {
10458       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
10459       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
10460     }
10461   mp->behavior = behavior;
10462   mp->sw_if_index = ntohl (sw_if_index);
10463   mp->fib_table = ntohl (fib_table);
10464   mp->end_psp = end_psp;
10465   mp->is_del = is_del;
10466
10467   S (mp);
10468   W (ret);
10469   return ret;
10470 }
10471
10472 static int
10473 api_ioam_enable (vat_main_t * vam)
10474 {
10475   unformat_input_t *input = vam->input;
10476   vl_api_ioam_enable_t *mp;
10477   u32 id = 0;
10478   int has_trace_option = 0;
10479   int has_pot_option = 0;
10480   int has_seqno_option = 0;
10481   int has_analyse_option = 0;
10482   int ret;
10483
10484   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10485     {
10486       if (unformat (input, "trace"))
10487         has_trace_option = 1;
10488       else if (unformat (input, "pot"))
10489         has_pot_option = 1;
10490       else if (unformat (input, "seqno"))
10491         has_seqno_option = 1;
10492       else if (unformat (input, "analyse"))
10493         has_analyse_option = 1;
10494       else
10495         break;
10496     }
10497   M (IOAM_ENABLE, mp);
10498   mp->id = htons (id);
10499   mp->seqno = has_seqno_option;
10500   mp->analyse = has_analyse_option;
10501   mp->pot_enable = has_pot_option;
10502   mp->trace_enable = has_trace_option;
10503
10504   S (mp);
10505   W (ret);
10506   return ret;
10507 }
10508
10509
10510 static int
10511 api_ioam_disable (vat_main_t * vam)
10512 {
10513   vl_api_ioam_disable_t *mp;
10514   int ret;
10515
10516   M (IOAM_DISABLE, mp);
10517   S (mp);
10518   W (ret);
10519   return ret;
10520 }
10521
10522 #define foreach_tcp_proto_field                 \
10523 _(src_port)                                     \
10524 _(dst_port)
10525
10526 #define foreach_udp_proto_field                 \
10527 _(src_port)                                     \
10528 _(dst_port)
10529
10530 #define foreach_ip4_proto_field                 \
10531 _(src_address)                                  \
10532 _(dst_address)                                  \
10533 _(tos)                                          \
10534 _(length)                                       \
10535 _(fragment_id)                                  \
10536 _(ttl)                                          \
10537 _(protocol)                                     \
10538 _(checksum)
10539
10540 typedef struct
10541 {
10542   u16 src_port, dst_port;
10543 } tcpudp_header_t;
10544
10545 #if VPP_API_TEST_BUILTIN == 0
10546 uword
10547 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10548 {
10549   u8 **maskp = va_arg (*args, u8 **);
10550   u8 *mask = 0;
10551   u8 found_something = 0;
10552   tcp_header_t *tcp;
10553
10554 #define _(a) u8 a=0;
10555   foreach_tcp_proto_field;
10556 #undef _
10557
10558   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10559     {
10560       if (0);
10561 #define _(a) else if (unformat (input, #a)) a=1;
10562       foreach_tcp_proto_field
10563 #undef _
10564         else
10565         break;
10566     }
10567
10568 #define _(a) found_something += a;
10569   foreach_tcp_proto_field;
10570 #undef _
10571
10572   if (found_something == 0)
10573     return 0;
10574
10575   vec_validate (mask, sizeof (*tcp) - 1);
10576
10577   tcp = (tcp_header_t *) mask;
10578
10579 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
10580   foreach_tcp_proto_field;
10581 #undef _
10582
10583   *maskp = mask;
10584   return 1;
10585 }
10586
10587 uword
10588 unformat_udp_mask (unformat_input_t * input, va_list * args)
10589 {
10590   u8 **maskp = va_arg (*args, u8 **);
10591   u8 *mask = 0;
10592   u8 found_something = 0;
10593   udp_header_t *udp;
10594
10595 #define _(a) u8 a=0;
10596   foreach_udp_proto_field;
10597 #undef _
10598
10599   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10600     {
10601       if (0);
10602 #define _(a) else if (unformat (input, #a)) a=1;
10603       foreach_udp_proto_field
10604 #undef _
10605         else
10606         break;
10607     }
10608
10609 #define _(a) found_something += a;
10610   foreach_udp_proto_field;
10611 #undef _
10612
10613   if (found_something == 0)
10614     return 0;
10615
10616   vec_validate (mask, sizeof (*udp) - 1);
10617
10618   udp = (udp_header_t *) mask;
10619
10620 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
10621   foreach_udp_proto_field;
10622 #undef _
10623
10624   *maskp = mask;
10625   return 1;
10626 }
10627
10628 uword
10629 unformat_l4_mask (unformat_input_t * input, va_list * args)
10630 {
10631   u8 **maskp = va_arg (*args, u8 **);
10632   u16 src_port = 0, dst_port = 0;
10633   tcpudp_header_t *tcpudp;
10634
10635   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10636     {
10637       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10638         return 1;
10639       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10640         return 1;
10641       else if (unformat (input, "src_port"))
10642         src_port = 0xFFFF;
10643       else if (unformat (input, "dst_port"))
10644         dst_port = 0xFFFF;
10645       else
10646         return 0;
10647     }
10648
10649   if (!src_port && !dst_port)
10650     return 0;
10651
10652   u8 *mask = 0;
10653   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10654
10655   tcpudp = (tcpudp_header_t *) mask;
10656   tcpudp->src_port = src_port;
10657   tcpudp->dst_port = dst_port;
10658
10659   *maskp = mask;
10660
10661   return 1;
10662 }
10663
10664 uword
10665 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10666 {
10667   u8 **maskp = va_arg (*args, u8 **);
10668   u8 *mask = 0;
10669   u8 found_something = 0;
10670   ip4_header_t *ip;
10671
10672 #define _(a) u8 a=0;
10673   foreach_ip4_proto_field;
10674 #undef _
10675   u8 version = 0;
10676   u8 hdr_length = 0;
10677
10678
10679   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10680     {
10681       if (unformat (input, "version"))
10682         version = 1;
10683       else if (unformat (input, "hdr_length"))
10684         hdr_length = 1;
10685       else if (unformat (input, "src"))
10686         src_address = 1;
10687       else if (unformat (input, "dst"))
10688         dst_address = 1;
10689       else if (unformat (input, "proto"))
10690         protocol = 1;
10691
10692 #define _(a) else if (unformat (input, #a)) a=1;
10693       foreach_ip4_proto_field
10694 #undef _
10695         else
10696         break;
10697     }
10698
10699 #define _(a) found_something += a;
10700   foreach_ip4_proto_field;
10701 #undef _
10702
10703   if (found_something == 0)
10704     return 0;
10705
10706   vec_validate (mask, sizeof (*ip) - 1);
10707
10708   ip = (ip4_header_t *) mask;
10709
10710 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10711   foreach_ip4_proto_field;
10712 #undef _
10713
10714   ip->ip_version_and_header_length = 0;
10715
10716   if (version)
10717     ip->ip_version_and_header_length |= 0xF0;
10718
10719   if (hdr_length)
10720     ip->ip_version_and_header_length |= 0x0F;
10721
10722   *maskp = mask;
10723   return 1;
10724 }
10725
10726 #define foreach_ip6_proto_field                 \
10727 _(src_address)                                  \
10728 _(dst_address)                                  \
10729 _(payload_length)                               \
10730 _(hop_limit)                                    \
10731 _(protocol)
10732
10733 uword
10734 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10735 {
10736   u8 **maskp = va_arg (*args, u8 **);
10737   u8 *mask = 0;
10738   u8 found_something = 0;
10739   ip6_header_t *ip;
10740   u32 ip_version_traffic_class_and_flow_label;
10741
10742 #define _(a) u8 a=0;
10743   foreach_ip6_proto_field;
10744 #undef _
10745   u8 version = 0;
10746   u8 traffic_class = 0;
10747   u8 flow_label = 0;
10748
10749   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10750     {
10751       if (unformat (input, "version"))
10752         version = 1;
10753       else if (unformat (input, "traffic-class"))
10754         traffic_class = 1;
10755       else if (unformat (input, "flow-label"))
10756         flow_label = 1;
10757       else if (unformat (input, "src"))
10758         src_address = 1;
10759       else if (unformat (input, "dst"))
10760         dst_address = 1;
10761       else if (unformat (input, "proto"))
10762         protocol = 1;
10763
10764 #define _(a) else if (unformat (input, #a)) a=1;
10765       foreach_ip6_proto_field
10766 #undef _
10767         else
10768         break;
10769     }
10770
10771 #define _(a) found_something += a;
10772   foreach_ip6_proto_field;
10773 #undef _
10774
10775   if (found_something == 0)
10776     return 0;
10777
10778   vec_validate (mask, sizeof (*ip) - 1);
10779
10780   ip = (ip6_header_t *) mask;
10781
10782 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10783   foreach_ip6_proto_field;
10784 #undef _
10785
10786   ip_version_traffic_class_and_flow_label = 0;
10787
10788   if (version)
10789     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10790
10791   if (traffic_class)
10792     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10793
10794   if (flow_label)
10795     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10796
10797   ip->ip_version_traffic_class_and_flow_label =
10798     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10799
10800   *maskp = mask;
10801   return 1;
10802 }
10803
10804 uword
10805 unformat_l3_mask (unformat_input_t * input, va_list * args)
10806 {
10807   u8 **maskp = va_arg (*args, u8 **);
10808
10809   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10810     {
10811       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10812         return 1;
10813       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10814         return 1;
10815       else
10816         break;
10817     }
10818   return 0;
10819 }
10820
10821 uword
10822 unformat_l2_mask (unformat_input_t * input, va_list * args)
10823 {
10824   u8 **maskp = va_arg (*args, u8 **);
10825   u8 *mask = 0;
10826   u8 src = 0;
10827   u8 dst = 0;
10828   u8 proto = 0;
10829   u8 tag1 = 0;
10830   u8 tag2 = 0;
10831   u8 ignore_tag1 = 0;
10832   u8 ignore_tag2 = 0;
10833   u8 cos1 = 0;
10834   u8 cos2 = 0;
10835   u8 dot1q = 0;
10836   u8 dot1ad = 0;
10837   int len = 14;
10838
10839   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10840     {
10841       if (unformat (input, "src"))
10842         src = 1;
10843       else if (unformat (input, "dst"))
10844         dst = 1;
10845       else if (unformat (input, "proto"))
10846         proto = 1;
10847       else if (unformat (input, "tag1"))
10848         tag1 = 1;
10849       else if (unformat (input, "tag2"))
10850         tag2 = 1;
10851       else if (unformat (input, "ignore-tag1"))
10852         ignore_tag1 = 1;
10853       else if (unformat (input, "ignore-tag2"))
10854         ignore_tag2 = 1;
10855       else if (unformat (input, "cos1"))
10856         cos1 = 1;
10857       else if (unformat (input, "cos2"))
10858         cos2 = 1;
10859       else if (unformat (input, "dot1q"))
10860         dot1q = 1;
10861       else if (unformat (input, "dot1ad"))
10862         dot1ad = 1;
10863       else
10864         break;
10865     }
10866   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10867        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10868     return 0;
10869
10870   if (tag1 || ignore_tag1 || cos1 || dot1q)
10871     len = 18;
10872   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10873     len = 22;
10874
10875   vec_validate (mask, len - 1);
10876
10877   if (dst)
10878     clib_memset (mask, 0xff, 6);
10879
10880   if (src)
10881     clib_memset (mask + 6, 0xff, 6);
10882
10883   if (tag2 || dot1ad)
10884     {
10885       /* inner vlan tag */
10886       if (tag2)
10887         {
10888           mask[19] = 0xff;
10889           mask[18] = 0x0f;
10890         }
10891       if (cos2)
10892         mask[18] |= 0xe0;
10893       if (proto)
10894         mask[21] = mask[20] = 0xff;
10895       if (tag1)
10896         {
10897           mask[15] = 0xff;
10898           mask[14] = 0x0f;
10899         }
10900       if (cos1)
10901         mask[14] |= 0xe0;
10902       *maskp = mask;
10903       return 1;
10904     }
10905   if (tag1 | dot1q)
10906     {
10907       if (tag1)
10908         {
10909           mask[15] = 0xff;
10910           mask[14] = 0x0f;
10911         }
10912       if (cos1)
10913         mask[14] |= 0xe0;
10914       if (proto)
10915         mask[16] = mask[17] = 0xff;
10916
10917       *maskp = mask;
10918       return 1;
10919     }
10920   if (cos2)
10921     mask[18] |= 0xe0;
10922   if (cos1)
10923     mask[14] |= 0xe0;
10924   if (proto)
10925     mask[12] = mask[13] = 0xff;
10926
10927   *maskp = mask;
10928   return 1;
10929 }
10930
10931 uword
10932 unformat_classify_mask (unformat_input_t * input, va_list * args)
10933 {
10934   u8 **maskp = va_arg (*args, u8 **);
10935   u32 *skipp = va_arg (*args, u32 *);
10936   u32 *matchp = va_arg (*args, u32 *);
10937   u32 match;
10938   u8 *mask = 0;
10939   u8 *l2 = 0;
10940   u8 *l3 = 0;
10941   u8 *l4 = 0;
10942   int i;
10943
10944   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10945     {
10946       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10947         ;
10948       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10949         ;
10950       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10951         ;
10952       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10953         ;
10954       else
10955         break;
10956     }
10957
10958   if (l4 && !l3)
10959     {
10960       vec_free (mask);
10961       vec_free (l2);
10962       vec_free (l4);
10963       return 0;
10964     }
10965
10966   if (mask || l2 || l3 || l4)
10967     {
10968       if (l2 || l3 || l4)
10969         {
10970           /* "With a free Ethernet header in every package" */
10971           if (l2 == 0)
10972             vec_validate (l2, 13);
10973           mask = l2;
10974           if (vec_len (l3))
10975             {
10976               vec_append (mask, l3);
10977               vec_free (l3);
10978             }
10979           if (vec_len (l4))
10980             {
10981               vec_append (mask, l4);
10982               vec_free (l4);
10983             }
10984         }
10985
10986       /* Scan forward looking for the first significant mask octet */
10987       for (i = 0; i < vec_len (mask); i++)
10988         if (mask[i])
10989           break;
10990
10991       /* compute (skip, match) params */
10992       *skipp = i / sizeof (u32x4);
10993       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10994
10995       /* Pad mask to an even multiple of the vector size */
10996       while (vec_len (mask) % sizeof (u32x4))
10997         vec_add1 (mask, 0);
10998
10999       match = vec_len (mask) / sizeof (u32x4);
11000
11001       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
11002         {
11003           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
11004           if (*tmp || *(tmp + 1))
11005             break;
11006           match--;
11007         }
11008       if (match == 0)
11009         clib_warning ("BUG: match 0");
11010
11011       _vec_len (mask) = match * sizeof (u32x4);
11012
11013       *matchp = match;
11014       *maskp = mask;
11015
11016       return 1;
11017     }
11018
11019   return 0;
11020 }
11021 #endif /* VPP_API_TEST_BUILTIN */
11022
11023 #define foreach_l2_next                         \
11024 _(drop, DROP)                                   \
11025 _(ethernet, ETHERNET_INPUT)                     \
11026 _(ip4, IP4_INPUT)                               \
11027 _(ip6, IP6_INPUT)
11028
11029 uword
11030 unformat_l2_next_index (unformat_input_t * input, va_list * args)
11031 {
11032   u32 *miss_next_indexp = va_arg (*args, u32 *);
11033   u32 next_index = 0;
11034   u32 tmp;
11035
11036 #define _(n,N) \
11037   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11038   foreach_l2_next;
11039 #undef _
11040
11041   if (unformat (input, "%d", &tmp))
11042     {
11043       next_index = tmp;
11044       goto out;
11045     }
11046
11047   return 0;
11048
11049 out:
11050   *miss_next_indexp = next_index;
11051   return 1;
11052 }
11053
11054 #define foreach_ip_next                         \
11055 _(drop, DROP)                                   \
11056 _(local, LOCAL)                                 \
11057 _(rewrite, REWRITE)
11058
11059 uword
11060 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11061 {
11062   u32 *miss_next_indexp = va_arg (*args, u32 *);
11063   u32 next_index = 0;
11064   u32 tmp;
11065
11066 #define _(n,N) \
11067   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11068   foreach_ip_next;
11069 #undef _
11070
11071   if (unformat (input, "%d", &tmp))
11072     {
11073       next_index = tmp;
11074       goto out;
11075     }
11076
11077   return 0;
11078
11079 out:
11080   *miss_next_indexp = next_index;
11081   return 1;
11082 }
11083
11084 #define foreach_acl_next                        \
11085 _(deny, DENY)
11086
11087 uword
11088 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11089 {
11090   u32 *miss_next_indexp = va_arg (*args, u32 *);
11091   u32 next_index = 0;
11092   u32 tmp;
11093
11094 #define _(n,N) \
11095   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11096   foreach_acl_next;
11097 #undef _
11098
11099   if (unformat (input, "permit"))
11100     {
11101       next_index = ~0;
11102       goto out;
11103     }
11104   else if (unformat (input, "%d", &tmp))
11105     {
11106       next_index = tmp;
11107       goto out;
11108     }
11109
11110   return 0;
11111
11112 out:
11113   *miss_next_indexp = next_index;
11114   return 1;
11115 }
11116
11117 uword
11118 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11119 {
11120   u32 *r = va_arg (*args, u32 *);
11121
11122   if (unformat (input, "conform-color"))
11123     *r = POLICE_CONFORM;
11124   else if (unformat (input, "exceed-color"))
11125     *r = POLICE_EXCEED;
11126   else
11127     return 0;
11128
11129   return 1;
11130 }
11131
11132 static int
11133 api_classify_add_del_table (vat_main_t * vam)
11134 {
11135   unformat_input_t *i = vam->input;
11136   vl_api_classify_add_del_table_t *mp;
11137
11138   u32 nbuckets = 2;
11139   u32 skip = ~0;
11140   u32 match = ~0;
11141   int is_add = 1;
11142   int del_chain = 0;
11143   u32 table_index = ~0;
11144   u32 next_table_index = ~0;
11145   u32 miss_next_index = ~0;
11146   u32 memory_size = 32 << 20;
11147   u8 *mask = 0;
11148   u32 current_data_flag = 0;
11149   int current_data_offset = 0;
11150   int ret;
11151
11152   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11153     {
11154       if (unformat (i, "del"))
11155         is_add = 0;
11156       else if (unformat (i, "del-chain"))
11157         {
11158           is_add = 0;
11159           del_chain = 1;
11160         }
11161       else if (unformat (i, "buckets %d", &nbuckets))
11162         ;
11163       else if (unformat (i, "memory_size %d", &memory_size))
11164         ;
11165       else if (unformat (i, "skip %d", &skip))
11166         ;
11167       else if (unformat (i, "match %d", &match))
11168         ;
11169       else if (unformat (i, "table %d", &table_index))
11170         ;
11171       else if (unformat (i, "mask %U", unformat_classify_mask,
11172                          &mask, &skip, &match))
11173         ;
11174       else if (unformat (i, "next-table %d", &next_table_index))
11175         ;
11176       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11177                          &miss_next_index))
11178         ;
11179       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11180                          &miss_next_index))
11181         ;
11182       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11183                          &miss_next_index))
11184         ;
11185       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11186         ;
11187       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11188         ;
11189       else
11190         break;
11191     }
11192
11193   if (is_add && mask == 0)
11194     {
11195       errmsg ("Mask required");
11196       return -99;
11197     }
11198
11199   if (is_add && skip == ~0)
11200     {
11201       errmsg ("skip count required");
11202       return -99;
11203     }
11204
11205   if (is_add && match == ~0)
11206     {
11207       errmsg ("match count required");
11208       return -99;
11209     }
11210
11211   if (!is_add && table_index == ~0)
11212     {
11213       errmsg ("table index required for delete");
11214       return -99;
11215     }
11216
11217   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11218
11219   mp->is_add = is_add;
11220   mp->del_chain = del_chain;
11221   mp->table_index = ntohl (table_index);
11222   mp->nbuckets = ntohl (nbuckets);
11223   mp->memory_size = ntohl (memory_size);
11224   mp->skip_n_vectors = ntohl (skip);
11225   mp->match_n_vectors = ntohl (match);
11226   mp->next_table_index = ntohl (next_table_index);
11227   mp->miss_next_index = ntohl (miss_next_index);
11228   mp->current_data_flag = ntohl (current_data_flag);
11229   mp->current_data_offset = ntohl (current_data_offset);
11230   mp->mask_len = ntohl (vec_len (mask));
11231   clib_memcpy (mp->mask, mask, vec_len (mask));
11232
11233   vec_free (mask);
11234
11235   S (mp);
11236   W (ret);
11237   return ret;
11238 }
11239
11240 #if VPP_API_TEST_BUILTIN == 0
11241 uword
11242 unformat_l4_match (unformat_input_t * input, va_list * args)
11243 {
11244   u8 **matchp = va_arg (*args, u8 **);
11245
11246   u8 *proto_header = 0;
11247   int src_port = 0;
11248   int dst_port = 0;
11249
11250   tcpudp_header_t h;
11251
11252   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11253     {
11254       if (unformat (input, "src_port %d", &src_port))
11255         ;
11256       else if (unformat (input, "dst_port %d", &dst_port))
11257         ;
11258       else
11259         return 0;
11260     }
11261
11262   h.src_port = clib_host_to_net_u16 (src_port);
11263   h.dst_port = clib_host_to_net_u16 (dst_port);
11264   vec_validate (proto_header, sizeof (h) - 1);
11265   memcpy (proto_header, &h, sizeof (h));
11266
11267   *matchp = proto_header;
11268
11269   return 1;
11270 }
11271
11272 uword
11273 unformat_ip4_match (unformat_input_t * input, va_list * args)
11274 {
11275   u8 **matchp = va_arg (*args, u8 **);
11276   u8 *match = 0;
11277   ip4_header_t *ip;
11278   int version = 0;
11279   u32 version_val;
11280   int hdr_length = 0;
11281   u32 hdr_length_val;
11282   int src = 0, dst = 0;
11283   ip4_address_t src_val, dst_val;
11284   int proto = 0;
11285   u32 proto_val;
11286   int tos = 0;
11287   u32 tos_val;
11288   int length = 0;
11289   u32 length_val;
11290   int fragment_id = 0;
11291   u32 fragment_id_val;
11292   int ttl = 0;
11293   int ttl_val;
11294   int checksum = 0;
11295   u32 checksum_val;
11296
11297   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11298     {
11299       if (unformat (input, "version %d", &version_val))
11300         version = 1;
11301       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11302         hdr_length = 1;
11303       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11304         src = 1;
11305       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11306         dst = 1;
11307       else if (unformat (input, "proto %d", &proto_val))
11308         proto = 1;
11309       else if (unformat (input, "tos %d", &tos_val))
11310         tos = 1;
11311       else if (unformat (input, "length %d", &length_val))
11312         length = 1;
11313       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11314         fragment_id = 1;
11315       else if (unformat (input, "ttl %d", &ttl_val))
11316         ttl = 1;
11317       else if (unformat (input, "checksum %d", &checksum_val))
11318         checksum = 1;
11319       else
11320         break;
11321     }
11322
11323   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11324       + ttl + checksum == 0)
11325     return 0;
11326
11327   /*
11328    * Aligned because we use the real comparison functions
11329    */
11330   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11331
11332   ip = (ip4_header_t *) match;
11333
11334   /* These are realistically matched in practice */
11335   if (src)
11336     ip->src_address.as_u32 = src_val.as_u32;
11337
11338   if (dst)
11339     ip->dst_address.as_u32 = dst_val.as_u32;
11340
11341   if (proto)
11342     ip->protocol = proto_val;
11343
11344
11345   /* These are not, but they're included for completeness */
11346   if (version)
11347     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11348
11349   if (hdr_length)
11350     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11351
11352   if (tos)
11353     ip->tos = tos_val;
11354
11355   if (length)
11356     ip->length = clib_host_to_net_u16 (length_val);
11357
11358   if (ttl)
11359     ip->ttl = ttl_val;
11360
11361   if (checksum)
11362     ip->checksum = clib_host_to_net_u16 (checksum_val);
11363
11364   *matchp = match;
11365   return 1;
11366 }
11367
11368 uword
11369 unformat_ip6_match (unformat_input_t * input, va_list * args)
11370 {
11371   u8 **matchp = va_arg (*args, u8 **);
11372   u8 *match = 0;
11373   ip6_header_t *ip;
11374   int version = 0;
11375   u32 version_val;
11376   u8 traffic_class = 0;
11377   u32 traffic_class_val = 0;
11378   u8 flow_label = 0;
11379   u8 flow_label_val;
11380   int src = 0, dst = 0;
11381   ip6_address_t src_val, dst_val;
11382   int proto = 0;
11383   u32 proto_val;
11384   int payload_length = 0;
11385   u32 payload_length_val;
11386   int hop_limit = 0;
11387   int hop_limit_val;
11388   u32 ip_version_traffic_class_and_flow_label;
11389
11390   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11391     {
11392       if (unformat (input, "version %d", &version_val))
11393         version = 1;
11394       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11395         traffic_class = 1;
11396       else if (unformat (input, "flow_label %d", &flow_label_val))
11397         flow_label = 1;
11398       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11399         src = 1;
11400       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11401         dst = 1;
11402       else if (unformat (input, "proto %d", &proto_val))
11403         proto = 1;
11404       else if (unformat (input, "payload_length %d", &payload_length_val))
11405         payload_length = 1;
11406       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11407         hop_limit = 1;
11408       else
11409         break;
11410     }
11411
11412   if (version + traffic_class + flow_label + src + dst + proto +
11413       payload_length + hop_limit == 0)
11414     return 0;
11415
11416   /*
11417    * Aligned because we use the real comparison functions
11418    */
11419   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11420
11421   ip = (ip6_header_t *) match;
11422
11423   if (src)
11424     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11425
11426   if (dst)
11427     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11428
11429   if (proto)
11430     ip->protocol = proto_val;
11431
11432   ip_version_traffic_class_and_flow_label = 0;
11433
11434   if (version)
11435     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11436
11437   if (traffic_class)
11438     ip_version_traffic_class_and_flow_label |=
11439       (traffic_class_val & 0xFF) << 20;
11440
11441   if (flow_label)
11442     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11443
11444   ip->ip_version_traffic_class_and_flow_label =
11445     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11446
11447   if (payload_length)
11448     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11449
11450   if (hop_limit)
11451     ip->hop_limit = hop_limit_val;
11452
11453   *matchp = match;
11454   return 1;
11455 }
11456
11457 uword
11458 unformat_l3_match (unformat_input_t * input, va_list * args)
11459 {
11460   u8 **matchp = va_arg (*args, u8 **);
11461
11462   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11463     {
11464       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11465         return 1;
11466       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11467         return 1;
11468       else
11469         break;
11470     }
11471   return 0;
11472 }
11473
11474 uword
11475 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11476 {
11477   u8 *tagp = va_arg (*args, u8 *);
11478   u32 tag;
11479
11480   if (unformat (input, "%d", &tag))
11481     {
11482       tagp[0] = (tag >> 8) & 0x0F;
11483       tagp[1] = tag & 0xFF;
11484       return 1;
11485     }
11486
11487   return 0;
11488 }
11489
11490 uword
11491 unformat_l2_match (unformat_input_t * input, va_list * args)
11492 {
11493   u8 **matchp = va_arg (*args, u8 **);
11494   u8 *match = 0;
11495   u8 src = 0;
11496   u8 src_val[6];
11497   u8 dst = 0;
11498   u8 dst_val[6];
11499   u8 proto = 0;
11500   u16 proto_val;
11501   u8 tag1 = 0;
11502   u8 tag1_val[2];
11503   u8 tag2 = 0;
11504   u8 tag2_val[2];
11505   int len = 14;
11506   u8 ignore_tag1 = 0;
11507   u8 ignore_tag2 = 0;
11508   u8 cos1 = 0;
11509   u8 cos2 = 0;
11510   u32 cos1_val = 0;
11511   u32 cos2_val = 0;
11512
11513   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11514     {
11515       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11516         src = 1;
11517       else
11518         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11519         dst = 1;
11520       else if (unformat (input, "proto %U",
11521                          unformat_ethernet_type_host_byte_order, &proto_val))
11522         proto = 1;
11523       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11524         tag1 = 1;
11525       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11526         tag2 = 1;
11527       else if (unformat (input, "ignore-tag1"))
11528         ignore_tag1 = 1;
11529       else if (unformat (input, "ignore-tag2"))
11530         ignore_tag2 = 1;
11531       else if (unformat (input, "cos1 %d", &cos1_val))
11532         cos1 = 1;
11533       else if (unformat (input, "cos2 %d", &cos2_val))
11534         cos2 = 1;
11535       else
11536         break;
11537     }
11538   if ((src + dst + proto + tag1 + tag2 +
11539        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11540     return 0;
11541
11542   if (tag1 || ignore_tag1 || cos1)
11543     len = 18;
11544   if (tag2 || ignore_tag2 || cos2)
11545     len = 22;
11546
11547   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11548
11549   if (dst)
11550     clib_memcpy (match, dst_val, 6);
11551
11552   if (src)
11553     clib_memcpy (match + 6, src_val, 6);
11554
11555   if (tag2)
11556     {
11557       /* inner vlan tag */
11558       match[19] = tag2_val[1];
11559       match[18] = tag2_val[0];
11560       if (cos2)
11561         match[18] |= (cos2_val & 0x7) << 5;
11562       if (proto)
11563         {
11564           match[21] = proto_val & 0xff;
11565           match[20] = proto_val >> 8;
11566         }
11567       if (tag1)
11568         {
11569           match[15] = tag1_val[1];
11570           match[14] = tag1_val[0];
11571         }
11572       if (cos1)
11573         match[14] |= (cos1_val & 0x7) << 5;
11574       *matchp = match;
11575       return 1;
11576     }
11577   if (tag1)
11578     {
11579       match[15] = tag1_val[1];
11580       match[14] = tag1_val[0];
11581       if (proto)
11582         {
11583           match[17] = proto_val & 0xff;
11584           match[16] = proto_val >> 8;
11585         }
11586       if (cos1)
11587         match[14] |= (cos1_val & 0x7) << 5;
11588
11589       *matchp = match;
11590       return 1;
11591     }
11592   if (cos2)
11593     match[18] |= (cos2_val & 0x7) << 5;
11594   if (cos1)
11595     match[14] |= (cos1_val & 0x7) << 5;
11596   if (proto)
11597     {
11598       match[13] = proto_val & 0xff;
11599       match[12] = proto_val >> 8;
11600     }
11601
11602   *matchp = match;
11603   return 1;
11604 }
11605
11606 uword
11607 unformat_qos_source (unformat_input_t * input, va_list * args)
11608 {
11609   int *qs = va_arg (*args, int *);
11610
11611   if (unformat (input, "ip"))
11612     *qs = QOS_SOURCE_IP;
11613   else if (unformat (input, "mpls"))
11614     *qs = QOS_SOURCE_MPLS;
11615   else if (unformat (input, "ext"))
11616     *qs = QOS_SOURCE_EXT;
11617   else if (unformat (input, "vlan"))
11618     *qs = QOS_SOURCE_VLAN;
11619   else
11620     return 0;
11621
11622   return 1;
11623 }
11624 #endif
11625
11626 uword
11627 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11628 {
11629   u8 **matchp = va_arg (*args, u8 **);
11630   u32 skip_n_vectors = va_arg (*args, u32);
11631   u32 match_n_vectors = va_arg (*args, u32);
11632
11633   u8 *match = 0;
11634   u8 *l2 = 0;
11635   u8 *l3 = 0;
11636   u8 *l4 = 0;
11637
11638   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11639     {
11640       if (unformat (input, "hex %U", unformat_hex_string, &match))
11641         ;
11642       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11643         ;
11644       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11645         ;
11646       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11647         ;
11648       else
11649         break;
11650     }
11651
11652   if (l4 && !l3)
11653     {
11654       vec_free (match);
11655       vec_free (l2);
11656       vec_free (l4);
11657       return 0;
11658     }
11659
11660   if (match || l2 || l3 || l4)
11661     {
11662       if (l2 || l3 || l4)
11663         {
11664           /* "Win a free Ethernet header in every packet" */
11665           if (l2 == 0)
11666             vec_validate_aligned (l2, 13, sizeof (u32x4));
11667           match = l2;
11668           if (vec_len (l3))
11669             {
11670               vec_append_aligned (match, l3, sizeof (u32x4));
11671               vec_free (l3);
11672             }
11673           if (vec_len (l4))
11674             {
11675               vec_append_aligned (match, l4, sizeof (u32x4));
11676               vec_free (l4);
11677             }
11678         }
11679
11680       /* Make sure the vector is big enough even if key is all 0's */
11681       vec_validate_aligned
11682         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11683          sizeof (u32x4));
11684
11685       /* Set size, include skipped vectors */
11686       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11687
11688       *matchp = match;
11689
11690       return 1;
11691     }
11692
11693   return 0;
11694 }
11695
11696 static int
11697 api_classify_add_del_session (vat_main_t * vam)
11698 {
11699   unformat_input_t *i = vam->input;
11700   vl_api_classify_add_del_session_t *mp;
11701   int is_add = 1;
11702   u32 table_index = ~0;
11703   u32 hit_next_index = ~0;
11704   u32 opaque_index = ~0;
11705   u8 *match = 0;
11706   i32 advance = 0;
11707   u32 skip_n_vectors = 0;
11708   u32 match_n_vectors = 0;
11709   u32 action = 0;
11710   u32 metadata = 0;
11711   int ret;
11712
11713   /*
11714    * Warning: you have to supply skip_n and match_n
11715    * because the API client cant simply look at the classify
11716    * table object.
11717    */
11718
11719   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11720     {
11721       if (unformat (i, "del"))
11722         is_add = 0;
11723       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11724                          &hit_next_index))
11725         ;
11726       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11727                          &hit_next_index))
11728         ;
11729       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11730                          &hit_next_index))
11731         ;
11732       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11733         ;
11734       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11735         ;
11736       else if (unformat (i, "opaque-index %d", &opaque_index))
11737         ;
11738       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11739         ;
11740       else if (unformat (i, "match_n %d", &match_n_vectors))
11741         ;
11742       else if (unformat (i, "match %U", api_unformat_classify_match,
11743                          &match, skip_n_vectors, match_n_vectors))
11744         ;
11745       else if (unformat (i, "advance %d", &advance))
11746         ;
11747       else if (unformat (i, "table-index %d", &table_index))
11748         ;
11749       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11750         action = 1;
11751       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11752         action = 2;
11753       else if (unformat (i, "action %d", &action))
11754         ;
11755       else if (unformat (i, "metadata %d", &metadata))
11756         ;
11757       else
11758         break;
11759     }
11760
11761   if (table_index == ~0)
11762     {
11763       errmsg ("Table index required");
11764       return -99;
11765     }
11766
11767   if (is_add && match == 0)
11768     {
11769       errmsg ("Match value required");
11770       return -99;
11771     }
11772
11773   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11774
11775   mp->is_add = is_add;
11776   mp->table_index = ntohl (table_index);
11777   mp->hit_next_index = ntohl (hit_next_index);
11778   mp->opaque_index = ntohl (opaque_index);
11779   mp->advance = ntohl (advance);
11780   mp->action = action;
11781   mp->metadata = ntohl (metadata);
11782   mp->match_len = ntohl (vec_len (match));
11783   clib_memcpy (mp->match, match, vec_len (match));
11784   vec_free (match);
11785
11786   S (mp);
11787   W (ret);
11788   return ret;
11789 }
11790
11791 static int
11792 api_classify_set_interface_ip_table (vat_main_t * vam)
11793 {
11794   unformat_input_t *i = vam->input;
11795   vl_api_classify_set_interface_ip_table_t *mp;
11796   u32 sw_if_index;
11797   int sw_if_index_set;
11798   u32 table_index = ~0;
11799   u8 is_ipv6 = 0;
11800   int ret;
11801
11802   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11803     {
11804       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11805         sw_if_index_set = 1;
11806       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11807         sw_if_index_set = 1;
11808       else if (unformat (i, "table %d", &table_index))
11809         ;
11810       else
11811         {
11812           clib_warning ("parse error '%U'", format_unformat_error, i);
11813           return -99;
11814         }
11815     }
11816
11817   if (sw_if_index_set == 0)
11818     {
11819       errmsg ("missing interface name or sw_if_index");
11820       return -99;
11821     }
11822
11823
11824   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11825
11826   mp->sw_if_index = ntohl (sw_if_index);
11827   mp->table_index = ntohl (table_index);
11828   mp->is_ipv6 = is_ipv6;
11829
11830   S (mp);
11831   W (ret);
11832   return ret;
11833 }
11834
11835 static int
11836 api_classify_set_interface_l2_tables (vat_main_t * vam)
11837 {
11838   unformat_input_t *i = vam->input;
11839   vl_api_classify_set_interface_l2_tables_t *mp;
11840   u32 sw_if_index;
11841   int sw_if_index_set;
11842   u32 ip4_table_index = ~0;
11843   u32 ip6_table_index = ~0;
11844   u32 other_table_index = ~0;
11845   u32 is_input = 1;
11846   int ret;
11847
11848   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11849     {
11850       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11851         sw_if_index_set = 1;
11852       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11853         sw_if_index_set = 1;
11854       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11855         ;
11856       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11857         ;
11858       else if (unformat (i, "other-table %d", &other_table_index))
11859         ;
11860       else if (unformat (i, "is-input %d", &is_input))
11861         ;
11862       else
11863         {
11864           clib_warning ("parse error '%U'", format_unformat_error, i);
11865           return -99;
11866         }
11867     }
11868
11869   if (sw_if_index_set == 0)
11870     {
11871       errmsg ("missing interface name or sw_if_index");
11872       return -99;
11873     }
11874
11875
11876   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11877
11878   mp->sw_if_index = ntohl (sw_if_index);
11879   mp->ip4_table_index = ntohl (ip4_table_index);
11880   mp->ip6_table_index = ntohl (ip6_table_index);
11881   mp->other_table_index = ntohl (other_table_index);
11882   mp->is_input = (u8) is_input;
11883
11884   S (mp);
11885   W (ret);
11886   return ret;
11887 }
11888
11889 static int
11890 api_set_ipfix_exporter (vat_main_t * vam)
11891 {
11892   unformat_input_t *i = vam->input;
11893   vl_api_set_ipfix_exporter_t *mp;
11894   ip4_address_t collector_address;
11895   u8 collector_address_set = 0;
11896   u32 collector_port = ~0;
11897   ip4_address_t src_address;
11898   u8 src_address_set = 0;
11899   u32 vrf_id = ~0;
11900   u32 path_mtu = ~0;
11901   u32 template_interval = ~0;
11902   u8 udp_checksum = 0;
11903   int ret;
11904
11905   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11906     {
11907       if (unformat (i, "collector_address %U", unformat_ip4_address,
11908                     &collector_address))
11909         collector_address_set = 1;
11910       else if (unformat (i, "collector_port %d", &collector_port))
11911         ;
11912       else if (unformat (i, "src_address %U", unformat_ip4_address,
11913                          &src_address))
11914         src_address_set = 1;
11915       else if (unformat (i, "vrf_id %d", &vrf_id))
11916         ;
11917       else if (unformat (i, "path_mtu %d", &path_mtu))
11918         ;
11919       else if (unformat (i, "template_interval %d", &template_interval))
11920         ;
11921       else if (unformat (i, "udp_checksum"))
11922         udp_checksum = 1;
11923       else
11924         break;
11925     }
11926
11927   if (collector_address_set == 0)
11928     {
11929       errmsg ("collector_address required");
11930       return -99;
11931     }
11932
11933   if (src_address_set == 0)
11934     {
11935       errmsg ("src_address required");
11936       return -99;
11937     }
11938
11939   M (SET_IPFIX_EXPORTER, mp);
11940
11941   memcpy (mp->collector_address, collector_address.data,
11942           sizeof (collector_address.data));
11943   mp->collector_port = htons ((u16) collector_port);
11944   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11945   mp->vrf_id = htonl (vrf_id);
11946   mp->path_mtu = htonl (path_mtu);
11947   mp->template_interval = htonl (template_interval);
11948   mp->udp_checksum = udp_checksum;
11949
11950   S (mp);
11951   W (ret);
11952   return ret;
11953 }
11954
11955 static int
11956 api_set_ipfix_classify_stream (vat_main_t * vam)
11957 {
11958   unformat_input_t *i = vam->input;
11959   vl_api_set_ipfix_classify_stream_t *mp;
11960   u32 domain_id = 0;
11961   u32 src_port = UDP_DST_PORT_ipfix;
11962   int ret;
11963
11964   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11965     {
11966       if (unformat (i, "domain %d", &domain_id))
11967         ;
11968       else if (unformat (i, "src_port %d", &src_port))
11969         ;
11970       else
11971         {
11972           errmsg ("unknown input `%U'", format_unformat_error, i);
11973           return -99;
11974         }
11975     }
11976
11977   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11978
11979   mp->domain_id = htonl (domain_id);
11980   mp->src_port = htons ((u16) src_port);
11981
11982   S (mp);
11983   W (ret);
11984   return ret;
11985 }
11986
11987 static int
11988 api_ipfix_classify_table_add_del (vat_main_t * vam)
11989 {
11990   unformat_input_t *i = vam->input;
11991   vl_api_ipfix_classify_table_add_del_t *mp;
11992   int is_add = -1;
11993   u32 classify_table_index = ~0;
11994   u8 ip_version = 0;
11995   u8 transport_protocol = 255;
11996   int ret;
11997
11998   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11999     {
12000       if (unformat (i, "add"))
12001         is_add = 1;
12002       else if (unformat (i, "del"))
12003         is_add = 0;
12004       else if (unformat (i, "table %d", &classify_table_index))
12005         ;
12006       else if (unformat (i, "ip4"))
12007         ip_version = 4;
12008       else if (unformat (i, "ip6"))
12009         ip_version = 6;
12010       else if (unformat (i, "tcp"))
12011         transport_protocol = 6;
12012       else if (unformat (i, "udp"))
12013         transport_protocol = 17;
12014       else
12015         {
12016           errmsg ("unknown input `%U'", format_unformat_error, i);
12017           return -99;
12018         }
12019     }
12020
12021   if (is_add == -1)
12022     {
12023       errmsg ("expecting: add|del");
12024       return -99;
12025     }
12026   if (classify_table_index == ~0)
12027     {
12028       errmsg ("classifier table not specified");
12029       return -99;
12030     }
12031   if (ip_version == 0)
12032     {
12033       errmsg ("IP version not specified");
12034       return -99;
12035     }
12036
12037   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
12038
12039   mp->is_add = is_add;
12040   mp->table_id = htonl (classify_table_index);
12041   mp->ip_version = ip_version;
12042   mp->transport_protocol = transport_protocol;
12043
12044   S (mp);
12045   W (ret);
12046   return ret;
12047 }
12048
12049 static int
12050 api_get_node_index (vat_main_t * vam)
12051 {
12052   unformat_input_t *i = vam->input;
12053   vl_api_get_node_index_t *mp;
12054   u8 *name = 0;
12055   int ret;
12056
12057   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12058     {
12059       if (unformat (i, "node %s", &name))
12060         ;
12061       else
12062         break;
12063     }
12064   if (name == 0)
12065     {
12066       errmsg ("node name required");
12067       return -99;
12068     }
12069   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12070     {
12071       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12072       return -99;
12073     }
12074
12075   M (GET_NODE_INDEX, mp);
12076   clib_memcpy (mp->node_name, name, vec_len (name));
12077   vec_free (name);
12078
12079   S (mp);
12080   W (ret);
12081   return ret;
12082 }
12083
12084 static int
12085 api_get_next_index (vat_main_t * vam)
12086 {
12087   unformat_input_t *i = vam->input;
12088   vl_api_get_next_index_t *mp;
12089   u8 *node_name = 0, *next_node_name = 0;
12090   int ret;
12091
12092   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12093     {
12094       if (unformat (i, "node-name %s", &node_name))
12095         ;
12096       else if (unformat (i, "next-node-name %s", &next_node_name))
12097         break;
12098     }
12099
12100   if (node_name == 0)
12101     {
12102       errmsg ("node name required");
12103       return -99;
12104     }
12105   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12106     {
12107       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12108       return -99;
12109     }
12110
12111   if (next_node_name == 0)
12112     {
12113       errmsg ("next node name required");
12114       return -99;
12115     }
12116   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12117     {
12118       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12119       return -99;
12120     }
12121
12122   M (GET_NEXT_INDEX, mp);
12123   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12124   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12125   vec_free (node_name);
12126   vec_free (next_node_name);
12127
12128   S (mp);
12129   W (ret);
12130   return ret;
12131 }
12132
12133 static int
12134 api_add_node_next (vat_main_t * vam)
12135 {
12136   unformat_input_t *i = vam->input;
12137   vl_api_add_node_next_t *mp;
12138   u8 *name = 0;
12139   u8 *next = 0;
12140   int ret;
12141
12142   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12143     {
12144       if (unformat (i, "node %s", &name))
12145         ;
12146       else if (unformat (i, "next %s", &next))
12147         ;
12148       else
12149         break;
12150     }
12151   if (name == 0)
12152     {
12153       errmsg ("node name required");
12154       return -99;
12155     }
12156   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12157     {
12158       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12159       return -99;
12160     }
12161   if (next == 0)
12162     {
12163       errmsg ("next node required");
12164       return -99;
12165     }
12166   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12167     {
12168       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12169       return -99;
12170     }
12171
12172   M (ADD_NODE_NEXT, mp);
12173   clib_memcpy (mp->node_name, name, vec_len (name));
12174   clib_memcpy (mp->next_name, next, vec_len (next));
12175   vec_free (name);
12176   vec_free (next);
12177
12178   S (mp);
12179   W (ret);
12180   return ret;
12181 }
12182
12183 static int
12184 api_l2tpv3_create_tunnel (vat_main_t * vam)
12185 {
12186   unformat_input_t *i = vam->input;
12187   ip6_address_t client_address, our_address;
12188   int client_address_set = 0;
12189   int our_address_set = 0;
12190   u32 local_session_id = 0;
12191   u32 remote_session_id = 0;
12192   u64 local_cookie = 0;
12193   u64 remote_cookie = 0;
12194   u8 l2_sublayer_present = 0;
12195   vl_api_l2tpv3_create_tunnel_t *mp;
12196   int ret;
12197
12198   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12199     {
12200       if (unformat (i, "client_address %U", unformat_ip6_address,
12201                     &client_address))
12202         client_address_set = 1;
12203       else if (unformat (i, "our_address %U", unformat_ip6_address,
12204                          &our_address))
12205         our_address_set = 1;
12206       else if (unformat (i, "local_session_id %d", &local_session_id))
12207         ;
12208       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12209         ;
12210       else if (unformat (i, "local_cookie %lld", &local_cookie))
12211         ;
12212       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12213         ;
12214       else if (unformat (i, "l2-sublayer-present"))
12215         l2_sublayer_present = 1;
12216       else
12217         break;
12218     }
12219
12220   if (client_address_set == 0)
12221     {
12222       errmsg ("client_address required");
12223       return -99;
12224     }
12225
12226   if (our_address_set == 0)
12227     {
12228       errmsg ("our_address required");
12229       return -99;
12230     }
12231
12232   M (L2TPV3_CREATE_TUNNEL, mp);
12233
12234   clib_memcpy (mp->client_address, client_address.as_u8,
12235                sizeof (mp->client_address));
12236
12237   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12238
12239   mp->local_session_id = ntohl (local_session_id);
12240   mp->remote_session_id = ntohl (remote_session_id);
12241   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12242   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12243   mp->l2_sublayer_present = l2_sublayer_present;
12244   mp->is_ipv6 = 1;
12245
12246   S (mp);
12247   W (ret);
12248   return ret;
12249 }
12250
12251 static int
12252 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12253 {
12254   unformat_input_t *i = vam->input;
12255   u32 sw_if_index;
12256   u8 sw_if_index_set = 0;
12257   u64 new_local_cookie = 0;
12258   u64 new_remote_cookie = 0;
12259   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12260   int ret;
12261
12262   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12263     {
12264       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12265         sw_if_index_set = 1;
12266       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12267         sw_if_index_set = 1;
12268       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12269         ;
12270       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12271         ;
12272       else
12273         break;
12274     }
12275
12276   if (sw_if_index_set == 0)
12277     {
12278       errmsg ("missing interface name or sw_if_index");
12279       return -99;
12280     }
12281
12282   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12283
12284   mp->sw_if_index = ntohl (sw_if_index);
12285   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12286   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12287
12288   S (mp);
12289   W (ret);
12290   return ret;
12291 }
12292
12293 static int
12294 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12295 {
12296   unformat_input_t *i = vam->input;
12297   vl_api_l2tpv3_interface_enable_disable_t *mp;
12298   u32 sw_if_index;
12299   u8 sw_if_index_set = 0;
12300   u8 enable_disable = 1;
12301   int ret;
12302
12303   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12304     {
12305       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12306         sw_if_index_set = 1;
12307       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12308         sw_if_index_set = 1;
12309       else if (unformat (i, "enable"))
12310         enable_disable = 1;
12311       else if (unformat (i, "disable"))
12312         enable_disable = 0;
12313       else
12314         break;
12315     }
12316
12317   if (sw_if_index_set == 0)
12318     {
12319       errmsg ("missing interface name or sw_if_index");
12320       return -99;
12321     }
12322
12323   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12324
12325   mp->sw_if_index = ntohl (sw_if_index);
12326   mp->enable_disable = enable_disable;
12327
12328   S (mp);
12329   W (ret);
12330   return ret;
12331 }
12332
12333 static int
12334 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12335 {
12336   unformat_input_t *i = vam->input;
12337   vl_api_l2tpv3_set_lookup_key_t *mp;
12338   u8 key = ~0;
12339   int ret;
12340
12341   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12342     {
12343       if (unformat (i, "lookup_v6_src"))
12344         key = L2T_LOOKUP_SRC_ADDRESS;
12345       else if (unformat (i, "lookup_v6_dst"))
12346         key = L2T_LOOKUP_DST_ADDRESS;
12347       else if (unformat (i, "lookup_session_id"))
12348         key = L2T_LOOKUP_SESSION_ID;
12349       else
12350         break;
12351     }
12352
12353   if (key == (u8) ~ 0)
12354     {
12355       errmsg ("l2tp session lookup key unset");
12356       return -99;
12357     }
12358
12359   M (L2TPV3_SET_LOOKUP_KEY, mp);
12360
12361   mp->key = key;
12362
12363   S (mp);
12364   W (ret);
12365   return ret;
12366 }
12367
12368 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12369   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12370 {
12371   vat_main_t *vam = &vat_main;
12372
12373   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12374          format_ip6_address, mp->our_address,
12375          format_ip6_address, mp->client_address,
12376          clib_net_to_host_u32 (mp->sw_if_index));
12377
12378   print (vam->ofp,
12379          "   local cookies %016llx %016llx remote cookie %016llx",
12380          clib_net_to_host_u64 (mp->local_cookie[0]),
12381          clib_net_to_host_u64 (mp->local_cookie[1]),
12382          clib_net_to_host_u64 (mp->remote_cookie));
12383
12384   print (vam->ofp, "   local session-id %d remote session-id %d",
12385          clib_net_to_host_u32 (mp->local_session_id),
12386          clib_net_to_host_u32 (mp->remote_session_id));
12387
12388   print (vam->ofp, "   l2 specific sublayer %s\n",
12389          mp->l2_sublayer_present ? "preset" : "absent");
12390
12391 }
12392
12393 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12394   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12395 {
12396   vat_main_t *vam = &vat_main;
12397   vat_json_node_t *node = NULL;
12398   struct in6_addr addr;
12399
12400   if (VAT_JSON_ARRAY != vam->json_tree.type)
12401     {
12402       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12403       vat_json_init_array (&vam->json_tree);
12404     }
12405   node = vat_json_array_add (&vam->json_tree);
12406
12407   vat_json_init_object (node);
12408
12409   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12410   vat_json_object_add_ip6 (node, "our_address", addr);
12411   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12412   vat_json_object_add_ip6 (node, "client_address", addr);
12413
12414   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12415   vat_json_init_array (lc);
12416   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12417   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12418   vat_json_object_add_uint (node, "remote_cookie",
12419                             clib_net_to_host_u64 (mp->remote_cookie));
12420
12421   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12422   vat_json_object_add_uint (node, "local_session_id",
12423                             clib_net_to_host_u32 (mp->local_session_id));
12424   vat_json_object_add_uint (node, "remote_session_id",
12425                             clib_net_to_host_u32 (mp->remote_session_id));
12426   vat_json_object_add_string_copy (node, "l2_sublayer",
12427                                    mp->l2_sublayer_present ? (u8 *) "present"
12428                                    : (u8 *) "absent");
12429 }
12430
12431 static int
12432 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12433 {
12434   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12435   vl_api_control_ping_t *mp_ping;
12436   int ret;
12437
12438   /* Get list of l2tpv3-tunnel interfaces */
12439   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12440   S (mp);
12441
12442   /* Use a control ping for synchronization */
12443   MPING (CONTROL_PING, mp_ping);
12444   S (mp_ping);
12445
12446   W (ret);
12447   return ret;
12448 }
12449
12450
12451 static void vl_api_sw_interface_tap_v2_details_t_handler
12452   (vl_api_sw_interface_tap_v2_details_t * mp)
12453 {
12454   vat_main_t *vam = &vat_main;
12455
12456   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12457                     mp->host_ip4_prefix_len);
12458   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12459                     mp->host_ip6_prefix_len);
12460
12461   print (vam->ofp,
12462          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
12463          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12464          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12465          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12466          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
12467
12468   vec_free (ip4);
12469   vec_free (ip6);
12470 }
12471
12472 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12473   (vl_api_sw_interface_tap_v2_details_t * mp)
12474 {
12475   vat_main_t *vam = &vat_main;
12476   vat_json_node_t *node = NULL;
12477
12478   if (VAT_JSON_ARRAY != vam->json_tree.type)
12479     {
12480       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12481       vat_json_init_array (&vam->json_tree);
12482     }
12483   node = vat_json_array_add (&vam->json_tree);
12484
12485   vat_json_init_object (node);
12486   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12487   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12488   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
12489   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12490   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12491   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12492   vat_json_object_add_string_copy (node, "host_mac_addr",
12493                                    format (0, "%U", format_ethernet_address,
12494                                            &mp->host_mac_addr));
12495   vat_json_object_add_string_copy (node, "host_namespace",
12496                                    mp->host_namespace);
12497   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12498   vat_json_object_add_string_copy (node, "host_ip4_addr",
12499                                    format (0, "%U/%d", format_ip4_address,
12500                                            mp->host_ip4_addr,
12501                                            mp->host_ip4_prefix_len));
12502   vat_json_object_add_string_copy (node, "host_ip6_addr",
12503                                    format (0, "%U/%d", format_ip6_address,
12504                                            mp->host_ip6_addr,
12505                                            mp->host_ip6_prefix_len));
12506
12507 }
12508
12509 static int
12510 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12511 {
12512   vl_api_sw_interface_tap_v2_dump_t *mp;
12513   vl_api_control_ping_t *mp_ping;
12514   int ret;
12515
12516   print (vam->ofp,
12517          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12518          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12519          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12520          "host_ip6_addr");
12521
12522   /* Get list of tap interfaces */
12523   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12524   S (mp);
12525
12526   /* Use a control ping for synchronization */
12527   MPING (CONTROL_PING, mp_ping);
12528   S (mp_ping);
12529
12530   W (ret);
12531   return ret;
12532 }
12533
12534 static void vl_api_sw_interface_virtio_pci_details_t_handler
12535   (vl_api_sw_interface_virtio_pci_details_t * mp)
12536 {
12537   vat_main_t *vam = &vat_main;
12538
12539   typedef union
12540   {
12541     struct
12542     {
12543       u16 domain;
12544       u8 bus;
12545       u8 slot:5;
12546       u8 function:3;
12547     };
12548     u32 as_u32;
12549   } pci_addr_t;
12550   pci_addr_t addr;
12551   addr.as_u32 = ntohl (mp->pci_addr);
12552   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
12553                          addr.slot, addr.function);
12554
12555   print (vam->ofp,
12556          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
12557          pci_addr, ntohl (mp->sw_if_index),
12558          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12559          format_ethernet_address, mp->mac_addr,
12560          clib_net_to_host_u64 (mp->features));
12561   vec_free (pci_addr);
12562 }
12563
12564 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
12565   (vl_api_sw_interface_virtio_pci_details_t * mp)
12566 {
12567   vat_main_t *vam = &vat_main;
12568   vat_json_node_t *node = NULL;
12569
12570   if (VAT_JSON_ARRAY != vam->json_tree.type)
12571     {
12572       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12573       vat_json_init_array (&vam->json_tree);
12574     }
12575   node = vat_json_array_add (&vam->json_tree);
12576
12577   vat_json_init_object (node);
12578   vat_json_object_add_uint (node, "pci-addr", ntohl (mp->pci_addr));
12579   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12580   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12581   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12582   vat_json_object_add_uint (node, "features",
12583                             clib_net_to_host_u64 (mp->features));
12584   vat_json_object_add_string_copy (node, "mac_addr",
12585                                    format (0, "%U", format_ethernet_address,
12586                                            &mp->mac_addr));
12587 }
12588
12589 static int
12590 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
12591 {
12592   vl_api_sw_interface_virtio_pci_dump_t *mp;
12593   vl_api_control_ping_t *mp_ping;
12594   int ret;
12595
12596   print (vam->ofp,
12597          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
12598          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
12599          "mac_addr", "features");
12600
12601   /* Get list of tap interfaces */
12602   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
12603   S (mp);
12604
12605   /* Use a control ping for synchronization */
12606   MPING (CONTROL_PING, mp_ping);
12607   S (mp_ping);
12608
12609   W (ret);
12610   return ret;
12611 }
12612
12613 static int
12614 api_vxlan_offload_rx (vat_main_t * vam)
12615 {
12616   unformat_input_t *line_input = vam->input;
12617   vl_api_vxlan_offload_rx_t *mp;
12618   u32 hw_if_index = ~0, rx_if_index = ~0;
12619   u8 is_add = 1;
12620   int ret;
12621
12622   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12623     {
12624       if (unformat (line_input, "del"))
12625         is_add = 0;
12626       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
12627                          &hw_if_index))
12628         ;
12629       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
12630         ;
12631       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
12632                          &rx_if_index))
12633         ;
12634       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
12635         ;
12636       else
12637         {
12638           errmsg ("parse error '%U'", format_unformat_error, line_input);
12639           return -99;
12640         }
12641     }
12642
12643   if (hw_if_index == ~0)
12644     {
12645       errmsg ("no hw interface");
12646       return -99;
12647     }
12648
12649   if (rx_if_index == ~0)
12650     {
12651       errmsg ("no rx tunnel");
12652       return -99;
12653     }
12654
12655   M (VXLAN_OFFLOAD_RX, mp);
12656
12657   mp->hw_if_index = ntohl (hw_if_index);
12658   mp->sw_if_index = ntohl (rx_if_index);
12659   mp->enable = is_add;
12660
12661   S (mp);
12662   W (ret);
12663   return ret;
12664 }
12665
12666 static uword unformat_vxlan_decap_next
12667   (unformat_input_t * input, va_list * args)
12668 {
12669   u32 *result = va_arg (*args, u32 *);
12670   u32 tmp;
12671
12672   if (unformat (input, "l2"))
12673     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12674   else if (unformat (input, "%d", &tmp))
12675     *result = tmp;
12676   else
12677     return 0;
12678   return 1;
12679 }
12680
12681 static int
12682 api_vxlan_add_del_tunnel (vat_main_t * vam)
12683 {
12684   unformat_input_t *line_input = vam->input;
12685   vl_api_vxlan_add_del_tunnel_t *mp;
12686   ip46_address_t src, dst;
12687   u8 is_add = 1;
12688   u8 ipv4_set = 0, ipv6_set = 0;
12689   u8 src_set = 0;
12690   u8 dst_set = 0;
12691   u8 grp_set = 0;
12692   u32 instance = ~0;
12693   u32 mcast_sw_if_index = ~0;
12694   u32 encap_vrf_id = 0;
12695   u32 decap_next_index = ~0;
12696   u32 vni = 0;
12697   int ret;
12698
12699   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12700   clib_memset (&src, 0, sizeof src);
12701   clib_memset (&dst, 0, sizeof dst);
12702
12703   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12704     {
12705       if (unformat (line_input, "del"))
12706         is_add = 0;
12707       else if (unformat (line_input, "instance %d", &instance))
12708         ;
12709       else
12710         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12711         {
12712           ipv4_set = 1;
12713           src_set = 1;
12714         }
12715       else
12716         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12717         {
12718           ipv4_set = 1;
12719           dst_set = 1;
12720         }
12721       else
12722         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12723         {
12724           ipv6_set = 1;
12725           src_set = 1;
12726         }
12727       else
12728         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12729         {
12730           ipv6_set = 1;
12731           dst_set = 1;
12732         }
12733       else if (unformat (line_input, "group %U %U",
12734                          unformat_ip4_address, &dst.ip4,
12735                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12736         {
12737           grp_set = dst_set = 1;
12738           ipv4_set = 1;
12739         }
12740       else if (unformat (line_input, "group %U",
12741                          unformat_ip4_address, &dst.ip4))
12742         {
12743           grp_set = dst_set = 1;
12744           ipv4_set = 1;
12745         }
12746       else if (unformat (line_input, "group %U %U",
12747                          unformat_ip6_address, &dst.ip6,
12748                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12749         {
12750           grp_set = dst_set = 1;
12751           ipv6_set = 1;
12752         }
12753       else if (unformat (line_input, "group %U",
12754                          unformat_ip6_address, &dst.ip6))
12755         {
12756           grp_set = dst_set = 1;
12757           ipv6_set = 1;
12758         }
12759       else
12760         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12761         ;
12762       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12763         ;
12764       else if (unformat (line_input, "decap-next %U",
12765                          unformat_vxlan_decap_next, &decap_next_index))
12766         ;
12767       else if (unformat (line_input, "vni %d", &vni))
12768         ;
12769       else
12770         {
12771           errmsg ("parse error '%U'", format_unformat_error, line_input);
12772           return -99;
12773         }
12774     }
12775
12776   if (src_set == 0)
12777     {
12778       errmsg ("tunnel src address not specified");
12779       return -99;
12780     }
12781   if (dst_set == 0)
12782     {
12783       errmsg ("tunnel dst address not specified");
12784       return -99;
12785     }
12786
12787   if (grp_set && !ip46_address_is_multicast (&dst))
12788     {
12789       errmsg ("tunnel group address not multicast");
12790       return -99;
12791     }
12792   if (grp_set && mcast_sw_if_index == ~0)
12793     {
12794       errmsg ("tunnel nonexistent multicast device");
12795       return -99;
12796     }
12797   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12798     {
12799       errmsg ("tunnel dst address must be unicast");
12800       return -99;
12801     }
12802
12803
12804   if (ipv4_set && ipv6_set)
12805     {
12806       errmsg ("both IPv4 and IPv6 addresses specified");
12807       return -99;
12808     }
12809
12810   if ((vni == 0) || (vni >> 24))
12811     {
12812       errmsg ("vni not specified or out of range");
12813       return -99;
12814     }
12815
12816   M (VXLAN_ADD_DEL_TUNNEL, mp);
12817
12818   if (ipv6_set)
12819     {
12820       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12821       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12822     }
12823   else
12824     {
12825       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12826       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12827     }
12828
12829   mp->instance = htonl (instance);
12830   mp->encap_vrf_id = ntohl (encap_vrf_id);
12831   mp->decap_next_index = ntohl (decap_next_index);
12832   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12833   mp->vni = ntohl (vni);
12834   mp->is_add = is_add;
12835   mp->is_ipv6 = ipv6_set;
12836
12837   S (mp);
12838   W (ret);
12839   return ret;
12840 }
12841
12842 static void vl_api_vxlan_tunnel_details_t_handler
12843   (vl_api_vxlan_tunnel_details_t * mp)
12844 {
12845   vat_main_t *vam = &vat_main;
12846   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12847   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12848
12849   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
12850          ntohl (mp->sw_if_index),
12851          ntohl (mp->instance),
12852          format_ip46_address, &src, IP46_TYPE_ANY,
12853          format_ip46_address, &dst, IP46_TYPE_ANY,
12854          ntohl (mp->encap_vrf_id),
12855          ntohl (mp->decap_next_index), ntohl (mp->vni),
12856          ntohl (mp->mcast_sw_if_index));
12857 }
12858
12859 static void vl_api_vxlan_tunnel_details_t_handler_json
12860   (vl_api_vxlan_tunnel_details_t * mp)
12861 {
12862   vat_main_t *vam = &vat_main;
12863   vat_json_node_t *node = NULL;
12864
12865   if (VAT_JSON_ARRAY != vam->json_tree.type)
12866     {
12867       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12868       vat_json_init_array (&vam->json_tree);
12869     }
12870   node = vat_json_array_add (&vam->json_tree);
12871
12872   vat_json_init_object (node);
12873   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12874
12875   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
12876
12877   if (mp->is_ipv6)
12878     {
12879       struct in6_addr ip6;
12880
12881       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12882       vat_json_object_add_ip6 (node, "src_address", ip6);
12883       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12884       vat_json_object_add_ip6 (node, "dst_address", ip6);
12885     }
12886   else
12887     {
12888       struct in_addr ip4;
12889
12890       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12891       vat_json_object_add_ip4 (node, "src_address", ip4);
12892       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12893       vat_json_object_add_ip4 (node, "dst_address", ip4);
12894     }
12895   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12896   vat_json_object_add_uint (node, "decap_next_index",
12897                             ntohl (mp->decap_next_index));
12898   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12899   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12900   vat_json_object_add_uint (node, "mcast_sw_if_index",
12901                             ntohl (mp->mcast_sw_if_index));
12902 }
12903
12904 static int
12905 api_vxlan_tunnel_dump (vat_main_t * vam)
12906 {
12907   unformat_input_t *i = vam->input;
12908   vl_api_vxlan_tunnel_dump_t *mp;
12909   vl_api_control_ping_t *mp_ping;
12910   u32 sw_if_index;
12911   u8 sw_if_index_set = 0;
12912   int ret;
12913
12914   /* Parse args required to build the message */
12915   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12916     {
12917       if (unformat (i, "sw_if_index %d", &sw_if_index))
12918         sw_if_index_set = 1;
12919       else
12920         break;
12921     }
12922
12923   if (sw_if_index_set == 0)
12924     {
12925       sw_if_index = ~0;
12926     }
12927
12928   if (!vam->json_output)
12929     {
12930       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
12931              "sw_if_index", "instance", "src_address", "dst_address",
12932              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12933     }
12934
12935   /* Get list of vxlan-tunnel interfaces */
12936   M (VXLAN_TUNNEL_DUMP, mp);
12937
12938   mp->sw_if_index = htonl (sw_if_index);
12939
12940   S (mp);
12941
12942   /* Use a control ping for synchronization */
12943   MPING (CONTROL_PING, mp_ping);
12944   S (mp_ping);
12945
12946   W (ret);
12947   return ret;
12948 }
12949
12950 static uword unformat_geneve_decap_next
12951   (unformat_input_t * input, va_list * args)
12952 {
12953   u32 *result = va_arg (*args, u32 *);
12954   u32 tmp;
12955
12956   if (unformat (input, "l2"))
12957     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12958   else if (unformat (input, "%d", &tmp))
12959     *result = tmp;
12960   else
12961     return 0;
12962   return 1;
12963 }
12964
12965 static int
12966 api_geneve_add_del_tunnel (vat_main_t * vam)
12967 {
12968   unformat_input_t *line_input = vam->input;
12969   vl_api_geneve_add_del_tunnel_t *mp;
12970   ip46_address_t src, dst;
12971   u8 is_add = 1;
12972   u8 ipv4_set = 0, ipv6_set = 0;
12973   u8 src_set = 0;
12974   u8 dst_set = 0;
12975   u8 grp_set = 0;
12976   u32 mcast_sw_if_index = ~0;
12977   u32 encap_vrf_id = 0;
12978   u32 decap_next_index = ~0;
12979   u32 vni = 0;
12980   int ret;
12981
12982   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12983   clib_memset (&src, 0, sizeof src);
12984   clib_memset (&dst, 0, sizeof dst);
12985
12986   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12987     {
12988       if (unformat (line_input, "del"))
12989         is_add = 0;
12990       else
12991         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12992         {
12993           ipv4_set = 1;
12994           src_set = 1;
12995         }
12996       else
12997         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12998         {
12999           ipv4_set = 1;
13000           dst_set = 1;
13001         }
13002       else
13003         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13004         {
13005           ipv6_set = 1;
13006           src_set = 1;
13007         }
13008       else
13009         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13010         {
13011           ipv6_set = 1;
13012           dst_set = 1;
13013         }
13014       else if (unformat (line_input, "group %U %U",
13015                          unformat_ip4_address, &dst.ip4,
13016                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13017         {
13018           grp_set = dst_set = 1;
13019           ipv4_set = 1;
13020         }
13021       else if (unformat (line_input, "group %U",
13022                          unformat_ip4_address, &dst.ip4))
13023         {
13024           grp_set = dst_set = 1;
13025           ipv4_set = 1;
13026         }
13027       else if (unformat (line_input, "group %U %U",
13028                          unformat_ip6_address, &dst.ip6,
13029                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13030         {
13031           grp_set = dst_set = 1;
13032           ipv6_set = 1;
13033         }
13034       else if (unformat (line_input, "group %U",
13035                          unformat_ip6_address, &dst.ip6))
13036         {
13037           grp_set = dst_set = 1;
13038           ipv6_set = 1;
13039         }
13040       else
13041         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13042         ;
13043       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13044         ;
13045       else if (unformat (line_input, "decap-next %U",
13046                          unformat_geneve_decap_next, &decap_next_index))
13047         ;
13048       else if (unformat (line_input, "vni %d", &vni))
13049         ;
13050       else
13051         {
13052           errmsg ("parse error '%U'", format_unformat_error, line_input);
13053           return -99;
13054         }
13055     }
13056
13057   if (src_set == 0)
13058     {
13059       errmsg ("tunnel src address not specified");
13060       return -99;
13061     }
13062   if (dst_set == 0)
13063     {
13064       errmsg ("tunnel dst address not specified");
13065       return -99;
13066     }
13067
13068   if (grp_set && !ip46_address_is_multicast (&dst))
13069     {
13070       errmsg ("tunnel group address not multicast");
13071       return -99;
13072     }
13073   if (grp_set && mcast_sw_if_index == ~0)
13074     {
13075       errmsg ("tunnel nonexistent multicast device");
13076       return -99;
13077     }
13078   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13079     {
13080       errmsg ("tunnel dst address must be unicast");
13081       return -99;
13082     }
13083
13084
13085   if (ipv4_set && ipv6_set)
13086     {
13087       errmsg ("both IPv4 and IPv6 addresses specified");
13088       return -99;
13089     }
13090
13091   if ((vni == 0) || (vni >> 24))
13092     {
13093       errmsg ("vni not specified or out of range");
13094       return -99;
13095     }
13096
13097   M (GENEVE_ADD_DEL_TUNNEL, mp);
13098
13099   if (ipv6_set)
13100     {
13101       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
13102       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
13103     }
13104   else
13105     {
13106       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
13107       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
13108     }
13109   mp->encap_vrf_id = ntohl (encap_vrf_id);
13110   mp->decap_next_index = ntohl (decap_next_index);
13111   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13112   mp->vni = ntohl (vni);
13113   mp->is_add = is_add;
13114   mp->is_ipv6 = ipv6_set;
13115
13116   S (mp);
13117   W (ret);
13118   return ret;
13119 }
13120
13121 static void vl_api_geneve_tunnel_details_t_handler
13122   (vl_api_geneve_tunnel_details_t * mp)
13123 {
13124   vat_main_t *vam = &vat_main;
13125   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13126   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13127
13128   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
13129          ntohl (mp->sw_if_index),
13130          format_ip46_address, &src, IP46_TYPE_ANY,
13131          format_ip46_address, &dst, IP46_TYPE_ANY,
13132          ntohl (mp->encap_vrf_id),
13133          ntohl (mp->decap_next_index), ntohl (mp->vni),
13134          ntohl (mp->mcast_sw_if_index));
13135 }
13136
13137 static void vl_api_geneve_tunnel_details_t_handler_json
13138   (vl_api_geneve_tunnel_details_t * mp)
13139 {
13140   vat_main_t *vam = &vat_main;
13141   vat_json_node_t *node = NULL;
13142
13143   if (VAT_JSON_ARRAY != vam->json_tree.type)
13144     {
13145       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13146       vat_json_init_array (&vam->json_tree);
13147     }
13148   node = vat_json_array_add (&vam->json_tree);
13149
13150   vat_json_init_object (node);
13151   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13152   if (mp->is_ipv6)
13153     {
13154       struct in6_addr ip6;
13155
13156       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13157       vat_json_object_add_ip6 (node, "src_address", ip6);
13158       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13159       vat_json_object_add_ip6 (node, "dst_address", ip6);
13160     }
13161   else
13162     {
13163       struct in_addr ip4;
13164
13165       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13166       vat_json_object_add_ip4 (node, "src_address", ip4);
13167       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13168       vat_json_object_add_ip4 (node, "dst_address", ip4);
13169     }
13170   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13171   vat_json_object_add_uint (node, "decap_next_index",
13172                             ntohl (mp->decap_next_index));
13173   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13174   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13175   vat_json_object_add_uint (node, "mcast_sw_if_index",
13176                             ntohl (mp->mcast_sw_if_index));
13177 }
13178
13179 static int
13180 api_geneve_tunnel_dump (vat_main_t * vam)
13181 {
13182   unformat_input_t *i = vam->input;
13183   vl_api_geneve_tunnel_dump_t *mp;
13184   vl_api_control_ping_t *mp_ping;
13185   u32 sw_if_index;
13186   u8 sw_if_index_set = 0;
13187   int ret;
13188
13189   /* Parse args required to build the message */
13190   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13191     {
13192       if (unformat (i, "sw_if_index %d", &sw_if_index))
13193         sw_if_index_set = 1;
13194       else
13195         break;
13196     }
13197
13198   if (sw_if_index_set == 0)
13199     {
13200       sw_if_index = ~0;
13201     }
13202
13203   if (!vam->json_output)
13204     {
13205       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13206              "sw_if_index", "local_address", "remote_address",
13207              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13208     }
13209
13210   /* Get list of geneve-tunnel interfaces */
13211   M (GENEVE_TUNNEL_DUMP, mp);
13212
13213   mp->sw_if_index = htonl (sw_if_index);
13214
13215   S (mp);
13216
13217   /* Use a control ping for synchronization */
13218   M (CONTROL_PING, mp_ping);
13219   S (mp_ping);
13220
13221   W (ret);
13222   return ret;
13223 }
13224
13225 static int
13226 api_gre_tunnel_add_del (vat_main_t * vam)
13227 {
13228   unformat_input_t *line_input = vam->input;
13229   vl_api_address_t src = { }, dst =
13230   {
13231   };
13232   vl_api_gre_tunnel_add_del_t *mp;
13233   vl_api_gre_tunnel_type_t t_type;
13234   u8 is_add = 1;
13235   u8 src_set = 0;
13236   u8 dst_set = 0;
13237   u32 outer_fib_id = 0;
13238   u32 session_id = 0;
13239   u32 instance = ~0;
13240   int ret;
13241
13242   t_type = GRE_API_TUNNEL_TYPE_L3;
13243
13244   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13245     {
13246       if (unformat (line_input, "del"))
13247         is_add = 0;
13248       else if (unformat (line_input, "instance %d", &instance))
13249         ;
13250       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
13251         {
13252           src_set = 1;
13253         }
13254       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
13255         {
13256           dst_set = 1;
13257         }
13258       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13259         ;
13260       else if (unformat (line_input, "teb"))
13261         t_type = GRE_API_TUNNEL_TYPE_TEB;
13262       else if (unformat (line_input, "erspan %d", &session_id))
13263         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
13264       else
13265         {
13266           errmsg ("parse error '%U'", format_unformat_error, line_input);
13267           return -99;
13268         }
13269     }
13270
13271   if (src_set == 0)
13272     {
13273       errmsg ("tunnel src address not specified");
13274       return -99;
13275     }
13276   if (dst_set == 0)
13277     {
13278       errmsg ("tunnel dst address not specified");
13279       return -99;
13280     }
13281
13282   M (GRE_TUNNEL_ADD_DEL, mp);
13283
13284   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
13285   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
13286
13287   mp->tunnel.instance = htonl (instance);
13288   mp->tunnel.outer_fib_id = htonl (outer_fib_id);
13289   mp->is_add = is_add;
13290   mp->tunnel.session_id = htons ((u16) session_id);
13291   mp->tunnel.type = htonl (t_type);
13292
13293   S (mp);
13294   W (ret);
13295   return ret;
13296 }
13297
13298 static void vl_api_gre_tunnel_details_t_handler
13299   (vl_api_gre_tunnel_details_t * mp)
13300 {
13301   vat_main_t *vam = &vat_main;
13302
13303   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13304          ntohl (mp->tunnel.sw_if_index),
13305          ntohl (mp->tunnel.instance),
13306          format_vl_api_address, &mp->tunnel.src,
13307          format_vl_api_address, &mp->tunnel.dst,
13308          mp->tunnel.type, ntohl (mp->tunnel.outer_fib_id),
13309          ntohl (mp->tunnel.session_id));
13310 }
13311
13312 static void
13313 vat_json_object_add_address (vat_json_node_t * node,
13314                              const char *str, const vl_api_address_t * addr)
13315 {
13316   if (ADDRESS_IP6 == addr->af)
13317     {
13318       struct in6_addr ip6;
13319
13320       clib_memcpy (&ip6, &addr->un.ip6, sizeof (ip6));
13321       vat_json_object_add_ip6 (node, str, ip6);
13322     }
13323   else
13324     {
13325       struct in_addr ip4;
13326
13327       clib_memcpy (&ip4, &addr->un.ip4, sizeof (ip4));
13328       vat_json_object_add_ip4 (node, str, ip4);
13329     }
13330 }
13331
13332 static void vl_api_gre_tunnel_details_t_handler_json
13333   (vl_api_gre_tunnel_details_t * mp)
13334 {
13335   vat_main_t *vam = &vat_main;
13336   vat_json_node_t *node = NULL;
13337
13338   if (VAT_JSON_ARRAY != vam->json_tree.type)
13339     {
13340       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13341       vat_json_init_array (&vam->json_tree);
13342     }
13343   node = vat_json_array_add (&vam->json_tree);
13344
13345   vat_json_init_object (node);
13346   vat_json_object_add_uint (node, "sw_if_index",
13347                             ntohl (mp->tunnel.sw_if_index));
13348   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
13349
13350   vat_json_object_add_address (node, "src", &mp->tunnel.src);
13351   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
13352   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
13353   vat_json_object_add_uint (node, "outer_fib_id",
13354                             ntohl (mp->tunnel.outer_fib_id));
13355   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
13356 }
13357
13358 static int
13359 api_gre_tunnel_dump (vat_main_t * vam)
13360 {
13361   unformat_input_t *i = vam->input;
13362   vl_api_gre_tunnel_dump_t *mp;
13363   vl_api_control_ping_t *mp_ping;
13364   u32 sw_if_index;
13365   u8 sw_if_index_set = 0;
13366   int ret;
13367
13368   /* Parse args required to build the message */
13369   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13370     {
13371       if (unformat (i, "sw_if_index %d", &sw_if_index))
13372         sw_if_index_set = 1;
13373       else
13374         break;
13375     }
13376
13377   if (sw_if_index_set == 0)
13378     {
13379       sw_if_index = ~0;
13380     }
13381
13382   if (!vam->json_output)
13383     {
13384       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13385              "sw_if_index", "instance", "src_address", "dst_address",
13386              "tunnel_type", "outer_fib_id", "session_id");
13387     }
13388
13389   /* Get list of gre-tunnel interfaces */
13390   M (GRE_TUNNEL_DUMP, mp);
13391
13392   mp->sw_if_index = htonl (sw_if_index);
13393
13394   S (mp);
13395
13396   /* Use a control ping for synchronization */
13397   MPING (CONTROL_PING, mp_ping);
13398   S (mp_ping);
13399
13400   W (ret);
13401   return ret;
13402 }
13403
13404 static int
13405 api_l2_fib_clear_table (vat_main_t * vam)
13406 {
13407 //  unformat_input_t * i = vam->input;
13408   vl_api_l2_fib_clear_table_t *mp;
13409   int ret;
13410
13411   M (L2_FIB_CLEAR_TABLE, mp);
13412
13413   S (mp);
13414   W (ret);
13415   return ret;
13416 }
13417
13418 static int
13419 api_l2_interface_efp_filter (vat_main_t * vam)
13420 {
13421   unformat_input_t *i = vam->input;
13422   vl_api_l2_interface_efp_filter_t *mp;
13423   u32 sw_if_index;
13424   u8 enable = 1;
13425   u8 sw_if_index_set = 0;
13426   int ret;
13427
13428   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13429     {
13430       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13431         sw_if_index_set = 1;
13432       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13433         sw_if_index_set = 1;
13434       else if (unformat (i, "enable"))
13435         enable = 1;
13436       else if (unformat (i, "disable"))
13437         enable = 0;
13438       else
13439         {
13440           clib_warning ("parse error '%U'", format_unformat_error, i);
13441           return -99;
13442         }
13443     }
13444
13445   if (sw_if_index_set == 0)
13446     {
13447       errmsg ("missing sw_if_index");
13448       return -99;
13449     }
13450
13451   M (L2_INTERFACE_EFP_FILTER, mp);
13452
13453   mp->sw_if_index = ntohl (sw_if_index);
13454   mp->enable_disable = enable;
13455
13456   S (mp);
13457   W (ret);
13458   return ret;
13459 }
13460
13461 #define foreach_vtr_op                          \
13462 _("disable",  L2_VTR_DISABLED)                  \
13463 _("push-1",  L2_VTR_PUSH_1)                     \
13464 _("push-2",  L2_VTR_PUSH_2)                     \
13465 _("pop-1",  L2_VTR_POP_1)                       \
13466 _("pop-2",  L2_VTR_POP_2)                       \
13467 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13468 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13469 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13470 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13471
13472 static int
13473 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13474 {
13475   unformat_input_t *i = vam->input;
13476   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13477   u32 sw_if_index;
13478   u8 sw_if_index_set = 0;
13479   u8 vtr_op_set = 0;
13480   u32 vtr_op = 0;
13481   u32 push_dot1q = 1;
13482   u32 tag1 = ~0;
13483   u32 tag2 = ~0;
13484   int ret;
13485
13486   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13487     {
13488       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13489         sw_if_index_set = 1;
13490       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13491         sw_if_index_set = 1;
13492       else if (unformat (i, "vtr_op %d", &vtr_op))
13493         vtr_op_set = 1;
13494 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13495       foreach_vtr_op
13496 #undef _
13497         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13498         ;
13499       else if (unformat (i, "tag1 %d", &tag1))
13500         ;
13501       else if (unformat (i, "tag2 %d", &tag2))
13502         ;
13503       else
13504         {
13505           clib_warning ("parse error '%U'", format_unformat_error, i);
13506           return -99;
13507         }
13508     }
13509
13510   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13511     {
13512       errmsg ("missing vtr operation or sw_if_index");
13513       return -99;
13514     }
13515
13516   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13517   mp->sw_if_index = ntohl (sw_if_index);
13518   mp->vtr_op = ntohl (vtr_op);
13519   mp->push_dot1q = ntohl (push_dot1q);
13520   mp->tag1 = ntohl (tag1);
13521   mp->tag2 = ntohl (tag2);
13522
13523   S (mp);
13524   W (ret);
13525   return ret;
13526 }
13527
13528 static int
13529 api_create_vhost_user_if (vat_main_t * vam)
13530 {
13531   unformat_input_t *i = vam->input;
13532   vl_api_create_vhost_user_if_t *mp;
13533   u8 *file_name;
13534   u8 is_server = 0;
13535   u8 file_name_set = 0;
13536   u32 custom_dev_instance = ~0;
13537   u8 hwaddr[6];
13538   u8 use_custom_mac = 0;
13539   u8 disable_mrg_rxbuf = 0;
13540   u8 disable_indirect_desc = 0;
13541   u8 *tag = 0;
13542   int ret;
13543
13544   /* Shut up coverity */
13545   clib_memset (hwaddr, 0, sizeof (hwaddr));
13546
13547   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13548     {
13549       if (unformat (i, "socket %s", &file_name))
13550         {
13551           file_name_set = 1;
13552         }
13553       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13554         ;
13555       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13556         use_custom_mac = 1;
13557       else if (unformat (i, "server"))
13558         is_server = 1;
13559       else if (unformat (i, "disable_mrg_rxbuf"))
13560         disable_mrg_rxbuf = 1;
13561       else if (unformat (i, "disable_indirect_desc"))
13562         disable_indirect_desc = 1;
13563       else if (unformat (i, "tag %s", &tag))
13564         ;
13565       else
13566         break;
13567     }
13568
13569   if (file_name_set == 0)
13570     {
13571       errmsg ("missing socket file name");
13572       return -99;
13573     }
13574
13575   if (vec_len (file_name) > 255)
13576     {
13577       errmsg ("socket file name too long");
13578       return -99;
13579     }
13580   vec_add1 (file_name, 0);
13581
13582   M (CREATE_VHOST_USER_IF, mp);
13583
13584   mp->is_server = is_server;
13585   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
13586   mp->disable_indirect_desc = disable_indirect_desc;
13587   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13588   vec_free (file_name);
13589   if (custom_dev_instance != ~0)
13590     {
13591       mp->renumber = 1;
13592       mp->custom_dev_instance = ntohl (custom_dev_instance);
13593     }
13594
13595   mp->use_custom_mac = use_custom_mac;
13596   clib_memcpy (mp->mac_address, hwaddr, 6);
13597   if (tag)
13598     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13599   vec_free (tag);
13600
13601   S (mp);
13602   W (ret);
13603   return ret;
13604 }
13605
13606 static int
13607 api_modify_vhost_user_if (vat_main_t * vam)
13608 {
13609   unformat_input_t *i = vam->input;
13610   vl_api_modify_vhost_user_if_t *mp;
13611   u8 *file_name;
13612   u8 is_server = 0;
13613   u8 file_name_set = 0;
13614   u32 custom_dev_instance = ~0;
13615   u8 sw_if_index_set = 0;
13616   u32 sw_if_index = (u32) ~ 0;
13617   int ret;
13618
13619   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13620     {
13621       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13622         sw_if_index_set = 1;
13623       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13624         sw_if_index_set = 1;
13625       else if (unformat (i, "socket %s", &file_name))
13626         {
13627           file_name_set = 1;
13628         }
13629       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13630         ;
13631       else if (unformat (i, "server"))
13632         is_server = 1;
13633       else
13634         break;
13635     }
13636
13637   if (sw_if_index_set == 0)
13638     {
13639       errmsg ("missing sw_if_index or interface name");
13640       return -99;
13641     }
13642
13643   if (file_name_set == 0)
13644     {
13645       errmsg ("missing socket file name");
13646       return -99;
13647     }
13648
13649   if (vec_len (file_name) > 255)
13650     {
13651       errmsg ("socket file name too long");
13652       return -99;
13653     }
13654   vec_add1 (file_name, 0);
13655
13656   M (MODIFY_VHOST_USER_IF, mp);
13657
13658   mp->sw_if_index = ntohl (sw_if_index);
13659   mp->is_server = is_server;
13660   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13661   vec_free (file_name);
13662   if (custom_dev_instance != ~0)
13663     {
13664       mp->renumber = 1;
13665       mp->custom_dev_instance = ntohl (custom_dev_instance);
13666     }
13667
13668   S (mp);
13669   W (ret);
13670   return ret;
13671 }
13672
13673 static int
13674 api_delete_vhost_user_if (vat_main_t * vam)
13675 {
13676   unformat_input_t *i = vam->input;
13677   vl_api_delete_vhost_user_if_t *mp;
13678   u32 sw_if_index = ~0;
13679   u8 sw_if_index_set = 0;
13680   int ret;
13681
13682   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13683     {
13684       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13685         sw_if_index_set = 1;
13686       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13687         sw_if_index_set = 1;
13688       else
13689         break;
13690     }
13691
13692   if (sw_if_index_set == 0)
13693     {
13694       errmsg ("missing sw_if_index or interface name");
13695       return -99;
13696     }
13697
13698
13699   M (DELETE_VHOST_USER_IF, mp);
13700
13701   mp->sw_if_index = ntohl (sw_if_index);
13702
13703   S (mp);
13704   W (ret);
13705   return ret;
13706 }
13707
13708 static void vl_api_sw_interface_vhost_user_details_t_handler
13709   (vl_api_sw_interface_vhost_user_details_t * mp)
13710 {
13711   vat_main_t *vam = &vat_main;
13712
13713   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13714          (char *) mp->interface_name,
13715          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13716          clib_net_to_host_u64 (mp->features), mp->is_server,
13717          ntohl (mp->num_regions), (char *) mp->sock_filename);
13718   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13719 }
13720
13721 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13722   (vl_api_sw_interface_vhost_user_details_t * mp)
13723 {
13724   vat_main_t *vam = &vat_main;
13725   vat_json_node_t *node = NULL;
13726
13727   if (VAT_JSON_ARRAY != vam->json_tree.type)
13728     {
13729       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13730       vat_json_init_array (&vam->json_tree);
13731     }
13732   node = vat_json_array_add (&vam->json_tree);
13733
13734   vat_json_init_object (node);
13735   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13736   vat_json_object_add_string_copy (node, "interface_name",
13737                                    mp->interface_name);
13738   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13739                             ntohl (mp->virtio_net_hdr_sz));
13740   vat_json_object_add_uint (node, "features",
13741                             clib_net_to_host_u64 (mp->features));
13742   vat_json_object_add_uint (node, "is_server", mp->is_server);
13743   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13744   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13745   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13746 }
13747
13748 static int
13749 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13750 {
13751   vl_api_sw_interface_vhost_user_dump_t *mp;
13752   vl_api_control_ping_t *mp_ping;
13753   int ret;
13754   print (vam->ofp,
13755          "Interface name            idx hdr_sz features server regions filename");
13756
13757   /* Get list of vhost-user interfaces */
13758   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13759   S (mp);
13760
13761   /* Use a control ping for synchronization */
13762   MPING (CONTROL_PING, mp_ping);
13763   S (mp_ping);
13764
13765   W (ret);
13766   return ret;
13767 }
13768
13769 static int
13770 api_show_version (vat_main_t * vam)
13771 {
13772   vl_api_show_version_t *mp;
13773   int ret;
13774
13775   M (SHOW_VERSION, mp);
13776
13777   S (mp);
13778   W (ret);
13779   return ret;
13780 }
13781
13782
13783 static int
13784 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13785 {
13786   unformat_input_t *line_input = vam->input;
13787   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13788   ip4_address_t local4, remote4;
13789   ip6_address_t local6, remote6;
13790   u8 is_add = 1;
13791   u8 ipv4_set = 0, ipv6_set = 0;
13792   u8 local_set = 0;
13793   u8 remote_set = 0;
13794   u8 grp_set = 0;
13795   u32 mcast_sw_if_index = ~0;
13796   u32 encap_vrf_id = 0;
13797   u32 decap_vrf_id = 0;
13798   u8 protocol = ~0;
13799   u32 vni;
13800   u8 vni_set = 0;
13801   int ret;
13802
13803   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13804   clib_memset (&local4, 0, sizeof local4);
13805   clib_memset (&remote4, 0, sizeof remote4);
13806   clib_memset (&local6, 0, sizeof local6);
13807   clib_memset (&remote6, 0, sizeof remote6);
13808
13809   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13810     {
13811       if (unformat (line_input, "del"))
13812         is_add = 0;
13813       else if (unformat (line_input, "local %U",
13814                          unformat_ip4_address, &local4))
13815         {
13816           local_set = 1;
13817           ipv4_set = 1;
13818         }
13819       else if (unformat (line_input, "remote %U",
13820                          unformat_ip4_address, &remote4))
13821         {
13822           remote_set = 1;
13823           ipv4_set = 1;
13824         }
13825       else if (unformat (line_input, "local %U",
13826                          unformat_ip6_address, &local6))
13827         {
13828           local_set = 1;
13829           ipv6_set = 1;
13830         }
13831       else if (unformat (line_input, "remote %U",
13832                          unformat_ip6_address, &remote6))
13833         {
13834           remote_set = 1;
13835           ipv6_set = 1;
13836         }
13837       else if (unformat (line_input, "group %U %U",
13838                          unformat_ip4_address, &remote4,
13839                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13840         {
13841           grp_set = remote_set = 1;
13842           ipv4_set = 1;
13843         }
13844       else if (unformat (line_input, "group %U",
13845                          unformat_ip4_address, &remote4))
13846         {
13847           grp_set = remote_set = 1;
13848           ipv4_set = 1;
13849         }
13850       else if (unformat (line_input, "group %U %U",
13851                          unformat_ip6_address, &remote6,
13852                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13853         {
13854           grp_set = remote_set = 1;
13855           ipv6_set = 1;
13856         }
13857       else if (unformat (line_input, "group %U",
13858                          unformat_ip6_address, &remote6))
13859         {
13860           grp_set = remote_set = 1;
13861           ipv6_set = 1;
13862         }
13863       else
13864         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13865         ;
13866       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13867         ;
13868       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13869         ;
13870       else if (unformat (line_input, "vni %d", &vni))
13871         vni_set = 1;
13872       else if (unformat (line_input, "next-ip4"))
13873         protocol = 1;
13874       else if (unformat (line_input, "next-ip6"))
13875         protocol = 2;
13876       else if (unformat (line_input, "next-ethernet"))
13877         protocol = 3;
13878       else if (unformat (line_input, "next-nsh"))
13879         protocol = 4;
13880       else
13881         {
13882           errmsg ("parse error '%U'", format_unformat_error, line_input);
13883           return -99;
13884         }
13885     }
13886
13887   if (local_set == 0)
13888     {
13889       errmsg ("tunnel local address not specified");
13890       return -99;
13891     }
13892   if (remote_set == 0)
13893     {
13894       errmsg ("tunnel remote address not specified");
13895       return -99;
13896     }
13897   if (grp_set && mcast_sw_if_index == ~0)
13898     {
13899       errmsg ("tunnel nonexistent multicast device");
13900       return -99;
13901     }
13902   if (ipv4_set && ipv6_set)
13903     {
13904       errmsg ("both IPv4 and IPv6 addresses specified");
13905       return -99;
13906     }
13907
13908   if (vni_set == 0)
13909     {
13910       errmsg ("vni not specified");
13911       return -99;
13912     }
13913
13914   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13915
13916
13917   if (ipv6_set)
13918     {
13919       clib_memcpy (&mp->local, &local6, sizeof (local6));
13920       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13921     }
13922   else
13923     {
13924       clib_memcpy (&mp->local, &local4, sizeof (local4));
13925       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13926     }
13927
13928   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13929   mp->encap_vrf_id = ntohl (encap_vrf_id);
13930   mp->decap_vrf_id = ntohl (decap_vrf_id);
13931   mp->protocol = protocol;
13932   mp->vni = ntohl (vni);
13933   mp->is_add = is_add;
13934   mp->is_ipv6 = ipv6_set;
13935
13936   S (mp);
13937   W (ret);
13938   return ret;
13939 }
13940
13941 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13942   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13943 {
13944   vat_main_t *vam = &vat_main;
13945   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13946   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13947
13948   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13949          ntohl (mp->sw_if_index),
13950          format_ip46_address, &local, IP46_TYPE_ANY,
13951          format_ip46_address, &remote, IP46_TYPE_ANY,
13952          ntohl (mp->vni), mp->protocol,
13953          ntohl (mp->mcast_sw_if_index),
13954          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13955 }
13956
13957
13958 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13959   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13960 {
13961   vat_main_t *vam = &vat_main;
13962   vat_json_node_t *node = NULL;
13963   struct in_addr ip4;
13964   struct in6_addr ip6;
13965
13966   if (VAT_JSON_ARRAY != vam->json_tree.type)
13967     {
13968       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13969       vat_json_init_array (&vam->json_tree);
13970     }
13971   node = vat_json_array_add (&vam->json_tree);
13972
13973   vat_json_init_object (node);
13974   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13975   if (mp->is_ipv6)
13976     {
13977       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13978       vat_json_object_add_ip6 (node, "local", ip6);
13979       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13980       vat_json_object_add_ip6 (node, "remote", ip6);
13981     }
13982   else
13983     {
13984       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13985       vat_json_object_add_ip4 (node, "local", ip4);
13986       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13987       vat_json_object_add_ip4 (node, "remote", ip4);
13988     }
13989   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13990   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13991   vat_json_object_add_uint (node, "mcast_sw_if_index",
13992                             ntohl (mp->mcast_sw_if_index));
13993   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13994   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13995   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13996 }
13997
13998 static int
13999 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
14000 {
14001   unformat_input_t *i = vam->input;
14002   vl_api_vxlan_gpe_tunnel_dump_t *mp;
14003   vl_api_control_ping_t *mp_ping;
14004   u32 sw_if_index;
14005   u8 sw_if_index_set = 0;
14006   int ret;
14007
14008   /* Parse args required to build the message */
14009   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14010     {
14011       if (unformat (i, "sw_if_index %d", &sw_if_index))
14012         sw_if_index_set = 1;
14013       else
14014         break;
14015     }
14016
14017   if (sw_if_index_set == 0)
14018     {
14019       sw_if_index = ~0;
14020     }
14021
14022   if (!vam->json_output)
14023     {
14024       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
14025              "sw_if_index", "local", "remote", "vni",
14026              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
14027     }
14028
14029   /* Get list of vxlan-tunnel interfaces */
14030   M (VXLAN_GPE_TUNNEL_DUMP, mp);
14031
14032   mp->sw_if_index = htonl (sw_if_index);
14033
14034   S (mp);
14035
14036   /* Use a control ping for synchronization */
14037   MPING (CONTROL_PING, mp_ping);
14038   S (mp_ping);
14039
14040   W (ret);
14041   return ret;
14042 }
14043
14044 static void vl_api_l2_fib_table_details_t_handler
14045   (vl_api_l2_fib_table_details_t * mp)
14046 {
14047   vat_main_t *vam = &vat_main;
14048
14049   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
14050          "       %d       %d     %d",
14051          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
14052          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
14053          mp->bvi_mac);
14054 }
14055
14056 static void vl_api_l2_fib_table_details_t_handler_json
14057   (vl_api_l2_fib_table_details_t * mp)
14058 {
14059   vat_main_t *vam = &vat_main;
14060   vat_json_node_t *node = NULL;
14061
14062   if (VAT_JSON_ARRAY != vam->json_tree.type)
14063     {
14064       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14065       vat_json_init_array (&vam->json_tree);
14066     }
14067   node = vat_json_array_add (&vam->json_tree);
14068
14069   vat_json_init_object (node);
14070   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
14071   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
14072   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14073   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
14074   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
14075   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
14076 }
14077
14078 static int
14079 api_l2_fib_table_dump (vat_main_t * vam)
14080 {
14081   unformat_input_t *i = vam->input;
14082   vl_api_l2_fib_table_dump_t *mp;
14083   vl_api_control_ping_t *mp_ping;
14084   u32 bd_id;
14085   u8 bd_id_set = 0;
14086   int ret;
14087
14088   /* Parse args required to build the message */
14089   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14090     {
14091       if (unformat (i, "bd_id %d", &bd_id))
14092         bd_id_set = 1;
14093       else
14094         break;
14095     }
14096
14097   if (bd_id_set == 0)
14098     {
14099       errmsg ("missing bridge domain");
14100       return -99;
14101     }
14102
14103   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
14104
14105   /* Get list of l2 fib entries */
14106   M (L2_FIB_TABLE_DUMP, mp);
14107
14108   mp->bd_id = ntohl (bd_id);
14109   S (mp);
14110
14111   /* Use a control ping for synchronization */
14112   MPING (CONTROL_PING, mp_ping);
14113   S (mp_ping);
14114
14115   W (ret);
14116   return ret;
14117 }
14118
14119
14120 static int
14121 api_interface_name_renumber (vat_main_t * vam)
14122 {
14123   unformat_input_t *line_input = vam->input;
14124   vl_api_interface_name_renumber_t *mp;
14125   u32 sw_if_index = ~0;
14126   u32 new_show_dev_instance = ~0;
14127   int ret;
14128
14129   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14130     {
14131       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
14132                     &sw_if_index))
14133         ;
14134       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14135         ;
14136       else if (unformat (line_input, "new_show_dev_instance %d",
14137                          &new_show_dev_instance))
14138         ;
14139       else
14140         break;
14141     }
14142
14143   if (sw_if_index == ~0)
14144     {
14145       errmsg ("missing interface name or sw_if_index");
14146       return -99;
14147     }
14148
14149   if (new_show_dev_instance == ~0)
14150     {
14151       errmsg ("missing new_show_dev_instance");
14152       return -99;
14153     }
14154
14155   M (INTERFACE_NAME_RENUMBER, mp);
14156
14157   mp->sw_if_index = ntohl (sw_if_index);
14158   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14159
14160   S (mp);
14161   W (ret);
14162   return ret;
14163 }
14164
14165 static int
14166 api_ip_probe_neighbor (vat_main_t * vam)
14167 {
14168   unformat_input_t *i = vam->input;
14169   vl_api_ip_probe_neighbor_t *mp;
14170   vl_api_address_t dst_adr = { };
14171   u8 int_set = 0;
14172   u8 adr_set = 0;
14173   u32 sw_if_index;
14174   int ret;
14175
14176   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14177     {
14178       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14179         int_set = 1;
14180       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14181         int_set = 1;
14182       else if (unformat (i, "address %U", unformat_vl_api_address, &dst_adr))
14183         adr_set = 1;
14184       else
14185         break;
14186     }
14187
14188   if (int_set == 0)
14189     {
14190       errmsg ("missing interface");
14191       return -99;
14192     }
14193
14194   if (adr_set == 0)
14195     {
14196       errmsg ("missing addresses");
14197       return -99;
14198     }
14199
14200   M (IP_PROBE_NEIGHBOR, mp);
14201
14202   mp->sw_if_index = ntohl (sw_if_index);
14203   clib_memcpy (&mp->dst, &dst_adr, sizeof (dst_adr));
14204
14205   S (mp);
14206   W (ret);
14207   return ret;
14208 }
14209
14210 static int
14211 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
14212 {
14213   unformat_input_t *i = vam->input;
14214   vl_api_ip_scan_neighbor_enable_disable_t *mp;
14215   u8 mode = IP_SCAN_V46_NEIGHBORS;
14216   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
14217   int ret;
14218
14219   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14220     {
14221       if (unformat (i, "ip4"))
14222         mode = IP_SCAN_V4_NEIGHBORS;
14223       else if (unformat (i, "ip6"))
14224         mode = IP_SCAN_V6_NEIGHBORS;
14225       if (unformat (i, "both"))
14226         mode = IP_SCAN_V46_NEIGHBORS;
14227       else if (unformat (i, "disable"))
14228         mode = IP_SCAN_DISABLED;
14229       else if (unformat (i, "interval %d", &interval))
14230         ;
14231       else if (unformat (i, "max-time %d", &time))
14232         ;
14233       else if (unformat (i, "max-update %d", &update))
14234         ;
14235       else if (unformat (i, "delay %d", &delay))
14236         ;
14237       else if (unformat (i, "stale %d", &stale))
14238         ;
14239       else
14240         break;
14241     }
14242
14243   if (interval > 255)
14244     {
14245       errmsg ("interval cannot exceed 255 minutes.");
14246       return -99;
14247     }
14248   if (time > 255)
14249     {
14250       errmsg ("max-time cannot exceed 255 usec.");
14251       return -99;
14252     }
14253   if (update > 255)
14254     {
14255       errmsg ("max-update cannot exceed 255.");
14256       return -99;
14257     }
14258   if (delay > 255)
14259     {
14260       errmsg ("delay cannot exceed 255 msec.");
14261       return -99;
14262     }
14263   if (stale > 255)
14264     {
14265       errmsg ("stale cannot exceed 255 minutes.");
14266       return -99;
14267     }
14268
14269   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14270   mp->mode = mode;
14271   mp->scan_interval = interval;
14272   mp->max_proc_time = time;
14273   mp->max_update = update;
14274   mp->scan_int_delay = delay;
14275   mp->stale_threshold = stale;
14276
14277   S (mp);
14278   W (ret);
14279   return ret;
14280 }
14281
14282 static int
14283 api_want_ip4_arp_events (vat_main_t * vam)
14284 {
14285   unformat_input_t *line_input = vam->input;
14286   vl_api_want_ip4_arp_events_t *mp;
14287   ip4_address_t address;
14288   int address_set = 0;
14289   u32 enable_disable = 1;
14290   int ret;
14291
14292   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14293     {
14294       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14295         address_set = 1;
14296       else if (unformat (line_input, "del"))
14297         enable_disable = 0;
14298       else
14299         break;
14300     }
14301
14302   if (address_set == 0)
14303     {
14304       errmsg ("missing addresses");
14305       return -99;
14306     }
14307
14308   M (WANT_IP4_ARP_EVENTS, mp);
14309   mp->enable_disable = enable_disable;
14310   mp->pid = htonl (getpid ());
14311   clib_memcpy (mp->ip, &address, sizeof (address));
14312
14313   S (mp);
14314   W (ret);
14315   return ret;
14316 }
14317
14318 static int
14319 api_want_ip6_nd_events (vat_main_t * vam)
14320 {
14321   unformat_input_t *line_input = vam->input;
14322   vl_api_want_ip6_nd_events_t *mp;
14323   vl_api_ip6_address_t address;
14324   int address_set = 0;
14325   u32 enable_disable = 1;
14326   int ret;
14327
14328   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14329     {
14330       if (unformat
14331           (line_input, "address %U", unformat_vl_api_ip6_address, &address))
14332         address_set = 1;
14333       else if (unformat (line_input, "del"))
14334         enable_disable = 0;
14335       else
14336         break;
14337     }
14338
14339   if (address_set == 0)
14340     {
14341       errmsg ("missing addresses");
14342       return -99;
14343     }
14344
14345   M (WANT_IP6_ND_EVENTS, mp);
14346   mp->enable_disable = enable_disable;
14347   mp->pid = htonl (getpid ());
14348   clib_memcpy (&mp->ip, &address, sizeof (address));
14349
14350   S (mp);
14351   W (ret);
14352   return ret;
14353 }
14354
14355 static int
14356 api_want_l2_macs_events (vat_main_t * vam)
14357 {
14358   unformat_input_t *line_input = vam->input;
14359   vl_api_want_l2_macs_events_t *mp;
14360   u8 enable_disable = 1;
14361   u32 scan_delay = 0;
14362   u32 max_macs_in_event = 0;
14363   u32 learn_limit = 0;
14364   int ret;
14365
14366   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14367     {
14368       if (unformat (line_input, "learn-limit %d", &learn_limit))
14369         ;
14370       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14371         ;
14372       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14373         ;
14374       else if (unformat (line_input, "disable"))
14375         enable_disable = 0;
14376       else
14377         break;
14378     }
14379
14380   M (WANT_L2_MACS_EVENTS, mp);
14381   mp->enable_disable = enable_disable;
14382   mp->pid = htonl (getpid ());
14383   mp->learn_limit = htonl (learn_limit);
14384   mp->scan_delay = (u8) scan_delay;
14385   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14386   S (mp);
14387   W (ret);
14388   return ret;
14389 }
14390
14391 static int
14392 api_input_acl_set_interface (vat_main_t * vam)
14393 {
14394   unformat_input_t *i = vam->input;
14395   vl_api_input_acl_set_interface_t *mp;
14396   u32 sw_if_index;
14397   int sw_if_index_set;
14398   u32 ip4_table_index = ~0;
14399   u32 ip6_table_index = ~0;
14400   u32 l2_table_index = ~0;
14401   u8 is_add = 1;
14402   int ret;
14403
14404   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14405     {
14406       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14407         sw_if_index_set = 1;
14408       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14409         sw_if_index_set = 1;
14410       else if (unformat (i, "del"))
14411         is_add = 0;
14412       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14413         ;
14414       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14415         ;
14416       else if (unformat (i, "l2-table %d", &l2_table_index))
14417         ;
14418       else
14419         {
14420           clib_warning ("parse error '%U'", format_unformat_error, i);
14421           return -99;
14422         }
14423     }
14424
14425   if (sw_if_index_set == 0)
14426     {
14427       errmsg ("missing interface name or sw_if_index");
14428       return -99;
14429     }
14430
14431   M (INPUT_ACL_SET_INTERFACE, mp);
14432
14433   mp->sw_if_index = ntohl (sw_if_index);
14434   mp->ip4_table_index = ntohl (ip4_table_index);
14435   mp->ip6_table_index = ntohl (ip6_table_index);
14436   mp->l2_table_index = ntohl (l2_table_index);
14437   mp->is_add = is_add;
14438
14439   S (mp);
14440   W (ret);
14441   return ret;
14442 }
14443
14444 static int
14445 api_output_acl_set_interface (vat_main_t * vam)
14446 {
14447   unformat_input_t *i = vam->input;
14448   vl_api_output_acl_set_interface_t *mp;
14449   u32 sw_if_index;
14450   int sw_if_index_set;
14451   u32 ip4_table_index = ~0;
14452   u32 ip6_table_index = ~0;
14453   u32 l2_table_index = ~0;
14454   u8 is_add = 1;
14455   int ret;
14456
14457   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14458     {
14459       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14460         sw_if_index_set = 1;
14461       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14462         sw_if_index_set = 1;
14463       else if (unformat (i, "del"))
14464         is_add = 0;
14465       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14466         ;
14467       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14468         ;
14469       else if (unformat (i, "l2-table %d", &l2_table_index))
14470         ;
14471       else
14472         {
14473           clib_warning ("parse error '%U'", format_unformat_error, i);
14474           return -99;
14475         }
14476     }
14477
14478   if (sw_if_index_set == 0)
14479     {
14480       errmsg ("missing interface name or sw_if_index");
14481       return -99;
14482     }
14483
14484   M (OUTPUT_ACL_SET_INTERFACE, mp);
14485
14486   mp->sw_if_index = ntohl (sw_if_index);
14487   mp->ip4_table_index = ntohl (ip4_table_index);
14488   mp->ip6_table_index = ntohl (ip6_table_index);
14489   mp->l2_table_index = ntohl (l2_table_index);
14490   mp->is_add = is_add;
14491
14492   S (mp);
14493   W (ret);
14494   return ret;
14495 }
14496
14497 static int
14498 api_ip_address_dump (vat_main_t * vam)
14499 {
14500   unformat_input_t *i = vam->input;
14501   vl_api_ip_address_dump_t *mp;
14502   vl_api_control_ping_t *mp_ping;
14503   u32 sw_if_index = ~0;
14504   u8 sw_if_index_set = 0;
14505   u8 ipv4_set = 0;
14506   u8 ipv6_set = 0;
14507   int ret;
14508
14509   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14510     {
14511       if (unformat (i, "sw_if_index %d", &sw_if_index))
14512         sw_if_index_set = 1;
14513       else
14514         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14515         sw_if_index_set = 1;
14516       else if (unformat (i, "ipv4"))
14517         ipv4_set = 1;
14518       else if (unformat (i, "ipv6"))
14519         ipv6_set = 1;
14520       else
14521         break;
14522     }
14523
14524   if (ipv4_set && ipv6_set)
14525     {
14526       errmsg ("ipv4 and ipv6 flags cannot be both set");
14527       return -99;
14528     }
14529
14530   if ((!ipv4_set) && (!ipv6_set))
14531     {
14532       errmsg ("no ipv4 nor ipv6 flag set");
14533       return -99;
14534     }
14535
14536   if (sw_if_index_set == 0)
14537     {
14538       errmsg ("missing interface name or sw_if_index");
14539       return -99;
14540     }
14541
14542   vam->current_sw_if_index = sw_if_index;
14543   vam->is_ipv6 = ipv6_set;
14544
14545   M (IP_ADDRESS_DUMP, mp);
14546   mp->sw_if_index = ntohl (sw_if_index);
14547   mp->is_ipv6 = ipv6_set;
14548   S (mp);
14549
14550   /* Use a control ping for synchronization */
14551   MPING (CONTROL_PING, mp_ping);
14552   S (mp_ping);
14553
14554   W (ret);
14555   return ret;
14556 }
14557
14558 static int
14559 api_ip_dump (vat_main_t * vam)
14560 {
14561   vl_api_ip_dump_t *mp;
14562   vl_api_control_ping_t *mp_ping;
14563   unformat_input_t *in = vam->input;
14564   int ipv4_set = 0;
14565   int ipv6_set = 0;
14566   int is_ipv6;
14567   int i;
14568   int ret;
14569
14570   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14571     {
14572       if (unformat (in, "ipv4"))
14573         ipv4_set = 1;
14574       else if (unformat (in, "ipv6"))
14575         ipv6_set = 1;
14576       else
14577         break;
14578     }
14579
14580   if (ipv4_set && ipv6_set)
14581     {
14582       errmsg ("ipv4 and ipv6 flags cannot be both set");
14583       return -99;
14584     }
14585
14586   if ((!ipv4_set) && (!ipv6_set))
14587     {
14588       errmsg ("no ipv4 nor ipv6 flag set");
14589       return -99;
14590     }
14591
14592   is_ipv6 = ipv6_set;
14593   vam->is_ipv6 = is_ipv6;
14594
14595   /* free old data */
14596   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14597     {
14598       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14599     }
14600   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14601
14602   M (IP_DUMP, mp);
14603   mp->is_ipv6 = ipv6_set;
14604   S (mp);
14605
14606   /* Use a control ping for synchronization */
14607   MPING (CONTROL_PING, mp_ping);
14608   S (mp_ping);
14609
14610   W (ret);
14611   return ret;
14612 }
14613
14614 static int
14615 api_ipsec_spd_add_del (vat_main_t * vam)
14616 {
14617   unformat_input_t *i = vam->input;
14618   vl_api_ipsec_spd_add_del_t *mp;
14619   u32 spd_id = ~0;
14620   u8 is_add = 1;
14621   int ret;
14622
14623   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14624     {
14625       if (unformat (i, "spd_id %d", &spd_id))
14626         ;
14627       else if (unformat (i, "del"))
14628         is_add = 0;
14629       else
14630         {
14631           clib_warning ("parse error '%U'", format_unformat_error, i);
14632           return -99;
14633         }
14634     }
14635   if (spd_id == ~0)
14636     {
14637       errmsg ("spd_id must be set");
14638       return -99;
14639     }
14640
14641   M (IPSEC_SPD_ADD_DEL, mp);
14642
14643   mp->spd_id = ntohl (spd_id);
14644   mp->is_add = is_add;
14645
14646   S (mp);
14647   W (ret);
14648   return ret;
14649 }
14650
14651 static int
14652 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14653 {
14654   unformat_input_t *i = vam->input;
14655   vl_api_ipsec_interface_add_del_spd_t *mp;
14656   u32 sw_if_index;
14657   u8 sw_if_index_set = 0;
14658   u32 spd_id = (u32) ~ 0;
14659   u8 is_add = 1;
14660   int ret;
14661
14662   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14663     {
14664       if (unformat (i, "del"))
14665         is_add = 0;
14666       else if (unformat (i, "spd_id %d", &spd_id))
14667         ;
14668       else
14669         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14670         sw_if_index_set = 1;
14671       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14672         sw_if_index_set = 1;
14673       else
14674         {
14675           clib_warning ("parse error '%U'", format_unformat_error, i);
14676           return -99;
14677         }
14678
14679     }
14680
14681   if (spd_id == (u32) ~ 0)
14682     {
14683       errmsg ("spd_id must be set");
14684       return -99;
14685     }
14686
14687   if (sw_if_index_set == 0)
14688     {
14689       errmsg ("missing interface name or sw_if_index");
14690       return -99;
14691     }
14692
14693   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14694
14695   mp->spd_id = ntohl (spd_id);
14696   mp->sw_if_index = ntohl (sw_if_index);
14697   mp->is_add = is_add;
14698
14699   S (mp);
14700   W (ret);
14701   return ret;
14702 }
14703
14704 static int
14705 api_ipsec_spd_entry_add_del (vat_main_t * vam)
14706 {
14707   unformat_input_t *i = vam->input;
14708   vl_api_ipsec_spd_entry_add_del_t *mp;
14709   u8 is_add = 1, is_outbound = 0;
14710   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14711   i32 priority = 0;
14712   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14713   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14714   vl_api_address_t laddr_start = { }, laddr_stop =
14715   {
14716   }, raddr_start =
14717   {
14718   }, raddr_stop =
14719   {
14720   };
14721   int ret;
14722
14723   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14724     {
14725       if (unformat (i, "del"))
14726         is_add = 0;
14727       if (unformat (i, "outbound"))
14728         is_outbound = 1;
14729       if (unformat (i, "inbound"))
14730         is_outbound = 0;
14731       else if (unformat (i, "spd_id %d", &spd_id))
14732         ;
14733       else if (unformat (i, "sa_id %d", &sa_id))
14734         ;
14735       else if (unformat (i, "priority %d", &priority))
14736         ;
14737       else if (unformat (i, "protocol %d", &protocol))
14738         ;
14739       else if (unformat (i, "lport_start %d", &lport_start))
14740         ;
14741       else if (unformat (i, "lport_stop %d", &lport_stop))
14742         ;
14743       else if (unformat (i, "rport_start %d", &rport_start))
14744         ;
14745       else if (unformat (i, "rport_stop %d", &rport_stop))
14746         ;
14747       else if (unformat (i, "laddr_start %U",
14748                          unformat_vl_api_address, &laddr_start))
14749         ;
14750       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
14751                          &laddr_stop))
14752         ;
14753       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
14754                          &raddr_start))
14755         ;
14756       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
14757                          &raddr_stop))
14758         ;
14759       else
14760         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14761         {
14762           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14763             {
14764               clib_warning ("unsupported action: 'resolve'");
14765               return -99;
14766             }
14767         }
14768       else
14769         {
14770           clib_warning ("parse error '%U'", format_unformat_error, i);
14771           return -99;
14772         }
14773
14774     }
14775
14776   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
14777
14778   mp->is_add = is_add;
14779
14780   mp->entry.spd_id = ntohl (spd_id);
14781   mp->entry.priority = ntohl (priority);
14782   mp->entry.is_outbound = is_outbound;
14783
14784   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
14785                sizeof (vl_api_address_t));
14786   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
14787                sizeof (vl_api_address_t));
14788   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
14789                sizeof (vl_api_address_t));
14790   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
14791                sizeof (vl_api_address_t));
14792
14793   mp->entry.protocol = (u8) protocol;
14794   mp->entry.local_port_start = ntohs ((u16) lport_start);
14795   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
14796   mp->entry.remote_port_start = ntohs ((u16) rport_start);
14797   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
14798   mp->entry.policy = (u8) policy;
14799   mp->entry.sa_id = ntohl (sa_id);
14800
14801   S (mp);
14802   W (ret);
14803   return ret;
14804 }
14805
14806 static int
14807 api_ipsec_sad_entry_add_del (vat_main_t * vam)
14808 {
14809   unformat_input_t *i = vam->input;
14810   vl_api_ipsec_sad_entry_add_del_t *mp;
14811   u32 sad_id = 0, spi = 0;
14812   u8 *ck = 0, *ik = 0;
14813   u8 is_add = 1;
14814
14815   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
14816   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
14817   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
14818   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
14819   vl_api_address_t tun_src, tun_dst;
14820   int ret;
14821
14822   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14823     {
14824       if (unformat (i, "del"))
14825         is_add = 0;
14826       else if (unformat (i, "sad_id %d", &sad_id))
14827         ;
14828       else if (unformat (i, "spi %d", &spi))
14829         ;
14830       else if (unformat (i, "esp"))
14831         protocol = IPSEC_API_PROTO_ESP;
14832       else
14833         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
14834         {
14835           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14836           if (ADDRESS_IP6 == tun_src.af)
14837             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14838         }
14839       else
14840         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
14841         {
14842           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14843           if (ADDRESS_IP6 == tun_src.af)
14844             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14845         }
14846       else
14847         if (unformat (i, "crypto_alg %U",
14848                       unformat_ipsec_api_crypto_alg, &crypto_alg))
14849         ;
14850       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14851         ;
14852       else if (unformat (i, "integ_alg %U",
14853                          unformat_ipsec_api_integ_alg, &integ_alg))
14854         ;
14855       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14856         ;
14857       else
14858         {
14859           clib_warning ("parse error '%U'", format_unformat_error, i);
14860           return -99;
14861         }
14862
14863     }
14864
14865   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
14866
14867   mp->is_add = is_add;
14868   mp->entry.sad_id = ntohl (sad_id);
14869   mp->entry.protocol = protocol;
14870   mp->entry.spi = ntohl (spi);
14871   mp->entry.flags = flags;
14872
14873   mp->entry.crypto_algorithm = crypto_alg;
14874   mp->entry.integrity_algorithm = integ_alg;
14875   mp->entry.crypto_key.length = vec_len (ck);
14876   mp->entry.integrity_key.length = vec_len (ik);
14877
14878   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
14879     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
14880
14881   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
14882     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
14883
14884   if (ck)
14885     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
14886   if (ik)
14887     clib_memcpy (mp->entry.integrity_key.data, ik,
14888                  mp->entry.integrity_key.length);
14889
14890   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
14891     {
14892       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
14893                    sizeof (mp->entry.tunnel_src));
14894       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
14895                    sizeof (mp->entry.tunnel_dst));
14896     }
14897
14898   S (mp);
14899   W (ret);
14900   return ret;
14901 }
14902
14903 static int
14904 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14905 {
14906   unformat_input_t *i = vam->input;
14907   vl_api_ipsec_tunnel_if_add_del_t *mp;
14908   u32 local_spi = 0, remote_spi = 0;
14909   u32 crypto_alg = 0, integ_alg = 0;
14910   u8 *lck = NULL, *rck = NULL;
14911   u8 *lik = NULL, *rik = NULL;
14912   vl_api_address_t local_ip = { 0 };
14913   vl_api_address_t remote_ip = { 0 };
14914   f64 before = 0;
14915   u8 is_add = 1;
14916   u8 esn = 0;
14917   u8 anti_replay = 0;
14918   u8 renumber = 0;
14919   u32 instance = ~0;
14920   u32 count = 1, jj;
14921   int ret = -1;
14922
14923   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14924     {
14925       if (unformat (i, "del"))
14926         is_add = 0;
14927       else if (unformat (i, "esn"))
14928         esn = 1;
14929       else if (unformat (i, "anti-replay"))
14930         anti_replay = 1;
14931       else if (unformat (i, "count %d", &count))
14932         ;
14933       else if (unformat (i, "local_spi %d", &local_spi))
14934         ;
14935       else if (unformat (i, "remote_spi %d", &remote_spi))
14936         ;
14937       else
14938         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
14939         ;
14940       else
14941         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
14942         ;
14943       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14944         ;
14945       else
14946         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14947         ;
14948       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14949         ;
14950       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14951         ;
14952       else
14953         if (unformat
14954             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
14955         {
14956           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
14957             {
14958               errmsg ("unsupported crypto-alg: '%U'\n",
14959                       format_ipsec_crypto_alg, crypto_alg);
14960               return -99;
14961             }
14962         }
14963       else
14964         if (unformat
14965             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
14966         {
14967           if (integ_alg >= IPSEC_INTEG_N_ALG)
14968             {
14969               errmsg ("unsupported integ-alg: '%U'\n",
14970                       format_ipsec_integ_alg, integ_alg);
14971               return -99;
14972             }
14973         }
14974       else if (unformat (i, "instance %u", &instance))
14975         renumber = 1;
14976       else
14977         {
14978           errmsg ("parse error '%U'\n", format_unformat_error, i);
14979           return -99;
14980         }
14981     }
14982
14983   if (count > 1)
14984     {
14985       /* Turn on async mode */
14986       vam->async_mode = 1;
14987       vam->async_errors = 0;
14988       before = vat_time_now (vam);
14989     }
14990
14991   for (jj = 0; jj < count; jj++)
14992     {
14993       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14994
14995       mp->is_add = is_add;
14996       mp->esn = esn;
14997       mp->anti_replay = anti_replay;
14998
14999       if (jj > 0)
15000         increment_vl_address (&remote_ip);
15001
15002       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
15003       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
15004
15005       mp->local_spi = htonl (local_spi + jj);
15006       mp->remote_spi = htonl (remote_spi + jj);
15007       mp->crypto_alg = (u8) crypto_alg;
15008
15009       mp->local_crypto_key_len = 0;
15010       if (lck)
15011         {
15012           mp->local_crypto_key_len = vec_len (lck);
15013           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15014             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15015           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15016         }
15017
15018       mp->remote_crypto_key_len = 0;
15019       if (rck)
15020         {
15021           mp->remote_crypto_key_len = vec_len (rck);
15022           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15023             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15024           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15025         }
15026
15027       mp->integ_alg = (u8) integ_alg;
15028
15029       mp->local_integ_key_len = 0;
15030       if (lik)
15031         {
15032           mp->local_integ_key_len = vec_len (lik);
15033           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15034             mp->local_integ_key_len = sizeof (mp->local_integ_key);
15035           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15036         }
15037
15038       mp->remote_integ_key_len = 0;
15039       if (rik)
15040         {
15041           mp->remote_integ_key_len = vec_len (rik);
15042           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15043             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15044           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15045         }
15046
15047       if (renumber)
15048         {
15049           mp->renumber = renumber;
15050           mp->show_instance = ntohl (instance);
15051         }
15052       S (mp);
15053     }
15054
15055   /* When testing multiple add/del ops, use a control-ping to sync */
15056   if (count > 1)
15057     {
15058       vl_api_control_ping_t *mp_ping;
15059       f64 after;
15060       f64 timeout;
15061
15062       /* Shut off async mode */
15063       vam->async_mode = 0;
15064
15065       MPING (CONTROL_PING, mp_ping);
15066       S (mp_ping);
15067
15068       timeout = vat_time_now (vam) + 1.0;
15069       while (vat_time_now (vam) < timeout)
15070         if (vam->result_ready == 1)
15071           goto out;
15072       vam->retval = -99;
15073
15074     out:
15075       if (vam->retval == -99)
15076         errmsg ("timeout");
15077
15078       if (vam->async_errors > 0)
15079         {
15080           errmsg ("%d asynchronous errors", vam->async_errors);
15081           vam->retval = -98;
15082         }
15083       vam->async_errors = 0;
15084       after = vat_time_now (vam);
15085
15086       /* slim chance, but we might have eaten SIGTERM on the first iteration */
15087       if (jj > 0)
15088         count = jj;
15089
15090       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
15091              count, after - before, count / (after - before));
15092     }
15093   else
15094     {
15095       /* Wait for a reply... */
15096       W (ret);
15097       return ret;
15098     }
15099
15100   return ret;
15101 }
15102
15103 static void
15104 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15105 {
15106   vat_main_t *vam = &vat_main;
15107
15108   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15109          "crypto_key %U integ_alg %u integ_key %U flags %x "
15110          "tunnel_src_addr %U tunnel_dst_addr %U "
15111          "salt %u seq_outbound %lu last_seq_inbound %lu "
15112          "replay_window %lu\n",
15113          ntohl (mp->entry.sad_id),
15114          ntohl (mp->sw_if_index),
15115          ntohl (mp->entry.spi),
15116          ntohl (mp->entry.protocol),
15117          ntohl (mp->entry.crypto_algorithm),
15118          format_hex_bytes, mp->entry.crypto_key.data,
15119          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
15120          format_hex_bytes, mp->entry.integrity_key.data,
15121          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
15122          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
15123          &mp->entry.tunnel_dst, ntohl (mp->salt),
15124          clib_net_to_host_u64 (mp->seq_outbound),
15125          clib_net_to_host_u64 (mp->last_seq_inbound),
15126          clib_net_to_host_u64 (mp->replay_window));
15127 }
15128
15129 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15130 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15131
15132 static void vl_api_ipsec_sa_details_t_handler_json
15133   (vl_api_ipsec_sa_details_t * mp)
15134 {
15135   vat_main_t *vam = &vat_main;
15136   vat_json_node_t *node = NULL;
15137   vl_api_ipsec_sad_flags_t flags;
15138
15139   if (VAT_JSON_ARRAY != vam->json_tree.type)
15140     {
15141       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15142       vat_json_init_array (&vam->json_tree);
15143     }
15144   node = vat_json_array_add (&vam->json_tree);
15145
15146   vat_json_init_object (node);
15147   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
15148   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15149   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
15150   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
15151   vat_json_object_add_uint (node, "crypto_alg",
15152                             ntohl (mp->entry.crypto_algorithm));
15153   vat_json_object_add_uint (node, "integ_alg",
15154                             ntohl (mp->entry.integrity_algorithm));
15155   flags = ntohl (mp->entry.flags);
15156   vat_json_object_add_uint (node, "use_esn",
15157                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
15158   vat_json_object_add_uint (node, "use_anti_replay",
15159                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
15160   vat_json_object_add_uint (node, "is_tunnel",
15161                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
15162   vat_json_object_add_uint (node, "is_tunnel_ip6",
15163                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
15164   vat_json_object_add_uint (node, "udp_encap",
15165                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
15166   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
15167                              mp->entry.crypto_key.length);
15168   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
15169                              mp->entry.integrity_key.length);
15170   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
15171   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
15172   vat_json_object_add_uint (node, "replay_window",
15173                             clib_net_to_host_u64 (mp->replay_window));
15174 }
15175
15176 static int
15177 api_ipsec_sa_dump (vat_main_t * vam)
15178 {
15179   unformat_input_t *i = vam->input;
15180   vl_api_ipsec_sa_dump_t *mp;
15181   vl_api_control_ping_t *mp_ping;
15182   u32 sa_id = ~0;
15183   int ret;
15184
15185   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15186     {
15187       if (unformat (i, "sa_id %d", &sa_id))
15188         ;
15189       else
15190         {
15191           clib_warning ("parse error '%U'", format_unformat_error, i);
15192           return -99;
15193         }
15194     }
15195
15196   M (IPSEC_SA_DUMP, mp);
15197
15198   mp->sa_id = ntohl (sa_id);
15199
15200   S (mp);
15201
15202   /* Use a control ping for synchronization */
15203   M (CONTROL_PING, mp_ping);
15204   S (mp_ping);
15205
15206   W (ret);
15207   return ret;
15208 }
15209
15210 static int
15211 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15212 {
15213   unformat_input_t *i = vam->input;
15214   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15215   u32 sw_if_index = ~0;
15216   u32 sa_id = ~0;
15217   u8 is_outbound = (u8) ~ 0;
15218   int ret;
15219
15220   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15221     {
15222       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15223         ;
15224       else if (unformat (i, "sa_id %d", &sa_id))
15225         ;
15226       else if (unformat (i, "outbound"))
15227         is_outbound = 1;
15228       else if (unformat (i, "inbound"))
15229         is_outbound = 0;
15230       else
15231         {
15232           clib_warning ("parse error '%U'", format_unformat_error, i);
15233           return -99;
15234         }
15235     }
15236
15237   if (sw_if_index == ~0)
15238     {
15239       errmsg ("interface must be specified");
15240       return -99;
15241     }
15242
15243   if (sa_id == ~0)
15244     {
15245       errmsg ("SA ID must be specified");
15246       return -99;
15247     }
15248
15249   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15250
15251   mp->sw_if_index = htonl (sw_if_index);
15252   mp->sa_id = htonl (sa_id);
15253   mp->is_outbound = is_outbound;
15254
15255   S (mp);
15256   W (ret);
15257
15258   return ret;
15259 }
15260
15261 static int
15262 api_get_first_msg_id (vat_main_t * vam)
15263 {
15264   vl_api_get_first_msg_id_t *mp;
15265   unformat_input_t *i = vam->input;
15266   u8 *name;
15267   u8 name_set = 0;
15268   int ret;
15269
15270   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15271     {
15272       if (unformat (i, "client %s", &name))
15273         name_set = 1;
15274       else
15275         break;
15276     }
15277
15278   if (name_set == 0)
15279     {
15280       errmsg ("missing client name");
15281       return -99;
15282     }
15283   vec_add1 (name, 0);
15284
15285   if (vec_len (name) > 63)
15286     {
15287       errmsg ("client name too long");
15288       return -99;
15289     }
15290
15291   M (GET_FIRST_MSG_ID, mp);
15292   clib_memcpy (mp->name, name, vec_len (name));
15293   S (mp);
15294   W (ret);
15295   return ret;
15296 }
15297
15298 static int
15299 api_cop_interface_enable_disable (vat_main_t * vam)
15300 {
15301   unformat_input_t *line_input = vam->input;
15302   vl_api_cop_interface_enable_disable_t *mp;
15303   u32 sw_if_index = ~0;
15304   u8 enable_disable = 1;
15305   int ret;
15306
15307   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15308     {
15309       if (unformat (line_input, "disable"))
15310         enable_disable = 0;
15311       if (unformat (line_input, "enable"))
15312         enable_disable = 1;
15313       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15314                          vam, &sw_if_index))
15315         ;
15316       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15317         ;
15318       else
15319         break;
15320     }
15321
15322   if (sw_if_index == ~0)
15323     {
15324       errmsg ("missing interface name or sw_if_index");
15325       return -99;
15326     }
15327
15328   /* Construct the API message */
15329   M (COP_INTERFACE_ENABLE_DISABLE, mp);
15330   mp->sw_if_index = ntohl (sw_if_index);
15331   mp->enable_disable = enable_disable;
15332
15333   /* send it... */
15334   S (mp);
15335   /* Wait for the reply */
15336   W (ret);
15337   return ret;
15338 }
15339
15340 static int
15341 api_cop_whitelist_enable_disable (vat_main_t * vam)
15342 {
15343   unformat_input_t *line_input = vam->input;
15344   vl_api_cop_whitelist_enable_disable_t *mp;
15345   u32 sw_if_index = ~0;
15346   u8 ip4 = 0, ip6 = 0, default_cop = 0;
15347   u32 fib_id = 0;
15348   int ret;
15349
15350   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15351     {
15352       if (unformat (line_input, "ip4"))
15353         ip4 = 1;
15354       else if (unformat (line_input, "ip6"))
15355         ip6 = 1;
15356       else if (unformat (line_input, "default"))
15357         default_cop = 1;
15358       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15359                          vam, &sw_if_index))
15360         ;
15361       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15362         ;
15363       else if (unformat (line_input, "fib-id %d", &fib_id))
15364         ;
15365       else
15366         break;
15367     }
15368
15369   if (sw_if_index == ~0)
15370     {
15371       errmsg ("missing interface name or sw_if_index");
15372       return -99;
15373     }
15374
15375   /* Construct the API message */
15376   M (COP_WHITELIST_ENABLE_DISABLE, mp);
15377   mp->sw_if_index = ntohl (sw_if_index);
15378   mp->fib_id = ntohl (fib_id);
15379   mp->ip4 = ip4;
15380   mp->ip6 = ip6;
15381   mp->default_cop = default_cop;
15382
15383   /* send it... */
15384   S (mp);
15385   /* Wait for the reply */
15386   W (ret);
15387   return ret;
15388 }
15389
15390 static int
15391 api_get_node_graph (vat_main_t * vam)
15392 {
15393   vl_api_get_node_graph_t *mp;
15394   int ret;
15395
15396   M (GET_NODE_GRAPH, mp);
15397
15398   /* send it... */
15399   S (mp);
15400   /* Wait for the reply */
15401   W (ret);
15402   return ret;
15403 }
15404
15405 /* *INDENT-OFF* */
15406 /** Used for parsing LISP eids */
15407 typedef CLIB_PACKED(struct{
15408   u8 addr[16];   /**< eid address */
15409   u32 len;       /**< prefix length if IP */
15410   u8 type;      /**< type of eid */
15411 }) lisp_eid_vat_t;
15412 /* *INDENT-ON* */
15413
15414 static uword
15415 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
15416 {
15417   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
15418
15419   clib_memset (a, 0, sizeof (a[0]));
15420
15421   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
15422     {
15423       a->type = 0;              /* ipv4 type */
15424     }
15425   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
15426     {
15427       a->type = 1;              /* ipv6 type */
15428     }
15429   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
15430     {
15431       a->type = 2;              /* mac type */
15432     }
15433   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
15434     {
15435       a->type = 3;              /* NSH type */
15436       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
15437       nsh->spi = clib_host_to_net_u32 (nsh->spi);
15438     }
15439   else
15440     {
15441       return 0;
15442     }
15443
15444   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
15445     {
15446       return 0;
15447     }
15448
15449   return 1;
15450 }
15451
15452 static int
15453 lisp_eid_size_vat (u8 type)
15454 {
15455   switch (type)
15456     {
15457     case 0:
15458       return 4;
15459     case 1:
15460       return 16;
15461     case 2:
15462       return 6;
15463     case 3:
15464       return 5;
15465     }
15466   return 0;
15467 }
15468
15469 static void
15470 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
15471 {
15472   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
15473 }
15474
15475 static int
15476 api_one_add_del_locator_set (vat_main_t * vam)
15477 {
15478   unformat_input_t *input = vam->input;
15479   vl_api_one_add_del_locator_set_t *mp;
15480   u8 is_add = 1;
15481   u8 *locator_set_name = NULL;
15482   u8 locator_set_name_set = 0;
15483   vl_api_local_locator_t locator, *locators = 0;
15484   u32 sw_if_index, priority, weight;
15485   u32 data_len = 0;
15486
15487   int ret;
15488   /* Parse args required to build the message */
15489   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15490     {
15491       if (unformat (input, "del"))
15492         {
15493           is_add = 0;
15494         }
15495       else if (unformat (input, "locator-set %s", &locator_set_name))
15496         {
15497           locator_set_name_set = 1;
15498         }
15499       else if (unformat (input, "sw_if_index %u p %u w %u",
15500                          &sw_if_index, &priority, &weight))
15501         {
15502           locator.sw_if_index = htonl (sw_if_index);
15503           locator.priority = priority;
15504           locator.weight = weight;
15505           vec_add1 (locators, locator);
15506         }
15507       else
15508         if (unformat
15509             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
15510              &sw_if_index, &priority, &weight))
15511         {
15512           locator.sw_if_index = htonl (sw_if_index);
15513           locator.priority = priority;
15514           locator.weight = weight;
15515           vec_add1 (locators, locator);
15516         }
15517       else
15518         break;
15519     }
15520
15521   if (locator_set_name_set == 0)
15522     {
15523       errmsg ("missing locator-set name");
15524       vec_free (locators);
15525       return -99;
15526     }
15527
15528   if (vec_len (locator_set_name) > 64)
15529     {
15530       errmsg ("locator-set name too long");
15531       vec_free (locator_set_name);
15532       vec_free (locators);
15533       return -99;
15534     }
15535   vec_add1 (locator_set_name, 0);
15536
15537   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
15538
15539   /* Construct the API message */
15540   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
15541
15542   mp->is_add = is_add;
15543   clib_memcpy (mp->locator_set_name, locator_set_name,
15544                vec_len (locator_set_name));
15545   vec_free (locator_set_name);
15546
15547   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
15548   if (locators)
15549     clib_memcpy (mp->locators, locators, data_len);
15550   vec_free (locators);
15551
15552   /* send it... */
15553   S (mp);
15554
15555   /* Wait for a reply... */
15556   W (ret);
15557   return ret;
15558 }
15559
15560 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
15561
15562 static int
15563 api_one_add_del_locator (vat_main_t * vam)
15564 {
15565   unformat_input_t *input = vam->input;
15566   vl_api_one_add_del_locator_t *mp;
15567   u32 tmp_if_index = ~0;
15568   u32 sw_if_index = ~0;
15569   u8 sw_if_index_set = 0;
15570   u8 sw_if_index_if_name_set = 0;
15571   u32 priority = ~0;
15572   u8 priority_set = 0;
15573   u32 weight = ~0;
15574   u8 weight_set = 0;
15575   u8 is_add = 1;
15576   u8 *locator_set_name = NULL;
15577   u8 locator_set_name_set = 0;
15578   int ret;
15579
15580   /* Parse args required to build the message */
15581   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15582     {
15583       if (unformat (input, "del"))
15584         {
15585           is_add = 0;
15586         }
15587       else if (unformat (input, "locator-set %s", &locator_set_name))
15588         {
15589           locator_set_name_set = 1;
15590         }
15591       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
15592                          &tmp_if_index))
15593         {
15594           sw_if_index_if_name_set = 1;
15595           sw_if_index = tmp_if_index;
15596         }
15597       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
15598         {
15599           sw_if_index_set = 1;
15600           sw_if_index = tmp_if_index;
15601         }
15602       else if (unformat (input, "p %d", &priority))
15603         {
15604           priority_set = 1;
15605         }
15606       else if (unformat (input, "w %d", &weight))
15607         {
15608           weight_set = 1;
15609         }
15610       else
15611         break;
15612     }
15613
15614   if (locator_set_name_set == 0)
15615     {
15616       errmsg ("missing locator-set name");
15617       return -99;
15618     }
15619
15620   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
15621     {
15622       errmsg ("missing sw_if_index");
15623       vec_free (locator_set_name);
15624       return -99;
15625     }
15626
15627   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
15628     {
15629       errmsg ("cannot use both params interface name and sw_if_index");
15630       vec_free (locator_set_name);
15631       return -99;
15632     }
15633
15634   if (priority_set == 0)
15635     {
15636       errmsg ("missing locator-set priority");
15637       vec_free (locator_set_name);
15638       return -99;
15639     }
15640
15641   if (weight_set == 0)
15642     {
15643       errmsg ("missing locator-set weight");
15644       vec_free (locator_set_name);
15645       return -99;
15646     }
15647
15648   if (vec_len (locator_set_name) > 64)
15649     {
15650       errmsg ("locator-set name too long");
15651       vec_free (locator_set_name);
15652       return -99;
15653     }
15654   vec_add1 (locator_set_name, 0);
15655
15656   /* Construct the API message */
15657   M (ONE_ADD_DEL_LOCATOR, mp);
15658
15659   mp->is_add = is_add;
15660   mp->sw_if_index = ntohl (sw_if_index);
15661   mp->priority = priority;
15662   mp->weight = weight;
15663   clib_memcpy (mp->locator_set_name, locator_set_name,
15664                vec_len (locator_set_name));
15665   vec_free (locator_set_name);
15666
15667   /* send it... */
15668   S (mp);
15669
15670   /* Wait for a reply... */
15671   W (ret);
15672   return ret;
15673 }
15674
15675 #define api_lisp_add_del_locator api_one_add_del_locator
15676
15677 uword
15678 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15679 {
15680   u32 *key_id = va_arg (*args, u32 *);
15681   u8 *s = 0;
15682
15683   if (unformat (input, "%s", &s))
15684     {
15685       if (!strcmp ((char *) s, "sha1"))
15686         key_id[0] = HMAC_SHA_1_96;
15687       else if (!strcmp ((char *) s, "sha256"))
15688         key_id[0] = HMAC_SHA_256_128;
15689       else
15690         {
15691           clib_warning ("invalid key_id: '%s'", s);
15692           key_id[0] = HMAC_NO_KEY;
15693         }
15694     }
15695   else
15696     return 0;
15697
15698   vec_free (s);
15699   return 1;
15700 }
15701
15702 static int
15703 api_one_add_del_local_eid (vat_main_t * vam)
15704 {
15705   unformat_input_t *input = vam->input;
15706   vl_api_one_add_del_local_eid_t *mp;
15707   u8 is_add = 1;
15708   u8 eid_set = 0;
15709   lisp_eid_vat_t _eid, *eid = &_eid;
15710   u8 *locator_set_name = 0;
15711   u8 locator_set_name_set = 0;
15712   u32 vni = 0;
15713   u16 key_id = 0;
15714   u8 *key = 0;
15715   int ret;
15716
15717   /* Parse args required to build the message */
15718   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15719     {
15720       if (unformat (input, "del"))
15721         {
15722           is_add = 0;
15723         }
15724       else if (unformat (input, "vni %d", &vni))
15725         {
15726           ;
15727         }
15728       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15729         {
15730           eid_set = 1;
15731         }
15732       else if (unformat (input, "locator-set %s", &locator_set_name))
15733         {
15734           locator_set_name_set = 1;
15735         }
15736       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15737         ;
15738       else if (unformat (input, "secret-key %_%v%_", &key))
15739         ;
15740       else
15741         break;
15742     }
15743
15744   if (locator_set_name_set == 0)
15745     {
15746       errmsg ("missing locator-set name");
15747       return -99;
15748     }
15749
15750   if (0 == eid_set)
15751     {
15752       errmsg ("EID address not set!");
15753       vec_free (locator_set_name);
15754       return -99;
15755     }
15756
15757   if (key && (0 == key_id))
15758     {
15759       errmsg ("invalid key_id!");
15760       return -99;
15761     }
15762
15763   if (vec_len (key) > 64)
15764     {
15765       errmsg ("key too long");
15766       vec_free (key);
15767       return -99;
15768     }
15769
15770   if (vec_len (locator_set_name) > 64)
15771     {
15772       errmsg ("locator-set name too long");
15773       vec_free (locator_set_name);
15774       return -99;
15775     }
15776   vec_add1 (locator_set_name, 0);
15777
15778   /* Construct the API message */
15779   M (ONE_ADD_DEL_LOCAL_EID, mp);
15780
15781   mp->is_add = is_add;
15782   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15783   mp->eid_type = eid->type;
15784   mp->prefix_len = eid->len;
15785   mp->vni = clib_host_to_net_u32 (vni);
15786   mp->key_id = clib_host_to_net_u16 (key_id);
15787   clib_memcpy (mp->locator_set_name, locator_set_name,
15788                vec_len (locator_set_name));
15789   clib_memcpy (mp->key, key, vec_len (key));
15790
15791   vec_free (locator_set_name);
15792   vec_free (key);
15793
15794   /* send it... */
15795   S (mp);
15796
15797   /* Wait for a reply... */
15798   W (ret);
15799   return ret;
15800 }
15801
15802 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15803
15804 static int
15805 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
15806 {
15807   u32 dp_table = 0, vni = 0;;
15808   unformat_input_t *input = vam->input;
15809   vl_api_gpe_add_del_fwd_entry_t *mp;
15810   u8 is_add = 1;
15811   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
15812   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
15813   u8 rmt_eid_set = 0, lcl_eid_set = 0;
15814   u32 action = ~0, w;
15815   ip4_address_t rmt_rloc4, lcl_rloc4;
15816   ip6_address_t rmt_rloc6, lcl_rloc6;
15817   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
15818   int ret;
15819
15820   clib_memset (&rloc, 0, sizeof (rloc));
15821
15822   /* Parse args required to build the message */
15823   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15824     {
15825       if (unformat (input, "del"))
15826         is_add = 0;
15827       else if (unformat (input, "add"))
15828         is_add = 1;
15829       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
15830         {
15831           rmt_eid_set = 1;
15832         }
15833       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
15834         {
15835           lcl_eid_set = 1;
15836         }
15837       else if (unformat (input, "vrf %d", &dp_table))
15838         ;
15839       else if (unformat (input, "bd %d", &dp_table))
15840         ;
15841       else if (unformat (input, "vni %d", &vni))
15842         ;
15843       else if (unformat (input, "w %d", &w))
15844         {
15845           if (!curr_rloc)
15846             {
15847               errmsg ("No RLOC configured for setting priority/weight!");
15848               return -99;
15849             }
15850           curr_rloc->weight = w;
15851         }
15852       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
15853                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
15854         {
15855           rloc.is_ip4 = 1;
15856
15857           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
15858           rloc.weight = 0;
15859           vec_add1 (lcl_locs, rloc);
15860
15861           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
15862           vec_add1 (rmt_locs, rloc);
15863           /* weight saved in rmt loc */
15864           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15865         }
15866       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
15867                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
15868         {
15869           rloc.is_ip4 = 0;
15870           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
15871           rloc.weight = 0;
15872           vec_add1 (lcl_locs, rloc);
15873
15874           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
15875           vec_add1 (rmt_locs, rloc);
15876           /* weight saved in rmt loc */
15877           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15878         }
15879       else if (unformat (input, "action %d", &action))
15880         {
15881           ;
15882         }
15883       else
15884         {
15885           clib_warning ("parse error '%U'", format_unformat_error, input);
15886           return -99;
15887         }
15888     }
15889
15890   if (!rmt_eid_set)
15891     {
15892       errmsg ("remote eid addresses not set");
15893       return -99;
15894     }
15895
15896   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
15897     {
15898       errmsg ("eid types don't match");
15899       return -99;
15900     }
15901
15902   if (0 == rmt_locs && (u32) ~ 0 == action)
15903     {
15904       errmsg ("action not set for negative mapping");
15905       return -99;
15906     }
15907
15908   /* Construct the API message */
15909   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
15910       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
15911
15912   mp->is_add = is_add;
15913   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
15914   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
15915   mp->eid_type = rmt_eid->type;
15916   mp->dp_table = clib_host_to_net_u32 (dp_table);
15917   mp->vni = clib_host_to_net_u32 (vni);
15918   mp->rmt_len = rmt_eid->len;
15919   mp->lcl_len = lcl_eid->len;
15920   mp->action = action;
15921
15922   if (0 != rmt_locs && 0 != lcl_locs)
15923     {
15924       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
15925       clib_memcpy (mp->locs, lcl_locs,
15926                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
15927
15928       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
15929       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
15930                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
15931     }
15932   vec_free (lcl_locs);
15933   vec_free (rmt_locs);
15934
15935   /* send it... */
15936   S (mp);
15937
15938   /* Wait for a reply... */
15939   W (ret);
15940   return ret;
15941 }
15942
15943 static int
15944 api_one_add_del_map_server (vat_main_t * vam)
15945 {
15946   unformat_input_t *input = vam->input;
15947   vl_api_one_add_del_map_server_t *mp;
15948   u8 is_add = 1;
15949   u8 ipv4_set = 0;
15950   u8 ipv6_set = 0;
15951   ip4_address_t ipv4;
15952   ip6_address_t ipv6;
15953   int ret;
15954
15955   /* Parse args required to build the message */
15956   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15957     {
15958       if (unformat (input, "del"))
15959         {
15960           is_add = 0;
15961         }
15962       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15963         {
15964           ipv4_set = 1;
15965         }
15966       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15967         {
15968           ipv6_set = 1;
15969         }
15970       else
15971         break;
15972     }
15973
15974   if (ipv4_set && ipv6_set)
15975     {
15976       errmsg ("both eid v4 and v6 addresses set");
15977       return -99;
15978     }
15979
15980   if (!ipv4_set && !ipv6_set)
15981     {
15982       errmsg ("eid addresses not set");
15983       return -99;
15984     }
15985
15986   /* Construct the API message */
15987   M (ONE_ADD_DEL_MAP_SERVER, mp);
15988
15989   mp->is_add = is_add;
15990   if (ipv6_set)
15991     {
15992       mp->is_ipv6 = 1;
15993       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15994     }
15995   else
15996     {
15997       mp->is_ipv6 = 0;
15998       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15999     }
16000
16001   /* send it... */
16002   S (mp);
16003
16004   /* Wait for a reply... */
16005   W (ret);
16006   return ret;
16007 }
16008
16009 #define api_lisp_add_del_map_server api_one_add_del_map_server
16010
16011 static int
16012 api_one_add_del_map_resolver (vat_main_t * vam)
16013 {
16014   unformat_input_t *input = vam->input;
16015   vl_api_one_add_del_map_resolver_t *mp;
16016   u8 is_add = 1;
16017   u8 ipv4_set = 0;
16018   u8 ipv6_set = 0;
16019   ip4_address_t ipv4;
16020   ip6_address_t ipv6;
16021   int ret;
16022
16023   /* Parse args required to build the message */
16024   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16025     {
16026       if (unformat (input, "del"))
16027         {
16028           is_add = 0;
16029         }
16030       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16031         {
16032           ipv4_set = 1;
16033         }
16034       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16035         {
16036           ipv6_set = 1;
16037         }
16038       else
16039         break;
16040     }
16041
16042   if (ipv4_set && ipv6_set)
16043     {
16044       errmsg ("both eid v4 and v6 addresses set");
16045       return -99;
16046     }
16047
16048   if (!ipv4_set && !ipv6_set)
16049     {
16050       errmsg ("eid addresses not set");
16051       return -99;
16052     }
16053
16054   /* Construct the API message */
16055   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
16056
16057   mp->is_add = is_add;
16058   if (ipv6_set)
16059     {
16060       mp->is_ipv6 = 1;
16061       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16062     }
16063   else
16064     {
16065       mp->is_ipv6 = 0;
16066       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16067     }
16068
16069   /* send it... */
16070   S (mp);
16071
16072   /* Wait for a reply... */
16073   W (ret);
16074   return ret;
16075 }
16076
16077 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
16078
16079 static int
16080 api_lisp_gpe_enable_disable (vat_main_t * vam)
16081 {
16082   unformat_input_t *input = vam->input;
16083   vl_api_gpe_enable_disable_t *mp;
16084   u8 is_set = 0;
16085   u8 is_en = 1;
16086   int ret;
16087
16088   /* Parse args required to build the message */
16089   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16090     {
16091       if (unformat (input, "enable"))
16092         {
16093           is_set = 1;
16094           is_en = 1;
16095         }
16096       else if (unformat (input, "disable"))
16097         {
16098           is_set = 1;
16099           is_en = 0;
16100         }
16101       else
16102         break;
16103     }
16104
16105   if (is_set == 0)
16106     {
16107       errmsg ("Value not set");
16108       return -99;
16109     }
16110
16111   /* Construct the API message */
16112   M (GPE_ENABLE_DISABLE, mp);
16113
16114   mp->is_en = is_en;
16115
16116   /* send it... */
16117   S (mp);
16118
16119   /* Wait for a reply... */
16120   W (ret);
16121   return ret;
16122 }
16123
16124 static int
16125 api_one_rloc_probe_enable_disable (vat_main_t * vam)
16126 {
16127   unformat_input_t *input = vam->input;
16128   vl_api_one_rloc_probe_enable_disable_t *mp;
16129   u8 is_set = 0;
16130   u8 is_en = 0;
16131   int ret;
16132
16133   /* Parse args required to build the message */
16134   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16135     {
16136       if (unformat (input, "enable"))
16137         {
16138           is_set = 1;
16139           is_en = 1;
16140         }
16141       else if (unformat (input, "disable"))
16142         is_set = 1;
16143       else
16144         break;
16145     }
16146
16147   if (!is_set)
16148     {
16149       errmsg ("Value not set");
16150       return -99;
16151     }
16152
16153   /* Construct the API message */
16154   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
16155
16156   mp->is_enabled = is_en;
16157
16158   /* send it... */
16159   S (mp);
16160
16161   /* Wait for a reply... */
16162   W (ret);
16163   return ret;
16164 }
16165
16166 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
16167
16168 static int
16169 api_one_map_register_enable_disable (vat_main_t * vam)
16170 {
16171   unformat_input_t *input = vam->input;
16172   vl_api_one_map_register_enable_disable_t *mp;
16173   u8 is_set = 0;
16174   u8 is_en = 0;
16175   int ret;
16176
16177   /* Parse args required to build the message */
16178   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16179     {
16180       if (unformat (input, "enable"))
16181         {
16182           is_set = 1;
16183           is_en = 1;
16184         }
16185       else if (unformat (input, "disable"))
16186         is_set = 1;
16187       else
16188         break;
16189     }
16190
16191   if (!is_set)
16192     {
16193       errmsg ("Value not set");
16194       return -99;
16195     }
16196
16197   /* Construct the API message */
16198   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
16199
16200   mp->is_enabled = is_en;
16201
16202   /* send it... */
16203   S (mp);
16204
16205   /* Wait for a reply... */
16206   W (ret);
16207   return ret;
16208 }
16209
16210 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
16211
16212 static int
16213 api_one_enable_disable (vat_main_t * vam)
16214 {
16215   unformat_input_t *input = vam->input;
16216   vl_api_one_enable_disable_t *mp;
16217   u8 is_set = 0;
16218   u8 is_en = 0;
16219   int ret;
16220
16221   /* Parse args required to build the message */
16222   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16223     {
16224       if (unformat (input, "enable"))
16225         {
16226           is_set = 1;
16227           is_en = 1;
16228         }
16229       else if (unformat (input, "disable"))
16230         {
16231           is_set = 1;
16232         }
16233       else
16234         break;
16235     }
16236
16237   if (!is_set)
16238     {
16239       errmsg ("Value not set");
16240       return -99;
16241     }
16242
16243   /* Construct the API message */
16244   M (ONE_ENABLE_DISABLE, mp);
16245
16246   mp->is_en = is_en;
16247
16248   /* send it... */
16249   S (mp);
16250
16251   /* Wait for a reply... */
16252   W (ret);
16253   return ret;
16254 }
16255
16256 #define api_lisp_enable_disable api_one_enable_disable
16257
16258 static int
16259 api_one_enable_disable_xtr_mode (vat_main_t * vam)
16260 {
16261   unformat_input_t *input = vam->input;
16262   vl_api_one_enable_disable_xtr_mode_t *mp;
16263   u8 is_set = 0;
16264   u8 is_en = 0;
16265   int ret;
16266
16267   /* Parse args required to build the message */
16268   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16269     {
16270       if (unformat (input, "enable"))
16271         {
16272           is_set = 1;
16273           is_en = 1;
16274         }
16275       else if (unformat (input, "disable"))
16276         {
16277           is_set = 1;
16278         }
16279       else
16280         break;
16281     }
16282
16283   if (!is_set)
16284     {
16285       errmsg ("Value not set");
16286       return -99;
16287     }
16288
16289   /* Construct the API message */
16290   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
16291
16292   mp->is_en = is_en;
16293
16294   /* send it... */
16295   S (mp);
16296
16297   /* Wait for a reply... */
16298   W (ret);
16299   return ret;
16300 }
16301
16302 static int
16303 api_one_show_xtr_mode (vat_main_t * vam)
16304 {
16305   vl_api_one_show_xtr_mode_t *mp;
16306   int ret;
16307
16308   /* Construct the API message */
16309   M (ONE_SHOW_XTR_MODE, mp);
16310
16311   /* send it... */
16312   S (mp);
16313
16314   /* Wait for a reply... */
16315   W (ret);
16316   return ret;
16317 }
16318
16319 static int
16320 api_one_enable_disable_pitr_mode (vat_main_t * vam)
16321 {
16322   unformat_input_t *input = vam->input;
16323   vl_api_one_enable_disable_pitr_mode_t *mp;
16324   u8 is_set = 0;
16325   u8 is_en = 0;
16326   int ret;
16327
16328   /* Parse args required to build the message */
16329   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16330     {
16331       if (unformat (input, "enable"))
16332         {
16333           is_set = 1;
16334           is_en = 1;
16335         }
16336       else if (unformat (input, "disable"))
16337         {
16338           is_set = 1;
16339         }
16340       else
16341         break;
16342     }
16343
16344   if (!is_set)
16345     {
16346       errmsg ("Value not set");
16347       return -99;
16348     }
16349
16350   /* Construct the API message */
16351   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
16352
16353   mp->is_en = is_en;
16354
16355   /* send it... */
16356   S (mp);
16357
16358   /* Wait for a reply... */
16359   W (ret);
16360   return ret;
16361 }
16362
16363 static int
16364 api_one_show_pitr_mode (vat_main_t * vam)
16365 {
16366   vl_api_one_show_pitr_mode_t *mp;
16367   int ret;
16368
16369   /* Construct the API message */
16370   M (ONE_SHOW_PITR_MODE, mp);
16371
16372   /* send it... */
16373   S (mp);
16374
16375   /* Wait for a reply... */
16376   W (ret);
16377   return ret;
16378 }
16379
16380 static int
16381 api_one_enable_disable_petr_mode (vat_main_t * vam)
16382 {
16383   unformat_input_t *input = vam->input;
16384   vl_api_one_enable_disable_petr_mode_t *mp;
16385   u8 is_set = 0;
16386   u8 is_en = 0;
16387   int ret;
16388
16389   /* Parse args required to build the message */
16390   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16391     {
16392       if (unformat (input, "enable"))
16393         {
16394           is_set = 1;
16395           is_en = 1;
16396         }
16397       else if (unformat (input, "disable"))
16398         {
16399           is_set = 1;
16400         }
16401       else
16402         break;
16403     }
16404
16405   if (!is_set)
16406     {
16407       errmsg ("Value not set");
16408       return -99;
16409     }
16410
16411   /* Construct the API message */
16412   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
16413
16414   mp->is_en = is_en;
16415
16416   /* send it... */
16417   S (mp);
16418
16419   /* Wait for a reply... */
16420   W (ret);
16421   return ret;
16422 }
16423
16424 static int
16425 api_one_show_petr_mode (vat_main_t * vam)
16426 {
16427   vl_api_one_show_petr_mode_t *mp;
16428   int ret;
16429
16430   /* Construct the API message */
16431   M (ONE_SHOW_PETR_MODE, mp);
16432
16433   /* send it... */
16434   S (mp);
16435
16436   /* Wait for a reply... */
16437   W (ret);
16438   return ret;
16439 }
16440
16441 static int
16442 api_show_one_map_register_state (vat_main_t * vam)
16443 {
16444   vl_api_show_one_map_register_state_t *mp;
16445   int ret;
16446
16447   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
16448
16449   /* send */
16450   S (mp);
16451
16452   /* wait for reply */
16453   W (ret);
16454   return ret;
16455 }
16456
16457 #define api_show_lisp_map_register_state api_show_one_map_register_state
16458
16459 static int
16460 api_show_one_rloc_probe_state (vat_main_t * vam)
16461 {
16462   vl_api_show_one_rloc_probe_state_t *mp;
16463   int ret;
16464
16465   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
16466
16467   /* send */
16468   S (mp);
16469
16470   /* wait for reply */
16471   W (ret);
16472   return ret;
16473 }
16474
16475 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
16476
16477 static int
16478 api_one_add_del_ndp_entry (vat_main_t * vam)
16479 {
16480   vl_api_one_add_del_ndp_entry_t *mp;
16481   unformat_input_t *input = vam->input;
16482   u8 is_add = 1;
16483   u8 mac_set = 0;
16484   u8 bd_set = 0;
16485   u8 ip_set = 0;
16486   u8 mac[6] = { 0, };
16487   u8 ip6[16] = { 0, };
16488   u32 bd = ~0;
16489   int ret;
16490
16491   /* Parse args required to build the message */
16492   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16493     {
16494       if (unformat (input, "del"))
16495         is_add = 0;
16496       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16497         mac_set = 1;
16498       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
16499         ip_set = 1;
16500       else if (unformat (input, "bd %d", &bd))
16501         bd_set = 1;
16502       else
16503         {
16504           errmsg ("parse error '%U'", format_unformat_error, input);
16505           return -99;
16506         }
16507     }
16508
16509   if (!bd_set || !ip_set || (!mac_set && is_add))
16510     {
16511       errmsg ("Missing BD, IP or MAC!");
16512       return -99;
16513     }
16514
16515   M (ONE_ADD_DEL_NDP_ENTRY, mp);
16516   mp->is_add = is_add;
16517   clib_memcpy (mp->mac, mac, 6);
16518   mp->bd = clib_host_to_net_u32 (bd);
16519   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
16520
16521   /* send */
16522   S (mp);
16523
16524   /* wait for reply */
16525   W (ret);
16526   return ret;
16527 }
16528
16529 static int
16530 api_one_add_del_l2_arp_entry (vat_main_t * vam)
16531 {
16532   vl_api_one_add_del_l2_arp_entry_t *mp;
16533   unformat_input_t *input = vam->input;
16534   u8 is_add = 1;
16535   u8 mac_set = 0;
16536   u8 bd_set = 0;
16537   u8 ip_set = 0;
16538   u8 mac[6] = { 0, };
16539   u32 ip4 = 0, bd = ~0;
16540   int ret;
16541
16542   /* Parse args required to build the message */
16543   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16544     {
16545       if (unformat (input, "del"))
16546         is_add = 0;
16547       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16548         mac_set = 1;
16549       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
16550         ip_set = 1;
16551       else if (unformat (input, "bd %d", &bd))
16552         bd_set = 1;
16553       else
16554         {
16555           errmsg ("parse error '%U'", format_unformat_error, input);
16556           return -99;
16557         }
16558     }
16559
16560   if (!bd_set || !ip_set || (!mac_set && is_add))
16561     {
16562       errmsg ("Missing BD, IP or MAC!");
16563       return -99;
16564     }
16565
16566   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
16567   mp->is_add = is_add;
16568   clib_memcpy (mp->mac, mac, 6);
16569   mp->bd = clib_host_to_net_u32 (bd);
16570   mp->ip4 = ip4;
16571
16572   /* send */
16573   S (mp);
16574
16575   /* wait for reply */
16576   W (ret);
16577   return ret;
16578 }
16579
16580 static int
16581 api_one_ndp_bd_get (vat_main_t * vam)
16582 {
16583   vl_api_one_ndp_bd_get_t *mp;
16584   int ret;
16585
16586   M (ONE_NDP_BD_GET, mp);
16587
16588   /* send */
16589   S (mp);
16590
16591   /* wait for reply */
16592   W (ret);
16593   return ret;
16594 }
16595
16596 static int
16597 api_one_ndp_entries_get (vat_main_t * vam)
16598 {
16599   vl_api_one_ndp_entries_get_t *mp;
16600   unformat_input_t *input = vam->input;
16601   u8 bd_set = 0;
16602   u32 bd = ~0;
16603   int ret;
16604
16605   /* Parse args required to build the message */
16606   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16607     {
16608       if (unformat (input, "bd %d", &bd))
16609         bd_set = 1;
16610       else
16611         {
16612           errmsg ("parse error '%U'", format_unformat_error, input);
16613           return -99;
16614         }
16615     }
16616
16617   if (!bd_set)
16618     {
16619       errmsg ("Expected bridge domain!");
16620       return -99;
16621     }
16622
16623   M (ONE_NDP_ENTRIES_GET, mp);
16624   mp->bd = clib_host_to_net_u32 (bd);
16625
16626   /* send */
16627   S (mp);
16628
16629   /* wait for reply */
16630   W (ret);
16631   return ret;
16632 }
16633
16634 static int
16635 api_one_l2_arp_bd_get (vat_main_t * vam)
16636 {
16637   vl_api_one_l2_arp_bd_get_t *mp;
16638   int ret;
16639
16640   M (ONE_L2_ARP_BD_GET, mp);
16641
16642   /* send */
16643   S (mp);
16644
16645   /* wait for reply */
16646   W (ret);
16647   return ret;
16648 }
16649
16650 static int
16651 api_one_l2_arp_entries_get (vat_main_t * vam)
16652 {
16653   vl_api_one_l2_arp_entries_get_t *mp;
16654   unformat_input_t *input = vam->input;
16655   u8 bd_set = 0;
16656   u32 bd = ~0;
16657   int ret;
16658
16659   /* Parse args required to build the message */
16660   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16661     {
16662       if (unformat (input, "bd %d", &bd))
16663         bd_set = 1;
16664       else
16665         {
16666           errmsg ("parse error '%U'", format_unformat_error, input);
16667           return -99;
16668         }
16669     }
16670
16671   if (!bd_set)
16672     {
16673       errmsg ("Expected bridge domain!");
16674       return -99;
16675     }
16676
16677   M (ONE_L2_ARP_ENTRIES_GET, mp);
16678   mp->bd = clib_host_to_net_u32 (bd);
16679
16680   /* send */
16681   S (mp);
16682
16683   /* wait for reply */
16684   W (ret);
16685   return ret;
16686 }
16687
16688 static int
16689 api_one_stats_enable_disable (vat_main_t * vam)
16690 {
16691   vl_api_one_stats_enable_disable_t *mp;
16692   unformat_input_t *input = vam->input;
16693   u8 is_set = 0;
16694   u8 is_en = 0;
16695   int ret;
16696
16697   /* Parse args required to build the message */
16698   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16699     {
16700       if (unformat (input, "enable"))
16701         {
16702           is_set = 1;
16703           is_en = 1;
16704         }
16705       else if (unformat (input, "disable"))
16706         {
16707           is_set = 1;
16708         }
16709       else
16710         break;
16711     }
16712
16713   if (!is_set)
16714     {
16715       errmsg ("Value not set");
16716       return -99;
16717     }
16718
16719   M (ONE_STATS_ENABLE_DISABLE, mp);
16720   mp->is_en = is_en;
16721
16722   /* send */
16723   S (mp);
16724
16725   /* wait for reply */
16726   W (ret);
16727   return ret;
16728 }
16729
16730 static int
16731 api_show_one_stats_enable_disable (vat_main_t * vam)
16732 {
16733   vl_api_show_one_stats_enable_disable_t *mp;
16734   int ret;
16735
16736   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16737
16738   /* send */
16739   S (mp);
16740
16741   /* wait for reply */
16742   W (ret);
16743   return ret;
16744 }
16745
16746 static int
16747 api_show_one_map_request_mode (vat_main_t * vam)
16748 {
16749   vl_api_show_one_map_request_mode_t *mp;
16750   int ret;
16751
16752   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16753
16754   /* send */
16755   S (mp);
16756
16757   /* wait for reply */
16758   W (ret);
16759   return ret;
16760 }
16761
16762 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16763
16764 static int
16765 api_one_map_request_mode (vat_main_t * vam)
16766 {
16767   unformat_input_t *input = vam->input;
16768   vl_api_one_map_request_mode_t *mp;
16769   u8 mode = 0;
16770   int ret;
16771
16772   /* Parse args required to build the message */
16773   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16774     {
16775       if (unformat (input, "dst-only"))
16776         mode = 0;
16777       else if (unformat (input, "src-dst"))
16778         mode = 1;
16779       else
16780         {
16781           errmsg ("parse error '%U'", format_unformat_error, input);
16782           return -99;
16783         }
16784     }
16785
16786   M (ONE_MAP_REQUEST_MODE, mp);
16787
16788   mp->mode = mode;
16789
16790   /* send */
16791   S (mp);
16792
16793   /* wait for reply */
16794   W (ret);
16795   return ret;
16796 }
16797
16798 #define api_lisp_map_request_mode api_one_map_request_mode
16799
16800 /**
16801  * Enable/disable ONE proxy ITR.
16802  *
16803  * @param vam vpp API test context
16804  * @return return code
16805  */
16806 static int
16807 api_one_pitr_set_locator_set (vat_main_t * vam)
16808 {
16809   u8 ls_name_set = 0;
16810   unformat_input_t *input = vam->input;
16811   vl_api_one_pitr_set_locator_set_t *mp;
16812   u8 is_add = 1;
16813   u8 *ls_name = 0;
16814   int ret;
16815
16816   /* Parse args required to build the message */
16817   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16818     {
16819       if (unformat (input, "del"))
16820         is_add = 0;
16821       else if (unformat (input, "locator-set %s", &ls_name))
16822         ls_name_set = 1;
16823       else
16824         {
16825           errmsg ("parse error '%U'", format_unformat_error, input);
16826           return -99;
16827         }
16828     }
16829
16830   if (!ls_name_set)
16831     {
16832       errmsg ("locator-set name not set!");
16833       return -99;
16834     }
16835
16836   M (ONE_PITR_SET_LOCATOR_SET, mp);
16837
16838   mp->is_add = is_add;
16839   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16840   vec_free (ls_name);
16841
16842   /* send */
16843   S (mp);
16844
16845   /* wait for reply */
16846   W (ret);
16847   return ret;
16848 }
16849
16850 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
16851
16852 static int
16853 api_one_nsh_set_locator_set (vat_main_t * vam)
16854 {
16855   u8 ls_name_set = 0;
16856   unformat_input_t *input = vam->input;
16857   vl_api_one_nsh_set_locator_set_t *mp;
16858   u8 is_add = 1;
16859   u8 *ls_name = 0;
16860   int ret;
16861
16862   /* Parse args required to build the message */
16863   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16864     {
16865       if (unformat (input, "del"))
16866         is_add = 0;
16867       else if (unformat (input, "ls %s", &ls_name))
16868         ls_name_set = 1;
16869       else
16870         {
16871           errmsg ("parse error '%U'", format_unformat_error, input);
16872           return -99;
16873         }
16874     }
16875
16876   if (!ls_name_set && is_add)
16877     {
16878       errmsg ("locator-set name not set!");
16879       return -99;
16880     }
16881
16882   M (ONE_NSH_SET_LOCATOR_SET, mp);
16883
16884   mp->is_add = is_add;
16885   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16886   vec_free (ls_name);
16887
16888   /* send */
16889   S (mp);
16890
16891   /* wait for reply */
16892   W (ret);
16893   return ret;
16894 }
16895
16896 static int
16897 api_show_one_pitr (vat_main_t * vam)
16898 {
16899   vl_api_show_one_pitr_t *mp;
16900   int ret;
16901
16902   if (!vam->json_output)
16903     {
16904       print (vam->ofp, "%=20s", "lisp status:");
16905     }
16906
16907   M (SHOW_ONE_PITR, mp);
16908   /* send it... */
16909   S (mp);
16910
16911   /* Wait for a reply... */
16912   W (ret);
16913   return ret;
16914 }
16915
16916 #define api_show_lisp_pitr api_show_one_pitr
16917
16918 static int
16919 api_one_use_petr (vat_main_t * vam)
16920 {
16921   unformat_input_t *input = vam->input;
16922   vl_api_one_use_petr_t *mp;
16923   u8 is_add = 0;
16924   ip_address_t ip;
16925   int ret;
16926
16927   clib_memset (&ip, 0, sizeof (ip));
16928
16929   /* Parse args required to build the message */
16930   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16931     {
16932       if (unformat (input, "disable"))
16933         is_add = 0;
16934       else
16935         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
16936         {
16937           is_add = 1;
16938           ip_addr_version (&ip) = IP4;
16939         }
16940       else
16941         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
16942         {
16943           is_add = 1;
16944           ip_addr_version (&ip) = IP6;
16945         }
16946       else
16947         {
16948           errmsg ("parse error '%U'", format_unformat_error, input);
16949           return -99;
16950         }
16951     }
16952
16953   M (ONE_USE_PETR, mp);
16954
16955   mp->is_add = is_add;
16956   if (is_add)
16957     {
16958       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
16959       if (mp->is_ip4)
16960         clib_memcpy (mp->address, &ip, 4);
16961       else
16962         clib_memcpy (mp->address, &ip, 16);
16963     }
16964
16965   /* send */
16966   S (mp);
16967
16968   /* wait for reply */
16969   W (ret);
16970   return ret;
16971 }
16972
16973 #define api_lisp_use_petr api_one_use_petr
16974
16975 static int
16976 api_show_one_nsh_mapping (vat_main_t * vam)
16977 {
16978   vl_api_show_one_use_petr_t *mp;
16979   int ret;
16980
16981   if (!vam->json_output)
16982     {
16983       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
16984     }
16985
16986   M (SHOW_ONE_NSH_MAPPING, mp);
16987   /* send it... */
16988   S (mp);
16989
16990   /* Wait for a reply... */
16991   W (ret);
16992   return ret;
16993 }
16994
16995 static int
16996 api_show_one_use_petr (vat_main_t * vam)
16997 {
16998   vl_api_show_one_use_petr_t *mp;
16999   int ret;
17000
17001   if (!vam->json_output)
17002     {
17003       print (vam->ofp, "%=20s", "Proxy-ETR status:");
17004     }
17005
17006   M (SHOW_ONE_USE_PETR, mp);
17007   /* send it... */
17008   S (mp);
17009
17010   /* Wait for a reply... */
17011   W (ret);
17012   return ret;
17013 }
17014
17015 #define api_show_lisp_use_petr api_show_one_use_petr
17016
17017 /**
17018  * Add/delete mapping between vni and vrf
17019  */
17020 static int
17021 api_one_eid_table_add_del_map (vat_main_t * vam)
17022 {
17023   unformat_input_t *input = vam->input;
17024   vl_api_one_eid_table_add_del_map_t *mp;
17025   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
17026   u32 vni, vrf, bd_index;
17027   int ret;
17028
17029   /* Parse args required to build the message */
17030   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17031     {
17032       if (unformat (input, "del"))
17033         is_add = 0;
17034       else if (unformat (input, "vrf %d", &vrf))
17035         vrf_set = 1;
17036       else if (unformat (input, "bd_index %d", &bd_index))
17037         bd_index_set = 1;
17038       else if (unformat (input, "vni %d", &vni))
17039         vni_set = 1;
17040       else
17041         break;
17042     }
17043
17044   if (!vni_set || (!vrf_set && !bd_index_set))
17045     {
17046       errmsg ("missing arguments!");
17047       return -99;
17048     }
17049
17050   if (vrf_set && bd_index_set)
17051     {
17052       errmsg ("error: both vrf and bd entered!");
17053       return -99;
17054     }
17055
17056   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
17057
17058   mp->is_add = is_add;
17059   mp->vni = htonl (vni);
17060   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
17061   mp->is_l2 = bd_index_set;
17062
17063   /* send */
17064   S (mp);
17065
17066   /* wait for reply */
17067   W (ret);
17068   return ret;
17069 }
17070
17071 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
17072
17073 uword
17074 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
17075 {
17076   u32 *action = va_arg (*args, u32 *);
17077   u8 *s = 0;
17078
17079   if (unformat (input, "%s", &s))
17080     {
17081       if (!strcmp ((char *) s, "no-action"))
17082         action[0] = 0;
17083       else if (!strcmp ((char *) s, "natively-forward"))
17084         action[0] = 1;
17085       else if (!strcmp ((char *) s, "send-map-request"))
17086         action[0] = 2;
17087       else if (!strcmp ((char *) s, "drop"))
17088         action[0] = 3;
17089       else
17090         {
17091           clib_warning ("invalid action: '%s'", s);
17092           action[0] = 3;
17093         }
17094     }
17095   else
17096     return 0;
17097
17098   vec_free (s);
17099   return 1;
17100 }
17101
17102 /**
17103  * Add/del remote mapping to/from ONE control plane
17104  *
17105  * @param vam vpp API test context
17106  * @return return code
17107  */
17108 static int
17109 api_one_add_del_remote_mapping (vat_main_t * vam)
17110 {
17111   unformat_input_t *input = vam->input;
17112   vl_api_one_add_del_remote_mapping_t *mp;
17113   u32 vni = 0;
17114   lisp_eid_vat_t _eid, *eid = &_eid;
17115   lisp_eid_vat_t _seid, *seid = &_seid;
17116   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
17117   u32 action = ~0, p, w, data_len;
17118   ip4_address_t rloc4;
17119   ip6_address_t rloc6;
17120   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
17121   int ret;
17122
17123   clib_memset (&rloc, 0, sizeof (rloc));
17124
17125   /* Parse args required to build the message */
17126   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17127     {
17128       if (unformat (input, "del-all"))
17129         {
17130           del_all = 1;
17131         }
17132       else if (unformat (input, "del"))
17133         {
17134           is_add = 0;
17135         }
17136       else if (unformat (input, "add"))
17137         {
17138           is_add = 1;
17139         }
17140       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17141         {
17142           eid_set = 1;
17143         }
17144       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
17145         {
17146           seid_set = 1;
17147         }
17148       else if (unformat (input, "vni %d", &vni))
17149         {
17150           ;
17151         }
17152       else if (unformat (input, "p %d w %d", &p, &w))
17153         {
17154           if (!curr_rloc)
17155             {
17156               errmsg ("No RLOC configured for setting priority/weight!");
17157               return -99;
17158             }
17159           curr_rloc->priority = p;
17160           curr_rloc->weight = w;
17161         }
17162       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
17163         {
17164           rloc.is_ip4 = 1;
17165           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
17166           vec_add1 (rlocs, rloc);
17167           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17168         }
17169       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
17170         {
17171           rloc.is_ip4 = 0;
17172           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
17173           vec_add1 (rlocs, rloc);
17174           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17175         }
17176       else if (unformat (input, "action %U",
17177                          unformat_negative_mapping_action, &action))
17178         {
17179           ;
17180         }
17181       else
17182         {
17183           clib_warning ("parse error '%U'", format_unformat_error, input);
17184           return -99;
17185         }
17186     }
17187
17188   if (0 == eid_set)
17189     {
17190       errmsg ("missing params!");
17191       return -99;
17192     }
17193
17194   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
17195     {
17196       errmsg ("no action set for negative map-reply!");
17197       return -99;
17198     }
17199
17200   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
17201
17202   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
17203   mp->is_add = is_add;
17204   mp->vni = htonl (vni);
17205   mp->action = (u8) action;
17206   mp->is_src_dst = seid_set;
17207   mp->eid_len = eid->len;
17208   mp->seid_len = seid->len;
17209   mp->del_all = del_all;
17210   mp->eid_type = eid->type;
17211   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17212   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
17213
17214   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
17215   clib_memcpy (mp->rlocs, rlocs, data_len);
17216   vec_free (rlocs);
17217
17218   /* send it... */
17219   S (mp);
17220
17221   /* Wait for a reply... */
17222   W (ret);
17223   return ret;
17224 }
17225
17226 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
17227
17228 /**
17229  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
17230  * forwarding entries in data-plane accordingly.
17231  *
17232  * @param vam vpp API test context
17233  * @return return code
17234  */
17235 static int
17236 api_one_add_del_adjacency (vat_main_t * vam)
17237 {
17238   unformat_input_t *input = vam->input;
17239   vl_api_one_add_del_adjacency_t *mp;
17240   u32 vni = 0;
17241   ip4_address_t leid4, reid4;
17242   ip6_address_t leid6, reid6;
17243   u8 reid_mac[6] = { 0 };
17244   u8 leid_mac[6] = { 0 };
17245   u8 reid_type, leid_type;
17246   u32 leid_len = 0, reid_len = 0, len;
17247   u8 is_add = 1;
17248   int ret;
17249
17250   leid_type = reid_type = (u8) ~ 0;
17251
17252   /* Parse args required to build the message */
17253   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17254     {
17255       if (unformat (input, "del"))
17256         {
17257           is_add = 0;
17258         }
17259       else if (unformat (input, "add"))
17260         {
17261           is_add = 1;
17262         }
17263       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
17264                          &reid4, &len))
17265         {
17266           reid_type = 0;        /* ipv4 */
17267           reid_len = len;
17268         }
17269       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
17270                          &reid6, &len))
17271         {
17272           reid_type = 1;        /* ipv6 */
17273           reid_len = len;
17274         }
17275       else if (unformat (input, "reid %U", unformat_ethernet_address,
17276                          reid_mac))
17277         {
17278           reid_type = 2;        /* mac */
17279         }
17280       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
17281                          &leid4, &len))
17282         {
17283           leid_type = 0;        /* ipv4 */
17284           leid_len = len;
17285         }
17286       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17287                          &leid6, &len))
17288         {
17289           leid_type = 1;        /* ipv6 */
17290           leid_len = len;
17291         }
17292       else if (unformat (input, "leid %U", unformat_ethernet_address,
17293                          leid_mac))
17294         {
17295           leid_type = 2;        /* mac */
17296         }
17297       else if (unformat (input, "vni %d", &vni))
17298         {
17299           ;
17300         }
17301       else
17302         {
17303           errmsg ("parse error '%U'", format_unformat_error, input);
17304           return -99;
17305         }
17306     }
17307
17308   if ((u8) ~ 0 == reid_type)
17309     {
17310       errmsg ("missing params!");
17311       return -99;
17312     }
17313
17314   if (leid_type != reid_type)
17315     {
17316       errmsg ("remote and local EIDs are of different types!");
17317       return -99;
17318     }
17319
17320   M (ONE_ADD_DEL_ADJACENCY, mp);
17321   mp->is_add = is_add;
17322   mp->vni = htonl (vni);
17323   mp->leid_len = leid_len;
17324   mp->reid_len = reid_len;
17325   mp->eid_type = reid_type;
17326
17327   switch (mp->eid_type)
17328     {
17329     case 0:
17330       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
17331       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
17332       break;
17333     case 1:
17334       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
17335       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
17336       break;
17337     case 2:
17338       clib_memcpy (mp->leid, leid_mac, 6);
17339       clib_memcpy (mp->reid, reid_mac, 6);
17340       break;
17341     default:
17342       errmsg ("unknown EID type %d!", mp->eid_type);
17343       return 0;
17344     }
17345
17346   /* send it... */
17347   S (mp);
17348
17349   /* Wait for a reply... */
17350   W (ret);
17351   return ret;
17352 }
17353
17354 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
17355
17356 uword
17357 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
17358 {
17359   u32 *mode = va_arg (*args, u32 *);
17360
17361   if (unformat (input, "lisp"))
17362     *mode = 0;
17363   else if (unformat (input, "vxlan"))
17364     *mode = 1;
17365   else
17366     return 0;
17367
17368   return 1;
17369 }
17370
17371 static int
17372 api_gpe_get_encap_mode (vat_main_t * vam)
17373 {
17374   vl_api_gpe_get_encap_mode_t *mp;
17375   int ret;
17376
17377   /* Construct the API message */
17378   M (GPE_GET_ENCAP_MODE, mp);
17379
17380   /* send it... */
17381   S (mp);
17382
17383   /* Wait for a reply... */
17384   W (ret);
17385   return ret;
17386 }
17387
17388 static int
17389 api_gpe_set_encap_mode (vat_main_t * vam)
17390 {
17391   unformat_input_t *input = vam->input;
17392   vl_api_gpe_set_encap_mode_t *mp;
17393   int ret;
17394   u32 mode = 0;
17395
17396   /* Parse args required to build the message */
17397   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17398     {
17399       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
17400         ;
17401       else
17402         break;
17403     }
17404
17405   /* Construct the API message */
17406   M (GPE_SET_ENCAP_MODE, mp);
17407
17408   mp->mode = mode;
17409
17410   /* send it... */
17411   S (mp);
17412
17413   /* Wait for a reply... */
17414   W (ret);
17415   return ret;
17416 }
17417
17418 static int
17419 api_lisp_gpe_add_del_iface (vat_main_t * vam)
17420 {
17421   unformat_input_t *input = vam->input;
17422   vl_api_gpe_add_del_iface_t *mp;
17423   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
17424   u32 dp_table = 0, vni = 0;
17425   int ret;
17426
17427   /* Parse args required to build the message */
17428   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17429     {
17430       if (unformat (input, "up"))
17431         {
17432           action_set = 1;
17433           is_add = 1;
17434         }
17435       else if (unformat (input, "down"))
17436         {
17437           action_set = 1;
17438           is_add = 0;
17439         }
17440       else if (unformat (input, "table_id %d", &dp_table))
17441         {
17442           dp_table_set = 1;
17443         }
17444       else if (unformat (input, "bd_id %d", &dp_table))
17445         {
17446           dp_table_set = 1;
17447           is_l2 = 1;
17448         }
17449       else if (unformat (input, "vni %d", &vni))
17450         {
17451           vni_set = 1;
17452         }
17453       else
17454         break;
17455     }
17456
17457   if (action_set == 0)
17458     {
17459       errmsg ("Action not set");
17460       return -99;
17461     }
17462   if (dp_table_set == 0 || vni_set == 0)
17463     {
17464       errmsg ("vni and dp_table must be set");
17465       return -99;
17466     }
17467
17468   /* Construct the API message */
17469   M (GPE_ADD_DEL_IFACE, mp);
17470
17471   mp->is_add = is_add;
17472   mp->dp_table = clib_host_to_net_u32 (dp_table);
17473   mp->is_l2 = is_l2;
17474   mp->vni = clib_host_to_net_u32 (vni);
17475
17476   /* send it... */
17477   S (mp);
17478
17479   /* Wait for a reply... */
17480   W (ret);
17481   return ret;
17482 }
17483
17484 static int
17485 api_one_map_register_fallback_threshold (vat_main_t * vam)
17486 {
17487   unformat_input_t *input = vam->input;
17488   vl_api_one_map_register_fallback_threshold_t *mp;
17489   u32 value = 0;
17490   u8 is_set = 0;
17491   int ret;
17492
17493   /* Parse args required to build the message */
17494   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17495     {
17496       if (unformat (input, "%u", &value))
17497         is_set = 1;
17498       else
17499         {
17500           clib_warning ("parse error '%U'", format_unformat_error, input);
17501           return -99;
17502         }
17503     }
17504
17505   if (!is_set)
17506     {
17507       errmsg ("fallback threshold value is missing!");
17508       return -99;
17509     }
17510
17511   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17512   mp->value = clib_host_to_net_u32 (value);
17513
17514   /* send it... */
17515   S (mp);
17516
17517   /* Wait for a reply... */
17518   W (ret);
17519   return ret;
17520 }
17521
17522 static int
17523 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
17524 {
17525   vl_api_show_one_map_register_fallback_threshold_t *mp;
17526   int ret;
17527
17528   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17529
17530   /* send it... */
17531   S (mp);
17532
17533   /* Wait for a reply... */
17534   W (ret);
17535   return ret;
17536 }
17537
17538 uword
17539 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
17540 {
17541   u32 *proto = va_arg (*args, u32 *);
17542
17543   if (unformat (input, "udp"))
17544     *proto = 1;
17545   else if (unformat (input, "api"))
17546     *proto = 2;
17547   else
17548     return 0;
17549
17550   return 1;
17551 }
17552
17553 static int
17554 api_one_set_transport_protocol (vat_main_t * vam)
17555 {
17556   unformat_input_t *input = vam->input;
17557   vl_api_one_set_transport_protocol_t *mp;
17558   u8 is_set = 0;
17559   u32 protocol = 0;
17560   int ret;
17561
17562   /* Parse args required to build the message */
17563   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17564     {
17565       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
17566         is_set = 1;
17567       else
17568         {
17569           clib_warning ("parse error '%U'", format_unformat_error, input);
17570           return -99;
17571         }
17572     }
17573
17574   if (!is_set)
17575     {
17576       errmsg ("Transport protocol missing!");
17577       return -99;
17578     }
17579
17580   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
17581   mp->protocol = (u8) protocol;
17582
17583   /* send it... */
17584   S (mp);
17585
17586   /* Wait for a reply... */
17587   W (ret);
17588   return ret;
17589 }
17590
17591 static int
17592 api_one_get_transport_protocol (vat_main_t * vam)
17593 {
17594   vl_api_one_get_transport_protocol_t *mp;
17595   int ret;
17596
17597   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
17598
17599   /* send it... */
17600   S (mp);
17601
17602   /* Wait for a reply... */
17603   W (ret);
17604   return ret;
17605 }
17606
17607 static int
17608 api_one_map_register_set_ttl (vat_main_t * vam)
17609 {
17610   unformat_input_t *input = vam->input;
17611   vl_api_one_map_register_set_ttl_t *mp;
17612   u32 ttl = 0;
17613   u8 is_set = 0;
17614   int ret;
17615
17616   /* Parse args required to build the message */
17617   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17618     {
17619       if (unformat (input, "%u", &ttl))
17620         is_set = 1;
17621       else
17622         {
17623           clib_warning ("parse error '%U'", format_unformat_error, input);
17624           return -99;
17625         }
17626     }
17627
17628   if (!is_set)
17629     {
17630       errmsg ("TTL value missing!");
17631       return -99;
17632     }
17633
17634   M (ONE_MAP_REGISTER_SET_TTL, mp);
17635   mp->ttl = clib_host_to_net_u32 (ttl);
17636
17637   /* send it... */
17638   S (mp);
17639
17640   /* Wait for a reply... */
17641   W (ret);
17642   return ret;
17643 }
17644
17645 static int
17646 api_show_one_map_register_ttl (vat_main_t * vam)
17647 {
17648   vl_api_show_one_map_register_ttl_t *mp;
17649   int ret;
17650
17651   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
17652
17653   /* send it... */
17654   S (mp);
17655
17656   /* Wait for a reply... */
17657   W (ret);
17658   return ret;
17659 }
17660
17661 /**
17662  * Add/del map request itr rlocs from ONE control plane and updates
17663  *
17664  * @param vam vpp API test context
17665  * @return return code
17666  */
17667 static int
17668 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17669 {
17670   unformat_input_t *input = vam->input;
17671   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17672   u8 *locator_set_name = 0;
17673   u8 locator_set_name_set = 0;
17674   u8 is_add = 1;
17675   int ret;
17676
17677   /* Parse args required to build the message */
17678   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17679     {
17680       if (unformat (input, "del"))
17681         {
17682           is_add = 0;
17683         }
17684       else if (unformat (input, "%_%v%_", &locator_set_name))
17685         {
17686           locator_set_name_set = 1;
17687         }
17688       else
17689         {
17690           clib_warning ("parse error '%U'", format_unformat_error, input);
17691           return -99;
17692         }
17693     }
17694
17695   if (is_add && !locator_set_name_set)
17696     {
17697       errmsg ("itr-rloc is not set!");
17698       return -99;
17699     }
17700
17701   if (is_add && vec_len (locator_set_name) > 64)
17702     {
17703       errmsg ("itr-rloc locator-set name too long");
17704       vec_free (locator_set_name);
17705       return -99;
17706     }
17707
17708   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17709   mp->is_add = is_add;
17710   if (is_add)
17711     {
17712       clib_memcpy (mp->locator_set_name, locator_set_name,
17713                    vec_len (locator_set_name));
17714     }
17715   else
17716     {
17717       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17718     }
17719   vec_free (locator_set_name);
17720
17721   /* send it... */
17722   S (mp);
17723
17724   /* Wait for a reply... */
17725   W (ret);
17726   return ret;
17727 }
17728
17729 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17730
17731 static int
17732 api_one_locator_dump (vat_main_t * vam)
17733 {
17734   unformat_input_t *input = vam->input;
17735   vl_api_one_locator_dump_t *mp;
17736   vl_api_control_ping_t *mp_ping;
17737   u8 is_index_set = 0, is_name_set = 0;
17738   u8 *ls_name = 0;
17739   u32 ls_index = ~0;
17740   int ret;
17741
17742   /* Parse args required to build the message */
17743   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17744     {
17745       if (unformat (input, "ls_name %_%v%_", &ls_name))
17746         {
17747           is_name_set = 1;
17748         }
17749       else if (unformat (input, "ls_index %d", &ls_index))
17750         {
17751           is_index_set = 1;
17752         }
17753       else
17754         {
17755           errmsg ("parse error '%U'", format_unformat_error, input);
17756           return -99;
17757         }
17758     }
17759
17760   if (!is_index_set && !is_name_set)
17761     {
17762       errmsg ("error: expected one of index or name!");
17763       return -99;
17764     }
17765
17766   if (is_index_set && is_name_set)
17767     {
17768       errmsg ("error: only one param expected!");
17769       return -99;
17770     }
17771
17772   if (vec_len (ls_name) > 62)
17773     {
17774       errmsg ("error: locator set name too long!");
17775       return -99;
17776     }
17777
17778   if (!vam->json_output)
17779     {
17780       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17781     }
17782
17783   M (ONE_LOCATOR_DUMP, mp);
17784   mp->is_index_set = is_index_set;
17785
17786   if (is_index_set)
17787     mp->ls_index = clib_host_to_net_u32 (ls_index);
17788   else
17789     {
17790       vec_add1 (ls_name, 0);
17791       strncpy ((char *) mp->ls_name, (char *) ls_name,
17792                sizeof (mp->ls_name) - 1);
17793     }
17794
17795   /* send it... */
17796   S (mp);
17797
17798   /* Use a control ping for synchronization */
17799   MPING (CONTROL_PING, mp_ping);
17800   S (mp_ping);
17801
17802   /* Wait for a reply... */
17803   W (ret);
17804   return ret;
17805 }
17806
17807 #define api_lisp_locator_dump api_one_locator_dump
17808
17809 static int
17810 api_one_locator_set_dump (vat_main_t * vam)
17811 {
17812   vl_api_one_locator_set_dump_t *mp;
17813   vl_api_control_ping_t *mp_ping;
17814   unformat_input_t *input = vam->input;
17815   u8 filter = 0;
17816   int ret;
17817
17818   /* Parse args required to build the message */
17819   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17820     {
17821       if (unformat (input, "local"))
17822         {
17823           filter = 1;
17824         }
17825       else if (unformat (input, "remote"))
17826         {
17827           filter = 2;
17828         }
17829       else
17830         {
17831           errmsg ("parse error '%U'", format_unformat_error, input);
17832           return -99;
17833         }
17834     }
17835
17836   if (!vam->json_output)
17837     {
17838       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
17839     }
17840
17841   M (ONE_LOCATOR_SET_DUMP, mp);
17842
17843   mp->filter = filter;
17844
17845   /* send it... */
17846   S (mp);
17847
17848   /* Use a control ping for synchronization */
17849   MPING (CONTROL_PING, mp_ping);
17850   S (mp_ping);
17851
17852   /* Wait for a reply... */
17853   W (ret);
17854   return ret;
17855 }
17856
17857 #define api_lisp_locator_set_dump api_one_locator_set_dump
17858
17859 static int
17860 api_one_eid_table_map_dump (vat_main_t * vam)
17861 {
17862   u8 is_l2 = 0;
17863   u8 mode_set = 0;
17864   unformat_input_t *input = vam->input;
17865   vl_api_one_eid_table_map_dump_t *mp;
17866   vl_api_control_ping_t *mp_ping;
17867   int ret;
17868
17869   /* Parse args required to build the message */
17870   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17871     {
17872       if (unformat (input, "l2"))
17873         {
17874           is_l2 = 1;
17875           mode_set = 1;
17876         }
17877       else if (unformat (input, "l3"))
17878         {
17879           is_l2 = 0;
17880           mode_set = 1;
17881         }
17882       else
17883         {
17884           errmsg ("parse error '%U'", format_unformat_error, input);
17885           return -99;
17886         }
17887     }
17888
17889   if (!mode_set)
17890     {
17891       errmsg ("expected one of 'l2' or 'l3' parameter!");
17892       return -99;
17893     }
17894
17895   if (!vam->json_output)
17896     {
17897       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
17898     }
17899
17900   M (ONE_EID_TABLE_MAP_DUMP, mp);
17901   mp->is_l2 = is_l2;
17902
17903   /* send it... */
17904   S (mp);
17905
17906   /* Use a control ping for synchronization */
17907   MPING (CONTROL_PING, mp_ping);
17908   S (mp_ping);
17909
17910   /* Wait for a reply... */
17911   W (ret);
17912   return ret;
17913 }
17914
17915 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
17916
17917 static int
17918 api_one_eid_table_vni_dump (vat_main_t * vam)
17919 {
17920   vl_api_one_eid_table_vni_dump_t *mp;
17921   vl_api_control_ping_t *mp_ping;
17922   int ret;
17923
17924   if (!vam->json_output)
17925     {
17926       print (vam->ofp, "VNI");
17927     }
17928
17929   M (ONE_EID_TABLE_VNI_DUMP, mp);
17930
17931   /* send it... */
17932   S (mp);
17933
17934   /* Use a control ping for synchronization */
17935   MPING (CONTROL_PING, mp_ping);
17936   S (mp_ping);
17937
17938   /* Wait for a reply... */
17939   W (ret);
17940   return ret;
17941 }
17942
17943 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
17944
17945 static int
17946 api_one_eid_table_dump (vat_main_t * vam)
17947 {
17948   unformat_input_t *i = vam->input;
17949   vl_api_one_eid_table_dump_t *mp;
17950   vl_api_control_ping_t *mp_ping;
17951   struct in_addr ip4;
17952   struct in6_addr ip6;
17953   u8 mac[6];
17954   u8 eid_type = ~0, eid_set = 0;
17955   u32 prefix_length = ~0, t, vni = 0;
17956   u8 filter = 0;
17957   int ret;
17958   lisp_nsh_api_t nsh;
17959
17960   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17961     {
17962       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
17963         {
17964           eid_set = 1;
17965           eid_type = 0;
17966           prefix_length = t;
17967         }
17968       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
17969         {
17970           eid_set = 1;
17971           eid_type = 1;
17972           prefix_length = t;
17973         }
17974       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
17975         {
17976           eid_set = 1;
17977           eid_type = 2;
17978         }
17979       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
17980         {
17981           eid_set = 1;
17982           eid_type = 3;
17983         }
17984       else if (unformat (i, "vni %d", &t))
17985         {
17986           vni = t;
17987         }
17988       else if (unformat (i, "local"))
17989         {
17990           filter = 1;
17991         }
17992       else if (unformat (i, "remote"))
17993         {
17994           filter = 2;
17995         }
17996       else
17997         {
17998           errmsg ("parse error '%U'", format_unformat_error, i);
17999           return -99;
18000         }
18001     }
18002
18003   if (!vam->json_output)
18004     {
18005       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
18006              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
18007     }
18008
18009   M (ONE_EID_TABLE_DUMP, mp);
18010
18011   mp->filter = filter;
18012   if (eid_set)
18013     {
18014       mp->eid_set = 1;
18015       mp->vni = htonl (vni);
18016       mp->eid_type = eid_type;
18017       switch (eid_type)
18018         {
18019         case 0:
18020           mp->prefix_length = prefix_length;
18021           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
18022           break;
18023         case 1:
18024           mp->prefix_length = prefix_length;
18025           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
18026           break;
18027         case 2:
18028           clib_memcpy (mp->eid, mac, sizeof (mac));
18029           break;
18030         case 3:
18031           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
18032           break;
18033         default:
18034           errmsg ("unknown EID type %d!", eid_type);
18035           return -99;
18036         }
18037     }
18038
18039   /* send it... */
18040   S (mp);
18041
18042   /* Use a control ping for synchronization */
18043   MPING (CONTROL_PING, mp_ping);
18044   S (mp_ping);
18045
18046   /* Wait for a reply... */
18047   W (ret);
18048   return ret;
18049 }
18050
18051 #define api_lisp_eid_table_dump api_one_eid_table_dump
18052
18053 static int
18054 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
18055 {
18056   unformat_input_t *i = vam->input;
18057   vl_api_gpe_fwd_entries_get_t *mp;
18058   u8 vni_set = 0;
18059   u32 vni = ~0;
18060   int ret;
18061
18062   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18063     {
18064       if (unformat (i, "vni %d", &vni))
18065         {
18066           vni_set = 1;
18067         }
18068       else
18069         {
18070           errmsg ("parse error '%U'", format_unformat_error, i);
18071           return -99;
18072         }
18073     }
18074
18075   if (!vni_set)
18076     {
18077       errmsg ("vni not set!");
18078       return -99;
18079     }
18080
18081   if (!vam->json_output)
18082     {
18083       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
18084              "leid", "reid");
18085     }
18086
18087   M (GPE_FWD_ENTRIES_GET, mp);
18088   mp->vni = clib_host_to_net_u32 (vni);
18089
18090   /* send it... */
18091   S (mp);
18092
18093   /* Wait for a reply... */
18094   W (ret);
18095   return ret;
18096 }
18097
18098 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
18099 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
18100 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
18101 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
18102 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
18103 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
18104 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
18105 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
18106
18107 static int
18108 api_one_adjacencies_get (vat_main_t * vam)
18109 {
18110   unformat_input_t *i = vam->input;
18111   vl_api_one_adjacencies_get_t *mp;
18112   u8 vni_set = 0;
18113   u32 vni = ~0;
18114   int ret;
18115
18116   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18117     {
18118       if (unformat (i, "vni %d", &vni))
18119         {
18120           vni_set = 1;
18121         }
18122       else
18123         {
18124           errmsg ("parse error '%U'", format_unformat_error, i);
18125           return -99;
18126         }
18127     }
18128
18129   if (!vni_set)
18130     {
18131       errmsg ("vni not set!");
18132       return -99;
18133     }
18134
18135   if (!vam->json_output)
18136     {
18137       print (vam->ofp, "%s %40s", "leid", "reid");
18138     }
18139
18140   M (ONE_ADJACENCIES_GET, mp);
18141   mp->vni = clib_host_to_net_u32 (vni);
18142
18143   /* send it... */
18144   S (mp);
18145
18146   /* Wait for a reply... */
18147   W (ret);
18148   return ret;
18149 }
18150
18151 #define api_lisp_adjacencies_get api_one_adjacencies_get
18152
18153 static int
18154 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
18155 {
18156   unformat_input_t *i = vam->input;
18157   vl_api_gpe_native_fwd_rpaths_get_t *mp;
18158   int ret;
18159   u8 ip_family_set = 0, is_ip4 = 1;
18160
18161   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18162     {
18163       if (unformat (i, "ip4"))
18164         {
18165           ip_family_set = 1;
18166           is_ip4 = 1;
18167         }
18168       else if (unformat (i, "ip6"))
18169         {
18170           ip_family_set = 1;
18171           is_ip4 = 0;
18172         }
18173       else
18174         {
18175           errmsg ("parse error '%U'", format_unformat_error, i);
18176           return -99;
18177         }
18178     }
18179
18180   if (!ip_family_set)
18181     {
18182       errmsg ("ip family not set!");
18183       return -99;
18184     }
18185
18186   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
18187   mp->is_ip4 = is_ip4;
18188
18189   /* send it... */
18190   S (mp);
18191
18192   /* Wait for a reply... */
18193   W (ret);
18194   return ret;
18195 }
18196
18197 static int
18198 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
18199 {
18200   vl_api_gpe_fwd_entry_vnis_get_t *mp;
18201   int ret;
18202
18203   if (!vam->json_output)
18204     {
18205       print (vam->ofp, "VNIs");
18206     }
18207
18208   M (GPE_FWD_ENTRY_VNIS_GET, mp);
18209
18210   /* send it... */
18211   S (mp);
18212
18213   /* Wait for a reply... */
18214   W (ret);
18215   return ret;
18216 }
18217
18218 static int
18219 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
18220 {
18221   unformat_input_t *i = vam->input;
18222   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
18223   int ret = 0;
18224   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
18225   struct in_addr ip4;
18226   struct in6_addr ip6;
18227   u32 table_id = 0, nh_sw_if_index = ~0;
18228
18229   clib_memset (&ip4, 0, sizeof (ip4));
18230   clib_memset (&ip6, 0, sizeof (ip6));
18231
18232   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18233     {
18234       if (unformat (i, "del"))
18235         is_add = 0;
18236       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
18237                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18238         {
18239           ip_set = 1;
18240           is_ip4 = 1;
18241         }
18242       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
18243                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18244         {
18245           ip_set = 1;
18246           is_ip4 = 0;
18247         }
18248       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
18249         {
18250           ip_set = 1;
18251           is_ip4 = 1;
18252           nh_sw_if_index = ~0;
18253         }
18254       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
18255         {
18256           ip_set = 1;
18257           is_ip4 = 0;
18258           nh_sw_if_index = ~0;
18259         }
18260       else if (unformat (i, "table %d", &table_id))
18261         ;
18262       else
18263         {
18264           errmsg ("parse error '%U'", format_unformat_error, i);
18265           return -99;
18266         }
18267     }
18268
18269   if (!ip_set)
18270     {
18271       errmsg ("nh addr not set!");
18272       return -99;
18273     }
18274
18275   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
18276   mp->is_add = is_add;
18277   mp->table_id = clib_host_to_net_u32 (table_id);
18278   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
18279   mp->is_ip4 = is_ip4;
18280   if (is_ip4)
18281     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
18282   else
18283     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
18284
18285   /* send it... */
18286   S (mp);
18287
18288   /* Wait for a reply... */
18289   W (ret);
18290   return ret;
18291 }
18292
18293 static int
18294 api_one_map_server_dump (vat_main_t * vam)
18295 {
18296   vl_api_one_map_server_dump_t *mp;
18297   vl_api_control_ping_t *mp_ping;
18298   int ret;
18299
18300   if (!vam->json_output)
18301     {
18302       print (vam->ofp, "%=20s", "Map server");
18303     }
18304
18305   M (ONE_MAP_SERVER_DUMP, mp);
18306   /* send it... */
18307   S (mp);
18308
18309   /* Use a control ping for synchronization */
18310   MPING (CONTROL_PING, mp_ping);
18311   S (mp_ping);
18312
18313   /* Wait for a reply... */
18314   W (ret);
18315   return ret;
18316 }
18317
18318 #define api_lisp_map_server_dump api_one_map_server_dump
18319
18320 static int
18321 api_one_map_resolver_dump (vat_main_t * vam)
18322 {
18323   vl_api_one_map_resolver_dump_t *mp;
18324   vl_api_control_ping_t *mp_ping;
18325   int ret;
18326
18327   if (!vam->json_output)
18328     {
18329       print (vam->ofp, "%=20s", "Map resolver");
18330     }
18331
18332   M (ONE_MAP_RESOLVER_DUMP, mp);
18333   /* send it... */
18334   S (mp);
18335
18336   /* Use a control ping for synchronization */
18337   MPING (CONTROL_PING, mp_ping);
18338   S (mp_ping);
18339
18340   /* Wait for a reply... */
18341   W (ret);
18342   return ret;
18343 }
18344
18345 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
18346
18347 static int
18348 api_one_stats_flush (vat_main_t * vam)
18349 {
18350   vl_api_one_stats_flush_t *mp;
18351   int ret = 0;
18352
18353   M (ONE_STATS_FLUSH, mp);
18354   S (mp);
18355   W (ret);
18356   return ret;
18357 }
18358
18359 static int
18360 api_one_stats_dump (vat_main_t * vam)
18361 {
18362   vl_api_one_stats_dump_t *mp;
18363   vl_api_control_ping_t *mp_ping;
18364   int ret;
18365
18366   M (ONE_STATS_DUMP, mp);
18367   /* send it... */
18368   S (mp);
18369
18370   /* Use a control ping for synchronization */
18371   MPING (CONTROL_PING, mp_ping);
18372   S (mp_ping);
18373
18374   /* Wait for a reply... */
18375   W (ret);
18376   return ret;
18377 }
18378
18379 static int
18380 api_show_one_status (vat_main_t * vam)
18381 {
18382   vl_api_show_one_status_t *mp;
18383   int ret;
18384
18385   if (!vam->json_output)
18386     {
18387       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
18388     }
18389
18390   M (SHOW_ONE_STATUS, mp);
18391   /* send it... */
18392   S (mp);
18393   /* Wait for a reply... */
18394   W (ret);
18395   return ret;
18396 }
18397
18398 #define api_show_lisp_status api_show_one_status
18399
18400 static int
18401 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
18402 {
18403   vl_api_gpe_fwd_entry_path_dump_t *mp;
18404   vl_api_control_ping_t *mp_ping;
18405   unformat_input_t *i = vam->input;
18406   u32 fwd_entry_index = ~0;
18407   int ret;
18408
18409   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18410     {
18411       if (unformat (i, "index %d", &fwd_entry_index))
18412         ;
18413       else
18414         break;
18415     }
18416
18417   if (~0 == fwd_entry_index)
18418     {
18419       errmsg ("no index specified!");
18420       return -99;
18421     }
18422
18423   if (!vam->json_output)
18424     {
18425       print (vam->ofp, "first line");
18426     }
18427
18428   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
18429
18430   /* send it... */
18431   S (mp);
18432   /* Use a control ping for synchronization */
18433   MPING (CONTROL_PING, mp_ping);
18434   S (mp_ping);
18435
18436   /* Wait for a reply... */
18437   W (ret);
18438   return ret;
18439 }
18440
18441 static int
18442 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
18443 {
18444   vl_api_one_get_map_request_itr_rlocs_t *mp;
18445   int ret;
18446
18447   if (!vam->json_output)
18448     {
18449       print (vam->ofp, "%=20s", "itr-rlocs:");
18450     }
18451
18452   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
18453   /* send it... */
18454   S (mp);
18455   /* Wait for a reply... */
18456   W (ret);
18457   return ret;
18458 }
18459
18460 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
18461
18462 static int
18463 api_af_packet_create (vat_main_t * vam)
18464 {
18465   unformat_input_t *i = vam->input;
18466   vl_api_af_packet_create_t *mp;
18467   u8 *host_if_name = 0;
18468   u8 hw_addr[6];
18469   u8 random_hw_addr = 1;
18470   int ret;
18471
18472   clib_memset (hw_addr, 0, sizeof (hw_addr));
18473
18474   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18475     {
18476       if (unformat (i, "name %s", &host_if_name))
18477         vec_add1 (host_if_name, 0);
18478       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18479         random_hw_addr = 0;
18480       else
18481         break;
18482     }
18483
18484   if (!vec_len (host_if_name))
18485     {
18486       errmsg ("host-interface name must be specified");
18487       return -99;
18488     }
18489
18490   if (vec_len (host_if_name) > 64)
18491     {
18492       errmsg ("host-interface name too long");
18493       return -99;
18494     }
18495
18496   M (AF_PACKET_CREATE, mp);
18497
18498   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18499   clib_memcpy (mp->hw_addr, hw_addr, 6);
18500   mp->use_random_hw_addr = random_hw_addr;
18501   vec_free (host_if_name);
18502
18503   S (mp);
18504
18505   /* *INDENT-OFF* */
18506   W2 (ret,
18507       ({
18508         if (ret == 0)
18509           fprintf (vam->ofp ? vam->ofp : stderr,
18510                    " new sw_if_index = %d\n", vam->sw_if_index);
18511       }));
18512   /* *INDENT-ON* */
18513   return ret;
18514 }
18515
18516 static int
18517 api_af_packet_delete (vat_main_t * vam)
18518 {
18519   unformat_input_t *i = vam->input;
18520   vl_api_af_packet_delete_t *mp;
18521   u8 *host_if_name = 0;
18522   int ret;
18523
18524   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18525     {
18526       if (unformat (i, "name %s", &host_if_name))
18527         vec_add1 (host_if_name, 0);
18528       else
18529         break;
18530     }
18531
18532   if (!vec_len (host_if_name))
18533     {
18534       errmsg ("host-interface name must be specified");
18535       return -99;
18536     }
18537
18538   if (vec_len (host_if_name) > 64)
18539     {
18540       errmsg ("host-interface name too long");
18541       return -99;
18542     }
18543
18544   M (AF_PACKET_DELETE, mp);
18545
18546   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18547   vec_free (host_if_name);
18548
18549   S (mp);
18550   W (ret);
18551   return ret;
18552 }
18553
18554 static void vl_api_af_packet_details_t_handler
18555   (vl_api_af_packet_details_t * mp)
18556 {
18557   vat_main_t *vam = &vat_main;
18558
18559   print (vam->ofp, "%-16s %d",
18560          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
18561 }
18562
18563 static void vl_api_af_packet_details_t_handler_json
18564   (vl_api_af_packet_details_t * mp)
18565 {
18566   vat_main_t *vam = &vat_main;
18567   vat_json_node_t *node = NULL;
18568
18569   if (VAT_JSON_ARRAY != vam->json_tree.type)
18570     {
18571       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18572       vat_json_init_array (&vam->json_tree);
18573     }
18574   node = vat_json_array_add (&vam->json_tree);
18575
18576   vat_json_init_object (node);
18577   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
18578   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
18579 }
18580
18581 static int
18582 api_af_packet_dump (vat_main_t * vam)
18583 {
18584   vl_api_af_packet_dump_t *mp;
18585   vl_api_control_ping_t *mp_ping;
18586   int ret;
18587
18588   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
18589   /* Get list of tap interfaces */
18590   M (AF_PACKET_DUMP, mp);
18591   S (mp);
18592
18593   /* Use a control ping for synchronization */
18594   MPING (CONTROL_PING, mp_ping);
18595   S (mp_ping);
18596
18597   W (ret);
18598   return ret;
18599 }
18600
18601 static int
18602 api_policer_add_del (vat_main_t * vam)
18603 {
18604   unformat_input_t *i = vam->input;
18605   vl_api_policer_add_del_t *mp;
18606   u8 is_add = 1;
18607   u8 *name = 0;
18608   u32 cir = 0;
18609   u32 eir = 0;
18610   u64 cb = 0;
18611   u64 eb = 0;
18612   u8 rate_type = 0;
18613   u8 round_type = 0;
18614   u8 type = 0;
18615   u8 color_aware = 0;
18616   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
18617   int ret;
18618
18619   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
18620   conform_action.dscp = 0;
18621   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
18622   exceed_action.dscp = 0;
18623   violate_action.action_type = SSE2_QOS_ACTION_DROP;
18624   violate_action.dscp = 0;
18625
18626   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18627     {
18628       if (unformat (i, "del"))
18629         is_add = 0;
18630       else if (unformat (i, "name %s", &name))
18631         vec_add1 (name, 0);
18632       else if (unformat (i, "cir %u", &cir))
18633         ;
18634       else if (unformat (i, "eir %u", &eir))
18635         ;
18636       else if (unformat (i, "cb %u", &cb))
18637         ;
18638       else if (unformat (i, "eb %u", &eb))
18639         ;
18640       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
18641                          &rate_type))
18642         ;
18643       else if (unformat (i, "round_type %U", unformat_policer_round_type,
18644                          &round_type))
18645         ;
18646       else if (unformat (i, "type %U", unformat_policer_type, &type))
18647         ;
18648       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
18649                          &conform_action))
18650         ;
18651       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
18652                          &exceed_action))
18653         ;
18654       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
18655                          &violate_action))
18656         ;
18657       else if (unformat (i, "color-aware"))
18658         color_aware = 1;
18659       else
18660         break;
18661     }
18662
18663   if (!vec_len (name))
18664     {
18665       errmsg ("policer name must be specified");
18666       return -99;
18667     }
18668
18669   if (vec_len (name) > 64)
18670     {
18671       errmsg ("policer name too long");
18672       return -99;
18673     }
18674
18675   M (POLICER_ADD_DEL, mp);
18676
18677   clib_memcpy (mp->name, name, vec_len (name));
18678   vec_free (name);
18679   mp->is_add = is_add;
18680   mp->cir = ntohl (cir);
18681   mp->eir = ntohl (eir);
18682   mp->cb = clib_net_to_host_u64 (cb);
18683   mp->eb = clib_net_to_host_u64 (eb);
18684   mp->rate_type = rate_type;
18685   mp->round_type = round_type;
18686   mp->type = type;
18687   mp->conform_action_type = conform_action.action_type;
18688   mp->conform_dscp = conform_action.dscp;
18689   mp->exceed_action_type = exceed_action.action_type;
18690   mp->exceed_dscp = exceed_action.dscp;
18691   mp->violate_action_type = violate_action.action_type;
18692   mp->violate_dscp = violate_action.dscp;
18693   mp->color_aware = color_aware;
18694
18695   S (mp);
18696   W (ret);
18697   return ret;
18698 }
18699
18700 static int
18701 api_policer_dump (vat_main_t * vam)
18702 {
18703   unformat_input_t *i = vam->input;
18704   vl_api_policer_dump_t *mp;
18705   vl_api_control_ping_t *mp_ping;
18706   u8 *match_name = 0;
18707   u8 match_name_valid = 0;
18708   int ret;
18709
18710   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18711     {
18712       if (unformat (i, "name %s", &match_name))
18713         {
18714           vec_add1 (match_name, 0);
18715           match_name_valid = 1;
18716         }
18717       else
18718         break;
18719     }
18720
18721   M (POLICER_DUMP, mp);
18722   mp->match_name_valid = match_name_valid;
18723   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18724   vec_free (match_name);
18725   /* send it... */
18726   S (mp);
18727
18728   /* Use a control ping for synchronization */
18729   MPING (CONTROL_PING, mp_ping);
18730   S (mp_ping);
18731
18732   /* Wait for a reply... */
18733   W (ret);
18734   return ret;
18735 }
18736
18737 static int
18738 api_policer_classify_set_interface (vat_main_t * vam)
18739 {
18740   unformat_input_t *i = vam->input;
18741   vl_api_policer_classify_set_interface_t *mp;
18742   u32 sw_if_index;
18743   int sw_if_index_set;
18744   u32 ip4_table_index = ~0;
18745   u32 ip6_table_index = ~0;
18746   u32 l2_table_index = ~0;
18747   u8 is_add = 1;
18748   int ret;
18749
18750   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18751     {
18752       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18753         sw_if_index_set = 1;
18754       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18755         sw_if_index_set = 1;
18756       else if (unformat (i, "del"))
18757         is_add = 0;
18758       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18759         ;
18760       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18761         ;
18762       else if (unformat (i, "l2-table %d", &l2_table_index))
18763         ;
18764       else
18765         {
18766           clib_warning ("parse error '%U'", format_unformat_error, i);
18767           return -99;
18768         }
18769     }
18770
18771   if (sw_if_index_set == 0)
18772     {
18773       errmsg ("missing interface name or sw_if_index");
18774       return -99;
18775     }
18776
18777   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18778
18779   mp->sw_if_index = ntohl (sw_if_index);
18780   mp->ip4_table_index = ntohl (ip4_table_index);
18781   mp->ip6_table_index = ntohl (ip6_table_index);
18782   mp->l2_table_index = ntohl (l2_table_index);
18783   mp->is_add = is_add;
18784
18785   S (mp);
18786   W (ret);
18787   return ret;
18788 }
18789
18790 static int
18791 api_policer_classify_dump (vat_main_t * vam)
18792 {
18793   unformat_input_t *i = vam->input;
18794   vl_api_policer_classify_dump_t *mp;
18795   vl_api_control_ping_t *mp_ping;
18796   u8 type = POLICER_CLASSIFY_N_TABLES;
18797   int ret;
18798
18799   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
18800     ;
18801   else
18802     {
18803       errmsg ("classify table type must be specified");
18804       return -99;
18805     }
18806
18807   if (!vam->json_output)
18808     {
18809       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18810     }
18811
18812   M (POLICER_CLASSIFY_DUMP, mp);
18813   mp->type = type;
18814   /* send it... */
18815   S (mp);
18816
18817   /* Use a control ping for synchronization */
18818   MPING (CONTROL_PING, mp_ping);
18819   S (mp_ping);
18820
18821   /* Wait for a reply... */
18822   W (ret);
18823   return ret;
18824 }
18825
18826 static int
18827 api_netmap_create (vat_main_t * vam)
18828 {
18829   unformat_input_t *i = vam->input;
18830   vl_api_netmap_create_t *mp;
18831   u8 *if_name = 0;
18832   u8 hw_addr[6];
18833   u8 random_hw_addr = 1;
18834   u8 is_pipe = 0;
18835   u8 is_master = 0;
18836   int ret;
18837
18838   clib_memset (hw_addr, 0, sizeof (hw_addr));
18839
18840   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18841     {
18842       if (unformat (i, "name %s", &if_name))
18843         vec_add1 (if_name, 0);
18844       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18845         random_hw_addr = 0;
18846       else if (unformat (i, "pipe"))
18847         is_pipe = 1;
18848       else if (unformat (i, "master"))
18849         is_master = 1;
18850       else if (unformat (i, "slave"))
18851         is_master = 0;
18852       else
18853         break;
18854     }
18855
18856   if (!vec_len (if_name))
18857     {
18858       errmsg ("interface name must be specified");
18859       return -99;
18860     }
18861
18862   if (vec_len (if_name) > 64)
18863     {
18864       errmsg ("interface name too long");
18865       return -99;
18866     }
18867
18868   M (NETMAP_CREATE, mp);
18869
18870   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18871   clib_memcpy (mp->hw_addr, hw_addr, 6);
18872   mp->use_random_hw_addr = random_hw_addr;
18873   mp->is_pipe = is_pipe;
18874   mp->is_master = is_master;
18875   vec_free (if_name);
18876
18877   S (mp);
18878   W (ret);
18879   return ret;
18880 }
18881
18882 static int
18883 api_netmap_delete (vat_main_t * vam)
18884 {
18885   unformat_input_t *i = vam->input;
18886   vl_api_netmap_delete_t *mp;
18887   u8 *if_name = 0;
18888   int ret;
18889
18890   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18891     {
18892       if (unformat (i, "name %s", &if_name))
18893         vec_add1 (if_name, 0);
18894       else
18895         break;
18896     }
18897
18898   if (!vec_len (if_name))
18899     {
18900       errmsg ("interface name must be specified");
18901       return -99;
18902     }
18903
18904   if (vec_len (if_name) > 64)
18905     {
18906       errmsg ("interface name too long");
18907       return -99;
18908     }
18909
18910   M (NETMAP_DELETE, mp);
18911
18912   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18913   vec_free (if_name);
18914
18915   S (mp);
18916   W (ret);
18917   return ret;
18918 }
18919
18920 static void
18921 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
18922 {
18923   if (fp->afi == IP46_TYPE_IP6)
18924     print (vam->ofp,
18925            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18926            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18927            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
18928            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18929            format_ip6_address, fp->next_hop);
18930   else if (fp->afi == IP46_TYPE_IP4)
18931     print (vam->ofp,
18932            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18933            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18934            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
18935            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18936            format_ip4_address, fp->next_hop);
18937 }
18938
18939 static void
18940 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
18941                                  vl_api_fib_path_t * fp)
18942 {
18943   struct in_addr ip4;
18944   struct in6_addr ip6;
18945
18946   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18947   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18948   vat_json_object_add_uint (node, "is_local", fp->is_local);
18949   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
18950   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
18951   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
18952   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
18953   if (fp->afi == IP46_TYPE_IP4)
18954     {
18955       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
18956       vat_json_object_add_ip4 (node, "next_hop", ip4);
18957     }
18958   else if (fp->afi == IP46_TYPE_IP6)
18959     {
18960       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
18961       vat_json_object_add_ip6 (node, "next_hop", ip6);
18962     }
18963 }
18964
18965 static void
18966 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
18967 {
18968   vat_main_t *vam = &vat_main;
18969   int count = ntohl (mp->mt_count);
18970   vl_api_fib_path_t *fp;
18971   i32 i;
18972
18973   print (vam->ofp, "[%d]: sw_if_index %d via:",
18974          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
18975   fp = mp->mt_paths;
18976   for (i = 0; i < count; i++)
18977     {
18978       vl_api_mpls_fib_path_print (vam, fp);
18979       fp++;
18980     }
18981
18982   print (vam->ofp, "");
18983 }
18984
18985 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
18986 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
18987
18988 static void
18989 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
18990 {
18991   vat_main_t *vam = &vat_main;
18992   vat_json_node_t *node = NULL;
18993   int count = ntohl (mp->mt_count);
18994   vl_api_fib_path_t *fp;
18995   i32 i;
18996
18997   if (VAT_JSON_ARRAY != vam->json_tree.type)
18998     {
18999       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19000       vat_json_init_array (&vam->json_tree);
19001     }
19002   node = vat_json_array_add (&vam->json_tree);
19003
19004   vat_json_init_object (node);
19005   vat_json_object_add_uint (node, "tunnel_index",
19006                             ntohl (mp->mt_tunnel_index));
19007   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
19008
19009   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
19010
19011   fp = mp->mt_paths;
19012   for (i = 0; i < count; i++)
19013     {
19014       vl_api_mpls_fib_path_json_print (node, fp);
19015       fp++;
19016     }
19017 }
19018
19019 static int
19020 api_mpls_tunnel_dump (vat_main_t * vam)
19021 {
19022   vl_api_mpls_tunnel_dump_t *mp;
19023   vl_api_control_ping_t *mp_ping;
19024   u32 sw_if_index = ~0;
19025   int ret;
19026
19027   /* Parse args required to build the message */
19028   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
19029     {
19030       if (unformat (vam->input, "sw_if_index %d", &sw_if_index))
19031         ;
19032     }
19033
19034   print (vam->ofp, "  sw_if_index %d", sw_if_index);
19035
19036   M (MPLS_TUNNEL_DUMP, mp);
19037   mp->sw_if_index = htonl (sw_if_index);
19038   S (mp);
19039
19040   /* Use a control ping for synchronization */
19041   MPING (CONTROL_PING, mp_ping);
19042   S (mp_ping);
19043
19044   W (ret);
19045   return ret;
19046 }
19047
19048 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
19049 #define vl_api_mpls_fib_details_t_print vl_noop_handler
19050
19051
19052 static void
19053 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
19054 {
19055   vat_main_t *vam = &vat_main;
19056   int count = ntohl (mp->count);
19057   vl_api_fib_path_t *fp;
19058   int i;
19059
19060   print (vam->ofp,
19061          "table-id %d, label %u, ess_bit %u",
19062          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
19063   fp = mp->path;
19064   for (i = 0; i < count; i++)
19065     {
19066       vl_api_mpls_fib_path_print (vam, fp);
19067       fp++;
19068     }
19069 }
19070
19071 static void vl_api_mpls_fib_details_t_handler_json
19072   (vl_api_mpls_fib_details_t * mp)
19073 {
19074   vat_main_t *vam = &vat_main;
19075   int count = ntohl (mp->count);
19076   vat_json_node_t *node = NULL;
19077   vl_api_fib_path_t *fp;
19078   int i;
19079
19080   if (VAT_JSON_ARRAY != vam->json_tree.type)
19081     {
19082       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19083       vat_json_init_array (&vam->json_tree);
19084     }
19085   node = vat_json_array_add (&vam->json_tree);
19086
19087   vat_json_init_object (node);
19088   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19089   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
19090   vat_json_object_add_uint (node, "label", ntohl (mp->label));
19091   vat_json_object_add_uint (node, "path_count", count);
19092   fp = mp->path;
19093   for (i = 0; i < count; i++)
19094     {
19095       vl_api_mpls_fib_path_json_print (node, fp);
19096       fp++;
19097     }
19098 }
19099
19100 static int
19101 api_mpls_fib_dump (vat_main_t * vam)
19102 {
19103   vl_api_mpls_fib_dump_t *mp;
19104   vl_api_control_ping_t *mp_ping;
19105   int ret;
19106
19107   M (MPLS_FIB_DUMP, mp);
19108   S (mp);
19109
19110   /* Use a control ping for synchronization */
19111   MPING (CONTROL_PING, mp_ping);
19112   S (mp_ping);
19113
19114   W (ret);
19115   return ret;
19116 }
19117
19118 #define vl_api_ip_fib_details_t_endian vl_noop_handler
19119 #define vl_api_ip_fib_details_t_print vl_noop_handler
19120
19121 static void
19122 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
19123 {
19124   vat_main_t *vam = &vat_main;
19125   int count = ntohl (mp->count);
19126   vl_api_fib_path_t *fp;
19127   int i;
19128
19129   print (vam->ofp,
19130          "table-id %d, prefix %U/%d stats-index %d",
19131          ntohl (mp->table_id), format_ip4_address, mp->address,
19132          mp->address_length, ntohl (mp->stats_index));
19133   fp = mp->path;
19134   for (i = 0; i < count; i++)
19135     {
19136       if (fp->afi == IP46_TYPE_IP6)
19137         print (vam->ofp,
19138                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19139                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
19140                "next_hop_table %d",
19141                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19142                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19143                format_ip6_address, fp->next_hop, ntohl (fp->table_id));
19144       else if (fp->afi == IP46_TYPE_IP4)
19145         print (vam->ofp,
19146                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19147                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
19148                "next_hop_table %d",
19149                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19150                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19151                format_ip4_address, fp->next_hop, ntohl (fp->table_id));
19152       fp++;
19153     }
19154 }
19155
19156 static void vl_api_ip_fib_details_t_handler_json
19157   (vl_api_ip_fib_details_t * mp)
19158 {
19159   vat_main_t *vam = &vat_main;
19160   int count = ntohl (mp->count);
19161   vat_json_node_t *node = NULL;
19162   struct in_addr ip4;
19163   struct in6_addr ip6;
19164   vl_api_fib_path_t *fp;
19165   int i;
19166
19167   if (VAT_JSON_ARRAY != vam->json_tree.type)
19168     {
19169       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19170       vat_json_init_array (&vam->json_tree);
19171     }
19172   node = vat_json_array_add (&vam->json_tree);
19173
19174   vat_json_init_object (node);
19175   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19176   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
19177   vat_json_object_add_ip4 (node, "prefix", ip4);
19178   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19179   vat_json_object_add_uint (node, "path_count", count);
19180   fp = mp->path;
19181   for (i = 0; i < count; i++)
19182     {
19183       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19184       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19185       vat_json_object_add_uint (node, "is_local", fp->is_local);
19186       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19187       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19188       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19189       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19190       if (fp->afi == IP46_TYPE_IP4)
19191         {
19192           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19193           vat_json_object_add_ip4 (node, "next_hop", ip4);
19194         }
19195       else if (fp->afi == IP46_TYPE_IP6)
19196         {
19197           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19198           vat_json_object_add_ip6 (node, "next_hop", ip6);
19199         }
19200     }
19201 }
19202
19203 static int
19204 api_ip_fib_dump (vat_main_t * vam)
19205 {
19206   vl_api_ip_fib_dump_t *mp;
19207   vl_api_control_ping_t *mp_ping;
19208   int ret;
19209
19210   M (IP_FIB_DUMP, mp);
19211   S (mp);
19212
19213   /* Use a control ping for synchronization */
19214   MPING (CONTROL_PING, mp_ping);
19215   S (mp_ping);
19216
19217   W (ret);
19218   return ret;
19219 }
19220
19221 static int
19222 api_ip_mfib_dump (vat_main_t * vam)
19223 {
19224   vl_api_ip_mfib_dump_t *mp;
19225   vl_api_control_ping_t *mp_ping;
19226   int ret;
19227
19228   M (IP_MFIB_DUMP, mp);
19229   S (mp);
19230
19231   /* Use a control ping for synchronization */
19232   MPING (CONTROL_PING, mp_ping);
19233   S (mp_ping);
19234
19235   W (ret);
19236   return ret;
19237 }
19238
19239 static void vl_api_ip_neighbor_details_t_handler
19240   (vl_api_ip_neighbor_details_t * mp)
19241 {
19242   vat_main_t *vam = &vat_main;
19243
19244   print (vam->ofp, "%c %U %U",
19245          (ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ? 'S' : 'D',
19246          format_vl_api_mac_address, &mp->neighbor.mac_address,
19247          format_vl_api_address, &mp->neighbor.ip_address);
19248 }
19249
19250 static void vl_api_ip_neighbor_details_t_handler_json
19251   (vl_api_ip_neighbor_details_t * mp)
19252 {
19253
19254   vat_main_t *vam = &vat_main;
19255   vat_json_node_t *node;
19256
19257   if (VAT_JSON_ARRAY != vam->json_tree.type)
19258     {
19259       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19260       vat_json_init_array (&vam->json_tree);
19261     }
19262   node = vat_json_array_add (&vam->json_tree);
19263
19264   vat_json_init_object (node);
19265   vat_json_object_add_string_copy
19266     (node, "flag",
19267      ((ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ?
19268       (u8 *) "static" : (u8 *) "dynamic"));
19269
19270   vat_json_object_add_string_copy (node, "link_layer",
19271                                    format (0, "%U", format_vl_api_mac_address,
19272                                            &mp->neighbor.mac_address));
19273   vat_json_object_add_address (node, "ip", &mp->neighbor.ip_address);
19274 }
19275
19276 static int
19277 api_ip_neighbor_dump (vat_main_t * vam)
19278 {
19279   unformat_input_t *i = vam->input;
19280   vl_api_ip_neighbor_dump_t *mp;
19281   vl_api_control_ping_t *mp_ping;
19282   u8 is_ipv6 = 0;
19283   u32 sw_if_index = ~0;
19284   int ret;
19285
19286   /* Parse args required to build the message */
19287   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19288     {
19289       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19290         ;
19291       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19292         ;
19293       else if (unformat (i, "ip6"))
19294         is_ipv6 = 1;
19295       else
19296         break;
19297     }
19298
19299   if (sw_if_index == ~0)
19300     {
19301       errmsg ("missing interface name or sw_if_index");
19302       return -99;
19303     }
19304
19305   M (IP_NEIGHBOR_DUMP, mp);
19306   mp->is_ipv6 = (u8) is_ipv6;
19307   mp->sw_if_index = ntohl (sw_if_index);
19308   S (mp);
19309
19310   /* Use a control ping for synchronization */
19311   MPING (CONTROL_PING, mp_ping);
19312   S (mp_ping);
19313
19314   W (ret);
19315   return ret;
19316 }
19317
19318 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
19319 #define vl_api_ip6_fib_details_t_print vl_noop_handler
19320
19321 static void
19322 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
19323 {
19324   vat_main_t *vam = &vat_main;
19325   int count = ntohl (mp->count);
19326   vl_api_fib_path_t *fp;
19327   int i;
19328
19329   print (vam->ofp,
19330          "table-id %d, prefix %U/%d stats-index %d",
19331          ntohl (mp->table_id), format_ip6_address, mp->address,
19332          mp->address_length, ntohl (mp->stats_index));
19333   fp = mp->path;
19334   for (i = 0; i < count; i++)
19335     {
19336       if (fp->afi == IP46_TYPE_IP6)
19337         print (vam->ofp,
19338                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19339                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19340                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19341                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19342                format_ip6_address, fp->next_hop);
19343       else if (fp->afi == IP46_TYPE_IP4)
19344         print (vam->ofp,
19345                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19346                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19347                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19348                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19349                format_ip4_address, fp->next_hop);
19350       fp++;
19351     }
19352 }
19353
19354 static void vl_api_ip6_fib_details_t_handler_json
19355   (vl_api_ip6_fib_details_t * mp)
19356 {
19357   vat_main_t *vam = &vat_main;
19358   int count = ntohl (mp->count);
19359   vat_json_node_t *node = NULL;
19360   struct in_addr ip4;
19361   struct in6_addr ip6;
19362   vl_api_fib_path_t *fp;
19363   int i;
19364
19365   if (VAT_JSON_ARRAY != vam->json_tree.type)
19366     {
19367       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19368       vat_json_init_array (&vam->json_tree);
19369     }
19370   node = vat_json_array_add (&vam->json_tree);
19371
19372   vat_json_init_object (node);
19373   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19374   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
19375   vat_json_object_add_ip6 (node, "prefix", ip6);
19376   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19377   vat_json_object_add_uint (node, "path_count", count);
19378   fp = mp->path;
19379   for (i = 0; i < count; i++)
19380     {
19381       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19382       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19383       vat_json_object_add_uint (node, "is_local", fp->is_local);
19384       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19385       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19386       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19387       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19388       if (fp->afi == IP46_TYPE_IP4)
19389         {
19390           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19391           vat_json_object_add_ip4 (node, "next_hop", ip4);
19392         }
19393       else if (fp->afi == IP46_TYPE_IP6)
19394         {
19395           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19396           vat_json_object_add_ip6 (node, "next_hop", ip6);
19397         }
19398     }
19399 }
19400
19401 static int
19402 api_ip6_fib_dump (vat_main_t * vam)
19403 {
19404   vl_api_ip6_fib_dump_t *mp;
19405   vl_api_control_ping_t *mp_ping;
19406   int ret;
19407
19408   M (IP6_FIB_DUMP, mp);
19409   S (mp);
19410
19411   /* Use a control ping for synchronization */
19412   MPING (CONTROL_PING, mp_ping);
19413   S (mp_ping);
19414
19415   W (ret);
19416   return ret;
19417 }
19418
19419 static int
19420 api_ip6_mfib_dump (vat_main_t * vam)
19421 {
19422   vl_api_ip6_mfib_dump_t *mp;
19423   vl_api_control_ping_t *mp_ping;
19424   int ret;
19425
19426   M (IP6_MFIB_DUMP, mp);
19427   S (mp);
19428
19429   /* Use a control ping for synchronization */
19430   MPING (CONTROL_PING, mp_ping);
19431   S (mp_ping);
19432
19433   W (ret);
19434   return ret;
19435 }
19436
19437 int
19438 api_classify_table_ids (vat_main_t * vam)
19439 {
19440   vl_api_classify_table_ids_t *mp;
19441   int ret;
19442
19443   /* Construct the API message */
19444   M (CLASSIFY_TABLE_IDS, mp);
19445   mp->context = 0;
19446
19447   S (mp);
19448   W (ret);
19449   return ret;
19450 }
19451
19452 int
19453 api_classify_table_by_interface (vat_main_t * vam)
19454 {
19455   unformat_input_t *input = vam->input;
19456   vl_api_classify_table_by_interface_t *mp;
19457
19458   u32 sw_if_index = ~0;
19459   int ret;
19460   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19461     {
19462       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19463         ;
19464       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19465         ;
19466       else
19467         break;
19468     }
19469   if (sw_if_index == ~0)
19470     {
19471       errmsg ("missing interface name or sw_if_index");
19472       return -99;
19473     }
19474
19475   /* Construct the API message */
19476   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
19477   mp->context = 0;
19478   mp->sw_if_index = ntohl (sw_if_index);
19479
19480   S (mp);
19481   W (ret);
19482   return ret;
19483 }
19484
19485 int
19486 api_classify_table_info (vat_main_t * vam)
19487 {
19488   unformat_input_t *input = vam->input;
19489   vl_api_classify_table_info_t *mp;
19490
19491   u32 table_id = ~0;
19492   int ret;
19493   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19494     {
19495       if (unformat (input, "table_id %d", &table_id))
19496         ;
19497       else
19498         break;
19499     }
19500   if (table_id == ~0)
19501     {
19502       errmsg ("missing table id");
19503       return -99;
19504     }
19505
19506   /* Construct the API message */
19507   M (CLASSIFY_TABLE_INFO, mp);
19508   mp->context = 0;
19509   mp->table_id = ntohl (table_id);
19510
19511   S (mp);
19512   W (ret);
19513   return ret;
19514 }
19515
19516 int
19517 api_classify_session_dump (vat_main_t * vam)
19518 {
19519   unformat_input_t *input = vam->input;
19520   vl_api_classify_session_dump_t *mp;
19521   vl_api_control_ping_t *mp_ping;
19522
19523   u32 table_id = ~0;
19524   int ret;
19525   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19526     {
19527       if (unformat (input, "table_id %d", &table_id))
19528         ;
19529       else
19530         break;
19531     }
19532   if (table_id == ~0)
19533     {
19534       errmsg ("missing table id");
19535       return -99;
19536     }
19537
19538   /* Construct the API message */
19539   M (CLASSIFY_SESSION_DUMP, mp);
19540   mp->context = 0;
19541   mp->table_id = ntohl (table_id);
19542   S (mp);
19543
19544   /* Use a control ping for synchronization */
19545   MPING (CONTROL_PING, mp_ping);
19546   S (mp_ping);
19547
19548   W (ret);
19549   return ret;
19550 }
19551
19552 static void
19553 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19554 {
19555   vat_main_t *vam = &vat_main;
19556
19557   print (vam->ofp, "collector_address %U, collector_port %d, "
19558          "src_address %U, vrf_id %d, path_mtu %u, "
19559          "template_interval %u, udp_checksum %d",
19560          format_ip4_address, mp->collector_address,
19561          ntohs (mp->collector_port),
19562          format_ip4_address, mp->src_address,
19563          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19564          ntohl (mp->template_interval), mp->udp_checksum);
19565
19566   vam->retval = 0;
19567   vam->result_ready = 1;
19568 }
19569
19570 static void
19571   vl_api_ipfix_exporter_details_t_handler_json
19572   (vl_api_ipfix_exporter_details_t * mp)
19573 {
19574   vat_main_t *vam = &vat_main;
19575   vat_json_node_t node;
19576   struct in_addr collector_address;
19577   struct in_addr src_address;
19578
19579   vat_json_init_object (&node);
19580   clib_memcpy (&collector_address, &mp->collector_address,
19581                sizeof (collector_address));
19582   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19583   vat_json_object_add_uint (&node, "collector_port",
19584                             ntohs (mp->collector_port));
19585   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19586   vat_json_object_add_ip4 (&node, "src_address", src_address);
19587   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19588   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19589   vat_json_object_add_uint (&node, "template_interval",
19590                             ntohl (mp->template_interval));
19591   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19592
19593   vat_json_print (vam->ofp, &node);
19594   vat_json_free (&node);
19595   vam->retval = 0;
19596   vam->result_ready = 1;
19597 }
19598
19599 int
19600 api_ipfix_exporter_dump (vat_main_t * vam)
19601 {
19602   vl_api_ipfix_exporter_dump_t *mp;
19603   int ret;
19604
19605   /* Construct the API message */
19606   M (IPFIX_EXPORTER_DUMP, mp);
19607   mp->context = 0;
19608
19609   S (mp);
19610   W (ret);
19611   return ret;
19612 }
19613
19614 static int
19615 api_ipfix_classify_stream_dump (vat_main_t * vam)
19616 {
19617   vl_api_ipfix_classify_stream_dump_t *mp;
19618   int ret;
19619
19620   /* Construct the API message */
19621   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19622   mp->context = 0;
19623
19624   S (mp);
19625   W (ret);
19626   return ret;
19627   /* NOTREACHED */
19628   return 0;
19629 }
19630
19631 static void
19632   vl_api_ipfix_classify_stream_details_t_handler
19633   (vl_api_ipfix_classify_stream_details_t * mp)
19634 {
19635   vat_main_t *vam = &vat_main;
19636   print (vam->ofp, "domain_id %d, src_port %d",
19637          ntohl (mp->domain_id), ntohs (mp->src_port));
19638   vam->retval = 0;
19639   vam->result_ready = 1;
19640 }
19641
19642 static void
19643   vl_api_ipfix_classify_stream_details_t_handler_json
19644   (vl_api_ipfix_classify_stream_details_t * mp)
19645 {
19646   vat_main_t *vam = &vat_main;
19647   vat_json_node_t node;
19648
19649   vat_json_init_object (&node);
19650   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19651   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19652
19653   vat_json_print (vam->ofp, &node);
19654   vat_json_free (&node);
19655   vam->retval = 0;
19656   vam->result_ready = 1;
19657 }
19658
19659 static int
19660 api_ipfix_classify_table_dump (vat_main_t * vam)
19661 {
19662   vl_api_ipfix_classify_table_dump_t *mp;
19663   vl_api_control_ping_t *mp_ping;
19664   int ret;
19665
19666   if (!vam->json_output)
19667     {
19668       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19669              "transport_protocol");
19670     }
19671
19672   /* Construct the API message */
19673   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19674
19675   /* send it... */
19676   S (mp);
19677
19678   /* Use a control ping for synchronization */
19679   MPING (CONTROL_PING, mp_ping);
19680   S (mp_ping);
19681
19682   W (ret);
19683   return ret;
19684 }
19685
19686 static void
19687   vl_api_ipfix_classify_table_details_t_handler
19688   (vl_api_ipfix_classify_table_details_t * mp)
19689 {
19690   vat_main_t *vam = &vat_main;
19691   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19692          mp->transport_protocol);
19693 }
19694
19695 static void
19696   vl_api_ipfix_classify_table_details_t_handler_json
19697   (vl_api_ipfix_classify_table_details_t * mp)
19698 {
19699   vat_json_node_t *node = NULL;
19700   vat_main_t *vam = &vat_main;
19701
19702   if (VAT_JSON_ARRAY != vam->json_tree.type)
19703     {
19704       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19705       vat_json_init_array (&vam->json_tree);
19706     }
19707
19708   node = vat_json_array_add (&vam->json_tree);
19709   vat_json_init_object (node);
19710
19711   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19712   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19713   vat_json_object_add_uint (node, "transport_protocol",
19714                             mp->transport_protocol);
19715 }
19716
19717 static int
19718 api_sw_interface_span_enable_disable (vat_main_t * vam)
19719 {
19720   unformat_input_t *i = vam->input;
19721   vl_api_sw_interface_span_enable_disable_t *mp;
19722   u32 src_sw_if_index = ~0;
19723   u32 dst_sw_if_index = ~0;
19724   u8 state = 3;
19725   int ret;
19726   u8 is_l2 = 0;
19727
19728   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19729     {
19730       if (unformat
19731           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19732         ;
19733       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19734         ;
19735       else
19736         if (unformat
19737             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19738         ;
19739       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19740         ;
19741       else if (unformat (i, "disable"))
19742         state = 0;
19743       else if (unformat (i, "rx"))
19744         state = 1;
19745       else if (unformat (i, "tx"))
19746         state = 2;
19747       else if (unformat (i, "both"))
19748         state = 3;
19749       else if (unformat (i, "l2"))
19750         is_l2 = 1;
19751       else
19752         break;
19753     }
19754
19755   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19756
19757   mp->sw_if_index_from = htonl (src_sw_if_index);
19758   mp->sw_if_index_to = htonl (dst_sw_if_index);
19759   mp->state = state;
19760   mp->is_l2 = is_l2;
19761
19762   S (mp);
19763   W (ret);
19764   return ret;
19765 }
19766
19767 static void
19768 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19769                                             * mp)
19770 {
19771   vat_main_t *vam = &vat_main;
19772   u8 *sw_if_from_name = 0;
19773   u8 *sw_if_to_name = 0;
19774   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19775   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19776   char *states[] = { "none", "rx", "tx", "both" };
19777   hash_pair_t *p;
19778
19779   /* *INDENT-OFF* */
19780   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19781   ({
19782     if ((u32) p->value[0] == sw_if_index_from)
19783       {
19784         sw_if_from_name = (u8 *)(p->key);
19785         if (sw_if_to_name)
19786           break;
19787       }
19788     if ((u32) p->value[0] == sw_if_index_to)
19789       {
19790         sw_if_to_name = (u8 *)(p->key);
19791         if (sw_if_from_name)
19792           break;
19793       }
19794   }));
19795   /* *INDENT-ON* */
19796   print (vam->ofp, "%20s => %20s (%s) %s",
19797          sw_if_from_name, sw_if_to_name, states[mp->state],
19798          mp->is_l2 ? "l2" : "device");
19799 }
19800
19801 static void
19802   vl_api_sw_interface_span_details_t_handler_json
19803   (vl_api_sw_interface_span_details_t * mp)
19804 {
19805   vat_main_t *vam = &vat_main;
19806   vat_json_node_t *node = NULL;
19807   u8 *sw_if_from_name = 0;
19808   u8 *sw_if_to_name = 0;
19809   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19810   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19811   hash_pair_t *p;
19812
19813   /* *INDENT-OFF* */
19814   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19815   ({
19816     if ((u32) p->value[0] == sw_if_index_from)
19817       {
19818         sw_if_from_name = (u8 *)(p->key);
19819         if (sw_if_to_name)
19820           break;
19821       }
19822     if ((u32) p->value[0] == sw_if_index_to)
19823       {
19824         sw_if_to_name = (u8 *)(p->key);
19825         if (sw_if_from_name)
19826           break;
19827       }
19828   }));
19829   /* *INDENT-ON* */
19830
19831   if (VAT_JSON_ARRAY != vam->json_tree.type)
19832     {
19833       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19834       vat_json_init_array (&vam->json_tree);
19835     }
19836   node = vat_json_array_add (&vam->json_tree);
19837
19838   vat_json_init_object (node);
19839   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
19840   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
19841   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
19842   if (0 != sw_if_to_name)
19843     {
19844       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
19845     }
19846   vat_json_object_add_uint (node, "state", mp->state);
19847   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
19848 }
19849
19850 static int
19851 api_sw_interface_span_dump (vat_main_t * vam)
19852 {
19853   unformat_input_t *input = vam->input;
19854   vl_api_sw_interface_span_dump_t *mp;
19855   vl_api_control_ping_t *mp_ping;
19856   u8 is_l2 = 0;
19857   int ret;
19858
19859   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19860     {
19861       if (unformat (input, "l2"))
19862         is_l2 = 1;
19863       else
19864         break;
19865     }
19866
19867   M (SW_INTERFACE_SPAN_DUMP, mp);
19868   mp->is_l2 = is_l2;
19869   S (mp);
19870
19871   /* Use a control ping for synchronization */
19872   MPING (CONTROL_PING, mp_ping);
19873   S (mp_ping);
19874
19875   W (ret);
19876   return ret;
19877 }
19878
19879 int
19880 api_pg_create_interface (vat_main_t * vam)
19881 {
19882   unformat_input_t *input = vam->input;
19883   vl_api_pg_create_interface_t *mp;
19884
19885   u32 if_id = ~0;
19886   int ret;
19887   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19888     {
19889       if (unformat (input, "if_id %d", &if_id))
19890         ;
19891       else
19892         break;
19893     }
19894   if (if_id == ~0)
19895     {
19896       errmsg ("missing pg interface index");
19897       return -99;
19898     }
19899
19900   /* Construct the API message */
19901   M (PG_CREATE_INTERFACE, mp);
19902   mp->context = 0;
19903   mp->interface_id = ntohl (if_id);
19904
19905   S (mp);
19906   W (ret);
19907   return ret;
19908 }
19909
19910 int
19911 api_pg_capture (vat_main_t * vam)
19912 {
19913   unformat_input_t *input = vam->input;
19914   vl_api_pg_capture_t *mp;
19915
19916   u32 if_id = ~0;
19917   u8 enable = 1;
19918   u32 count = 1;
19919   u8 pcap_file_set = 0;
19920   u8 *pcap_file = 0;
19921   int ret;
19922   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19923     {
19924       if (unformat (input, "if_id %d", &if_id))
19925         ;
19926       else if (unformat (input, "pcap %s", &pcap_file))
19927         pcap_file_set = 1;
19928       else if (unformat (input, "count %d", &count))
19929         ;
19930       else if (unformat (input, "disable"))
19931         enable = 0;
19932       else
19933         break;
19934     }
19935   if (if_id == ~0)
19936     {
19937       errmsg ("missing pg interface index");
19938       return -99;
19939     }
19940   if (pcap_file_set > 0)
19941     {
19942       if (vec_len (pcap_file) > 255)
19943         {
19944           errmsg ("pcap file name is too long");
19945           return -99;
19946         }
19947     }
19948
19949   u32 name_len = vec_len (pcap_file);
19950   /* Construct the API message */
19951   M (PG_CAPTURE, mp);
19952   mp->context = 0;
19953   mp->interface_id = ntohl (if_id);
19954   mp->is_enabled = enable;
19955   mp->count = ntohl (count);
19956   mp->pcap_name_length = ntohl (name_len);
19957   if (pcap_file_set != 0)
19958     {
19959       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
19960     }
19961   vec_free (pcap_file);
19962
19963   S (mp);
19964   W (ret);
19965   return ret;
19966 }
19967
19968 int
19969 api_pg_enable_disable (vat_main_t * vam)
19970 {
19971   unformat_input_t *input = vam->input;
19972   vl_api_pg_enable_disable_t *mp;
19973
19974   u8 enable = 1;
19975   u8 stream_name_set = 0;
19976   u8 *stream_name = 0;
19977   int ret;
19978   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19979     {
19980       if (unformat (input, "stream %s", &stream_name))
19981         stream_name_set = 1;
19982       else if (unformat (input, "disable"))
19983         enable = 0;
19984       else
19985         break;
19986     }
19987
19988   if (stream_name_set > 0)
19989     {
19990       if (vec_len (stream_name) > 255)
19991         {
19992           errmsg ("stream name too long");
19993           return -99;
19994         }
19995     }
19996
19997   u32 name_len = vec_len (stream_name);
19998   /* Construct the API message */
19999   M (PG_ENABLE_DISABLE, mp);
20000   mp->context = 0;
20001   mp->is_enabled = enable;
20002   if (stream_name_set != 0)
20003     {
20004       mp->stream_name_length = ntohl (name_len);
20005       clib_memcpy (mp->stream_name, stream_name, name_len);
20006     }
20007   vec_free (stream_name);
20008
20009   S (mp);
20010   W (ret);
20011   return ret;
20012 }
20013
20014 int
20015 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
20016 {
20017   unformat_input_t *input = vam->input;
20018   vl_api_ip_source_and_port_range_check_add_del_t *mp;
20019
20020   u16 *low_ports = 0;
20021   u16 *high_ports = 0;
20022   u16 this_low;
20023   u16 this_hi;
20024   vl_api_prefix_t prefix;
20025   u32 tmp, tmp2;
20026   u8 prefix_set = 0;
20027   u32 vrf_id = ~0;
20028   u8 is_add = 1;
20029   int ret;
20030
20031   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20032     {
20033       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
20034         prefix_set = 1;
20035       else if (unformat (input, "vrf %d", &vrf_id))
20036         ;
20037       else if (unformat (input, "del"))
20038         is_add = 0;
20039       else if (unformat (input, "port %d", &tmp))
20040         {
20041           if (tmp == 0 || tmp > 65535)
20042             {
20043               errmsg ("port %d out of range", tmp);
20044               return -99;
20045             }
20046           this_low = tmp;
20047           this_hi = this_low + 1;
20048           vec_add1 (low_ports, this_low);
20049           vec_add1 (high_ports, this_hi);
20050         }
20051       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
20052         {
20053           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
20054             {
20055               errmsg ("incorrect range parameters");
20056               return -99;
20057             }
20058           this_low = tmp;
20059           /* Note: in debug CLI +1 is added to high before
20060              passing to real fn that does "the work"
20061              (ip_source_and_port_range_check_add_del).
20062              This fn is a wrapper around the binary API fn a
20063              control plane will call, which expects this increment
20064              to have occurred. Hence letting the binary API control
20065              plane fn do the increment for consistency between VAT
20066              and other control planes.
20067            */
20068           this_hi = tmp2;
20069           vec_add1 (low_ports, this_low);
20070           vec_add1 (high_ports, this_hi);
20071         }
20072       else
20073         break;
20074     }
20075
20076   if (prefix_set == 0)
20077     {
20078       errmsg ("<address>/<mask> not specified");
20079       return -99;
20080     }
20081
20082   if (vrf_id == ~0)
20083     {
20084       errmsg ("VRF ID required, not specified");
20085       return -99;
20086     }
20087
20088   if (vrf_id == 0)
20089     {
20090       errmsg
20091         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20092       return -99;
20093     }
20094
20095   if (vec_len (low_ports) == 0)
20096     {
20097       errmsg ("At least one port or port range required");
20098       return -99;
20099     }
20100
20101   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
20102
20103   mp->is_add = is_add;
20104
20105   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
20106
20107   mp->number_of_ranges = vec_len (low_ports);
20108
20109   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
20110   vec_free (low_ports);
20111
20112   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
20113   vec_free (high_ports);
20114
20115   mp->vrf_id = ntohl (vrf_id);
20116
20117   S (mp);
20118   W (ret);
20119   return ret;
20120 }
20121
20122 int
20123 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
20124 {
20125   unformat_input_t *input = vam->input;
20126   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
20127   u32 sw_if_index = ~0;
20128   int vrf_set = 0;
20129   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
20130   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
20131   u8 is_add = 1;
20132   int ret;
20133
20134   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20135     {
20136       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20137         ;
20138       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20139         ;
20140       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
20141         vrf_set = 1;
20142       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
20143         vrf_set = 1;
20144       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
20145         vrf_set = 1;
20146       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
20147         vrf_set = 1;
20148       else if (unformat (input, "del"))
20149         is_add = 0;
20150       else
20151         break;
20152     }
20153
20154   if (sw_if_index == ~0)
20155     {
20156       errmsg ("Interface required but not specified");
20157       return -99;
20158     }
20159
20160   if (vrf_set == 0)
20161     {
20162       errmsg ("VRF ID required but not specified");
20163       return -99;
20164     }
20165
20166   if (tcp_out_vrf_id == 0
20167       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
20168     {
20169       errmsg
20170         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20171       return -99;
20172     }
20173
20174   /* Construct the API message */
20175   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20176
20177   mp->sw_if_index = ntohl (sw_if_index);
20178   mp->is_add = is_add;
20179   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20180   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20181   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20182   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20183
20184   /* send it... */
20185   S (mp);
20186
20187   /* Wait for a reply... */
20188   W (ret);
20189   return ret;
20190 }
20191
20192 static int
20193 api_ipsec_gre_tunnel_add_del (vat_main_t * vam)
20194 {
20195   unformat_input_t *i = vam->input;
20196   vl_api_ipsec_gre_tunnel_add_del_t *mp;
20197   u32 local_sa_id = 0;
20198   u32 remote_sa_id = 0;
20199   vl_api_ip4_address_t src_address;
20200   vl_api_ip4_address_t dst_address;
20201   u8 is_add = 1;
20202   int ret;
20203
20204   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20205     {
20206       if (unformat (i, "local_sa %d", &local_sa_id))
20207         ;
20208       else if (unformat (i, "remote_sa %d", &remote_sa_id))
20209         ;
20210       else
20211         if (unformat (i, "src %U", unformat_vl_api_ip4_address, &src_address))
20212         ;
20213       else
20214         if (unformat (i, "dst %U", unformat_vl_api_ip4_address, &dst_address))
20215         ;
20216       else if (unformat (i, "del"))
20217         is_add = 0;
20218       else
20219         {
20220           clib_warning ("parse error '%U'", format_unformat_error, i);
20221           return -99;
20222         }
20223     }
20224
20225   M (IPSEC_GRE_TUNNEL_ADD_DEL, mp);
20226
20227   mp->tunnel.local_sa_id = ntohl (local_sa_id);
20228   mp->tunnel.remote_sa_id = ntohl (remote_sa_id);
20229   clib_memcpy (mp->tunnel.src, &src_address, sizeof (src_address));
20230   clib_memcpy (mp->tunnel.dst, &dst_address, sizeof (dst_address));
20231   mp->is_add = is_add;
20232
20233   S (mp);
20234   W (ret);
20235   return ret;
20236 }
20237
20238 static int
20239 api_set_punt (vat_main_t * vam)
20240 {
20241   unformat_input_t *i = vam->input;
20242   vl_api_address_family_t af;
20243   vl_api_set_punt_t *mp;
20244   u32 protocol = ~0;
20245   u32 port = ~0;
20246   int is_add = 1;
20247   int ret;
20248
20249   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20250     {
20251       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
20252         ;
20253       else if (unformat (i, "protocol %d", &protocol))
20254         ;
20255       else if (unformat (i, "port %d", &port))
20256         ;
20257       else if (unformat (i, "del"))
20258         is_add = 0;
20259       else
20260         {
20261           clib_warning ("parse error '%U'", format_unformat_error, i);
20262           return -99;
20263         }
20264     }
20265
20266   M (SET_PUNT, mp);
20267
20268   mp->is_add = (u8) is_add;
20269   mp->punt.type = PUNT_API_TYPE_L4;
20270   mp->punt.punt.l4.af = af;
20271   mp->punt.punt.l4.protocol = (u8) protocol;
20272   mp->punt.punt.l4.port = htons ((u16) port);
20273
20274   S (mp);
20275   W (ret);
20276   return ret;
20277 }
20278
20279 static void vl_api_ipsec_gre_tunnel_details_t_handler
20280   (vl_api_ipsec_gre_tunnel_details_t * mp)
20281 {
20282   vat_main_t *vam = &vat_main;
20283
20284   print (vam->ofp, "%11d%15U%15U%14d%14d",
20285          ntohl (mp->tunnel.sw_if_index),
20286          format_vl_api_ip4_address, mp->tunnel.src,
20287          format_vl_api_ip4_address, mp->tunnel.dst,
20288          ntohl (mp->tunnel.local_sa_id), ntohl (mp->tunnel.remote_sa_id));
20289 }
20290
20291 static void
20292 vat_json_object_add_vl_api_ip4 (vat_json_node_t * node,
20293                                 const char *name,
20294                                 const vl_api_ip4_address_t addr)
20295 {
20296   struct in_addr ip4;
20297
20298   clib_memcpy (&ip4, addr, sizeof (ip4));
20299   vat_json_object_add_ip4 (node, name, ip4);
20300 }
20301
20302 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
20303   (vl_api_ipsec_gre_tunnel_details_t * mp)
20304 {
20305   vat_main_t *vam = &vat_main;
20306   vat_json_node_t *node = NULL;
20307
20308   if (VAT_JSON_ARRAY != vam->json_tree.type)
20309     {
20310       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20311       vat_json_init_array (&vam->json_tree);
20312     }
20313   node = vat_json_array_add (&vam->json_tree);
20314
20315   vat_json_init_object (node);
20316   vat_json_object_add_uint (node, "sw_if_index",
20317                             ntohl (mp->tunnel.sw_if_index));
20318   vat_json_object_add_vl_api_ip4 (node, "src", mp->tunnel.src);
20319   vat_json_object_add_vl_api_ip4 (node, "src", mp->tunnel.dst);
20320   vat_json_object_add_uint (node, "local_sa_id",
20321                             ntohl (mp->tunnel.local_sa_id));
20322   vat_json_object_add_uint (node, "remote_sa_id",
20323                             ntohl (mp->tunnel.remote_sa_id));
20324 }
20325
20326 static int
20327 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
20328 {
20329   unformat_input_t *i = vam->input;
20330   vl_api_ipsec_gre_tunnel_dump_t *mp;
20331   vl_api_control_ping_t *mp_ping;
20332   u32 sw_if_index;
20333   u8 sw_if_index_set = 0;
20334   int ret;
20335
20336   /* Parse args required to build the message */
20337   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20338     {
20339       if (unformat (i, "sw_if_index %d", &sw_if_index))
20340         sw_if_index_set = 1;
20341       else
20342         break;
20343     }
20344
20345   if (sw_if_index_set == 0)
20346     {
20347       sw_if_index = ~0;
20348     }
20349
20350   if (!vam->json_output)
20351     {
20352       print (vam->ofp, "%11s%15s%15s%14s%14s",
20353              "sw_if_index", "src_address", "dst_address",
20354              "local_sa_id", "remote_sa_id");
20355     }
20356
20357   /* Get list of gre-tunnel interfaces */
20358   M (IPSEC_GRE_TUNNEL_DUMP, mp);
20359
20360   mp->sw_if_index = htonl (sw_if_index);
20361
20362   S (mp);
20363
20364   /* Use a control ping for synchronization */
20365   MPING (CONTROL_PING, mp_ping);
20366   S (mp_ping);
20367
20368   W (ret);
20369   return ret;
20370 }
20371
20372 static int
20373 api_delete_subif (vat_main_t * vam)
20374 {
20375   unformat_input_t *i = vam->input;
20376   vl_api_delete_subif_t *mp;
20377   u32 sw_if_index = ~0;
20378   int ret;
20379
20380   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20381     {
20382       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20383         ;
20384       if (unformat (i, "sw_if_index %d", &sw_if_index))
20385         ;
20386       else
20387         break;
20388     }
20389
20390   if (sw_if_index == ~0)
20391     {
20392       errmsg ("missing sw_if_index");
20393       return -99;
20394     }
20395
20396   /* Construct the API message */
20397   M (DELETE_SUBIF, mp);
20398   mp->sw_if_index = ntohl (sw_if_index);
20399
20400   S (mp);
20401   W (ret);
20402   return ret;
20403 }
20404
20405 #define foreach_pbb_vtr_op      \
20406 _("disable",  L2_VTR_DISABLED)  \
20407 _("pop",  L2_VTR_POP_2)         \
20408 _("push",  L2_VTR_PUSH_2)
20409
20410 static int
20411 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
20412 {
20413   unformat_input_t *i = vam->input;
20414   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
20415   u32 sw_if_index = ~0, vtr_op = ~0;
20416   u16 outer_tag = ~0;
20417   u8 dmac[6], smac[6];
20418   u8 dmac_set = 0, smac_set = 0;
20419   u16 vlanid = 0;
20420   u32 sid = ~0;
20421   u32 tmp;
20422   int ret;
20423
20424   /* Shut up coverity */
20425   clib_memset (dmac, 0, sizeof (dmac));
20426   clib_memset (smac, 0, sizeof (smac));
20427
20428   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20429     {
20430       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20431         ;
20432       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20433         ;
20434       else if (unformat (i, "vtr_op %d", &vtr_op))
20435         ;
20436 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
20437       foreach_pbb_vtr_op
20438 #undef _
20439         else if (unformat (i, "translate_pbb_stag"))
20440         {
20441           if (unformat (i, "%d", &tmp))
20442             {
20443               vtr_op = L2_VTR_TRANSLATE_2_1;
20444               outer_tag = tmp;
20445             }
20446           else
20447             {
20448               errmsg
20449                 ("translate_pbb_stag operation requires outer tag definition");
20450               return -99;
20451             }
20452         }
20453       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
20454         dmac_set++;
20455       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
20456         smac_set++;
20457       else if (unformat (i, "sid %d", &sid))
20458         ;
20459       else if (unformat (i, "vlanid %d", &tmp))
20460         vlanid = tmp;
20461       else
20462         {
20463           clib_warning ("parse error '%U'", format_unformat_error, i);
20464           return -99;
20465         }
20466     }
20467
20468   if ((sw_if_index == ~0) || (vtr_op == ~0))
20469     {
20470       errmsg ("missing sw_if_index or vtr operation");
20471       return -99;
20472     }
20473   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
20474       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
20475     {
20476       errmsg
20477         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
20478       return -99;
20479     }
20480
20481   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
20482   mp->sw_if_index = ntohl (sw_if_index);
20483   mp->vtr_op = ntohl (vtr_op);
20484   mp->outer_tag = ntohs (outer_tag);
20485   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
20486   clib_memcpy (mp->b_smac, smac, sizeof (smac));
20487   mp->b_vlanid = ntohs (vlanid);
20488   mp->i_sid = ntohl (sid);
20489
20490   S (mp);
20491   W (ret);
20492   return ret;
20493 }
20494
20495 static int
20496 api_flow_classify_set_interface (vat_main_t * vam)
20497 {
20498   unformat_input_t *i = vam->input;
20499   vl_api_flow_classify_set_interface_t *mp;
20500   u32 sw_if_index;
20501   int sw_if_index_set;
20502   u32 ip4_table_index = ~0;
20503   u32 ip6_table_index = ~0;
20504   u8 is_add = 1;
20505   int ret;
20506
20507   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20508     {
20509       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20510         sw_if_index_set = 1;
20511       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20512         sw_if_index_set = 1;
20513       else if (unformat (i, "del"))
20514         is_add = 0;
20515       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20516         ;
20517       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20518         ;
20519       else
20520         {
20521           clib_warning ("parse error '%U'", format_unformat_error, i);
20522           return -99;
20523         }
20524     }
20525
20526   if (sw_if_index_set == 0)
20527     {
20528       errmsg ("missing interface name or sw_if_index");
20529       return -99;
20530     }
20531
20532   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
20533
20534   mp->sw_if_index = ntohl (sw_if_index);
20535   mp->ip4_table_index = ntohl (ip4_table_index);
20536   mp->ip6_table_index = ntohl (ip6_table_index);
20537   mp->is_add = is_add;
20538
20539   S (mp);
20540   W (ret);
20541   return ret;
20542 }
20543
20544 static int
20545 api_flow_classify_dump (vat_main_t * vam)
20546 {
20547   unformat_input_t *i = vam->input;
20548   vl_api_flow_classify_dump_t *mp;
20549   vl_api_control_ping_t *mp_ping;
20550   u8 type = FLOW_CLASSIFY_N_TABLES;
20551   int ret;
20552
20553   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
20554     ;
20555   else
20556     {
20557       errmsg ("classify table type must be specified");
20558       return -99;
20559     }
20560
20561   if (!vam->json_output)
20562     {
20563       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20564     }
20565
20566   M (FLOW_CLASSIFY_DUMP, mp);
20567   mp->type = type;
20568   /* send it... */
20569   S (mp);
20570
20571   /* Use a control ping for synchronization */
20572   MPING (CONTROL_PING, mp_ping);
20573   S (mp_ping);
20574
20575   /* Wait for a reply... */
20576   W (ret);
20577   return ret;
20578 }
20579
20580 static int
20581 api_feature_enable_disable (vat_main_t * vam)
20582 {
20583   unformat_input_t *i = vam->input;
20584   vl_api_feature_enable_disable_t *mp;
20585   u8 *arc_name = 0;
20586   u8 *feature_name = 0;
20587   u32 sw_if_index = ~0;
20588   u8 enable = 1;
20589   int ret;
20590
20591   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20592     {
20593       if (unformat (i, "arc_name %s", &arc_name))
20594         ;
20595       else if (unformat (i, "feature_name %s", &feature_name))
20596         ;
20597       else
20598         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20599         ;
20600       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20601         ;
20602       else if (unformat (i, "disable"))
20603         enable = 0;
20604       else
20605         break;
20606     }
20607
20608   if (arc_name == 0)
20609     {
20610       errmsg ("missing arc name");
20611       return -99;
20612     }
20613   if (vec_len (arc_name) > 63)
20614     {
20615       errmsg ("arc name too long");
20616     }
20617
20618   if (feature_name == 0)
20619     {
20620       errmsg ("missing feature name");
20621       return -99;
20622     }
20623   if (vec_len (feature_name) > 63)
20624     {
20625       errmsg ("feature name too long");
20626     }
20627
20628   if (sw_if_index == ~0)
20629     {
20630       errmsg ("missing interface name or sw_if_index");
20631       return -99;
20632     }
20633
20634   /* Construct the API message */
20635   M (FEATURE_ENABLE_DISABLE, mp);
20636   mp->sw_if_index = ntohl (sw_if_index);
20637   mp->enable = enable;
20638   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
20639   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
20640   vec_free (arc_name);
20641   vec_free (feature_name);
20642
20643   S (mp);
20644   W (ret);
20645   return ret;
20646 }
20647
20648 static int
20649 api_sw_interface_tag_add_del (vat_main_t * vam)
20650 {
20651   unformat_input_t *i = vam->input;
20652   vl_api_sw_interface_tag_add_del_t *mp;
20653   u32 sw_if_index = ~0;
20654   u8 *tag = 0;
20655   u8 enable = 1;
20656   int ret;
20657
20658   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20659     {
20660       if (unformat (i, "tag %s", &tag))
20661         ;
20662       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20663         ;
20664       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20665         ;
20666       else if (unformat (i, "del"))
20667         enable = 0;
20668       else
20669         break;
20670     }
20671
20672   if (sw_if_index == ~0)
20673     {
20674       errmsg ("missing interface name or sw_if_index");
20675       return -99;
20676     }
20677
20678   if (enable && (tag == 0))
20679     {
20680       errmsg ("no tag specified");
20681       return -99;
20682     }
20683
20684   /* Construct the API message */
20685   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20686   mp->sw_if_index = ntohl (sw_if_index);
20687   mp->is_add = enable;
20688   if (enable)
20689     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
20690   vec_free (tag);
20691
20692   S (mp);
20693   W (ret);
20694   return ret;
20695 }
20696
20697 static void vl_api_l2_xconnect_details_t_handler
20698   (vl_api_l2_xconnect_details_t * mp)
20699 {
20700   vat_main_t *vam = &vat_main;
20701
20702   print (vam->ofp, "%15d%15d",
20703          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20704 }
20705
20706 static void vl_api_l2_xconnect_details_t_handler_json
20707   (vl_api_l2_xconnect_details_t * mp)
20708 {
20709   vat_main_t *vam = &vat_main;
20710   vat_json_node_t *node = NULL;
20711
20712   if (VAT_JSON_ARRAY != vam->json_tree.type)
20713     {
20714       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20715       vat_json_init_array (&vam->json_tree);
20716     }
20717   node = vat_json_array_add (&vam->json_tree);
20718
20719   vat_json_init_object (node);
20720   vat_json_object_add_uint (node, "rx_sw_if_index",
20721                             ntohl (mp->rx_sw_if_index));
20722   vat_json_object_add_uint (node, "tx_sw_if_index",
20723                             ntohl (mp->tx_sw_if_index));
20724 }
20725
20726 static int
20727 api_l2_xconnect_dump (vat_main_t * vam)
20728 {
20729   vl_api_l2_xconnect_dump_t *mp;
20730   vl_api_control_ping_t *mp_ping;
20731   int ret;
20732
20733   if (!vam->json_output)
20734     {
20735       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20736     }
20737
20738   M (L2_XCONNECT_DUMP, mp);
20739
20740   S (mp);
20741
20742   /* Use a control ping for synchronization */
20743   MPING (CONTROL_PING, mp_ping);
20744   S (mp_ping);
20745
20746   W (ret);
20747   return ret;
20748 }
20749
20750 static int
20751 api_hw_interface_set_mtu (vat_main_t * vam)
20752 {
20753   unformat_input_t *i = vam->input;
20754   vl_api_hw_interface_set_mtu_t *mp;
20755   u32 sw_if_index = ~0;
20756   u32 mtu = 0;
20757   int ret;
20758
20759   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20760     {
20761       if (unformat (i, "mtu %d", &mtu))
20762         ;
20763       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20764         ;
20765       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20766         ;
20767       else
20768         break;
20769     }
20770
20771   if (sw_if_index == ~0)
20772     {
20773       errmsg ("missing interface name or sw_if_index");
20774       return -99;
20775     }
20776
20777   if (mtu == 0)
20778     {
20779       errmsg ("no mtu specified");
20780       return -99;
20781     }
20782
20783   /* Construct the API message */
20784   M (HW_INTERFACE_SET_MTU, mp);
20785   mp->sw_if_index = ntohl (sw_if_index);
20786   mp->mtu = ntohs ((u16) mtu);
20787
20788   S (mp);
20789   W (ret);
20790   return ret;
20791 }
20792
20793 static int
20794 api_p2p_ethernet_add (vat_main_t * vam)
20795 {
20796   unformat_input_t *i = vam->input;
20797   vl_api_p2p_ethernet_add_t *mp;
20798   u32 parent_if_index = ~0;
20799   u32 sub_id = ~0;
20800   u8 remote_mac[6];
20801   u8 mac_set = 0;
20802   int ret;
20803
20804   clib_memset (remote_mac, 0, sizeof (remote_mac));
20805   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20806     {
20807       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20808         ;
20809       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20810         ;
20811       else
20812         if (unformat
20813             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20814         mac_set++;
20815       else if (unformat (i, "sub_id %d", &sub_id))
20816         ;
20817       else
20818         {
20819           clib_warning ("parse error '%U'", format_unformat_error, i);
20820           return -99;
20821         }
20822     }
20823
20824   if (parent_if_index == ~0)
20825     {
20826       errmsg ("missing interface name or sw_if_index");
20827       return -99;
20828     }
20829   if (mac_set == 0)
20830     {
20831       errmsg ("missing remote mac address");
20832       return -99;
20833     }
20834   if (sub_id == ~0)
20835     {
20836       errmsg ("missing sub-interface id");
20837       return -99;
20838     }
20839
20840   M (P2P_ETHERNET_ADD, mp);
20841   mp->parent_if_index = ntohl (parent_if_index);
20842   mp->subif_id = ntohl (sub_id);
20843   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20844
20845   S (mp);
20846   W (ret);
20847   return ret;
20848 }
20849
20850 static int
20851 api_p2p_ethernet_del (vat_main_t * vam)
20852 {
20853   unformat_input_t *i = vam->input;
20854   vl_api_p2p_ethernet_del_t *mp;
20855   u32 parent_if_index = ~0;
20856   u8 remote_mac[6];
20857   u8 mac_set = 0;
20858   int ret;
20859
20860   clib_memset (remote_mac, 0, sizeof (remote_mac));
20861   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20862     {
20863       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20864         ;
20865       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20866         ;
20867       else
20868         if (unformat
20869             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20870         mac_set++;
20871       else
20872         {
20873           clib_warning ("parse error '%U'", format_unformat_error, i);
20874           return -99;
20875         }
20876     }
20877
20878   if (parent_if_index == ~0)
20879     {
20880       errmsg ("missing interface name or sw_if_index");
20881       return -99;
20882     }
20883   if (mac_set == 0)
20884     {
20885       errmsg ("missing remote mac address");
20886       return -99;
20887     }
20888
20889   M (P2P_ETHERNET_DEL, mp);
20890   mp->parent_if_index = ntohl (parent_if_index);
20891   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20892
20893   S (mp);
20894   W (ret);
20895   return ret;
20896 }
20897
20898 static int
20899 api_lldp_config (vat_main_t * vam)
20900 {
20901   unformat_input_t *i = vam->input;
20902   vl_api_lldp_config_t *mp;
20903   int tx_hold = 0;
20904   int tx_interval = 0;
20905   u8 *sys_name = NULL;
20906   int ret;
20907
20908   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20909     {
20910       if (unformat (i, "system-name %s", &sys_name))
20911         ;
20912       else if (unformat (i, "tx-hold %d", &tx_hold))
20913         ;
20914       else if (unformat (i, "tx-interval %d", &tx_interval))
20915         ;
20916       else
20917         {
20918           clib_warning ("parse error '%U'", format_unformat_error, i);
20919           return -99;
20920         }
20921     }
20922
20923   vec_add1 (sys_name, 0);
20924
20925   M (LLDP_CONFIG, mp);
20926   mp->tx_hold = htonl (tx_hold);
20927   mp->tx_interval = htonl (tx_interval);
20928   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
20929   vec_free (sys_name);
20930
20931   S (mp);
20932   W (ret);
20933   return ret;
20934 }
20935
20936 static int
20937 api_sw_interface_set_lldp (vat_main_t * vam)
20938 {
20939   unformat_input_t *i = vam->input;
20940   vl_api_sw_interface_set_lldp_t *mp;
20941   u32 sw_if_index = ~0;
20942   u32 enable = 1;
20943   u8 *port_desc = NULL, *mgmt_oid = NULL;
20944   ip4_address_t ip4_addr;
20945   ip6_address_t ip6_addr;
20946   int ret;
20947
20948   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
20949   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
20950
20951   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20952     {
20953       if (unformat (i, "disable"))
20954         enable = 0;
20955       else
20956         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20957         ;
20958       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20959         ;
20960       else if (unformat (i, "port-desc %s", &port_desc))
20961         ;
20962       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
20963         ;
20964       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
20965         ;
20966       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
20967         ;
20968       else
20969         break;
20970     }
20971
20972   if (sw_if_index == ~0)
20973     {
20974       errmsg ("missing interface name or sw_if_index");
20975       return -99;
20976     }
20977
20978   /* Construct the API message */
20979   vec_add1 (port_desc, 0);
20980   vec_add1 (mgmt_oid, 0);
20981   M (SW_INTERFACE_SET_LLDP, mp);
20982   mp->sw_if_index = ntohl (sw_if_index);
20983   mp->enable = enable;
20984   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
20985   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
20986   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
20987   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
20988   vec_free (port_desc);
20989   vec_free (mgmt_oid);
20990
20991   S (mp);
20992   W (ret);
20993   return ret;
20994 }
20995
20996 static int
20997 api_tcp_configure_src_addresses (vat_main_t * vam)
20998 {
20999   vl_api_tcp_configure_src_addresses_t *mp;
21000   unformat_input_t *i = vam->input;
21001   ip4_address_t v4first, v4last;
21002   ip6_address_t v6first, v6last;
21003   u8 range_set = 0;
21004   u32 vrf_id = 0;
21005   int ret;
21006
21007   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21008     {
21009       if (unformat (i, "%U - %U",
21010                     unformat_ip4_address, &v4first,
21011                     unformat_ip4_address, &v4last))
21012         {
21013           if (range_set)
21014             {
21015               errmsg ("one range per message (range already set)");
21016               return -99;
21017             }
21018           range_set = 1;
21019         }
21020       else if (unformat (i, "%U - %U",
21021                          unformat_ip6_address, &v6first,
21022                          unformat_ip6_address, &v6last))
21023         {
21024           if (range_set)
21025             {
21026               errmsg ("one range per message (range already set)");
21027               return -99;
21028             }
21029           range_set = 2;
21030         }
21031       else if (unformat (i, "vrf %d", &vrf_id))
21032         ;
21033       else
21034         break;
21035     }
21036
21037   if (range_set == 0)
21038     {
21039       errmsg ("address range not set");
21040       return -99;
21041     }
21042
21043   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
21044   mp->vrf_id = ntohl (vrf_id);
21045   /* ipv6? */
21046   if (range_set == 2)
21047     {
21048       mp->is_ipv6 = 1;
21049       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
21050       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
21051     }
21052   else
21053     {
21054       mp->is_ipv6 = 0;
21055       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
21056       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
21057     }
21058   S (mp);
21059   W (ret);
21060   return ret;
21061 }
21062
21063 static void vl_api_app_namespace_add_del_reply_t_handler
21064   (vl_api_app_namespace_add_del_reply_t * mp)
21065 {
21066   vat_main_t *vam = &vat_main;
21067   i32 retval = ntohl (mp->retval);
21068   if (vam->async_mode)
21069     {
21070       vam->async_errors += (retval < 0);
21071     }
21072   else
21073     {
21074       vam->retval = retval;
21075       if (retval == 0)
21076         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
21077       vam->result_ready = 1;
21078     }
21079 }
21080
21081 static void vl_api_app_namespace_add_del_reply_t_handler_json
21082   (vl_api_app_namespace_add_del_reply_t * mp)
21083 {
21084   vat_main_t *vam = &vat_main;
21085   vat_json_node_t node;
21086
21087   vat_json_init_object (&node);
21088   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
21089   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
21090
21091   vat_json_print (vam->ofp, &node);
21092   vat_json_free (&node);
21093
21094   vam->retval = ntohl (mp->retval);
21095   vam->result_ready = 1;
21096 }
21097
21098 static int
21099 api_app_namespace_add_del (vat_main_t * vam)
21100 {
21101   vl_api_app_namespace_add_del_t *mp;
21102   unformat_input_t *i = vam->input;
21103   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
21104   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
21105   u64 secret;
21106   int ret;
21107
21108   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21109     {
21110       if (unformat (i, "id %_%v%_", &ns_id))
21111         ;
21112       else if (unformat (i, "secret %lu", &secret))
21113         secret_set = 1;
21114       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21115         sw_if_index_set = 1;
21116       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
21117         ;
21118       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
21119         ;
21120       else
21121         break;
21122     }
21123   if (!ns_id || !secret_set || !sw_if_index_set)
21124     {
21125       errmsg ("namespace id, secret and sw_if_index must be set");
21126       return -99;
21127     }
21128   if (vec_len (ns_id) > 64)
21129     {
21130       errmsg ("namespace id too long");
21131       return -99;
21132     }
21133   M (APP_NAMESPACE_ADD_DEL, mp);
21134
21135   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
21136   mp->namespace_id_len = vec_len (ns_id);
21137   mp->secret = clib_host_to_net_u64 (secret);
21138   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21139   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
21140   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
21141   vec_free (ns_id);
21142   S (mp);
21143   W (ret);
21144   return ret;
21145 }
21146
21147 static int
21148 api_sock_init_shm (vat_main_t * vam)
21149 {
21150 #if VPP_API_TEST_BUILTIN == 0
21151   unformat_input_t *i = vam->input;
21152   vl_api_shm_elem_config_t *config = 0;
21153   u64 size = 64 << 20;
21154   int rv;
21155
21156   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21157     {
21158       if (unformat (i, "size %U", unformat_memory_size, &size))
21159         ;
21160       else
21161         break;
21162     }
21163
21164   /*
21165    * Canned custom ring allocator config.
21166    * Should probably parse all of this
21167    */
21168   vec_validate (config, 6);
21169   config[0].type = VL_API_VLIB_RING;
21170   config[0].size = 256;
21171   config[0].count = 32;
21172
21173   config[1].type = VL_API_VLIB_RING;
21174   config[1].size = 1024;
21175   config[1].count = 16;
21176
21177   config[2].type = VL_API_VLIB_RING;
21178   config[2].size = 4096;
21179   config[2].count = 2;
21180
21181   config[3].type = VL_API_CLIENT_RING;
21182   config[3].size = 256;
21183   config[3].count = 32;
21184
21185   config[4].type = VL_API_CLIENT_RING;
21186   config[4].size = 1024;
21187   config[4].count = 16;
21188
21189   config[5].type = VL_API_CLIENT_RING;
21190   config[5].size = 4096;
21191   config[5].count = 2;
21192
21193   config[6].type = VL_API_QUEUE;
21194   config[6].count = 128;
21195   config[6].size = sizeof (uword);
21196
21197   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
21198   if (!rv)
21199     vam->client_index_invalid = 1;
21200   return rv;
21201 #else
21202   return -99;
21203 #endif
21204 }
21205
21206 static int
21207 api_dns_enable_disable (vat_main_t * vam)
21208 {
21209   unformat_input_t *line_input = vam->input;
21210   vl_api_dns_enable_disable_t *mp;
21211   u8 enable_disable = 1;
21212   int ret;
21213
21214   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21215     {
21216       if (unformat (line_input, "disable"))
21217         enable_disable = 0;
21218       if (unformat (line_input, "enable"))
21219         enable_disable = 1;
21220       else
21221         break;
21222     }
21223
21224   /* Construct the API message */
21225   M (DNS_ENABLE_DISABLE, mp);
21226   mp->enable = enable_disable;
21227
21228   /* send it... */
21229   S (mp);
21230   /* Wait for the reply */
21231   W (ret);
21232   return ret;
21233 }
21234
21235 static int
21236 api_dns_resolve_name (vat_main_t * vam)
21237 {
21238   unformat_input_t *line_input = vam->input;
21239   vl_api_dns_resolve_name_t *mp;
21240   u8 *name = 0;
21241   int ret;
21242
21243   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21244     {
21245       if (unformat (line_input, "%s", &name))
21246         ;
21247       else
21248         break;
21249     }
21250
21251   if (vec_len (name) > 127)
21252     {
21253       errmsg ("name too long");
21254       return -99;
21255     }
21256
21257   /* Construct the API message */
21258   M (DNS_RESOLVE_NAME, mp);
21259   memcpy (mp->name, name, vec_len (name));
21260   vec_free (name);
21261
21262   /* send it... */
21263   S (mp);
21264   /* Wait for the reply */
21265   W (ret);
21266   return ret;
21267 }
21268
21269 static int
21270 api_dns_resolve_ip (vat_main_t * vam)
21271 {
21272   unformat_input_t *line_input = vam->input;
21273   vl_api_dns_resolve_ip_t *mp;
21274   int is_ip6 = -1;
21275   ip4_address_t addr4;
21276   ip6_address_t addr6;
21277   int ret;
21278
21279   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21280     {
21281       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
21282         is_ip6 = 1;
21283       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
21284         is_ip6 = 0;
21285       else
21286         break;
21287     }
21288
21289   if (is_ip6 == -1)
21290     {
21291       errmsg ("missing address");
21292       return -99;
21293     }
21294
21295   /* Construct the API message */
21296   M (DNS_RESOLVE_IP, mp);
21297   mp->is_ip6 = is_ip6;
21298   if (is_ip6)
21299     memcpy (mp->address, &addr6, sizeof (addr6));
21300   else
21301     memcpy (mp->address, &addr4, sizeof (addr4));
21302
21303   /* send it... */
21304   S (mp);
21305   /* Wait for the reply */
21306   W (ret);
21307   return ret;
21308 }
21309
21310 static int
21311 api_dns_name_server_add_del (vat_main_t * vam)
21312 {
21313   unformat_input_t *i = vam->input;
21314   vl_api_dns_name_server_add_del_t *mp;
21315   u8 is_add = 1;
21316   ip6_address_t ip6_server;
21317   ip4_address_t ip4_server;
21318   int ip6_set = 0;
21319   int ip4_set = 0;
21320   int ret = 0;
21321
21322   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21323     {
21324       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
21325         ip6_set = 1;
21326       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
21327         ip4_set = 1;
21328       else if (unformat (i, "del"))
21329         is_add = 0;
21330       else
21331         {
21332           clib_warning ("parse error '%U'", format_unformat_error, i);
21333           return -99;
21334         }
21335     }
21336
21337   if (ip4_set && ip6_set)
21338     {
21339       errmsg ("Only one server address allowed per message");
21340       return -99;
21341     }
21342   if ((ip4_set + ip6_set) == 0)
21343     {
21344       errmsg ("Server address required");
21345       return -99;
21346     }
21347
21348   /* Construct the API message */
21349   M (DNS_NAME_SERVER_ADD_DEL, mp);
21350
21351   if (ip6_set)
21352     {
21353       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
21354       mp->is_ip6 = 1;
21355     }
21356   else
21357     {
21358       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
21359       mp->is_ip6 = 0;
21360     }
21361
21362   mp->is_add = is_add;
21363
21364   /* send it... */
21365   S (mp);
21366
21367   /* Wait for a reply, return good/bad news  */
21368   W (ret);
21369   return ret;
21370 }
21371
21372 static void
21373 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
21374 {
21375   vat_main_t *vam = &vat_main;
21376
21377   if (mp->is_ip4)
21378     {
21379       print (vam->ofp,
21380              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21381              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21382              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
21383              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
21384              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21385              clib_net_to_host_u32 (mp->action_index), mp->tag);
21386     }
21387   else
21388     {
21389       print (vam->ofp,
21390              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21391              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21392              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
21393              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
21394              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21395              clib_net_to_host_u32 (mp->action_index), mp->tag);
21396     }
21397 }
21398
21399 static void
21400 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
21401                                              mp)
21402 {
21403   vat_main_t *vam = &vat_main;
21404   vat_json_node_t *node = NULL;
21405   struct in6_addr ip6;
21406   struct in_addr ip4;
21407
21408   if (VAT_JSON_ARRAY != vam->json_tree.type)
21409     {
21410       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21411       vat_json_init_array (&vam->json_tree);
21412     }
21413   node = vat_json_array_add (&vam->json_tree);
21414   vat_json_init_object (node);
21415
21416   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
21417   vat_json_object_add_uint (node, "appns_index",
21418                             clib_net_to_host_u32 (mp->appns_index));
21419   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
21420   vat_json_object_add_uint (node, "scope", mp->scope);
21421   vat_json_object_add_uint (node, "action_index",
21422                             clib_net_to_host_u32 (mp->action_index));
21423   vat_json_object_add_uint (node, "lcl_port",
21424                             clib_net_to_host_u16 (mp->lcl_port));
21425   vat_json_object_add_uint (node, "rmt_port",
21426                             clib_net_to_host_u16 (mp->rmt_port));
21427   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
21428   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
21429   vat_json_object_add_string_copy (node, "tag", mp->tag);
21430   if (mp->is_ip4)
21431     {
21432       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
21433       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
21434       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
21435       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
21436     }
21437   else
21438     {
21439       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
21440       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
21441       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
21442       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
21443     }
21444 }
21445
21446 static int
21447 api_session_rule_add_del (vat_main_t * vam)
21448 {
21449   vl_api_session_rule_add_del_t *mp;
21450   unformat_input_t *i = vam->input;
21451   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
21452   u32 appns_index = 0, scope = 0;
21453   ip4_address_t lcl_ip4, rmt_ip4;
21454   ip6_address_t lcl_ip6, rmt_ip6;
21455   u8 is_ip4 = 1, conn_set = 0;
21456   u8 is_add = 1, *tag = 0;
21457   int ret;
21458
21459   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21460     {
21461       if (unformat (i, "del"))
21462         is_add = 0;
21463       else if (unformat (i, "add"))
21464         ;
21465       else if (unformat (i, "proto tcp"))
21466         proto = 0;
21467       else if (unformat (i, "proto udp"))
21468         proto = 1;
21469       else if (unformat (i, "appns %d", &appns_index))
21470         ;
21471       else if (unformat (i, "scope %d", &scope))
21472         ;
21473       else if (unformat (i, "tag %_%v%_", &tag))
21474         ;
21475       else
21476         if (unformat
21477             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
21478              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
21479              &rmt_port))
21480         {
21481           is_ip4 = 1;
21482           conn_set = 1;
21483         }
21484       else
21485         if (unformat
21486             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
21487              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
21488              &rmt_port))
21489         {
21490           is_ip4 = 0;
21491           conn_set = 1;
21492         }
21493       else if (unformat (i, "action %d", &action))
21494         ;
21495       else
21496         break;
21497     }
21498   if (proto == ~0 || !conn_set || action == ~0)
21499     {
21500       errmsg ("transport proto, connection and action must be set");
21501       return -99;
21502     }
21503
21504   if (scope > 3)
21505     {
21506       errmsg ("scope should be 0-3");
21507       return -99;
21508     }
21509
21510   M (SESSION_RULE_ADD_DEL, mp);
21511
21512   mp->is_ip4 = is_ip4;
21513   mp->transport_proto = proto;
21514   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
21515   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
21516   mp->lcl_plen = lcl_plen;
21517   mp->rmt_plen = rmt_plen;
21518   mp->action_index = clib_host_to_net_u32 (action);
21519   mp->appns_index = clib_host_to_net_u32 (appns_index);
21520   mp->scope = scope;
21521   mp->is_add = is_add;
21522   if (is_ip4)
21523     {
21524       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
21525       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
21526     }
21527   else
21528     {
21529       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
21530       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
21531     }
21532   if (tag)
21533     {
21534       clib_memcpy (mp->tag, tag, vec_len (tag));
21535       vec_free (tag);
21536     }
21537
21538   S (mp);
21539   W (ret);
21540   return ret;
21541 }
21542
21543 static int
21544 api_session_rules_dump (vat_main_t * vam)
21545 {
21546   vl_api_session_rules_dump_t *mp;
21547   vl_api_control_ping_t *mp_ping;
21548   int ret;
21549
21550   if (!vam->json_output)
21551     {
21552       print (vam->ofp, "%=20s", "Session Rules");
21553     }
21554
21555   M (SESSION_RULES_DUMP, mp);
21556   /* send it... */
21557   S (mp);
21558
21559   /* Use a control ping for synchronization */
21560   MPING (CONTROL_PING, mp_ping);
21561   S (mp_ping);
21562
21563   /* Wait for a reply... */
21564   W (ret);
21565   return ret;
21566 }
21567
21568 static int
21569 api_ip_container_proxy_add_del (vat_main_t * vam)
21570 {
21571   vl_api_ip_container_proxy_add_del_t *mp;
21572   unformat_input_t *i = vam->input;
21573   u32 sw_if_index = ~0;
21574   vl_api_prefix_t pfx = { };
21575   u8 is_add = 1;
21576   int ret;
21577
21578   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21579     {
21580       if (unformat (i, "del"))
21581         is_add = 0;
21582       else if (unformat (i, "add"))
21583         ;
21584       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
21585         ;
21586       else if (unformat (i, "sw_if_index %u", &sw_if_index))
21587         ;
21588       else
21589         break;
21590     }
21591   if (sw_if_index == ~0 || pfx.address_length == 0)
21592     {
21593       errmsg ("address and sw_if_index must be set");
21594       return -99;
21595     }
21596
21597   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
21598
21599   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21600   mp->is_add = is_add;
21601   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
21602
21603   S (mp);
21604   W (ret);
21605   return ret;
21606 }
21607
21608 static int
21609 api_qos_record_enable_disable (vat_main_t * vam)
21610 {
21611   unformat_input_t *i = vam->input;
21612   vl_api_qos_record_enable_disable_t *mp;
21613   u32 sw_if_index, qs = 0xff;
21614   u8 sw_if_index_set = 0;
21615   u8 enable = 1;
21616   int ret;
21617
21618   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21619     {
21620       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21621         sw_if_index_set = 1;
21622       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21623         sw_if_index_set = 1;
21624       else if (unformat (i, "%U", unformat_qos_source, &qs))
21625         ;
21626       else if (unformat (i, "disable"))
21627         enable = 0;
21628       else
21629         {
21630           clib_warning ("parse error '%U'", format_unformat_error, i);
21631           return -99;
21632         }
21633     }
21634
21635   if (sw_if_index_set == 0)
21636     {
21637       errmsg ("missing interface name or sw_if_index");
21638       return -99;
21639     }
21640   if (qs == 0xff)
21641     {
21642       errmsg ("input location must be specified");
21643       return -99;
21644     }
21645
21646   M (QOS_RECORD_ENABLE_DISABLE, mp);
21647
21648   mp->sw_if_index = ntohl (sw_if_index);
21649   mp->input_source = qs;
21650   mp->enable = enable;
21651
21652   S (mp);
21653   W (ret);
21654   return ret;
21655 }
21656
21657
21658 static int
21659 q_or_quit (vat_main_t * vam)
21660 {
21661 #if VPP_API_TEST_BUILTIN == 0
21662   longjmp (vam->jump_buf, 1);
21663 #endif
21664   return 0;                     /* not so much */
21665 }
21666
21667 static int
21668 q (vat_main_t * vam)
21669 {
21670   return q_or_quit (vam);
21671 }
21672
21673 static int
21674 quit (vat_main_t * vam)
21675 {
21676   return q_or_quit (vam);
21677 }
21678
21679 static int
21680 comment (vat_main_t * vam)
21681 {
21682   return 0;
21683 }
21684
21685 static int
21686 statseg (vat_main_t * vam)
21687 {
21688   ssvm_private_t *ssvmp = &vam->stat_segment;
21689   ssvm_shared_header_t *shared_header = ssvmp->sh;
21690   vlib_counter_t **counters;
21691   u64 thread0_index1_packets;
21692   u64 thread0_index1_bytes;
21693   f64 vector_rate, input_rate;
21694   uword *p;
21695
21696   uword *counter_vector_by_name;
21697   if (vam->stat_segment_lockp == 0)
21698     {
21699       errmsg ("Stat segment not mapped...");
21700       return -99;
21701     }
21702
21703   /* look up "/if/rx for sw_if_index 1 as a test */
21704
21705   clib_spinlock_lock (vam->stat_segment_lockp);
21706
21707   counter_vector_by_name = (uword *) shared_header->opaque[1];
21708
21709   p = hash_get_mem (counter_vector_by_name, "/if/rx");
21710   if (p == 0)
21711     {
21712       clib_spinlock_unlock (vam->stat_segment_lockp);
21713       errmsg ("/if/tx not found?");
21714       return -99;
21715     }
21716
21717   /* Fish per-thread vector of combined counters from shared memory */
21718   counters = (vlib_counter_t **) p[0];
21719
21720   if (vec_len (counters[0]) < 2)
21721     {
21722       clib_spinlock_unlock (vam->stat_segment_lockp);
21723       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
21724       return -99;
21725     }
21726
21727   /* Read thread 0 sw_if_index 1 counter */
21728   thread0_index1_packets = counters[0][1].packets;
21729   thread0_index1_bytes = counters[0][1].bytes;
21730
21731   p = hash_get_mem (counter_vector_by_name, "vector_rate");
21732   if (p == 0)
21733     {
21734       clib_spinlock_unlock (vam->stat_segment_lockp);
21735       errmsg ("vector_rate not found?");
21736       return -99;
21737     }
21738
21739   vector_rate = *(f64 *) (p[0]);
21740   p = hash_get_mem (counter_vector_by_name, "input_rate");
21741   if (p == 0)
21742     {
21743       clib_spinlock_unlock (vam->stat_segment_lockp);
21744       errmsg ("input_rate not found?");
21745       return -99;
21746     }
21747   input_rate = *(f64 *) (p[0]);
21748
21749   clib_spinlock_unlock (vam->stat_segment_lockp);
21750
21751   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
21752          vector_rate, input_rate);
21753   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
21754          thread0_index1_packets, thread0_index1_bytes);
21755
21756   return 0;
21757 }
21758
21759 static int
21760 cmd_cmp (void *a1, void *a2)
21761 {
21762   u8 **c1 = a1;
21763   u8 **c2 = a2;
21764
21765   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21766 }
21767
21768 static int
21769 help (vat_main_t * vam)
21770 {
21771   u8 **cmds = 0;
21772   u8 *name = 0;
21773   hash_pair_t *p;
21774   unformat_input_t *i = vam->input;
21775   int j;
21776
21777   if (unformat (i, "%s", &name))
21778     {
21779       uword *hs;
21780
21781       vec_add1 (name, 0);
21782
21783       hs = hash_get_mem (vam->help_by_name, name);
21784       if (hs)
21785         print (vam->ofp, "usage: %s %s", name, hs[0]);
21786       else
21787         print (vam->ofp, "No such msg / command '%s'", name);
21788       vec_free (name);
21789       return 0;
21790     }
21791
21792   print (vam->ofp, "Help is available for the following:");
21793
21794     /* *INDENT-OFF* */
21795     hash_foreach_pair (p, vam->function_by_name,
21796     ({
21797       vec_add1 (cmds, (u8 *)(p->key));
21798     }));
21799     /* *INDENT-ON* */
21800
21801   vec_sort_with_function (cmds, cmd_cmp);
21802
21803   for (j = 0; j < vec_len (cmds); j++)
21804     print (vam->ofp, "%s", cmds[j]);
21805
21806   vec_free (cmds);
21807   return 0;
21808 }
21809
21810 static int
21811 set (vat_main_t * vam)
21812 {
21813   u8 *name = 0, *value = 0;
21814   unformat_input_t *i = vam->input;
21815
21816   if (unformat (i, "%s", &name))
21817     {
21818       /* The input buffer is a vector, not a string. */
21819       value = vec_dup (i->buffer);
21820       vec_delete (value, i->index, 0);
21821       /* Almost certainly has a trailing newline */
21822       if (value[vec_len (value) - 1] == '\n')
21823         value[vec_len (value) - 1] = 0;
21824       /* Make sure it's a proper string, one way or the other */
21825       vec_add1 (value, 0);
21826       (void) clib_macro_set_value (&vam->macro_main,
21827                                    (char *) name, (char *) value);
21828     }
21829   else
21830     errmsg ("usage: set <name> <value>");
21831
21832   vec_free (name);
21833   vec_free (value);
21834   return 0;
21835 }
21836
21837 static int
21838 unset (vat_main_t * vam)
21839 {
21840   u8 *name = 0;
21841
21842   if (unformat (vam->input, "%s", &name))
21843     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
21844       errmsg ("unset: %s wasn't set", name);
21845   vec_free (name);
21846   return 0;
21847 }
21848
21849 typedef struct
21850 {
21851   u8 *name;
21852   u8 *value;
21853 } macro_sort_t;
21854
21855
21856 static int
21857 macro_sort_cmp (void *a1, void *a2)
21858 {
21859   macro_sort_t *s1 = a1;
21860   macro_sort_t *s2 = a2;
21861
21862   return strcmp ((char *) (s1->name), (char *) (s2->name));
21863 }
21864
21865 static int
21866 dump_macro_table (vat_main_t * vam)
21867 {
21868   macro_sort_t *sort_me = 0, *sm;
21869   int i;
21870   hash_pair_t *p;
21871
21872     /* *INDENT-OFF* */
21873     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
21874     ({
21875       vec_add2 (sort_me, sm, 1);
21876       sm->name = (u8 *)(p->key);
21877       sm->value = (u8 *) (p->value[0]);
21878     }));
21879     /* *INDENT-ON* */
21880
21881   vec_sort_with_function (sort_me, macro_sort_cmp);
21882
21883   if (vec_len (sort_me))
21884     print (vam->ofp, "%-15s%s", "Name", "Value");
21885   else
21886     print (vam->ofp, "The macro table is empty...");
21887
21888   for (i = 0; i < vec_len (sort_me); i++)
21889     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
21890   return 0;
21891 }
21892
21893 static int
21894 dump_node_table (vat_main_t * vam)
21895 {
21896   int i, j;
21897   vlib_node_t *node, *next_node;
21898
21899   if (vec_len (vam->graph_nodes) == 0)
21900     {
21901       print (vam->ofp, "Node table empty, issue get_node_graph...");
21902       return 0;
21903     }
21904
21905   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
21906     {
21907       node = vam->graph_nodes[0][i];
21908       print (vam->ofp, "[%d] %s", i, node->name);
21909       for (j = 0; j < vec_len (node->next_nodes); j++)
21910         {
21911           if (node->next_nodes[j] != ~0)
21912             {
21913               next_node = vam->graph_nodes[0][node->next_nodes[j]];
21914               print (vam->ofp, "  [%d] %s", j, next_node->name);
21915             }
21916         }
21917     }
21918   return 0;
21919 }
21920
21921 static int
21922 value_sort_cmp (void *a1, void *a2)
21923 {
21924   name_sort_t *n1 = a1;
21925   name_sort_t *n2 = a2;
21926
21927   if (n1->value < n2->value)
21928     return -1;
21929   if (n1->value > n2->value)
21930     return 1;
21931   return 0;
21932 }
21933
21934
21935 static int
21936 dump_msg_api_table (vat_main_t * vam)
21937 {
21938   api_main_t *am = &api_main;
21939   name_sort_t *nses = 0, *ns;
21940   hash_pair_t *hp;
21941   int i;
21942
21943   /* *INDENT-OFF* */
21944   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
21945   ({
21946     vec_add2 (nses, ns, 1);
21947     ns->name = (u8 *)(hp->key);
21948     ns->value = (u32) hp->value[0];
21949   }));
21950   /* *INDENT-ON* */
21951
21952   vec_sort_with_function (nses, value_sort_cmp);
21953
21954   for (i = 0; i < vec_len (nses); i++)
21955     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
21956   vec_free (nses);
21957   return 0;
21958 }
21959
21960 static int
21961 get_msg_id (vat_main_t * vam)
21962 {
21963   u8 *name_and_crc;
21964   u32 message_index;
21965
21966   if (unformat (vam->input, "%s", &name_and_crc))
21967     {
21968       message_index = vl_msg_api_get_msg_index (name_and_crc);
21969       if (message_index == ~0)
21970         {
21971           print (vam->ofp, " '%s' not found", name_and_crc);
21972           return 0;
21973         }
21974       print (vam->ofp, " '%s' has message index %d",
21975              name_and_crc, message_index);
21976       return 0;
21977     }
21978   errmsg ("name_and_crc required...");
21979   return 0;
21980 }
21981
21982 static int
21983 search_node_table (vat_main_t * vam)
21984 {
21985   unformat_input_t *line_input = vam->input;
21986   u8 *node_to_find;
21987   int j;
21988   vlib_node_t *node, *next_node;
21989   uword *p;
21990
21991   if (vam->graph_node_index_by_name == 0)
21992     {
21993       print (vam->ofp, "Node table empty, issue get_node_graph...");
21994       return 0;
21995     }
21996
21997   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21998     {
21999       if (unformat (line_input, "%s", &node_to_find))
22000         {
22001           vec_add1 (node_to_find, 0);
22002           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
22003           if (p == 0)
22004             {
22005               print (vam->ofp, "%s not found...", node_to_find);
22006               goto out;
22007             }
22008           node = vam->graph_nodes[0][p[0]];
22009           print (vam->ofp, "[%d] %s", p[0], node->name);
22010           for (j = 0; j < vec_len (node->next_nodes); j++)
22011             {
22012               if (node->next_nodes[j] != ~0)
22013                 {
22014                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
22015                   print (vam->ofp, "  [%d] %s", j, next_node->name);
22016                 }
22017             }
22018         }
22019
22020       else
22021         {
22022           clib_warning ("parse error '%U'", format_unformat_error,
22023                         line_input);
22024           return -99;
22025         }
22026
22027     out:
22028       vec_free (node_to_find);
22029
22030     }
22031
22032   return 0;
22033 }
22034
22035
22036 static int
22037 script (vat_main_t * vam)
22038 {
22039 #if (VPP_API_TEST_BUILTIN==0)
22040   u8 *s = 0;
22041   char *save_current_file;
22042   unformat_input_t save_input;
22043   jmp_buf save_jump_buf;
22044   u32 save_line_number;
22045
22046   FILE *new_fp, *save_ifp;
22047
22048   if (unformat (vam->input, "%s", &s))
22049     {
22050       new_fp = fopen ((char *) s, "r");
22051       if (new_fp == 0)
22052         {
22053           errmsg ("Couldn't open script file %s", s);
22054           vec_free (s);
22055           return -99;
22056         }
22057     }
22058   else
22059     {
22060       errmsg ("Missing script name");
22061       return -99;
22062     }
22063
22064   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
22065   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
22066   save_ifp = vam->ifp;
22067   save_line_number = vam->input_line_number;
22068   save_current_file = (char *) vam->current_file;
22069
22070   vam->input_line_number = 0;
22071   vam->ifp = new_fp;
22072   vam->current_file = s;
22073   do_one_file (vam);
22074
22075   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
22076   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
22077   vam->ifp = save_ifp;
22078   vam->input_line_number = save_line_number;
22079   vam->current_file = (u8 *) save_current_file;
22080   vec_free (s);
22081
22082   return 0;
22083 #else
22084   clib_warning ("use the exec command...");
22085   return -99;
22086 #endif
22087 }
22088
22089 static int
22090 echo (vat_main_t * vam)
22091 {
22092   print (vam->ofp, "%v", vam->input->buffer);
22093   return 0;
22094 }
22095
22096 /* List of API message constructors, CLI names map to api_xxx */
22097 #define foreach_vpe_api_msg                                             \
22098 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
22099 _(sw_interface_dump,"")                                                 \
22100 _(sw_interface_set_flags,                                               \
22101   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
22102 _(sw_interface_add_del_address,                                         \
22103   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
22104 _(sw_interface_set_rx_mode,                                             \
22105   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
22106 _(sw_interface_set_rx_placement,                                        \
22107   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
22108 _(sw_interface_rx_placement_dump,                                       \
22109   "[<intfc> | sw_if_index <id>]")                                         \
22110 _(sw_interface_set_table,                                               \
22111   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
22112 _(sw_interface_set_mpls_enable,                                         \
22113   "<intfc> | sw_if_index [disable | dis]")                              \
22114 _(sw_interface_set_vpath,                                               \
22115   "<intfc> | sw_if_index <id> enable | disable")                        \
22116 _(sw_interface_set_vxlan_bypass,                                        \
22117   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22118 _(sw_interface_set_geneve_bypass,                                       \
22119   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22120 _(sw_interface_set_l2_xconnect,                                         \
22121   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22122   "enable | disable")                                                   \
22123 _(sw_interface_set_l2_bridge,                                           \
22124   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
22125   "[shg <split-horizon-group>] [bvi]\n"                                 \
22126   "enable | disable")                                                   \
22127 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
22128 _(bridge_domain_add_del,                                                \
22129   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [mac-age 0-255] [bd-tag <text>] [del]\n") \
22130 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
22131 _(l2fib_add_del,                                                        \
22132   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
22133 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
22134 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
22135 _(l2_flags,                                                             \
22136   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22137 _(bridge_flags,                                                         \
22138   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22139 _(tap_create_v2,                                                        \
22140   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
22141 _(tap_delete_v2,                                                        \
22142   "<vpp-if-name> | sw_if_index <id>")                                   \
22143 _(sw_interface_tap_v2_dump, "")                                         \
22144 _(virtio_pci_create,                                                    \
22145   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled]") \
22146 _(virtio_pci_delete,                                                    \
22147   "<vpp-if-name> | sw_if_index <id>")                                   \
22148 _(sw_interface_virtio_pci_dump, "")                                     \
22149 _(bond_create,                                                          \
22150   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
22151   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
22152   "[id <if-id>]")                                                       \
22153 _(bond_delete,                                                          \
22154   "<vpp-if-name> | sw_if_index <id>")                                   \
22155 _(bond_enslave,                                                         \
22156   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
22157 _(bond_detach_slave,                                                    \
22158   "sw_if_index <n>")                                                    \
22159 _(sw_interface_bond_dump, "")                                           \
22160 _(sw_interface_slave_dump,                                              \
22161   "<vpp-if-name> | sw_if_index <id>")                                   \
22162 _(ip_table_add_del,                                                     \
22163   "table <n> [ipv6] [add | del]\n")                                     \
22164 _(ip_add_del_route,                                                     \
22165   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
22166   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
22167   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
22168   "[multipath] [count <n>] [del]")                                      \
22169 _(ip_mroute_add_del,                                                    \
22170   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
22171   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
22172 _(mpls_table_add_del,                                                   \
22173   "table <n> [add | del]\n")                                            \
22174 _(mpls_route_add_del,                                                   \
22175   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
22176   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
22177   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
22178   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
22179   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
22180   "[count <n>] [del]")                                                  \
22181 _(mpls_ip_bind_unbind,                                                  \
22182   "<label> <addr/len>")                                                 \
22183 _(mpls_tunnel_add_del,                                                  \
22184   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
22185   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
22186   "[l2-only]  [out-label <n>]")                                         \
22187 _(sr_mpls_policy_add,                                                   \
22188   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
22189 _(sr_mpls_policy_del,                                                   \
22190   "bsid <id>")                                                          \
22191 _(bier_table_add_del,                                                   \
22192   "<label> <sub-domain> <set> <bsl> [del]")                             \
22193 _(bier_route_add_del,                                                   \
22194   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
22195   "[<intfc> | sw_if_index <id>]"                                        \
22196   "[weight <n>] [del] [multipath]")                                     \
22197 _(proxy_arp_add_del,                                                    \
22198   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
22199 _(proxy_arp_intfc_enable_disable,                                       \
22200   "<intfc> | sw_if_index <id> enable | disable")                        \
22201 _(sw_interface_set_unnumbered,                                          \
22202   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
22203 _(ip_neighbor_add_del,                                                  \
22204   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
22205   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
22206 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
22207 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
22208   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
22209   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
22210   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
22211 _(reset_fib, "vrf <n> [ipv6]")                                          \
22212 _(dhcp_proxy_config,                                                    \
22213   "svr <v46-address> src <v46-address>\n"                               \
22214    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
22215 _(dhcp_proxy_set_vss,                                                   \
22216   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
22217 _(dhcp_proxy_dump, "ip6")                                               \
22218 _(dhcp_client_config,                                                   \
22219   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
22220 _(set_ip_flow_hash,                                                     \
22221   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
22222 _(sw_interface_ip6_enable_disable,                                      \
22223   "<intfc> | sw_if_index <id> enable | disable")                        \
22224 _(ip6nd_proxy_add_del,                                                  \
22225   "<intfc> | sw_if_index <id> <ip6-address>")                           \
22226 _(ip6nd_proxy_dump, "")                                                 \
22227 _(sw_interface_ip6nd_ra_prefix,                                         \
22228   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
22229   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
22230   "[nolink] [isno]")                                                    \
22231 _(sw_interface_ip6nd_ra_config,                                         \
22232   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
22233   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
22234   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
22235 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
22236 _(l2_patch_add_del,                                                     \
22237   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22238   "enable | disable")                                                   \
22239 _(sr_localsid_add_del,                                                  \
22240   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
22241   "fib-table <num> (end.psp) sw_if_index <num>")                        \
22242 _(classify_add_del_table,                                               \
22243   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
22244   " [del] [del-chain] mask <mask-value>\n"                              \
22245   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
22246   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
22247 _(classify_add_del_session,                                             \
22248   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
22249   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
22250   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
22251   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
22252 _(classify_set_interface_ip_table,                                      \
22253   "<intfc> | sw_if_index <nn> table <nn>")                              \
22254 _(classify_set_interface_l2_tables,                                     \
22255   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22256   "  [other-table <nn>]")                                               \
22257 _(get_node_index, "node <node-name")                                    \
22258 _(add_node_next, "node <node-name> next <next-node-name>")              \
22259 _(l2tpv3_create_tunnel,                                                 \
22260   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
22261   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
22262   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
22263 _(l2tpv3_set_tunnel_cookies,                                            \
22264   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
22265   "[new_remote_cookie <nn>]\n")                                         \
22266 _(l2tpv3_interface_enable_disable,                                      \
22267   "<intfc> | sw_if_index <nn> enable | disable")                        \
22268 _(l2tpv3_set_lookup_key,                                                \
22269   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
22270 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
22271 _(vxlan_offload_rx,                                                     \
22272   "hw { <interface name> | hw_if_index <nn>} "                          \
22273   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
22274 _(vxlan_add_del_tunnel,                                                 \
22275   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22276   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
22277   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22278 _(geneve_add_del_tunnel,                                                \
22279   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22280   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22281   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22282 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
22283 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
22284 _(gre_tunnel_add_del,                                                   \
22285   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
22286   "[teb | erspan <session-id>] [del]")                                  \
22287 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
22288 _(l2_fib_clear_table, "")                                               \
22289 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
22290 _(l2_interface_vlan_tag_rewrite,                                        \
22291   "<intfc> | sw_if_index <nn> \n"                                       \
22292   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
22293   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
22294 _(create_vhost_user_if,                                                 \
22295         "socket <filename> [server] [renumber <dev_instance>] "         \
22296         "[disable_mrg_rxbuf] [disable_indirect_desc] "                  \
22297         "[mac <mac_address>]")                                          \
22298 _(modify_vhost_user_if,                                                 \
22299         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
22300         "[server] [renumber <dev_instance>]")                           \
22301 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
22302 _(sw_interface_vhost_user_dump, "")                                     \
22303 _(show_version, "")                                                     \
22304 _(show_threads, "")                                                     \
22305 _(vxlan_gpe_add_del_tunnel,                                             \
22306   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
22307   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22308   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
22309   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
22310 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
22311 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
22312 _(interface_name_renumber,                                              \
22313   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
22314 _(input_acl_set_interface,                                              \
22315   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22316   "  [l2-table <nn>] [del]")                                            \
22317 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
22318 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
22319   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
22320 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
22321 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
22322 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
22323 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
22324 _(ip_dump, "ipv4 | ipv6")                                               \
22325 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
22326 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
22327   "  spid_id <n> ")                                                     \
22328 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
22329   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
22330   "  integ_alg <alg> integ_key <hex>")                                  \
22331 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
22332   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
22333   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
22334   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
22335 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
22336   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
22337   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
22338   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
22339   "  [instance <n>]")     \
22340 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
22341 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
22342 _(delete_loopback,"sw_if_index <nn>")                                   \
22343 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
22344 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
22345 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
22346 _(want_interface_events,  "enable|disable")                             \
22347 _(get_first_msg_id, "client <name>")                                    \
22348 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
22349 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
22350   "fib-id <nn> [ip4][ip6][default]")                                    \
22351 _(get_node_graph, " ")                                                  \
22352 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
22353 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
22354 _(ioam_disable, "")                                                     \
22355 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
22356                             " sw_if_index <sw_if_index> p <priority> "  \
22357                             "w <weight>] [del]")                        \
22358 _(one_add_del_locator, "locator-set <locator_name> "                    \
22359                         "iface <intf> | sw_if_index <sw_if_index> "     \
22360                         "p <priority> w <weight> [del]")                \
22361 _(one_add_del_local_eid,"vni <vni> eid "                                \
22362                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22363                          "locator-set <locator_name> [del]"             \
22364                          "[key-id sha1|sha256 secret-key <secret-key>]")\
22365 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
22366 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
22367 _(one_enable_disable, "enable|disable")                                 \
22368 _(one_map_register_enable_disable, "enable|disable")                    \
22369 _(one_map_register_fallback_threshold, "<value>")                       \
22370 _(one_rloc_probe_enable_disable, "enable|disable")                      \
22371 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
22372                                "[seid <seid>] "                         \
22373                                "rloc <locator> p <prio> "               \
22374                                "w <weight> [rloc <loc> ... ] "          \
22375                                "action <action> [del-all]")             \
22376 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
22377                           "<local-eid>")                                \
22378 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
22379 _(one_use_petr, "ip-address> | disable")                                \
22380 _(one_map_request_mode, "src-dst|dst-only")                             \
22381 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
22382 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
22383 _(one_locator_set_dump, "[local | remote]")                             \
22384 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
22385 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
22386                        "[local] | [remote]")                            \
22387 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
22388 _(one_ndp_bd_get, "")                                                   \
22389 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
22390 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
22391 _(one_l2_arp_bd_get, "")                                                \
22392 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
22393 _(one_stats_enable_disable, "enable|disable")                           \
22394 _(show_one_stats_enable_disable, "")                                    \
22395 _(one_eid_table_vni_dump, "")                                           \
22396 _(one_eid_table_map_dump, "l2|l3")                                      \
22397 _(one_map_resolver_dump, "")                                            \
22398 _(one_map_server_dump, "")                                              \
22399 _(one_adjacencies_get, "vni <vni>")                                     \
22400 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
22401 _(show_one_rloc_probe_state, "")                                        \
22402 _(show_one_map_register_state, "")                                      \
22403 _(show_one_status, "")                                                  \
22404 _(one_stats_dump, "")                                                   \
22405 _(one_stats_flush, "")                                                  \
22406 _(one_get_map_request_itr_rlocs, "")                                    \
22407 _(one_map_register_set_ttl, "<ttl>")                                    \
22408 _(one_set_transport_protocol, "udp|api")                                \
22409 _(one_get_transport_protocol, "")                                       \
22410 _(one_enable_disable_xtr_mode, "enable|disable")                        \
22411 _(one_show_xtr_mode, "")                                                \
22412 _(one_enable_disable_pitr_mode, "enable|disable")                       \
22413 _(one_show_pitr_mode, "")                                               \
22414 _(one_enable_disable_petr_mode, "enable|disable")                       \
22415 _(one_show_petr_mode, "")                                               \
22416 _(show_one_nsh_mapping, "")                                             \
22417 _(show_one_pitr, "")                                                    \
22418 _(show_one_use_petr, "")                                                \
22419 _(show_one_map_request_mode, "")                                        \
22420 _(show_one_map_register_ttl, "")                                        \
22421 _(show_one_map_register_fallback_threshold, "")                         \
22422 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
22423                             " sw_if_index <sw_if_index> p <priority> "  \
22424                             "w <weight>] [del]")                        \
22425 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
22426                         "iface <intf> | sw_if_index <sw_if_index> "     \
22427                         "p <priority> w <weight> [del]")                \
22428 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
22429                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22430                          "locator-set <locator_name> [del]"             \
22431                          "[key-id sha1|sha256 secret-key <secret-key>]") \
22432 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
22433 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
22434 _(lisp_enable_disable, "enable|disable")                                \
22435 _(lisp_map_register_enable_disable, "enable|disable")                   \
22436 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
22437 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
22438                                "[seid <seid>] "                         \
22439                                "rloc <locator> p <prio> "               \
22440                                "w <weight> [rloc <loc> ... ] "          \
22441                                "action <action> [del-all]")             \
22442 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
22443                           "<local-eid>")                                \
22444 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
22445 _(lisp_use_petr, "<ip-address> | disable")                              \
22446 _(lisp_map_request_mode, "src-dst|dst-only")                            \
22447 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
22448 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
22449 _(lisp_locator_set_dump, "[local | remote]")                            \
22450 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
22451 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
22452                        "[local] | [remote]")                            \
22453 _(lisp_eid_table_vni_dump, "")                                          \
22454 _(lisp_eid_table_map_dump, "l2|l3")                                     \
22455 _(lisp_map_resolver_dump, "")                                           \
22456 _(lisp_map_server_dump, "")                                             \
22457 _(lisp_adjacencies_get, "vni <vni>")                                    \
22458 _(gpe_fwd_entry_vnis_get, "")                                           \
22459 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
22460 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
22461                                 "[table <table-id>]")                   \
22462 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
22463 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
22464 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
22465 _(gpe_get_encap_mode, "")                                               \
22466 _(lisp_gpe_add_del_iface, "up|down")                                    \
22467 _(lisp_gpe_enable_disable, "enable|disable")                            \
22468 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
22469   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
22470 _(show_lisp_rloc_probe_state, "")                                       \
22471 _(show_lisp_map_register_state, "")                                     \
22472 _(show_lisp_status, "")                                                 \
22473 _(lisp_get_map_request_itr_rlocs, "")                                   \
22474 _(show_lisp_pitr, "")                                                   \
22475 _(show_lisp_use_petr, "")                                               \
22476 _(show_lisp_map_request_mode, "")                                       \
22477 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
22478 _(af_packet_delete, "name <host interface name>")                       \
22479 _(af_packet_dump, "")                                                   \
22480 _(policer_add_del, "name <policer name> <params> [del]")                \
22481 _(policer_dump, "[name <policer name>]")                                \
22482 _(policer_classify_set_interface,                                       \
22483   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22484   "  [l2-table <nn>] [del]")                                            \
22485 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
22486 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
22487     "[master|slave]")                                                   \
22488 _(netmap_delete, "name <interface name>")                               \
22489 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
22490 _(mpls_fib_dump, "")                                                    \
22491 _(classify_table_ids, "")                                               \
22492 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
22493 _(classify_table_info, "table_id <nn>")                                 \
22494 _(classify_session_dump, "table_id <nn>")                               \
22495 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
22496     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
22497     "[template_interval <nn>] [udp_checksum]")                          \
22498 _(ipfix_exporter_dump, "")                                              \
22499 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
22500 _(ipfix_classify_stream_dump, "")                                       \
22501 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
22502 _(ipfix_classify_table_dump, "")                                        \
22503 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
22504 _(sw_interface_span_dump, "[l2]")                                           \
22505 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
22506 _(pg_create_interface, "if_id <nn>")                                    \
22507 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
22508 _(pg_enable_disable, "[stream <id>] disable")                           \
22509 _(ip_source_and_port_range_check_add_del,                               \
22510   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
22511 _(ip_source_and_port_range_check_interface_add_del,                     \
22512   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
22513   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
22514 _(ipsec_gre_tunnel_add_del,                                             \
22515   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
22516 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
22517 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
22518 _(l2_interface_pbb_tag_rewrite,                                         \
22519   "<intfc> | sw_if_index <nn> \n"                                       \
22520   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
22521   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
22522 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
22523 _(flow_classify_set_interface,                                          \
22524   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
22525 _(flow_classify_dump, "type [ip4|ip6]")                                 \
22526 _(ip_fib_dump, "")                                                      \
22527 _(ip_mfib_dump, "")                                                     \
22528 _(ip6_fib_dump, "")                                                     \
22529 _(ip6_mfib_dump, "")                                                    \
22530 _(feature_enable_disable, "arc_name <arc_name> "                        \
22531   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
22532 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
22533 "[disable]")                                                            \
22534 _(l2_xconnect_dump, "")                                                 \
22535 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
22536 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
22537 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
22538 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
22539 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
22540 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
22541 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
22542   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
22543 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
22544 _(sock_init_shm, "size <nnn>")                                          \
22545 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
22546 _(dns_enable_disable, "[enable][disable]")                              \
22547 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22548 _(dns_resolve_name, "<hostname>")                                       \
22549 _(dns_resolve_ip, "<ip4|ip6>")                                          \
22550 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22551 _(dns_resolve_name, "<hostname>")                                       \
22552 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
22553   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
22554 _(session_rules_dump, "")                                               \
22555 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
22556 _(output_acl_set_interface,                                             \
22557   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22558   "  [l2-table <nn>] [del]")                                            \
22559 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
22560
22561 /* List of command functions, CLI names map directly to functions */
22562 #define foreach_cli_function                                    \
22563 _(comment, "usage: comment <ignore-rest-of-line>")              \
22564 _(dump_interface_table, "usage: dump_interface_table")          \
22565 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
22566 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
22567 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
22568 _(dump_macro_table, "usage: dump_macro_table ")                 \
22569 _(dump_node_table, "usage: dump_node_table")                    \
22570 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
22571 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
22572 _(echo, "usage: echo <message>")                                \
22573 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
22574 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
22575 _(help, "usage: help")                                          \
22576 _(q, "usage: quit")                                             \
22577 _(quit, "usage: quit")                                          \
22578 _(search_node_table, "usage: search_node_table <name>...")      \
22579 _(set, "usage: set <variable-name> <value>")                    \
22580 _(script, "usage: script <file-name>")                          \
22581 _(statseg, "usage: statseg");                                   \
22582 _(unset, "usage: unset <variable-name>")
22583
22584 #define _(N,n)                                  \
22585     static void vl_api_##n##_t_handler_uni      \
22586     (vl_api_##n##_t * mp)                       \
22587     {                                           \
22588         vat_main_t * vam = &vat_main;           \
22589         if (vam->json_output) {                 \
22590             vl_api_##n##_t_handler_json(mp);    \
22591         } else {                                \
22592             vl_api_##n##_t_handler(mp);         \
22593         }                                       \
22594     }
22595 foreach_vpe_api_reply_msg;
22596 #if VPP_API_TEST_BUILTIN == 0
22597 foreach_standalone_reply_msg;
22598 #endif
22599 #undef _
22600
22601 void
22602 vat_api_hookup (vat_main_t * vam)
22603 {
22604 #define _(N,n)                                                  \
22605     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
22606                            vl_api_##n##_t_handler_uni,          \
22607                            vl_noop_handler,                     \
22608                            vl_api_##n##_t_endian,               \
22609                            vl_api_##n##_t_print,                \
22610                            sizeof(vl_api_##n##_t), 1);
22611   foreach_vpe_api_reply_msg;
22612 #if VPP_API_TEST_BUILTIN == 0
22613   foreach_standalone_reply_msg;
22614 #endif
22615 #undef _
22616
22617 #if (VPP_API_TEST_BUILTIN==0)
22618   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
22619
22620   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
22621
22622   vam->function_by_name = hash_create_string (0, sizeof (uword));
22623
22624   vam->help_by_name = hash_create_string (0, sizeof (uword));
22625 #endif
22626
22627   /* API messages we can send */
22628 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
22629   foreach_vpe_api_msg;
22630 #undef _
22631
22632   /* Help strings */
22633 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22634   foreach_vpe_api_msg;
22635 #undef _
22636
22637   /* CLI functions */
22638 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
22639   foreach_cli_function;
22640 #undef _
22641
22642   /* Help strings */
22643 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22644   foreach_cli_function;
22645 #undef _
22646 }
22647
22648 #if VPP_API_TEST_BUILTIN
22649 static clib_error_t *
22650 vat_api_hookup_shim (vlib_main_t * vm)
22651 {
22652   vat_api_hookup (&vat_main);
22653   return 0;
22654 }
22655
22656 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
22657 #endif
22658
22659 /*
22660  * fd.io coding-style-patch-verification: ON
22661  *
22662  * Local Variables:
22663  * eval: (c-set-style "gnu")
22664  * End:
22665  */