lldp: Move to plugin
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2020 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 <vlib/pci/pci.h>
22 #include <vpp/api/types.h>
23 #include <vppinfra/socket.h>
24 #include <vlibapi/api.h>
25 #include <vlibmemory/api.h>
26 #include <vnet/ip/ip.h>
27 #include <vnet/ip-neighbor/ip_neighbor.h>
28 #include <vnet/ip/ip_types_api.h>
29 #include <vnet/l2/l2_input.h>
30 #include <vnet/l2tp/l2tp.h>
31 #include <vnet/vxlan/vxlan.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/ip/ip6_hop_by_hop.h>
46 #include <vnet/ip/ip_source_and_port_range_check.h>
47 #include <vnet/policer/xlate.h>
48 #include <vnet/span/span.h>
49 #include <vnet/policer/policer.h>
50 #include <vnet/policer/police.h>
51 #include <vnet/mfib/mfib_types.h>
52 #include <vnet/bonding/node.h>
53 #include <vnet/qos/qos_types.h>
54 #include <vnet/ethernet/ethernet_types_api.h>
55 #include <vnet/ip/ip_types_api.h>
56 #include "vat/json_format.h"
57 #include <vnet/ip/ip_types_api.h>
58 #include <vnet/ethernet/ethernet_types_api.h>
59
60 #include <inttypes.h>
61 #include <sys/stat.h>
62
63 #define vl_typedefs             /* define message structures */
64 #include <vpp/api/vpe_all_api_h.h>
65 #undef vl_typedefs
66
67 /* declare message handlers for each api */
68
69 #define vl_endianfun            /* define message structures */
70 #include <vpp/api/vpe_all_api_h.h>
71 #undef vl_endianfun
72
73 /* instantiate all the print functions we know about */
74 #if VPP_API_TEST_BUILTIN == 0
75 #define vl_print(handle, ...)
76 #else
77 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
78 #endif
79 #define vl_printfun
80 #include <vpp/api/vpe_all_api_h.h>
81 #undef vl_printfun
82
83 #define __plugin_msg_base 0
84 #include <vlibapi/vat_helper_macros.h>
85
86 #include <vnet/format_fns.h>
87
88 void vl_api_set_elog_main (elog_main_t * m);
89 int vl_api_set_elog_trace_api_messages (int enable);
90
91 #if VPP_API_TEST_BUILTIN == 0
92 #include <netdb.h>
93
94 u32
95 vl (void *p)
96 {
97   return vec_len (p);
98 }
99
100 int
101 vat_socket_connect (vat_main_t * vam)
102 {
103   int rv;
104   api_main_t *am = vlibapi_get_main ();
105   vam->socket_client_main = &socket_client_main;
106   if ((rv = vl_socket_client_connect ((char *) vam->socket_name,
107                                       "vpp_api_test",
108                                       0 /* default socket rx, tx buffer */ )))
109     return rv;
110
111   /* vpp expects the client index in network order */
112   vam->my_client_index = htonl (socket_client_main.client_index);
113   am->my_client_index = vam->my_client_index;
114   return 0;
115 }
116 #else /* vpp built-in case, we don't do sockets... */
117 int
118 vat_socket_connect (vat_main_t * vam)
119 {
120   return 0;
121 }
122
123 int
124 vl_socket_client_read (int wait)
125 {
126   return -1;
127 };
128
129 int
130 vl_socket_client_write ()
131 {
132   return -1;
133 };
134
135 void *
136 vl_socket_client_msg_alloc (int nbytes)
137 {
138   return 0;
139 }
140 #endif
141
142
143 f64
144 vat_time_now (vat_main_t * vam)
145 {
146 #if VPP_API_TEST_BUILTIN
147   return vlib_time_now (vam->vlib_main);
148 #else
149   return clib_time_now (&vam->clib_time);
150 #endif
151 }
152
153 void
154 errmsg (char *fmt, ...)
155 {
156   vat_main_t *vam = &vat_main;
157   va_list va;
158   u8 *s;
159
160   va_start (va, fmt);
161   s = va_format (0, fmt, &va);
162   va_end (va);
163
164   vec_add1 (s, 0);
165
166 #if VPP_API_TEST_BUILTIN
167   vlib_cli_output (vam->vlib_main, (char *) s);
168 #else
169   {
170     if (vam->ifp != stdin)
171       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
172                vam->input_line_number);
173     else
174       fformat (vam->ofp, "%s\n", (char *) s);
175     fflush (vam->ofp);
176   }
177 #endif
178
179   vec_free (s);
180 }
181
182 #if VPP_API_TEST_BUILTIN == 0
183 static uword
184 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
185 {
186   vat_main_t *vam = va_arg (*args, vat_main_t *);
187   u32 *result = va_arg (*args, u32 *);
188   u8 *if_name;
189   uword *p;
190
191   if (!unformat (input, "%s", &if_name))
192     return 0;
193
194   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
195   if (p == 0)
196     return 0;
197   *result = p[0];
198   return 1;
199 }
200
201 static uword
202 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
203 {
204   return 0;
205 }
206
207 /* Parse an IP4 address %d.%d.%d.%d. */
208 uword
209 unformat_ip4_address (unformat_input_t * input, va_list * args)
210 {
211   u8 *result = va_arg (*args, u8 *);
212   unsigned a[4];
213
214   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
215     return 0;
216
217   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
218     return 0;
219
220   result[0] = a[0];
221   result[1] = a[1];
222   result[2] = a[2];
223   result[3] = a[3];
224
225   return 1;
226 }
227
228 uword
229 unformat_ethernet_address (unformat_input_t * input, va_list * args)
230 {
231   u8 *result = va_arg (*args, u8 *);
232   u32 i, a[6];
233
234   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
235                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
236     return 0;
237
238   /* Check range. */
239   for (i = 0; i < 6; i++)
240     if (a[i] >= (1 << 8))
241       return 0;
242
243   for (i = 0; i < 6; i++)
244     result[i] = a[i];
245
246   return 1;
247 }
248
249 /* Returns ethernet type as an int in host byte order. */
250 uword
251 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
252                                         va_list * args)
253 {
254   u16 *result = va_arg (*args, u16 *);
255   int type;
256
257   /* Numeric type. */
258   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
259     {
260       if (type >= (1 << 16))
261         return 0;
262       *result = type;
263       return 1;
264     }
265   return 0;
266 }
267
268 /* Parse an IP46 address. */
269 uword
270 unformat_ip46_address (unformat_input_t * input, va_list * args)
271 {
272   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
273   ip46_type_t type = va_arg (*args, ip46_type_t);
274   if ((type != IP46_TYPE_IP6) &&
275       unformat (input, "%U", unformat_ip4_address, &ip46->ip4))
276     {
277       ip46_address_mask_ip4 (ip46);
278       return 1;
279     }
280   else if ((type != IP46_TYPE_IP4) &&
281            unformat (input, "%U", unformat_ip6_address, &ip46->ip6))
282     {
283       return 1;
284     }
285   return 0;
286 }
287
288 /* Parse an IP6 address. */
289 uword
290 unformat_ip6_address (unformat_input_t * input, va_list * args)
291 {
292   ip6_address_t *result = va_arg (*args, ip6_address_t *);
293   u16 hex_quads[8];
294   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
295   uword c, n_colon, double_colon_index;
296
297   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
298   double_colon_index = ARRAY_LEN (hex_quads);
299   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
300     {
301       hex_digit = 16;
302       if (c >= '0' && c <= '9')
303         hex_digit = c - '0';
304       else if (c >= 'a' && c <= 'f')
305         hex_digit = c + 10 - 'a';
306       else if (c >= 'A' && c <= 'F')
307         hex_digit = c + 10 - 'A';
308       else if (c == ':' && n_colon < 2)
309         n_colon++;
310       else
311         {
312           unformat_put_input (input);
313           break;
314         }
315
316       /* Too many hex quads. */
317       if (n_hex_quads >= ARRAY_LEN (hex_quads))
318         return 0;
319
320       if (hex_digit < 16)
321         {
322           hex_quad = (hex_quad << 4) | hex_digit;
323
324           /* Hex quad must fit in 16 bits. */
325           if (n_hex_digits >= 4)
326             return 0;
327
328           n_colon = 0;
329           n_hex_digits++;
330         }
331
332       /* Save position of :: */
333       if (n_colon == 2)
334         {
335           /* More than one :: ? */
336           if (double_colon_index < ARRAY_LEN (hex_quads))
337             return 0;
338           double_colon_index = n_hex_quads;
339         }
340
341       if (n_colon > 0 && n_hex_digits > 0)
342         {
343           hex_quads[n_hex_quads++] = hex_quad;
344           hex_quad = 0;
345           n_hex_digits = 0;
346         }
347     }
348
349   if (n_hex_digits > 0)
350     hex_quads[n_hex_quads++] = hex_quad;
351
352   {
353     word i;
354
355     /* Expand :: to appropriate number of zero hex quads. */
356     if (double_colon_index < ARRAY_LEN (hex_quads))
357       {
358         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
359
360         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
361           hex_quads[n_zero + i] = hex_quads[i];
362
363         for (i = 0; i < n_zero; i++)
364           hex_quads[double_colon_index + i] = 0;
365
366         n_hex_quads = ARRAY_LEN (hex_quads);
367       }
368
369     /* Too few hex quads given. */
370     if (n_hex_quads < ARRAY_LEN (hex_quads))
371       return 0;
372
373     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
374       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
375
376     return 1;
377   }
378 }
379
380 uword
381 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
382 {
383   u32 *r = va_arg (*args, u32 *);
384
385   if (0);
386 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
387   foreach_ipsec_policy_action
388 #undef _
389     else
390     return 0;
391   return 1;
392 }
393
394 u8 *
395 format_ipsec_crypto_alg (u8 * s, va_list * args)
396 {
397   u32 i = va_arg (*args, u32);
398   u8 *t = 0;
399
400   switch (i)
401     {
402 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
403       foreach_ipsec_crypto_alg
404 #undef _
405     default:
406       return format (s, "unknown");
407     }
408   return format (s, "%s", t);
409 }
410
411 u8 *
412 format_ipsec_integ_alg (u8 * s, va_list * args)
413 {
414   u32 i = va_arg (*args, u32);
415   u8 *t = 0;
416
417   switch (i)
418     {
419 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
420       foreach_ipsec_integ_alg
421 #undef _
422     default:
423       return format (s, "unknown");
424     }
425   return format (s, "%s", t);
426 }
427
428 #else /* VPP_API_TEST_BUILTIN == 1 */
429 static uword
430 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
431 {
432   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
433   vnet_main_t *vnm = vnet_get_main ();
434   u32 *result = va_arg (*args, u32 *);
435
436   return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
437 }
438
439 static uword
440 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
441 {
442   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
443   vnet_main_t *vnm = vnet_get_main ();
444   u32 *result = va_arg (*args, u32 *);
445
446   return unformat (input, "%U", unformat_vnet_hw_interface, vnm, result);
447 }
448
449 #endif /* VPP_API_TEST_BUILTIN */
450
451 uword
452 unformat_ipsec_api_crypto_alg (unformat_input_t * input, va_list * args)
453 {
454   u32 *r = va_arg (*args, u32 *);
455
456   if (0);
457 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_CRYPTO_ALG_##f;
458   foreach_ipsec_crypto_alg
459 #undef _
460     else
461     return 0;
462   return 1;
463 }
464
465 uword
466 unformat_ipsec_api_integ_alg (unformat_input_t * input, va_list * args)
467 {
468   u32 *r = va_arg (*args, u32 *);
469
470   if (0);
471 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_INTEG_ALG_##f;
472   foreach_ipsec_integ_alg
473 #undef _
474     else
475     return 0;
476   return 1;
477 }
478
479 static uword
480 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
481 {
482   u8 *r = va_arg (*args, u8 *);
483
484   if (unformat (input, "kbps"))
485     *r = SSE2_QOS_RATE_KBPS;
486   else if (unformat (input, "pps"))
487     *r = SSE2_QOS_RATE_PPS;
488   else
489     return 0;
490   return 1;
491 }
492
493 static uword
494 unformat_policer_round_type (unformat_input_t * input, va_list * args)
495 {
496   u8 *r = va_arg (*args, u8 *);
497
498   if (unformat (input, "closest"))
499     *r = SSE2_QOS_ROUND_TO_CLOSEST;
500   else if (unformat (input, "up"))
501     *r = SSE2_QOS_ROUND_TO_UP;
502   else if (unformat (input, "down"))
503     *r = SSE2_QOS_ROUND_TO_DOWN;
504   else
505     return 0;
506   return 1;
507 }
508
509 static uword
510 unformat_policer_type (unformat_input_t * input, va_list * args)
511 {
512   u8 *r = va_arg (*args, u8 *);
513
514   if (unformat (input, "1r2c"))
515     *r = SSE2_QOS_POLICER_TYPE_1R2C;
516   else if (unformat (input, "1r3c"))
517     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
518   else if (unformat (input, "2r3c-2698"))
519     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
520   else if (unformat (input, "2r3c-4115"))
521     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
522   else if (unformat (input, "2r3c-mef5cf1"))
523     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
524   else
525     return 0;
526   return 1;
527 }
528
529 static uword
530 unformat_dscp (unformat_input_t * input, va_list * va)
531 {
532   u8 *r = va_arg (*va, u8 *);
533
534   if (0);
535 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
536   foreach_vnet_dscp
537 #undef _
538     else
539     return 0;
540   return 1;
541 }
542
543 static uword
544 unformat_policer_action_type (unformat_input_t * input, va_list * va)
545 {
546   sse2_qos_pol_action_params_st *a
547     = va_arg (*va, sse2_qos_pol_action_params_st *);
548
549   if (unformat (input, "drop"))
550     a->action_type = SSE2_QOS_ACTION_DROP;
551   else if (unformat (input, "transmit"))
552     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
553   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
554     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
555   else
556     return 0;
557   return 1;
558 }
559
560 static uword
561 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
562 {
563   u32 *r = va_arg (*va, u32 *);
564   u32 tid;
565
566   if (unformat (input, "ip4"))
567     tid = POLICER_CLASSIFY_TABLE_IP4;
568   else if (unformat (input, "ip6"))
569     tid = POLICER_CLASSIFY_TABLE_IP6;
570   else if (unformat (input, "l2"))
571     tid = POLICER_CLASSIFY_TABLE_L2;
572   else
573     return 0;
574
575   *r = tid;
576   return 1;
577 }
578
579 static uword
580 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
581 {
582   u32 *r = va_arg (*va, u32 *);
583   u32 tid;
584
585   if (unformat (input, "ip4"))
586     tid = FLOW_CLASSIFY_TABLE_IP4;
587   else if (unformat (input, "ip6"))
588     tid = FLOW_CLASSIFY_TABLE_IP6;
589   else
590     return 0;
591
592   *r = tid;
593   return 1;
594 }
595
596 #if (VPP_API_TEST_BUILTIN==0)
597
598 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
599 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
600 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
601 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
602
603 uword
604 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
605 {
606   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
607   mfib_itf_attribute_t attr;
608
609   old = *iflags;
610   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
611   {
612     if (unformat (input, mfib_itf_flag_long_names[attr]))
613       *iflags |= (1 << attr);
614   }
615   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
616   {
617     if (unformat (input, mfib_itf_flag_names[attr]))
618       *iflags |= (1 << attr);
619   }
620
621   return (old == *iflags ? 0 : 1);
622 }
623
624 uword
625 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
626 {
627   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
628   mfib_entry_attribute_t attr;
629
630   old = *eflags;
631   FOR_EACH_MFIB_ATTRIBUTE (attr)
632   {
633     if (unformat (input, mfib_flag_long_names[attr]))
634       *eflags |= (1 << attr);
635   }
636   FOR_EACH_MFIB_ATTRIBUTE (attr)
637   {
638     if (unformat (input, mfib_flag_names[attr]))
639       *eflags |= (1 << attr);
640   }
641
642   return (old == *eflags ? 0 : 1);
643 }
644
645 u8 *
646 format_ip4_address (u8 * s, va_list * args)
647 {
648   u8 *a = va_arg (*args, u8 *);
649   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
650 }
651
652 u8 *
653 format_ip6_address (u8 * s, va_list * args)
654 {
655   ip6_address_t *a = va_arg (*args, ip6_address_t *);
656   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
657
658   i_max_n_zero = ARRAY_LEN (a->as_u16);
659   max_n_zeros = 0;
660   i_first_zero = i_max_n_zero;
661   n_zeros = 0;
662   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
663     {
664       u32 is_zero = a->as_u16[i] == 0;
665       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
666         {
667           i_first_zero = i;
668           n_zeros = 0;
669         }
670       n_zeros += is_zero;
671       if ((!is_zero && n_zeros > max_n_zeros)
672           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
673         {
674           i_max_n_zero = i_first_zero;
675           max_n_zeros = n_zeros;
676           i_first_zero = ARRAY_LEN (a->as_u16);
677           n_zeros = 0;
678         }
679     }
680
681   last_double_colon = 0;
682   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
683     {
684       if (i == i_max_n_zero && max_n_zeros > 1)
685         {
686           s = format (s, "::");
687           i += max_n_zeros - 1;
688           last_double_colon = 1;
689         }
690       else
691         {
692           s = format (s, "%s%x",
693                       (last_double_colon || i == 0) ? "" : ":",
694                       clib_net_to_host_u16 (a->as_u16[i]));
695           last_double_colon = 0;
696         }
697     }
698
699   return s;
700 }
701
702 /* Format an IP46 address. */
703 u8 *
704 format_ip46_address (u8 * s, va_list * args)
705 {
706   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
707   ip46_type_t type = va_arg (*args, ip46_type_t);
708   int is_ip4 = 1;
709
710   switch (type)
711     {
712     case IP46_TYPE_ANY:
713       is_ip4 = ip46_address_is_ip4 (ip46);
714       break;
715     case IP46_TYPE_IP4:
716       is_ip4 = 1;
717       break;
718     case IP46_TYPE_IP6:
719       is_ip4 = 0;
720       break;
721     }
722
723   return is_ip4 ?
724     format (s, "%U", format_ip4_address, &ip46->ip4) :
725     format (s, "%U", format_ip6_address, &ip46->ip6);
726 }
727
728 u8 *
729 format_ethernet_address (u8 * s, va_list * args)
730 {
731   u8 *a = va_arg (*args, u8 *);
732
733   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
734                  a[0], a[1], a[2], a[3], a[4], a[5]);
735 }
736 #endif
737
738 static void
739 increment_v4_address (vl_api_ip4_address_t * i)
740 {
741   ip4_address_t *a = (ip4_address_t *) i;
742   u32 v;
743
744   v = ntohl (a->as_u32) + 1;
745   a->as_u32 = ntohl (v);
746 }
747
748 static void
749 increment_v6_address (vl_api_ip6_address_t * i)
750 {
751   ip6_address_t *a = (ip6_address_t *) i;
752   u64 v0, v1;
753
754   v0 = clib_net_to_host_u64 (a->as_u64[0]);
755   v1 = clib_net_to_host_u64 (a->as_u64[1]);
756
757   v1 += 1;
758   if (v1 == 0)
759     v0 += 1;
760   a->as_u64[0] = clib_net_to_host_u64 (v0);
761   a->as_u64[1] = clib_net_to_host_u64 (v1);
762 }
763
764 static void
765 increment_address (vl_api_address_t * a)
766 {
767   if (a->af == ADDRESS_IP4)
768     increment_v4_address (&a->un.ip4);
769   else if (a->af == ADDRESS_IP6)
770     increment_v6_address (&a->un.ip6);
771 }
772
773 static void
774 set_ip4_address (vl_api_address_t * a, u32 v)
775 {
776   if (a->af == ADDRESS_IP4)
777     {
778       ip4_address_t *i = (ip4_address_t *) & a->un.ip4;
779       i->as_u32 = v;
780     }
781 }
782
783 void
784 ip_set (ip46_address_t * dst, void *src, u8 is_ip4)
785 {
786   if (is_ip4)
787     dst->ip4.as_u32 = ((ip4_address_t *) src)->as_u32;
788   else
789     clib_memcpy_fast (&dst->ip6, (ip6_address_t *) src,
790                       sizeof (ip6_address_t));
791 }
792
793 static void
794 increment_mac_address (u8 * mac)
795 {
796   u64 tmp = *((u64 *) mac);
797   tmp = clib_net_to_host_u64 (tmp);
798   tmp += 1 << 16;               /* skip unused (least significant) octets */
799   tmp = clib_host_to_net_u64 (tmp);
800
801   clib_memcpy (mac, &tmp, 6);
802 }
803
804 static void
805 vat_json_object_add_address (vat_json_node_t * node,
806                              const char *str, const vl_api_address_t * addr)
807 {
808   if (ADDRESS_IP6 == addr->af)
809     {
810       struct in6_addr ip6;
811
812       clib_memcpy (&ip6, &addr->un.ip6, sizeof (ip6));
813       vat_json_object_add_ip6 (node, str, ip6);
814     }
815   else
816     {
817       struct in_addr ip4;
818
819       clib_memcpy (&ip4, &addr->un.ip4, sizeof (ip4));
820       vat_json_object_add_ip4 (node, str, ip4);
821     }
822 }
823
824 static void
825 vat_json_object_add_prefix (vat_json_node_t * node,
826                             const vl_api_prefix_t * prefix)
827 {
828   vat_json_object_add_uint (node, "len", prefix->len);
829   vat_json_object_add_address (node, "address", &prefix->address);
830 }
831
832 static void vl_api_create_loopback_reply_t_handler
833   (vl_api_create_loopback_reply_t * mp)
834 {
835   vat_main_t *vam = &vat_main;
836   i32 retval = ntohl (mp->retval);
837
838   vam->retval = retval;
839   vam->regenerate_interface_table = 1;
840   vam->sw_if_index = ntohl (mp->sw_if_index);
841   vam->result_ready = 1;
842 }
843
844 static void vl_api_create_loopback_reply_t_handler_json
845   (vl_api_create_loopback_reply_t * mp)
846 {
847   vat_main_t *vam = &vat_main;
848   vat_json_node_t node;
849
850   vat_json_init_object (&node);
851   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
852   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
853
854   vat_json_print (vam->ofp, &node);
855   vat_json_free (&node);
856   vam->retval = ntohl (mp->retval);
857   vam->result_ready = 1;
858 }
859
860 static void vl_api_create_loopback_instance_reply_t_handler
861   (vl_api_create_loopback_instance_reply_t * mp)
862 {
863   vat_main_t *vam = &vat_main;
864   i32 retval = ntohl (mp->retval);
865
866   vam->retval = retval;
867   vam->regenerate_interface_table = 1;
868   vam->sw_if_index = ntohl (mp->sw_if_index);
869   vam->result_ready = 1;
870 }
871
872 static void vl_api_create_loopback_instance_reply_t_handler_json
873   (vl_api_create_loopback_instance_reply_t * mp)
874 {
875   vat_main_t *vam = &vat_main;
876   vat_json_node_t node;
877
878   vat_json_init_object (&node);
879   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
880   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
881
882   vat_json_print (vam->ofp, &node);
883   vat_json_free (&node);
884   vam->retval = ntohl (mp->retval);
885   vam->result_ready = 1;
886 }
887
888 static void vl_api_af_packet_create_reply_t_handler
889   (vl_api_af_packet_create_reply_t * mp)
890 {
891   vat_main_t *vam = &vat_main;
892   i32 retval = ntohl (mp->retval);
893
894   vam->retval = retval;
895   vam->regenerate_interface_table = 1;
896   vam->sw_if_index = ntohl (mp->sw_if_index);
897   vam->result_ready = 1;
898 }
899
900 static void vl_api_af_packet_create_reply_t_handler_json
901   (vl_api_af_packet_create_reply_t * mp)
902 {
903   vat_main_t *vam = &vat_main;
904   vat_json_node_t node;
905
906   vat_json_init_object (&node);
907   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
908   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
909
910   vat_json_print (vam->ofp, &node);
911   vat_json_free (&node);
912
913   vam->retval = ntohl (mp->retval);
914   vam->result_ready = 1;
915 }
916
917 static void vl_api_create_vlan_subif_reply_t_handler
918   (vl_api_create_vlan_subif_reply_t * mp)
919 {
920   vat_main_t *vam = &vat_main;
921   i32 retval = ntohl (mp->retval);
922
923   vam->retval = retval;
924   vam->regenerate_interface_table = 1;
925   vam->sw_if_index = ntohl (mp->sw_if_index);
926   vam->result_ready = 1;
927 }
928
929 static void vl_api_create_vlan_subif_reply_t_handler_json
930   (vl_api_create_vlan_subif_reply_t * mp)
931 {
932   vat_main_t *vam = &vat_main;
933   vat_json_node_t node;
934
935   vat_json_init_object (&node);
936   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
937   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
938
939   vat_json_print (vam->ofp, &node);
940   vat_json_free (&node);
941
942   vam->retval = ntohl (mp->retval);
943   vam->result_ready = 1;
944 }
945
946 static void vl_api_create_subif_reply_t_handler
947   (vl_api_create_subif_reply_t * mp)
948 {
949   vat_main_t *vam = &vat_main;
950   i32 retval = ntohl (mp->retval);
951
952   vam->retval = retval;
953   vam->regenerate_interface_table = 1;
954   vam->sw_if_index = ntohl (mp->sw_if_index);
955   vam->result_ready = 1;
956 }
957
958 static void vl_api_create_subif_reply_t_handler_json
959   (vl_api_create_subif_reply_t * mp)
960 {
961   vat_main_t *vam = &vat_main;
962   vat_json_node_t node;
963
964   vat_json_init_object (&node);
965   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
966   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
967
968   vat_json_print (vam->ofp, &node);
969   vat_json_free (&node);
970
971   vam->retval = ntohl (mp->retval);
972   vam->result_ready = 1;
973 }
974
975 static void vl_api_interface_name_renumber_reply_t_handler
976   (vl_api_interface_name_renumber_reply_t * mp)
977 {
978   vat_main_t *vam = &vat_main;
979   i32 retval = ntohl (mp->retval);
980
981   vam->retval = retval;
982   vam->regenerate_interface_table = 1;
983   vam->result_ready = 1;
984 }
985
986 static void vl_api_interface_name_renumber_reply_t_handler_json
987   (vl_api_interface_name_renumber_reply_t * mp)
988 {
989   vat_main_t *vam = &vat_main;
990   vat_json_node_t node;
991
992   vat_json_init_object (&node);
993   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
994
995   vat_json_print (vam->ofp, &node);
996   vat_json_free (&node);
997
998   vam->retval = ntohl (mp->retval);
999   vam->result_ready = 1;
1000 }
1001
1002 /*
1003  * Special-case: build the interface table, maintain
1004  * the next loopback sw_if_index vbl.
1005  */
1006 static void vl_api_sw_interface_details_t_handler
1007   (vl_api_sw_interface_details_t * mp)
1008 {
1009   vat_main_t *vam = &vat_main;
1010   u8 *s = format (0, "%s%c", mp->interface_name, 0);
1011
1012   hash_set_mem (vam->sw_if_index_by_interface_name, s,
1013                 ntohl (mp->sw_if_index));
1014
1015   /* In sub interface case, fill the sub interface table entry */
1016   if (mp->sw_if_index != mp->sup_sw_if_index)
1017     {
1018       sw_interface_subif_t *sub = NULL;
1019
1020       vec_add2 (vam->sw_if_subif_table, sub, 1);
1021
1022       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
1023       strncpy ((char *) sub->interface_name, (char *) s,
1024                vec_len (sub->interface_name));
1025       sub->sw_if_index = ntohl (mp->sw_if_index);
1026       sub->sub_id = ntohl (mp->sub_id);
1027
1028       sub->raw_flags = ntohl (mp->sub_if_flags & SUB_IF_API_FLAG_MASK_VNET);
1029
1030       sub->sub_number_of_tags = mp->sub_number_of_tags;
1031       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
1032       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
1033
1034       /* vlan tag rewrite */
1035       sub->vtr_op = ntohl (mp->vtr_op);
1036       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
1037       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
1038       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
1039     }
1040 }
1041
1042 static void vl_api_sw_interface_details_t_handler_json
1043   (vl_api_sw_interface_details_t * mp)
1044 {
1045   vat_main_t *vam = &vat_main;
1046   vat_json_node_t *node = NULL;
1047
1048   if (VAT_JSON_ARRAY != vam->json_tree.type)
1049     {
1050       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1051       vat_json_init_array (&vam->json_tree);
1052     }
1053   node = vat_json_array_add (&vam->json_tree);
1054
1055   vat_json_init_object (node);
1056   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1057   vat_json_object_add_uint (node, "sup_sw_if_index",
1058                             ntohl (mp->sup_sw_if_index));
1059   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
1060                              sizeof (mp->l2_address));
1061   vat_json_object_add_string_copy (node, "interface_name",
1062                                    mp->interface_name);
1063   vat_json_object_add_string_copy (node, "interface_dev_type",
1064                                    mp->interface_dev_type);
1065   vat_json_object_add_uint (node, "flags", mp->flags);
1066   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
1067   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
1068   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
1069   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
1070   vat_json_object_add_uint (node, "sub_number_of_tags",
1071                             mp->sub_number_of_tags);
1072   vat_json_object_add_uint (node, "sub_outer_vlan_id",
1073                             ntohs (mp->sub_outer_vlan_id));
1074   vat_json_object_add_uint (node, "sub_inner_vlan_id",
1075                             ntohs (mp->sub_inner_vlan_id));
1076   vat_json_object_add_uint (node, "sub_if_flags", ntohl (mp->sub_if_flags));
1077   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1078   vat_json_object_add_uint (node, "vtr_push_dot1q",
1079                             ntohl (mp->vtr_push_dot1q));
1080   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1081   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1082   if (ntohl (mp->sub_if_flags) & SUB_IF_API_FLAG_DOT1AH)
1083     {
1084       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1085                                        format (0, "%U",
1086                                                format_ethernet_address,
1087                                                &mp->b_dmac));
1088       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1089                                        format (0, "%U",
1090                                                format_ethernet_address,
1091                                                &mp->b_smac));
1092       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1093       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1094     }
1095 }
1096
1097 #if VPP_API_TEST_BUILTIN == 0
1098 static void vl_api_sw_interface_event_t_handler
1099   (vl_api_sw_interface_event_t * mp)
1100 {
1101   vat_main_t *vam = &vat_main;
1102   if (vam->interface_event_display)
1103     errmsg ("interface flags: sw_if_index %d %s %s",
1104             ntohl (mp->sw_if_index),
1105             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_ADMIN_UP) ?
1106             "admin-up" : "admin-down",
1107             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_LINK_UP) ?
1108             "link-up" : "link-down");
1109 }
1110 #endif
1111
1112 __clib_unused static void
1113 vl_api_sw_interface_event_t_handler_json (vl_api_sw_interface_event_t * mp)
1114 {
1115   /* JSON output not supported */
1116 }
1117
1118 static void
1119 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1120 {
1121   vat_main_t *vam = &vat_main;
1122   i32 retval = ntohl (mp->retval);
1123
1124   vam->retval = retval;
1125   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1126   vam->result_ready = 1;
1127 }
1128
1129 static void
1130 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1131 {
1132   vat_main_t *vam = &vat_main;
1133   vat_json_node_t node;
1134   void *oldheap;
1135   u8 *reply;
1136
1137   vat_json_init_object (&node);
1138   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1139   vat_json_object_add_uint (&node, "reply_in_shmem",
1140                             ntohl (mp->reply_in_shmem));
1141   /* Toss the shared-memory original... */
1142   oldheap = vl_msg_push_heap ();
1143
1144   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1145   vec_free (reply);
1146
1147   vl_msg_pop_heap (oldheap);
1148
1149   vat_json_print (vam->ofp, &node);
1150   vat_json_free (&node);
1151
1152   vam->retval = ntohl (mp->retval);
1153   vam->result_ready = 1;
1154 }
1155
1156 static void
1157 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1158 {
1159   vat_main_t *vam = &vat_main;
1160   i32 retval = ntohl (mp->retval);
1161
1162   vec_reset_length (vam->cmd_reply);
1163
1164   vam->retval = retval;
1165   if (retval == 0)
1166     vam->cmd_reply = vl_api_from_api_to_new_vec (mp, &mp->reply);
1167   vam->result_ready = 1;
1168 }
1169
1170 static void
1171 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1172 {
1173   vat_main_t *vam = &vat_main;
1174   vat_json_node_t node;
1175   u8 *reply = 0;                /* reply vector */
1176
1177   reply = vl_api_from_api_to_new_vec (mp, &mp->reply);
1178   vec_reset_length (vam->cmd_reply);
1179
1180   vat_json_init_object (&node);
1181   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1182   vat_json_object_add_string_copy (&node, "reply", reply);
1183
1184   vat_json_print (vam->ofp, &node);
1185   vat_json_free (&node);
1186   vec_free (reply);
1187
1188   vam->retval = ntohl (mp->retval);
1189   vam->result_ready = 1;
1190 }
1191
1192 static void vl_api_classify_add_del_table_reply_t_handler
1193   (vl_api_classify_add_del_table_reply_t * mp)
1194 {
1195   vat_main_t *vam = &vat_main;
1196   i32 retval = ntohl (mp->retval);
1197   if (vam->async_mode)
1198     {
1199       vam->async_errors += (retval < 0);
1200     }
1201   else
1202     {
1203       vam->retval = retval;
1204       if (retval == 0 &&
1205           ((mp->new_table_index != 0xFFFFFFFF) ||
1206            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1207            (mp->match_n_vectors != 0xFFFFFFFF)))
1208         /*
1209          * Note: this is just barely thread-safe, depends on
1210          * the main thread spinning waiting for an answer...
1211          */
1212         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1213                 ntohl (mp->new_table_index),
1214                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1215       vam->result_ready = 1;
1216     }
1217 }
1218
1219 static void vl_api_classify_add_del_table_reply_t_handler_json
1220   (vl_api_classify_add_del_table_reply_t * mp)
1221 {
1222   vat_main_t *vam = &vat_main;
1223   vat_json_node_t node;
1224
1225   vat_json_init_object (&node);
1226   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1227   vat_json_object_add_uint (&node, "new_table_index",
1228                             ntohl (mp->new_table_index));
1229   vat_json_object_add_uint (&node, "skip_n_vectors",
1230                             ntohl (mp->skip_n_vectors));
1231   vat_json_object_add_uint (&node, "match_n_vectors",
1232                             ntohl (mp->match_n_vectors));
1233
1234   vat_json_print (vam->ofp, &node);
1235   vat_json_free (&node);
1236
1237   vam->retval = ntohl (mp->retval);
1238   vam->result_ready = 1;
1239 }
1240
1241 static void vl_api_get_node_index_reply_t_handler
1242   (vl_api_get_node_index_reply_t * mp)
1243 {
1244   vat_main_t *vam = &vat_main;
1245   i32 retval = ntohl (mp->retval);
1246   if (vam->async_mode)
1247     {
1248       vam->async_errors += (retval < 0);
1249     }
1250   else
1251     {
1252       vam->retval = retval;
1253       if (retval == 0)
1254         errmsg ("node index %d", ntohl (mp->node_index));
1255       vam->result_ready = 1;
1256     }
1257 }
1258
1259 static void vl_api_get_node_index_reply_t_handler_json
1260   (vl_api_get_node_index_reply_t * mp)
1261 {
1262   vat_main_t *vam = &vat_main;
1263   vat_json_node_t node;
1264
1265   vat_json_init_object (&node);
1266   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1267   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1268
1269   vat_json_print (vam->ofp, &node);
1270   vat_json_free (&node);
1271
1272   vam->retval = ntohl (mp->retval);
1273   vam->result_ready = 1;
1274 }
1275
1276 static void vl_api_get_next_index_reply_t_handler
1277   (vl_api_get_next_index_reply_t * mp)
1278 {
1279   vat_main_t *vam = &vat_main;
1280   i32 retval = ntohl (mp->retval);
1281   if (vam->async_mode)
1282     {
1283       vam->async_errors += (retval < 0);
1284     }
1285   else
1286     {
1287       vam->retval = retval;
1288       if (retval == 0)
1289         errmsg ("next node index %d", ntohl (mp->next_index));
1290       vam->result_ready = 1;
1291     }
1292 }
1293
1294 static void vl_api_get_next_index_reply_t_handler_json
1295   (vl_api_get_next_index_reply_t * mp)
1296 {
1297   vat_main_t *vam = &vat_main;
1298   vat_json_node_t node;
1299
1300   vat_json_init_object (&node);
1301   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1302   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1303
1304   vat_json_print (vam->ofp, &node);
1305   vat_json_free (&node);
1306
1307   vam->retval = ntohl (mp->retval);
1308   vam->result_ready = 1;
1309 }
1310
1311 static void vl_api_add_node_next_reply_t_handler
1312   (vl_api_add_node_next_reply_t * mp)
1313 {
1314   vat_main_t *vam = &vat_main;
1315   i32 retval = ntohl (mp->retval);
1316   if (vam->async_mode)
1317     {
1318       vam->async_errors += (retval < 0);
1319     }
1320   else
1321     {
1322       vam->retval = retval;
1323       if (retval == 0)
1324         errmsg ("next index %d", ntohl (mp->next_index));
1325       vam->result_ready = 1;
1326     }
1327 }
1328
1329 static void vl_api_add_node_next_reply_t_handler_json
1330   (vl_api_add_node_next_reply_t * mp)
1331 {
1332   vat_main_t *vam = &vat_main;
1333   vat_json_node_t node;
1334
1335   vat_json_init_object (&node);
1336   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1337   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1338
1339   vat_json_print (vam->ofp, &node);
1340   vat_json_free (&node);
1341
1342   vam->retval = ntohl (mp->retval);
1343   vam->result_ready = 1;
1344 }
1345
1346 static void vl_api_show_version_reply_t_handler
1347   (vl_api_show_version_reply_t * mp)
1348 {
1349   vat_main_t *vam = &vat_main;
1350   i32 retval = ntohl (mp->retval);
1351
1352   if (retval >= 0)
1353     {
1354       errmsg ("        program: %s", mp->program);
1355       errmsg ("        version: %s", mp->version);
1356       errmsg ("     build date: %s", mp->build_date);
1357       errmsg ("build directory: %s", mp->build_directory);
1358     }
1359   vam->retval = retval;
1360   vam->result_ready = 1;
1361 }
1362
1363 static void vl_api_show_version_reply_t_handler_json
1364   (vl_api_show_version_reply_t * mp)
1365 {
1366   vat_main_t *vam = &vat_main;
1367   vat_json_node_t node;
1368
1369   vat_json_init_object (&node);
1370   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1371   vat_json_object_add_string_copy (&node, "program", mp->program);
1372   vat_json_object_add_string_copy (&node, "version", mp->version);
1373   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1374   vat_json_object_add_string_copy (&node, "build_directory",
1375                                    mp->build_directory);
1376
1377   vat_json_print (vam->ofp, &node);
1378   vat_json_free (&node);
1379
1380   vam->retval = ntohl (mp->retval);
1381   vam->result_ready = 1;
1382 }
1383
1384 static void vl_api_show_threads_reply_t_handler
1385   (vl_api_show_threads_reply_t * mp)
1386 {
1387   vat_main_t *vam = &vat_main;
1388   i32 retval = ntohl (mp->retval);
1389   int i, count = 0;
1390
1391   if (retval >= 0)
1392     count = ntohl (mp->count);
1393
1394   for (i = 0; i < count; i++)
1395     print (vam->ofp,
1396            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1397            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1398            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1399            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1400            ntohl (mp->thread_data[i].cpu_socket));
1401
1402   vam->retval = retval;
1403   vam->result_ready = 1;
1404 }
1405
1406 static void vl_api_show_threads_reply_t_handler_json
1407   (vl_api_show_threads_reply_t * mp)
1408 {
1409   vat_main_t *vam = &vat_main;
1410   vat_json_node_t node;
1411   vl_api_thread_data_t *td;
1412   i32 retval = ntohl (mp->retval);
1413   int i, count = 0;
1414
1415   if (retval >= 0)
1416     count = ntohl (mp->count);
1417
1418   vat_json_init_object (&node);
1419   vat_json_object_add_int (&node, "retval", retval);
1420   vat_json_object_add_uint (&node, "count", count);
1421
1422   for (i = 0; i < count; i++)
1423     {
1424       td = &mp->thread_data[i];
1425       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1426       vat_json_object_add_string_copy (&node, "name", td->name);
1427       vat_json_object_add_string_copy (&node, "type", td->type);
1428       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1429       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1430       vat_json_object_add_int (&node, "core", ntohl (td->id));
1431       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1432     }
1433
1434   vat_json_print (vam->ofp, &node);
1435   vat_json_free (&node);
1436
1437   vam->retval = retval;
1438   vam->result_ready = 1;
1439 }
1440
1441 static int
1442 api_show_threads (vat_main_t * vam)
1443 {
1444   vl_api_show_threads_t *mp;
1445   int ret;
1446
1447   print (vam->ofp,
1448          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1449          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1450
1451   M (SHOW_THREADS, mp);
1452
1453   S (mp);
1454   W (ret);
1455   return ret;
1456 }
1457
1458 static void
1459 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1460 {
1461   u32 n_macs = ntohl (mp->n_macs);
1462   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1463           ntohl (mp->pid), mp->client_index, n_macs);
1464   int i;
1465   for (i = 0; i < n_macs; i++)
1466     {
1467       vl_api_mac_entry_t *mac = &mp->mac[i];
1468       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1469               i + 1, ntohl (mac->sw_if_index),
1470               format_ethernet_address, mac->mac_addr, mac->action);
1471       if (i == 1000)
1472         break;
1473     }
1474 }
1475
1476 static void
1477 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1478 {
1479   /* JSON output not supported */
1480 }
1481
1482 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1483 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1484
1485 /*
1486  * Special-case: build the bridge domain table, maintain
1487  * the next bd id vbl.
1488  */
1489 static void vl_api_bridge_domain_details_t_handler
1490   (vl_api_bridge_domain_details_t * mp)
1491 {
1492   vat_main_t *vam = &vat_main;
1493   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1494   int i;
1495
1496   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1497          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1498
1499   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1500          ntohl (mp->bd_id), mp->learn, mp->forward,
1501          mp->flood, ntohl (mp->bvi_sw_if_index),
1502          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1503
1504   if (n_sw_ifs)
1505     {
1506       vl_api_bridge_domain_sw_if_t *sw_ifs;
1507       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1508              "Interface Name");
1509
1510       sw_ifs = mp->sw_if_details;
1511       for (i = 0; i < n_sw_ifs; i++)
1512         {
1513           u8 *sw_if_name = 0;
1514           u32 sw_if_index;
1515           hash_pair_t *p;
1516
1517           sw_if_index = ntohl (sw_ifs->sw_if_index);
1518
1519           /* *INDENT-OFF* */
1520           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1521                              ({
1522                                if ((u32) p->value[0] == sw_if_index)
1523                                  {
1524                                    sw_if_name = (u8 *)(p->key);
1525                                    break;
1526                                  }
1527                              }));
1528           /* *INDENT-ON* */
1529           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1530                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1531                  "sw_if_index not found!");
1532
1533           sw_ifs++;
1534         }
1535     }
1536 }
1537
1538 static void vl_api_bridge_domain_details_t_handler_json
1539   (vl_api_bridge_domain_details_t * mp)
1540 {
1541   vat_main_t *vam = &vat_main;
1542   vat_json_node_t *node, *array = NULL;
1543   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1544
1545   if (VAT_JSON_ARRAY != vam->json_tree.type)
1546     {
1547       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1548       vat_json_init_array (&vam->json_tree);
1549     }
1550   node = vat_json_array_add (&vam->json_tree);
1551
1552   vat_json_init_object (node);
1553   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1554   vat_json_object_add_uint (node, "flood", mp->flood);
1555   vat_json_object_add_uint (node, "forward", mp->forward);
1556   vat_json_object_add_uint (node, "learn", mp->learn);
1557   vat_json_object_add_uint (node, "bvi_sw_if_index",
1558                             ntohl (mp->bvi_sw_if_index));
1559   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1560   array = vat_json_object_add (node, "sw_if");
1561   vat_json_init_array (array);
1562
1563
1564
1565   if (n_sw_ifs)
1566     {
1567       vl_api_bridge_domain_sw_if_t *sw_ifs;
1568       int i;
1569
1570       sw_ifs = mp->sw_if_details;
1571       for (i = 0; i < n_sw_ifs; i++)
1572         {
1573           node = vat_json_array_add (array);
1574           vat_json_init_object (node);
1575           vat_json_object_add_uint (node, "sw_if_index",
1576                                     ntohl (sw_ifs->sw_if_index));
1577           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1578           sw_ifs++;
1579         }
1580     }
1581 }
1582
1583 static void vl_api_control_ping_reply_t_handler
1584   (vl_api_control_ping_reply_t * mp)
1585 {
1586   vat_main_t *vam = &vat_main;
1587   i32 retval = ntohl (mp->retval);
1588   if (vam->async_mode)
1589     {
1590       vam->async_errors += (retval < 0);
1591     }
1592   else
1593     {
1594       vam->retval = retval;
1595       vam->result_ready = 1;
1596     }
1597   if (vam->socket_client_main)
1598     vam->socket_client_main->control_pings_outstanding--;
1599 }
1600
1601 static void vl_api_control_ping_reply_t_handler_json
1602   (vl_api_control_ping_reply_t * mp)
1603 {
1604   vat_main_t *vam = &vat_main;
1605   i32 retval = ntohl (mp->retval);
1606
1607   if (VAT_JSON_NONE != vam->json_tree.type)
1608     {
1609       vat_json_print (vam->ofp, &vam->json_tree);
1610       vat_json_free (&vam->json_tree);
1611       vam->json_tree.type = VAT_JSON_NONE;
1612     }
1613   else
1614     {
1615       /* just print [] */
1616       vat_json_init_array (&vam->json_tree);
1617       vat_json_print (vam->ofp, &vam->json_tree);
1618       vam->json_tree.type = VAT_JSON_NONE;
1619     }
1620
1621   vam->retval = retval;
1622   vam->result_ready = 1;
1623 }
1624
1625 static void
1626   vl_api_bridge_domain_set_mac_age_reply_t_handler
1627   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1628 {
1629   vat_main_t *vam = &vat_main;
1630   i32 retval = ntohl (mp->retval);
1631   if (vam->async_mode)
1632     {
1633       vam->async_errors += (retval < 0);
1634     }
1635   else
1636     {
1637       vam->retval = retval;
1638       vam->result_ready = 1;
1639     }
1640 }
1641
1642 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1643   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1644 {
1645   vat_main_t *vam = &vat_main;
1646   vat_json_node_t node;
1647
1648   vat_json_init_object (&node);
1649   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1650
1651   vat_json_print (vam->ofp, &node);
1652   vat_json_free (&node);
1653
1654   vam->retval = ntohl (mp->retval);
1655   vam->result_ready = 1;
1656 }
1657
1658 static void
1659 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1660 {
1661   vat_main_t *vam = &vat_main;
1662   i32 retval = ntohl (mp->retval);
1663   if (vam->async_mode)
1664     {
1665       vam->async_errors += (retval < 0);
1666     }
1667   else
1668     {
1669       vam->retval = retval;
1670       vam->result_ready = 1;
1671     }
1672 }
1673
1674 static void vl_api_l2_flags_reply_t_handler_json
1675   (vl_api_l2_flags_reply_t * mp)
1676 {
1677   vat_main_t *vam = &vat_main;
1678   vat_json_node_t node;
1679
1680   vat_json_init_object (&node);
1681   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1682   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1683                             ntohl (mp->resulting_feature_bitmap));
1684
1685   vat_json_print (vam->ofp, &node);
1686   vat_json_free (&node);
1687
1688   vam->retval = ntohl (mp->retval);
1689   vam->result_ready = 1;
1690 }
1691
1692 static void vl_api_bridge_flags_reply_t_handler
1693   (vl_api_bridge_flags_reply_t * mp)
1694 {
1695   vat_main_t *vam = &vat_main;
1696   i32 retval = ntohl (mp->retval);
1697   if (vam->async_mode)
1698     {
1699       vam->async_errors += (retval < 0);
1700     }
1701   else
1702     {
1703       vam->retval = retval;
1704       vam->result_ready = 1;
1705     }
1706 }
1707
1708 static void vl_api_bridge_flags_reply_t_handler_json
1709   (vl_api_bridge_flags_reply_t * mp)
1710 {
1711   vat_main_t *vam = &vat_main;
1712   vat_json_node_t node;
1713
1714   vat_json_init_object (&node);
1715   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1716   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1717                             ntohl (mp->resulting_feature_bitmap));
1718
1719   vat_json_print (vam->ofp, &node);
1720   vat_json_free (&node);
1721
1722   vam->retval = ntohl (mp->retval);
1723   vam->result_ready = 1;
1724 }
1725
1726 static void
1727 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1728 {
1729   vat_main_t *vam = &vat_main;
1730   i32 retval = ntohl (mp->retval);
1731   if (vam->async_mode)
1732     {
1733       vam->async_errors += (retval < 0);
1734     }
1735   else
1736     {
1737       vam->retval = retval;
1738       vam->sw_if_index = ntohl (mp->sw_if_index);
1739       vam->result_ready = 1;
1740     }
1741
1742 }
1743
1744 static void vl_api_tap_create_v2_reply_t_handler_json
1745   (vl_api_tap_create_v2_reply_t * mp)
1746 {
1747   vat_main_t *vam = &vat_main;
1748   vat_json_node_t node;
1749
1750   vat_json_init_object (&node);
1751   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1752   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1753
1754   vat_json_print (vam->ofp, &node);
1755   vat_json_free (&node);
1756
1757   vam->retval = ntohl (mp->retval);
1758   vam->result_ready = 1;
1759
1760 }
1761
1762 static void
1763 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1764 {
1765   vat_main_t *vam = &vat_main;
1766   i32 retval = ntohl (mp->retval);
1767   if (vam->async_mode)
1768     {
1769       vam->async_errors += (retval < 0);
1770     }
1771   else
1772     {
1773       vam->retval = retval;
1774       vam->result_ready = 1;
1775     }
1776 }
1777
1778 static void vl_api_tap_delete_v2_reply_t_handler_json
1779   (vl_api_tap_delete_v2_reply_t * mp)
1780 {
1781   vat_main_t *vam = &vat_main;
1782   vat_json_node_t node;
1783
1784   vat_json_init_object (&node);
1785   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1786
1787   vat_json_print (vam->ofp, &node);
1788   vat_json_free (&node);
1789
1790   vam->retval = ntohl (mp->retval);
1791   vam->result_ready = 1;
1792 }
1793
1794 static void
1795 vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1796                                           mp)
1797 {
1798   vat_main_t *vam = &vat_main;
1799   i32 retval = ntohl (mp->retval);
1800   if (vam->async_mode)
1801     {
1802       vam->async_errors += (retval < 0);
1803     }
1804   else
1805     {
1806       vam->retval = retval;
1807       vam->sw_if_index = ntohl (mp->sw_if_index);
1808       vam->result_ready = 1;
1809     }
1810 }
1811
1812 static void vl_api_virtio_pci_create_reply_t_handler_json
1813   (vl_api_virtio_pci_create_reply_t * mp)
1814 {
1815   vat_main_t *vam = &vat_main;
1816   vat_json_node_t node;
1817
1818   vat_json_init_object (&node);
1819   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1820   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1821
1822   vat_json_print (vam->ofp, &node);
1823   vat_json_free (&node);
1824
1825   vam->retval = ntohl (mp->retval);
1826   vam->result_ready = 1;
1827
1828 }
1829
1830 static void
1831   vl_api_virtio_pci_create_v2_reply_t_handler
1832   (vl_api_virtio_pci_create_v2_reply_t * mp)
1833 {
1834   vat_main_t *vam = &vat_main;
1835   i32 retval = ntohl (mp->retval);
1836   if (vam->async_mode)
1837     {
1838       vam->async_errors += (retval < 0);
1839     }
1840   else
1841     {
1842       vam->retval = retval;
1843       vam->sw_if_index = ntohl (mp->sw_if_index);
1844       vam->result_ready = 1;
1845     }
1846 }
1847
1848 static void vl_api_virtio_pci_create_v2_reply_t_handler_json
1849   (vl_api_virtio_pci_create_v2_reply_t * mp)
1850 {
1851   vat_main_t *vam = &vat_main;
1852   vat_json_node_t node;
1853
1854   vat_json_init_object (&node);
1855   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1856   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1857
1858   vat_json_print (vam->ofp, &node);
1859   vat_json_free (&node);
1860
1861   vam->retval = ntohl (mp->retval);
1862   vam->result_ready = 1;
1863 }
1864
1865 static void
1866 vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1867                                           mp)
1868 {
1869   vat_main_t *vam = &vat_main;
1870   i32 retval = ntohl (mp->retval);
1871   if (vam->async_mode)
1872     {
1873       vam->async_errors += (retval < 0);
1874     }
1875   else
1876     {
1877       vam->retval = retval;
1878       vam->result_ready = 1;
1879     }
1880 }
1881
1882 static void vl_api_virtio_pci_delete_reply_t_handler_json
1883   (vl_api_virtio_pci_delete_reply_t * mp)
1884 {
1885   vat_main_t *vam = &vat_main;
1886   vat_json_node_t node;
1887
1888   vat_json_init_object (&node);
1889   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1890
1891   vat_json_print (vam->ofp, &node);
1892   vat_json_free (&node);
1893
1894   vam->retval = ntohl (mp->retval);
1895   vam->result_ready = 1;
1896 }
1897
1898 static void
1899 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1900 {
1901   vat_main_t *vam = &vat_main;
1902   i32 retval = ntohl (mp->retval);
1903
1904   if (vam->async_mode)
1905     {
1906       vam->async_errors += (retval < 0);
1907     }
1908   else
1909     {
1910       vam->retval = retval;
1911       vam->sw_if_index = ntohl (mp->sw_if_index);
1912       vam->result_ready = 1;
1913     }
1914 }
1915
1916 static void vl_api_bond_create_reply_t_handler_json
1917   (vl_api_bond_create_reply_t * mp)
1918 {
1919   vat_main_t *vam = &vat_main;
1920   vat_json_node_t node;
1921
1922   vat_json_init_object (&node);
1923   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1924   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1925
1926   vat_json_print (vam->ofp, &node);
1927   vat_json_free (&node);
1928
1929   vam->retval = ntohl (mp->retval);
1930   vam->result_ready = 1;
1931 }
1932
1933 static void
1934 vl_api_bond_create2_reply_t_handler (vl_api_bond_create2_reply_t * mp)
1935 {
1936   vat_main_t *vam = &vat_main;
1937   i32 retval = ntohl (mp->retval);
1938
1939   if (vam->async_mode)
1940     {
1941       vam->async_errors += (retval < 0);
1942     }
1943   else
1944     {
1945       vam->retval = retval;
1946       vam->sw_if_index = ntohl (mp->sw_if_index);
1947       vam->result_ready = 1;
1948     }
1949 }
1950
1951 static void vl_api_bond_create2_reply_t_handler_json
1952   (vl_api_bond_create2_reply_t * mp)
1953 {
1954   vat_main_t *vam = &vat_main;
1955   vat_json_node_t node;
1956
1957   vat_json_init_object (&node);
1958   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1959   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1960
1961   vat_json_print (vam->ofp, &node);
1962   vat_json_free (&node);
1963
1964   vam->retval = ntohl (mp->retval);
1965   vam->result_ready = 1;
1966 }
1967
1968 static void
1969 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1970 {
1971   vat_main_t *vam = &vat_main;
1972   i32 retval = ntohl (mp->retval);
1973
1974   if (vam->async_mode)
1975     {
1976       vam->async_errors += (retval < 0);
1977     }
1978   else
1979     {
1980       vam->retval = retval;
1981       vam->result_ready = 1;
1982     }
1983 }
1984
1985 static void vl_api_bond_delete_reply_t_handler_json
1986   (vl_api_bond_delete_reply_t * mp)
1987 {
1988   vat_main_t *vam = &vat_main;
1989   vat_json_node_t node;
1990
1991   vat_json_init_object (&node);
1992   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1993
1994   vat_json_print (vam->ofp, &node);
1995   vat_json_free (&node);
1996
1997   vam->retval = ntohl (mp->retval);
1998   vam->result_ready = 1;
1999 }
2000
2001 static void
2002 vl_api_bond_add_member_reply_t_handler (vl_api_bond_add_member_reply_t * mp)
2003 {
2004   vat_main_t *vam = &vat_main;
2005   i32 retval = ntohl (mp->retval);
2006
2007   if (vam->async_mode)
2008     {
2009       vam->async_errors += (retval < 0);
2010     }
2011   else
2012     {
2013       vam->retval = retval;
2014       vam->result_ready = 1;
2015     }
2016 }
2017
2018 static void vl_api_bond_add_member_reply_t_handler_json
2019   (vl_api_bond_add_member_reply_t * mp)
2020 {
2021   vat_main_t *vam = &vat_main;
2022   vat_json_node_t node;
2023
2024   vat_json_init_object (&node);
2025   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2026
2027   vat_json_print (vam->ofp, &node);
2028   vat_json_free (&node);
2029
2030   vam->retval = ntohl (mp->retval);
2031   vam->result_ready = 1;
2032 }
2033
2034 static void
2035 vl_api_bond_detach_member_reply_t_handler (vl_api_bond_detach_member_reply_t *
2036                                            mp)
2037 {
2038   vat_main_t *vam = &vat_main;
2039   i32 retval = ntohl (mp->retval);
2040
2041   if (vam->async_mode)
2042     {
2043       vam->async_errors += (retval < 0);
2044     }
2045   else
2046     {
2047       vam->retval = retval;
2048       vam->result_ready = 1;
2049     }
2050 }
2051
2052 static void vl_api_bond_detach_member_reply_t_handler_json
2053   (vl_api_bond_detach_member_reply_t * mp)
2054 {
2055   vat_main_t *vam = &vat_main;
2056   vat_json_node_t node;
2057
2058   vat_json_init_object (&node);
2059   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2060
2061   vat_json_print (vam->ofp, &node);
2062   vat_json_free (&node);
2063
2064   vam->retval = ntohl (mp->retval);
2065   vam->result_ready = 1;
2066 }
2067
2068 static int
2069 api_sw_interface_set_bond_weight (vat_main_t * vam)
2070 {
2071   unformat_input_t *i = vam->input;
2072   vl_api_sw_interface_set_bond_weight_t *mp;
2073   u32 sw_if_index = ~0;
2074   u32 weight = 0;
2075   u8 weight_enter = 0;
2076   int ret;
2077
2078   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2079     {
2080       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2081         ;
2082       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2083         ;
2084       else if (unformat (i, "weight %u", &weight))
2085         weight_enter = 1;
2086       else
2087         break;
2088     }
2089
2090   if (sw_if_index == ~0)
2091     {
2092       errmsg ("missing interface name or sw_if_index");
2093       return -99;
2094     }
2095   if (weight_enter == 0)
2096     {
2097       errmsg ("missing valid weight");
2098       return -99;
2099     }
2100
2101   /* Construct the API message */
2102   M (SW_INTERFACE_SET_BOND_WEIGHT, mp);
2103   mp->sw_if_index = ntohl (sw_if_index);
2104   mp->weight = ntohl (weight);
2105
2106   S (mp);
2107   W (ret);
2108   return ret;
2109 }
2110
2111 static void vl_api_sw_bond_interface_details_t_handler
2112   (vl_api_sw_bond_interface_details_t * mp)
2113 {
2114   vat_main_t *vam = &vat_main;
2115
2116   print (vam->ofp,
2117          "%-16s %-12d %-12U %-13U %-14u %-14u",
2118          mp->interface_name, ntohl (mp->sw_if_index),
2119          format_bond_mode, ntohl (mp->mode), format_bond_load_balance,
2120          ntohl (mp->lb), ntohl (mp->active_members), ntohl (mp->members));
2121 }
2122
2123 static void vl_api_sw_bond_interface_details_t_handler_json
2124   (vl_api_sw_bond_interface_details_t * mp)
2125 {
2126   vat_main_t *vam = &vat_main;
2127   vat_json_node_t *node = NULL;
2128
2129   if (VAT_JSON_ARRAY != vam->json_tree.type)
2130     {
2131       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2132       vat_json_init_array (&vam->json_tree);
2133     }
2134   node = vat_json_array_add (&vam->json_tree);
2135
2136   vat_json_init_object (node);
2137   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2138   vat_json_object_add_string_copy (node, "interface_name",
2139                                    mp->interface_name);
2140   vat_json_object_add_uint (node, "mode", ntohl (mp->mode));
2141   vat_json_object_add_uint (node, "load_balance", ntohl (mp->lb));
2142   vat_json_object_add_uint (node, "active_members",
2143                             ntohl (mp->active_members));
2144   vat_json_object_add_uint (node, "members", ntohl (mp->members));
2145 }
2146
2147 static int
2148 api_sw_bond_interface_dump (vat_main_t * vam)
2149 {
2150   unformat_input_t *i = vam->input;
2151   vl_api_sw_bond_interface_dump_t *mp;
2152   vl_api_control_ping_t *mp_ping;
2153   int ret;
2154   u32 sw_if_index = ~0;
2155
2156   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2157     {
2158       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2159         ;
2160       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2161         ;
2162       else
2163         break;
2164     }
2165
2166   print (vam->ofp,
2167          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2168          "interface name", "sw_if_index", "mode", "load balance",
2169          "active members", "members");
2170
2171   /* Get list of bond interfaces */
2172   M (SW_BOND_INTERFACE_DUMP, mp);
2173   mp->sw_if_index = ntohl (sw_if_index);
2174   S (mp);
2175
2176   /* Use a control ping for synchronization */
2177   MPING (CONTROL_PING, mp_ping);
2178   S (mp_ping);
2179
2180   W (ret);
2181   return ret;
2182 }
2183
2184 static void vl_api_sw_member_interface_details_t_handler
2185   (vl_api_sw_member_interface_details_t * mp)
2186 {
2187   vat_main_t *vam = &vat_main;
2188
2189   print (vam->ofp,
2190          "%-25s %-12d %-7d %-12d %-10d %-10d", mp->interface_name,
2191          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout,
2192          ntohl (mp->weight), mp->is_local_numa);
2193 }
2194
2195 static void vl_api_sw_member_interface_details_t_handler_json
2196   (vl_api_sw_member_interface_details_t * mp)
2197 {
2198   vat_main_t *vam = &vat_main;
2199   vat_json_node_t *node = NULL;
2200
2201   if (VAT_JSON_ARRAY != vam->json_tree.type)
2202     {
2203       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2204       vat_json_init_array (&vam->json_tree);
2205     }
2206   node = vat_json_array_add (&vam->json_tree);
2207
2208   vat_json_init_object (node);
2209   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2210   vat_json_object_add_string_copy (node, "interface_name",
2211                                    mp->interface_name);
2212   vat_json_object_add_uint (node, "passive", mp->is_passive);
2213   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2214   vat_json_object_add_uint (node, "weight", ntohl (mp->weight));
2215   vat_json_object_add_uint (node, "is_local_numa", mp->is_local_numa);
2216 }
2217
2218 static int
2219 api_sw_member_interface_dump (vat_main_t * vam)
2220 {
2221   unformat_input_t *i = vam->input;
2222   vl_api_sw_member_interface_dump_t *mp;
2223   vl_api_control_ping_t *mp_ping;
2224   u32 sw_if_index = ~0;
2225   u8 sw_if_index_set = 0;
2226   int ret;
2227
2228   /* Parse args required to build the message */
2229   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2230     {
2231       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2232         sw_if_index_set = 1;
2233       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2234         sw_if_index_set = 1;
2235       else
2236         break;
2237     }
2238
2239   if (sw_if_index_set == 0)
2240     {
2241       errmsg ("missing vpp interface name. ");
2242       return -99;
2243     }
2244
2245   print (vam->ofp,
2246          "\n%-25s %-12s %-7s %-12s %-10s %-10s",
2247          "member interface name", "sw_if_index", "passive", "long_timeout",
2248          "weight", "local numa");
2249
2250   /* Get list of bond interfaces */
2251   M (SW_MEMBER_INTERFACE_DUMP, mp);
2252   mp->sw_if_index = ntohl (sw_if_index);
2253   S (mp);
2254
2255   /* Use a control ping for synchronization */
2256   MPING (CONTROL_PING, mp_ping);
2257   S (mp_ping);
2258
2259   W (ret);
2260   return ret;
2261 }
2262
2263 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2264   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2265 {
2266   vat_main_t *vam = &vat_main;
2267   i32 retval = ntohl (mp->retval);
2268   if (vam->async_mode)
2269     {
2270       vam->async_errors += (retval < 0);
2271     }
2272   else
2273     {
2274       vam->retval = retval;
2275       vam->sw_if_index = ntohl (mp->sw_if_index);
2276       vam->result_ready = 1;
2277     }
2278   vam->regenerate_interface_table = 1;
2279 }
2280
2281 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2282   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2283 {
2284   vat_main_t *vam = &vat_main;
2285   vat_json_node_t node;
2286
2287   vat_json_init_object (&node);
2288   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2289   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2290                             ntohl (mp->sw_if_index));
2291
2292   vat_json_print (vam->ofp, &node);
2293   vat_json_free (&node);
2294
2295   vam->retval = ntohl (mp->retval);
2296   vam->result_ready = 1;
2297 }
2298
2299 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2300   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2301 {
2302   vat_main_t *vam = &vat_main;
2303   i32 retval = ntohl (mp->retval);
2304   if (vam->async_mode)
2305     {
2306       vam->async_errors += (retval < 0);
2307     }
2308   else
2309     {
2310       vam->retval = retval;
2311       vam->sw_if_index = ntohl (mp->sw_if_index);
2312       vam->result_ready = 1;
2313     }
2314 }
2315
2316 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2317   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2318 {
2319   vat_main_t *vam = &vat_main;
2320   vat_json_node_t node;
2321
2322   vat_json_init_object (&node);
2323   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2324   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2325
2326   vat_json_print (vam->ofp, &node);
2327   vat_json_free (&node);
2328
2329   vam->retval = ntohl (mp->retval);
2330   vam->result_ready = 1;
2331 }
2332
2333 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2334   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2335 {
2336   vat_main_t *vam = &vat_main;
2337   i32 retval = ntohl (mp->retval);
2338   if (vam->async_mode)
2339     {
2340       vam->async_errors += (retval < 0);
2341     }
2342   else
2343     {
2344       vam->retval = retval;
2345       vam->result_ready = 1;
2346     }
2347 }
2348
2349 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2350   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2351 {
2352   vat_main_t *vam = &vat_main;
2353   vat_json_node_t node;
2354
2355   vat_json_init_object (&node);
2356   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2357   vat_json_object_add_uint (&node, "fwd_entry_index",
2358                             clib_net_to_host_u32 (mp->fwd_entry_index));
2359
2360   vat_json_print (vam->ofp, &node);
2361   vat_json_free (&node);
2362
2363   vam->retval = ntohl (mp->retval);
2364   vam->result_ready = 1;
2365 }
2366
2367 u8 *
2368 format_lisp_transport_protocol (u8 * s, va_list * args)
2369 {
2370   u32 proto = va_arg (*args, u32);
2371
2372   switch (proto)
2373     {
2374     case 1:
2375       return format (s, "udp");
2376     case 2:
2377       return format (s, "api");
2378     default:
2379       return 0;
2380     }
2381   return 0;
2382 }
2383
2384 static void vl_api_one_get_transport_protocol_reply_t_handler
2385   (vl_api_one_get_transport_protocol_reply_t * mp)
2386 {
2387   vat_main_t *vam = &vat_main;
2388   i32 retval = ntohl (mp->retval);
2389   if (vam->async_mode)
2390     {
2391       vam->async_errors += (retval < 0);
2392     }
2393   else
2394     {
2395       u32 proto = mp->protocol;
2396       print (vam->ofp, "Transport protocol: %U",
2397              format_lisp_transport_protocol, proto);
2398       vam->retval = retval;
2399       vam->result_ready = 1;
2400     }
2401 }
2402
2403 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2404   (vl_api_one_get_transport_protocol_reply_t * mp)
2405 {
2406   vat_main_t *vam = &vat_main;
2407   vat_json_node_t node;
2408   u8 *s;
2409
2410   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2411   vec_add1 (s, 0);
2412
2413   vat_json_init_object (&node);
2414   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2415   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2416
2417   vec_free (s);
2418   vat_json_print (vam->ofp, &node);
2419   vat_json_free (&node);
2420
2421   vam->retval = ntohl (mp->retval);
2422   vam->result_ready = 1;
2423 }
2424
2425 static void vl_api_one_add_del_locator_set_reply_t_handler
2426   (vl_api_one_add_del_locator_set_reply_t * mp)
2427 {
2428   vat_main_t *vam = &vat_main;
2429   i32 retval = ntohl (mp->retval);
2430   if (vam->async_mode)
2431     {
2432       vam->async_errors += (retval < 0);
2433     }
2434   else
2435     {
2436       vam->retval = retval;
2437       vam->result_ready = 1;
2438     }
2439 }
2440
2441 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2442   (vl_api_one_add_del_locator_set_reply_t * mp)
2443 {
2444   vat_main_t *vam = &vat_main;
2445   vat_json_node_t node;
2446
2447   vat_json_init_object (&node);
2448   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2449   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2450
2451   vat_json_print (vam->ofp, &node);
2452   vat_json_free (&node);
2453
2454   vam->retval = ntohl (mp->retval);
2455   vam->result_ready = 1;
2456 }
2457
2458 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2459   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2460 {
2461   vat_main_t *vam = &vat_main;
2462   i32 retval = ntohl (mp->retval);
2463   if (vam->async_mode)
2464     {
2465       vam->async_errors += (retval < 0);
2466     }
2467   else
2468     {
2469       vam->retval = retval;
2470       vam->sw_if_index = ntohl (mp->sw_if_index);
2471       vam->result_ready = 1;
2472     }
2473   vam->regenerate_interface_table = 1;
2474 }
2475
2476 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2477   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2478 {
2479   vat_main_t *vam = &vat_main;
2480   vat_json_node_t node;
2481
2482   vat_json_init_object (&node);
2483   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2484   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2485
2486   vat_json_print (vam->ofp, &node);
2487   vat_json_free (&node);
2488
2489   vam->retval = ntohl (mp->retval);
2490   vam->result_ready = 1;
2491 }
2492
2493 static void vl_api_vxlan_offload_rx_reply_t_handler
2494   (vl_api_vxlan_offload_rx_reply_t * mp)
2495 {
2496   vat_main_t *vam = &vat_main;
2497   i32 retval = ntohl (mp->retval);
2498   if (vam->async_mode)
2499     {
2500       vam->async_errors += (retval < 0);
2501     }
2502   else
2503     {
2504       vam->retval = retval;
2505       vam->result_ready = 1;
2506     }
2507 }
2508
2509 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2510   (vl_api_vxlan_offload_rx_reply_t * mp)
2511 {
2512   vat_main_t *vam = &vat_main;
2513   vat_json_node_t node;
2514
2515   vat_json_init_object (&node);
2516   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2517
2518   vat_json_print (vam->ofp, &node);
2519   vat_json_free (&node);
2520
2521   vam->retval = ntohl (mp->retval);
2522   vam->result_ready = 1;
2523 }
2524
2525 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2526   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2527 {
2528   vat_main_t *vam = &vat_main;
2529   i32 retval = ntohl (mp->retval);
2530   if (vam->async_mode)
2531     {
2532       vam->async_errors += (retval < 0);
2533     }
2534   else
2535     {
2536       vam->retval = retval;
2537       vam->sw_if_index = ntohl (mp->sw_if_index);
2538       vam->result_ready = 1;
2539     }
2540   vam->regenerate_interface_table = 1;
2541 }
2542
2543 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2544   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2545 {
2546   vat_main_t *vam = &vat_main;
2547   vat_json_node_t node;
2548
2549   vat_json_init_object (&node);
2550   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2551   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2552
2553   vat_json_print (vam->ofp, &node);
2554   vat_json_free (&node);
2555
2556   vam->retval = ntohl (mp->retval);
2557   vam->result_ready = 1;
2558 }
2559
2560 static void vl_api_gre_tunnel_add_del_reply_t_handler
2561   (vl_api_gre_tunnel_add_del_reply_t * mp)
2562 {
2563   vat_main_t *vam = &vat_main;
2564   i32 retval = ntohl (mp->retval);
2565   if (vam->async_mode)
2566     {
2567       vam->async_errors += (retval < 0);
2568     }
2569   else
2570     {
2571       vam->retval = retval;
2572       vam->sw_if_index = ntohl (mp->sw_if_index);
2573       vam->result_ready = 1;
2574     }
2575 }
2576
2577 static void vl_api_gre_tunnel_add_del_reply_t_handler_json
2578   (vl_api_gre_tunnel_add_del_reply_t * mp)
2579 {
2580   vat_main_t *vam = &vat_main;
2581   vat_json_node_t node;
2582
2583   vat_json_init_object (&node);
2584   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2585   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2586
2587   vat_json_print (vam->ofp, &node);
2588   vat_json_free (&node);
2589
2590   vam->retval = ntohl (mp->retval);
2591   vam->result_ready = 1;
2592 }
2593
2594 static void vl_api_create_vhost_user_if_reply_t_handler
2595   (vl_api_create_vhost_user_if_reply_t * mp)
2596 {
2597   vat_main_t *vam = &vat_main;
2598   i32 retval = ntohl (mp->retval);
2599   if (vam->async_mode)
2600     {
2601       vam->async_errors += (retval < 0);
2602     }
2603   else
2604     {
2605       vam->retval = retval;
2606       vam->sw_if_index = ntohl (mp->sw_if_index);
2607       vam->result_ready = 1;
2608     }
2609   vam->regenerate_interface_table = 1;
2610 }
2611
2612 static void vl_api_create_vhost_user_if_reply_t_handler_json
2613   (vl_api_create_vhost_user_if_reply_t * mp)
2614 {
2615   vat_main_t *vam = &vat_main;
2616   vat_json_node_t node;
2617
2618   vat_json_init_object (&node);
2619   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2620   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2621
2622   vat_json_print (vam->ofp, &node);
2623   vat_json_free (&node);
2624
2625   vam->retval = ntohl (mp->retval);
2626   vam->result_ready = 1;
2627 }
2628
2629 static void vl_api_ip_address_details_t_handler
2630   (vl_api_ip_address_details_t * mp)
2631 {
2632   vat_main_t *vam = &vat_main;
2633   static ip_address_details_t empty_ip_address_details = { {0} };
2634   ip_address_details_t *address = NULL;
2635   ip_details_t *current_ip_details = NULL;
2636   ip_details_t *details = NULL;
2637
2638   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2639
2640   if (!details || vam->current_sw_if_index >= vec_len (details)
2641       || !details[vam->current_sw_if_index].present)
2642     {
2643       errmsg ("ip address details arrived but not stored");
2644       errmsg ("ip_dump should be called first");
2645       return;
2646     }
2647
2648   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2649
2650 #define addresses (current_ip_details->addr)
2651
2652   vec_validate_init_empty (addresses, vec_len (addresses),
2653                            empty_ip_address_details);
2654
2655   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2656
2657   clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
2658   address->prefix_length = mp->prefix.len;
2659 #undef addresses
2660 }
2661
2662 static void vl_api_ip_address_details_t_handler_json
2663   (vl_api_ip_address_details_t * mp)
2664 {
2665   vat_main_t *vam = &vat_main;
2666   vat_json_node_t *node = NULL;
2667
2668   if (VAT_JSON_ARRAY != vam->json_tree.type)
2669     {
2670       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2671       vat_json_init_array (&vam->json_tree);
2672     }
2673   node = vat_json_array_add (&vam->json_tree);
2674
2675   vat_json_init_object (node);
2676   vat_json_object_add_prefix (node, &mp->prefix);
2677 }
2678
2679 static void
2680 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2681 {
2682   vat_main_t *vam = &vat_main;
2683   static ip_details_t empty_ip_details = { 0 };
2684   ip_details_t *ip = NULL;
2685   u32 sw_if_index = ~0;
2686
2687   sw_if_index = ntohl (mp->sw_if_index);
2688
2689   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2690                            sw_if_index, empty_ip_details);
2691
2692   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2693                          sw_if_index);
2694
2695   ip->present = 1;
2696 }
2697
2698 static void
2699 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2700 {
2701   vat_main_t *vam = &vat_main;
2702
2703   if (VAT_JSON_ARRAY != vam->json_tree.type)
2704     {
2705       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2706       vat_json_init_array (&vam->json_tree);
2707     }
2708   vat_json_array_add_uint (&vam->json_tree,
2709                            clib_net_to_host_u32 (mp->sw_if_index));
2710 }
2711
2712 static void vl_api_get_first_msg_id_reply_t_handler
2713   (vl_api_get_first_msg_id_reply_t * mp)
2714 {
2715   vat_main_t *vam = &vat_main;
2716   i32 retval = ntohl (mp->retval);
2717
2718   if (vam->async_mode)
2719     {
2720       vam->async_errors += (retval < 0);
2721     }
2722   else
2723     {
2724       vam->retval = retval;
2725       vam->result_ready = 1;
2726     }
2727   if (retval >= 0)
2728     {
2729       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2730     }
2731 }
2732
2733 static void vl_api_get_first_msg_id_reply_t_handler_json
2734   (vl_api_get_first_msg_id_reply_t * mp)
2735 {
2736   vat_main_t *vam = &vat_main;
2737   vat_json_node_t node;
2738
2739   vat_json_init_object (&node);
2740   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2741   vat_json_object_add_uint (&node, "first_msg_id",
2742                             (uint) ntohs (mp->first_msg_id));
2743
2744   vat_json_print (vam->ofp, &node);
2745   vat_json_free (&node);
2746
2747   vam->retval = ntohl (mp->retval);
2748   vam->result_ready = 1;
2749 }
2750
2751 static void vl_api_get_node_graph_reply_t_handler
2752   (vl_api_get_node_graph_reply_t * mp)
2753 {
2754   vat_main_t *vam = &vat_main;
2755   i32 retval = ntohl (mp->retval);
2756   u8 *pvt_copy, *reply;
2757   void *oldheap;
2758   vlib_node_t *node;
2759   int i;
2760
2761   if (vam->async_mode)
2762     {
2763       vam->async_errors += (retval < 0);
2764     }
2765   else
2766     {
2767       vam->retval = retval;
2768       vam->result_ready = 1;
2769     }
2770
2771   /* "Should never happen..." */
2772   if (retval != 0)
2773     return;
2774
2775   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2776   pvt_copy = vec_dup (reply);
2777
2778   /* Toss the shared-memory original... */
2779   oldheap = vl_msg_push_heap ();
2780
2781   vec_free (reply);
2782
2783   vl_msg_pop_heap (oldheap);
2784
2785   if (vam->graph_nodes)
2786     {
2787       hash_free (vam->graph_node_index_by_name);
2788
2789       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2790         {
2791           node = vam->graph_nodes[0][i];
2792           vec_free (node->name);
2793           vec_free (node->next_nodes);
2794           vec_free (node);
2795         }
2796       vec_free (vam->graph_nodes[0]);
2797       vec_free (vam->graph_nodes);
2798     }
2799
2800   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2801   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2802   vec_free (pvt_copy);
2803
2804   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2805     {
2806       node = vam->graph_nodes[0][i];
2807       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2808     }
2809 }
2810
2811 static void vl_api_get_node_graph_reply_t_handler_json
2812   (vl_api_get_node_graph_reply_t * mp)
2813 {
2814   vat_main_t *vam = &vat_main;
2815   void *oldheap;
2816   vat_json_node_t node;
2817   u8 *reply;
2818
2819   /* $$$$ make this real? */
2820   vat_json_init_object (&node);
2821   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2822   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2823
2824   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2825
2826   /* Toss the shared-memory original... */
2827   oldheap = vl_msg_push_heap ();
2828
2829   vec_free (reply);
2830
2831   vl_msg_pop_heap (oldheap);
2832
2833   vat_json_print (vam->ofp, &node);
2834   vat_json_free (&node);
2835
2836   vam->retval = ntohl (mp->retval);
2837   vam->result_ready = 1;
2838 }
2839
2840 static void
2841 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2842 {
2843   vat_main_t *vam = &vat_main;
2844   u8 *s = 0;
2845
2846   if (mp->local)
2847     {
2848       s = format (s, "%=16d%=16d%=16d",
2849                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2850     }
2851   else
2852     {
2853       s = format (s, "%=16U%=16d%=16d",
2854                   format_ip46_address,
2855                   mp->ip_address, mp->priority, mp->weight);
2856     }
2857
2858   print (vam->ofp, "%v", s);
2859   vec_free (s);
2860 }
2861
2862 static void
2863 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2864 {
2865   vat_main_t *vam = &vat_main;
2866   vat_json_node_t *node = NULL;
2867   struct in6_addr ip6;
2868   struct in_addr ip4;
2869
2870   if (VAT_JSON_ARRAY != vam->json_tree.type)
2871     {
2872       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2873       vat_json_init_array (&vam->json_tree);
2874     }
2875   node = vat_json_array_add (&vam->json_tree);
2876   vat_json_init_object (node);
2877
2878   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2879   vat_json_object_add_uint (node, "priority", mp->priority);
2880   vat_json_object_add_uint (node, "weight", mp->weight);
2881
2882   if (mp->local)
2883     vat_json_object_add_uint (node, "sw_if_index",
2884                               clib_net_to_host_u32 (mp->sw_if_index));
2885   else
2886     {
2887       if (mp->ip_address.af)
2888         {
2889           clib_memcpy (&ip6, mp->ip_address.un.ip6, sizeof (ip6));
2890           vat_json_object_add_ip6 (node, "address", ip6);
2891         }
2892       else
2893         {
2894           clib_memcpy (&ip4, mp->ip_address.un.ip4, sizeof (ip4));
2895           vat_json_object_add_ip4 (node, "address", ip4);
2896         }
2897     }
2898 }
2899
2900 static void
2901 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2902                                           mp)
2903 {
2904   vat_main_t *vam = &vat_main;
2905   u8 *ls_name = 0;
2906
2907   ls_name = format (0, "%s", mp->ls_name);
2908
2909   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2910          ls_name);
2911   vec_free (ls_name);
2912 }
2913
2914 static void
2915   vl_api_one_locator_set_details_t_handler_json
2916   (vl_api_one_locator_set_details_t * mp)
2917 {
2918   vat_main_t *vam = &vat_main;
2919   vat_json_node_t *node = 0;
2920   u8 *ls_name = 0;
2921
2922   ls_name = format (0, "%s", mp->ls_name);
2923   vec_add1 (ls_name, 0);
2924
2925   if (VAT_JSON_ARRAY != vam->json_tree.type)
2926     {
2927       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2928       vat_json_init_array (&vam->json_tree);
2929     }
2930   node = vat_json_array_add (&vam->json_tree);
2931
2932   vat_json_init_object (node);
2933   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2934   vat_json_object_add_uint (node, "ls_index",
2935                             clib_net_to_host_u32 (mp->ls_index));
2936   vec_free (ls_name);
2937 }
2938
2939 typedef struct
2940 {
2941   u32 spi;
2942   u8 si;
2943 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2944
2945 uword
2946 unformat_nsh_address (unformat_input_t * input, va_list * args)
2947 {
2948   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2949   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2950 }
2951
2952 static u8 *
2953 format_nsh_address_vat (u8 * s, va_list * args)
2954 {
2955   nsh_t *a = va_arg (*args, nsh_t *);
2956   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2957 }
2958
2959 static u8 *
2960 format_lisp_flat_eid (u8 * s, va_list * args)
2961 {
2962   vl_api_eid_t *eid = va_arg (*args, vl_api_eid_t *);
2963
2964   switch (eid->type)
2965     {
2966     case EID_TYPE_API_PREFIX:
2967       if (eid->address.prefix.address.af)
2968         return format (s, "%U/%d", format_ip6_address,
2969                        eid->address.prefix.address.un.ip6,
2970                        eid->address.prefix.len);
2971       return format (s, "%U/%d", format_ip4_address,
2972                      eid->address.prefix.address.un.ip4,
2973                      eid->address.prefix.len);
2974     case EID_TYPE_API_MAC:
2975       return format (s, "%U", format_ethernet_address, eid->address.mac);
2976     case EID_TYPE_API_NSH:
2977       return format (s, "%U", format_nsh_address_vat, eid->address.nsh);
2978     }
2979   return 0;
2980 }
2981
2982 static u8 *
2983 format_lisp_eid_vat (u8 * s, va_list * args)
2984 {
2985   vl_api_eid_t *deid = va_arg (*args, vl_api_eid_t *);
2986   vl_api_eid_t *seid = va_arg (*args, vl_api_eid_t *);
2987   u8 is_src_dst = (u8) va_arg (*args, int);
2988
2989   if (is_src_dst)
2990     s = format (s, "%U|", format_lisp_flat_eid, seid);
2991
2992   s = format (s, "%U", format_lisp_flat_eid, deid);
2993
2994   return s;
2995 }
2996
2997 static void
2998 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2999 {
3000   vat_main_t *vam = &vat_main;
3001   u8 *s = 0, *eid = 0;
3002
3003   if (~0 == mp->locator_set_index)
3004     s = format (0, "action: %d", mp->action);
3005   else
3006     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3007
3008   eid = format (0, "%U", format_lisp_eid_vat,
3009                 &mp->deid, &mp->seid, mp->is_src_dst);
3010   vec_add1 (eid, 0);
3011
3012   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3013          clib_net_to_host_u32 (mp->vni),
3014          eid,
3015          mp->is_local ? "local" : "remote",
3016          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3017          clib_net_to_host_u16 (mp->key.id), mp->key.key);
3018
3019   vec_free (s);
3020   vec_free (eid);
3021 }
3022
3023 static void
3024 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3025                                              * mp)
3026 {
3027   vat_main_t *vam = &vat_main;
3028   vat_json_node_t *node = 0;
3029   u8 *eid = 0;
3030
3031   if (VAT_JSON_ARRAY != vam->json_tree.type)
3032     {
3033       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3034       vat_json_init_array (&vam->json_tree);
3035     }
3036   node = vat_json_array_add (&vam->json_tree);
3037
3038   vat_json_init_object (node);
3039   if (~0 == mp->locator_set_index)
3040     vat_json_object_add_uint (node, "action", mp->action);
3041   else
3042     vat_json_object_add_uint (node, "locator_set_index",
3043                               clib_net_to_host_u32 (mp->locator_set_index));
3044
3045   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3046   if (mp->deid.type == 3)
3047     {
3048       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3049       vat_json_init_object (nsh_json);
3050       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) & mp->deid.address.nsh;
3051       vat_json_object_add_uint (nsh_json, "spi",
3052                                 clib_net_to_host_u32 (nsh->spi));
3053       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3054     }
3055   else
3056     {
3057       eid = format (0, "%U", format_lisp_eid_vat,
3058                     &mp->deid, &mp->seid, mp->is_src_dst);
3059       vec_add1 (eid, 0);
3060       vat_json_object_add_string_copy (node, "eid", eid);
3061       vec_free (eid);
3062     }
3063   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3064   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3065   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3066
3067   if (mp->key.id)
3068     {
3069       vat_json_object_add_uint (node, "key_id",
3070                                 clib_net_to_host_u16 (mp->key.id));
3071       vat_json_object_add_string_copy (node, "key", mp->key.key);
3072     }
3073 }
3074
3075 static void
3076 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3077 {
3078   vat_main_t *vam = &vat_main;
3079   u8 *seid = 0, *deid = 0;
3080   ip46_address_t lloc, rloc;
3081
3082   deid = format (0, "%U", format_lisp_eid_vat, &mp->deid, 0, 0);
3083
3084   seid = format (0, "%U", format_lisp_eid_vat, &mp->seid, 0, 0);
3085
3086   vec_add1 (deid, 0);
3087   vec_add1 (seid, 0);
3088
3089   if (mp->lloc.af)
3090     {
3091       clib_memcpy (&lloc.ip6, mp->lloc.un.ip6, 16);
3092       clib_memcpy (&rloc.ip6, mp->rloc.un.ip6, 16);
3093     }
3094   else
3095     {
3096       clib_memcpy (&lloc.ip4, mp->lloc.un.ip4, 4);
3097       clib_memcpy (&rloc.ip4, mp->rloc.un.ip4, 4);
3098     }
3099
3100
3101   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3102          clib_net_to_host_u32 (mp->vni),
3103          seid, deid,
3104          format_ip46_address, lloc,
3105          format_ip46_address, rloc,
3106          clib_net_to_host_u32 (mp->pkt_count),
3107          clib_net_to_host_u32 (mp->bytes));
3108
3109   vec_free (deid);
3110   vec_free (seid);
3111 }
3112
3113 static void
3114 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3115 {
3116   struct in6_addr ip6;
3117   struct in_addr ip4;
3118   vat_main_t *vam = &vat_main;
3119   vat_json_node_t *node = 0;
3120   u8 *deid = 0, *seid = 0;
3121
3122   if (VAT_JSON_ARRAY != vam->json_tree.type)
3123     {
3124       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3125       vat_json_init_array (&vam->json_tree);
3126     }
3127   node = vat_json_array_add (&vam->json_tree);
3128
3129   vat_json_init_object (node);
3130   deid = format (0, "%U", format_lisp_eid_vat, &mp->deid, 0, 0);
3131
3132   seid = format (0, "%U", format_lisp_eid_vat, &mp->seid, 0, 0);
3133
3134   vec_add1 (deid, 0);
3135   vec_add1 (seid, 0);
3136
3137   vat_json_object_add_string_copy (node, "seid", seid);
3138   vat_json_object_add_string_copy (node, "deid", deid);
3139   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3140
3141   if (mp->lloc.af)
3142     {
3143       clib_memcpy (&ip6, mp->lloc.un.ip6, sizeof (ip6));
3144       vat_json_object_add_ip6 (node, "lloc", ip6);
3145       clib_memcpy (&ip6, mp->rloc.un.ip6, sizeof (ip6));
3146       vat_json_object_add_ip6 (node, "rloc", ip6);
3147
3148     }
3149   else
3150     {
3151       clib_memcpy (&ip4, mp->lloc.un.ip4, sizeof (ip4));
3152       vat_json_object_add_ip4 (node, "lloc", ip4);
3153       clib_memcpy (&ip4, mp->rloc.un.ip4, sizeof (ip4));
3154       vat_json_object_add_ip4 (node, "rloc", ip4);
3155     }
3156   vat_json_object_add_uint (node, "pkt_count",
3157                             clib_net_to_host_u32 (mp->pkt_count));
3158   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3159
3160   vec_free (deid);
3161   vec_free (seid);
3162 }
3163
3164 static void
3165   vl_api_one_eid_table_map_details_t_handler
3166   (vl_api_one_eid_table_map_details_t * mp)
3167 {
3168   vat_main_t *vam = &vat_main;
3169
3170   u8 *line = format (0, "%=10d%=10d",
3171                      clib_net_to_host_u32 (mp->vni),
3172                      clib_net_to_host_u32 (mp->dp_table));
3173   print (vam->ofp, "%v", line);
3174   vec_free (line);
3175 }
3176
3177 static void
3178   vl_api_one_eid_table_map_details_t_handler_json
3179   (vl_api_one_eid_table_map_details_t * mp)
3180 {
3181   vat_main_t *vam = &vat_main;
3182   vat_json_node_t *node = NULL;
3183
3184   if (VAT_JSON_ARRAY != vam->json_tree.type)
3185     {
3186       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3187       vat_json_init_array (&vam->json_tree);
3188     }
3189   node = vat_json_array_add (&vam->json_tree);
3190   vat_json_init_object (node);
3191   vat_json_object_add_uint (node, "dp_table",
3192                             clib_net_to_host_u32 (mp->dp_table));
3193   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3194 }
3195
3196 static void
3197   vl_api_one_eid_table_vni_details_t_handler
3198   (vl_api_one_eid_table_vni_details_t * mp)
3199 {
3200   vat_main_t *vam = &vat_main;
3201
3202   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3203   print (vam->ofp, "%v", line);
3204   vec_free (line);
3205 }
3206
3207 static void
3208   vl_api_one_eid_table_vni_details_t_handler_json
3209   (vl_api_one_eid_table_vni_details_t * mp)
3210 {
3211   vat_main_t *vam = &vat_main;
3212   vat_json_node_t *node = NULL;
3213
3214   if (VAT_JSON_ARRAY != vam->json_tree.type)
3215     {
3216       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3217       vat_json_init_array (&vam->json_tree);
3218     }
3219   node = vat_json_array_add (&vam->json_tree);
3220   vat_json_init_object (node);
3221   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3222 }
3223
3224 static void
3225   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3226   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3227 {
3228   vat_main_t *vam = &vat_main;
3229   int retval = clib_net_to_host_u32 (mp->retval);
3230
3231   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3232   print (vam->ofp, "fallback threshold value: %d", mp->value);
3233
3234   vam->retval = retval;
3235   vam->result_ready = 1;
3236 }
3237
3238 static void
3239   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3240   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3241 {
3242   vat_main_t *vam = &vat_main;
3243   vat_json_node_t _node, *node = &_node;
3244   int retval = clib_net_to_host_u32 (mp->retval);
3245
3246   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3247   vat_json_init_object (node);
3248   vat_json_object_add_uint (node, "value", mp->value);
3249
3250   vat_json_print (vam->ofp, node);
3251   vat_json_free (node);
3252
3253   vam->retval = retval;
3254   vam->result_ready = 1;
3255 }
3256
3257 static void
3258   vl_api_show_one_map_register_state_reply_t_handler
3259   (vl_api_show_one_map_register_state_reply_t * mp)
3260 {
3261   vat_main_t *vam = &vat_main;
3262   int retval = clib_net_to_host_u32 (mp->retval);
3263
3264   print (vam->ofp, "%s", mp->is_enable ? "enabled" : "disabled");
3265
3266   vam->retval = retval;
3267   vam->result_ready = 1;
3268 }
3269
3270 static void
3271   vl_api_show_one_map_register_state_reply_t_handler_json
3272   (vl_api_show_one_map_register_state_reply_t * mp)
3273 {
3274   vat_main_t *vam = &vat_main;
3275   vat_json_node_t _node, *node = &_node;
3276   int retval = clib_net_to_host_u32 (mp->retval);
3277
3278   u8 *s = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
3279
3280   vat_json_init_object (node);
3281   vat_json_object_add_string_copy (node, "state", s);
3282
3283   vat_json_print (vam->ofp, node);
3284   vat_json_free (node);
3285
3286   vam->retval = retval;
3287   vam->result_ready = 1;
3288   vec_free (s);
3289 }
3290
3291 static void
3292   vl_api_show_one_rloc_probe_state_reply_t_handler
3293   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3294 {
3295   vat_main_t *vam = &vat_main;
3296   int retval = clib_net_to_host_u32 (mp->retval);
3297
3298   if (retval)
3299     goto end;
3300
3301   print (vam->ofp, "%s", mp->is_enable ? "enabled" : "disabled");
3302 end:
3303   vam->retval = retval;
3304   vam->result_ready = 1;
3305 }
3306
3307 static void
3308   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3309   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3310 {
3311   vat_main_t *vam = &vat_main;
3312   vat_json_node_t _node, *node = &_node;
3313   int retval = clib_net_to_host_u32 (mp->retval);
3314
3315   u8 *s = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
3316   vat_json_init_object (node);
3317   vat_json_object_add_string_copy (node, "state", s);
3318
3319   vat_json_print (vam->ofp, node);
3320   vat_json_free (node);
3321
3322   vam->retval = retval;
3323   vam->result_ready = 1;
3324   vec_free (s);
3325 }
3326
3327 static void
3328   vl_api_show_one_stats_enable_disable_reply_t_handler
3329   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3330 {
3331   vat_main_t *vam = &vat_main;
3332   int retval = clib_net_to_host_u32 (mp->retval);
3333
3334   if (retval)
3335     goto end;
3336
3337   print (vam->ofp, "%s", mp->is_enable ? "enabled" : "disabled");
3338 end:
3339   vam->retval = retval;
3340   vam->result_ready = 1;
3341 }
3342
3343 static void
3344   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3345   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3346 {
3347   vat_main_t *vam = &vat_main;
3348   vat_json_node_t _node, *node = &_node;
3349   int retval = clib_net_to_host_u32 (mp->retval);
3350
3351   u8 *s = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
3352   vat_json_init_object (node);
3353   vat_json_object_add_string_copy (node, "state", s);
3354
3355   vat_json_print (vam->ofp, node);
3356   vat_json_free (node);
3357
3358   vam->retval = retval;
3359   vam->result_ready = 1;
3360   vec_free (s);
3361 }
3362
3363 static void
3364 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3365 {
3366   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3367   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3368   e->vni = clib_net_to_host_u32 (e->vni);
3369 }
3370
3371 static void
3372   gpe_fwd_entries_get_reply_t_net_to_host
3373   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3374 {
3375   u32 i;
3376
3377   mp->count = clib_net_to_host_u32 (mp->count);
3378   for (i = 0; i < mp->count; i++)
3379     {
3380       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3381     }
3382 }
3383
3384 static u8 *
3385 format_gpe_encap_mode (u8 * s, va_list * args)
3386 {
3387   u32 mode = va_arg (*args, u32);
3388
3389   switch (mode)
3390     {
3391     case 0:
3392       return format (s, "lisp");
3393     case 1:
3394       return format (s, "vxlan");
3395     }
3396   return 0;
3397 }
3398
3399 static void
3400   vl_api_gpe_get_encap_mode_reply_t_handler
3401   (vl_api_gpe_get_encap_mode_reply_t * mp)
3402 {
3403   vat_main_t *vam = &vat_main;
3404
3405   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3406   vam->retval = ntohl (mp->retval);
3407   vam->result_ready = 1;
3408 }
3409
3410 static void
3411   vl_api_gpe_get_encap_mode_reply_t_handler_json
3412   (vl_api_gpe_get_encap_mode_reply_t * mp)
3413 {
3414   vat_main_t *vam = &vat_main;
3415   vat_json_node_t node;
3416
3417   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3418   vec_add1 (encap_mode, 0);
3419
3420   vat_json_init_object (&node);
3421   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3422
3423   vec_free (encap_mode);
3424   vat_json_print (vam->ofp, &node);
3425   vat_json_free (&node);
3426
3427   vam->retval = ntohl (mp->retval);
3428   vam->result_ready = 1;
3429 }
3430
3431 static void
3432   vl_api_gpe_fwd_entry_path_details_t_handler
3433   (vl_api_gpe_fwd_entry_path_details_t * mp)
3434 {
3435   vat_main_t *vam = &vat_main;
3436   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3437
3438   if (mp->lcl_loc.addr.af)
3439     format_ip_address_fcn = format_ip6_address;
3440   else
3441     format_ip_address_fcn = format_ip4_address;
3442
3443   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3444          format_ip_address_fcn, &mp->lcl_loc.addr.un,
3445          format_ip_address_fcn, &mp->rmt_loc.addr.un);
3446 }
3447
3448 static void
3449 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3450 {
3451   struct in6_addr ip6;
3452   struct in_addr ip4;
3453
3454   if (loc->addr.af)
3455     {
3456       clib_memcpy (&ip6, loc->addr.un.ip6, sizeof (ip6));
3457       vat_json_object_add_ip6 (n, "address", ip6);
3458     }
3459   else
3460     {
3461       clib_memcpy (&ip4, loc->addr.un.ip4, sizeof (ip4));
3462       vat_json_object_add_ip4 (n, "address", ip4);
3463     }
3464   vat_json_object_add_uint (n, "weight", loc->weight);
3465 }
3466
3467 static void
3468   vl_api_gpe_fwd_entry_path_details_t_handler_json
3469   (vl_api_gpe_fwd_entry_path_details_t * mp)
3470 {
3471   vat_main_t *vam = &vat_main;
3472   vat_json_node_t *node = NULL;
3473   vat_json_node_t *loc_node;
3474
3475   if (VAT_JSON_ARRAY != vam->json_tree.type)
3476     {
3477       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3478       vat_json_init_array (&vam->json_tree);
3479     }
3480   node = vat_json_array_add (&vam->json_tree);
3481   vat_json_init_object (node);
3482
3483   loc_node = vat_json_object_add (node, "local_locator");
3484   vat_json_init_object (loc_node);
3485   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3486
3487   loc_node = vat_json_object_add (node, "remote_locator");
3488   vat_json_init_object (loc_node);
3489   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3490 }
3491
3492 static void
3493   vl_api_gpe_fwd_entries_get_reply_t_handler
3494   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3495 {
3496   vat_main_t *vam = &vat_main;
3497   u32 i;
3498   int retval = clib_net_to_host_u32 (mp->retval);
3499   vl_api_gpe_fwd_entry_t *e;
3500
3501   if (retval)
3502     goto end;
3503
3504   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3505
3506   for (i = 0; i < mp->count; i++)
3507     {
3508       e = &mp->entries[i];
3509       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3510              format_lisp_flat_eid, e->leid, format_lisp_flat_eid, e->reid);
3511     }
3512
3513 end:
3514   vam->retval = retval;
3515   vam->result_ready = 1;
3516 }
3517
3518 static void
3519   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3520   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3521 {
3522   u8 *s = 0;
3523   vat_main_t *vam = &vat_main;
3524   vat_json_node_t *e = 0, root;
3525   u32 i;
3526   int retval = clib_net_to_host_u32 (mp->retval);
3527   vl_api_gpe_fwd_entry_t *fwd;
3528
3529   if (retval)
3530     goto end;
3531
3532   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3533   vat_json_init_array (&root);
3534
3535   for (i = 0; i < mp->count; i++)
3536     {
3537       e = vat_json_array_add (&root);
3538       fwd = &mp->entries[i];
3539
3540       vat_json_init_object (e);
3541       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3542       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3543       vat_json_object_add_int (e, "vni", fwd->vni);
3544       vat_json_object_add_int (e, "action", fwd->action);
3545
3546       s = format (0, "%U", format_lisp_flat_eid, fwd->leid);
3547       vec_add1 (s, 0);
3548       vat_json_object_add_string_copy (e, "leid", s);
3549       vec_free (s);
3550
3551       s = format (0, "%U", format_lisp_flat_eid, fwd->reid);
3552       vec_add1 (s, 0);
3553       vat_json_object_add_string_copy (e, "reid", s);
3554       vec_free (s);
3555     }
3556
3557   vat_json_print (vam->ofp, &root);
3558   vat_json_free (&root);
3559
3560 end:
3561   vam->retval = retval;
3562   vam->result_ready = 1;
3563 }
3564
3565 static void
3566   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3567   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3568 {
3569   vat_main_t *vam = &vat_main;
3570   u32 i, n;
3571   int retval = clib_net_to_host_u32 (mp->retval);
3572   vl_api_gpe_native_fwd_rpath_t *r;
3573
3574   if (retval)
3575     goto end;
3576
3577   n = clib_net_to_host_u32 (mp->count);
3578
3579   for (i = 0; i < n; i++)
3580     {
3581       r = &mp->entries[i];
3582       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3583              clib_net_to_host_u32 (r->fib_index),
3584              clib_net_to_host_u32 (r->nh_sw_if_index),
3585              r->nh_addr.af ? format_ip6_address : format_ip4_address,
3586              r->nh_addr.un);
3587     }
3588
3589 end:
3590   vam->retval = retval;
3591   vam->result_ready = 1;
3592 }
3593
3594 static void
3595   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3596   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3597 {
3598   vat_main_t *vam = &vat_main;
3599   vat_json_node_t root, *e;
3600   u32 i, n;
3601   int retval = clib_net_to_host_u32 (mp->retval);
3602   vl_api_gpe_native_fwd_rpath_t *r;
3603   u8 *s;
3604
3605   if (retval)
3606     goto end;
3607
3608   n = clib_net_to_host_u32 (mp->count);
3609   vat_json_init_array (&root);
3610
3611   for (i = 0; i < n; i++)
3612     {
3613       e = vat_json_array_add (&root);
3614       vat_json_init_object (e);
3615       r = &mp->entries[i];
3616       s =
3617         format (0, "%U",
3618                 r->nh_addr.af ? format_ip6_address : format_ip4_address,
3619                 r->nh_addr.un);
3620       vec_add1 (s, 0);
3621       vat_json_object_add_string_copy (e, "ip4", s);
3622       vec_free (s);
3623
3624       vat_json_object_add_uint (e, "fib_index",
3625                                 clib_net_to_host_u32 (r->fib_index));
3626       vat_json_object_add_uint (e, "nh_sw_if_index",
3627                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3628     }
3629
3630   vat_json_print (vam->ofp, &root);
3631   vat_json_free (&root);
3632
3633 end:
3634   vam->retval = retval;
3635   vam->result_ready = 1;
3636 }
3637
3638 static void
3639   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3640   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3641 {
3642   vat_main_t *vam = &vat_main;
3643   u32 i, n;
3644   int retval = clib_net_to_host_u32 (mp->retval);
3645
3646   if (retval)
3647     goto end;
3648
3649   n = clib_net_to_host_u32 (mp->count);
3650
3651   for (i = 0; i < n; i++)
3652     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3653
3654 end:
3655   vam->retval = retval;
3656   vam->result_ready = 1;
3657 }
3658
3659 static void
3660   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3661   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3662 {
3663   vat_main_t *vam = &vat_main;
3664   vat_json_node_t root;
3665   u32 i, n;
3666   int retval = clib_net_to_host_u32 (mp->retval);
3667
3668   if (retval)
3669     goto end;
3670
3671   n = clib_net_to_host_u32 (mp->count);
3672   vat_json_init_array (&root);
3673
3674   for (i = 0; i < n; i++)
3675     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3676
3677   vat_json_print (vam->ofp, &root);
3678   vat_json_free (&root);
3679
3680 end:
3681   vam->retval = retval;
3682   vam->result_ready = 1;
3683 }
3684
3685 static void
3686   vl_api_one_ndp_entries_get_reply_t_handler
3687   (vl_api_one_ndp_entries_get_reply_t * mp)
3688 {
3689   vat_main_t *vam = &vat_main;
3690   u32 i, n;
3691   int retval = clib_net_to_host_u32 (mp->retval);
3692
3693   if (retval)
3694     goto end;
3695
3696   n = clib_net_to_host_u32 (mp->count);
3697
3698   for (i = 0; i < n; i++)
3699     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3700            format_ethernet_address, mp->entries[i].mac);
3701
3702 end:
3703   vam->retval = retval;
3704   vam->result_ready = 1;
3705 }
3706
3707 static void
3708   vl_api_one_ndp_entries_get_reply_t_handler_json
3709   (vl_api_one_ndp_entries_get_reply_t * mp)
3710 {
3711   u8 *s = 0;
3712   vat_main_t *vam = &vat_main;
3713   vat_json_node_t *e = 0, root;
3714   u32 i, n;
3715   int retval = clib_net_to_host_u32 (mp->retval);
3716   vl_api_one_ndp_entry_t *arp_entry;
3717
3718   if (retval)
3719     goto end;
3720
3721   n = clib_net_to_host_u32 (mp->count);
3722   vat_json_init_array (&root);
3723
3724   for (i = 0; i < n; i++)
3725     {
3726       e = vat_json_array_add (&root);
3727       arp_entry = &mp->entries[i];
3728
3729       vat_json_init_object (e);
3730       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3731       vec_add1 (s, 0);
3732
3733       vat_json_object_add_string_copy (e, "mac", s);
3734       vec_free (s);
3735
3736       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3737       vec_add1 (s, 0);
3738       vat_json_object_add_string_copy (e, "ip6", s);
3739       vec_free (s);
3740     }
3741
3742   vat_json_print (vam->ofp, &root);
3743   vat_json_free (&root);
3744
3745 end:
3746   vam->retval = retval;
3747   vam->result_ready = 1;
3748 }
3749
3750 static void
3751   vl_api_one_l2_arp_entries_get_reply_t_handler
3752   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3753 {
3754   vat_main_t *vam = &vat_main;
3755   u32 i, n;
3756   int retval = clib_net_to_host_u32 (mp->retval);
3757
3758   if (retval)
3759     goto end;
3760
3761   n = clib_net_to_host_u32 (mp->count);
3762
3763   for (i = 0; i < n; i++)
3764     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3765            format_ethernet_address, mp->entries[i].mac);
3766
3767 end:
3768   vam->retval = retval;
3769   vam->result_ready = 1;
3770 }
3771
3772 static void
3773   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3774   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3775 {
3776   u8 *s = 0;
3777   vat_main_t *vam = &vat_main;
3778   vat_json_node_t *e = 0, root;
3779   u32 i, n;
3780   int retval = clib_net_to_host_u32 (mp->retval);
3781   vl_api_one_l2_arp_entry_t *arp_entry;
3782
3783   if (retval)
3784     goto end;
3785
3786   n = clib_net_to_host_u32 (mp->count);
3787   vat_json_init_array (&root);
3788
3789   for (i = 0; i < n; i++)
3790     {
3791       e = vat_json_array_add (&root);
3792       arp_entry = &mp->entries[i];
3793
3794       vat_json_init_object (e);
3795       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3796       vec_add1 (s, 0);
3797
3798       vat_json_object_add_string_copy (e, "mac", s);
3799       vec_free (s);
3800
3801       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3802       vec_add1 (s, 0);
3803       vat_json_object_add_string_copy (e, "ip4", s);
3804       vec_free (s);
3805     }
3806
3807   vat_json_print (vam->ofp, &root);
3808   vat_json_free (&root);
3809
3810 end:
3811   vam->retval = retval;
3812   vam->result_ready = 1;
3813 }
3814
3815 static void
3816 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3817 {
3818   vat_main_t *vam = &vat_main;
3819   u32 i, n;
3820   int retval = clib_net_to_host_u32 (mp->retval);
3821
3822   if (retval)
3823     goto end;
3824
3825   n = clib_net_to_host_u32 (mp->count);
3826
3827   for (i = 0; i < n; i++)
3828     {
3829       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3830     }
3831
3832 end:
3833   vam->retval = retval;
3834   vam->result_ready = 1;
3835 }
3836
3837 static void
3838   vl_api_one_ndp_bd_get_reply_t_handler_json
3839   (vl_api_one_ndp_bd_get_reply_t * mp)
3840 {
3841   vat_main_t *vam = &vat_main;
3842   vat_json_node_t root;
3843   u32 i, n;
3844   int retval = clib_net_to_host_u32 (mp->retval);
3845
3846   if (retval)
3847     goto end;
3848
3849   n = clib_net_to_host_u32 (mp->count);
3850   vat_json_init_array (&root);
3851
3852   for (i = 0; i < n; i++)
3853     {
3854       vat_json_array_add_uint (&root,
3855                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3856     }
3857
3858   vat_json_print (vam->ofp, &root);
3859   vat_json_free (&root);
3860
3861 end:
3862   vam->retval = retval;
3863   vam->result_ready = 1;
3864 }
3865
3866 static void
3867   vl_api_one_l2_arp_bd_get_reply_t_handler
3868   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3869 {
3870   vat_main_t *vam = &vat_main;
3871   u32 i, n;
3872   int retval = clib_net_to_host_u32 (mp->retval);
3873
3874   if (retval)
3875     goto end;
3876
3877   n = clib_net_to_host_u32 (mp->count);
3878
3879   for (i = 0; i < n; i++)
3880     {
3881       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3882     }
3883
3884 end:
3885   vam->retval = retval;
3886   vam->result_ready = 1;
3887 }
3888
3889 static void
3890   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3891   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3892 {
3893   vat_main_t *vam = &vat_main;
3894   vat_json_node_t root;
3895   u32 i, n;
3896   int retval = clib_net_to_host_u32 (mp->retval);
3897
3898   if (retval)
3899     goto end;
3900
3901   n = clib_net_to_host_u32 (mp->count);
3902   vat_json_init_array (&root);
3903
3904   for (i = 0; i < n; i++)
3905     {
3906       vat_json_array_add_uint (&root,
3907                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3908     }
3909
3910   vat_json_print (vam->ofp, &root);
3911   vat_json_free (&root);
3912
3913 end:
3914   vam->retval = retval;
3915   vam->result_ready = 1;
3916 }
3917
3918 static void
3919   vl_api_one_adjacencies_get_reply_t_handler
3920   (vl_api_one_adjacencies_get_reply_t * mp)
3921 {
3922   vat_main_t *vam = &vat_main;
3923   u32 i, n;
3924   int retval = clib_net_to_host_u32 (mp->retval);
3925   vl_api_one_adjacency_t *a;
3926
3927   if (retval)
3928     goto end;
3929
3930   n = clib_net_to_host_u32 (mp->count);
3931
3932   for (i = 0; i < n; i++)
3933     {
3934       a = &mp->adjacencies[i];
3935       print (vam->ofp, "%U %40U",
3936              format_lisp_flat_eid, a->leid, format_lisp_flat_eid, a->reid);
3937     }
3938
3939 end:
3940   vam->retval = retval;
3941   vam->result_ready = 1;
3942 }
3943
3944 static void
3945   vl_api_one_adjacencies_get_reply_t_handler_json
3946   (vl_api_one_adjacencies_get_reply_t * mp)
3947 {
3948   u8 *s = 0;
3949   vat_main_t *vam = &vat_main;
3950   vat_json_node_t *e = 0, root;
3951   u32 i, n;
3952   int retval = clib_net_to_host_u32 (mp->retval);
3953   vl_api_one_adjacency_t *a;
3954
3955   if (retval)
3956     goto end;
3957
3958   n = clib_net_to_host_u32 (mp->count);
3959   vat_json_init_array (&root);
3960
3961   for (i = 0; i < n; i++)
3962     {
3963       e = vat_json_array_add (&root);
3964       a = &mp->adjacencies[i];
3965
3966       vat_json_init_object (e);
3967       s = format (0, "%U", format_lisp_flat_eid, a->leid);
3968       vec_add1 (s, 0);
3969       vat_json_object_add_string_copy (e, "leid", s);
3970       vec_free (s);
3971
3972       s = format (0, "%U", format_lisp_flat_eid, a->reid);
3973       vec_add1 (s, 0);
3974       vat_json_object_add_string_copy (e, "reid", s);
3975       vec_free (s);
3976     }
3977
3978   vat_json_print (vam->ofp, &root);
3979   vat_json_free (&root);
3980
3981 end:
3982   vam->retval = retval;
3983   vam->result_ready = 1;
3984 }
3985
3986 static void
3987 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3988 {
3989   vat_main_t *vam = &vat_main;
3990
3991   print (vam->ofp, "%=20U",
3992          mp->ip_address.af ? format_ip6_address : format_ip4_address,
3993          mp->ip_address.un);
3994 }
3995
3996 static void
3997   vl_api_one_map_server_details_t_handler_json
3998   (vl_api_one_map_server_details_t * mp)
3999 {
4000   vat_main_t *vam = &vat_main;
4001   vat_json_node_t *node = NULL;
4002   struct in6_addr ip6;
4003   struct in_addr ip4;
4004
4005   if (VAT_JSON_ARRAY != vam->json_tree.type)
4006     {
4007       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4008       vat_json_init_array (&vam->json_tree);
4009     }
4010   node = vat_json_array_add (&vam->json_tree);
4011
4012   vat_json_init_object (node);
4013   if (mp->ip_address.af)
4014     {
4015       clib_memcpy (&ip6, mp->ip_address.un.ip6, sizeof (ip6));
4016       vat_json_object_add_ip6 (node, "map-server", ip6);
4017     }
4018   else
4019     {
4020       clib_memcpy (&ip4, mp->ip_address.un.ip4, sizeof (ip4));
4021       vat_json_object_add_ip4 (node, "map-server", ip4);
4022     }
4023 }
4024
4025 static void
4026 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4027                                            * mp)
4028 {
4029   vat_main_t *vam = &vat_main;
4030
4031   print (vam->ofp, "%=20U",
4032          mp->ip_address.af ? format_ip6_address : format_ip4_address,
4033          mp->ip_address.un);
4034 }
4035
4036 static void
4037   vl_api_one_map_resolver_details_t_handler_json
4038   (vl_api_one_map_resolver_details_t * mp)
4039 {
4040   vat_main_t *vam = &vat_main;
4041   vat_json_node_t *node = NULL;
4042   struct in6_addr ip6;
4043   struct in_addr ip4;
4044
4045   if (VAT_JSON_ARRAY != vam->json_tree.type)
4046     {
4047       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4048       vat_json_init_array (&vam->json_tree);
4049     }
4050   node = vat_json_array_add (&vam->json_tree);
4051
4052   vat_json_init_object (node);
4053   if (mp->ip_address.af)
4054     {
4055       clib_memcpy (&ip6, mp->ip_address.un.ip6, sizeof (ip6));
4056       vat_json_object_add_ip6 (node, "map resolver", ip6);
4057     }
4058   else
4059     {
4060       clib_memcpy (&ip4, mp->ip_address.un.ip4, sizeof (ip4));
4061       vat_json_object_add_ip4 (node, "map resolver", ip4);
4062     }
4063 }
4064
4065 static void
4066 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4067 {
4068   vat_main_t *vam = &vat_main;
4069   i32 retval = ntohl (mp->retval);
4070
4071   if (0 <= retval)
4072     {
4073       print (vam->ofp, "feature: %s\ngpe: %s",
4074              mp->feature_status ? "enabled" : "disabled",
4075              mp->gpe_status ? "enabled" : "disabled");
4076     }
4077
4078   vam->retval = retval;
4079   vam->result_ready = 1;
4080 }
4081
4082 static void
4083   vl_api_show_one_status_reply_t_handler_json
4084   (vl_api_show_one_status_reply_t * mp)
4085 {
4086   vat_main_t *vam = &vat_main;
4087   vat_json_node_t node;
4088   u8 *gpe_status = NULL;
4089   u8 *feature_status = NULL;
4090
4091   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4092   feature_status = format (0, "%s",
4093                            mp->feature_status ? "enabled" : "disabled");
4094   vec_add1 (gpe_status, 0);
4095   vec_add1 (feature_status, 0);
4096
4097   vat_json_init_object (&node);
4098   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4099   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4100
4101   vec_free (gpe_status);
4102   vec_free (feature_status);
4103
4104   vat_json_print (vam->ofp, &node);
4105   vat_json_free (&node);
4106
4107   vam->retval = ntohl (mp->retval);
4108   vam->result_ready = 1;
4109 }
4110
4111 static void
4112   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4113   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4114 {
4115   vat_main_t *vam = &vat_main;
4116   i32 retval = ntohl (mp->retval);
4117
4118   if (retval >= 0)
4119     {
4120       print (vam->ofp, "%=20s", mp->locator_set_name);
4121     }
4122
4123   vam->retval = retval;
4124   vam->result_ready = 1;
4125 }
4126
4127 static void
4128   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4129   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4130 {
4131   vat_main_t *vam = &vat_main;
4132   vat_json_node_t *node = NULL;
4133
4134   if (VAT_JSON_ARRAY != vam->json_tree.type)
4135     {
4136       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4137       vat_json_init_array (&vam->json_tree);
4138     }
4139   node = vat_json_array_add (&vam->json_tree);
4140
4141   vat_json_init_object (node);
4142   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4143
4144   vat_json_print (vam->ofp, node);
4145   vat_json_free (node);
4146
4147   vam->retval = ntohl (mp->retval);
4148   vam->result_ready = 1;
4149 }
4150
4151 static u8 *
4152 format_lisp_map_request_mode (u8 * s, va_list * args)
4153 {
4154   u32 mode = va_arg (*args, u32);
4155
4156   switch (mode)
4157     {
4158     case 0:
4159       return format (0, "dst-only");
4160     case 1:
4161       return format (0, "src-dst");
4162     }
4163   return 0;
4164 }
4165
4166 static void
4167   vl_api_show_one_map_request_mode_reply_t_handler
4168   (vl_api_show_one_map_request_mode_reply_t * mp)
4169 {
4170   vat_main_t *vam = &vat_main;
4171   i32 retval = ntohl (mp->retval);
4172
4173   if (0 <= retval)
4174     {
4175       u32 mode = mp->mode;
4176       print (vam->ofp, "map_request_mode: %U",
4177              format_lisp_map_request_mode, mode);
4178     }
4179
4180   vam->retval = retval;
4181   vam->result_ready = 1;
4182 }
4183
4184 static void
4185   vl_api_show_one_map_request_mode_reply_t_handler_json
4186   (vl_api_show_one_map_request_mode_reply_t * mp)
4187 {
4188   vat_main_t *vam = &vat_main;
4189   vat_json_node_t node;
4190   u8 *s = 0;
4191   u32 mode;
4192
4193   mode = mp->mode;
4194   s = format (0, "%U", format_lisp_map_request_mode, mode);
4195   vec_add1 (s, 0);
4196
4197   vat_json_init_object (&node);
4198   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4199   vat_json_print (vam->ofp, &node);
4200   vat_json_free (&node);
4201
4202   vec_free (s);
4203   vam->retval = ntohl (mp->retval);
4204   vam->result_ready = 1;
4205 }
4206
4207 static void
4208   vl_api_one_show_xtr_mode_reply_t_handler
4209   (vl_api_one_show_xtr_mode_reply_t * mp)
4210 {
4211   vat_main_t *vam = &vat_main;
4212   i32 retval = ntohl (mp->retval);
4213
4214   if (0 <= retval)
4215     {
4216       print (vam->ofp, "%s\n", mp->is_enable ? "enabled" : "disabled");
4217     }
4218
4219   vam->retval = retval;
4220   vam->result_ready = 1;
4221 }
4222
4223 static void
4224   vl_api_one_show_xtr_mode_reply_t_handler_json
4225   (vl_api_one_show_xtr_mode_reply_t * mp)
4226 {
4227   vat_main_t *vam = &vat_main;
4228   vat_json_node_t node;
4229   u8 *status = 0;
4230
4231   status = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
4232   vec_add1 (status, 0);
4233
4234   vat_json_init_object (&node);
4235   vat_json_object_add_string_copy (&node, "status", status);
4236
4237   vec_free (status);
4238
4239   vat_json_print (vam->ofp, &node);
4240   vat_json_free (&node);
4241
4242   vam->retval = ntohl (mp->retval);
4243   vam->result_ready = 1;
4244 }
4245
4246 static void
4247   vl_api_one_show_pitr_mode_reply_t_handler
4248   (vl_api_one_show_pitr_mode_reply_t * mp)
4249 {
4250   vat_main_t *vam = &vat_main;
4251   i32 retval = ntohl (mp->retval);
4252
4253   if (0 <= retval)
4254     {
4255       print (vam->ofp, "%s\n", mp->is_enable ? "enabled" : "disabled");
4256     }
4257
4258   vam->retval = retval;
4259   vam->result_ready = 1;
4260 }
4261
4262 static void
4263   vl_api_one_show_pitr_mode_reply_t_handler_json
4264   (vl_api_one_show_pitr_mode_reply_t * mp)
4265 {
4266   vat_main_t *vam = &vat_main;
4267   vat_json_node_t node;
4268   u8 *status = 0;
4269
4270   status = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
4271   vec_add1 (status, 0);
4272
4273   vat_json_init_object (&node);
4274   vat_json_object_add_string_copy (&node, "status", status);
4275
4276   vec_free (status);
4277
4278   vat_json_print (vam->ofp, &node);
4279   vat_json_free (&node);
4280
4281   vam->retval = ntohl (mp->retval);
4282   vam->result_ready = 1;
4283 }
4284
4285 static void
4286   vl_api_one_show_petr_mode_reply_t_handler
4287   (vl_api_one_show_petr_mode_reply_t * mp)
4288 {
4289   vat_main_t *vam = &vat_main;
4290   i32 retval = ntohl (mp->retval);
4291
4292   if (0 <= retval)
4293     {
4294       print (vam->ofp, "%s\n", mp->is_enable ? "enabled" : "disabled");
4295     }
4296
4297   vam->retval = retval;
4298   vam->result_ready = 1;
4299 }
4300
4301 static void
4302   vl_api_one_show_petr_mode_reply_t_handler_json
4303   (vl_api_one_show_petr_mode_reply_t * mp)
4304 {
4305   vat_main_t *vam = &vat_main;
4306   vat_json_node_t node;
4307   u8 *status = 0;
4308
4309   status = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
4310   vec_add1 (status, 0);
4311
4312   vat_json_init_object (&node);
4313   vat_json_object_add_string_copy (&node, "status", status);
4314
4315   vec_free (status);
4316
4317   vat_json_print (vam->ofp, &node);
4318   vat_json_free (&node);
4319
4320   vam->retval = ntohl (mp->retval);
4321   vam->result_ready = 1;
4322 }
4323
4324 static void
4325   vl_api_show_one_use_petr_reply_t_handler
4326   (vl_api_show_one_use_petr_reply_t * mp)
4327 {
4328   vat_main_t *vam = &vat_main;
4329   i32 retval = ntohl (mp->retval);
4330
4331   if (0 <= retval)
4332     {
4333       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4334       if (mp->status)
4335         {
4336           print (vam->ofp, "Proxy-ETR address; %U",
4337                  mp->ip_address.af ? format_ip6_address : format_ip4_address,
4338                  mp->ip_address.un);
4339         }
4340     }
4341
4342   vam->retval = retval;
4343   vam->result_ready = 1;
4344 }
4345
4346 static void
4347   vl_api_show_one_use_petr_reply_t_handler_json
4348   (vl_api_show_one_use_petr_reply_t * mp)
4349 {
4350   vat_main_t *vam = &vat_main;
4351   vat_json_node_t node;
4352   u8 *status = 0;
4353   struct in_addr ip4;
4354   struct in6_addr ip6;
4355
4356   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4357   vec_add1 (status, 0);
4358
4359   vat_json_init_object (&node);
4360   vat_json_object_add_string_copy (&node, "status", status);
4361   if (mp->status)
4362     {
4363       if (mp->ip_address.af)
4364         {
4365           clib_memcpy (&ip6, mp->ip_address.un.ip6, sizeof (ip6));
4366           vat_json_object_add_ip6 (&node, "address", ip6);
4367         }
4368       else
4369         {
4370           clib_memcpy (&ip4, mp->ip_address.un.ip4, sizeof (ip4));
4371           vat_json_object_add_ip4 (&node, "address", ip4);
4372         }
4373     }
4374
4375   vec_free (status);
4376
4377   vat_json_print (vam->ofp, &node);
4378   vat_json_free (&node);
4379
4380   vam->retval = ntohl (mp->retval);
4381   vam->result_ready = 1;
4382 }
4383
4384 static void
4385   vl_api_show_one_nsh_mapping_reply_t_handler
4386   (vl_api_show_one_nsh_mapping_reply_t * mp)
4387 {
4388   vat_main_t *vam = &vat_main;
4389   i32 retval = ntohl (mp->retval);
4390
4391   if (0 <= retval)
4392     {
4393       print (vam->ofp, "%-20s%-16s",
4394              mp->is_set ? "set" : "not-set",
4395              mp->is_set ? (char *) mp->locator_set_name : "");
4396     }
4397
4398   vam->retval = retval;
4399   vam->result_ready = 1;
4400 }
4401
4402 static void
4403   vl_api_show_one_nsh_mapping_reply_t_handler_json
4404   (vl_api_show_one_nsh_mapping_reply_t * mp)
4405 {
4406   vat_main_t *vam = &vat_main;
4407   vat_json_node_t node;
4408   u8 *status = 0;
4409
4410   status = format (0, "%s", mp->is_set ? "yes" : "no");
4411   vec_add1 (status, 0);
4412
4413   vat_json_init_object (&node);
4414   vat_json_object_add_string_copy (&node, "is_set", status);
4415   if (mp->is_set)
4416     {
4417       vat_json_object_add_string_copy (&node, "locator_set",
4418                                        mp->locator_set_name);
4419     }
4420
4421   vec_free (status);
4422
4423   vat_json_print (vam->ofp, &node);
4424   vat_json_free (&node);
4425
4426   vam->retval = ntohl (mp->retval);
4427   vam->result_ready = 1;
4428 }
4429
4430 static void
4431   vl_api_show_one_map_register_ttl_reply_t_handler
4432   (vl_api_show_one_map_register_ttl_reply_t * mp)
4433 {
4434   vat_main_t *vam = &vat_main;
4435   i32 retval = ntohl (mp->retval);
4436
4437   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4438
4439   if (0 <= retval)
4440     {
4441       print (vam->ofp, "ttl: %u", mp->ttl);
4442     }
4443
4444   vam->retval = retval;
4445   vam->result_ready = 1;
4446 }
4447
4448 static void
4449   vl_api_show_one_map_register_ttl_reply_t_handler_json
4450   (vl_api_show_one_map_register_ttl_reply_t * mp)
4451 {
4452   vat_main_t *vam = &vat_main;
4453   vat_json_node_t node;
4454
4455   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4456   vat_json_init_object (&node);
4457   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4458
4459   vat_json_print (vam->ofp, &node);
4460   vat_json_free (&node);
4461
4462   vam->retval = ntohl (mp->retval);
4463   vam->result_ready = 1;
4464 }
4465
4466 static void
4467 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4468 {
4469   vat_main_t *vam = &vat_main;
4470   i32 retval = ntohl (mp->retval);
4471
4472   if (0 <= retval)
4473     {
4474       print (vam->ofp, "%-20s%-16s",
4475              mp->status ? "enabled" : "disabled",
4476              mp->status ? (char *) mp->locator_set_name : "");
4477     }
4478
4479   vam->retval = retval;
4480   vam->result_ready = 1;
4481 }
4482
4483 static void
4484 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4485 {
4486   vat_main_t *vam = &vat_main;
4487   vat_json_node_t node;
4488   u8 *status = 0;
4489
4490   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4491   vec_add1 (status, 0);
4492
4493   vat_json_init_object (&node);
4494   vat_json_object_add_string_copy (&node, "status", status);
4495   if (mp->status)
4496     {
4497       vat_json_object_add_string_copy (&node, "locator_set",
4498                                        mp->locator_set_name);
4499     }
4500
4501   vec_free (status);
4502
4503   vat_json_print (vam->ofp, &node);
4504   vat_json_free (&node);
4505
4506   vam->retval = ntohl (mp->retval);
4507   vam->result_ready = 1;
4508 }
4509
4510 static u8 *
4511 format_policer_type (u8 * s, va_list * va)
4512 {
4513   u32 i = va_arg (*va, u32);
4514
4515   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4516     s = format (s, "1r2c");
4517   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4518     s = format (s, "1r3c");
4519   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4520     s = format (s, "2r3c-2698");
4521   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4522     s = format (s, "2r3c-4115");
4523   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4524     s = format (s, "2r3c-mef5cf1");
4525   else
4526     s = format (s, "ILLEGAL");
4527   return s;
4528 }
4529
4530 static u8 *
4531 format_policer_rate_type (u8 * s, va_list * va)
4532 {
4533   u32 i = va_arg (*va, u32);
4534
4535   if (i == SSE2_QOS_RATE_KBPS)
4536     s = format (s, "kbps");
4537   else if (i == SSE2_QOS_RATE_PPS)
4538     s = format (s, "pps");
4539   else
4540     s = format (s, "ILLEGAL");
4541   return s;
4542 }
4543
4544 static u8 *
4545 format_policer_round_type (u8 * s, va_list * va)
4546 {
4547   u32 i = va_arg (*va, u32);
4548
4549   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4550     s = format (s, "closest");
4551   else if (i == SSE2_QOS_ROUND_TO_UP)
4552     s = format (s, "up");
4553   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4554     s = format (s, "down");
4555   else
4556     s = format (s, "ILLEGAL");
4557   return s;
4558 }
4559
4560 static u8 *
4561 format_policer_action_type (u8 * s, va_list * va)
4562 {
4563   u32 i = va_arg (*va, u32);
4564
4565   if (i == SSE2_QOS_ACTION_DROP)
4566     s = format (s, "drop");
4567   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4568     s = format (s, "transmit");
4569   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4570     s = format (s, "mark-and-transmit");
4571   else
4572     s = format (s, "ILLEGAL");
4573   return s;
4574 }
4575
4576 static u8 *
4577 format_dscp (u8 * s, va_list * va)
4578 {
4579   u32 i = va_arg (*va, u32);
4580   char *t = 0;
4581
4582   switch (i)
4583     {
4584 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4585       foreach_vnet_dscp
4586 #undef _
4587     default:
4588       return format (s, "ILLEGAL");
4589     }
4590   s = format (s, "%s", t);
4591   return s;
4592 }
4593
4594 static void
4595 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4596 {
4597   vat_main_t *vam = &vat_main;
4598   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4599
4600   if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4601     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp);
4602   else
4603     conform_dscp_str = format (0, "");
4604
4605   if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4606     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp);
4607   else
4608     exceed_dscp_str = format (0, "");
4609
4610   if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4611     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp);
4612   else
4613     violate_dscp_str = format (0, "");
4614
4615   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4616          "rate type %U, round type %U, %s rate, %s color-aware, "
4617          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4618          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4619          "conform action %U%s, exceed action %U%s, violate action %U%s",
4620          mp->name,
4621          format_policer_type, mp->type,
4622          ntohl (mp->cir),
4623          ntohl (mp->eir),
4624          clib_net_to_host_u64 (mp->cb),
4625          clib_net_to_host_u64 (mp->eb),
4626          format_policer_rate_type, mp->rate_type,
4627          format_policer_round_type, mp->round_type,
4628          mp->single_rate ? "single" : "dual",
4629          mp->color_aware ? "is" : "not",
4630          ntohl (mp->cir_tokens_per_period),
4631          ntohl (mp->pir_tokens_per_period),
4632          ntohl (mp->scale),
4633          ntohl (mp->current_limit),
4634          ntohl (mp->current_bucket),
4635          ntohl (mp->extended_limit),
4636          ntohl (mp->extended_bucket),
4637          clib_net_to_host_u64 (mp->last_update_time),
4638          format_policer_action_type, mp->conform_action.type,
4639          conform_dscp_str,
4640          format_policer_action_type, mp->exceed_action.type,
4641          exceed_dscp_str,
4642          format_policer_action_type, mp->violate_action.type,
4643          violate_dscp_str);
4644
4645   vec_free (conform_dscp_str);
4646   vec_free (exceed_dscp_str);
4647   vec_free (violate_dscp_str);
4648 }
4649
4650 static void vl_api_policer_details_t_handler_json
4651   (vl_api_policer_details_t * mp)
4652 {
4653   vat_main_t *vam = &vat_main;
4654   vat_json_node_t *node;
4655   u8 *rate_type_str, *round_type_str, *type_str;
4656   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4657
4658   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4659   round_type_str =
4660     format (0, "%U", format_policer_round_type, mp->round_type);
4661   type_str = format (0, "%U", format_policer_type, mp->type);
4662   conform_action_str = format (0, "%U", format_policer_action_type,
4663                                mp->conform_action.type);
4664   exceed_action_str = format (0, "%U", format_policer_action_type,
4665                               mp->exceed_action.type);
4666   violate_action_str = format (0, "%U", format_policer_action_type,
4667                                mp->violate_action.type);
4668
4669   if (VAT_JSON_ARRAY != vam->json_tree.type)
4670     {
4671       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4672       vat_json_init_array (&vam->json_tree);
4673     }
4674   node = vat_json_array_add (&vam->json_tree);
4675
4676   vat_json_init_object (node);
4677   vat_json_object_add_string_copy (node, "name", mp->name);
4678   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4679   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4680   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4681   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4682   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4683   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4684   vat_json_object_add_string_copy (node, "type", type_str);
4685   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4686   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4687   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4688   vat_json_object_add_uint (node, "cir_tokens_per_period",
4689                             ntohl (mp->cir_tokens_per_period));
4690   vat_json_object_add_uint (node, "eir_tokens_per_period",
4691                             ntohl (mp->pir_tokens_per_period));
4692   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4693   vat_json_object_add_uint (node, "current_bucket",
4694                             ntohl (mp->current_bucket));
4695   vat_json_object_add_uint (node, "extended_limit",
4696                             ntohl (mp->extended_limit));
4697   vat_json_object_add_uint (node, "extended_bucket",
4698                             ntohl (mp->extended_bucket));
4699   vat_json_object_add_uint (node, "last_update_time",
4700                             ntohl (mp->last_update_time));
4701   vat_json_object_add_string_copy (node, "conform_action",
4702                                    conform_action_str);
4703   if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4704     {
4705       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp);
4706       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4707       vec_free (dscp_str);
4708     }
4709   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4710   if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4711     {
4712       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp);
4713       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4714       vec_free (dscp_str);
4715     }
4716   vat_json_object_add_string_copy (node, "violate_action",
4717                                    violate_action_str);
4718   if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4719     {
4720       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp);
4721       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4722       vec_free (dscp_str);
4723     }
4724
4725   vec_free (rate_type_str);
4726   vec_free (round_type_str);
4727   vec_free (type_str);
4728   vec_free (conform_action_str);
4729   vec_free (exceed_action_str);
4730   vec_free (violate_action_str);
4731 }
4732
4733 static void
4734 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4735                                            mp)
4736 {
4737   vat_main_t *vam = &vat_main;
4738   int i, count = ntohl (mp->count);
4739
4740   if (count > 0)
4741     print (vam->ofp, "classify table ids (%d) : ", count);
4742   for (i = 0; i < count; i++)
4743     {
4744       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4745       print (vam->ofp, (i < count - 1) ? "," : "");
4746     }
4747   vam->retval = ntohl (mp->retval);
4748   vam->result_ready = 1;
4749 }
4750
4751 static void
4752   vl_api_classify_table_ids_reply_t_handler_json
4753   (vl_api_classify_table_ids_reply_t * mp)
4754 {
4755   vat_main_t *vam = &vat_main;
4756   int i, count = ntohl (mp->count);
4757
4758   if (count > 0)
4759     {
4760       vat_json_node_t node;
4761
4762       vat_json_init_object (&node);
4763       for (i = 0; i < count; i++)
4764         {
4765           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4766         }
4767       vat_json_print (vam->ofp, &node);
4768       vat_json_free (&node);
4769     }
4770   vam->retval = ntohl (mp->retval);
4771   vam->result_ready = 1;
4772 }
4773
4774 static void
4775   vl_api_classify_table_by_interface_reply_t_handler
4776   (vl_api_classify_table_by_interface_reply_t * mp)
4777 {
4778   vat_main_t *vam = &vat_main;
4779   u32 table_id;
4780
4781   table_id = ntohl (mp->l2_table_id);
4782   if (table_id != ~0)
4783     print (vam->ofp, "l2 table id : %d", table_id);
4784   else
4785     print (vam->ofp, "l2 table id : No input ACL tables configured");
4786   table_id = ntohl (mp->ip4_table_id);
4787   if (table_id != ~0)
4788     print (vam->ofp, "ip4 table id : %d", table_id);
4789   else
4790     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4791   table_id = ntohl (mp->ip6_table_id);
4792   if (table_id != ~0)
4793     print (vam->ofp, "ip6 table id : %d", table_id);
4794   else
4795     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4796   vam->retval = ntohl (mp->retval);
4797   vam->result_ready = 1;
4798 }
4799
4800 static void
4801   vl_api_classify_table_by_interface_reply_t_handler_json
4802   (vl_api_classify_table_by_interface_reply_t * mp)
4803 {
4804   vat_main_t *vam = &vat_main;
4805   vat_json_node_t node;
4806
4807   vat_json_init_object (&node);
4808
4809   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4810   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4811   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4812
4813   vat_json_print (vam->ofp, &node);
4814   vat_json_free (&node);
4815
4816   vam->retval = ntohl (mp->retval);
4817   vam->result_ready = 1;
4818 }
4819
4820 static void vl_api_policer_add_del_reply_t_handler
4821   (vl_api_policer_add_del_reply_t * mp)
4822 {
4823   vat_main_t *vam = &vat_main;
4824   i32 retval = ntohl (mp->retval);
4825   if (vam->async_mode)
4826     {
4827       vam->async_errors += (retval < 0);
4828     }
4829   else
4830     {
4831       vam->retval = retval;
4832       vam->result_ready = 1;
4833       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4834         /*
4835          * Note: this is just barely thread-safe, depends on
4836          * the main thread spinning waiting for an answer...
4837          */
4838         errmsg ("policer index %d", ntohl (mp->policer_index));
4839     }
4840 }
4841
4842 static void vl_api_policer_add_del_reply_t_handler_json
4843   (vl_api_policer_add_del_reply_t * mp)
4844 {
4845   vat_main_t *vam = &vat_main;
4846   vat_json_node_t node;
4847
4848   vat_json_init_object (&node);
4849   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4850   vat_json_object_add_uint (&node, "policer_index",
4851                             ntohl (mp->policer_index));
4852
4853   vat_json_print (vam->ofp, &node);
4854   vat_json_free (&node);
4855
4856   vam->retval = ntohl (mp->retval);
4857   vam->result_ready = 1;
4858 }
4859
4860 /* Format hex dump. */
4861 u8 *
4862 format_hex_bytes (u8 * s, va_list * va)
4863 {
4864   u8 *bytes = va_arg (*va, u8 *);
4865   int n_bytes = va_arg (*va, int);
4866   uword i;
4867
4868   /* Print short or long form depending on byte count. */
4869   uword short_form = n_bytes <= 32;
4870   u32 indent = format_get_indent (s);
4871
4872   if (n_bytes == 0)
4873     return s;
4874
4875   for (i = 0; i < n_bytes; i++)
4876     {
4877       if (!short_form && (i % 32) == 0)
4878         s = format (s, "%08x: ", i);
4879       s = format (s, "%02x", bytes[i]);
4880       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4881         s = format (s, "\n%U", format_white_space, indent);
4882     }
4883
4884   return s;
4885 }
4886
4887 static void
4888 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4889                                             * mp)
4890 {
4891   vat_main_t *vam = &vat_main;
4892   i32 retval = ntohl (mp->retval);
4893   if (retval == 0)
4894     {
4895       print (vam->ofp, "classify table info :");
4896       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4897              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4898              ntohl (mp->miss_next_index));
4899       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4900              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4901              ntohl (mp->match_n_vectors));
4902       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4903              ntohl (mp->mask_length));
4904     }
4905   vam->retval = retval;
4906   vam->result_ready = 1;
4907 }
4908
4909 static void
4910   vl_api_classify_table_info_reply_t_handler_json
4911   (vl_api_classify_table_info_reply_t * mp)
4912 {
4913   vat_main_t *vam = &vat_main;
4914   vat_json_node_t node;
4915
4916   i32 retval = ntohl (mp->retval);
4917   if (retval == 0)
4918     {
4919       vat_json_init_object (&node);
4920
4921       vat_json_object_add_int (&node, "sessions",
4922                                ntohl (mp->active_sessions));
4923       vat_json_object_add_int (&node, "nexttbl",
4924                                ntohl (mp->next_table_index));
4925       vat_json_object_add_int (&node, "nextnode",
4926                                ntohl (mp->miss_next_index));
4927       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4928       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4929       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4930       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4931                       ntohl (mp->mask_length), 0);
4932       vat_json_object_add_string_copy (&node, "mask", s);
4933
4934       vat_json_print (vam->ofp, &node);
4935       vat_json_free (&node);
4936     }
4937   vam->retval = ntohl (mp->retval);
4938   vam->result_ready = 1;
4939 }
4940
4941 static void
4942 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4943                                            mp)
4944 {
4945   vat_main_t *vam = &vat_main;
4946
4947   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4948          ntohl (mp->hit_next_index), ntohl (mp->advance),
4949          ntohl (mp->opaque_index));
4950   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4951          ntohl (mp->match_length));
4952 }
4953
4954 static void
4955   vl_api_classify_session_details_t_handler_json
4956   (vl_api_classify_session_details_t * mp)
4957 {
4958   vat_main_t *vam = &vat_main;
4959   vat_json_node_t *node = NULL;
4960
4961   if (VAT_JSON_ARRAY != vam->json_tree.type)
4962     {
4963       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4964       vat_json_init_array (&vam->json_tree);
4965     }
4966   node = vat_json_array_add (&vam->json_tree);
4967
4968   vat_json_init_object (node);
4969   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4970   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4971   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4972   u8 *s =
4973     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4974             0);
4975   vat_json_object_add_string_copy (node, "match", s);
4976 }
4977
4978 static void vl_api_pg_create_interface_reply_t_handler
4979   (vl_api_pg_create_interface_reply_t * mp)
4980 {
4981   vat_main_t *vam = &vat_main;
4982
4983   vam->retval = ntohl (mp->retval);
4984   vam->result_ready = 1;
4985 }
4986
4987 static void vl_api_pg_create_interface_reply_t_handler_json
4988   (vl_api_pg_create_interface_reply_t * mp)
4989 {
4990   vat_main_t *vam = &vat_main;
4991   vat_json_node_t node;
4992
4993   i32 retval = ntohl (mp->retval);
4994   if (retval == 0)
4995     {
4996       vat_json_init_object (&node);
4997
4998       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4999
5000       vat_json_print (vam->ofp, &node);
5001       vat_json_free (&node);
5002     }
5003   vam->retval = ntohl (mp->retval);
5004   vam->result_ready = 1;
5005 }
5006
5007 static void vl_api_policer_classify_details_t_handler
5008   (vl_api_policer_classify_details_t * mp)
5009 {
5010   vat_main_t *vam = &vat_main;
5011
5012   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5013          ntohl (mp->table_index));
5014 }
5015
5016 static void vl_api_policer_classify_details_t_handler_json
5017   (vl_api_policer_classify_details_t * mp)
5018 {
5019   vat_main_t *vam = &vat_main;
5020   vat_json_node_t *node;
5021
5022   if (VAT_JSON_ARRAY != vam->json_tree.type)
5023     {
5024       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5025       vat_json_init_array (&vam->json_tree);
5026     }
5027   node = vat_json_array_add (&vam->json_tree);
5028
5029   vat_json_init_object (node);
5030   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5031   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5032 }
5033
5034 static void vl_api_flow_classify_details_t_handler
5035   (vl_api_flow_classify_details_t * mp)
5036 {
5037   vat_main_t *vam = &vat_main;
5038
5039   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5040          ntohl (mp->table_index));
5041 }
5042
5043 static void vl_api_flow_classify_details_t_handler_json
5044   (vl_api_flow_classify_details_t * mp)
5045 {
5046   vat_main_t *vam = &vat_main;
5047   vat_json_node_t *node;
5048
5049   if (VAT_JSON_ARRAY != vam->json_tree.type)
5050     {
5051       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5052       vat_json_init_array (&vam->json_tree);
5053     }
5054   node = vat_json_array_add (&vam->json_tree);
5055
5056   vat_json_init_object (node);
5057   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5058   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5059 }
5060
5061 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5062 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5063 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5064 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5065 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5066 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5067 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5068 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5069 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5070 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5071
5072 /*
5073  * Generate boilerplate reply handlers, which
5074  * dig the return value out of the xxx_reply_t API message,
5075  * stick it into vam->retval, and set vam->result_ready
5076  *
5077  * Could also do this by pointing N message decode slots at
5078  * a single function, but that could break in subtle ways.
5079  */
5080
5081 #define foreach_standard_reply_retval_handler           \
5082 _(sw_interface_set_flags_reply)                         \
5083 _(sw_interface_add_del_address_reply)                   \
5084 _(sw_interface_set_rx_mode_reply)                       \
5085 _(sw_interface_set_rx_placement_reply)                  \
5086 _(sw_interface_set_table_reply)                         \
5087 _(sw_interface_set_mpls_enable_reply)                   \
5088 _(sw_interface_set_vpath_reply)                         \
5089 _(sw_interface_set_vxlan_bypass_reply)                  \
5090 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5091 _(sw_interface_set_l2_bridge_reply)                     \
5092 _(sw_interface_set_bond_weight_reply)                   \
5093 _(bridge_domain_add_del_reply)                          \
5094 _(sw_interface_set_l2_xconnect_reply)                   \
5095 _(l2fib_add_del_reply)                                  \
5096 _(l2fib_flush_int_reply)                                \
5097 _(l2fib_flush_bd_reply)                                 \
5098 _(ip_route_add_del_reply)                               \
5099 _(ip_table_add_del_reply)                               \
5100 _(ip_table_replace_begin_reply)                         \
5101 _(ip_table_flush_reply)                                 \
5102 _(ip_table_replace_end_reply)                           \
5103 _(ip_mroute_add_del_reply)                              \
5104 _(mpls_route_add_del_reply)                             \
5105 _(mpls_table_add_del_reply)                             \
5106 _(mpls_ip_bind_unbind_reply)                            \
5107 _(bier_route_add_del_reply)                             \
5108 _(bier_table_add_del_reply)                             \
5109 _(sw_interface_set_unnumbered_reply)                    \
5110 _(set_ip_flow_hash_reply)                               \
5111 _(sw_interface_ip6_enable_disable_reply)                \
5112 _(l2_patch_add_del_reply)                               \
5113 _(sr_mpls_policy_add_reply)                             \
5114 _(sr_mpls_policy_mod_reply)                             \
5115 _(sr_mpls_policy_del_reply)                             \
5116 _(sr_policy_add_reply)                                  \
5117 _(sr_policy_mod_reply)                                  \
5118 _(sr_policy_del_reply)                                  \
5119 _(sr_localsid_add_del_reply)                            \
5120 _(sr_steering_add_del_reply)                            \
5121 _(classify_add_del_session_reply)                       \
5122 _(classify_set_interface_ip_table_reply)                \
5123 _(classify_set_interface_l2_tables_reply)               \
5124 _(l2tpv3_set_tunnel_cookies_reply)                      \
5125 _(l2tpv3_interface_enable_disable_reply)                \
5126 _(l2tpv3_set_lookup_key_reply)                          \
5127 _(l2_fib_clear_table_reply)                             \
5128 _(l2_interface_efp_filter_reply)                        \
5129 _(l2_interface_vlan_tag_rewrite_reply)                  \
5130 _(modify_vhost_user_if_reply)                           \
5131 _(delete_vhost_user_if_reply)                           \
5132 _(want_l2_macs_events_reply)                            \
5133 _(input_acl_set_interface_reply)                        \
5134 _(ipsec_spd_add_del_reply)                              \
5135 _(ipsec_interface_add_del_spd_reply)                    \
5136 _(ipsec_spd_entry_add_del_reply)                        \
5137 _(ipsec_sad_entry_add_del_reply)                        \
5138 _(ipsec_tunnel_if_add_del_reply)                        \
5139 _(ipsec_tunnel_if_set_sa_reply)                         \
5140 _(delete_loopback_reply)                                \
5141 _(bd_ip_mac_add_del_reply)                              \
5142 _(bd_ip_mac_flush_reply)                                \
5143 _(want_interface_events_reply)                          \
5144 _(cop_interface_enable_disable_reply)                   \
5145 _(cop_whitelist_enable_disable_reply)                   \
5146 _(sw_interface_clear_stats_reply)                       \
5147 _(ioam_enable_reply)                                    \
5148 _(ioam_disable_reply)                                   \
5149 _(one_add_del_locator_reply)                            \
5150 _(one_add_del_local_eid_reply)                          \
5151 _(one_add_del_remote_mapping_reply)                     \
5152 _(one_add_del_adjacency_reply)                          \
5153 _(one_add_del_map_resolver_reply)                       \
5154 _(one_add_del_map_server_reply)                         \
5155 _(one_enable_disable_reply)                             \
5156 _(one_rloc_probe_enable_disable_reply)                  \
5157 _(one_map_register_enable_disable_reply)                \
5158 _(one_map_register_set_ttl_reply)                       \
5159 _(one_set_transport_protocol_reply)                     \
5160 _(one_map_register_fallback_threshold_reply)            \
5161 _(one_pitr_set_locator_set_reply)                       \
5162 _(one_map_request_mode_reply)                           \
5163 _(one_add_del_map_request_itr_rlocs_reply)              \
5164 _(one_eid_table_add_del_map_reply)                      \
5165 _(one_use_petr_reply)                                   \
5166 _(one_stats_enable_disable_reply)                       \
5167 _(one_add_del_l2_arp_entry_reply)                       \
5168 _(one_add_del_ndp_entry_reply)                          \
5169 _(one_stats_flush_reply)                                \
5170 _(one_enable_disable_xtr_mode_reply)                    \
5171 _(one_enable_disable_pitr_mode_reply)                   \
5172 _(one_enable_disable_petr_mode_reply)                   \
5173 _(gpe_enable_disable_reply)                             \
5174 _(gpe_set_encap_mode_reply)                             \
5175 _(gpe_add_del_iface_reply)                              \
5176 _(gpe_add_del_native_fwd_rpath_reply)                   \
5177 _(af_packet_delete_reply)                               \
5178 _(policer_classify_set_interface_reply)                 \
5179 _(set_ipfix_exporter_reply)                             \
5180 _(set_ipfix_classify_stream_reply)                      \
5181 _(ipfix_classify_table_add_del_reply)                   \
5182 _(flow_classify_set_interface_reply)                    \
5183 _(sw_interface_span_enable_disable_reply)               \
5184 _(pg_capture_reply)                                     \
5185 _(pg_enable_disable_reply)                              \
5186 _(pg_interface_enable_disable_coalesce_reply)           \
5187 _(ip_source_and_port_range_check_add_del_reply)         \
5188 _(ip_source_and_port_range_check_interface_add_del_reply)\
5189 _(delete_subif_reply)                                   \
5190 _(l2_interface_pbb_tag_rewrite_reply)                   \
5191 _(set_punt_reply)                                       \
5192 _(feature_enable_disable_reply)                         \
5193 _(feature_gso_enable_disable_reply)                     \
5194 _(sw_interface_tag_add_del_reply)                       \
5195 _(sw_interface_add_del_mac_address_reply)               \
5196 _(hw_interface_set_mtu_reply)                           \
5197 _(p2p_ethernet_add_reply)                               \
5198 _(p2p_ethernet_del_reply)                               \
5199 _(tcp_configure_src_addresses_reply)                    \
5200 _(session_rule_add_del_reply)                           \
5201 _(ip_container_proxy_add_del_reply)                     \
5202 _(output_acl_set_interface_reply)                       \
5203 _(qos_record_enable_disable_reply)                      \
5204 _(flow_add_reply)
5205
5206 #define _(n)                                    \
5207     static void vl_api_##n##_t_handler          \
5208     (vl_api_##n##_t * mp)                       \
5209     {                                           \
5210         vat_main_t * vam = &vat_main;           \
5211         i32 retval = ntohl(mp->retval);         \
5212         if (vam->async_mode) {                  \
5213             vam->async_errors += (retval < 0);  \
5214         } else {                                \
5215             vam->retval = retval;               \
5216             vam->result_ready = 1;              \
5217         }                                       \
5218     }
5219 foreach_standard_reply_retval_handler;
5220 #undef _
5221
5222 #define _(n)                                    \
5223     static void vl_api_##n##_t_handler_json     \
5224     (vl_api_##n##_t * mp)                       \
5225     {                                           \
5226         vat_main_t * vam = &vat_main;           \
5227         vat_json_node_t node;                   \
5228         vat_json_init_object(&node);            \
5229         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5230         vat_json_print(vam->ofp, &node);        \
5231         vam->retval = ntohl(mp->retval);        \
5232         vam->result_ready = 1;                  \
5233     }
5234 foreach_standard_reply_retval_handler;
5235 #undef _
5236
5237 /*
5238  * Table of message reply handlers, must include boilerplate handlers
5239  * we just generated
5240  */
5241
5242 #define foreach_vpe_api_reply_msg                                       \
5243 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5244 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5245 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5246 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5247 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5248 _(CLI_REPLY, cli_reply)                                                 \
5249 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5250 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5251   sw_interface_add_del_address_reply)                                   \
5252 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5253 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5254 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5255 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5256 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5257 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5258 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5259 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5260 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5261   sw_interface_set_l2_xconnect_reply)                                   \
5262 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5263   sw_interface_set_l2_bridge_reply)                                     \
5264 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5265 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5266 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5267 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5268 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5269 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5270 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5271 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5272 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5273 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5274 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5275 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5276 _(VIRTIO_PCI_CREATE_V2_REPLY, virtio_pci_create_v2_reply)               \
5277 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5278 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5279 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5280 _(BOND_CREATE2_REPLY, bond_create2_reply)                               \
5281 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5282 _(BOND_ADD_MEMBER_REPLY, bond_add_member_reply)                         \
5283 _(BOND_DETACH_MEMBER_REPLY, bond_detach_member_reply)                   \
5284 _(SW_INTERFACE_SET_BOND_WEIGHT_REPLY, sw_interface_set_bond_weight_reply) \
5285 _(SW_BOND_INTERFACE_DETAILS, sw_bond_interface_details)                 \
5286 _(SW_MEMBER_INTERFACE_DETAILS, sw_member_interface_details)               \
5287 _(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply)                       \
5288 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5289 _(IP_TABLE_REPLACE_BEGIN_REPLY, ip_table_replace_begin_reply)           \
5290 _(IP_TABLE_FLUSH_REPLY, ip_table_flush_reply)                           \
5291 _(IP_TABLE_REPLACE_END_REPLY, ip_table_replace_end_reply)               \
5292 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5293 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5294 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5295 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5296 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5297 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5298 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5299 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5300   sw_interface_set_unnumbered_reply)                                    \
5301 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5302 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5303 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5304 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5305   sw_interface_ip6_enable_disable_reply)                                \
5306 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5307 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5308 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5309 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5310 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5311 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5312 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5313 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5314 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5315 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5316 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5317 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5318 classify_set_interface_ip_table_reply)                                  \
5319 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5320   classify_set_interface_l2_tables_reply)                               \
5321 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5322 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5323 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5324 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5325 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5326   l2tpv3_interface_enable_disable_reply)                                \
5327 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5328 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5329 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5330 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5331 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5332 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5333 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5334 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5335 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5336 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5337 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5338 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5339 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5340 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5341 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5342 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5343 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5344 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5345 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5346 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5347 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5348 _(L2_MACS_EVENT, l2_macs_event)                                         \
5349 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5350 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5351 _(IP_DETAILS, ip_details)                                               \
5352 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5353 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5354 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5355 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5356 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5357 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5358 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5359 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5360 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5361 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5362 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5363 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5364 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5365 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5366 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5367 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5368 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5369 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5370 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5371 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5372 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5373 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5374 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5375 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5376 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5377 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5378 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5379 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5380   one_map_register_enable_disable_reply)                                \
5381 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5382 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5383 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5384 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5385   one_map_register_fallback_threshold_reply)                            \
5386 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5387   one_rloc_probe_enable_disable_reply)                                  \
5388 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5389 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5390 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5391 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5392 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5393 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5394 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5395 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5396 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5397 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5398 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5399 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5400 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5401 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5402 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5403 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5404   show_one_stats_enable_disable_reply)                                  \
5405 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5406 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5407 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5408 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5409 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5410 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5411 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5412 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5413   one_enable_disable_pitr_mode_reply)                                   \
5414 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5415   one_enable_disable_petr_mode_reply)                                   \
5416 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5417 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5418 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5419 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5420 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5421 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5422 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5423 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5424 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5425 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5426 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5427 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5428   gpe_add_del_native_fwd_rpath_reply)                                   \
5429 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5430   gpe_fwd_entry_path_details)                                           \
5431 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5432 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5433   one_add_del_map_request_itr_rlocs_reply)                              \
5434 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5435   one_get_map_request_itr_rlocs_reply)                                  \
5436 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5437 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5438 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5439 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5440 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5441 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5442   show_one_map_register_state_reply)                                    \
5443 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5444 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5445   show_one_map_register_fallback_threshold_reply)                       \
5446 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5447 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5448 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5449 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5450 _(POLICER_DETAILS, policer_details)                                     \
5451 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5452 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5453 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5454 _(MPLS_TABLE_DETAILS, mpls_table_details)                               \
5455 _(MPLS_ROUTE_DETAILS, mpls_route_details)                               \
5456 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5457 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5458 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5459 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5460 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5461 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5462 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5463 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5464 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5465 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5466 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5467 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5468 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5469 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5470 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5471 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5472 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5473 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5474 _(PG_INTERFACE_ENABLE_DISABLE_COALESCE_REPLY, pg_interface_enable_disable_coalesce_reply) \
5475 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5476  ip_source_and_port_range_check_add_del_reply)                          \
5477 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5478  ip_source_and_port_range_check_interface_add_del_reply)                \
5479 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5480 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5481 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5482 _(IP_TABLE_DETAILS, ip_table_details)                                   \
5483 _(IP_ROUTE_DETAILS, ip_route_details)                                   \
5484 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5485 _(FEATURE_GSO_ENABLE_DISABLE_REPLY, feature_gso_enable_disable_reply)   \
5486 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5487 _(SW_INTERFACE_ADD_DEL_MAC_ADDRESS_REPLY, sw_interface_add_del_mac_address_reply) \
5488 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5489 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5490 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5491 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5492 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5493 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5494 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5495 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5496 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5497 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5498 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5499 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)             \
5500 _(FLOW_ADD_REPLY, flow_add_reply)   \
5501
5502 #define foreach_standalone_reply_msg                                    \
5503 _(SW_INTERFACE_EVENT, sw_interface_event)
5504
5505 typedef struct
5506 {
5507   u8 *name;
5508   u32 value;
5509 } name_sort_t;
5510
5511 #define STR_VTR_OP_CASE(op)     \
5512     case L2_VTR_ ## op:         \
5513         return "" # op;
5514
5515 static const char *
5516 str_vtr_op (u32 vtr_op)
5517 {
5518   switch (vtr_op)
5519     {
5520       STR_VTR_OP_CASE (DISABLED);
5521       STR_VTR_OP_CASE (PUSH_1);
5522       STR_VTR_OP_CASE (PUSH_2);
5523       STR_VTR_OP_CASE (POP_1);
5524       STR_VTR_OP_CASE (POP_2);
5525       STR_VTR_OP_CASE (TRANSLATE_1_1);
5526       STR_VTR_OP_CASE (TRANSLATE_1_2);
5527       STR_VTR_OP_CASE (TRANSLATE_2_1);
5528       STR_VTR_OP_CASE (TRANSLATE_2_2);
5529     }
5530
5531   return "UNKNOWN";
5532 }
5533
5534 static int
5535 dump_sub_interface_table (vat_main_t * vam)
5536 {
5537   const sw_interface_subif_t *sub = NULL;
5538
5539   if (vam->json_output)
5540     {
5541       clib_warning
5542         ("JSON output supported only for VPE API calls and dump_stats_table");
5543       return -99;
5544     }
5545
5546   print (vam->ofp,
5547          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5548          "Interface", "sw_if_index",
5549          "sub id", "dot1ad", "tags", "outer id",
5550          "inner id", "exact", "default", "outer any", "inner any");
5551
5552   vec_foreach (sub, vam->sw_if_subif_table)
5553   {
5554     print (vam->ofp,
5555            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5556            sub->interface_name,
5557            sub->sw_if_index,
5558            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5559            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5560            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5561            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5562     if (sub->vtr_op != L2_VTR_DISABLED)
5563       {
5564         print (vam->ofp,
5565                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5566                "tag1: %d tag2: %d ]",
5567                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5568                sub->vtr_tag1, sub->vtr_tag2);
5569       }
5570   }
5571
5572   return 0;
5573 }
5574
5575 static int
5576 name_sort_cmp (void *a1, void *a2)
5577 {
5578   name_sort_t *n1 = a1;
5579   name_sort_t *n2 = a2;
5580
5581   return strcmp ((char *) n1->name, (char *) n2->name);
5582 }
5583
5584 static int
5585 dump_interface_table (vat_main_t * vam)
5586 {
5587   hash_pair_t *p;
5588   name_sort_t *nses = 0, *ns;
5589
5590   if (vam->json_output)
5591     {
5592       clib_warning
5593         ("JSON output supported only for VPE API calls and dump_stats_table");
5594       return -99;
5595     }
5596
5597   /* *INDENT-OFF* */
5598   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5599   ({
5600     vec_add2 (nses, ns, 1);
5601     ns->name = (u8 *)(p->key);
5602     ns->value = (u32) p->value[0];
5603   }));
5604   /* *INDENT-ON* */
5605
5606   vec_sort_with_function (nses, name_sort_cmp);
5607
5608   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5609   vec_foreach (ns, nses)
5610   {
5611     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5612   }
5613   vec_free (nses);
5614   return 0;
5615 }
5616
5617 static int
5618 dump_ip_table (vat_main_t * vam, int is_ipv6)
5619 {
5620   const ip_details_t *det = NULL;
5621   const ip_address_details_t *address = NULL;
5622   u32 i = ~0;
5623
5624   print (vam->ofp, "%-12s", "sw_if_index");
5625
5626   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5627   {
5628     i++;
5629     if (!det->present)
5630       {
5631         continue;
5632       }
5633     print (vam->ofp, "%-12d", i);
5634     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5635     if (!det->addr)
5636       {
5637         continue;
5638       }
5639     vec_foreach (address, det->addr)
5640     {
5641       print (vam->ofp,
5642              "            %-30U%-13d",
5643              is_ipv6 ? format_ip6_address : format_ip4_address,
5644              address->ip, address->prefix_length);
5645     }
5646   }
5647
5648   return 0;
5649 }
5650
5651 static int
5652 dump_ipv4_table (vat_main_t * vam)
5653 {
5654   if (vam->json_output)
5655     {
5656       clib_warning
5657         ("JSON output supported only for VPE API calls and dump_stats_table");
5658       return -99;
5659     }
5660
5661   return dump_ip_table (vam, 0);
5662 }
5663
5664 static int
5665 dump_ipv6_table (vat_main_t * vam)
5666 {
5667   if (vam->json_output)
5668     {
5669       clib_warning
5670         ("JSON output supported only for VPE API calls and dump_stats_table");
5671       return -99;
5672     }
5673
5674   return dump_ip_table (vam, 1);
5675 }
5676
5677 /*
5678  * Pass CLI buffers directly in the CLI_INBAND API message,
5679  * instead of an additional shared memory area.
5680  */
5681 static int
5682 exec_inband (vat_main_t * vam)
5683 {
5684   vl_api_cli_inband_t *mp;
5685   unformat_input_t *i = vam->input;
5686   int ret;
5687
5688   if (vec_len (i->buffer) == 0)
5689     return -1;
5690
5691   if (vam->exec_mode == 0 && unformat (i, "mode"))
5692     {
5693       vam->exec_mode = 1;
5694       return 0;
5695     }
5696   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5697     {
5698       vam->exec_mode = 0;
5699       return 0;
5700     }
5701
5702   /*
5703    * In order for the CLI command to work, it
5704    * must be a vector ending in \n, not a C-string ending
5705    * in \n\0.
5706    */
5707   M2 (CLI_INBAND, mp, vec_len (vam->input->buffer));
5708   vl_api_vec_to_api_string (vam->input->buffer, &mp->cmd);
5709
5710   S (mp);
5711   W (ret);
5712   /* json responses may or may not include a useful reply... */
5713   if (vec_len (vam->cmd_reply))
5714     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5715   return ret;
5716 }
5717
5718 int
5719 exec (vat_main_t * vam)
5720 {
5721   return exec_inband (vam);
5722 }
5723
5724 static int
5725 api_create_loopback (vat_main_t * vam)
5726 {
5727   unformat_input_t *i = vam->input;
5728   vl_api_create_loopback_t *mp;
5729   vl_api_create_loopback_instance_t *mp_lbi;
5730   u8 mac_address[6];
5731   u8 mac_set = 0;
5732   u8 is_specified = 0;
5733   u32 user_instance = 0;
5734   int ret;
5735
5736   clib_memset (mac_address, 0, sizeof (mac_address));
5737
5738   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5739     {
5740       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5741         mac_set = 1;
5742       if (unformat (i, "instance %d", &user_instance))
5743         is_specified = 1;
5744       else
5745         break;
5746     }
5747
5748   if (is_specified)
5749     {
5750       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5751       mp_lbi->is_specified = is_specified;
5752       if (is_specified)
5753         mp_lbi->user_instance = htonl (user_instance);
5754       if (mac_set)
5755         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5756       S (mp_lbi);
5757     }
5758   else
5759     {
5760       /* Construct the API message */
5761       M (CREATE_LOOPBACK, mp);
5762       if (mac_set)
5763         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5764       S (mp);
5765     }
5766
5767   W (ret);
5768   return ret;
5769 }
5770
5771 static int
5772 api_delete_loopback (vat_main_t * vam)
5773 {
5774   unformat_input_t *i = vam->input;
5775   vl_api_delete_loopback_t *mp;
5776   u32 sw_if_index = ~0;
5777   int ret;
5778
5779   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5780     {
5781       if (unformat (i, "sw_if_index %d", &sw_if_index))
5782         ;
5783       else
5784         break;
5785     }
5786
5787   if (sw_if_index == ~0)
5788     {
5789       errmsg ("missing sw_if_index");
5790       return -99;
5791     }
5792
5793   /* Construct the API message */
5794   M (DELETE_LOOPBACK, mp);
5795   mp->sw_if_index = ntohl (sw_if_index);
5796
5797   S (mp);
5798   W (ret);
5799   return ret;
5800 }
5801
5802 static int
5803 api_want_interface_events (vat_main_t * vam)
5804 {
5805   unformat_input_t *i = vam->input;
5806   vl_api_want_interface_events_t *mp;
5807   int enable = -1;
5808   int ret;
5809
5810   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5811     {
5812       if (unformat (i, "enable"))
5813         enable = 1;
5814       else if (unformat (i, "disable"))
5815         enable = 0;
5816       else
5817         break;
5818     }
5819
5820   if (enable == -1)
5821     {
5822       errmsg ("missing enable|disable");
5823       return -99;
5824     }
5825
5826   M (WANT_INTERFACE_EVENTS, mp);
5827   mp->enable_disable = enable;
5828
5829   vam->interface_event_display = enable;
5830
5831   S (mp);
5832   W (ret);
5833   return ret;
5834 }
5835
5836
5837 /* Note: non-static, called once to set up the initial intfc table */
5838 int
5839 api_sw_interface_dump (vat_main_t * vam)
5840 {
5841   vl_api_sw_interface_dump_t *mp;
5842   vl_api_control_ping_t *mp_ping;
5843   hash_pair_t *p;
5844   name_sort_t *nses = 0, *ns;
5845   sw_interface_subif_t *sub = NULL;
5846   int ret;
5847
5848   /* Toss the old name table */
5849   /* *INDENT-OFF* */
5850   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5851   ({
5852     vec_add2 (nses, ns, 1);
5853     ns->name = (u8 *)(p->key);
5854     ns->value = (u32) p->value[0];
5855   }));
5856   /* *INDENT-ON* */
5857
5858   hash_free (vam->sw_if_index_by_interface_name);
5859
5860   vec_foreach (ns, nses) vec_free (ns->name);
5861
5862   vec_free (nses);
5863
5864   vec_foreach (sub, vam->sw_if_subif_table)
5865   {
5866     vec_free (sub->interface_name);
5867   }
5868   vec_free (vam->sw_if_subif_table);
5869
5870   /* recreate the interface name hash table */
5871   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5872
5873   /*
5874    * Ask for all interface names. Otherwise, the epic catalog of
5875    * name filters becomes ridiculously long, and vat ends up needing
5876    * to be taught about new interface types.
5877    */
5878   M (SW_INTERFACE_DUMP, mp);
5879   S (mp);
5880
5881   /* Use a control ping for synchronization */
5882   MPING (CONTROL_PING, mp_ping);
5883   S (mp_ping);
5884
5885   W (ret);
5886   return ret;
5887 }
5888
5889 static int
5890 api_sw_interface_set_flags (vat_main_t * vam)
5891 {
5892   unformat_input_t *i = vam->input;
5893   vl_api_sw_interface_set_flags_t *mp;
5894   u32 sw_if_index;
5895   u8 sw_if_index_set = 0;
5896   u8 admin_up = 0;
5897   int ret;
5898
5899   /* Parse args required to build the message */
5900   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5901     {
5902       if (unformat (i, "admin-up"))
5903         admin_up = 1;
5904       else if (unformat (i, "admin-down"))
5905         admin_up = 0;
5906       else
5907         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5908         sw_if_index_set = 1;
5909       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5910         sw_if_index_set = 1;
5911       else
5912         break;
5913     }
5914
5915   if (sw_if_index_set == 0)
5916     {
5917       errmsg ("missing interface name or sw_if_index");
5918       return -99;
5919     }
5920
5921   /* Construct the API message */
5922   M (SW_INTERFACE_SET_FLAGS, mp);
5923   mp->sw_if_index = ntohl (sw_if_index);
5924   mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
5925
5926   /* send it... */
5927   S (mp);
5928
5929   /* Wait for a reply, return the good/bad news... */
5930   W (ret);
5931   return ret;
5932 }
5933
5934 static int
5935 api_sw_interface_set_rx_mode (vat_main_t * vam)
5936 {
5937   unformat_input_t *i = vam->input;
5938   vl_api_sw_interface_set_rx_mode_t *mp;
5939   u32 sw_if_index;
5940   u8 sw_if_index_set = 0;
5941   int ret;
5942   u8 queue_id_valid = 0;
5943   u32 queue_id;
5944   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
5945
5946   /* Parse args required to build the message */
5947   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5948     {
5949       if (unformat (i, "queue %d", &queue_id))
5950         queue_id_valid = 1;
5951       else if (unformat (i, "polling"))
5952         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
5953       else if (unformat (i, "interrupt"))
5954         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
5955       else if (unformat (i, "adaptive"))
5956         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
5957       else
5958         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5959         sw_if_index_set = 1;
5960       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5961         sw_if_index_set = 1;
5962       else
5963         break;
5964     }
5965
5966   if (sw_if_index_set == 0)
5967     {
5968       errmsg ("missing interface name or sw_if_index");
5969       return -99;
5970     }
5971   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
5972     {
5973       errmsg ("missing rx-mode");
5974       return -99;
5975     }
5976
5977   /* Construct the API message */
5978   M (SW_INTERFACE_SET_RX_MODE, mp);
5979   mp->sw_if_index = ntohl (sw_if_index);
5980   mp->mode = (vl_api_rx_mode_t) mode;
5981   mp->queue_id_valid = queue_id_valid;
5982   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
5983
5984   /* send it... */
5985   S (mp);
5986
5987   /* Wait for a reply, return the good/bad news... */
5988   W (ret);
5989   return ret;
5990 }
5991
5992 static int
5993 api_sw_interface_set_rx_placement (vat_main_t * vam)
5994 {
5995   unformat_input_t *i = vam->input;
5996   vl_api_sw_interface_set_rx_placement_t *mp;
5997   u32 sw_if_index;
5998   u8 sw_if_index_set = 0;
5999   int ret;
6000   u8 is_main = 0;
6001   u32 queue_id, thread_index;
6002
6003   /* Parse args required to build the message */
6004   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6005     {
6006       if (unformat (i, "queue %d", &queue_id))
6007         ;
6008       else if (unformat (i, "main"))
6009         is_main = 1;
6010       else if (unformat (i, "worker %d", &thread_index))
6011         ;
6012       else
6013         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6014         sw_if_index_set = 1;
6015       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6016         sw_if_index_set = 1;
6017       else
6018         break;
6019     }
6020
6021   if (sw_if_index_set == 0)
6022     {
6023       errmsg ("missing interface name or sw_if_index");
6024       return -99;
6025     }
6026
6027   if (is_main)
6028     thread_index = 0;
6029   /* Construct the API message */
6030   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6031   mp->sw_if_index = ntohl (sw_if_index);
6032   mp->worker_id = ntohl (thread_index);
6033   mp->queue_id = ntohl (queue_id);
6034   mp->is_main = is_main;
6035
6036   /* send it... */
6037   S (mp);
6038   /* Wait for a reply, return the good/bad news... */
6039   W (ret);
6040   return ret;
6041 }
6042
6043 static void vl_api_sw_interface_rx_placement_details_t_handler
6044   (vl_api_sw_interface_rx_placement_details_t * mp)
6045 {
6046   vat_main_t *vam = &vat_main;
6047   u32 worker_id = ntohl (mp->worker_id);
6048
6049   print (vam->ofp,
6050          "\n%-11d %-11s %-6d %-5d %-9s",
6051          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6052          worker_id, ntohl (mp->queue_id),
6053          (mp->mode ==
6054           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6055 }
6056
6057 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6058   (vl_api_sw_interface_rx_placement_details_t * mp)
6059 {
6060   vat_main_t *vam = &vat_main;
6061   vat_json_node_t *node = NULL;
6062
6063   if (VAT_JSON_ARRAY != vam->json_tree.type)
6064     {
6065       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6066       vat_json_init_array (&vam->json_tree);
6067     }
6068   node = vat_json_array_add (&vam->json_tree);
6069
6070   vat_json_init_object (node);
6071   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6072   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6073   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6074   vat_json_object_add_uint (node, "mode", mp->mode);
6075 }
6076
6077 static int
6078 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6079 {
6080   unformat_input_t *i = vam->input;
6081   vl_api_sw_interface_rx_placement_dump_t *mp;
6082   vl_api_control_ping_t *mp_ping;
6083   int ret;
6084   u32 sw_if_index;
6085   u8 sw_if_index_set = 0;
6086
6087   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6088     {
6089       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6090         sw_if_index_set++;
6091       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6092         sw_if_index_set++;
6093       else
6094         break;
6095     }
6096
6097   print (vam->ofp,
6098          "\n%-11s %-11s %-6s %-5s %-4s",
6099          "sw_if_index", "main/worker", "thread", "queue", "mode");
6100
6101   /* Dump Interface rx placement */
6102   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6103
6104   if (sw_if_index_set)
6105     mp->sw_if_index = htonl (sw_if_index);
6106   else
6107     mp->sw_if_index = ~0;
6108
6109   S (mp);
6110
6111   /* Use a control ping for synchronization */
6112   MPING (CONTROL_PING, mp_ping);
6113   S (mp_ping);
6114
6115   W (ret);
6116   return ret;
6117 }
6118
6119 static int
6120 api_sw_interface_clear_stats (vat_main_t * vam)
6121 {
6122   unformat_input_t *i = vam->input;
6123   vl_api_sw_interface_clear_stats_t *mp;
6124   u32 sw_if_index;
6125   u8 sw_if_index_set = 0;
6126   int ret;
6127
6128   /* Parse args required to build the message */
6129   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6130     {
6131       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6132         sw_if_index_set = 1;
6133       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6134         sw_if_index_set = 1;
6135       else
6136         break;
6137     }
6138
6139   /* Construct the API message */
6140   M (SW_INTERFACE_CLEAR_STATS, mp);
6141
6142   if (sw_if_index_set == 1)
6143     mp->sw_if_index = ntohl (sw_if_index);
6144   else
6145     mp->sw_if_index = ~0;
6146
6147   /* send it... */
6148   S (mp);
6149
6150   /* Wait for a reply, return the good/bad news... */
6151   W (ret);
6152   return ret;
6153 }
6154
6155 static int
6156 api_sw_interface_add_del_address (vat_main_t * vam)
6157 {
6158   unformat_input_t *i = vam->input;
6159   vl_api_sw_interface_add_del_address_t *mp;
6160   u32 sw_if_index;
6161   u8 sw_if_index_set = 0;
6162   u8 is_add = 1, del_all = 0;
6163   u32 address_length = 0;
6164   u8 v4_address_set = 0;
6165   u8 v6_address_set = 0;
6166   ip4_address_t v4address;
6167   ip6_address_t v6address;
6168   int ret;
6169
6170   /* Parse args required to build the message */
6171   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6172     {
6173       if (unformat (i, "del-all"))
6174         del_all = 1;
6175       else if (unformat (i, "del"))
6176         is_add = 0;
6177       else
6178         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6179         sw_if_index_set = 1;
6180       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6181         sw_if_index_set = 1;
6182       else if (unformat (i, "%U/%d",
6183                          unformat_ip4_address, &v4address, &address_length))
6184         v4_address_set = 1;
6185       else if (unformat (i, "%U/%d",
6186                          unformat_ip6_address, &v6address, &address_length))
6187         v6_address_set = 1;
6188       else
6189         break;
6190     }
6191
6192   if (sw_if_index_set == 0)
6193     {
6194       errmsg ("missing interface name or sw_if_index");
6195       return -99;
6196     }
6197   if (v4_address_set && v6_address_set)
6198     {
6199       errmsg ("both v4 and v6 addresses set");
6200       return -99;
6201     }
6202   if (!v4_address_set && !v6_address_set && !del_all)
6203     {
6204       errmsg ("no addresses set");
6205       return -99;
6206     }
6207
6208   /* Construct the API message */
6209   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6210
6211   mp->sw_if_index = ntohl (sw_if_index);
6212   mp->is_add = is_add;
6213   mp->del_all = del_all;
6214   if (v6_address_set)
6215     {
6216       mp->prefix.address.af = ADDRESS_IP6;
6217       clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
6218     }
6219   else
6220     {
6221       mp->prefix.address.af = ADDRESS_IP4;
6222       clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
6223     }
6224   mp->prefix.len = address_length;
6225
6226   /* send it... */
6227   S (mp);
6228
6229   /* Wait for a reply, return good/bad news  */
6230   W (ret);
6231   return ret;
6232 }
6233
6234 static int
6235 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6236 {
6237   unformat_input_t *i = vam->input;
6238   vl_api_sw_interface_set_mpls_enable_t *mp;
6239   u32 sw_if_index;
6240   u8 sw_if_index_set = 0;
6241   u8 enable = 1;
6242   int ret;
6243
6244   /* Parse args required to build the message */
6245   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6246     {
6247       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6248         sw_if_index_set = 1;
6249       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6250         sw_if_index_set = 1;
6251       else if (unformat (i, "disable"))
6252         enable = 0;
6253       else if (unformat (i, "dis"))
6254         enable = 0;
6255       else
6256         break;
6257     }
6258
6259   if (sw_if_index_set == 0)
6260     {
6261       errmsg ("missing interface name or sw_if_index");
6262       return -99;
6263     }
6264
6265   /* Construct the API message */
6266   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6267
6268   mp->sw_if_index = ntohl (sw_if_index);
6269   mp->enable = enable;
6270
6271   /* send it... */
6272   S (mp);
6273
6274   /* Wait for a reply... */
6275   W (ret);
6276   return ret;
6277 }
6278
6279 static int
6280 api_sw_interface_set_table (vat_main_t * vam)
6281 {
6282   unformat_input_t *i = vam->input;
6283   vl_api_sw_interface_set_table_t *mp;
6284   u32 sw_if_index, vrf_id = 0;
6285   u8 sw_if_index_set = 0;
6286   u8 is_ipv6 = 0;
6287   int ret;
6288
6289   /* Parse args required to build the message */
6290   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6291     {
6292       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6293         sw_if_index_set = 1;
6294       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6295         sw_if_index_set = 1;
6296       else if (unformat (i, "vrf %d", &vrf_id))
6297         ;
6298       else if (unformat (i, "ipv6"))
6299         is_ipv6 = 1;
6300       else
6301         break;
6302     }
6303
6304   if (sw_if_index_set == 0)
6305     {
6306       errmsg ("missing interface name or sw_if_index");
6307       return -99;
6308     }
6309
6310   /* Construct the API message */
6311   M (SW_INTERFACE_SET_TABLE, mp);
6312
6313   mp->sw_if_index = ntohl (sw_if_index);
6314   mp->is_ipv6 = is_ipv6;
6315   mp->vrf_id = ntohl (vrf_id);
6316
6317   /* send it... */
6318   S (mp);
6319
6320   /* Wait for a reply... */
6321   W (ret);
6322   return ret;
6323 }
6324
6325 static void vl_api_sw_interface_get_table_reply_t_handler
6326   (vl_api_sw_interface_get_table_reply_t * mp)
6327 {
6328   vat_main_t *vam = &vat_main;
6329
6330   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6331
6332   vam->retval = ntohl (mp->retval);
6333   vam->result_ready = 1;
6334
6335 }
6336
6337 static void vl_api_sw_interface_get_table_reply_t_handler_json
6338   (vl_api_sw_interface_get_table_reply_t * mp)
6339 {
6340   vat_main_t *vam = &vat_main;
6341   vat_json_node_t node;
6342
6343   vat_json_init_object (&node);
6344   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6345   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6346
6347   vat_json_print (vam->ofp, &node);
6348   vat_json_free (&node);
6349
6350   vam->retval = ntohl (mp->retval);
6351   vam->result_ready = 1;
6352 }
6353
6354 static int
6355 api_sw_interface_get_table (vat_main_t * vam)
6356 {
6357   unformat_input_t *i = vam->input;
6358   vl_api_sw_interface_get_table_t *mp;
6359   u32 sw_if_index;
6360   u8 sw_if_index_set = 0;
6361   u8 is_ipv6 = 0;
6362   int ret;
6363
6364   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6365     {
6366       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6367         sw_if_index_set = 1;
6368       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6369         sw_if_index_set = 1;
6370       else if (unformat (i, "ipv6"))
6371         is_ipv6 = 1;
6372       else
6373         break;
6374     }
6375
6376   if (sw_if_index_set == 0)
6377     {
6378       errmsg ("missing interface name or sw_if_index");
6379       return -99;
6380     }
6381
6382   M (SW_INTERFACE_GET_TABLE, mp);
6383   mp->sw_if_index = htonl (sw_if_index);
6384   mp->is_ipv6 = is_ipv6;
6385
6386   S (mp);
6387   W (ret);
6388   return ret;
6389 }
6390
6391 static int
6392 api_sw_interface_set_vpath (vat_main_t * vam)
6393 {
6394   unformat_input_t *i = vam->input;
6395   vl_api_sw_interface_set_vpath_t *mp;
6396   u32 sw_if_index = 0;
6397   u8 sw_if_index_set = 0;
6398   u8 is_enable = 0;
6399   int ret;
6400
6401   /* Parse args required to build the message */
6402   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6403     {
6404       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6405         sw_if_index_set = 1;
6406       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6407         sw_if_index_set = 1;
6408       else if (unformat (i, "enable"))
6409         is_enable = 1;
6410       else if (unformat (i, "disable"))
6411         is_enable = 0;
6412       else
6413         break;
6414     }
6415
6416   if (sw_if_index_set == 0)
6417     {
6418       errmsg ("missing interface name or sw_if_index");
6419       return -99;
6420     }
6421
6422   /* Construct the API message */
6423   M (SW_INTERFACE_SET_VPATH, mp);
6424
6425   mp->sw_if_index = ntohl (sw_if_index);
6426   mp->enable = is_enable;
6427
6428   /* send it... */
6429   S (mp);
6430
6431   /* Wait for a reply... */
6432   W (ret);
6433   return ret;
6434 }
6435
6436 static int
6437 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6438 {
6439   unformat_input_t *i = vam->input;
6440   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6441   u32 sw_if_index = 0;
6442   u8 sw_if_index_set = 0;
6443   u8 is_enable = 1;
6444   u8 is_ipv6 = 0;
6445   int ret;
6446
6447   /* Parse args required to build the message */
6448   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6449     {
6450       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6451         sw_if_index_set = 1;
6452       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6453         sw_if_index_set = 1;
6454       else if (unformat (i, "enable"))
6455         is_enable = 1;
6456       else if (unformat (i, "disable"))
6457         is_enable = 0;
6458       else if (unformat (i, "ip4"))
6459         is_ipv6 = 0;
6460       else if (unformat (i, "ip6"))
6461         is_ipv6 = 1;
6462       else
6463         break;
6464     }
6465
6466   if (sw_if_index_set == 0)
6467     {
6468       errmsg ("missing interface name or sw_if_index");
6469       return -99;
6470     }
6471
6472   /* Construct the API message */
6473   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6474
6475   mp->sw_if_index = ntohl (sw_if_index);
6476   mp->enable = is_enable;
6477   mp->is_ipv6 = is_ipv6;
6478
6479   /* send it... */
6480   S (mp);
6481
6482   /* Wait for a reply... */
6483   W (ret);
6484   return ret;
6485 }
6486
6487 static int
6488 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6489 {
6490   unformat_input_t *i = vam->input;
6491   vl_api_sw_interface_set_l2_xconnect_t *mp;
6492   u32 rx_sw_if_index;
6493   u8 rx_sw_if_index_set = 0;
6494   u32 tx_sw_if_index;
6495   u8 tx_sw_if_index_set = 0;
6496   u8 enable = 1;
6497   int ret;
6498
6499   /* Parse args required to build the message */
6500   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6501     {
6502       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6503         rx_sw_if_index_set = 1;
6504       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6505         tx_sw_if_index_set = 1;
6506       else if (unformat (i, "rx"))
6507         {
6508           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6509             {
6510               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6511                             &rx_sw_if_index))
6512                 rx_sw_if_index_set = 1;
6513             }
6514           else
6515             break;
6516         }
6517       else if (unformat (i, "tx"))
6518         {
6519           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6520             {
6521               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6522                             &tx_sw_if_index))
6523                 tx_sw_if_index_set = 1;
6524             }
6525           else
6526             break;
6527         }
6528       else if (unformat (i, "enable"))
6529         enable = 1;
6530       else if (unformat (i, "disable"))
6531         enable = 0;
6532       else
6533         break;
6534     }
6535
6536   if (rx_sw_if_index_set == 0)
6537     {
6538       errmsg ("missing rx interface name or rx_sw_if_index");
6539       return -99;
6540     }
6541
6542   if (enable && (tx_sw_if_index_set == 0))
6543     {
6544       errmsg ("missing tx interface name or tx_sw_if_index");
6545       return -99;
6546     }
6547
6548   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6549
6550   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6551   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6552   mp->enable = enable;
6553
6554   S (mp);
6555   W (ret);
6556   return ret;
6557 }
6558
6559 static int
6560 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6561 {
6562   unformat_input_t *i = vam->input;
6563   vl_api_sw_interface_set_l2_bridge_t *mp;
6564   vl_api_l2_port_type_t port_type;
6565   u32 rx_sw_if_index;
6566   u8 rx_sw_if_index_set = 0;
6567   u32 bd_id;
6568   u8 bd_id_set = 0;
6569   u32 shg = 0;
6570   u8 enable = 1;
6571   int ret;
6572
6573   port_type = L2_API_PORT_TYPE_NORMAL;
6574
6575   /* Parse args required to build the message */
6576   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6577     {
6578       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6579         rx_sw_if_index_set = 1;
6580       else if (unformat (i, "bd_id %d", &bd_id))
6581         bd_id_set = 1;
6582       else
6583         if (unformat
6584             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6585         rx_sw_if_index_set = 1;
6586       else if (unformat (i, "shg %d", &shg))
6587         ;
6588       else if (unformat (i, "bvi"))
6589         port_type = L2_API_PORT_TYPE_BVI;
6590       else if (unformat (i, "uu-fwd"))
6591         port_type = L2_API_PORT_TYPE_UU_FWD;
6592       else if (unformat (i, "enable"))
6593         enable = 1;
6594       else if (unformat (i, "disable"))
6595         enable = 0;
6596       else
6597         break;
6598     }
6599
6600   if (rx_sw_if_index_set == 0)
6601     {
6602       errmsg ("missing rx interface name or sw_if_index");
6603       return -99;
6604     }
6605
6606   if (enable && (bd_id_set == 0))
6607     {
6608       errmsg ("missing bridge domain");
6609       return -99;
6610     }
6611
6612   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6613
6614   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6615   mp->bd_id = ntohl (bd_id);
6616   mp->shg = (u8) shg;
6617   mp->port_type = ntohl (port_type);
6618   mp->enable = enable;
6619
6620   S (mp);
6621   W (ret);
6622   return ret;
6623 }
6624
6625 static int
6626 api_bridge_domain_dump (vat_main_t * vam)
6627 {
6628   unformat_input_t *i = vam->input;
6629   vl_api_bridge_domain_dump_t *mp;
6630   vl_api_control_ping_t *mp_ping;
6631   u32 bd_id = ~0;
6632   int ret;
6633
6634   /* Parse args required to build the message */
6635   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6636     {
6637       if (unformat (i, "bd_id %d", &bd_id))
6638         ;
6639       else
6640         break;
6641     }
6642
6643   M (BRIDGE_DOMAIN_DUMP, mp);
6644   mp->bd_id = ntohl (bd_id);
6645   S (mp);
6646
6647   /* Use a control ping for synchronization */
6648   MPING (CONTROL_PING, mp_ping);
6649   S (mp_ping);
6650
6651   W (ret);
6652   return ret;
6653 }
6654
6655 static int
6656 api_bridge_domain_add_del (vat_main_t * vam)
6657 {
6658   unformat_input_t *i = vam->input;
6659   vl_api_bridge_domain_add_del_t *mp;
6660   u32 bd_id = ~0;
6661   u8 is_add = 1;
6662   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6663   u8 *bd_tag = NULL;
6664   u32 mac_age = 0;
6665   int ret;
6666
6667   /* Parse args required to build the message */
6668   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6669     {
6670       if (unformat (i, "bd_id %d", &bd_id))
6671         ;
6672       else if (unformat (i, "flood %d", &flood))
6673         ;
6674       else if (unformat (i, "uu-flood %d", &uu_flood))
6675         ;
6676       else if (unformat (i, "forward %d", &forward))
6677         ;
6678       else if (unformat (i, "learn %d", &learn))
6679         ;
6680       else if (unformat (i, "arp-term %d", &arp_term))
6681         ;
6682       else if (unformat (i, "mac-age %d", &mac_age))
6683         ;
6684       else if (unformat (i, "bd-tag %s", &bd_tag))
6685         ;
6686       else if (unformat (i, "del"))
6687         {
6688           is_add = 0;
6689           flood = uu_flood = forward = learn = 0;
6690         }
6691       else
6692         break;
6693     }
6694
6695   if (bd_id == ~0)
6696     {
6697       errmsg ("missing bridge domain");
6698       ret = -99;
6699       goto done;
6700     }
6701
6702   if (mac_age > 255)
6703     {
6704       errmsg ("mac age must be less than 256 ");
6705       ret = -99;
6706       goto done;
6707     }
6708
6709   if ((bd_tag) && (vec_len (bd_tag) > 63))
6710     {
6711       errmsg ("bd-tag cannot be longer than 63");
6712       ret = -99;
6713       goto done;
6714     }
6715
6716   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6717
6718   mp->bd_id = ntohl (bd_id);
6719   mp->flood = flood;
6720   mp->uu_flood = uu_flood;
6721   mp->forward = forward;
6722   mp->learn = learn;
6723   mp->arp_term = arp_term;
6724   mp->is_add = is_add;
6725   mp->mac_age = (u8) mac_age;
6726   if (bd_tag)
6727     {
6728       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6729       mp->bd_tag[vec_len (bd_tag)] = 0;
6730     }
6731   S (mp);
6732   W (ret);
6733
6734 done:
6735   vec_free (bd_tag);
6736   return ret;
6737 }
6738
6739 static int
6740 api_l2fib_flush_bd (vat_main_t * vam)
6741 {
6742   unformat_input_t *i = vam->input;
6743   vl_api_l2fib_flush_bd_t *mp;
6744   u32 bd_id = ~0;
6745   int ret;
6746
6747   /* Parse args required to build the message */
6748   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6749     {
6750       if (unformat (i, "bd_id %d", &bd_id));
6751       else
6752         break;
6753     }
6754
6755   if (bd_id == ~0)
6756     {
6757       errmsg ("missing bridge domain");
6758       return -99;
6759     }
6760
6761   M (L2FIB_FLUSH_BD, mp);
6762
6763   mp->bd_id = htonl (bd_id);
6764
6765   S (mp);
6766   W (ret);
6767   return ret;
6768 }
6769
6770 static int
6771 api_l2fib_flush_int (vat_main_t * vam)
6772 {
6773   unformat_input_t *i = vam->input;
6774   vl_api_l2fib_flush_int_t *mp;
6775   u32 sw_if_index = ~0;
6776   int ret;
6777
6778   /* Parse args required to build the message */
6779   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6780     {
6781       if (unformat (i, "sw_if_index %d", &sw_if_index));
6782       else
6783         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6784       else
6785         break;
6786     }
6787
6788   if (sw_if_index == ~0)
6789     {
6790       errmsg ("missing interface name or sw_if_index");
6791       return -99;
6792     }
6793
6794   M (L2FIB_FLUSH_INT, mp);
6795
6796   mp->sw_if_index = ntohl (sw_if_index);
6797
6798   S (mp);
6799   W (ret);
6800   return ret;
6801 }
6802
6803 static int
6804 api_l2fib_add_del (vat_main_t * vam)
6805 {
6806   unformat_input_t *i = vam->input;
6807   vl_api_l2fib_add_del_t *mp;
6808   f64 timeout;
6809   u8 mac[6] = { 0 };
6810   u8 mac_set = 0;
6811   u32 bd_id;
6812   u8 bd_id_set = 0;
6813   u32 sw_if_index = 0;
6814   u8 sw_if_index_set = 0;
6815   u8 is_add = 1;
6816   u8 static_mac = 0;
6817   u8 filter_mac = 0;
6818   u8 bvi_mac = 0;
6819   int count = 1;
6820   f64 before = 0;
6821   int j;
6822
6823   /* Parse args required to build the message */
6824   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6825     {
6826       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6827         mac_set = 1;
6828       else if (unformat (i, "bd_id %d", &bd_id))
6829         bd_id_set = 1;
6830       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6831         sw_if_index_set = 1;
6832       else if (unformat (i, "sw_if"))
6833         {
6834           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6835             {
6836               if (unformat
6837                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6838                 sw_if_index_set = 1;
6839             }
6840           else
6841             break;
6842         }
6843       else if (unformat (i, "static"))
6844         static_mac = 1;
6845       else if (unformat (i, "filter"))
6846         {
6847           filter_mac = 1;
6848           static_mac = 1;
6849         }
6850       else if (unformat (i, "bvi"))
6851         {
6852           bvi_mac = 1;
6853           static_mac = 1;
6854         }
6855       else if (unformat (i, "del"))
6856         is_add = 0;
6857       else if (unformat (i, "count %d", &count))
6858         ;
6859       else
6860         break;
6861     }
6862
6863   if (mac_set == 0)
6864     {
6865       errmsg ("missing mac address");
6866       return -99;
6867     }
6868
6869   if (bd_id_set == 0)
6870     {
6871       errmsg ("missing bridge domain");
6872       return -99;
6873     }
6874
6875   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6876     {
6877       errmsg ("missing interface name or sw_if_index");
6878       return -99;
6879     }
6880
6881   if (count > 1)
6882     {
6883       /* Turn on async mode */
6884       vam->async_mode = 1;
6885       vam->async_errors = 0;
6886       before = vat_time_now (vam);
6887     }
6888
6889   for (j = 0; j < count; j++)
6890     {
6891       M (L2FIB_ADD_DEL, mp);
6892
6893       clib_memcpy (mp->mac, mac, 6);
6894       mp->bd_id = ntohl (bd_id);
6895       mp->is_add = is_add;
6896       mp->sw_if_index = ntohl (sw_if_index);
6897
6898       if (is_add)
6899         {
6900           mp->static_mac = static_mac;
6901           mp->filter_mac = filter_mac;
6902           mp->bvi_mac = bvi_mac;
6903         }
6904       increment_mac_address (mac);
6905       /* send it... */
6906       S (mp);
6907     }
6908
6909   if (count > 1)
6910     {
6911       vl_api_control_ping_t *mp_ping;
6912       f64 after;
6913
6914       /* Shut off async mode */
6915       vam->async_mode = 0;
6916
6917       MPING (CONTROL_PING, mp_ping);
6918       S (mp_ping);
6919
6920       timeout = vat_time_now (vam) + 1.0;
6921       while (vat_time_now (vam) < timeout)
6922         if (vam->result_ready == 1)
6923           goto out;
6924       vam->retval = -99;
6925
6926     out:
6927       if (vam->retval == -99)
6928         errmsg ("timeout");
6929
6930       if (vam->async_errors > 0)
6931         {
6932           errmsg ("%d asynchronous errors", vam->async_errors);
6933           vam->retval = -98;
6934         }
6935       vam->async_errors = 0;
6936       after = vat_time_now (vam);
6937
6938       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6939              count, after - before, count / (after - before));
6940     }
6941   else
6942     {
6943       int ret;
6944
6945       /* Wait for a reply... */
6946       W (ret);
6947       return ret;
6948     }
6949   /* Return the good/bad news */
6950   return (vam->retval);
6951 }
6952
6953 static int
6954 api_bridge_domain_set_mac_age (vat_main_t * vam)
6955 {
6956   unformat_input_t *i = vam->input;
6957   vl_api_bridge_domain_set_mac_age_t *mp;
6958   u32 bd_id = ~0;
6959   u32 mac_age = 0;
6960   int ret;
6961
6962   /* Parse args required to build the message */
6963   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6964     {
6965       if (unformat (i, "bd_id %d", &bd_id));
6966       else if (unformat (i, "mac-age %d", &mac_age));
6967       else
6968         break;
6969     }
6970
6971   if (bd_id == ~0)
6972     {
6973       errmsg ("missing bridge domain");
6974       return -99;
6975     }
6976
6977   if (mac_age > 255)
6978     {
6979       errmsg ("mac age must be less than 256 ");
6980       return -99;
6981     }
6982
6983   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
6984
6985   mp->bd_id = htonl (bd_id);
6986   mp->mac_age = (u8) mac_age;
6987
6988   S (mp);
6989   W (ret);
6990   return ret;
6991 }
6992
6993 static int
6994 api_l2_flags (vat_main_t * vam)
6995 {
6996   unformat_input_t *i = vam->input;
6997   vl_api_l2_flags_t *mp;
6998   u32 sw_if_index;
6999   u32 flags = 0;
7000   u8 sw_if_index_set = 0;
7001   u8 is_set = 0;
7002   int ret;
7003
7004   /* Parse args required to build the message */
7005   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7006     {
7007       if (unformat (i, "sw_if_index %d", &sw_if_index))
7008         sw_if_index_set = 1;
7009       else if (unformat (i, "sw_if"))
7010         {
7011           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7012             {
7013               if (unformat
7014                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7015                 sw_if_index_set = 1;
7016             }
7017           else
7018             break;
7019         }
7020       else if (unformat (i, "learn"))
7021         flags |= L2_LEARN;
7022       else if (unformat (i, "forward"))
7023         flags |= L2_FWD;
7024       else if (unformat (i, "flood"))
7025         flags |= L2_FLOOD;
7026       else if (unformat (i, "uu-flood"))
7027         flags |= L2_UU_FLOOD;
7028       else if (unformat (i, "arp-term"))
7029         flags |= L2_ARP_TERM;
7030       else if (unformat (i, "off"))
7031         is_set = 0;
7032       else if (unformat (i, "disable"))
7033         is_set = 0;
7034       else
7035         break;
7036     }
7037
7038   if (sw_if_index_set == 0)
7039     {
7040       errmsg ("missing interface name or sw_if_index");
7041       return -99;
7042     }
7043
7044   M (L2_FLAGS, mp);
7045
7046   mp->sw_if_index = ntohl (sw_if_index);
7047   mp->feature_bitmap = ntohl (flags);
7048   mp->is_set = is_set;
7049
7050   S (mp);
7051   W (ret);
7052   return ret;
7053 }
7054
7055 static int
7056 api_bridge_flags (vat_main_t * vam)
7057 {
7058   unformat_input_t *i = vam->input;
7059   vl_api_bridge_flags_t *mp;
7060   u32 bd_id;
7061   u8 bd_id_set = 0;
7062   u8 is_set = 1;
7063   bd_flags_t flags = 0;
7064   int ret;
7065
7066   /* Parse args required to build the message */
7067   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7068     {
7069       if (unformat (i, "bd_id %d", &bd_id))
7070         bd_id_set = 1;
7071       else if (unformat (i, "learn"))
7072         flags |= BRIDGE_API_FLAG_LEARN;
7073       else if (unformat (i, "forward"))
7074         flags |= BRIDGE_API_FLAG_FWD;
7075       else if (unformat (i, "flood"))
7076         flags |= BRIDGE_API_FLAG_FLOOD;
7077       else if (unformat (i, "uu-flood"))
7078         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7079       else if (unformat (i, "arp-term"))
7080         flags |= BRIDGE_API_FLAG_ARP_TERM;
7081       else if (unformat (i, "off"))
7082         is_set = 0;
7083       else if (unformat (i, "disable"))
7084         is_set = 0;
7085       else
7086         break;
7087     }
7088
7089   if (bd_id_set == 0)
7090     {
7091       errmsg ("missing bridge domain");
7092       return -99;
7093     }
7094
7095   M (BRIDGE_FLAGS, mp);
7096
7097   mp->bd_id = ntohl (bd_id);
7098   mp->flags = ntohl (flags);
7099   mp->is_set = is_set;
7100
7101   S (mp);
7102   W (ret);
7103   return ret;
7104 }
7105
7106 static int
7107 api_bd_ip_mac_add_del (vat_main_t * vam)
7108 {
7109   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7110   vl_api_mac_address_t mac = { 0 };
7111   unformat_input_t *i = vam->input;
7112   vl_api_bd_ip_mac_add_del_t *mp;
7113   u32 bd_id;
7114   u8 is_add = 1;
7115   u8 bd_id_set = 0;
7116   u8 ip_set = 0;
7117   u8 mac_set = 0;
7118   int ret;
7119
7120
7121   /* Parse args required to build the message */
7122   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7123     {
7124       if (unformat (i, "bd_id %d", &bd_id))
7125         {
7126           bd_id_set++;
7127         }
7128       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7129         {
7130           ip_set++;
7131         }
7132       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7133         {
7134           mac_set++;
7135         }
7136       else if (unformat (i, "del"))
7137         is_add = 0;
7138       else
7139         break;
7140     }
7141
7142   if (bd_id_set == 0)
7143     {
7144       errmsg ("missing bridge domain");
7145       return -99;
7146     }
7147   else if (ip_set == 0)
7148     {
7149       errmsg ("missing IP address");
7150       return -99;
7151     }
7152   else if (mac_set == 0)
7153     {
7154       errmsg ("missing MAC address");
7155       return -99;
7156     }
7157
7158   M (BD_IP_MAC_ADD_DEL, mp);
7159
7160   mp->entry.bd_id = ntohl (bd_id);
7161   mp->is_add = is_add;
7162
7163   clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
7164   clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
7165
7166   S (mp);
7167   W (ret);
7168   return ret;
7169 }
7170
7171 static int
7172 api_bd_ip_mac_flush (vat_main_t * vam)
7173 {
7174   unformat_input_t *i = vam->input;
7175   vl_api_bd_ip_mac_flush_t *mp;
7176   u32 bd_id;
7177   u8 bd_id_set = 0;
7178   int ret;
7179
7180   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7181     {
7182       if (unformat (i, "bd_id %d", &bd_id))
7183         {
7184           bd_id_set++;
7185         }
7186       else
7187         break;
7188     }
7189
7190   if (bd_id_set == 0)
7191     {
7192       errmsg ("missing bridge domain");
7193       return -99;
7194     }
7195
7196   M (BD_IP_MAC_FLUSH, mp);
7197
7198   mp->bd_id = ntohl (bd_id);
7199
7200   S (mp);
7201   W (ret);
7202   return ret;
7203 }
7204
7205 static void vl_api_bd_ip_mac_details_t_handler
7206   (vl_api_bd_ip_mac_details_t * mp)
7207 {
7208   vat_main_t *vam = &vat_main;
7209
7210   print (vam->ofp,
7211          "\n%-5d %U %U",
7212          ntohl (mp->entry.bd_id),
7213          format_vl_api_mac_address, mp->entry.mac,
7214          format_vl_api_address, &mp->entry.ip);
7215 }
7216
7217 static void vl_api_bd_ip_mac_details_t_handler_json
7218   (vl_api_bd_ip_mac_details_t * mp)
7219 {
7220   vat_main_t *vam = &vat_main;
7221   vat_json_node_t *node = NULL;
7222
7223   if (VAT_JSON_ARRAY != vam->json_tree.type)
7224     {
7225       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7226       vat_json_init_array (&vam->json_tree);
7227     }
7228   node = vat_json_array_add (&vam->json_tree);
7229
7230   vat_json_init_object (node);
7231   vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
7232   vat_json_object_add_string_copy (node, "mac_address",
7233                                    format (0, "%U", format_vl_api_mac_address,
7234                                            &mp->entry.mac));
7235   u8 *ip = 0;
7236
7237   ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
7238   vat_json_object_add_string_copy (node, "ip_address", ip);
7239   vec_free (ip);
7240 }
7241
7242 static int
7243 api_bd_ip_mac_dump (vat_main_t * vam)
7244 {
7245   unformat_input_t *i = vam->input;
7246   vl_api_bd_ip_mac_dump_t *mp;
7247   vl_api_control_ping_t *mp_ping;
7248   int ret;
7249   u32 bd_id;
7250   u8 bd_id_set = 0;
7251
7252   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7253     {
7254       if (unformat (i, "bd_id %d", &bd_id))
7255         {
7256           bd_id_set++;
7257         }
7258       else
7259         break;
7260     }
7261
7262   print (vam->ofp,
7263          "\n%-5s %-7s %-20s %-30s",
7264          "bd_id", "is_ipv6", "mac_address", "ip_address");
7265
7266   /* Dump Bridge Domain Ip to Mac entries */
7267   M (BD_IP_MAC_DUMP, mp);
7268
7269   if (bd_id_set)
7270     mp->bd_id = htonl (bd_id);
7271   else
7272     mp->bd_id = ~0;
7273
7274   S (mp);
7275
7276   /* Use a control ping for synchronization */
7277   MPING (CONTROL_PING, mp_ping);
7278   S (mp_ping);
7279
7280   W (ret);
7281   return ret;
7282 }
7283
7284 static int
7285 api_tap_create_v2 (vat_main_t * vam)
7286 {
7287   unformat_input_t *i = vam->input;
7288   vl_api_tap_create_v2_t *mp;
7289   u8 mac_address[6];
7290   u8 random_mac = 1;
7291   u32 id = ~0;
7292   u32 num_rx_queues = 0;
7293   u8 *host_if_name = 0;
7294   u8 host_if_name_set = 0;
7295   u8 *host_ns = 0;
7296   u8 host_ns_set = 0;
7297   u8 host_mac_addr[6];
7298   u8 host_mac_addr_set = 0;
7299   u8 *host_bridge = 0;
7300   u8 host_bridge_set = 0;
7301   u8 host_ip4_prefix_set = 0;
7302   u8 host_ip6_prefix_set = 0;
7303   ip4_address_t host_ip4_addr;
7304   ip4_address_t host_ip4_gw;
7305   u8 host_ip4_gw_set = 0;
7306   u32 host_ip4_prefix_len = 0;
7307   ip6_address_t host_ip6_addr;
7308   ip6_address_t host_ip6_gw;
7309   u8 host_ip6_gw_set = 0;
7310   u32 host_ip6_prefix_len = 0;
7311   u32 host_mtu_size = 0;
7312   u8 host_mtu_set = 0;
7313   u32 tap_flags = 0;
7314   int ret;
7315   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7316
7317   clib_memset (mac_address, 0, sizeof (mac_address));
7318
7319   /* Parse args required to build the message */
7320   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7321     {
7322       if (unformat (i, "id %u", &id))
7323         ;
7324       else
7325         if (unformat
7326             (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7327         random_mac = 0;
7328       else if (unformat (i, "host-if-name %s", &host_if_name))
7329         host_if_name_set = 1;
7330       else if (unformat (i, "num-rx-queues %u", &num_rx_queues))
7331         ;
7332       else if (unformat (i, "host-ns %s", &host_ns))
7333         host_ns_set = 1;
7334       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7335                          host_mac_addr))
7336         host_mac_addr_set = 1;
7337       else if (unformat (i, "host-bridge %s", &host_bridge))
7338         host_bridge_set = 1;
7339       else if (unformat (i, "host-ip4-addr %U/%u", unformat_ip4_address,
7340                          &host_ip4_addr, &host_ip4_prefix_len))
7341         host_ip4_prefix_set = 1;
7342       else if (unformat (i, "host-ip6-addr %U/%u", unformat_ip6_address,
7343                          &host_ip6_addr, &host_ip6_prefix_len))
7344         host_ip6_prefix_set = 1;
7345       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7346                          &host_ip4_gw))
7347         host_ip4_gw_set = 1;
7348       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7349                          &host_ip6_gw))
7350         host_ip6_gw_set = 1;
7351       else if (unformat (i, "rx-ring-size %u", &rx_ring_sz))
7352         ;
7353       else if (unformat (i, "tx-ring-size %u", &tx_ring_sz))
7354         ;
7355       else if (unformat (i, "host-mtu-size %u", &host_mtu_size))
7356         host_mtu_set = 1;
7357       else if (unformat (i, "no-gso"))
7358         tap_flags &= ~TAP_API_FLAG_GSO;
7359       else if (unformat (i, "gso"))
7360         tap_flags |= TAP_API_FLAG_GSO;
7361       else if (unformat (i, "csum-offload"))
7362         tap_flags |= TAP_API_FLAG_CSUM_OFFLOAD;
7363       else if (unformat (i, "persist"))
7364         tap_flags |= TAP_API_FLAG_PERSIST;
7365       else if (unformat (i, "attach"))
7366         tap_flags |= TAP_API_FLAG_ATTACH;
7367       else if (unformat (i, "tun"))
7368         tap_flags |= TAP_API_FLAG_TUN;
7369       else if (unformat (i, "gro-coalesce"))
7370         tap_flags |= TAP_API_FLAG_GRO_COALESCE;
7371       else if (unformat (i, "packed"))
7372         tap_flags |= TAP_API_FLAG_PACKED;
7373       else if (unformat (i, "in-order"))
7374         tap_flags |= TAP_API_FLAG_IN_ORDER;
7375       else
7376         break;
7377     }
7378
7379   if (vec_len (host_if_name) > 63)
7380     {
7381       errmsg ("tap name too long. ");
7382       return -99;
7383     }
7384   if (vec_len (host_ns) > 63)
7385     {
7386       errmsg ("host name space too long. ");
7387       return -99;
7388     }
7389   if (vec_len (host_bridge) > 63)
7390     {
7391       errmsg ("host bridge name too long. ");
7392       return -99;
7393     }
7394   if (host_ip4_prefix_len > 32)
7395     {
7396       errmsg ("host ip4 prefix length not valid. ");
7397       return -99;
7398     }
7399   if (host_ip6_prefix_len > 128)
7400     {
7401       errmsg ("host ip6 prefix length not valid. ");
7402       return -99;
7403     }
7404   if (!is_pow2 (rx_ring_sz))
7405     {
7406       errmsg ("rx ring size must be power of 2. ");
7407       return -99;
7408     }
7409   if (rx_ring_sz > 32768)
7410     {
7411       errmsg ("rx ring size must be 32768 or lower. ");
7412       return -99;
7413     }
7414   if (!is_pow2 (tx_ring_sz))
7415     {
7416       errmsg ("tx ring size must be power of 2. ");
7417       return -99;
7418     }
7419   if (tx_ring_sz > 32768)
7420     {
7421       errmsg ("tx ring size must be 32768 or lower. ");
7422       return -99;
7423     }
7424   if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
7425     {
7426       errmsg ("host MTU size must be in between 64 and 65355. ");
7427       return -99;
7428     }
7429
7430   /* Construct the API message */
7431   M (TAP_CREATE_V2, mp);
7432
7433   mp->id = ntohl (id);
7434   mp->use_random_mac = random_mac;
7435   mp->num_rx_queues = (u8) num_rx_queues;
7436   mp->tx_ring_sz = ntohs (tx_ring_sz);
7437   mp->rx_ring_sz = ntohs (rx_ring_sz);
7438   mp->host_mtu_set = host_mtu_set;
7439   mp->host_mtu_size = ntohl (host_mtu_size);
7440   mp->host_mac_addr_set = host_mac_addr_set;
7441   mp->host_ip4_prefix_set = host_ip4_prefix_set;
7442   mp->host_ip6_prefix_set = host_ip6_prefix_set;
7443   mp->host_ip4_gw_set = host_ip4_gw_set;
7444   mp->host_ip6_gw_set = host_ip6_gw_set;
7445   mp->tap_flags = ntohl (tap_flags);
7446   mp->host_namespace_set = host_ns_set;
7447   mp->host_if_name_set = host_if_name_set;
7448   mp->host_bridge_set = host_bridge_set;
7449
7450   if (random_mac == 0)
7451     clib_memcpy (mp->mac_address, mac_address, 6);
7452   if (host_mac_addr_set)
7453     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7454   if (host_if_name_set)
7455     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7456   if (host_ns_set)
7457     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7458   if (host_bridge_set)
7459     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7460   if (host_ip4_prefix_set)
7461     {
7462       clib_memcpy (mp->host_ip4_prefix.address, &host_ip4_addr, 4);
7463       mp->host_ip4_prefix.len = (u8) host_ip4_prefix_len;
7464     }
7465   if (host_ip6_prefix_set)
7466     {
7467       clib_memcpy (mp->host_ip6_prefix.address, &host_ip6_addr, 16);
7468       mp->host_ip6_prefix.len = (u8) host_ip6_prefix_len;
7469     }
7470   if (host_ip4_gw_set)
7471     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7472   if (host_ip6_gw_set)
7473     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7474
7475   vec_free (host_ns);
7476   vec_free (host_if_name);
7477   vec_free (host_bridge);
7478
7479   /* send it... */
7480   S (mp);
7481
7482   /* Wait for a reply... */
7483   W (ret);
7484   return ret;
7485 }
7486
7487 static int
7488 api_tap_delete_v2 (vat_main_t * vam)
7489 {
7490   unformat_input_t *i = vam->input;
7491   vl_api_tap_delete_v2_t *mp;
7492   u32 sw_if_index = ~0;
7493   u8 sw_if_index_set = 0;
7494   int ret;
7495
7496   /* Parse args required to build the message */
7497   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7498     {
7499       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7500         sw_if_index_set = 1;
7501       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7502         sw_if_index_set = 1;
7503       else
7504         break;
7505     }
7506
7507   if (sw_if_index_set == 0)
7508     {
7509       errmsg ("missing vpp interface name. ");
7510       return -99;
7511     }
7512
7513   /* Construct the API message */
7514   M (TAP_DELETE_V2, mp);
7515
7516   mp->sw_if_index = ntohl (sw_if_index);
7517
7518   /* send it... */
7519   S (mp);
7520
7521   /* Wait for a reply... */
7522   W (ret);
7523   return ret;
7524 }
7525
7526 uword
7527 unformat_vlib_pci_addr (unformat_input_t * input, va_list * args)
7528 {
7529   vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
7530   u32 x[4];
7531
7532   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7533     return 0;
7534
7535   addr->domain = x[0];
7536   addr->bus = x[1];
7537   addr->slot = x[2];
7538   addr->function = x[3];
7539
7540   return 1;
7541 }
7542
7543 static int
7544 api_virtio_pci_create_v2 (vat_main_t * vam)
7545 {
7546   unformat_input_t *i = vam->input;
7547   vl_api_virtio_pci_create_v2_t *mp;
7548   u8 mac_address[6];
7549   u8 random_mac = 1;
7550   u32 pci_addr = 0;
7551   u64 features = (u64) ~ (0ULL);
7552   u32 virtio_flags = 0;
7553   int ret;
7554
7555   clib_memset (mac_address, 0, sizeof (mac_address));
7556
7557   /* Parse args required to build the message */
7558   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7559     {
7560       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7561         {
7562           random_mac = 0;
7563         }
7564       else if (unformat (i, "pci-addr %U", unformat_vlib_pci_addr, &pci_addr))
7565         ;
7566       else if (unformat (i, "features 0x%llx", &features))
7567         ;
7568       else if (unformat (i, "gso-enabled"))
7569         virtio_flags |= VIRTIO_API_FLAG_GSO;
7570       else if (unformat (i, "csum-offload-enabled"))
7571         virtio_flags |= VIRTIO_API_FLAG_CSUM_OFFLOAD;
7572       else if (unformat (i, "gro-coalesce"))
7573         virtio_flags |= VIRTIO_API_FLAG_GRO_COALESCE;
7574       else if (unformat (i, "packed"))
7575         virtio_flags |= VIRTIO_API_FLAG_PACKED;
7576       else if (unformat (i, "in-order"))
7577         virtio_flags |= VIRTIO_API_FLAG_IN_ORDER;
7578       else
7579         break;
7580     }
7581
7582   if (pci_addr == 0)
7583     {
7584       errmsg ("pci address must be non zero. ");
7585       return -99;
7586     }
7587
7588   /* Construct the API message */
7589   M (VIRTIO_PCI_CREATE_V2, mp);
7590
7591   mp->use_random_mac = random_mac;
7592
7593   mp->pci_addr.domain = htons (((vlib_pci_addr_t) pci_addr).domain);
7594   mp->pci_addr.bus = ((vlib_pci_addr_t) pci_addr).bus;
7595   mp->pci_addr.slot = ((vlib_pci_addr_t) pci_addr).slot;
7596   mp->pci_addr.function = ((vlib_pci_addr_t) pci_addr).function;
7597
7598   mp->features = clib_host_to_net_u64 (features);
7599   mp->virtio_flags = clib_host_to_net_u32 (virtio_flags);
7600
7601   if (random_mac == 0)
7602     clib_memcpy (mp->mac_address, mac_address, 6);
7603
7604   /* send it... */
7605   S (mp);
7606
7607   /* Wait for a reply... */
7608   W (ret);
7609   return ret;
7610 }
7611
7612 static int
7613 api_virtio_pci_delete (vat_main_t * vam)
7614 {
7615   unformat_input_t *i = vam->input;
7616   vl_api_virtio_pci_delete_t *mp;
7617   u32 sw_if_index = ~0;
7618   u8 sw_if_index_set = 0;
7619   int ret;
7620
7621   /* Parse args required to build the message */
7622   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7623     {
7624       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7625         sw_if_index_set = 1;
7626       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7627         sw_if_index_set = 1;
7628       else
7629         break;
7630     }
7631
7632   if (sw_if_index_set == 0)
7633     {
7634       errmsg ("missing vpp interface name. ");
7635       return -99;
7636     }
7637
7638   /* Construct the API message */
7639   M (VIRTIO_PCI_DELETE, mp);
7640
7641   mp->sw_if_index = htonl (sw_if_index);
7642
7643   /* send it... */
7644   S (mp);
7645
7646   /* Wait for a reply... */
7647   W (ret);
7648   return ret;
7649 }
7650
7651 static int
7652 api_bond_create (vat_main_t * vam)
7653 {
7654   unformat_input_t *i = vam->input;
7655   vl_api_bond_create_t *mp;
7656   u8 mac_address[6];
7657   u8 custom_mac = 0;
7658   int ret;
7659   u8 mode;
7660   u8 lb;
7661   u8 mode_is_set = 0;
7662   u32 id = ~0;
7663   u8 numa_only = 0;
7664
7665   clib_memset (mac_address, 0, sizeof (mac_address));
7666   lb = BOND_LB_L2;
7667
7668   /* Parse args required to build the message */
7669   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7670     {
7671       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7672         mode_is_set = 1;
7673       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7674                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7675         ;
7676       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7677                          mac_address))
7678         custom_mac = 1;
7679       else if (unformat (i, "numa-only"))
7680         numa_only = 1;
7681       else if (unformat (i, "id %u", &id))
7682         ;
7683       else
7684         break;
7685     }
7686
7687   if (mode_is_set == 0)
7688     {
7689       errmsg ("Missing bond mode. ");
7690       return -99;
7691     }
7692
7693   /* Construct the API message */
7694   M (BOND_CREATE, mp);
7695
7696   mp->use_custom_mac = custom_mac;
7697
7698   mp->mode = htonl (mode);
7699   mp->lb = htonl (lb);
7700   mp->id = htonl (id);
7701   mp->numa_only = numa_only;
7702
7703   if (custom_mac)
7704     clib_memcpy (mp->mac_address, mac_address, 6);
7705
7706   /* send it... */
7707   S (mp);
7708
7709   /* Wait for a reply... */
7710   W (ret);
7711   return ret;
7712 }
7713
7714 static int
7715 api_bond_create2 (vat_main_t * vam)
7716 {
7717   unformat_input_t *i = vam->input;
7718   vl_api_bond_create2_t *mp;
7719   u8 mac_address[6];
7720   u8 custom_mac = 0;
7721   int ret;
7722   u8 mode;
7723   u8 lb;
7724   u8 mode_is_set = 0;
7725   u32 id = ~0;
7726   u8 numa_only = 0;
7727   u8 gso = 0;
7728
7729   clib_memset (mac_address, 0, sizeof (mac_address));
7730   lb = BOND_LB_L2;
7731
7732   /* Parse args required to build the message */
7733   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7734     {
7735       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7736         mode_is_set = 1;
7737       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7738                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7739         ;
7740       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7741                          mac_address))
7742         custom_mac = 1;
7743       else if (unformat (i, "numa-only"))
7744         numa_only = 1;
7745       else if (unformat (i, "gso"))
7746         gso = 1;
7747       else if (unformat (i, "id %u", &id))
7748         ;
7749       else
7750         break;
7751     }
7752
7753   if (mode_is_set == 0)
7754     {
7755       errmsg ("Missing bond mode. ");
7756       return -99;
7757     }
7758
7759   /* Construct the API message */
7760   M (BOND_CREATE2, mp);
7761
7762   mp->use_custom_mac = custom_mac;
7763
7764   mp->mode = htonl (mode);
7765   mp->lb = htonl (lb);
7766   mp->id = htonl (id);
7767   mp->numa_only = numa_only;
7768   mp->enable_gso = gso;
7769
7770   if (custom_mac)
7771     clib_memcpy (mp->mac_address, mac_address, 6);
7772
7773   /* send it... */
7774   S (mp);
7775
7776   /* Wait for a reply... */
7777   W (ret);
7778   return ret;
7779 }
7780
7781 static int
7782 api_bond_delete (vat_main_t * vam)
7783 {
7784   unformat_input_t *i = vam->input;
7785   vl_api_bond_delete_t *mp;
7786   u32 sw_if_index = ~0;
7787   u8 sw_if_index_set = 0;
7788   int ret;
7789
7790   /* Parse args required to build the message */
7791   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7792     {
7793       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7794         sw_if_index_set = 1;
7795       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7796         sw_if_index_set = 1;
7797       else
7798         break;
7799     }
7800
7801   if (sw_if_index_set == 0)
7802     {
7803       errmsg ("missing vpp interface name. ");
7804       return -99;
7805     }
7806
7807   /* Construct the API message */
7808   M (BOND_DELETE, mp);
7809
7810   mp->sw_if_index = ntohl (sw_if_index);
7811
7812   /* send it... */
7813   S (mp);
7814
7815   /* Wait for a reply... */
7816   W (ret);
7817   return ret;
7818 }
7819
7820 static int
7821 api_bond_add_member (vat_main_t * vam)
7822 {
7823   unformat_input_t *i = vam->input;
7824   vl_api_bond_add_member_t *mp;
7825   u32 bond_sw_if_index;
7826   int ret;
7827   u8 is_passive;
7828   u8 is_long_timeout;
7829   u32 bond_sw_if_index_is_set = 0;
7830   u32 sw_if_index;
7831   u8 sw_if_index_is_set = 0;
7832
7833   /* Parse args required to build the message */
7834   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7835     {
7836       if (unformat (i, "sw_if_index %d", &sw_if_index))
7837         sw_if_index_is_set = 1;
7838       else if (unformat (i, "bond %u", &bond_sw_if_index))
7839         bond_sw_if_index_is_set = 1;
7840       else if (unformat (i, "passive %d", &is_passive))
7841         ;
7842       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7843         ;
7844       else
7845         break;
7846     }
7847
7848   if (bond_sw_if_index_is_set == 0)
7849     {
7850       errmsg ("Missing bond sw_if_index. ");
7851       return -99;
7852     }
7853   if (sw_if_index_is_set == 0)
7854     {
7855       errmsg ("Missing member sw_if_index. ");
7856       return -99;
7857     }
7858
7859   /* Construct the API message */
7860   M (BOND_ADD_MEMBER, mp);
7861
7862   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7863   mp->sw_if_index = ntohl (sw_if_index);
7864   mp->is_long_timeout = is_long_timeout;
7865   mp->is_passive = is_passive;
7866
7867   /* send it... */
7868   S (mp);
7869
7870   /* Wait for a reply... */
7871   W (ret);
7872   return ret;
7873 }
7874
7875 static int
7876 api_bond_detach_member (vat_main_t * vam)
7877 {
7878   unformat_input_t *i = vam->input;
7879   vl_api_bond_detach_member_t *mp;
7880   u32 sw_if_index = ~0;
7881   u8 sw_if_index_set = 0;
7882   int ret;
7883
7884   /* Parse args required to build the message */
7885   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7886     {
7887       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7888         sw_if_index_set = 1;
7889       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7890         sw_if_index_set = 1;
7891       else
7892         break;
7893     }
7894
7895   if (sw_if_index_set == 0)
7896     {
7897       errmsg ("missing vpp interface name. ");
7898       return -99;
7899     }
7900
7901   /* Construct the API message */
7902   M (BOND_DETACH_MEMBER, mp);
7903
7904   mp->sw_if_index = ntohl (sw_if_index);
7905
7906   /* send it... */
7907   S (mp);
7908
7909   /* Wait for a reply... */
7910   W (ret);
7911   return ret;
7912 }
7913
7914 static int
7915 api_ip_table_add_del (vat_main_t * vam)
7916 {
7917   unformat_input_t *i = vam->input;
7918   vl_api_ip_table_add_del_t *mp;
7919   u32 table_id = ~0;
7920   u8 is_ipv6 = 0;
7921   u8 is_add = 1;
7922   int ret = 0;
7923
7924   /* Parse args required to build the message */
7925   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7926     {
7927       if (unformat (i, "ipv6"))
7928         is_ipv6 = 1;
7929       else if (unformat (i, "del"))
7930         is_add = 0;
7931       else if (unformat (i, "add"))
7932         is_add = 1;
7933       else if (unformat (i, "table %d", &table_id))
7934         ;
7935       else
7936         {
7937           clib_warning ("parse error '%U'", format_unformat_error, i);
7938           return -99;
7939         }
7940     }
7941
7942   if (~0 == table_id)
7943     {
7944       errmsg ("missing table-ID");
7945       return -99;
7946     }
7947
7948   /* Construct the API message */
7949   M (IP_TABLE_ADD_DEL, mp);
7950
7951   mp->table.table_id = ntohl (table_id);
7952   mp->table.is_ip6 = is_ipv6;
7953   mp->is_add = is_add;
7954
7955   /* send it... */
7956   S (mp);
7957
7958   /* Wait for a reply... */
7959   W (ret);
7960
7961   return ret;
7962 }
7963
7964 uword
7965 unformat_fib_path (unformat_input_t * input, va_list * args)
7966 {
7967   vat_main_t *vam = va_arg (*args, vat_main_t *);
7968   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
7969   u32 weight, preference;
7970   mpls_label_t out_label;
7971
7972   clib_memset (path, 0, sizeof (*path));
7973   path->weight = 1;
7974   path->sw_if_index = ~0;
7975   path->rpf_id = ~0;
7976   path->n_labels = 0;
7977
7978   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7979     {
7980       if (unformat (input, "%U %U",
7981                     unformat_vl_api_ip4_address,
7982                     &path->nh.address.ip4,
7983                     api_unformat_sw_if_index, vam, &path->sw_if_index))
7984         {
7985           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7986         }
7987       else if (unformat (input, "%U %U",
7988                          unformat_vl_api_ip6_address,
7989                          &path->nh.address.ip6,
7990                          api_unformat_sw_if_index, vam, &path->sw_if_index))
7991         {
7992           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7993         }
7994       else if (unformat (input, "weight %u", &weight))
7995         {
7996           path->weight = weight;
7997         }
7998       else if (unformat (input, "preference %u", &preference))
7999         {
8000           path->preference = preference;
8001         }
8002       else if (unformat (input, "%U next-hop-table %d",
8003                          unformat_vl_api_ip4_address,
8004                          &path->nh.address.ip4, &path->table_id))
8005         {
8006           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8007         }
8008       else if (unformat (input, "%U next-hop-table %d",
8009                          unformat_vl_api_ip6_address,
8010                          &path->nh.address.ip6, &path->table_id))
8011         {
8012           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8013         }
8014       else if (unformat (input, "%U",
8015                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
8016         {
8017           /*
8018            * the recursive next-hops are by default in the default table
8019            */
8020           path->table_id = 0;
8021           path->sw_if_index = ~0;
8022           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8023         }
8024       else if (unformat (input, "%U",
8025                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
8026         {
8027           /*
8028            * the recursive next-hops are by default in the default table
8029            */
8030           path->table_id = 0;
8031           path->sw_if_index = ~0;
8032           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8033         }
8034       else if (unformat (input, "resolve-via-host"))
8035         {
8036           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
8037         }
8038       else if (unformat (input, "resolve-via-attached"))
8039         {
8040           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
8041         }
8042       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
8043         {
8044           path->type = FIB_API_PATH_TYPE_LOCAL;
8045           path->sw_if_index = ~0;
8046           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8047         }
8048       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
8049         {
8050           path->type = FIB_API_PATH_TYPE_LOCAL;
8051           path->sw_if_index = ~0;
8052           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8053         }
8054       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
8055         ;
8056       else if (unformat (input, "via-label %d", &path->nh.via_label))
8057         {
8058           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
8059           path->sw_if_index = ~0;
8060         }
8061       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
8062         {
8063           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
8064           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
8065         }
8066       else if (unformat (input, "local"))
8067         {
8068           path->type = FIB_API_PATH_TYPE_LOCAL;
8069         }
8070       else if (unformat (input, "out-labels"))
8071         {
8072           while (unformat (input, "%d", &out_label))
8073             {
8074               path->label_stack[path->n_labels].label = out_label;
8075               path->label_stack[path->n_labels].is_uniform = 0;
8076               path->label_stack[path->n_labels].ttl = 64;
8077               path->n_labels++;
8078             }
8079         }
8080       else if (unformat (input, "via"))
8081         {
8082           /* new path, back up and return */
8083           unformat_put_input (input);
8084           unformat_put_input (input);
8085           unformat_put_input (input);
8086           unformat_put_input (input);
8087           break;
8088         }
8089       else
8090         {
8091           return (0);
8092         }
8093     }
8094
8095   path->proto = ntohl (path->proto);
8096   path->type = ntohl (path->type);
8097   path->flags = ntohl (path->flags);
8098   path->table_id = ntohl (path->table_id);
8099   path->sw_if_index = ntohl (path->sw_if_index);
8100
8101   return (1);
8102 }
8103
8104 static int
8105 api_ip_route_add_del (vat_main_t * vam)
8106 {
8107   unformat_input_t *i = vam->input;
8108   vl_api_ip_route_add_del_t *mp;
8109   u32 vrf_id = 0;
8110   u8 is_add = 1;
8111   u8 is_multipath = 0;
8112   u8 prefix_set = 0;
8113   u8 path_count = 0;
8114   vl_api_prefix_t pfx = { };
8115   vl_api_fib_path_t paths[8];
8116   int count = 1;
8117   int j;
8118   f64 before = 0;
8119   u32 random_add_del = 0;
8120   u32 *random_vector = 0;
8121   u32 random_seed = 0xdeaddabe;
8122
8123   /* Parse args required to build the message */
8124   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8125     {
8126       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8127         prefix_set = 1;
8128       else if (unformat (i, "del"))
8129         is_add = 0;
8130       else if (unformat (i, "add"))
8131         is_add = 1;
8132       else if (unformat (i, "vrf %d", &vrf_id))
8133         ;
8134       else if (unformat (i, "count %d", &count))
8135         ;
8136       else if (unformat (i, "random"))
8137         random_add_del = 1;
8138       else if (unformat (i, "multipath"))
8139         is_multipath = 1;
8140       else if (unformat (i, "seed %d", &random_seed))
8141         ;
8142       else
8143         if (unformat
8144             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8145         {
8146           path_count++;
8147           if (8 == path_count)
8148             {
8149               errmsg ("max 8 paths");
8150               return -99;
8151             }
8152         }
8153       else
8154         {
8155           clib_warning ("parse error '%U'", format_unformat_error, i);
8156           return -99;
8157         }
8158     }
8159
8160   if (!path_count)
8161     {
8162       errmsg ("specify a path; via ...");
8163       return -99;
8164     }
8165   if (prefix_set == 0)
8166     {
8167       errmsg ("missing prefix");
8168       return -99;
8169     }
8170
8171   /* Generate a pile of unique, random routes */
8172   if (random_add_del)
8173     {
8174       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
8175       u32 this_random_address;
8176       uword *random_hash;
8177
8178       random_hash = hash_create (count, sizeof (uword));
8179
8180       hash_set (random_hash, i->as_u32, 1);
8181       for (j = 0; j <= count; j++)
8182         {
8183           do
8184             {
8185               this_random_address = random_u32 (&random_seed);
8186               this_random_address =
8187                 clib_host_to_net_u32 (this_random_address);
8188             }
8189           while (hash_get (random_hash, this_random_address));
8190           vec_add1 (random_vector, this_random_address);
8191           hash_set (random_hash, this_random_address, 1);
8192         }
8193       hash_free (random_hash);
8194       set_ip4_address (&pfx.address, random_vector[0]);
8195     }
8196
8197   if (count > 1)
8198     {
8199       /* Turn on async mode */
8200       vam->async_mode = 1;
8201       vam->async_errors = 0;
8202       before = vat_time_now (vam);
8203     }
8204
8205   for (j = 0; j < count; j++)
8206     {
8207       /* Construct the API message */
8208       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8209
8210       mp->is_add = is_add;
8211       mp->is_multipath = is_multipath;
8212
8213       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8214       mp->route.table_id = ntohl (vrf_id);
8215       mp->route.n_paths = path_count;
8216
8217       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
8218
8219       if (random_add_del)
8220         set_ip4_address (&pfx.address, random_vector[j + 1]);
8221       else
8222         increment_address (&pfx.address);
8223       /* send it... */
8224       S (mp);
8225       /* If we receive SIGTERM, stop now... */
8226       if (vam->do_exit)
8227         break;
8228     }
8229
8230   /* When testing multiple add/del ops, use a control-ping to sync */
8231   if (count > 1)
8232     {
8233       vl_api_control_ping_t *mp_ping;
8234       f64 after;
8235       f64 timeout;
8236
8237       /* Shut off async mode */
8238       vam->async_mode = 0;
8239
8240       MPING (CONTROL_PING, mp_ping);
8241       S (mp_ping);
8242
8243       timeout = vat_time_now (vam) + 1.0;
8244       while (vat_time_now (vam) < timeout)
8245         if (vam->result_ready == 1)
8246           goto out;
8247       vam->retval = -99;
8248
8249     out:
8250       if (vam->retval == -99)
8251         errmsg ("timeout");
8252
8253       if (vam->async_errors > 0)
8254         {
8255           errmsg ("%d asynchronous errors", vam->async_errors);
8256           vam->retval = -98;
8257         }
8258       vam->async_errors = 0;
8259       after = vat_time_now (vam);
8260
8261       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8262       if (j > 0)
8263         count = j;
8264
8265       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8266              count, after - before, count / (after - before));
8267     }
8268   else
8269     {
8270       int ret;
8271
8272       /* Wait for a reply... */
8273       W (ret);
8274       return ret;
8275     }
8276
8277   /* Return the good/bad news */
8278   return (vam->retval);
8279 }
8280
8281 static int
8282 api_ip_mroute_add_del (vat_main_t * vam)
8283 {
8284   unformat_input_t *i = vam->input;
8285   u8 path_set = 0, prefix_set = 0, is_add = 1;
8286   vl_api_ip_mroute_add_del_t *mp;
8287   mfib_entry_flags_t eflags = 0;
8288   vl_api_mfib_path_t path;
8289   vl_api_mprefix_t pfx = { };
8290   u32 vrf_id = 0;
8291   int ret;
8292
8293   /* Parse args required to build the message */
8294   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8295     {
8296       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
8297         {
8298           prefix_set = 1;
8299           pfx.grp_address_length = htons (pfx.grp_address_length);
8300         }
8301       else if (unformat (i, "del"))
8302         is_add = 0;
8303       else if (unformat (i, "add"))
8304         is_add = 1;
8305       else if (unformat (i, "vrf %d", &vrf_id))
8306         ;
8307       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
8308         path.itf_flags = htonl (path.itf_flags);
8309       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8310         ;
8311       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
8312         path_set = 1;
8313       else
8314         {
8315           clib_warning ("parse error '%U'", format_unformat_error, i);
8316           return -99;
8317         }
8318     }
8319
8320   if (prefix_set == 0)
8321     {
8322       errmsg ("missing addresses\n");
8323       return -99;
8324     }
8325   if (path_set == 0)
8326     {
8327       errmsg ("missing path\n");
8328       return -99;
8329     }
8330
8331   /* Construct the API message */
8332   M (IP_MROUTE_ADD_DEL, mp);
8333
8334   mp->is_add = is_add;
8335   mp->is_multipath = 1;
8336
8337   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8338   mp->route.table_id = htonl (vrf_id);
8339   mp->route.n_paths = 1;
8340   mp->route.entry_flags = htonl (eflags);
8341
8342   clib_memcpy (&mp->route.paths, &path, sizeof (path));
8343
8344   /* send it... */
8345   S (mp);
8346   /* Wait for a reply... */
8347   W (ret);
8348   return ret;
8349 }
8350
8351 static int
8352 api_mpls_table_add_del (vat_main_t * vam)
8353 {
8354   unformat_input_t *i = vam->input;
8355   vl_api_mpls_table_add_del_t *mp;
8356   u32 table_id = ~0;
8357   u8 is_add = 1;
8358   int ret = 0;
8359
8360   /* Parse args required to build the message */
8361   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8362     {
8363       if (unformat (i, "table %d", &table_id))
8364         ;
8365       else if (unformat (i, "del"))
8366         is_add = 0;
8367       else if (unformat (i, "add"))
8368         is_add = 1;
8369       else
8370         {
8371           clib_warning ("parse error '%U'", format_unformat_error, i);
8372           return -99;
8373         }
8374     }
8375
8376   if (~0 == table_id)
8377     {
8378       errmsg ("missing table-ID");
8379       return -99;
8380     }
8381
8382   /* Construct the API message */
8383   M (MPLS_TABLE_ADD_DEL, mp);
8384
8385   mp->mt_table.mt_table_id = ntohl (table_id);
8386   mp->mt_is_add = is_add;
8387
8388   /* send it... */
8389   S (mp);
8390
8391   /* Wait for a reply... */
8392   W (ret);
8393
8394   return ret;
8395 }
8396
8397 static int
8398 api_mpls_route_add_del (vat_main_t * vam)
8399 {
8400   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
8401   mpls_label_t local_label = MPLS_LABEL_INVALID;
8402   unformat_input_t *i = vam->input;
8403   vl_api_mpls_route_add_del_t *mp;
8404   vl_api_fib_path_t paths[8];
8405   int count = 1, j;
8406   f64 before = 0;
8407
8408   /* Parse args required to build the message */
8409   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8410     {
8411       if (unformat (i, "%d", &local_label))
8412         ;
8413       else if (unformat (i, "eos"))
8414         is_eos = 1;
8415       else if (unformat (i, "non-eos"))
8416         is_eos = 0;
8417       else if (unformat (i, "del"))
8418         is_add = 0;
8419       else if (unformat (i, "add"))
8420         is_add = 1;
8421       else if (unformat (i, "multipath"))
8422         is_multipath = 1;
8423       else if (unformat (i, "count %d", &count))
8424         ;
8425       else
8426         if (unformat
8427             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8428         {
8429           path_count++;
8430           if (8 == path_count)
8431             {
8432               errmsg ("max 8 paths");
8433               return -99;
8434             }
8435         }
8436       else
8437         {
8438           clib_warning ("parse error '%U'", format_unformat_error, i);
8439           return -99;
8440         }
8441     }
8442
8443   if (!path_count)
8444     {
8445       errmsg ("specify a path; via ...");
8446       return -99;
8447     }
8448
8449   if (MPLS_LABEL_INVALID == local_label)
8450     {
8451       errmsg ("missing label");
8452       return -99;
8453     }
8454
8455   if (count > 1)
8456     {
8457       /* Turn on async mode */
8458       vam->async_mode = 1;
8459       vam->async_errors = 0;
8460       before = vat_time_now (vam);
8461     }
8462
8463   for (j = 0; j < count; j++)
8464     {
8465       /* Construct the API message */
8466       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8467
8468       mp->mr_is_add = is_add;
8469       mp->mr_is_multipath = is_multipath;
8470
8471       mp->mr_route.mr_label = local_label;
8472       mp->mr_route.mr_eos = is_eos;
8473       mp->mr_route.mr_table_id = 0;
8474       mp->mr_route.mr_n_paths = path_count;
8475
8476       clib_memcpy (&mp->mr_route.mr_paths, paths,
8477                    sizeof (paths[0]) * path_count);
8478
8479       local_label++;
8480
8481       /* send it... */
8482       S (mp);
8483       /* If we receive SIGTERM, stop now... */
8484       if (vam->do_exit)
8485         break;
8486     }
8487
8488   /* When testing multiple add/del ops, use a control-ping to sync */
8489   if (count > 1)
8490     {
8491       vl_api_control_ping_t *mp_ping;
8492       f64 after;
8493       f64 timeout;
8494
8495       /* Shut off async mode */
8496       vam->async_mode = 0;
8497
8498       MPING (CONTROL_PING, mp_ping);
8499       S (mp_ping);
8500
8501       timeout = vat_time_now (vam) + 1.0;
8502       while (vat_time_now (vam) < timeout)
8503         if (vam->result_ready == 1)
8504           goto out;
8505       vam->retval = -99;
8506
8507     out:
8508       if (vam->retval == -99)
8509         errmsg ("timeout");
8510
8511       if (vam->async_errors > 0)
8512         {
8513           errmsg ("%d asynchronous errors", vam->async_errors);
8514           vam->retval = -98;
8515         }
8516       vam->async_errors = 0;
8517       after = vat_time_now (vam);
8518
8519       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8520       if (j > 0)
8521         count = j;
8522
8523       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8524              count, after - before, count / (after - before));
8525     }
8526   else
8527     {
8528       int ret;
8529
8530       /* Wait for a reply... */
8531       W (ret);
8532       return ret;
8533     }
8534
8535   /* Return the good/bad news */
8536   return (vam->retval);
8537   return (0);
8538 }
8539
8540 static int
8541 api_mpls_ip_bind_unbind (vat_main_t * vam)
8542 {
8543   unformat_input_t *i = vam->input;
8544   vl_api_mpls_ip_bind_unbind_t *mp;
8545   u32 ip_table_id = 0;
8546   u8 is_bind = 1;
8547   vl_api_prefix_t pfx;
8548   u8 prefix_set = 0;
8549   mpls_label_t local_label = MPLS_LABEL_INVALID;
8550   int ret;
8551
8552   /* Parse args required to build the message */
8553   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8554     {
8555       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8556         prefix_set = 1;
8557       else if (unformat (i, "%d", &local_label))
8558         ;
8559       else if (unformat (i, "table-id %d", &ip_table_id))
8560         ;
8561       else if (unformat (i, "unbind"))
8562         is_bind = 0;
8563       else if (unformat (i, "bind"))
8564         is_bind = 1;
8565       else
8566         {
8567           clib_warning ("parse error '%U'", format_unformat_error, i);
8568           return -99;
8569         }
8570     }
8571
8572   if (!prefix_set)
8573     {
8574       errmsg ("IP prefix not set");
8575       return -99;
8576     }
8577
8578   if (MPLS_LABEL_INVALID == local_label)
8579     {
8580       errmsg ("missing label");
8581       return -99;
8582     }
8583
8584   /* Construct the API message */
8585   M (MPLS_IP_BIND_UNBIND, mp);
8586
8587   mp->mb_is_bind = is_bind;
8588   mp->mb_ip_table_id = ntohl (ip_table_id);
8589   mp->mb_mpls_table_id = 0;
8590   mp->mb_label = ntohl (local_label);
8591   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
8592
8593   /* send it... */
8594   S (mp);
8595
8596   /* Wait for a reply... */
8597   W (ret);
8598   return ret;
8599   return (0);
8600 }
8601
8602 static int
8603 api_sr_mpls_policy_add (vat_main_t * vam)
8604 {
8605   unformat_input_t *i = vam->input;
8606   vl_api_sr_mpls_policy_add_t *mp;
8607   u32 bsid = 0;
8608   u32 weight = 1;
8609   u8 type = 0;
8610   u8 n_segments = 0;
8611   u32 sid;
8612   u32 *segments = NULL;
8613   int ret;
8614
8615   /* Parse args required to build the message */
8616   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8617     {
8618       if (unformat (i, "bsid %d", &bsid))
8619         ;
8620       else if (unformat (i, "weight %d", &weight))
8621         ;
8622       else if (unformat (i, "spray"))
8623         type = 1;
8624       else if (unformat (i, "next %d", &sid))
8625         {
8626           n_segments += 1;
8627           vec_add1 (segments, htonl (sid));
8628         }
8629       else
8630         {
8631           clib_warning ("parse error '%U'", format_unformat_error, i);
8632           return -99;
8633         }
8634     }
8635
8636   if (bsid == 0)
8637     {
8638       errmsg ("bsid not set");
8639       return -99;
8640     }
8641
8642   if (n_segments == 0)
8643     {
8644       errmsg ("no sid in segment stack");
8645       return -99;
8646     }
8647
8648   /* Construct the API message */
8649   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8650
8651   mp->bsid = htonl (bsid);
8652   mp->weight = htonl (weight);
8653   mp->is_spray = type;
8654   mp->n_segments = n_segments;
8655   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8656   vec_free (segments);
8657
8658   /* send it... */
8659   S (mp);
8660
8661   /* Wait for a reply... */
8662   W (ret);
8663   return ret;
8664 }
8665
8666 static int
8667 api_sr_mpls_policy_del (vat_main_t * vam)
8668 {
8669   unformat_input_t *i = vam->input;
8670   vl_api_sr_mpls_policy_del_t *mp;
8671   u32 bsid = 0;
8672   int ret;
8673
8674   /* Parse args required to build the message */
8675   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8676     {
8677       if (unformat (i, "bsid %d", &bsid))
8678         ;
8679       else
8680         {
8681           clib_warning ("parse error '%U'", format_unformat_error, i);
8682           return -99;
8683         }
8684     }
8685
8686   if (bsid == 0)
8687     {
8688       errmsg ("bsid not set");
8689       return -99;
8690     }
8691
8692   /* Construct the API message */
8693   M (SR_MPLS_POLICY_DEL, mp);
8694
8695   mp->bsid = htonl (bsid);
8696
8697   /* send it... */
8698   S (mp);
8699
8700   /* Wait for a reply... */
8701   W (ret);
8702   return ret;
8703 }
8704
8705 static int
8706 api_bier_table_add_del (vat_main_t * vam)
8707 {
8708   unformat_input_t *i = vam->input;
8709   vl_api_bier_table_add_del_t *mp;
8710   u8 is_add = 1;
8711   u32 set = 0, sub_domain = 0, hdr_len = 3;
8712   mpls_label_t local_label = MPLS_LABEL_INVALID;
8713   int ret;
8714
8715   /* Parse args required to build the message */
8716   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8717     {
8718       if (unformat (i, "sub-domain %d", &sub_domain))
8719         ;
8720       else if (unformat (i, "set %d", &set))
8721         ;
8722       else if (unformat (i, "label %d", &local_label))
8723         ;
8724       else if (unformat (i, "hdr-len %d", &hdr_len))
8725         ;
8726       else if (unformat (i, "add"))
8727         is_add = 1;
8728       else if (unformat (i, "del"))
8729         is_add = 0;
8730       else
8731         {
8732           clib_warning ("parse error '%U'", format_unformat_error, i);
8733           return -99;
8734         }
8735     }
8736
8737   if (MPLS_LABEL_INVALID == local_label)
8738     {
8739       errmsg ("missing label\n");
8740       return -99;
8741     }
8742
8743   /* Construct the API message */
8744   M (BIER_TABLE_ADD_DEL, mp);
8745
8746   mp->bt_is_add = is_add;
8747   mp->bt_label = ntohl (local_label);
8748   mp->bt_tbl_id.bt_set = set;
8749   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8750   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8751
8752   /* send it... */
8753   S (mp);
8754
8755   /* Wait for a reply... */
8756   W (ret);
8757
8758   return (ret);
8759 }
8760
8761 static int
8762 api_bier_route_add_del (vat_main_t * vam)
8763 {
8764   unformat_input_t *i = vam->input;
8765   vl_api_bier_route_add_del_t *mp;
8766   u8 is_add = 1;
8767   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8768   ip4_address_t v4_next_hop_address;
8769   ip6_address_t v6_next_hop_address;
8770   u8 next_hop_set = 0;
8771   u8 next_hop_proto_is_ip4 = 1;
8772   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8773   int ret;
8774
8775   /* Parse args required to build the message */
8776   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8777     {
8778       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8779         {
8780           next_hop_proto_is_ip4 = 1;
8781           next_hop_set = 1;
8782         }
8783       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8784         {
8785           next_hop_proto_is_ip4 = 0;
8786           next_hop_set = 1;
8787         }
8788       if (unformat (i, "sub-domain %d", &sub_domain))
8789         ;
8790       else if (unformat (i, "set %d", &set))
8791         ;
8792       else if (unformat (i, "hdr-len %d", &hdr_len))
8793         ;
8794       else if (unformat (i, "bp %d", &bp))
8795         ;
8796       else if (unformat (i, "add"))
8797         is_add = 1;
8798       else if (unformat (i, "del"))
8799         is_add = 0;
8800       else if (unformat (i, "out-label %d", &next_hop_out_label))
8801         ;
8802       else
8803         {
8804           clib_warning ("parse error '%U'", format_unformat_error, i);
8805           return -99;
8806         }
8807     }
8808
8809   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8810     {
8811       errmsg ("next hop / label set\n");
8812       return -99;
8813     }
8814   if (0 == bp)
8815     {
8816       errmsg ("bit=position not set\n");
8817       return -99;
8818     }
8819
8820   /* Construct the API message */
8821   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
8822
8823   mp->br_is_add = is_add;
8824   mp->br_route.br_tbl_id.bt_set = set;
8825   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
8826   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
8827   mp->br_route.br_bp = ntohs (bp);
8828   mp->br_route.br_n_paths = 1;
8829   mp->br_route.br_paths[0].n_labels = 1;
8830   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
8831   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
8832                                     FIB_API_PATH_NH_PROTO_IP4 :
8833                                     FIB_API_PATH_NH_PROTO_IP6);
8834
8835   if (next_hop_proto_is_ip4)
8836     {
8837       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
8838                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8839     }
8840   else
8841     {
8842       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
8843                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8844     }
8845
8846   /* send it... */
8847   S (mp);
8848
8849   /* Wait for a reply... */
8850   W (ret);
8851
8852   return (ret);
8853 }
8854
8855 static int
8856 api_mpls_tunnel_add_del (vat_main_t * vam)
8857 {
8858   unformat_input_t *i = vam->input;
8859   vl_api_mpls_tunnel_add_del_t *mp;
8860
8861   vl_api_fib_path_t paths[8];
8862   u32 sw_if_index = ~0;
8863   u8 path_count = 0;
8864   u8 l2_only = 0;
8865   u8 is_add = 1;
8866   int ret;
8867
8868   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8869     {
8870       if (unformat (i, "add"))
8871         is_add = 1;
8872       else
8873         if (unformat
8874             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
8875         is_add = 0;
8876       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8877         is_add = 0;
8878       else if (unformat (i, "l2-only"))
8879         l2_only = 1;
8880       else
8881         if (unformat
8882             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8883         {
8884           path_count++;
8885           if (8 == path_count)
8886             {
8887               errmsg ("max 8 paths");
8888               return -99;
8889             }
8890         }
8891       else
8892         {
8893           clib_warning ("parse error '%U'", format_unformat_error, i);
8894           return -99;
8895         }
8896     }
8897
8898   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8899
8900   mp->mt_is_add = is_add;
8901   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
8902   mp->mt_tunnel.mt_l2_only = l2_only;
8903   mp->mt_tunnel.mt_is_multicast = 0;
8904   mp->mt_tunnel.mt_n_paths = path_count;
8905
8906   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
8907                sizeof (paths[0]) * path_count);
8908
8909   S (mp);
8910   W (ret);
8911   return ret;
8912 }
8913
8914 static int
8915 api_sw_interface_set_unnumbered (vat_main_t * vam)
8916 {
8917   unformat_input_t *i = vam->input;
8918   vl_api_sw_interface_set_unnumbered_t *mp;
8919   u32 sw_if_index;
8920   u32 unnum_sw_index = ~0;
8921   u8 is_add = 1;
8922   u8 sw_if_index_set = 0;
8923   int ret;
8924
8925   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8926     {
8927       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8928         sw_if_index_set = 1;
8929       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8930         sw_if_index_set = 1;
8931       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8932         ;
8933       else if (unformat (i, "del"))
8934         is_add = 0;
8935       else
8936         {
8937           clib_warning ("parse error '%U'", format_unformat_error, i);
8938           return -99;
8939         }
8940     }
8941
8942   if (sw_if_index_set == 0)
8943     {
8944       errmsg ("missing interface name or sw_if_index");
8945       return -99;
8946     }
8947
8948   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8949
8950   mp->sw_if_index = ntohl (sw_if_index);
8951   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8952   mp->is_add = is_add;
8953
8954   S (mp);
8955   W (ret);
8956   return ret;
8957 }
8958
8959
8960 static int
8961 api_create_vlan_subif (vat_main_t * vam)
8962 {
8963   unformat_input_t *i = vam->input;
8964   vl_api_create_vlan_subif_t *mp;
8965   u32 sw_if_index;
8966   u8 sw_if_index_set = 0;
8967   u32 vlan_id;
8968   u8 vlan_id_set = 0;
8969   int ret;
8970
8971   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8972     {
8973       if (unformat (i, "sw_if_index %d", &sw_if_index))
8974         sw_if_index_set = 1;
8975       else
8976         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8977         sw_if_index_set = 1;
8978       else if (unformat (i, "vlan %d", &vlan_id))
8979         vlan_id_set = 1;
8980       else
8981         {
8982           clib_warning ("parse error '%U'", format_unformat_error, i);
8983           return -99;
8984         }
8985     }
8986
8987   if (sw_if_index_set == 0)
8988     {
8989       errmsg ("missing interface name or sw_if_index");
8990       return -99;
8991     }
8992
8993   if (vlan_id_set == 0)
8994     {
8995       errmsg ("missing vlan_id");
8996       return -99;
8997     }
8998   M (CREATE_VLAN_SUBIF, mp);
8999
9000   mp->sw_if_index = ntohl (sw_if_index);
9001   mp->vlan_id = ntohl (vlan_id);
9002
9003   S (mp);
9004   W (ret);
9005   return ret;
9006 }
9007
9008 #define foreach_create_subif_bit                \
9009 _(no_tags)                                      \
9010 _(one_tag)                                      \
9011 _(two_tags)                                     \
9012 _(dot1ad)                                       \
9013 _(exact_match)                                  \
9014 _(default_sub)                                  \
9015 _(outer_vlan_id_any)                            \
9016 _(inner_vlan_id_any)
9017
9018 #define foreach_create_subif_flag               \
9019 _(0, "no_tags")                                 \
9020 _(1, "one_tag")                                 \
9021 _(2, "two_tags")                                \
9022 _(3, "dot1ad")                                  \
9023 _(4, "exact_match")                             \
9024 _(5, "default_sub")                             \
9025 _(6, "outer_vlan_id_any")                       \
9026 _(7, "inner_vlan_id_any")
9027
9028 static int
9029 api_create_subif (vat_main_t * vam)
9030 {
9031   unformat_input_t *i = vam->input;
9032   vl_api_create_subif_t *mp;
9033   u32 sw_if_index;
9034   u8 sw_if_index_set = 0;
9035   u32 sub_id;
9036   u8 sub_id_set = 0;
9037   u32 __attribute__ ((unused)) no_tags = 0;
9038   u32 __attribute__ ((unused)) one_tag = 0;
9039   u32 __attribute__ ((unused)) two_tags = 0;
9040   u32 __attribute__ ((unused)) dot1ad = 0;
9041   u32 __attribute__ ((unused)) exact_match = 0;
9042   u32 __attribute__ ((unused)) default_sub = 0;
9043   u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
9044   u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
9045   u32 tmp;
9046   u16 outer_vlan_id = 0;
9047   u16 inner_vlan_id = 0;
9048   int ret;
9049
9050   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9051     {
9052       if (unformat (i, "sw_if_index %d", &sw_if_index))
9053         sw_if_index_set = 1;
9054       else
9055         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9056         sw_if_index_set = 1;
9057       else if (unformat (i, "sub_id %d", &sub_id))
9058         sub_id_set = 1;
9059       else if (unformat (i, "outer_vlan_id %d", &tmp))
9060         outer_vlan_id = tmp;
9061       else if (unformat (i, "inner_vlan_id %d", &tmp))
9062         inner_vlan_id = tmp;
9063
9064 #define _(a) else if (unformat (i, #a)) a = 1 ;
9065       foreach_create_subif_bit
9066 #undef _
9067         else
9068         {
9069           clib_warning ("parse error '%U'", format_unformat_error, i);
9070           return -99;
9071         }
9072     }
9073
9074   if (sw_if_index_set == 0)
9075     {
9076       errmsg ("missing interface name or sw_if_index");
9077       return -99;
9078     }
9079
9080   if (sub_id_set == 0)
9081     {
9082       errmsg ("missing sub_id");
9083       return -99;
9084     }
9085   M (CREATE_SUBIF, mp);
9086
9087   mp->sw_if_index = ntohl (sw_if_index);
9088   mp->sub_id = ntohl (sub_id);
9089
9090 #define _(a,b) mp->sub_if_flags |= (1 << a);
9091   foreach_create_subif_flag;
9092 #undef _
9093
9094   mp->outer_vlan_id = ntohs (outer_vlan_id);
9095   mp->inner_vlan_id = ntohs (inner_vlan_id);
9096
9097   S (mp);
9098   W (ret);
9099   return ret;
9100 }
9101
9102 static int
9103 api_ip_table_replace_begin (vat_main_t * vam)
9104 {
9105   unformat_input_t *i = vam->input;
9106   vl_api_ip_table_replace_begin_t *mp;
9107   u32 table_id = 0;
9108   u8 is_ipv6 = 0;
9109
9110   int ret;
9111   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9112     {
9113       if (unformat (i, "table %d", &table_id))
9114         ;
9115       else if (unformat (i, "ipv6"))
9116         is_ipv6 = 1;
9117       else
9118         {
9119           clib_warning ("parse error '%U'", format_unformat_error, i);
9120           return -99;
9121         }
9122     }
9123
9124   M (IP_TABLE_REPLACE_BEGIN, mp);
9125
9126   mp->table.table_id = ntohl (table_id);
9127   mp->table.is_ip6 = is_ipv6;
9128
9129   S (mp);
9130   W (ret);
9131   return ret;
9132 }
9133
9134 static int
9135 api_ip_table_flush (vat_main_t * vam)
9136 {
9137   unformat_input_t *i = vam->input;
9138   vl_api_ip_table_flush_t *mp;
9139   u32 table_id = 0;
9140   u8 is_ipv6 = 0;
9141
9142   int ret;
9143   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9144     {
9145       if (unformat (i, "table %d", &table_id))
9146         ;
9147       else if (unformat (i, "ipv6"))
9148         is_ipv6 = 1;
9149       else
9150         {
9151           clib_warning ("parse error '%U'", format_unformat_error, i);
9152           return -99;
9153         }
9154     }
9155
9156   M (IP_TABLE_FLUSH, mp);
9157
9158   mp->table.table_id = ntohl (table_id);
9159   mp->table.is_ip6 = is_ipv6;
9160
9161   S (mp);
9162   W (ret);
9163   return ret;
9164 }
9165
9166 static int
9167 api_ip_table_replace_end (vat_main_t * vam)
9168 {
9169   unformat_input_t *i = vam->input;
9170   vl_api_ip_table_replace_end_t *mp;
9171   u32 table_id = 0;
9172   u8 is_ipv6 = 0;
9173
9174   int ret;
9175   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9176     {
9177       if (unformat (i, "table %d", &table_id))
9178         ;
9179       else if (unformat (i, "ipv6"))
9180         is_ipv6 = 1;
9181       else
9182         {
9183           clib_warning ("parse error '%U'", format_unformat_error, i);
9184           return -99;
9185         }
9186     }
9187
9188   M (IP_TABLE_REPLACE_END, mp);
9189
9190   mp->table.table_id = ntohl (table_id);
9191   mp->table.is_ip6 = is_ipv6;
9192
9193   S (mp);
9194   W (ret);
9195   return ret;
9196 }
9197
9198 static int
9199 api_set_ip_flow_hash (vat_main_t * vam)
9200 {
9201   unformat_input_t *i = vam->input;
9202   vl_api_set_ip_flow_hash_t *mp;
9203   u32 vrf_id = 0;
9204   u8 is_ipv6 = 0;
9205   u8 vrf_id_set = 0;
9206   u8 src = 0;
9207   u8 dst = 0;
9208   u8 sport = 0;
9209   u8 dport = 0;
9210   u8 proto = 0;
9211   u8 reverse = 0;
9212   int ret;
9213
9214   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9215     {
9216       if (unformat (i, "vrf %d", &vrf_id))
9217         vrf_id_set = 1;
9218       else if (unformat (i, "ipv6"))
9219         is_ipv6 = 1;
9220       else if (unformat (i, "src"))
9221         src = 1;
9222       else if (unformat (i, "dst"))
9223         dst = 1;
9224       else if (unformat (i, "sport"))
9225         sport = 1;
9226       else if (unformat (i, "dport"))
9227         dport = 1;
9228       else if (unformat (i, "proto"))
9229         proto = 1;
9230       else if (unformat (i, "reverse"))
9231         reverse = 1;
9232
9233       else
9234         {
9235           clib_warning ("parse error '%U'", format_unformat_error, i);
9236           return -99;
9237         }
9238     }
9239
9240   if (vrf_id_set == 0)
9241     {
9242       errmsg ("missing vrf id");
9243       return -99;
9244     }
9245
9246   M (SET_IP_FLOW_HASH, mp);
9247   mp->src = src;
9248   mp->dst = dst;
9249   mp->sport = sport;
9250   mp->dport = dport;
9251   mp->proto = proto;
9252   mp->reverse = reverse;
9253   mp->vrf_id = ntohl (vrf_id);
9254   mp->is_ipv6 = is_ipv6;
9255
9256   S (mp);
9257   W (ret);
9258   return ret;
9259 }
9260
9261 static int
9262 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9263 {
9264   unformat_input_t *i = vam->input;
9265   vl_api_sw_interface_ip6_enable_disable_t *mp;
9266   u32 sw_if_index;
9267   u8 sw_if_index_set = 0;
9268   u8 enable = 0;
9269   int ret;
9270
9271   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9272     {
9273       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9274         sw_if_index_set = 1;
9275       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9276         sw_if_index_set = 1;
9277       else if (unformat (i, "enable"))
9278         enable = 1;
9279       else if (unformat (i, "disable"))
9280         enable = 0;
9281       else
9282         {
9283           clib_warning ("parse error '%U'", format_unformat_error, i);
9284           return -99;
9285         }
9286     }
9287
9288   if (sw_if_index_set == 0)
9289     {
9290       errmsg ("missing interface name or sw_if_index");
9291       return -99;
9292     }
9293
9294   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9295
9296   mp->sw_if_index = ntohl (sw_if_index);
9297   mp->enable = enable;
9298
9299   S (mp);
9300   W (ret);
9301   return ret;
9302 }
9303
9304
9305 static int
9306 api_l2_patch_add_del (vat_main_t * vam)
9307 {
9308   unformat_input_t *i = vam->input;
9309   vl_api_l2_patch_add_del_t *mp;
9310   u32 rx_sw_if_index;
9311   u8 rx_sw_if_index_set = 0;
9312   u32 tx_sw_if_index;
9313   u8 tx_sw_if_index_set = 0;
9314   u8 is_add = 1;
9315   int ret;
9316
9317   /* Parse args required to build the message */
9318   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9319     {
9320       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9321         rx_sw_if_index_set = 1;
9322       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9323         tx_sw_if_index_set = 1;
9324       else if (unformat (i, "rx"))
9325         {
9326           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9327             {
9328               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9329                             &rx_sw_if_index))
9330                 rx_sw_if_index_set = 1;
9331             }
9332           else
9333             break;
9334         }
9335       else if (unformat (i, "tx"))
9336         {
9337           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9338             {
9339               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9340                             &tx_sw_if_index))
9341                 tx_sw_if_index_set = 1;
9342             }
9343           else
9344             break;
9345         }
9346       else if (unformat (i, "del"))
9347         is_add = 0;
9348       else
9349         break;
9350     }
9351
9352   if (rx_sw_if_index_set == 0)
9353     {
9354       errmsg ("missing rx interface name or rx_sw_if_index");
9355       return -99;
9356     }
9357
9358   if (tx_sw_if_index_set == 0)
9359     {
9360       errmsg ("missing tx interface name or tx_sw_if_index");
9361       return -99;
9362     }
9363
9364   M (L2_PATCH_ADD_DEL, mp);
9365
9366   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9367   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9368   mp->is_add = is_add;
9369
9370   S (mp);
9371   W (ret);
9372   return ret;
9373 }
9374
9375 u8 is_del;
9376 u8 localsid_addr[16];
9377 u8 end_psp;
9378 u8 behavior;
9379 u32 sw_if_index;
9380 u32 vlan_index;
9381 u32 fib_table;
9382 u8 nh_addr[16];
9383
9384 static int
9385 api_sr_localsid_add_del (vat_main_t * vam)
9386 {
9387   unformat_input_t *i = vam->input;
9388   vl_api_sr_localsid_add_del_t *mp;
9389
9390   u8 is_del;
9391   ip6_address_t localsid;
9392   u8 end_psp = 0;
9393   u8 behavior = ~0;
9394   u32 sw_if_index;
9395   u32 fib_table = ~(u32) 0;
9396   ip46_address_t nh_addr;
9397   clib_memset (&nh_addr, 0, sizeof (ip46_address_t));
9398
9399   bool nexthop_set = 0;
9400
9401   int ret;
9402
9403   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9404     {
9405       if (unformat (i, "del"))
9406         is_del = 1;
9407       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9408       else if (unformat (i, "next-hop %U", unformat_ip46_address, &nh_addr))
9409         nexthop_set = 1;
9410       else if (unformat (i, "behavior %u", &behavior));
9411       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9412       else if (unformat (i, "fib-table %u", &fib_table));
9413       else if (unformat (i, "end.psp %u", &behavior));
9414       else
9415         break;
9416     }
9417
9418   M (SR_LOCALSID_ADD_DEL, mp);
9419
9420   clib_memcpy (mp->localsid, &localsid, sizeof (mp->localsid));
9421
9422   if (nexthop_set)
9423     {
9424       clib_memcpy (&mp->nh_addr.un, &nh_addr, sizeof (mp->nh_addr.un));
9425     }
9426   mp->behavior = behavior;
9427   mp->sw_if_index = ntohl (sw_if_index);
9428   mp->fib_table = ntohl (fib_table);
9429   mp->end_psp = end_psp;
9430   mp->is_del = is_del;
9431
9432   S (mp);
9433   W (ret);
9434   return ret;
9435 }
9436
9437 static int
9438 api_ioam_enable (vat_main_t * vam)
9439 {
9440   unformat_input_t *input = vam->input;
9441   vl_api_ioam_enable_t *mp;
9442   u32 id = 0;
9443   int has_trace_option = 0;
9444   int has_pot_option = 0;
9445   int has_seqno_option = 0;
9446   int has_analyse_option = 0;
9447   int ret;
9448
9449   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9450     {
9451       if (unformat (input, "trace"))
9452         has_trace_option = 1;
9453       else if (unformat (input, "pot"))
9454         has_pot_option = 1;
9455       else if (unformat (input, "seqno"))
9456         has_seqno_option = 1;
9457       else if (unformat (input, "analyse"))
9458         has_analyse_option = 1;
9459       else
9460         break;
9461     }
9462   M (IOAM_ENABLE, mp);
9463   mp->id = htons (id);
9464   mp->seqno = has_seqno_option;
9465   mp->analyse = has_analyse_option;
9466   mp->pot_enable = has_pot_option;
9467   mp->trace_enable = has_trace_option;
9468
9469   S (mp);
9470   W (ret);
9471   return ret;
9472 }
9473
9474
9475 static int
9476 api_ioam_disable (vat_main_t * vam)
9477 {
9478   vl_api_ioam_disable_t *mp;
9479   int ret;
9480
9481   M (IOAM_DISABLE, mp);
9482   S (mp);
9483   W (ret);
9484   return ret;
9485 }
9486
9487 #define foreach_tcp_proto_field                 \
9488 _(src_port)                                     \
9489 _(dst_port)
9490
9491 #define foreach_udp_proto_field                 \
9492 _(src_port)                                     \
9493 _(dst_port)
9494
9495 #define foreach_ip4_proto_field                 \
9496 _(src_address)                                  \
9497 _(dst_address)                                  \
9498 _(tos)                                          \
9499 _(length)                                       \
9500 _(fragment_id)                                  \
9501 _(ttl)                                          \
9502 _(protocol)                                     \
9503 _(checksum)
9504
9505 typedef struct
9506 {
9507   u16 src_port, dst_port;
9508 } tcpudp_header_t;
9509
9510 #if VPP_API_TEST_BUILTIN == 0
9511 uword
9512 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9513 {
9514   u8 **maskp = va_arg (*args, u8 **);
9515   u8 *mask = 0;
9516   u8 found_something = 0;
9517   tcp_header_t *tcp;
9518
9519 #define _(a) u8 a=0;
9520   foreach_tcp_proto_field;
9521 #undef _
9522
9523   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9524     {
9525       if (0);
9526 #define _(a) else if (unformat (input, #a)) a=1;
9527       foreach_tcp_proto_field
9528 #undef _
9529         else
9530         break;
9531     }
9532
9533 #define _(a) found_something += a;
9534   foreach_tcp_proto_field;
9535 #undef _
9536
9537   if (found_something == 0)
9538     return 0;
9539
9540   vec_validate (mask, sizeof (*tcp) - 1);
9541
9542   tcp = (tcp_header_t *) mask;
9543
9544 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
9545   foreach_tcp_proto_field;
9546 #undef _
9547
9548   *maskp = mask;
9549   return 1;
9550 }
9551
9552 uword
9553 unformat_udp_mask (unformat_input_t * input, va_list * args)
9554 {
9555   u8 **maskp = va_arg (*args, u8 **);
9556   u8 *mask = 0;
9557   u8 found_something = 0;
9558   udp_header_t *udp;
9559
9560 #define _(a) u8 a=0;
9561   foreach_udp_proto_field;
9562 #undef _
9563
9564   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9565     {
9566       if (0);
9567 #define _(a) else if (unformat (input, #a)) a=1;
9568       foreach_udp_proto_field
9569 #undef _
9570         else
9571         break;
9572     }
9573
9574 #define _(a) found_something += a;
9575   foreach_udp_proto_field;
9576 #undef _
9577
9578   if (found_something == 0)
9579     return 0;
9580
9581   vec_validate (mask, sizeof (*udp) - 1);
9582
9583   udp = (udp_header_t *) mask;
9584
9585 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
9586   foreach_udp_proto_field;
9587 #undef _
9588
9589   *maskp = mask;
9590   return 1;
9591 }
9592
9593 uword
9594 unformat_l4_mask (unformat_input_t * input, va_list * args)
9595 {
9596   u8 **maskp = va_arg (*args, u8 **);
9597   u16 src_port = 0, dst_port = 0;
9598   tcpudp_header_t *tcpudp;
9599
9600   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9601     {
9602       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9603         return 1;
9604       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9605         return 1;
9606       else if (unformat (input, "src_port"))
9607         src_port = 0xFFFF;
9608       else if (unformat (input, "dst_port"))
9609         dst_port = 0xFFFF;
9610       else
9611         return 0;
9612     }
9613
9614   if (!src_port && !dst_port)
9615     return 0;
9616
9617   u8 *mask = 0;
9618   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9619
9620   tcpudp = (tcpudp_header_t *) mask;
9621   tcpudp->src_port = src_port;
9622   tcpudp->dst_port = dst_port;
9623
9624   *maskp = mask;
9625
9626   return 1;
9627 }
9628
9629 uword
9630 unformat_ip4_mask (unformat_input_t * input, va_list * args)
9631 {
9632   u8 **maskp = va_arg (*args, u8 **);
9633   u8 *mask = 0;
9634   u8 found_something = 0;
9635   ip4_header_t *ip;
9636
9637 #define _(a) u8 a=0;
9638   foreach_ip4_proto_field;
9639 #undef _
9640   u8 version = 0;
9641   u8 hdr_length = 0;
9642
9643
9644   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9645     {
9646       if (unformat (input, "version"))
9647         version = 1;
9648       else if (unformat (input, "hdr_length"))
9649         hdr_length = 1;
9650       else if (unformat (input, "src"))
9651         src_address = 1;
9652       else if (unformat (input, "dst"))
9653         dst_address = 1;
9654       else if (unformat (input, "proto"))
9655         protocol = 1;
9656
9657 #define _(a) else if (unformat (input, #a)) a=1;
9658       foreach_ip4_proto_field
9659 #undef _
9660         else
9661         break;
9662     }
9663
9664 #define _(a) found_something += a;
9665   foreach_ip4_proto_field;
9666 #undef _
9667
9668   if (found_something == 0)
9669     return 0;
9670
9671   vec_validate (mask, sizeof (*ip) - 1);
9672
9673   ip = (ip4_header_t *) mask;
9674
9675 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
9676   foreach_ip4_proto_field;
9677 #undef _
9678
9679   ip->ip_version_and_header_length = 0;
9680
9681   if (version)
9682     ip->ip_version_and_header_length |= 0xF0;
9683
9684   if (hdr_length)
9685     ip->ip_version_and_header_length |= 0x0F;
9686
9687   *maskp = mask;
9688   return 1;
9689 }
9690
9691 #define foreach_ip6_proto_field                 \
9692 _(src_address)                                  \
9693 _(dst_address)                                  \
9694 _(payload_length)                               \
9695 _(hop_limit)                                    \
9696 _(protocol)
9697
9698 uword
9699 unformat_ip6_mask (unformat_input_t * input, va_list * args)
9700 {
9701   u8 **maskp = va_arg (*args, u8 **);
9702   u8 *mask = 0;
9703   u8 found_something = 0;
9704   ip6_header_t *ip;
9705   u32 ip_version_traffic_class_and_flow_label;
9706
9707 #define _(a) u8 a=0;
9708   foreach_ip6_proto_field;
9709 #undef _
9710   u8 version = 0;
9711   u8 traffic_class = 0;
9712   u8 flow_label = 0;
9713
9714   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9715     {
9716       if (unformat (input, "version"))
9717         version = 1;
9718       else if (unformat (input, "traffic-class"))
9719         traffic_class = 1;
9720       else if (unformat (input, "flow-label"))
9721         flow_label = 1;
9722       else if (unformat (input, "src"))
9723         src_address = 1;
9724       else if (unformat (input, "dst"))
9725         dst_address = 1;
9726       else if (unformat (input, "proto"))
9727         protocol = 1;
9728
9729 #define _(a) else if (unformat (input, #a)) a=1;
9730       foreach_ip6_proto_field
9731 #undef _
9732         else
9733         break;
9734     }
9735
9736 #define _(a) found_something += a;
9737   foreach_ip6_proto_field;
9738 #undef _
9739
9740   if (found_something == 0)
9741     return 0;
9742
9743   vec_validate (mask, sizeof (*ip) - 1);
9744
9745   ip = (ip6_header_t *) mask;
9746
9747 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
9748   foreach_ip6_proto_field;
9749 #undef _
9750
9751   ip_version_traffic_class_and_flow_label = 0;
9752
9753   if (version)
9754     ip_version_traffic_class_and_flow_label |= 0xF0000000;
9755
9756   if (traffic_class)
9757     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9758
9759   if (flow_label)
9760     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9761
9762   ip->ip_version_traffic_class_and_flow_label =
9763     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9764
9765   *maskp = mask;
9766   return 1;
9767 }
9768
9769 uword
9770 unformat_l3_mask (unformat_input_t * input, va_list * args)
9771 {
9772   u8 **maskp = va_arg (*args, u8 **);
9773
9774   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9775     {
9776       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9777         return 1;
9778       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9779         return 1;
9780       else
9781         break;
9782     }
9783   return 0;
9784 }
9785
9786 uword
9787 unformat_l2_mask (unformat_input_t * input, va_list * args)
9788 {
9789   u8 **maskp = va_arg (*args, u8 **);
9790   u8 *mask = 0;
9791   u8 src = 0;
9792   u8 dst = 0;
9793   u8 proto = 0;
9794   u8 tag1 = 0;
9795   u8 tag2 = 0;
9796   u8 ignore_tag1 = 0;
9797   u8 ignore_tag2 = 0;
9798   u8 cos1 = 0;
9799   u8 cos2 = 0;
9800   u8 dot1q = 0;
9801   u8 dot1ad = 0;
9802   int len = 14;
9803
9804   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9805     {
9806       if (unformat (input, "src"))
9807         src = 1;
9808       else if (unformat (input, "dst"))
9809         dst = 1;
9810       else if (unformat (input, "proto"))
9811         proto = 1;
9812       else if (unformat (input, "tag1"))
9813         tag1 = 1;
9814       else if (unformat (input, "tag2"))
9815         tag2 = 1;
9816       else if (unformat (input, "ignore-tag1"))
9817         ignore_tag1 = 1;
9818       else if (unformat (input, "ignore-tag2"))
9819         ignore_tag2 = 1;
9820       else if (unformat (input, "cos1"))
9821         cos1 = 1;
9822       else if (unformat (input, "cos2"))
9823         cos2 = 1;
9824       else if (unformat (input, "dot1q"))
9825         dot1q = 1;
9826       else if (unformat (input, "dot1ad"))
9827         dot1ad = 1;
9828       else
9829         break;
9830     }
9831   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9832        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9833     return 0;
9834
9835   if (tag1 || ignore_tag1 || cos1 || dot1q)
9836     len = 18;
9837   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9838     len = 22;
9839
9840   vec_validate (mask, len - 1);
9841
9842   if (dst)
9843     clib_memset (mask, 0xff, 6);
9844
9845   if (src)
9846     clib_memset (mask + 6, 0xff, 6);
9847
9848   if (tag2 || dot1ad)
9849     {
9850       /* inner vlan tag */
9851       if (tag2)
9852         {
9853           mask[19] = 0xff;
9854           mask[18] = 0x0f;
9855         }
9856       if (cos2)
9857         mask[18] |= 0xe0;
9858       if (proto)
9859         mask[21] = mask[20] = 0xff;
9860       if (tag1)
9861         {
9862           mask[15] = 0xff;
9863           mask[14] = 0x0f;
9864         }
9865       if (cos1)
9866         mask[14] |= 0xe0;
9867       *maskp = mask;
9868       return 1;
9869     }
9870   if (tag1 | dot1q)
9871     {
9872       if (tag1)
9873         {
9874           mask[15] = 0xff;
9875           mask[14] = 0x0f;
9876         }
9877       if (cos1)
9878         mask[14] |= 0xe0;
9879       if (proto)
9880         mask[16] = mask[17] = 0xff;
9881
9882       *maskp = mask;
9883       return 1;
9884     }
9885   if (cos2)
9886     mask[18] |= 0xe0;
9887   if (cos1)
9888     mask[14] |= 0xe0;
9889   if (proto)
9890     mask[12] = mask[13] = 0xff;
9891
9892   *maskp = mask;
9893   return 1;
9894 }
9895
9896 uword
9897 unformat_classify_mask (unformat_input_t * input, va_list * args)
9898 {
9899   u8 **maskp = va_arg (*args, u8 **);
9900   u32 *skipp = va_arg (*args, u32 *);
9901   u32 *matchp = va_arg (*args, u32 *);
9902   u32 match;
9903   u8 *mask = 0;
9904   u8 *l2 = 0;
9905   u8 *l3 = 0;
9906   u8 *l4 = 0;
9907   int i;
9908
9909   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9910     {
9911       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9912         ;
9913       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9914         ;
9915       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9916         ;
9917       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9918         ;
9919       else
9920         break;
9921     }
9922
9923   if (l4 && !l3)
9924     {
9925       vec_free (mask);
9926       vec_free (l2);
9927       vec_free (l4);
9928       return 0;
9929     }
9930
9931   if (mask || l2 || l3 || l4)
9932     {
9933       if (l2 || l3 || l4)
9934         {
9935           /* "With a free Ethernet header in every package" */
9936           if (l2 == 0)
9937             vec_validate (l2, 13);
9938           mask = l2;
9939           if (vec_len (l3))
9940             {
9941               vec_append (mask, l3);
9942               vec_free (l3);
9943             }
9944           if (vec_len (l4))
9945             {
9946               vec_append (mask, l4);
9947               vec_free (l4);
9948             }
9949         }
9950
9951       /* Scan forward looking for the first significant mask octet */
9952       for (i = 0; i < vec_len (mask); i++)
9953         if (mask[i])
9954           break;
9955
9956       /* compute (skip, match) params */
9957       *skipp = i / sizeof (u32x4);
9958       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9959
9960       /* Pad mask to an even multiple of the vector size */
9961       while (vec_len (mask) % sizeof (u32x4))
9962         vec_add1 (mask, 0);
9963
9964       match = vec_len (mask) / sizeof (u32x4);
9965
9966       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9967         {
9968           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9969           if (*tmp || *(tmp + 1))
9970             break;
9971           match--;
9972         }
9973       if (match == 0)
9974         clib_warning ("BUG: match 0");
9975
9976       _vec_len (mask) = match * sizeof (u32x4);
9977
9978       *matchp = match;
9979       *maskp = mask;
9980
9981       return 1;
9982     }
9983
9984   return 0;
9985 }
9986 #endif /* VPP_API_TEST_BUILTIN */
9987
9988 #define foreach_l2_next                         \
9989 _(drop, DROP)                                   \
9990 _(ethernet, ETHERNET_INPUT)                     \
9991 _(ip4, IP4_INPUT)                               \
9992 _(ip6, IP6_INPUT)
9993
9994 uword
9995 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9996 {
9997   u32 *miss_next_indexp = va_arg (*args, u32 *);
9998   u32 next_index = 0;
9999   u32 tmp;
10000
10001 #define _(n,N) \
10002   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10003   foreach_l2_next;
10004 #undef _
10005
10006   if (unformat (input, "%d", &tmp))
10007     {
10008       next_index = tmp;
10009       goto out;
10010     }
10011
10012   return 0;
10013
10014 out:
10015   *miss_next_indexp = next_index;
10016   return 1;
10017 }
10018
10019 #define foreach_ip_next                         \
10020 _(drop, DROP)                                   \
10021 _(local, LOCAL)                                 \
10022 _(rewrite, REWRITE)
10023
10024 uword
10025 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10026 {
10027   u32 *miss_next_indexp = va_arg (*args, u32 *);
10028   u32 next_index = 0;
10029   u32 tmp;
10030
10031 #define _(n,N) \
10032   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10033   foreach_ip_next;
10034 #undef _
10035
10036   if (unformat (input, "%d", &tmp))
10037     {
10038       next_index = tmp;
10039       goto out;
10040     }
10041
10042   return 0;
10043
10044 out:
10045   *miss_next_indexp = next_index;
10046   return 1;
10047 }
10048
10049 #define foreach_acl_next                        \
10050 _(deny, DENY)
10051
10052 uword
10053 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10054 {
10055   u32 *miss_next_indexp = va_arg (*args, u32 *);
10056   u32 next_index = 0;
10057   u32 tmp;
10058
10059 #define _(n,N) \
10060   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10061   foreach_acl_next;
10062 #undef _
10063
10064   if (unformat (input, "permit"))
10065     {
10066       next_index = ~0;
10067       goto out;
10068     }
10069   else if (unformat (input, "%d", &tmp))
10070     {
10071       next_index = tmp;
10072       goto out;
10073     }
10074
10075   return 0;
10076
10077 out:
10078   *miss_next_indexp = next_index;
10079   return 1;
10080 }
10081
10082 uword
10083 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10084 {
10085   u32 *r = va_arg (*args, u32 *);
10086
10087   if (unformat (input, "conform-color"))
10088     *r = POLICE_CONFORM;
10089   else if (unformat (input, "exceed-color"))
10090     *r = POLICE_EXCEED;
10091   else
10092     return 0;
10093
10094   return 1;
10095 }
10096
10097 static int
10098 api_classify_add_del_table (vat_main_t * vam)
10099 {
10100   unformat_input_t *i = vam->input;
10101   vl_api_classify_add_del_table_t *mp;
10102
10103   u32 nbuckets = 2;
10104   u32 skip = ~0;
10105   u32 match = ~0;
10106   int is_add = 1;
10107   int del_chain = 0;
10108   u32 table_index = ~0;
10109   u32 next_table_index = ~0;
10110   u32 miss_next_index = ~0;
10111   u32 memory_size = 32 << 20;
10112   u8 *mask = 0;
10113   u32 current_data_flag = 0;
10114   int current_data_offset = 0;
10115   int ret;
10116
10117   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10118     {
10119       if (unformat (i, "del"))
10120         is_add = 0;
10121       else if (unformat (i, "del-chain"))
10122         {
10123           is_add = 0;
10124           del_chain = 1;
10125         }
10126       else if (unformat (i, "buckets %d", &nbuckets))
10127         ;
10128       else if (unformat (i, "memory_size %d", &memory_size))
10129         ;
10130       else if (unformat (i, "skip %d", &skip))
10131         ;
10132       else if (unformat (i, "match %d", &match))
10133         ;
10134       else if (unformat (i, "table %d", &table_index))
10135         ;
10136       else if (unformat (i, "mask %U", unformat_classify_mask,
10137                          &mask, &skip, &match))
10138         ;
10139       else if (unformat (i, "next-table %d", &next_table_index))
10140         ;
10141       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10142                          &miss_next_index))
10143         ;
10144       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10145                          &miss_next_index))
10146         ;
10147       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10148                          &miss_next_index))
10149         ;
10150       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10151         ;
10152       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10153         ;
10154       else
10155         break;
10156     }
10157
10158   if (is_add && mask == 0)
10159     {
10160       errmsg ("Mask required");
10161       return -99;
10162     }
10163
10164   if (is_add && skip == ~0)
10165     {
10166       errmsg ("skip count required");
10167       return -99;
10168     }
10169
10170   if (is_add && match == ~0)
10171     {
10172       errmsg ("match count required");
10173       return -99;
10174     }
10175
10176   if (!is_add && table_index == ~0)
10177     {
10178       errmsg ("table index required for delete");
10179       return -99;
10180     }
10181
10182   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10183
10184   mp->is_add = is_add;
10185   mp->del_chain = del_chain;
10186   mp->table_index = ntohl (table_index);
10187   mp->nbuckets = ntohl (nbuckets);
10188   mp->memory_size = ntohl (memory_size);
10189   mp->skip_n_vectors = ntohl (skip);
10190   mp->match_n_vectors = ntohl (match);
10191   mp->next_table_index = ntohl (next_table_index);
10192   mp->miss_next_index = ntohl (miss_next_index);
10193   mp->current_data_flag = ntohl (current_data_flag);
10194   mp->current_data_offset = ntohl (current_data_offset);
10195   mp->mask_len = ntohl (vec_len (mask));
10196   clib_memcpy (mp->mask, mask, vec_len (mask));
10197
10198   vec_free (mask);
10199
10200   S (mp);
10201   W (ret);
10202   return ret;
10203 }
10204
10205 #if VPP_API_TEST_BUILTIN == 0
10206 uword
10207 unformat_l4_match (unformat_input_t * input, va_list * args)
10208 {
10209   u8 **matchp = va_arg (*args, u8 **);
10210
10211   u8 *proto_header = 0;
10212   int src_port = 0;
10213   int dst_port = 0;
10214
10215   tcpudp_header_t h;
10216
10217   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10218     {
10219       if (unformat (input, "src_port %d", &src_port))
10220         ;
10221       else if (unformat (input, "dst_port %d", &dst_port))
10222         ;
10223       else
10224         return 0;
10225     }
10226
10227   h.src_port = clib_host_to_net_u16 (src_port);
10228   h.dst_port = clib_host_to_net_u16 (dst_port);
10229   vec_validate (proto_header, sizeof (h) - 1);
10230   memcpy (proto_header, &h, sizeof (h));
10231
10232   *matchp = proto_header;
10233
10234   return 1;
10235 }
10236
10237 uword
10238 unformat_ip4_match (unformat_input_t * input, va_list * args)
10239 {
10240   u8 **matchp = va_arg (*args, u8 **);
10241   u8 *match = 0;
10242   ip4_header_t *ip;
10243   int version = 0;
10244   u32 version_val;
10245   int hdr_length = 0;
10246   u32 hdr_length_val;
10247   int src = 0, dst = 0;
10248   ip4_address_t src_val, dst_val;
10249   int proto = 0;
10250   u32 proto_val;
10251   int tos = 0;
10252   u32 tos_val;
10253   int length = 0;
10254   u32 length_val;
10255   int fragment_id = 0;
10256   u32 fragment_id_val;
10257   int ttl = 0;
10258   int ttl_val;
10259   int checksum = 0;
10260   u32 checksum_val;
10261
10262   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10263     {
10264       if (unformat (input, "version %d", &version_val))
10265         version = 1;
10266       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10267         hdr_length = 1;
10268       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10269         src = 1;
10270       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10271         dst = 1;
10272       else if (unformat (input, "proto %d", &proto_val))
10273         proto = 1;
10274       else if (unformat (input, "tos %d", &tos_val))
10275         tos = 1;
10276       else if (unformat (input, "length %d", &length_val))
10277         length = 1;
10278       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10279         fragment_id = 1;
10280       else if (unformat (input, "ttl %d", &ttl_val))
10281         ttl = 1;
10282       else if (unformat (input, "checksum %d", &checksum_val))
10283         checksum = 1;
10284       else
10285         break;
10286     }
10287
10288   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10289       + ttl + checksum == 0)
10290     return 0;
10291
10292   /*
10293    * Aligned because we use the real comparison functions
10294    */
10295   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10296
10297   ip = (ip4_header_t *) match;
10298
10299   /* These are realistically matched in practice */
10300   if (src)
10301     ip->src_address.as_u32 = src_val.as_u32;
10302
10303   if (dst)
10304     ip->dst_address.as_u32 = dst_val.as_u32;
10305
10306   if (proto)
10307     ip->protocol = proto_val;
10308
10309
10310   /* These are not, but they're included for completeness */
10311   if (version)
10312     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10313
10314   if (hdr_length)
10315     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10316
10317   if (tos)
10318     ip->tos = tos_val;
10319
10320   if (length)
10321     ip->length = clib_host_to_net_u16 (length_val);
10322
10323   if (ttl)
10324     ip->ttl = ttl_val;
10325
10326   if (checksum)
10327     ip->checksum = clib_host_to_net_u16 (checksum_val);
10328
10329   *matchp = match;
10330   return 1;
10331 }
10332
10333 uword
10334 unformat_ip6_match (unformat_input_t * input, va_list * args)
10335 {
10336   u8 **matchp = va_arg (*args, u8 **);
10337   u8 *match = 0;
10338   ip6_header_t *ip;
10339   int version = 0;
10340   u32 version_val;
10341   u8 traffic_class = 0;
10342   u32 traffic_class_val = 0;
10343   u8 flow_label = 0;
10344   u8 flow_label_val;
10345   int src = 0, dst = 0;
10346   ip6_address_t src_val, dst_val;
10347   int proto = 0;
10348   u32 proto_val;
10349   int payload_length = 0;
10350   u32 payload_length_val;
10351   int hop_limit = 0;
10352   int hop_limit_val;
10353   u32 ip_version_traffic_class_and_flow_label;
10354
10355   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10356     {
10357       if (unformat (input, "version %d", &version_val))
10358         version = 1;
10359       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10360         traffic_class = 1;
10361       else if (unformat (input, "flow_label %d", &flow_label_val))
10362         flow_label = 1;
10363       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10364         src = 1;
10365       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10366         dst = 1;
10367       else if (unformat (input, "proto %d", &proto_val))
10368         proto = 1;
10369       else if (unformat (input, "payload_length %d", &payload_length_val))
10370         payload_length = 1;
10371       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10372         hop_limit = 1;
10373       else
10374         break;
10375     }
10376
10377   if (version + traffic_class + flow_label + src + dst + proto +
10378       payload_length + hop_limit == 0)
10379     return 0;
10380
10381   /*
10382    * Aligned because we use the real comparison functions
10383    */
10384   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10385
10386   ip = (ip6_header_t *) match;
10387
10388   if (src)
10389     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10390
10391   if (dst)
10392     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10393
10394   if (proto)
10395     ip->protocol = proto_val;
10396
10397   ip_version_traffic_class_and_flow_label = 0;
10398
10399   if (version)
10400     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10401
10402   if (traffic_class)
10403     ip_version_traffic_class_and_flow_label |=
10404       (traffic_class_val & 0xFF) << 20;
10405
10406   if (flow_label)
10407     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10408
10409   ip->ip_version_traffic_class_and_flow_label =
10410     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10411
10412   if (payload_length)
10413     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10414
10415   if (hop_limit)
10416     ip->hop_limit = hop_limit_val;
10417
10418   *matchp = match;
10419   return 1;
10420 }
10421
10422 uword
10423 unformat_l3_match (unformat_input_t * input, va_list * args)
10424 {
10425   u8 **matchp = va_arg (*args, u8 **);
10426
10427   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10428     {
10429       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10430         return 1;
10431       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10432         return 1;
10433       else
10434         break;
10435     }
10436   return 0;
10437 }
10438
10439 uword
10440 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10441 {
10442   u8 *tagp = va_arg (*args, u8 *);
10443   u32 tag;
10444
10445   if (unformat (input, "%d", &tag))
10446     {
10447       tagp[0] = (tag >> 8) & 0x0F;
10448       tagp[1] = tag & 0xFF;
10449       return 1;
10450     }
10451
10452   return 0;
10453 }
10454
10455 uword
10456 unformat_l2_match (unformat_input_t * input, va_list * args)
10457 {
10458   u8 **matchp = va_arg (*args, u8 **);
10459   u8 *match = 0;
10460   u8 src = 0;
10461   u8 src_val[6];
10462   u8 dst = 0;
10463   u8 dst_val[6];
10464   u8 proto = 0;
10465   u16 proto_val;
10466   u8 tag1 = 0;
10467   u8 tag1_val[2];
10468   u8 tag2 = 0;
10469   u8 tag2_val[2];
10470   int len = 14;
10471   u8 ignore_tag1 = 0;
10472   u8 ignore_tag2 = 0;
10473   u8 cos1 = 0;
10474   u8 cos2 = 0;
10475   u32 cos1_val = 0;
10476   u32 cos2_val = 0;
10477
10478   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10479     {
10480       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10481         src = 1;
10482       else
10483         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10484         dst = 1;
10485       else if (unformat (input, "proto %U",
10486                          unformat_ethernet_type_host_byte_order, &proto_val))
10487         proto = 1;
10488       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10489         tag1 = 1;
10490       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10491         tag2 = 1;
10492       else if (unformat (input, "ignore-tag1"))
10493         ignore_tag1 = 1;
10494       else if (unformat (input, "ignore-tag2"))
10495         ignore_tag2 = 1;
10496       else if (unformat (input, "cos1 %d", &cos1_val))
10497         cos1 = 1;
10498       else if (unformat (input, "cos2 %d", &cos2_val))
10499         cos2 = 1;
10500       else
10501         break;
10502     }
10503   if ((src + dst + proto + tag1 + tag2 +
10504        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10505     return 0;
10506
10507   if (tag1 || ignore_tag1 || cos1)
10508     len = 18;
10509   if (tag2 || ignore_tag2 || cos2)
10510     len = 22;
10511
10512   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10513
10514   if (dst)
10515     clib_memcpy (match, dst_val, 6);
10516
10517   if (src)
10518     clib_memcpy (match + 6, src_val, 6);
10519
10520   if (tag2)
10521     {
10522       /* inner vlan tag */
10523       match[19] = tag2_val[1];
10524       match[18] = tag2_val[0];
10525       if (cos2)
10526         match[18] |= (cos2_val & 0x7) << 5;
10527       if (proto)
10528         {
10529           match[21] = proto_val & 0xff;
10530           match[20] = proto_val >> 8;
10531         }
10532       if (tag1)
10533         {
10534           match[15] = tag1_val[1];
10535           match[14] = tag1_val[0];
10536         }
10537       if (cos1)
10538         match[14] |= (cos1_val & 0x7) << 5;
10539       *matchp = match;
10540       return 1;
10541     }
10542   if (tag1)
10543     {
10544       match[15] = tag1_val[1];
10545       match[14] = tag1_val[0];
10546       if (proto)
10547         {
10548           match[17] = proto_val & 0xff;
10549           match[16] = proto_val >> 8;
10550         }
10551       if (cos1)
10552         match[14] |= (cos1_val & 0x7) << 5;
10553
10554       *matchp = match;
10555       return 1;
10556     }
10557   if (cos2)
10558     match[18] |= (cos2_val & 0x7) << 5;
10559   if (cos1)
10560     match[14] |= (cos1_val & 0x7) << 5;
10561   if (proto)
10562     {
10563       match[13] = proto_val & 0xff;
10564       match[12] = proto_val >> 8;
10565     }
10566
10567   *matchp = match;
10568   return 1;
10569 }
10570
10571 uword
10572 unformat_qos_source (unformat_input_t * input, va_list * args)
10573 {
10574   int *qs = va_arg (*args, int *);
10575
10576   if (unformat (input, "ip"))
10577     *qs = QOS_SOURCE_IP;
10578   else if (unformat (input, "mpls"))
10579     *qs = QOS_SOURCE_MPLS;
10580   else if (unformat (input, "ext"))
10581     *qs = QOS_SOURCE_EXT;
10582   else if (unformat (input, "vlan"))
10583     *qs = QOS_SOURCE_VLAN;
10584   else
10585     return 0;
10586
10587   return 1;
10588 }
10589 #endif
10590
10591 uword
10592 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10593 {
10594   u8 **matchp = va_arg (*args, u8 **);
10595   u32 skip_n_vectors = va_arg (*args, u32);
10596   u32 match_n_vectors = va_arg (*args, u32);
10597
10598   u8 *match = 0;
10599   u8 *l2 = 0;
10600   u8 *l3 = 0;
10601   u8 *l4 = 0;
10602
10603   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10604     {
10605       if (unformat (input, "hex %U", unformat_hex_string, &match))
10606         ;
10607       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10608         ;
10609       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10610         ;
10611       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10612         ;
10613       else
10614         break;
10615     }
10616
10617   if (l4 && !l3)
10618     {
10619       vec_free (match);
10620       vec_free (l2);
10621       vec_free (l4);
10622       return 0;
10623     }
10624
10625   if (match || l2 || l3 || l4)
10626     {
10627       if (l2 || l3 || l4)
10628         {
10629           /* "Win a free Ethernet header in every packet" */
10630           if (l2 == 0)
10631             vec_validate_aligned (l2, 13, sizeof (u32x4));
10632           match = l2;
10633           if (vec_len (l3))
10634             {
10635               vec_append_aligned (match, l3, sizeof (u32x4));
10636               vec_free (l3);
10637             }
10638           if (vec_len (l4))
10639             {
10640               vec_append_aligned (match, l4, sizeof (u32x4));
10641               vec_free (l4);
10642             }
10643         }
10644
10645       /* Make sure the vector is big enough even if key is all 0's */
10646       vec_validate_aligned
10647         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
10648          sizeof (u32x4));
10649
10650       /* Set size, include skipped vectors */
10651       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
10652
10653       *matchp = match;
10654
10655       return 1;
10656     }
10657
10658   return 0;
10659 }
10660
10661 static int
10662 api_classify_add_del_session (vat_main_t * vam)
10663 {
10664   unformat_input_t *i = vam->input;
10665   vl_api_classify_add_del_session_t *mp;
10666   int is_add = 1;
10667   u32 table_index = ~0;
10668   u32 hit_next_index = ~0;
10669   u32 opaque_index = ~0;
10670   u8 *match = 0;
10671   i32 advance = 0;
10672   u32 skip_n_vectors = 0;
10673   u32 match_n_vectors = 0;
10674   u32 action = 0;
10675   u32 metadata = 0;
10676   int ret;
10677
10678   /*
10679    * Warning: you have to supply skip_n and match_n
10680    * because the API client cant simply look at the classify
10681    * table object.
10682    */
10683
10684   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10685     {
10686       if (unformat (i, "del"))
10687         is_add = 0;
10688       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
10689                          &hit_next_index))
10690         ;
10691       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10692                          &hit_next_index))
10693         ;
10694       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
10695                          &hit_next_index))
10696         ;
10697       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10698         ;
10699       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10700         ;
10701       else if (unformat (i, "opaque-index %d", &opaque_index))
10702         ;
10703       else if (unformat (i, "skip_n %d", &skip_n_vectors))
10704         ;
10705       else if (unformat (i, "match_n %d", &match_n_vectors))
10706         ;
10707       else if (unformat (i, "match %U", api_unformat_classify_match,
10708                          &match, skip_n_vectors, match_n_vectors))
10709         ;
10710       else if (unformat (i, "advance %d", &advance))
10711         ;
10712       else if (unformat (i, "table-index %d", &table_index))
10713         ;
10714       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10715         action = 1;
10716       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10717         action = 2;
10718       else if (unformat (i, "action %d", &action))
10719         ;
10720       else if (unformat (i, "metadata %d", &metadata))
10721         ;
10722       else
10723         break;
10724     }
10725
10726   if (table_index == ~0)
10727     {
10728       errmsg ("Table index required");
10729       return -99;
10730     }
10731
10732   if (is_add && match == 0)
10733     {
10734       errmsg ("Match value required");
10735       return -99;
10736     }
10737
10738   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10739
10740   mp->is_add = is_add;
10741   mp->table_index = ntohl (table_index);
10742   mp->hit_next_index = ntohl (hit_next_index);
10743   mp->opaque_index = ntohl (opaque_index);
10744   mp->advance = ntohl (advance);
10745   mp->action = action;
10746   mp->metadata = ntohl (metadata);
10747   mp->match_len = ntohl (vec_len (match));
10748   clib_memcpy (mp->match, match, vec_len (match));
10749   vec_free (match);
10750
10751   S (mp);
10752   W (ret);
10753   return ret;
10754 }
10755
10756 static int
10757 api_classify_set_interface_ip_table (vat_main_t * vam)
10758 {
10759   unformat_input_t *i = vam->input;
10760   vl_api_classify_set_interface_ip_table_t *mp;
10761   u32 sw_if_index;
10762   int sw_if_index_set;
10763   u32 table_index = ~0;
10764   u8 is_ipv6 = 0;
10765   int ret;
10766
10767   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10768     {
10769       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10770         sw_if_index_set = 1;
10771       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10772         sw_if_index_set = 1;
10773       else if (unformat (i, "table %d", &table_index))
10774         ;
10775       else
10776         {
10777           clib_warning ("parse error '%U'", format_unformat_error, i);
10778           return -99;
10779         }
10780     }
10781
10782   if (sw_if_index_set == 0)
10783     {
10784       errmsg ("missing interface name or sw_if_index");
10785       return -99;
10786     }
10787
10788
10789   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10790
10791   mp->sw_if_index = ntohl (sw_if_index);
10792   mp->table_index = ntohl (table_index);
10793   mp->is_ipv6 = is_ipv6;
10794
10795   S (mp);
10796   W (ret);
10797   return ret;
10798 }
10799
10800 static int
10801 api_classify_set_interface_l2_tables (vat_main_t * vam)
10802 {
10803   unformat_input_t *i = vam->input;
10804   vl_api_classify_set_interface_l2_tables_t *mp;
10805   u32 sw_if_index;
10806   int sw_if_index_set;
10807   u32 ip4_table_index = ~0;
10808   u32 ip6_table_index = ~0;
10809   u32 other_table_index = ~0;
10810   u32 is_input = 1;
10811   int ret;
10812
10813   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10814     {
10815       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10816         sw_if_index_set = 1;
10817       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10818         sw_if_index_set = 1;
10819       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10820         ;
10821       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10822         ;
10823       else if (unformat (i, "other-table %d", &other_table_index))
10824         ;
10825       else if (unformat (i, "is-input %d", &is_input))
10826         ;
10827       else
10828         {
10829           clib_warning ("parse error '%U'", format_unformat_error, i);
10830           return -99;
10831         }
10832     }
10833
10834   if (sw_if_index_set == 0)
10835     {
10836       errmsg ("missing interface name or sw_if_index");
10837       return -99;
10838     }
10839
10840
10841   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10842
10843   mp->sw_if_index = ntohl (sw_if_index);
10844   mp->ip4_table_index = ntohl (ip4_table_index);
10845   mp->ip6_table_index = ntohl (ip6_table_index);
10846   mp->other_table_index = ntohl (other_table_index);
10847   mp->is_input = (u8) is_input;
10848
10849   S (mp);
10850   W (ret);
10851   return ret;
10852 }
10853
10854 static int
10855 api_set_ipfix_exporter (vat_main_t * vam)
10856 {
10857   unformat_input_t *i = vam->input;
10858   vl_api_set_ipfix_exporter_t *mp;
10859   ip4_address_t collector_address;
10860   u8 collector_address_set = 0;
10861   u32 collector_port = ~0;
10862   ip4_address_t src_address;
10863   u8 src_address_set = 0;
10864   u32 vrf_id = ~0;
10865   u32 path_mtu = ~0;
10866   u32 template_interval = ~0;
10867   u8 udp_checksum = 0;
10868   int ret;
10869
10870   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10871     {
10872       if (unformat (i, "collector_address %U", unformat_ip4_address,
10873                     &collector_address))
10874         collector_address_set = 1;
10875       else if (unformat (i, "collector_port %d", &collector_port))
10876         ;
10877       else if (unformat (i, "src_address %U", unformat_ip4_address,
10878                          &src_address))
10879         src_address_set = 1;
10880       else if (unformat (i, "vrf_id %d", &vrf_id))
10881         ;
10882       else if (unformat (i, "path_mtu %d", &path_mtu))
10883         ;
10884       else if (unformat (i, "template_interval %d", &template_interval))
10885         ;
10886       else if (unformat (i, "udp_checksum"))
10887         udp_checksum = 1;
10888       else
10889         break;
10890     }
10891
10892   if (collector_address_set == 0)
10893     {
10894       errmsg ("collector_address required");
10895       return -99;
10896     }
10897
10898   if (src_address_set == 0)
10899     {
10900       errmsg ("src_address required");
10901       return -99;
10902     }
10903
10904   M (SET_IPFIX_EXPORTER, mp);
10905
10906   memcpy (mp->collector_address.un.ip4, collector_address.data,
10907           sizeof (collector_address.data));
10908   mp->collector_port = htons ((u16) collector_port);
10909   memcpy (mp->src_address.un.ip4, src_address.data,
10910           sizeof (src_address.data));
10911   mp->vrf_id = htonl (vrf_id);
10912   mp->path_mtu = htonl (path_mtu);
10913   mp->template_interval = htonl (template_interval);
10914   mp->udp_checksum = udp_checksum;
10915
10916   S (mp);
10917   W (ret);
10918   return ret;
10919 }
10920
10921 static int
10922 api_set_ipfix_classify_stream (vat_main_t * vam)
10923 {
10924   unformat_input_t *i = vam->input;
10925   vl_api_set_ipfix_classify_stream_t *mp;
10926   u32 domain_id = 0;
10927   u32 src_port = UDP_DST_PORT_ipfix;
10928   int ret;
10929
10930   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10931     {
10932       if (unformat (i, "domain %d", &domain_id))
10933         ;
10934       else if (unformat (i, "src_port %d", &src_port))
10935         ;
10936       else
10937         {
10938           errmsg ("unknown input `%U'", format_unformat_error, i);
10939           return -99;
10940         }
10941     }
10942
10943   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10944
10945   mp->domain_id = htonl (domain_id);
10946   mp->src_port = htons ((u16) src_port);
10947
10948   S (mp);
10949   W (ret);
10950   return ret;
10951 }
10952
10953 static int
10954 api_ipfix_classify_table_add_del (vat_main_t * vam)
10955 {
10956   unformat_input_t *i = vam->input;
10957   vl_api_ipfix_classify_table_add_del_t *mp;
10958   int is_add = -1;
10959   u32 classify_table_index = ~0;
10960   u8 ip_version = 0;
10961   u8 transport_protocol = 255;
10962   int ret;
10963
10964   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10965     {
10966       if (unformat (i, "add"))
10967         is_add = 1;
10968       else if (unformat (i, "del"))
10969         is_add = 0;
10970       else if (unformat (i, "table %d", &classify_table_index))
10971         ;
10972       else if (unformat (i, "ip4"))
10973         ip_version = 4;
10974       else if (unformat (i, "ip6"))
10975         ip_version = 6;
10976       else if (unformat (i, "tcp"))
10977         transport_protocol = 6;
10978       else if (unformat (i, "udp"))
10979         transport_protocol = 17;
10980       else
10981         {
10982           errmsg ("unknown input `%U'", format_unformat_error, i);
10983           return -99;
10984         }
10985     }
10986
10987   if (is_add == -1)
10988     {
10989       errmsg ("expecting: add|del");
10990       return -99;
10991     }
10992   if (classify_table_index == ~0)
10993     {
10994       errmsg ("classifier table not specified");
10995       return -99;
10996     }
10997   if (ip_version == 0)
10998     {
10999       errmsg ("IP version not specified");
11000       return -99;
11001     }
11002
11003   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11004
11005   mp->is_add = is_add;
11006   mp->table_id = htonl (classify_table_index);
11007   mp->ip_version = ip_version;
11008   mp->transport_protocol = transport_protocol;
11009
11010   S (mp);
11011   W (ret);
11012   return ret;
11013 }
11014
11015 static int
11016 api_get_node_index (vat_main_t * vam)
11017 {
11018   unformat_input_t *i = vam->input;
11019   vl_api_get_node_index_t *mp;
11020   u8 *name = 0;
11021   int ret;
11022
11023   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11024     {
11025       if (unformat (i, "node %s", &name))
11026         ;
11027       else
11028         break;
11029     }
11030   if (name == 0)
11031     {
11032       errmsg ("node name required");
11033       return -99;
11034     }
11035   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11036     {
11037       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11038       return -99;
11039     }
11040
11041   M (GET_NODE_INDEX, mp);
11042   clib_memcpy (mp->node_name, name, vec_len (name));
11043   vec_free (name);
11044
11045   S (mp);
11046   W (ret);
11047   return ret;
11048 }
11049
11050 static int
11051 api_get_next_index (vat_main_t * vam)
11052 {
11053   unformat_input_t *i = vam->input;
11054   vl_api_get_next_index_t *mp;
11055   u8 *node_name = 0, *next_node_name = 0;
11056   int ret;
11057
11058   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11059     {
11060       if (unformat (i, "node-name %s", &node_name))
11061         ;
11062       else if (unformat (i, "next-node-name %s", &next_node_name))
11063         break;
11064     }
11065
11066   if (node_name == 0)
11067     {
11068       errmsg ("node name required");
11069       return -99;
11070     }
11071   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11072     {
11073       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11074       return -99;
11075     }
11076
11077   if (next_node_name == 0)
11078     {
11079       errmsg ("next node name required");
11080       return -99;
11081     }
11082   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11083     {
11084       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11085       return -99;
11086     }
11087
11088   M (GET_NEXT_INDEX, mp);
11089   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11090   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11091   vec_free (node_name);
11092   vec_free (next_node_name);
11093
11094   S (mp);
11095   W (ret);
11096   return ret;
11097 }
11098
11099 static int
11100 api_add_node_next (vat_main_t * vam)
11101 {
11102   unformat_input_t *i = vam->input;
11103   vl_api_add_node_next_t *mp;
11104   u8 *name = 0;
11105   u8 *next = 0;
11106   int ret;
11107
11108   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11109     {
11110       if (unformat (i, "node %s", &name))
11111         ;
11112       else if (unformat (i, "next %s", &next))
11113         ;
11114       else
11115         break;
11116     }
11117   if (name == 0)
11118     {
11119       errmsg ("node name required");
11120       return -99;
11121     }
11122   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11123     {
11124       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11125       return -99;
11126     }
11127   if (next == 0)
11128     {
11129       errmsg ("next node required");
11130       return -99;
11131     }
11132   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11133     {
11134       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11135       return -99;
11136     }
11137
11138   M (ADD_NODE_NEXT, mp);
11139   clib_memcpy (mp->node_name, name, vec_len (name));
11140   clib_memcpy (mp->next_name, next, vec_len (next));
11141   vec_free (name);
11142   vec_free (next);
11143
11144   S (mp);
11145   W (ret);
11146   return ret;
11147 }
11148
11149 static int
11150 api_l2tpv3_create_tunnel (vat_main_t * vam)
11151 {
11152   unformat_input_t *i = vam->input;
11153   ip6_address_t client_address, our_address;
11154   int client_address_set = 0;
11155   int our_address_set = 0;
11156   u32 local_session_id = 0;
11157   u32 remote_session_id = 0;
11158   u64 local_cookie = 0;
11159   u64 remote_cookie = 0;
11160   u8 l2_sublayer_present = 0;
11161   vl_api_l2tpv3_create_tunnel_t *mp;
11162   int ret;
11163
11164   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11165     {
11166       if (unformat (i, "client_address %U", unformat_ip6_address,
11167                     &client_address))
11168         client_address_set = 1;
11169       else if (unformat (i, "our_address %U", unformat_ip6_address,
11170                          &our_address))
11171         our_address_set = 1;
11172       else if (unformat (i, "local_session_id %d", &local_session_id))
11173         ;
11174       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11175         ;
11176       else if (unformat (i, "local_cookie %lld", &local_cookie))
11177         ;
11178       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11179         ;
11180       else if (unformat (i, "l2-sublayer-present"))
11181         l2_sublayer_present = 1;
11182       else
11183         break;
11184     }
11185
11186   if (client_address_set == 0)
11187     {
11188       errmsg ("client_address required");
11189       return -99;
11190     }
11191
11192   if (our_address_set == 0)
11193     {
11194       errmsg ("our_address required");
11195       return -99;
11196     }
11197
11198   M (L2TPV3_CREATE_TUNNEL, mp);
11199
11200   clib_memcpy (mp->client_address.un.ip6, client_address.as_u8,
11201                sizeof (ip6_address_t));
11202
11203   clib_memcpy (mp->our_address.un.ip6, our_address.as_u8,
11204                sizeof (ip6_address_t));
11205
11206   mp->local_session_id = ntohl (local_session_id);
11207   mp->remote_session_id = ntohl (remote_session_id);
11208   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11209   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11210   mp->l2_sublayer_present = l2_sublayer_present;
11211
11212   S (mp);
11213   W (ret);
11214   return ret;
11215 }
11216
11217 static int
11218 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11219 {
11220   unformat_input_t *i = vam->input;
11221   u32 sw_if_index;
11222   u8 sw_if_index_set = 0;
11223   u64 new_local_cookie = 0;
11224   u64 new_remote_cookie = 0;
11225   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11226   int ret;
11227
11228   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11229     {
11230       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11231         sw_if_index_set = 1;
11232       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11233         sw_if_index_set = 1;
11234       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11235         ;
11236       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11237         ;
11238       else
11239         break;
11240     }
11241
11242   if (sw_if_index_set == 0)
11243     {
11244       errmsg ("missing interface name or sw_if_index");
11245       return -99;
11246     }
11247
11248   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11249
11250   mp->sw_if_index = ntohl (sw_if_index);
11251   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11252   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11253
11254   S (mp);
11255   W (ret);
11256   return ret;
11257 }
11258
11259 static int
11260 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11261 {
11262   unformat_input_t *i = vam->input;
11263   vl_api_l2tpv3_interface_enable_disable_t *mp;
11264   u32 sw_if_index;
11265   u8 sw_if_index_set = 0;
11266   u8 enable_disable = 1;
11267   int ret;
11268
11269   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11270     {
11271       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11272         sw_if_index_set = 1;
11273       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11274         sw_if_index_set = 1;
11275       else if (unformat (i, "enable"))
11276         enable_disable = 1;
11277       else if (unformat (i, "disable"))
11278         enable_disable = 0;
11279       else
11280         break;
11281     }
11282
11283   if (sw_if_index_set == 0)
11284     {
11285       errmsg ("missing interface name or sw_if_index");
11286       return -99;
11287     }
11288
11289   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11290
11291   mp->sw_if_index = ntohl (sw_if_index);
11292   mp->enable_disable = enable_disable;
11293
11294   S (mp);
11295   W (ret);
11296   return ret;
11297 }
11298
11299 static int
11300 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11301 {
11302   unformat_input_t *i = vam->input;
11303   vl_api_l2tpv3_set_lookup_key_t *mp;
11304   u8 key = ~0;
11305   int ret;
11306
11307   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11308     {
11309       if (unformat (i, "lookup_v6_src"))
11310         key = L2T_LOOKUP_SRC_ADDRESS;
11311       else if (unformat (i, "lookup_v6_dst"))
11312         key = L2T_LOOKUP_DST_ADDRESS;
11313       else if (unformat (i, "lookup_session_id"))
11314         key = L2T_LOOKUP_SESSION_ID;
11315       else
11316         break;
11317     }
11318
11319   if (key == (u8) ~ 0)
11320     {
11321       errmsg ("l2tp session lookup key unset");
11322       return -99;
11323     }
11324
11325   M (L2TPV3_SET_LOOKUP_KEY, mp);
11326
11327   mp->key = key;
11328
11329   S (mp);
11330   W (ret);
11331   return ret;
11332 }
11333
11334 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11335   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11336 {
11337   vat_main_t *vam = &vat_main;
11338
11339   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11340          format_ip6_address, mp->our_address,
11341          format_ip6_address, mp->client_address,
11342          clib_net_to_host_u32 (mp->sw_if_index));
11343
11344   print (vam->ofp,
11345          "   local cookies %016llx %016llx remote cookie %016llx",
11346          clib_net_to_host_u64 (mp->local_cookie[0]),
11347          clib_net_to_host_u64 (mp->local_cookie[1]),
11348          clib_net_to_host_u64 (mp->remote_cookie));
11349
11350   print (vam->ofp, "   local session-id %d remote session-id %d",
11351          clib_net_to_host_u32 (mp->local_session_id),
11352          clib_net_to_host_u32 (mp->remote_session_id));
11353
11354   print (vam->ofp, "   l2 specific sublayer %s\n",
11355          mp->l2_sublayer_present ? "preset" : "absent");
11356
11357 }
11358
11359 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11360   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11361 {
11362   vat_main_t *vam = &vat_main;
11363   vat_json_node_t *node = NULL;
11364   struct in6_addr addr;
11365
11366   if (VAT_JSON_ARRAY != vam->json_tree.type)
11367     {
11368       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11369       vat_json_init_array (&vam->json_tree);
11370     }
11371   node = vat_json_array_add (&vam->json_tree);
11372
11373   vat_json_init_object (node);
11374
11375   clib_memcpy (&addr, mp->our_address.un.ip6, sizeof (addr));
11376   vat_json_object_add_ip6 (node, "our_address", addr);
11377   clib_memcpy (&addr, mp->client_address.un.ip6, sizeof (addr));
11378   vat_json_object_add_ip6 (node, "client_address", addr);
11379
11380   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11381   vat_json_init_array (lc);
11382   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11383   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11384   vat_json_object_add_uint (node, "remote_cookie",
11385                             clib_net_to_host_u64 (mp->remote_cookie));
11386
11387   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11388   vat_json_object_add_uint (node, "local_session_id",
11389                             clib_net_to_host_u32 (mp->local_session_id));
11390   vat_json_object_add_uint (node, "remote_session_id",
11391                             clib_net_to_host_u32 (mp->remote_session_id));
11392   vat_json_object_add_string_copy (node, "l2_sublayer",
11393                                    mp->l2_sublayer_present ? (u8 *) "present"
11394                                    : (u8 *) "absent");
11395 }
11396
11397 static int
11398 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11399 {
11400   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11401   vl_api_control_ping_t *mp_ping;
11402   int ret;
11403
11404   /* Get list of l2tpv3-tunnel interfaces */
11405   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11406   S (mp);
11407
11408   /* Use a control ping for synchronization */
11409   MPING (CONTROL_PING, mp_ping);
11410   S (mp_ping);
11411
11412   W (ret);
11413   return ret;
11414 }
11415
11416
11417 static void vl_api_sw_interface_tap_v2_details_t_handler
11418   (vl_api_sw_interface_tap_v2_details_t * mp)
11419 {
11420   vat_main_t *vam = &vat_main;
11421
11422   u8 *ip4 =
11423     format (0, "%U/%d", format_ip4_address, mp->host_ip4_prefix.address,
11424             mp->host_ip4_prefix.len);
11425   u8 *ip6 =
11426     format (0, "%U/%d", format_ip6_address, mp->host_ip6_prefix.address,
11427             mp->host_ip6_prefix.len);
11428
11429   print (vam->ofp,
11430          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
11431          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
11432          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11433          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
11434          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
11435
11436   vec_free (ip4);
11437   vec_free (ip6);
11438 }
11439
11440 static void vl_api_sw_interface_tap_v2_details_t_handler_json
11441   (vl_api_sw_interface_tap_v2_details_t * mp)
11442 {
11443   vat_main_t *vam = &vat_main;
11444   vat_json_node_t *node = NULL;
11445
11446   if (VAT_JSON_ARRAY != vam->json_tree.type)
11447     {
11448       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11449       vat_json_init_array (&vam->json_tree);
11450     }
11451   node = vat_json_array_add (&vam->json_tree);
11452
11453   vat_json_init_object (node);
11454   vat_json_object_add_uint (node, "id", ntohl (mp->id));
11455   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11456   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
11457   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11458   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11459   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11460   vat_json_object_add_string_copy (node, "host_mac_addr",
11461                                    format (0, "%U", format_ethernet_address,
11462                                            &mp->host_mac_addr));
11463   vat_json_object_add_string_copy (node, "host_namespace",
11464                                    mp->host_namespace);
11465   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
11466   vat_json_object_add_string_copy (node, "host_ip4_addr",
11467                                    format (0, "%U/%d", format_ip4_address,
11468                                            mp->host_ip4_prefix.address,
11469                                            mp->host_ip4_prefix.len));
11470   vat_json_object_add_string_copy (node, "host_ip6_prefix",
11471                                    format (0, "%U/%d", format_ip6_address,
11472                                            mp->host_ip6_prefix.address,
11473                                            mp->host_ip6_prefix.len));
11474
11475 }
11476
11477 static int
11478 api_sw_interface_tap_v2_dump (vat_main_t * vam)
11479 {
11480   vl_api_sw_interface_tap_v2_dump_t *mp;
11481   vl_api_control_ping_t *mp_ping;
11482   int ret;
11483
11484   print (vam->ofp,
11485          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
11486          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
11487          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
11488          "host_ip6_addr");
11489
11490   /* Get list of tap interfaces */
11491   M (SW_INTERFACE_TAP_V2_DUMP, mp);
11492   S (mp);
11493
11494   /* Use a control ping for synchronization */
11495   MPING (CONTROL_PING, mp_ping);
11496   S (mp_ping);
11497
11498   W (ret);
11499   return ret;
11500 }
11501
11502 static void vl_api_sw_interface_virtio_pci_details_t_handler
11503   (vl_api_sw_interface_virtio_pci_details_t * mp)
11504 {
11505   vat_main_t *vam = &vat_main;
11506
11507   typedef union
11508   {
11509     struct
11510     {
11511       u16 domain;
11512       u8 bus;
11513       u8 slot:5;
11514       u8 function:3;
11515     };
11516     u32 as_u32;
11517   } pci_addr_t;
11518   pci_addr_t addr;
11519
11520   addr.domain = ntohs (mp->pci_addr.domain);
11521   addr.bus = mp->pci_addr.bus;
11522   addr.slot = mp->pci_addr.slot;
11523   addr.function = mp->pci_addr.function;
11524
11525   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
11526                          addr.slot, addr.function);
11527
11528   print (vam->ofp,
11529          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
11530          pci_addr, ntohl (mp->sw_if_index),
11531          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11532          format_ethernet_address, mp->mac_addr,
11533          clib_net_to_host_u64 (mp->features));
11534   vec_free (pci_addr);
11535 }
11536
11537 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
11538   (vl_api_sw_interface_virtio_pci_details_t * mp)
11539 {
11540   vat_main_t *vam = &vat_main;
11541   vat_json_node_t *node = NULL;
11542   vlib_pci_addr_t pci_addr;
11543
11544   if (VAT_JSON_ARRAY != vam->json_tree.type)
11545     {
11546       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11547       vat_json_init_array (&vam->json_tree);
11548     }
11549   node = vat_json_array_add (&vam->json_tree);
11550
11551   pci_addr.domain = ntohs (mp->pci_addr.domain);
11552   pci_addr.bus = mp->pci_addr.bus;
11553   pci_addr.slot = mp->pci_addr.slot;
11554   pci_addr.function = mp->pci_addr.function;
11555
11556   vat_json_init_object (node);
11557   vat_json_object_add_uint (node, "pci-addr", pci_addr.as_u32);
11558   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11559   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11560   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11561   vat_json_object_add_uint (node, "features",
11562                             clib_net_to_host_u64 (mp->features));
11563   vat_json_object_add_string_copy (node, "mac_addr",
11564                                    format (0, "%U", format_ethernet_address,
11565                                            &mp->mac_addr));
11566 }
11567
11568 static int
11569 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
11570 {
11571   vl_api_sw_interface_virtio_pci_dump_t *mp;
11572   vl_api_control_ping_t *mp_ping;
11573   int ret;
11574
11575   print (vam->ofp,
11576          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
11577          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
11578          "mac_addr", "features");
11579
11580   /* Get list of tap interfaces */
11581   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
11582   S (mp);
11583
11584   /* Use a control ping for synchronization */
11585   MPING (CONTROL_PING, mp_ping);
11586   S (mp_ping);
11587
11588   W (ret);
11589   return ret;
11590 }
11591
11592 static int
11593 api_vxlan_offload_rx (vat_main_t * vam)
11594 {
11595   unformat_input_t *line_input = vam->input;
11596   vl_api_vxlan_offload_rx_t *mp;
11597   u32 hw_if_index = ~0, rx_if_index = ~0;
11598   u8 is_add = 1;
11599   int ret;
11600
11601   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11602     {
11603       if (unformat (line_input, "del"))
11604         is_add = 0;
11605       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
11606                          &hw_if_index))
11607         ;
11608       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
11609         ;
11610       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
11611                          &rx_if_index))
11612         ;
11613       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
11614         ;
11615       else
11616         {
11617           errmsg ("parse error '%U'", format_unformat_error, line_input);
11618           return -99;
11619         }
11620     }
11621
11622   if (hw_if_index == ~0)
11623     {
11624       errmsg ("no hw interface");
11625       return -99;
11626     }
11627
11628   if (rx_if_index == ~0)
11629     {
11630       errmsg ("no rx tunnel");
11631       return -99;
11632     }
11633
11634   M (VXLAN_OFFLOAD_RX, mp);
11635
11636   mp->hw_if_index = ntohl (hw_if_index);
11637   mp->sw_if_index = ntohl (rx_if_index);
11638   mp->enable = is_add;
11639
11640   S (mp);
11641   W (ret);
11642   return ret;
11643 }
11644
11645 static uword unformat_vxlan_decap_next
11646   (unformat_input_t * input, va_list * args)
11647 {
11648   u32 *result = va_arg (*args, u32 *);
11649   u32 tmp;
11650
11651   if (unformat (input, "l2"))
11652     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11653   else if (unformat (input, "%d", &tmp))
11654     *result = tmp;
11655   else
11656     return 0;
11657   return 1;
11658 }
11659
11660 static int
11661 api_vxlan_add_del_tunnel (vat_main_t * vam)
11662 {
11663   unformat_input_t *line_input = vam->input;
11664   vl_api_vxlan_add_del_tunnel_t *mp;
11665   ip46_address_t src, dst;
11666   u8 is_add = 1;
11667   u8 ipv4_set = 0, ipv6_set = 0;
11668   u8 src_set = 0;
11669   u8 dst_set = 0;
11670   u8 grp_set = 0;
11671   u32 instance = ~0;
11672   u32 mcast_sw_if_index = ~0;
11673   u32 encap_vrf_id = 0;
11674   u32 decap_next_index = ~0;
11675   u32 vni = 0;
11676   int ret;
11677
11678   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11679   clib_memset (&src, 0, sizeof src);
11680   clib_memset (&dst, 0, sizeof dst);
11681
11682   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11683     {
11684       if (unformat (line_input, "del"))
11685         is_add = 0;
11686       else if (unformat (line_input, "instance %d", &instance))
11687         ;
11688       else
11689         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11690         {
11691           ipv4_set = 1;
11692           src_set = 1;
11693         }
11694       else
11695         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11696         {
11697           ipv4_set = 1;
11698           dst_set = 1;
11699         }
11700       else
11701         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11702         {
11703           ipv6_set = 1;
11704           src_set = 1;
11705         }
11706       else
11707         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11708         {
11709           ipv6_set = 1;
11710           dst_set = 1;
11711         }
11712       else if (unformat (line_input, "group %U %U",
11713                          unformat_ip4_address, &dst.ip4,
11714                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11715         {
11716           grp_set = dst_set = 1;
11717           ipv4_set = 1;
11718         }
11719       else if (unformat (line_input, "group %U",
11720                          unformat_ip4_address, &dst.ip4))
11721         {
11722           grp_set = dst_set = 1;
11723           ipv4_set = 1;
11724         }
11725       else if (unformat (line_input, "group %U %U",
11726                          unformat_ip6_address, &dst.ip6,
11727                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11728         {
11729           grp_set = dst_set = 1;
11730           ipv6_set = 1;
11731         }
11732       else if (unformat (line_input, "group %U",
11733                          unformat_ip6_address, &dst.ip6))
11734         {
11735           grp_set = dst_set = 1;
11736           ipv6_set = 1;
11737         }
11738       else
11739         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11740         ;
11741       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11742         ;
11743       else if (unformat (line_input, "decap-next %U",
11744                          unformat_vxlan_decap_next, &decap_next_index))
11745         ;
11746       else if (unformat (line_input, "vni %d", &vni))
11747         ;
11748       else
11749         {
11750           errmsg ("parse error '%U'", format_unformat_error, line_input);
11751           return -99;
11752         }
11753     }
11754
11755   if (src_set == 0)
11756     {
11757       errmsg ("tunnel src address not specified");
11758       return -99;
11759     }
11760   if (dst_set == 0)
11761     {
11762       errmsg ("tunnel dst address not specified");
11763       return -99;
11764     }
11765
11766   if (grp_set && !ip46_address_is_multicast (&dst))
11767     {
11768       errmsg ("tunnel group address not multicast");
11769       return -99;
11770     }
11771   if (grp_set && mcast_sw_if_index == ~0)
11772     {
11773       errmsg ("tunnel nonexistent multicast device");
11774       return -99;
11775     }
11776   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11777     {
11778       errmsg ("tunnel dst address must be unicast");
11779       return -99;
11780     }
11781
11782
11783   if (ipv4_set && ipv6_set)
11784     {
11785       errmsg ("both IPv4 and IPv6 addresses specified");
11786       return -99;
11787     }
11788
11789   if ((vni == 0) || (vni >> 24))
11790     {
11791       errmsg ("vni not specified or out of range");
11792       return -99;
11793     }
11794
11795   M (VXLAN_ADD_DEL_TUNNEL, mp);
11796
11797   if (ipv6_set)
11798     {
11799       clib_memcpy (mp->src_address.un.ip6, &src.ip6, sizeof (src.ip6));
11800       clib_memcpy (mp->dst_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
11801     }
11802   else
11803     {
11804       clib_memcpy (mp->src_address.un.ip4, &src.ip4, sizeof (src.ip4));
11805       clib_memcpy (mp->dst_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
11806     }
11807   mp->src_address.af = ipv6_set;
11808   mp->dst_address.af = ipv6_set;
11809
11810   mp->instance = htonl (instance);
11811   mp->encap_vrf_id = ntohl (encap_vrf_id);
11812   mp->decap_next_index = ntohl (decap_next_index);
11813   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11814   mp->vni = ntohl (vni);
11815   mp->is_add = is_add;
11816
11817   S (mp);
11818   W (ret);
11819   return ret;
11820 }
11821
11822 static void vl_api_vxlan_tunnel_details_t_handler
11823   (vl_api_vxlan_tunnel_details_t * mp)
11824 {
11825   vat_main_t *vam = &vat_main;
11826   ip46_address_t src =
11827     to_ip46 (mp->dst_address.af, (u8 *) & mp->dst_address.un);
11828   ip46_address_t dst =
11829     to_ip46 (mp->dst_address.af, (u8 *) & mp->src_address.un);
11830
11831   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
11832          ntohl (mp->sw_if_index),
11833          ntohl (mp->instance),
11834          format_ip46_address, &src, IP46_TYPE_ANY,
11835          format_ip46_address, &dst, IP46_TYPE_ANY,
11836          ntohl (mp->encap_vrf_id),
11837          ntohl (mp->decap_next_index), ntohl (mp->vni),
11838          ntohl (mp->mcast_sw_if_index));
11839 }
11840
11841 static void vl_api_vxlan_tunnel_details_t_handler_json
11842   (vl_api_vxlan_tunnel_details_t * mp)
11843 {
11844   vat_main_t *vam = &vat_main;
11845   vat_json_node_t *node = NULL;
11846
11847   if (VAT_JSON_ARRAY != vam->json_tree.type)
11848     {
11849       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11850       vat_json_init_array (&vam->json_tree);
11851     }
11852   node = vat_json_array_add (&vam->json_tree);
11853
11854   vat_json_init_object (node);
11855   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11856
11857   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
11858
11859   if (mp->src_address.af)
11860     {
11861       struct in6_addr ip6;
11862
11863       clib_memcpy (&ip6, mp->src_address.un.ip6, sizeof (ip6));
11864       vat_json_object_add_ip6 (node, "src_address", ip6);
11865       clib_memcpy (&ip6, mp->dst_address.un.ip6, sizeof (ip6));
11866       vat_json_object_add_ip6 (node, "dst_address", ip6);
11867     }
11868   else
11869     {
11870       struct in_addr ip4;
11871
11872       clib_memcpy (&ip4, mp->src_address.un.ip4, sizeof (ip4));
11873       vat_json_object_add_ip4 (node, "src_address", ip4);
11874       clib_memcpy (&ip4, mp->dst_address.un.ip4, sizeof (ip4));
11875       vat_json_object_add_ip4 (node, "dst_address", ip4);
11876     }
11877   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11878   vat_json_object_add_uint (node, "decap_next_index",
11879                             ntohl (mp->decap_next_index));
11880   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11881   vat_json_object_add_uint (node, "mcast_sw_if_index",
11882                             ntohl (mp->mcast_sw_if_index));
11883 }
11884
11885 static int
11886 api_vxlan_tunnel_dump (vat_main_t * vam)
11887 {
11888   unformat_input_t *i = vam->input;
11889   vl_api_vxlan_tunnel_dump_t *mp;
11890   vl_api_control_ping_t *mp_ping;
11891   u32 sw_if_index;
11892   u8 sw_if_index_set = 0;
11893   int ret;
11894
11895   /* Parse args required to build the message */
11896   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11897     {
11898       if (unformat (i, "sw_if_index %d", &sw_if_index))
11899         sw_if_index_set = 1;
11900       else
11901         break;
11902     }
11903
11904   if (sw_if_index_set == 0)
11905     {
11906       sw_if_index = ~0;
11907     }
11908
11909   if (!vam->json_output)
11910     {
11911       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
11912              "sw_if_index", "instance", "src_address", "dst_address",
11913              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
11914     }
11915
11916   /* Get list of vxlan-tunnel interfaces */
11917   M (VXLAN_TUNNEL_DUMP, mp);
11918
11919   mp->sw_if_index = htonl (sw_if_index);
11920
11921   S (mp);
11922
11923   /* Use a control ping for synchronization */
11924   MPING (CONTROL_PING, mp_ping);
11925   S (mp_ping);
11926
11927   W (ret);
11928   return ret;
11929 }
11930
11931 static int
11932 api_gre_tunnel_add_del (vat_main_t * vam)
11933 {
11934   unformat_input_t *line_input = vam->input;
11935   vl_api_address_t src = { }, dst =
11936   {
11937   };
11938   vl_api_gre_tunnel_add_del_t *mp;
11939   vl_api_gre_tunnel_type_t t_type;
11940   u8 is_add = 1;
11941   u8 src_set = 0;
11942   u8 dst_set = 0;
11943   u32 outer_table_id = 0;
11944   u32 session_id = 0;
11945   u32 instance = ~0;
11946   int ret;
11947
11948   t_type = GRE_API_TUNNEL_TYPE_L3;
11949
11950   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11951     {
11952       if (unformat (line_input, "del"))
11953         is_add = 0;
11954       else if (unformat (line_input, "instance %d", &instance))
11955         ;
11956       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
11957         {
11958           src_set = 1;
11959         }
11960       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
11961         {
11962           dst_set = 1;
11963         }
11964       else if (unformat (line_input, "outer-table-id %d", &outer_table_id))
11965         ;
11966       else if (unformat (line_input, "teb"))
11967         t_type = GRE_API_TUNNEL_TYPE_TEB;
11968       else if (unformat (line_input, "erspan %d", &session_id))
11969         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
11970       else
11971         {
11972           errmsg ("parse error '%U'", format_unformat_error, line_input);
11973           return -99;
11974         }
11975     }
11976
11977   if (src_set == 0)
11978     {
11979       errmsg ("tunnel src address not specified");
11980       return -99;
11981     }
11982   if (dst_set == 0)
11983     {
11984       errmsg ("tunnel dst address not specified");
11985       return -99;
11986     }
11987
11988   M (GRE_TUNNEL_ADD_DEL, mp);
11989
11990   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
11991   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
11992
11993   mp->tunnel.instance = htonl (instance);
11994   mp->tunnel.outer_table_id = htonl (outer_table_id);
11995   mp->is_add = is_add;
11996   mp->tunnel.session_id = htons ((u16) session_id);
11997   mp->tunnel.type = htonl (t_type);
11998
11999   S (mp);
12000   W (ret);
12001   return ret;
12002 }
12003
12004 static void vl_api_gre_tunnel_details_t_handler
12005   (vl_api_gre_tunnel_details_t * mp)
12006 {
12007   vat_main_t *vam = &vat_main;
12008
12009   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
12010          ntohl (mp->tunnel.sw_if_index),
12011          ntohl (mp->tunnel.instance),
12012          format_vl_api_address, &mp->tunnel.src,
12013          format_vl_api_address, &mp->tunnel.dst,
12014          mp->tunnel.type, ntohl (mp->tunnel.outer_table_id),
12015          ntohl (mp->tunnel.session_id));
12016 }
12017
12018 static void vl_api_gre_tunnel_details_t_handler_json
12019   (vl_api_gre_tunnel_details_t * mp)
12020 {
12021   vat_main_t *vam = &vat_main;
12022   vat_json_node_t *node = NULL;
12023
12024   if (VAT_JSON_ARRAY != vam->json_tree.type)
12025     {
12026       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12027       vat_json_init_array (&vam->json_tree);
12028     }
12029   node = vat_json_array_add (&vam->json_tree);
12030
12031   vat_json_init_object (node);
12032   vat_json_object_add_uint (node, "sw_if_index",
12033                             ntohl (mp->tunnel.sw_if_index));
12034   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
12035
12036   vat_json_object_add_address (node, "src", &mp->tunnel.src);
12037   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
12038   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
12039   vat_json_object_add_uint (node, "outer_table_id",
12040                             ntohl (mp->tunnel.outer_table_id));
12041   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
12042 }
12043
12044 static int
12045 api_gre_tunnel_dump (vat_main_t * vam)
12046 {
12047   unformat_input_t *i = vam->input;
12048   vl_api_gre_tunnel_dump_t *mp;
12049   vl_api_control_ping_t *mp_ping;
12050   u32 sw_if_index;
12051   u8 sw_if_index_set = 0;
12052   int ret;
12053
12054   /* Parse args required to build the message */
12055   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12056     {
12057       if (unformat (i, "sw_if_index %d", &sw_if_index))
12058         sw_if_index_set = 1;
12059       else
12060         break;
12061     }
12062
12063   if (sw_if_index_set == 0)
12064     {
12065       sw_if_index = ~0;
12066     }
12067
12068   if (!vam->json_output)
12069     {
12070       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
12071              "sw_if_index", "instance", "src_address", "dst_address",
12072              "tunnel_type", "outer_fib_id", "session_id");
12073     }
12074
12075   /* Get list of gre-tunnel interfaces */
12076   M (GRE_TUNNEL_DUMP, mp);
12077
12078   mp->sw_if_index = htonl (sw_if_index);
12079
12080   S (mp);
12081
12082   /* Use a control ping for synchronization */
12083   MPING (CONTROL_PING, mp_ping);
12084   S (mp_ping);
12085
12086   W (ret);
12087   return ret;
12088 }
12089
12090 static int
12091 api_l2_fib_clear_table (vat_main_t * vam)
12092 {
12093 //  unformat_input_t * i = vam->input;
12094   vl_api_l2_fib_clear_table_t *mp;
12095   int ret;
12096
12097   M (L2_FIB_CLEAR_TABLE, mp);
12098
12099   S (mp);
12100   W (ret);
12101   return ret;
12102 }
12103
12104 static int
12105 api_l2_interface_efp_filter (vat_main_t * vam)
12106 {
12107   unformat_input_t *i = vam->input;
12108   vl_api_l2_interface_efp_filter_t *mp;
12109   u32 sw_if_index;
12110   u8 enable = 1;
12111   u8 sw_if_index_set = 0;
12112   int ret;
12113
12114   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12115     {
12116       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12117         sw_if_index_set = 1;
12118       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12119         sw_if_index_set = 1;
12120       else if (unformat (i, "enable"))
12121         enable = 1;
12122       else if (unformat (i, "disable"))
12123         enable = 0;
12124       else
12125         {
12126           clib_warning ("parse error '%U'", format_unformat_error, i);
12127           return -99;
12128         }
12129     }
12130
12131   if (sw_if_index_set == 0)
12132     {
12133       errmsg ("missing sw_if_index");
12134       return -99;
12135     }
12136
12137   M (L2_INTERFACE_EFP_FILTER, mp);
12138
12139   mp->sw_if_index = ntohl (sw_if_index);
12140   mp->enable_disable = enable;
12141
12142   S (mp);
12143   W (ret);
12144   return ret;
12145 }
12146
12147 #define foreach_vtr_op                          \
12148 _("disable",  L2_VTR_DISABLED)                  \
12149 _("push-1",  L2_VTR_PUSH_1)                     \
12150 _("push-2",  L2_VTR_PUSH_2)                     \
12151 _("pop-1",  L2_VTR_POP_1)                       \
12152 _("pop-2",  L2_VTR_POP_2)                       \
12153 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12154 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12155 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12156 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12157
12158 static int
12159 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12160 {
12161   unformat_input_t *i = vam->input;
12162   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12163   u32 sw_if_index;
12164   u8 sw_if_index_set = 0;
12165   u8 vtr_op_set = 0;
12166   u32 vtr_op = 0;
12167   u32 push_dot1q = 1;
12168   u32 tag1 = ~0;
12169   u32 tag2 = ~0;
12170   int ret;
12171
12172   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12173     {
12174       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12175         sw_if_index_set = 1;
12176       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12177         sw_if_index_set = 1;
12178       else if (unformat (i, "vtr_op %d", &vtr_op))
12179         vtr_op_set = 1;
12180 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12181       foreach_vtr_op
12182 #undef _
12183         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12184         ;
12185       else if (unformat (i, "tag1 %d", &tag1))
12186         ;
12187       else if (unformat (i, "tag2 %d", &tag2))
12188         ;
12189       else
12190         {
12191           clib_warning ("parse error '%U'", format_unformat_error, i);
12192           return -99;
12193         }
12194     }
12195
12196   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12197     {
12198       errmsg ("missing vtr operation or sw_if_index");
12199       return -99;
12200     }
12201
12202   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12203   mp->sw_if_index = ntohl (sw_if_index);
12204   mp->vtr_op = ntohl (vtr_op);
12205   mp->push_dot1q = ntohl (push_dot1q);
12206   mp->tag1 = ntohl (tag1);
12207   mp->tag2 = ntohl (tag2);
12208
12209   S (mp);
12210   W (ret);
12211   return ret;
12212 }
12213
12214 static int
12215 api_create_vhost_user_if (vat_main_t * vam)
12216 {
12217   unformat_input_t *i = vam->input;
12218   vl_api_create_vhost_user_if_t *mp;
12219   u8 *file_name;
12220   u8 is_server = 0;
12221   u8 file_name_set = 0;
12222   u32 custom_dev_instance = ~0;
12223   u8 hwaddr[6];
12224   u8 use_custom_mac = 0;
12225   u8 disable_mrg_rxbuf = 0;
12226   u8 disable_indirect_desc = 0;
12227   u8 *tag = 0;
12228   u8 enable_gso = 0;
12229   u8 enable_packed = 0;
12230   int ret;
12231
12232   /* Shut up coverity */
12233   clib_memset (hwaddr, 0, sizeof (hwaddr));
12234
12235   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12236     {
12237       if (unformat (i, "socket %s", &file_name))
12238         {
12239           file_name_set = 1;
12240         }
12241       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12242         ;
12243       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12244         use_custom_mac = 1;
12245       else if (unformat (i, "server"))
12246         is_server = 1;
12247       else if (unformat (i, "disable_mrg_rxbuf"))
12248         disable_mrg_rxbuf = 1;
12249       else if (unformat (i, "disable_indirect_desc"))
12250         disable_indirect_desc = 1;
12251       else if (unformat (i, "gso"))
12252         enable_gso = 1;
12253       else if (unformat (i, "packed"))
12254         enable_packed = 1;
12255       else if (unformat (i, "tag %s", &tag))
12256         ;
12257       else
12258         break;
12259     }
12260
12261   if (file_name_set == 0)
12262     {
12263       errmsg ("missing socket file name");
12264       return -99;
12265     }
12266
12267   if (vec_len (file_name) > 255)
12268     {
12269       errmsg ("socket file name too long");
12270       return -99;
12271     }
12272   vec_add1 (file_name, 0);
12273
12274   M (CREATE_VHOST_USER_IF, mp);
12275
12276   mp->is_server = is_server;
12277   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
12278   mp->disable_indirect_desc = disable_indirect_desc;
12279   mp->enable_gso = enable_gso;
12280   mp->enable_packed = enable_packed;
12281   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12282   vec_free (file_name);
12283   if (custom_dev_instance != ~0)
12284     {
12285       mp->renumber = 1;
12286       mp->custom_dev_instance = ntohl (custom_dev_instance);
12287     }
12288
12289   mp->use_custom_mac = use_custom_mac;
12290   clib_memcpy (mp->mac_address, hwaddr, 6);
12291   if (tag)
12292     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
12293   vec_free (tag);
12294
12295   S (mp);
12296   W (ret);
12297   return ret;
12298 }
12299
12300 static int
12301 api_modify_vhost_user_if (vat_main_t * vam)
12302 {
12303   unformat_input_t *i = vam->input;
12304   vl_api_modify_vhost_user_if_t *mp;
12305   u8 *file_name;
12306   u8 is_server = 0;
12307   u8 file_name_set = 0;
12308   u32 custom_dev_instance = ~0;
12309   u8 sw_if_index_set = 0;
12310   u32 sw_if_index = (u32) ~ 0;
12311   u8 enable_gso = 0;
12312   u8 enable_packed = 0;
12313   int ret;
12314
12315   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12316     {
12317       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12318         sw_if_index_set = 1;
12319       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12320         sw_if_index_set = 1;
12321       else if (unformat (i, "socket %s", &file_name))
12322         {
12323           file_name_set = 1;
12324         }
12325       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12326         ;
12327       else if (unformat (i, "server"))
12328         is_server = 1;
12329       else if (unformat (i, "gso"))
12330         enable_gso = 1;
12331       else if (unformat (i, "packed"))
12332         enable_packed = 1;
12333       else
12334         break;
12335     }
12336
12337   if (sw_if_index_set == 0)
12338     {
12339       errmsg ("missing sw_if_index or interface name");
12340       return -99;
12341     }
12342
12343   if (file_name_set == 0)
12344     {
12345       errmsg ("missing socket file name");
12346       return -99;
12347     }
12348
12349   if (vec_len (file_name) > 255)
12350     {
12351       errmsg ("socket file name too long");
12352       return -99;
12353     }
12354   vec_add1 (file_name, 0);
12355
12356   M (MODIFY_VHOST_USER_IF, mp);
12357
12358   mp->sw_if_index = ntohl (sw_if_index);
12359   mp->is_server = is_server;
12360   mp->enable_gso = enable_gso;
12361   mp->enable_packed = enable_packed;
12362   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12363   vec_free (file_name);
12364   if (custom_dev_instance != ~0)
12365     {
12366       mp->renumber = 1;
12367       mp->custom_dev_instance = ntohl (custom_dev_instance);
12368     }
12369
12370   S (mp);
12371   W (ret);
12372   return ret;
12373 }
12374
12375 static int
12376 api_delete_vhost_user_if (vat_main_t * vam)
12377 {
12378   unformat_input_t *i = vam->input;
12379   vl_api_delete_vhost_user_if_t *mp;
12380   u32 sw_if_index = ~0;
12381   u8 sw_if_index_set = 0;
12382   int ret;
12383
12384   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12385     {
12386       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12387         sw_if_index_set = 1;
12388       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12389         sw_if_index_set = 1;
12390       else
12391         break;
12392     }
12393
12394   if (sw_if_index_set == 0)
12395     {
12396       errmsg ("missing sw_if_index or interface name");
12397       return -99;
12398     }
12399
12400
12401   M (DELETE_VHOST_USER_IF, mp);
12402
12403   mp->sw_if_index = ntohl (sw_if_index);
12404
12405   S (mp);
12406   W (ret);
12407   return ret;
12408 }
12409
12410 static void vl_api_sw_interface_vhost_user_details_t_handler
12411   (vl_api_sw_interface_vhost_user_details_t * mp)
12412 {
12413   vat_main_t *vam = &vat_main;
12414   u64 features;
12415
12416   features =
12417     clib_net_to_host_u32 (mp->features_first_32) | ((u64)
12418                                                     clib_net_to_host_u32
12419                                                     (mp->features_last_32) <<
12420                                                     32);
12421
12422   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
12423          (char *) mp->interface_name,
12424          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
12425          features, mp->is_server,
12426          ntohl (mp->num_regions), (char *) mp->sock_filename);
12427   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
12428 }
12429
12430 static void vl_api_sw_interface_vhost_user_details_t_handler_json
12431   (vl_api_sw_interface_vhost_user_details_t * mp)
12432 {
12433   vat_main_t *vam = &vat_main;
12434   vat_json_node_t *node = NULL;
12435
12436   if (VAT_JSON_ARRAY != vam->json_tree.type)
12437     {
12438       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12439       vat_json_init_array (&vam->json_tree);
12440     }
12441   node = vat_json_array_add (&vam->json_tree);
12442
12443   vat_json_init_object (node);
12444   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12445   vat_json_object_add_string_copy (node, "interface_name",
12446                                    mp->interface_name);
12447   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
12448                             ntohl (mp->virtio_net_hdr_sz));
12449   vat_json_object_add_uint (node, "features_first_32",
12450                             clib_net_to_host_u32 (mp->features_first_32));
12451   vat_json_object_add_uint (node, "features_last_32",
12452                             clib_net_to_host_u32 (mp->features_last_32));
12453   vat_json_object_add_uint (node, "is_server", mp->is_server);
12454   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
12455   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
12456   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
12457 }
12458
12459 static int
12460 api_sw_interface_vhost_user_dump (vat_main_t * vam)
12461 {
12462   unformat_input_t *i = vam->input;
12463   vl_api_sw_interface_vhost_user_dump_t *mp;
12464   vl_api_control_ping_t *mp_ping;
12465   int ret;
12466   u32 sw_if_index = ~0;
12467
12468   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12469     {
12470       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12471         ;
12472       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12473         ;
12474       else
12475         break;
12476     }
12477
12478   print (vam->ofp,
12479          "Interface name            idx hdr_sz features server regions filename");
12480
12481   /* Get list of vhost-user interfaces */
12482   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
12483   mp->sw_if_index = ntohl (sw_if_index);
12484   S (mp);
12485
12486   /* Use a control ping for synchronization */
12487   MPING (CONTROL_PING, mp_ping);
12488   S (mp_ping);
12489
12490   W (ret);
12491   return ret;
12492 }
12493
12494 static int
12495 api_show_version (vat_main_t * vam)
12496 {
12497   vl_api_show_version_t *mp;
12498   int ret;
12499
12500   M (SHOW_VERSION, mp);
12501
12502   S (mp);
12503   W (ret);
12504   return ret;
12505 }
12506
12507
12508 static int
12509 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
12510 {
12511   unformat_input_t *line_input = vam->input;
12512   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
12513   ip46_address_t local, remote;
12514   u8 is_add = 1;
12515   u8 local_set = 0;
12516   u8 remote_set = 0;
12517   u8 grp_set = 0;
12518   u32 mcast_sw_if_index = ~0;
12519   u32 encap_vrf_id = 0;
12520   u32 decap_vrf_id = 0;
12521   u8 protocol = ~0;
12522   u32 vni;
12523   u8 vni_set = 0;
12524   int ret;
12525
12526   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12527     {
12528       if (unformat (line_input, "del"))
12529         is_add = 0;
12530       else if (unformat (line_input, "local %U",
12531                          unformat_ip46_address, &local))
12532         {
12533           local_set = 1;
12534         }
12535       else if (unformat (line_input, "remote %U",
12536                          unformat_ip46_address, &remote))
12537         {
12538           remote_set = 1;
12539         }
12540       else if (unformat (line_input, "group %U %U",
12541                          unformat_ip46_address, &remote,
12542                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12543         {
12544           grp_set = remote_set = 1;
12545         }
12546       else if (unformat (line_input, "group %U",
12547                          unformat_ip46_address, &remote))
12548         {
12549           grp_set = remote_set = 1;
12550         }
12551       else
12552         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12553         ;
12554       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12555         ;
12556       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
12557         ;
12558       else if (unformat (line_input, "vni %d", &vni))
12559         vni_set = 1;
12560       else if (unformat (line_input, "next-ip4"))
12561         protocol = 1;
12562       else if (unformat (line_input, "next-ip6"))
12563         protocol = 2;
12564       else if (unformat (line_input, "next-ethernet"))
12565         protocol = 3;
12566       else if (unformat (line_input, "next-nsh"))
12567         protocol = 4;
12568       else
12569         {
12570           errmsg ("parse error '%U'", format_unformat_error, line_input);
12571           return -99;
12572         }
12573     }
12574
12575   if (local_set == 0)
12576     {
12577       errmsg ("tunnel local address not specified");
12578       return -99;
12579     }
12580   if (remote_set == 0)
12581     {
12582       errmsg ("tunnel remote address not specified");
12583       return -99;
12584     }
12585   if (grp_set && mcast_sw_if_index == ~0)
12586     {
12587       errmsg ("tunnel nonexistent multicast device");
12588       return -99;
12589     }
12590   if (ip46_address_is_ip4 (&local) != ip46_address_is_ip4 (&remote))
12591     {
12592       errmsg ("both IPv4 and IPv6 addresses specified");
12593       return -99;
12594     }
12595
12596   if (vni_set == 0)
12597     {
12598       errmsg ("vni not specified");
12599       return -99;
12600     }
12601
12602   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
12603
12604   ip_address_encode (&local,
12605                      ip46_address_is_ip4 (&local) ? IP46_TYPE_IP4 :
12606                      IP46_TYPE_IP6, &mp->local);
12607   ip_address_encode (&remote,
12608                      ip46_address_is_ip4 (&remote) ? IP46_TYPE_IP4 :
12609                      IP46_TYPE_IP6, &mp->remote);
12610
12611   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12612   mp->encap_vrf_id = ntohl (encap_vrf_id);
12613   mp->decap_vrf_id = ntohl (decap_vrf_id);
12614   mp->protocol = protocol;
12615   mp->vni = ntohl (vni);
12616   mp->is_add = is_add;
12617
12618   S (mp);
12619   W (ret);
12620   return ret;
12621 }
12622
12623 static void vl_api_vxlan_gpe_tunnel_details_t_handler
12624   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12625 {
12626   vat_main_t *vam = &vat_main;
12627   ip46_address_t local, remote;
12628
12629   ip_address_decode (&mp->local, &local);
12630   ip_address_decode (&mp->remote, &remote);
12631
12632   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
12633          ntohl (mp->sw_if_index),
12634          format_ip46_address, &local, IP46_TYPE_ANY,
12635          format_ip46_address, &remote, IP46_TYPE_ANY,
12636          ntohl (mp->vni), mp->protocol,
12637          ntohl (mp->mcast_sw_if_index),
12638          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
12639 }
12640
12641
12642 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
12643   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12644 {
12645   vat_main_t *vam = &vat_main;
12646   vat_json_node_t *node = NULL;
12647   struct in_addr ip4;
12648   struct in6_addr ip6;
12649   ip46_address_t local, remote;
12650
12651   ip_address_decode (&mp->local, &local);
12652   ip_address_decode (&mp->remote, &remote);
12653
12654   if (VAT_JSON_ARRAY != vam->json_tree.type)
12655     {
12656       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12657       vat_json_init_array (&vam->json_tree);
12658     }
12659   node = vat_json_array_add (&vam->json_tree);
12660
12661   vat_json_init_object (node);
12662   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12663   if (ip46_address_is_ip4 (&local))
12664     {
12665       clib_memcpy (&ip4, &local.ip4, sizeof (ip4));
12666       vat_json_object_add_ip4 (node, "local", ip4);
12667       clib_memcpy (&ip4, &remote.ip4, sizeof (ip4));
12668       vat_json_object_add_ip4 (node, "remote", ip4);
12669     }
12670   else
12671     {
12672       clib_memcpy (&ip6, &local.ip6, sizeof (ip6));
12673       vat_json_object_add_ip6 (node, "local", ip6);
12674       clib_memcpy (&ip6, &remote.ip6, sizeof (ip6));
12675       vat_json_object_add_ip6 (node, "remote", ip6);
12676     }
12677   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12678   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
12679   vat_json_object_add_uint (node, "mcast_sw_if_index",
12680                             ntohl (mp->mcast_sw_if_index));
12681   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12682   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
12683   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12684 }
12685
12686 static int
12687 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
12688 {
12689   unformat_input_t *i = vam->input;
12690   vl_api_vxlan_gpe_tunnel_dump_t *mp;
12691   vl_api_control_ping_t *mp_ping;
12692   u32 sw_if_index;
12693   u8 sw_if_index_set = 0;
12694   int ret;
12695
12696   /* Parse args required to build the message */
12697   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12698     {
12699       if (unformat (i, "sw_if_index %d", &sw_if_index))
12700         sw_if_index_set = 1;
12701       else
12702         break;
12703     }
12704
12705   if (sw_if_index_set == 0)
12706     {
12707       sw_if_index = ~0;
12708     }
12709
12710   if (!vam->json_output)
12711     {
12712       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
12713              "sw_if_index", "local", "remote", "vni",
12714              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
12715     }
12716
12717   /* Get list of vxlan-tunnel interfaces */
12718   M (VXLAN_GPE_TUNNEL_DUMP, mp);
12719
12720   mp->sw_if_index = htonl (sw_if_index);
12721
12722   S (mp);
12723
12724   /* Use a control ping for synchronization */
12725   MPING (CONTROL_PING, mp_ping);
12726   S (mp_ping);
12727
12728   W (ret);
12729   return ret;
12730 }
12731
12732 static void vl_api_l2_fib_table_details_t_handler
12733   (vl_api_l2_fib_table_details_t * mp)
12734 {
12735   vat_main_t *vam = &vat_main;
12736
12737   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
12738          "       %d       %d     %d",
12739          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
12740          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
12741          mp->bvi_mac);
12742 }
12743
12744 static void vl_api_l2_fib_table_details_t_handler_json
12745   (vl_api_l2_fib_table_details_t * mp)
12746 {
12747   vat_main_t *vam = &vat_main;
12748   vat_json_node_t *node = NULL;
12749
12750   if (VAT_JSON_ARRAY != vam->json_tree.type)
12751     {
12752       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12753       vat_json_init_array (&vam->json_tree);
12754     }
12755   node = vat_json_array_add (&vam->json_tree);
12756
12757   vat_json_init_object (node);
12758   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
12759   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
12760   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12761   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
12762   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
12763   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
12764 }
12765
12766 static int
12767 api_l2_fib_table_dump (vat_main_t * vam)
12768 {
12769   unformat_input_t *i = vam->input;
12770   vl_api_l2_fib_table_dump_t *mp;
12771   vl_api_control_ping_t *mp_ping;
12772   u32 bd_id;
12773   u8 bd_id_set = 0;
12774   int ret;
12775
12776   /* Parse args required to build the message */
12777   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12778     {
12779       if (unformat (i, "bd_id %d", &bd_id))
12780         bd_id_set = 1;
12781       else
12782         break;
12783     }
12784
12785   if (bd_id_set == 0)
12786     {
12787       errmsg ("missing bridge domain");
12788       return -99;
12789     }
12790
12791   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
12792
12793   /* Get list of l2 fib entries */
12794   M (L2_FIB_TABLE_DUMP, mp);
12795
12796   mp->bd_id = ntohl (bd_id);
12797   S (mp);
12798
12799   /* Use a control ping for synchronization */
12800   MPING (CONTROL_PING, mp_ping);
12801   S (mp_ping);
12802
12803   W (ret);
12804   return ret;
12805 }
12806
12807
12808 static int
12809 api_interface_name_renumber (vat_main_t * vam)
12810 {
12811   unformat_input_t *line_input = vam->input;
12812   vl_api_interface_name_renumber_t *mp;
12813   u32 sw_if_index = ~0;
12814   u32 new_show_dev_instance = ~0;
12815   int ret;
12816
12817   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12818     {
12819       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
12820                     &sw_if_index))
12821         ;
12822       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12823         ;
12824       else if (unformat (line_input, "new_show_dev_instance %d",
12825                          &new_show_dev_instance))
12826         ;
12827       else
12828         break;
12829     }
12830
12831   if (sw_if_index == ~0)
12832     {
12833       errmsg ("missing interface name or sw_if_index");
12834       return -99;
12835     }
12836
12837   if (new_show_dev_instance == ~0)
12838     {
12839       errmsg ("missing new_show_dev_instance");
12840       return -99;
12841     }
12842
12843   M (INTERFACE_NAME_RENUMBER, mp);
12844
12845   mp->sw_if_index = ntohl (sw_if_index);
12846   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
12847
12848   S (mp);
12849   W (ret);
12850   return ret;
12851 }
12852
12853 static int
12854 api_want_l2_macs_events (vat_main_t * vam)
12855 {
12856   unformat_input_t *line_input = vam->input;
12857   vl_api_want_l2_macs_events_t *mp;
12858   u8 enable_disable = 1;
12859   u32 scan_delay = 0;
12860   u32 max_macs_in_event = 0;
12861   u32 learn_limit = 0;
12862   int ret;
12863
12864   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12865     {
12866       if (unformat (line_input, "learn-limit %d", &learn_limit))
12867         ;
12868       else if (unformat (line_input, "scan-delay %d", &scan_delay))
12869         ;
12870       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
12871         ;
12872       else if (unformat (line_input, "disable"))
12873         enable_disable = 0;
12874       else
12875         break;
12876     }
12877
12878   M (WANT_L2_MACS_EVENTS, mp);
12879   mp->enable_disable = enable_disable;
12880   mp->pid = htonl (getpid ());
12881   mp->learn_limit = htonl (learn_limit);
12882   mp->scan_delay = (u8) scan_delay;
12883   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
12884   S (mp);
12885   W (ret);
12886   return ret;
12887 }
12888
12889 static int
12890 api_input_acl_set_interface (vat_main_t * vam)
12891 {
12892   unformat_input_t *i = vam->input;
12893   vl_api_input_acl_set_interface_t *mp;
12894   u32 sw_if_index;
12895   int sw_if_index_set;
12896   u32 ip4_table_index = ~0;
12897   u32 ip6_table_index = ~0;
12898   u32 l2_table_index = ~0;
12899   u8 is_add = 1;
12900   int ret;
12901
12902   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12903     {
12904       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12905         sw_if_index_set = 1;
12906       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12907         sw_if_index_set = 1;
12908       else if (unformat (i, "del"))
12909         is_add = 0;
12910       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12911         ;
12912       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12913         ;
12914       else if (unformat (i, "l2-table %d", &l2_table_index))
12915         ;
12916       else
12917         {
12918           clib_warning ("parse error '%U'", format_unformat_error, i);
12919           return -99;
12920         }
12921     }
12922
12923   if (sw_if_index_set == 0)
12924     {
12925       errmsg ("missing interface name or sw_if_index");
12926       return -99;
12927     }
12928
12929   M (INPUT_ACL_SET_INTERFACE, mp);
12930
12931   mp->sw_if_index = ntohl (sw_if_index);
12932   mp->ip4_table_index = ntohl (ip4_table_index);
12933   mp->ip6_table_index = ntohl (ip6_table_index);
12934   mp->l2_table_index = ntohl (l2_table_index);
12935   mp->is_add = is_add;
12936
12937   S (mp);
12938   W (ret);
12939   return ret;
12940 }
12941
12942 static int
12943 api_output_acl_set_interface (vat_main_t * vam)
12944 {
12945   unformat_input_t *i = vam->input;
12946   vl_api_output_acl_set_interface_t *mp;
12947   u32 sw_if_index;
12948   int sw_if_index_set;
12949   u32 ip4_table_index = ~0;
12950   u32 ip6_table_index = ~0;
12951   u32 l2_table_index = ~0;
12952   u8 is_add = 1;
12953   int ret;
12954
12955   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12956     {
12957       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12958         sw_if_index_set = 1;
12959       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12960         sw_if_index_set = 1;
12961       else if (unformat (i, "del"))
12962         is_add = 0;
12963       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12964         ;
12965       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12966         ;
12967       else if (unformat (i, "l2-table %d", &l2_table_index))
12968         ;
12969       else
12970         {
12971           clib_warning ("parse error '%U'", format_unformat_error, i);
12972           return -99;
12973         }
12974     }
12975
12976   if (sw_if_index_set == 0)
12977     {
12978       errmsg ("missing interface name or sw_if_index");
12979       return -99;
12980     }
12981
12982   M (OUTPUT_ACL_SET_INTERFACE, mp);
12983
12984   mp->sw_if_index = ntohl (sw_if_index);
12985   mp->ip4_table_index = ntohl (ip4_table_index);
12986   mp->ip6_table_index = ntohl (ip6_table_index);
12987   mp->l2_table_index = ntohl (l2_table_index);
12988   mp->is_add = is_add;
12989
12990   S (mp);
12991   W (ret);
12992   return ret;
12993 }
12994
12995 static int
12996 api_ip_address_dump (vat_main_t * vam)
12997 {
12998   unformat_input_t *i = vam->input;
12999   vl_api_ip_address_dump_t *mp;
13000   vl_api_control_ping_t *mp_ping;
13001   u32 sw_if_index = ~0;
13002   u8 sw_if_index_set = 0;
13003   u8 ipv4_set = 0;
13004   u8 ipv6_set = 0;
13005   int ret;
13006
13007   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13008     {
13009       if (unformat (i, "sw_if_index %d", &sw_if_index))
13010         sw_if_index_set = 1;
13011       else
13012         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13013         sw_if_index_set = 1;
13014       else if (unformat (i, "ipv4"))
13015         ipv4_set = 1;
13016       else if (unformat (i, "ipv6"))
13017         ipv6_set = 1;
13018       else
13019         break;
13020     }
13021
13022   if (ipv4_set && ipv6_set)
13023     {
13024       errmsg ("ipv4 and ipv6 flags cannot be both set");
13025       return -99;
13026     }
13027
13028   if ((!ipv4_set) && (!ipv6_set))
13029     {
13030       errmsg ("no ipv4 nor ipv6 flag set");
13031       return -99;
13032     }
13033
13034   if (sw_if_index_set == 0)
13035     {
13036       errmsg ("missing interface name or sw_if_index");
13037       return -99;
13038     }
13039
13040   vam->current_sw_if_index = sw_if_index;
13041   vam->is_ipv6 = ipv6_set;
13042
13043   M (IP_ADDRESS_DUMP, mp);
13044   mp->sw_if_index = ntohl (sw_if_index);
13045   mp->is_ipv6 = ipv6_set;
13046   S (mp);
13047
13048   /* Use a control ping for synchronization */
13049   MPING (CONTROL_PING, mp_ping);
13050   S (mp_ping);
13051
13052   W (ret);
13053   return ret;
13054 }
13055
13056 static int
13057 api_ip_dump (vat_main_t * vam)
13058 {
13059   vl_api_ip_dump_t *mp;
13060   vl_api_control_ping_t *mp_ping;
13061   unformat_input_t *in = vam->input;
13062   int ipv4_set = 0;
13063   int ipv6_set = 0;
13064   int is_ipv6;
13065   int i;
13066   int ret;
13067
13068   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13069     {
13070       if (unformat (in, "ipv4"))
13071         ipv4_set = 1;
13072       else if (unformat (in, "ipv6"))
13073         ipv6_set = 1;
13074       else
13075         break;
13076     }
13077
13078   if (ipv4_set && ipv6_set)
13079     {
13080       errmsg ("ipv4 and ipv6 flags cannot be both set");
13081       return -99;
13082     }
13083
13084   if ((!ipv4_set) && (!ipv6_set))
13085     {
13086       errmsg ("no ipv4 nor ipv6 flag set");
13087       return -99;
13088     }
13089
13090   is_ipv6 = ipv6_set;
13091   vam->is_ipv6 = is_ipv6;
13092
13093   /* free old data */
13094   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13095     {
13096       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13097     }
13098   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13099
13100   M (IP_DUMP, mp);
13101   mp->is_ipv6 = ipv6_set;
13102   S (mp);
13103
13104   /* Use a control ping for synchronization */
13105   MPING (CONTROL_PING, mp_ping);
13106   S (mp_ping);
13107
13108   W (ret);
13109   return ret;
13110 }
13111
13112 static int
13113 api_ipsec_spd_add_del (vat_main_t * vam)
13114 {
13115   unformat_input_t *i = vam->input;
13116   vl_api_ipsec_spd_add_del_t *mp;
13117   u32 spd_id = ~0;
13118   u8 is_add = 1;
13119   int ret;
13120
13121   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13122     {
13123       if (unformat (i, "spd_id %d", &spd_id))
13124         ;
13125       else if (unformat (i, "del"))
13126         is_add = 0;
13127       else
13128         {
13129           clib_warning ("parse error '%U'", format_unformat_error, i);
13130           return -99;
13131         }
13132     }
13133   if (spd_id == ~0)
13134     {
13135       errmsg ("spd_id must be set");
13136       return -99;
13137     }
13138
13139   M (IPSEC_SPD_ADD_DEL, mp);
13140
13141   mp->spd_id = ntohl (spd_id);
13142   mp->is_add = is_add;
13143
13144   S (mp);
13145   W (ret);
13146   return ret;
13147 }
13148
13149 static int
13150 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13151 {
13152   unformat_input_t *i = vam->input;
13153   vl_api_ipsec_interface_add_del_spd_t *mp;
13154   u32 sw_if_index;
13155   u8 sw_if_index_set = 0;
13156   u32 spd_id = (u32) ~ 0;
13157   u8 is_add = 1;
13158   int ret;
13159
13160   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13161     {
13162       if (unformat (i, "del"))
13163         is_add = 0;
13164       else if (unformat (i, "spd_id %d", &spd_id))
13165         ;
13166       else
13167         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13168         sw_if_index_set = 1;
13169       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13170         sw_if_index_set = 1;
13171       else
13172         {
13173           clib_warning ("parse error '%U'", format_unformat_error, i);
13174           return -99;
13175         }
13176
13177     }
13178
13179   if (spd_id == (u32) ~ 0)
13180     {
13181       errmsg ("spd_id must be set");
13182       return -99;
13183     }
13184
13185   if (sw_if_index_set == 0)
13186     {
13187       errmsg ("missing interface name or sw_if_index");
13188       return -99;
13189     }
13190
13191   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
13192
13193   mp->spd_id = ntohl (spd_id);
13194   mp->sw_if_index = ntohl (sw_if_index);
13195   mp->is_add = is_add;
13196
13197   S (mp);
13198   W (ret);
13199   return ret;
13200 }
13201
13202 static int
13203 api_ipsec_spd_entry_add_del (vat_main_t * vam)
13204 {
13205   unformat_input_t *i = vam->input;
13206   vl_api_ipsec_spd_entry_add_del_t *mp;
13207   u8 is_add = 1, is_outbound = 0;
13208   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
13209   i32 priority = 0;
13210   u32 rport_start = 0, rport_stop = (u32) ~ 0;
13211   u32 lport_start = 0, lport_stop = (u32) ~ 0;
13212   vl_api_address_t laddr_start = { }, laddr_stop =
13213   {
13214   }, raddr_start =
13215   {
13216   }, raddr_stop =
13217   {
13218   };
13219   int ret;
13220
13221   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13222     {
13223       if (unformat (i, "del"))
13224         is_add = 0;
13225       if (unformat (i, "outbound"))
13226         is_outbound = 1;
13227       if (unformat (i, "inbound"))
13228         is_outbound = 0;
13229       else if (unformat (i, "spd_id %d", &spd_id))
13230         ;
13231       else if (unformat (i, "sa_id %d", &sa_id))
13232         ;
13233       else if (unformat (i, "priority %d", &priority))
13234         ;
13235       else if (unformat (i, "protocol %d", &protocol))
13236         ;
13237       else if (unformat (i, "lport_start %d", &lport_start))
13238         ;
13239       else if (unformat (i, "lport_stop %d", &lport_stop))
13240         ;
13241       else if (unformat (i, "rport_start %d", &rport_start))
13242         ;
13243       else if (unformat (i, "rport_stop %d", &rport_stop))
13244         ;
13245       else if (unformat (i, "laddr_start %U",
13246                          unformat_vl_api_address, &laddr_start))
13247         ;
13248       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
13249                          &laddr_stop))
13250         ;
13251       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
13252                          &raddr_start))
13253         ;
13254       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
13255                          &raddr_stop))
13256         ;
13257       else
13258         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
13259         {
13260           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
13261             {
13262               clib_warning ("unsupported action: 'resolve'");
13263               return -99;
13264             }
13265         }
13266       else
13267         {
13268           clib_warning ("parse error '%U'", format_unformat_error, i);
13269           return -99;
13270         }
13271
13272     }
13273
13274   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
13275
13276   mp->is_add = is_add;
13277
13278   mp->entry.spd_id = ntohl (spd_id);
13279   mp->entry.priority = ntohl (priority);
13280   mp->entry.is_outbound = is_outbound;
13281
13282   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
13283                sizeof (vl_api_address_t));
13284   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
13285                sizeof (vl_api_address_t));
13286   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
13287                sizeof (vl_api_address_t));
13288   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
13289                sizeof (vl_api_address_t));
13290
13291   mp->entry.protocol = (u8) protocol;
13292   mp->entry.local_port_start = ntohs ((u16) lport_start);
13293   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
13294   mp->entry.remote_port_start = ntohs ((u16) rport_start);
13295   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
13296   mp->entry.policy = (u8) policy;
13297   mp->entry.sa_id = ntohl (sa_id);
13298
13299   S (mp);
13300   W (ret);
13301   return ret;
13302 }
13303
13304 static int
13305 api_ipsec_sad_entry_add_del (vat_main_t * vam)
13306 {
13307   unformat_input_t *i = vam->input;
13308   vl_api_ipsec_sad_entry_add_del_t *mp;
13309   u32 sad_id = 0, spi = 0;
13310   u8 *ck = 0, *ik = 0;
13311   u8 is_add = 1;
13312
13313   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
13314   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
13315   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
13316   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
13317   vl_api_address_t tun_src, tun_dst;
13318   int ret;
13319
13320   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13321     {
13322       if (unformat (i, "del"))
13323         is_add = 0;
13324       else if (unformat (i, "sad_id %d", &sad_id))
13325         ;
13326       else if (unformat (i, "spi %d", &spi))
13327         ;
13328       else if (unformat (i, "esp"))
13329         protocol = IPSEC_API_PROTO_ESP;
13330       else
13331         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
13332         {
13333           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13334           if (ADDRESS_IP6 == tun_src.af)
13335             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13336         }
13337       else
13338         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
13339         {
13340           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13341           if (ADDRESS_IP6 == tun_src.af)
13342             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13343         }
13344       else
13345         if (unformat (i, "crypto_alg %U",
13346                       unformat_ipsec_api_crypto_alg, &crypto_alg))
13347         ;
13348       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13349         ;
13350       else if (unformat (i, "integ_alg %U",
13351                          unformat_ipsec_api_integ_alg, &integ_alg))
13352         ;
13353       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13354         ;
13355       else
13356         {
13357           clib_warning ("parse error '%U'", format_unformat_error, i);
13358           return -99;
13359         }
13360
13361     }
13362
13363   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
13364
13365   mp->is_add = is_add;
13366   mp->entry.sad_id = ntohl (sad_id);
13367   mp->entry.protocol = protocol;
13368   mp->entry.spi = ntohl (spi);
13369   mp->entry.flags = flags;
13370
13371   mp->entry.crypto_algorithm = crypto_alg;
13372   mp->entry.integrity_algorithm = integ_alg;
13373   mp->entry.crypto_key.length = vec_len (ck);
13374   mp->entry.integrity_key.length = vec_len (ik);
13375
13376   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
13377     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
13378
13379   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
13380     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
13381
13382   if (ck)
13383     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
13384   if (ik)
13385     clib_memcpy (mp->entry.integrity_key.data, ik,
13386                  mp->entry.integrity_key.length);
13387
13388   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
13389     {
13390       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
13391                    sizeof (mp->entry.tunnel_src));
13392       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
13393                    sizeof (mp->entry.tunnel_dst));
13394     }
13395
13396   S (mp);
13397   W (ret);
13398   return ret;
13399 }
13400
13401 static int
13402 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
13403 {
13404   unformat_input_t *i = vam->input;
13405   vl_api_ipsec_tunnel_if_add_del_t *mp;
13406   u32 local_spi = 0, remote_spi = 0;
13407   u32 crypto_alg = 0, integ_alg = 0;
13408   u8 *lck = NULL, *rck = NULL;
13409   u8 *lik = NULL, *rik = NULL;
13410   vl_api_address_t local_ip = { 0 };
13411   vl_api_address_t remote_ip = { 0 };
13412   f64 before = 0;
13413   u8 is_add = 1;
13414   u8 esn = 0;
13415   u8 anti_replay = 0;
13416   u8 renumber = 0;
13417   u32 instance = ~0;
13418   u32 count = 1, jj;
13419   int ret = -1;
13420
13421   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13422     {
13423       if (unformat (i, "del"))
13424         is_add = 0;
13425       else if (unformat (i, "esn"))
13426         esn = 1;
13427       else if (unformat (i, "anti-replay"))
13428         anti_replay = 1;
13429       else if (unformat (i, "count %d", &count))
13430         ;
13431       else if (unformat (i, "local_spi %d", &local_spi))
13432         ;
13433       else if (unformat (i, "remote_spi %d", &remote_spi))
13434         ;
13435       else
13436         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
13437         ;
13438       else
13439         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
13440         ;
13441       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
13442         ;
13443       else
13444         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
13445         ;
13446       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
13447         ;
13448       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
13449         ;
13450       else
13451         if (unformat
13452             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
13453         {
13454           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
13455             {
13456               errmsg ("unsupported crypto-alg: '%U'\n",
13457                       format_ipsec_crypto_alg, crypto_alg);
13458               return -99;
13459             }
13460         }
13461       else
13462         if (unformat
13463             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
13464         {
13465           if (integ_alg >= IPSEC_INTEG_N_ALG)
13466             {
13467               errmsg ("unsupported integ-alg: '%U'\n",
13468                       format_ipsec_integ_alg, integ_alg);
13469               return -99;
13470             }
13471         }
13472       else if (unformat (i, "instance %u", &instance))
13473         renumber = 1;
13474       else
13475         {
13476           errmsg ("parse error '%U'\n", format_unformat_error, i);
13477           return -99;
13478         }
13479     }
13480
13481   if (count > 1)
13482     {
13483       /* Turn on async mode */
13484       vam->async_mode = 1;
13485       vam->async_errors = 0;
13486       before = vat_time_now (vam);
13487     }
13488
13489   for (jj = 0; jj < count; jj++)
13490     {
13491       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
13492
13493       mp->is_add = is_add;
13494       mp->esn = esn;
13495       mp->anti_replay = anti_replay;
13496
13497       if (jj > 0)
13498         increment_address (&remote_ip);
13499
13500       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
13501       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
13502
13503       mp->local_spi = htonl (local_spi + jj);
13504       mp->remote_spi = htonl (remote_spi + jj);
13505       mp->crypto_alg = (u8) crypto_alg;
13506
13507       mp->local_crypto_key_len = 0;
13508       if (lck)
13509         {
13510           mp->local_crypto_key_len = vec_len (lck);
13511           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
13512             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
13513           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
13514         }
13515
13516       mp->remote_crypto_key_len = 0;
13517       if (rck)
13518         {
13519           mp->remote_crypto_key_len = vec_len (rck);
13520           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
13521             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
13522           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
13523         }
13524
13525       mp->integ_alg = (u8) integ_alg;
13526
13527       mp->local_integ_key_len = 0;
13528       if (lik)
13529         {
13530           mp->local_integ_key_len = vec_len (lik);
13531           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
13532             mp->local_integ_key_len = sizeof (mp->local_integ_key);
13533           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
13534         }
13535
13536       mp->remote_integ_key_len = 0;
13537       if (rik)
13538         {
13539           mp->remote_integ_key_len = vec_len (rik);
13540           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
13541             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
13542           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
13543         }
13544
13545       if (renumber)
13546         {
13547           mp->renumber = renumber;
13548           mp->show_instance = ntohl (instance);
13549         }
13550       S (mp);
13551     }
13552
13553   /* When testing multiple add/del ops, use a control-ping to sync */
13554   if (count > 1)
13555     {
13556       vl_api_control_ping_t *mp_ping;
13557       f64 after;
13558       f64 timeout;
13559
13560       /* Shut off async mode */
13561       vam->async_mode = 0;
13562
13563       MPING (CONTROL_PING, mp_ping);
13564       S (mp_ping);
13565
13566       timeout = vat_time_now (vam) + 1.0;
13567       while (vat_time_now (vam) < timeout)
13568         if (vam->result_ready == 1)
13569           goto out;
13570       vam->retval = -99;
13571
13572     out:
13573       if (vam->retval == -99)
13574         errmsg ("timeout");
13575
13576       if (vam->async_errors > 0)
13577         {
13578           errmsg ("%d asynchronous errors", vam->async_errors);
13579           vam->retval = -98;
13580         }
13581       vam->async_errors = 0;
13582       after = vat_time_now (vam);
13583
13584       /* slim chance, but we might have eaten SIGTERM on the first iteration */
13585       if (jj > 0)
13586         count = jj;
13587
13588       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
13589              count, after - before, count / (after - before));
13590     }
13591   else
13592     {
13593       /* Wait for a reply... */
13594       W (ret);
13595       return ret;
13596     }
13597
13598   return ret;
13599 }
13600
13601 static void
13602 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
13603 {
13604   vat_main_t *vam = &vat_main;
13605
13606   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
13607          "crypto_key %U integ_alg %u integ_key %U flags %x "
13608          "tunnel_src_addr %U tunnel_dst_addr %U "
13609          "salt %u seq_outbound %lu last_seq_inbound %lu "
13610          "replay_window %lu stat_index %u\n",
13611          ntohl (mp->entry.sad_id),
13612          ntohl (mp->sw_if_index),
13613          ntohl (mp->entry.spi),
13614          ntohl (mp->entry.protocol),
13615          ntohl (mp->entry.crypto_algorithm),
13616          format_hex_bytes, mp->entry.crypto_key.data,
13617          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
13618          format_hex_bytes, mp->entry.integrity_key.data,
13619          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
13620          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
13621          &mp->entry.tunnel_dst, ntohl (mp->salt),
13622          clib_net_to_host_u64 (mp->seq_outbound),
13623          clib_net_to_host_u64 (mp->last_seq_inbound),
13624          clib_net_to_host_u64 (mp->replay_window), ntohl (mp->stat_index));
13625 }
13626
13627 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
13628 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
13629
13630 static void vl_api_ipsec_sa_details_t_handler_json
13631   (vl_api_ipsec_sa_details_t * mp)
13632 {
13633   vat_main_t *vam = &vat_main;
13634   vat_json_node_t *node = NULL;
13635   vl_api_ipsec_sad_flags_t flags;
13636
13637   if (VAT_JSON_ARRAY != vam->json_tree.type)
13638     {
13639       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13640       vat_json_init_array (&vam->json_tree);
13641     }
13642   node = vat_json_array_add (&vam->json_tree);
13643
13644   vat_json_init_object (node);
13645   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
13646   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13647   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
13648   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
13649   vat_json_object_add_uint (node, "crypto_alg",
13650                             ntohl (mp->entry.crypto_algorithm));
13651   vat_json_object_add_uint (node, "integ_alg",
13652                             ntohl (mp->entry.integrity_algorithm));
13653   flags = ntohl (mp->entry.flags);
13654   vat_json_object_add_uint (node, "use_esn",
13655                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
13656   vat_json_object_add_uint (node, "use_anti_replay",
13657                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
13658   vat_json_object_add_uint (node, "is_tunnel",
13659                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
13660   vat_json_object_add_uint (node, "is_tunnel_ip6",
13661                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
13662   vat_json_object_add_uint (node, "udp_encap",
13663                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
13664   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
13665                              mp->entry.crypto_key.length);
13666   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
13667                              mp->entry.integrity_key.length);
13668   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
13669   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
13670   vat_json_object_add_uint (node, "replay_window",
13671                             clib_net_to_host_u64 (mp->replay_window));
13672   vat_json_object_add_uint (node, "stat_index", ntohl (mp->stat_index));
13673 }
13674
13675 static int
13676 api_ipsec_sa_dump (vat_main_t * vam)
13677 {
13678   unformat_input_t *i = vam->input;
13679   vl_api_ipsec_sa_dump_t *mp;
13680   vl_api_control_ping_t *mp_ping;
13681   u32 sa_id = ~0;
13682   int ret;
13683
13684   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13685     {
13686       if (unformat (i, "sa_id %d", &sa_id))
13687         ;
13688       else
13689         {
13690           clib_warning ("parse error '%U'", format_unformat_error, i);
13691           return -99;
13692         }
13693     }
13694
13695   M (IPSEC_SA_DUMP, mp);
13696
13697   mp->sa_id = ntohl (sa_id);
13698
13699   S (mp);
13700
13701   /* Use a control ping for synchronization */
13702   M (CONTROL_PING, mp_ping);
13703   S (mp_ping);
13704
13705   W (ret);
13706   return ret;
13707 }
13708
13709 static int
13710 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
13711 {
13712   unformat_input_t *i = vam->input;
13713   vl_api_ipsec_tunnel_if_set_sa_t *mp;
13714   u32 sw_if_index = ~0;
13715   u32 sa_id = ~0;
13716   u8 is_outbound = (u8) ~ 0;
13717   int ret;
13718
13719   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13720     {
13721       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13722         ;
13723       else if (unformat (i, "sa_id %d", &sa_id))
13724         ;
13725       else if (unformat (i, "outbound"))
13726         is_outbound = 1;
13727       else if (unformat (i, "inbound"))
13728         is_outbound = 0;
13729       else
13730         {
13731           clib_warning ("parse error '%U'", format_unformat_error, i);
13732           return -99;
13733         }
13734     }
13735
13736   if (sw_if_index == ~0)
13737     {
13738       errmsg ("interface must be specified");
13739       return -99;
13740     }
13741
13742   if (sa_id == ~0)
13743     {
13744       errmsg ("SA ID must be specified");
13745       return -99;
13746     }
13747
13748   M (IPSEC_TUNNEL_IF_SET_SA, mp);
13749
13750   mp->sw_if_index = htonl (sw_if_index);
13751   mp->sa_id = htonl (sa_id);
13752   mp->is_outbound = is_outbound;
13753
13754   S (mp);
13755   W (ret);
13756
13757   return ret;
13758 }
13759
13760 static int
13761 api_get_first_msg_id (vat_main_t * vam)
13762 {
13763   vl_api_get_first_msg_id_t *mp;
13764   unformat_input_t *i = vam->input;
13765   u8 *name;
13766   u8 name_set = 0;
13767   int ret;
13768
13769   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13770     {
13771       if (unformat (i, "client %s", &name))
13772         name_set = 1;
13773       else
13774         break;
13775     }
13776
13777   if (name_set == 0)
13778     {
13779       errmsg ("missing client name");
13780       return -99;
13781     }
13782   vec_add1 (name, 0);
13783
13784   if (vec_len (name) > 63)
13785     {
13786       errmsg ("client name too long");
13787       return -99;
13788     }
13789
13790   M (GET_FIRST_MSG_ID, mp);
13791   clib_memcpy (mp->name, name, vec_len (name));
13792   S (mp);
13793   W (ret);
13794   return ret;
13795 }
13796
13797 static int
13798 api_cop_interface_enable_disable (vat_main_t * vam)
13799 {
13800   unformat_input_t *line_input = vam->input;
13801   vl_api_cop_interface_enable_disable_t *mp;
13802   u32 sw_if_index = ~0;
13803   u8 enable_disable = 1;
13804   int ret;
13805
13806   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13807     {
13808       if (unformat (line_input, "disable"))
13809         enable_disable = 0;
13810       if (unformat (line_input, "enable"))
13811         enable_disable = 1;
13812       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13813                          vam, &sw_if_index))
13814         ;
13815       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13816         ;
13817       else
13818         break;
13819     }
13820
13821   if (sw_if_index == ~0)
13822     {
13823       errmsg ("missing interface name or sw_if_index");
13824       return -99;
13825     }
13826
13827   /* Construct the API message */
13828   M (COP_INTERFACE_ENABLE_DISABLE, mp);
13829   mp->sw_if_index = ntohl (sw_if_index);
13830   mp->enable_disable = enable_disable;
13831
13832   /* send it... */
13833   S (mp);
13834   /* Wait for the reply */
13835   W (ret);
13836   return ret;
13837 }
13838
13839 static int
13840 api_cop_whitelist_enable_disable (vat_main_t * vam)
13841 {
13842   unformat_input_t *line_input = vam->input;
13843   vl_api_cop_whitelist_enable_disable_t *mp;
13844   u32 sw_if_index = ~0;
13845   u8 ip4 = 0, ip6 = 0, default_cop = 0;
13846   u32 fib_id = 0;
13847   int ret;
13848
13849   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13850     {
13851       if (unformat (line_input, "ip4"))
13852         ip4 = 1;
13853       else if (unformat (line_input, "ip6"))
13854         ip6 = 1;
13855       else if (unformat (line_input, "default"))
13856         default_cop = 1;
13857       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13858                          vam, &sw_if_index))
13859         ;
13860       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13861         ;
13862       else if (unformat (line_input, "fib-id %d", &fib_id))
13863         ;
13864       else
13865         break;
13866     }
13867
13868   if (sw_if_index == ~0)
13869     {
13870       errmsg ("missing interface name or sw_if_index");
13871       return -99;
13872     }
13873
13874   /* Construct the API message */
13875   M (COP_WHITELIST_ENABLE_DISABLE, mp);
13876   mp->sw_if_index = ntohl (sw_if_index);
13877   mp->fib_id = ntohl (fib_id);
13878   mp->ip4 = ip4;
13879   mp->ip6 = ip6;
13880   mp->default_cop = default_cop;
13881
13882   /* send it... */
13883   S (mp);
13884   /* Wait for the reply */
13885   W (ret);
13886   return ret;
13887 }
13888
13889 static int
13890 api_get_node_graph (vat_main_t * vam)
13891 {
13892   vl_api_get_node_graph_t *mp;
13893   int ret;
13894
13895   M (GET_NODE_GRAPH, mp);
13896
13897   /* send it... */
13898   S (mp);
13899   /* Wait for the reply */
13900   W (ret);
13901   return ret;
13902 }
13903
13904 /* *INDENT-OFF* */
13905 /** Used for parsing LISP eids */
13906 typedef CLIB_PACKED(struct{
13907   union {
13908           ip46_address_t ip;
13909           mac_address_t mac;
13910           lisp_nsh_api_t nsh;
13911   } addr;
13912   u32 len;       /**< prefix length if IP */
13913   u8 type;      /**< type of eid */
13914 }) lisp_eid_vat_t;
13915 /* *INDENT-ON* */
13916
13917 static uword
13918 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
13919 {
13920   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
13921
13922   clib_memset (a, 0, sizeof (a[0]));
13923
13924   if (unformat (input, "%U/%d", unformat_ip46_address, a->addr.ip, &a->len))
13925     {
13926       a->type = 0;              /* ip prefix type */
13927     }
13928   else if (unformat (input, "%U", unformat_ethernet_address, &a->addr.mac))
13929     {
13930       a->type = 1;              /* mac type */
13931     }
13932   else if (unformat (input, "%U", unformat_nsh_address, a->addr.nsh))
13933     {
13934       a->type = 2;              /* NSH type */
13935       a->addr.nsh.spi = clib_host_to_net_u32 (a->addr.nsh.spi);
13936     }
13937   else
13938     {
13939       return 0;
13940     }
13941
13942   if (a->type == 0)
13943     {
13944       if (ip46_address_is_ip4 (&a->addr.ip))
13945         return a->len > 32 ? 1 : 0;
13946       else
13947         return a->len > 128 ? 1 : 0;
13948     }
13949
13950   return 1;
13951 }
13952
13953 static void
13954 lisp_eid_put_vat (vl_api_eid_t * eid, const lisp_eid_vat_t * vat_eid)
13955 {
13956   eid->type = vat_eid->type;
13957   switch (eid->type)
13958     {
13959     case EID_TYPE_API_PREFIX:
13960       if (ip46_address_is_ip4 (&vat_eid->addr.ip))
13961         {
13962           clib_memcpy (&eid->address.prefix.address.un.ip4,
13963                        &vat_eid->addr.ip.ip4, 4);
13964           eid->address.prefix.address.af = ADDRESS_IP4;
13965           eid->address.prefix.len = vat_eid->len;
13966         }
13967       else
13968         {
13969           clib_memcpy (&eid->address.prefix.address.un.ip6,
13970                        &vat_eid->addr.ip.ip6, 16);
13971           eid->address.prefix.address.af = ADDRESS_IP6;
13972           eid->address.prefix.len = vat_eid->len;
13973         }
13974       return;
13975     case EID_TYPE_API_MAC:
13976       clib_memcpy (&eid->address.mac, &vat_eid->addr.mac,
13977                    sizeof (eid->address.mac));
13978       return;
13979     case EID_TYPE_API_NSH:
13980       clib_memcpy (&eid->address.nsh, &vat_eid->addr.nsh,
13981                    sizeof (eid->address.nsh));
13982       return;
13983     default:
13984       ASSERT (0);
13985       return;
13986     }
13987 }
13988
13989 static int
13990 api_one_add_del_locator_set (vat_main_t * vam)
13991 {
13992   unformat_input_t *input = vam->input;
13993   vl_api_one_add_del_locator_set_t *mp;
13994   u8 is_add = 1;
13995   u8 *locator_set_name = NULL;
13996   u8 locator_set_name_set = 0;
13997   vl_api_local_locator_t locator, *locators = 0;
13998   u32 sw_if_index, priority, weight;
13999   u32 data_len = 0;
14000
14001   int ret;
14002   /* Parse args required to build the message */
14003   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14004     {
14005       if (unformat (input, "del"))
14006         {
14007           is_add = 0;
14008         }
14009       else if (unformat (input, "locator-set %s", &locator_set_name))
14010         {
14011           locator_set_name_set = 1;
14012         }
14013       else if (unformat (input, "sw_if_index %u p %u w %u",
14014                          &sw_if_index, &priority, &weight))
14015         {
14016           locator.sw_if_index = htonl (sw_if_index);
14017           locator.priority = priority;
14018           locator.weight = weight;
14019           vec_add1 (locators, locator);
14020         }
14021       else
14022         if (unformat
14023             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14024              &sw_if_index, &priority, &weight))
14025         {
14026           locator.sw_if_index = htonl (sw_if_index);
14027           locator.priority = priority;
14028           locator.weight = weight;
14029           vec_add1 (locators, locator);
14030         }
14031       else
14032         break;
14033     }
14034
14035   if (locator_set_name_set == 0)
14036     {
14037       errmsg ("missing locator-set name");
14038       vec_free (locators);
14039       return -99;
14040     }
14041
14042   if (vec_len (locator_set_name) > 64)
14043     {
14044       errmsg ("locator-set name too long");
14045       vec_free (locator_set_name);
14046       vec_free (locators);
14047       return -99;
14048     }
14049   vec_add1 (locator_set_name, 0);
14050
14051   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14052
14053   /* Construct the API message */
14054   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14055
14056   mp->is_add = is_add;
14057   clib_memcpy (mp->locator_set_name, locator_set_name,
14058                vec_len (locator_set_name));
14059   vec_free (locator_set_name);
14060
14061   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14062   if (locators)
14063     clib_memcpy (mp->locators, locators, data_len);
14064   vec_free (locators);
14065
14066   /* send it... */
14067   S (mp);
14068
14069   /* Wait for a reply... */
14070   W (ret);
14071   return ret;
14072 }
14073
14074 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14075
14076 static int
14077 api_one_add_del_locator (vat_main_t * vam)
14078 {
14079   unformat_input_t *input = vam->input;
14080   vl_api_one_add_del_locator_t *mp;
14081   u32 tmp_if_index = ~0;
14082   u32 sw_if_index = ~0;
14083   u8 sw_if_index_set = 0;
14084   u8 sw_if_index_if_name_set = 0;
14085   u32 priority = ~0;
14086   u8 priority_set = 0;
14087   u32 weight = ~0;
14088   u8 weight_set = 0;
14089   u8 is_add = 1;
14090   u8 *locator_set_name = NULL;
14091   u8 locator_set_name_set = 0;
14092   int ret;
14093
14094   /* Parse args required to build the message */
14095   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14096     {
14097       if (unformat (input, "del"))
14098         {
14099           is_add = 0;
14100         }
14101       else if (unformat (input, "locator-set %s", &locator_set_name))
14102         {
14103           locator_set_name_set = 1;
14104         }
14105       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14106                          &tmp_if_index))
14107         {
14108           sw_if_index_if_name_set = 1;
14109           sw_if_index = tmp_if_index;
14110         }
14111       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14112         {
14113           sw_if_index_set = 1;
14114           sw_if_index = tmp_if_index;
14115         }
14116       else if (unformat (input, "p %d", &priority))
14117         {
14118           priority_set = 1;
14119         }
14120       else if (unformat (input, "w %d", &weight))
14121         {
14122           weight_set = 1;
14123         }
14124       else
14125         break;
14126     }
14127
14128   if (locator_set_name_set == 0)
14129     {
14130       errmsg ("missing locator-set name");
14131       return -99;
14132     }
14133
14134   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14135     {
14136       errmsg ("missing sw_if_index");
14137       vec_free (locator_set_name);
14138       return -99;
14139     }
14140
14141   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14142     {
14143       errmsg ("cannot use both params interface name and sw_if_index");
14144       vec_free (locator_set_name);
14145       return -99;
14146     }
14147
14148   if (priority_set == 0)
14149     {
14150       errmsg ("missing locator-set priority");
14151       vec_free (locator_set_name);
14152       return -99;
14153     }
14154
14155   if (weight_set == 0)
14156     {
14157       errmsg ("missing locator-set weight");
14158       vec_free (locator_set_name);
14159       return -99;
14160     }
14161
14162   if (vec_len (locator_set_name) > 64)
14163     {
14164       errmsg ("locator-set name too long");
14165       vec_free (locator_set_name);
14166       return -99;
14167     }
14168   vec_add1 (locator_set_name, 0);
14169
14170   /* Construct the API message */
14171   M (ONE_ADD_DEL_LOCATOR, mp);
14172
14173   mp->is_add = is_add;
14174   mp->sw_if_index = ntohl (sw_if_index);
14175   mp->priority = priority;
14176   mp->weight = weight;
14177   clib_memcpy (mp->locator_set_name, locator_set_name,
14178                vec_len (locator_set_name));
14179   vec_free (locator_set_name);
14180
14181   /* send it... */
14182   S (mp);
14183
14184   /* Wait for a reply... */
14185   W (ret);
14186   return ret;
14187 }
14188
14189 #define api_lisp_add_del_locator api_one_add_del_locator
14190
14191 uword
14192 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
14193 {
14194   u32 *key_id = va_arg (*args, u32 *);
14195   u8 *s = 0;
14196
14197   if (unformat (input, "%s", &s))
14198     {
14199       if (!strcmp ((char *) s, "sha1"))
14200         key_id[0] = HMAC_SHA_1_96;
14201       else if (!strcmp ((char *) s, "sha256"))
14202         key_id[0] = HMAC_SHA_256_128;
14203       else
14204         {
14205           clib_warning ("invalid key_id: '%s'", s);
14206           key_id[0] = HMAC_NO_KEY;
14207         }
14208     }
14209   else
14210     return 0;
14211
14212   vec_free (s);
14213   return 1;
14214 }
14215
14216 static int
14217 api_one_add_del_local_eid (vat_main_t * vam)
14218 {
14219   unformat_input_t *input = vam->input;
14220   vl_api_one_add_del_local_eid_t *mp;
14221   u8 is_add = 1;
14222   u8 eid_set = 0;
14223   lisp_eid_vat_t _eid, *eid = &_eid;
14224   u8 *locator_set_name = 0;
14225   u8 locator_set_name_set = 0;
14226   u32 vni = 0;
14227   u16 key_id = 0;
14228   u8 *key = 0;
14229   int ret;
14230
14231   /* Parse args required to build the message */
14232   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14233     {
14234       if (unformat (input, "del"))
14235         {
14236           is_add = 0;
14237         }
14238       else if (unformat (input, "vni %d", &vni))
14239         {
14240           ;
14241         }
14242       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14243         {
14244           eid_set = 1;
14245         }
14246       else if (unformat (input, "locator-set %s", &locator_set_name))
14247         {
14248           locator_set_name_set = 1;
14249         }
14250       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
14251         ;
14252       else if (unformat (input, "secret-key %_%v%_", &key))
14253         ;
14254       else
14255         break;
14256     }
14257
14258   if (locator_set_name_set == 0)
14259     {
14260       errmsg ("missing locator-set name");
14261       return -99;
14262     }
14263
14264   if (0 == eid_set)
14265     {
14266       errmsg ("EID address not set!");
14267       vec_free (locator_set_name);
14268       return -99;
14269     }
14270
14271   if (key && (0 == key_id))
14272     {
14273       errmsg ("invalid key_id!");
14274       return -99;
14275     }
14276
14277   if (vec_len (key) > 64)
14278     {
14279       errmsg ("key too long");
14280       vec_free (key);
14281       return -99;
14282     }
14283
14284   if (vec_len (locator_set_name) > 64)
14285     {
14286       errmsg ("locator-set name too long");
14287       vec_free (locator_set_name);
14288       return -99;
14289     }
14290   vec_add1 (locator_set_name, 0);
14291
14292   /* Construct the API message */
14293   M (ONE_ADD_DEL_LOCAL_EID, mp);
14294
14295   mp->is_add = is_add;
14296   lisp_eid_put_vat (&mp->eid, eid);
14297   mp->vni = clib_host_to_net_u32 (vni);
14298   mp->key.id = key_id;
14299   clib_memcpy (mp->locator_set_name, locator_set_name,
14300                vec_len (locator_set_name));
14301   clib_memcpy (mp->key.key, key, vec_len (key));
14302
14303   vec_free (locator_set_name);
14304   vec_free (key);
14305
14306   /* send it... */
14307   S (mp);
14308
14309   /* Wait for a reply... */
14310   W (ret);
14311   return ret;
14312 }
14313
14314 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
14315
14316 static int
14317 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
14318 {
14319   u32 dp_table = 0, vni = 0;;
14320   unformat_input_t *input = vam->input;
14321   vl_api_gpe_add_del_fwd_entry_t *mp;
14322   u8 is_add = 1;
14323   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
14324   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
14325   u8 rmt_eid_set = 0, lcl_eid_set = 0;
14326   u32 action = ~0, w;
14327   ip4_address_t rmt_rloc4, lcl_rloc4;
14328   ip6_address_t rmt_rloc6, lcl_rloc6;
14329   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
14330   int ret;
14331
14332   clib_memset (&rloc, 0, sizeof (rloc));
14333
14334   /* Parse args required to build the message */
14335   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14336     {
14337       if (unformat (input, "del"))
14338         is_add = 0;
14339       else if (unformat (input, "add"))
14340         is_add = 1;
14341       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
14342         {
14343           rmt_eid_set = 1;
14344         }
14345       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
14346         {
14347           lcl_eid_set = 1;
14348         }
14349       else if (unformat (input, "vrf %d", &dp_table))
14350         ;
14351       else if (unformat (input, "bd %d", &dp_table))
14352         ;
14353       else if (unformat (input, "vni %d", &vni))
14354         ;
14355       else if (unformat (input, "w %d", &w))
14356         {
14357           if (!curr_rloc)
14358             {
14359               errmsg ("No RLOC configured for setting priority/weight!");
14360               return -99;
14361             }
14362           curr_rloc->weight = w;
14363         }
14364       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14365                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14366         {
14367           rloc.addr.af = 0;
14368           clib_memcpy (&rloc.addr.un.ip4, &lcl_rloc4, sizeof (lcl_rloc4));
14369           rloc.weight = 0;
14370           vec_add1 (lcl_locs, rloc);
14371
14372           clib_memcpy (&rloc.addr.un.ip4, &rmt_rloc4, sizeof (rmt_rloc4));
14373           vec_add1 (rmt_locs, rloc);
14374           /* weight saved in rmt loc */
14375           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14376         }
14377       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14378                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14379         {
14380           rloc.addr.af = 1;
14381           clib_memcpy (&rloc.addr.un.ip6, &lcl_rloc6, sizeof (lcl_rloc6));
14382           rloc.weight = 0;
14383           vec_add1 (lcl_locs, rloc);
14384
14385           clib_memcpy (&rloc.addr.un.ip6, &rmt_rloc6, sizeof (rmt_rloc6));
14386           vec_add1 (rmt_locs, rloc);
14387           /* weight saved in rmt loc */
14388           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14389         }
14390       else if (unformat (input, "action %d", &action))
14391         {
14392           ;
14393         }
14394       else
14395         {
14396           clib_warning ("parse error '%U'", format_unformat_error, input);
14397           return -99;
14398         }
14399     }
14400
14401   if (!rmt_eid_set)
14402     {
14403       errmsg ("remote eid addresses not set");
14404       return -99;
14405     }
14406
14407   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14408     {
14409       errmsg ("eid types don't match");
14410       return -99;
14411     }
14412
14413   if (0 == rmt_locs && (u32) ~ 0 == action)
14414     {
14415       errmsg ("action not set for negative mapping");
14416       return -99;
14417     }
14418
14419   /* Construct the API message */
14420   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14421       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
14422
14423   mp->is_add = is_add;
14424   lisp_eid_put_vat (&mp->rmt_eid, rmt_eid);
14425   lisp_eid_put_vat (&mp->lcl_eid, lcl_eid);
14426   mp->dp_table = clib_host_to_net_u32 (dp_table);
14427   mp->vni = clib_host_to_net_u32 (vni);
14428   mp->action = action;
14429
14430   if (0 != rmt_locs && 0 != lcl_locs)
14431     {
14432       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14433       clib_memcpy (mp->locs, lcl_locs,
14434                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
14435
14436       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14437       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14438                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
14439     }
14440   vec_free (lcl_locs);
14441   vec_free (rmt_locs);
14442
14443   /* send it... */
14444   S (mp);
14445
14446   /* Wait for a reply... */
14447   W (ret);
14448   return ret;
14449 }
14450
14451 static int
14452 api_one_add_del_map_server (vat_main_t * vam)
14453 {
14454   unformat_input_t *input = vam->input;
14455   vl_api_one_add_del_map_server_t *mp;
14456   u8 is_add = 1;
14457   u8 ipv4_set = 0;
14458   u8 ipv6_set = 0;
14459   ip4_address_t ipv4;
14460   ip6_address_t ipv6;
14461   int ret;
14462
14463   /* Parse args required to build the message */
14464   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14465     {
14466       if (unformat (input, "del"))
14467         {
14468           is_add = 0;
14469         }
14470       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14471         {
14472           ipv4_set = 1;
14473         }
14474       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14475         {
14476           ipv6_set = 1;
14477         }
14478       else
14479         break;
14480     }
14481
14482   if (ipv4_set && ipv6_set)
14483     {
14484       errmsg ("both eid v4 and v6 addresses set");
14485       return -99;
14486     }
14487
14488   if (!ipv4_set && !ipv6_set)
14489     {
14490       errmsg ("eid addresses not set");
14491       return -99;
14492     }
14493
14494   /* Construct the API message */
14495   M (ONE_ADD_DEL_MAP_SERVER, mp);
14496
14497   mp->is_add = is_add;
14498   if (ipv6_set)
14499     {
14500       mp->ip_address.af = 1;
14501       clib_memcpy (mp->ip_address.un.ip6, &ipv6, sizeof (ipv6));
14502     }
14503   else
14504     {
14505       mp->ip_address.af = 0;
14506       clib_memcpy (mp->ip_address.un.ip4, &ipv4, sizeof (ipv4));
14507     }
14508
14509   /* send it... */
14510   S (mp);
14511
14512   /* Wait for a reply... */
14513   W (ret);
14514   return ret;
14515 }
14516
14517 #define api_lisp_add_del_map_server api_one_add_del_map_server
14518
14519 static int
14520 api_one_add_del_map_resolver (vat_main_t * vam)
14521 {
14522   unformat_input_t *input = vam->input;
14523   vl_api_one_add_del_map_resolver_t *mp;
14524   u8 is_add = 1;
14525   u8 ipv4_set = 0;
14526   u8 ipv6_set = 0;
14527   ip4_address_t ipv4;
14528   ip6_address_t ipv6;
14529   int ret;
14530
14531   /* Parse args required to build the message */
14532   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14533     {
14534       if (unformat (input, "del"))
14535         {
14536           is_add = 0;
14537         }
14538       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14539         {
14540           ipv4_set = 1;
14541         }
14542       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14543         {
14544           ipv6_set = 1;
14545         }
14546       else
14547         break;
14548     }
14549
14550   if (ipv4_set && ipv6_set)
14551     {
14552       errmsg ("both eid v4 and v6 addresses set");
14553       return -99;
14554     }
14555
14556   if (!ipv4_set && !ipv6_set)
14557     {
14558       errmsg ("eid addresses not set");
14559       return -99;
14560     }
14561
14562   /* Construct the API message */
14563   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
14564
14565   mp->is_add = is_add;
14566   if (ipv6_set)
14567     {
14568       mp->ip_address.af = 1;
14569       clib_memcpy (mp->ip_address.un.ip6, &ipv6, sizeof (ipv6));
14570     }
14571   else
14572     {
14573       mp->ip_address.af = 0;
14574       clib_memcpy (mp->ip_address.un.ip6, &ipv4, sizeof (ipv4));
14575     }
14576
14577   /* send it... */
14578   S (mp);
14579
14580   /* Wait for a reply... */
14581   W (ret);
14582   return ret;
14583 }
14584
14585 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14586
14587 static int
14588 api_lisp_gpe_enable_disable (vat_main_t * vam)
14589 {
14590   unformat_input_t *input = vam->input;
14591   vl_api_gpe_enable_disable_t *mp;
14592   u8 is_set = 0;
14593   u8 is_enable = 1;
14594   int ret;
14595
14596   /* Parse args required to build the message */
14597   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14598     {
14599       if (unformat (input, "enable"))
14600         {
14601           is_set = 1;
14602           is_enable = 1;
14603         }
14604       else if (unformat (input, "disable"))
14605         {
14606           is_set = 1;
14607           is_enable = 0;
14608         }
14609       else
14610         break;
14611     }
14612
14613   if (is_set == 0)
14614     {
14615       errmsg ("Value not set");
14616       return -99;
14617     }
14618
14619   /* Construct the API message */
14620   M (GPE_ENABLE_DISABLE, mp);
14621
14622   mp->is_enable = is_enable;
14623
14624   /* send it... */
14625   S (mp);
14626
14627   /* Wait for a reply... */
14628   W (ret);
14629   return ret;
14630 }
14631
14632 static int
14633 api_one_rloc_probe_enable_disable (vat_main_t * vam)
14634 {
14635   unformat_input_t *input = vam->input;
14636   vl_api_one_rloc_probe_enable_disable_t *mp;
14637   u8 is_set = 0;
14638   u8 is_enable = 0;
14639   int ret;
14640
14641   /* Parse args required to build the message */
14642   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14643     {
14644       if (unformat (input, "enable"))
14645         {
14646           is_set = 1;
14647           is_enable = 1;
14648         }
14649       else if (unformat (input, "disable"))
14650         is_set = 1;
14651       else
14652         break;
14653     }
14654
14655   if (!is_set)
14656     {
14657       errmsg ("Value not set");
14658       return -99;
14659     }
14660
14661   /* Construct the API message */
14662   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
14663
14664   mp->is_enable = is_enable;
14665
14666   /* send it... */
14667   S (mp);
14668
14669   /* Wait for a reply... */
14670   W (ret);
14671   return ret;
14672 }
14673
14674 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14675
14676 static int
14677 api_one_map_register_enable_disable (vat_main_t * vam)
14678 {
14679   unformat_input_t *input = vam->input;
14680   vl_api_one_map_register_enable_disable_t *mp;
14681   u8 is_set = 0;
14682   u8 is_enable = 0;
14683   int ret;
14684
14685   /* Parse args required to build the message */
14686   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14687     {
14688       if (unformat (input, "enable"))
14689         {
14690           is_set = 1;
14691           is_enable = 1;
14692         }
14693       else if (unformat (input, "disable"))
14694         is_set = 1;
14695       else
14696         break;
14697     }
14698
14699   if (!is_set)
14700     {
14701       errmsg ("Value not set");
14702       return -99;
14703     }
14704
14705   /* Construct the API message */
14706   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
14707
14708   mp->is_enable = is_enable;
14709
14710   /* send it... */
14711   S (mp);
14712
14713   /* Wait for a reply... */
14714   W (ret);
14715   return ret;
14716 }
14717
14718 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14719
14720 static int
14721 api_one_enable_disable (vat_main_t * vam)
14722 {
14723   unformat_input_t *input = vam->input;
14724   vl_api_one_enable_disable_t *mp;
14725   u8 is_set = 0;
14726   u8 is_enable = 0;
14727   int ret;
14728
14729   /* Parse args required to build the message */
14730   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14731     {
14732       if (unformat (input, "enable"))
14733         {
14734           is_set = 1;
14735           is_enable = 1;
14736         }
14737       else if (unformat (input, "disable"))
14738         {
14739           is_set = 1;
14740         }
14741       else
14742         break;
14743     }
14744
14745   if (!is_set)
14746     {
14747       errmsg ("Value not set");
14748       return -99;
14749     }
14750
14751   /* Construct the API message */
14752   M (ONE_ENABLE_DISABLE, mp);
14753
14754   mp->is_enable = is_enable;
14755
14756   /* send it... */
14757   S (mp);
14758
14759   /* Wait for a reply... */
14760   W (ret);
14761   return ret;
14762 }
14763
14764 #define api_lisp_enable_disable api_one_enable_disable
14765
14766 static int
14767 api_one_enable_disable_xtr_mode (vat_main_t * vam)
14768 {
14769   unformat_input_t *input = vam->input;
14770   vl_api_one_enable_disable_xtr_mode_t *mp;
14771   u8 is_set = 0;
14772   u8 is_enable = 0;
14773   int ret;
14774
14775   /* Parse args required to build the message */
14776   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14777     {
14778       if (unformat (input, "enable"))
14779         {
14780           is_set = 1;
14781           is_enable = 1;
14782         }
14783       else if (unformat (input, "disable"))
14784         {
14785           is_set = 1;
14786         }
14787       else
14788         break;
14789     }
14790
14791   if (!is_set)
14792     {
14793       errmsg ("Value not set");
14794       return -99;
14795     }
14796
14797   /* Construct the API message */
14798   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
14799
14800   mp->is_enable = is_enable;
14801
14802   /* send it... */
14803   S (mp);
14804
14805   /* Wait for a reply... */
14806   W (ret);
14807   return ret;
14808 }
14809
14810 static int
14811 api_one_show_xtr_mode (vat_main_t * vam)
14812 {
14813   vl_api_one_show_xtr_mode_t *mp;
14814   int ret;
14815
14816   /* Construct the API message */
14817   M (ONE_SHOW_XTR_MODE, mp);
14818
14819   /* send it... */
14820   S (mp);
14821
14822   /* Wait for a reply... */
14823   W (ret);
14824   return ret;
14825 }
14826
14827 static int
14828 api_one_enable_disable_pitr_mode (vat_main_t * vam)
14829 {
14830   unformat_input_t *input = vam->input;
14831   vl_api_one_enable_disable_pitr_mode_t *mp;
14832   u8 is_set = 0;
14833   u8 is_enable = 0;
14834   int ret;
14835
14836   /* Parse args required to build the message */
14837   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14838     {
14839       if (unformat (input, "enable"))
14840         {
14841           is_set = 1;
14842           is_enable = 1;
14843         }
14844       else if (unformat (input, "disable"))
14845         {
14846           is_set = 1;
14847         }
14848       else
14849         break;
14850     }
14851
14852   if (!is_set)
14853     {
14854       errmsg ("Value not set");
14855       return -99;
14856     }
14857
14858   /* Construct the API message */
14859   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
14860
14861   mp->is_enable = is_enable;
14862
14863   /* send it... */
14864   S (mp);
14865
14866   /* Wait for a reply... */
14867   W (ret);
14868   return ret;
14869 }
14870
14871 static int
14872 api_one_show_pitr_mode (vat_main_t * vam)
14873 {
14874   vl_api_one_show_pitr_mode_t *mp;
14875   int ret;
14876
14877   /* Construct the API message */
14878   M (ONE_SHOW_PITR_MODE, mp);
14879
14880   /* send it... */
14881   S (mp);
14882
14883   /* Wait for a reply... */
14884   W (ret);
14885   return ret;
14886 }
14887
14888 static int
14889 api_one_enable_disable_petr_mode (vat_main_t * vam)
14890 {
14891   unformat_input_t *input = vam->input;
14892   vl_api_one_enable_disable_petr_mode_t *mp;
14893   u8 is_set = 0;
14894   u8 is_enable = 0;
14895   int ret;
14896
14897   /* Parse args required to build the message */
14898   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14899     {
14900       if (unformat (input, "enable"))
14901         {
14902           is_set = 1;
14903           is_enable = 1;
14904         }
14905       else if (unformat (input, "disable"))
14906         {
14907           is_set = 1;
14908         }
14909       else
14910         break;
14911     }
14912
14913   if (!is_set)
14914     {
14915       errmsg ("Value not set");
14916       return -99;
14917     }
14918
14919   /* Construct the API message */
14920   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
14921
14922   mp->is_enable = is_enable;
14923
14924   /* send it... */
14925   S (mp);
14926
14927   /* Wait for a reply... */
14928   W (ret);
14929   return ret;
14930 }
14931
14932 static int
14933 api_one_show_petr_mode (vat_main_t * vam)
14934 {
14935   vl_api_one_show_petr_mode_t *mp;
14936   int ret;
14937
14938   /* Construct the API message */
14939   M (ONE_SHOW_PETR_MODE, mp);
14940
14941   /* send it... */
14942   S (mp);
14943
14944   /* Wait for a reply... */
14945   W (ret);
14946   return ret;
14947 }
14948
14949 static int
14950 api_show_one_map_register_state (vat_main_t * vam)
14951 {
14952   vl_api_show_one_map_register_state_t *mp;
14953   int ret;
14954
14955   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
14956
14957   /* send */
14958   S (mp);
14959
14960   /* wait for reply */
14961   W (ret);
14962   return ret;
14963 }
14964
14965 #define api_show_lisp_map_register_state api_show_one_map_register_state
14966
14967 static int
14968 api_show_one_rloc_probe_state (vat_main_t * vam)
14969 {
14970   vl_api_show_one_rloc_probe_state_t *mp;
14971   int ret;
14972
14973   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
14974
14975   /* send */
14976   S (mp);
14977
14978   /* wait for reply */
14979   W (ret);
14980   return ret;
14981 }
14982
14983 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
14984
14985 static int
14986 api_one_add_del_ndp_entry (vat_main_t * vam)
14987 {
14988   vl_api_one_add_del_ndp_entry_t *mp;
14989   unformat_input_t *input = vam->input;
14990   u8 is_add = 1;
14991   u8 mac_set = 0;
14992   u8 bd_set = 0;
14993   u8 ip_set = 0;
14994   u8 mac[6] = { 0, };
14995   u8 ip6[16] = { 0, };
14996   u32 bd = ~0;
14997   int ret;
14998
14999   /* Parse args required to build the message */
15000   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15001     {
15002       if (unformat (input, "del"))
15003         is_add = 0;
15004       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15005         mac_set = 1;
15006       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
15007         ip_set = 1;
15008       else if (unformat (input, "bd %d", &bd))
15009         bd_set = 1;
15010       else
15011         {
15012           errmsg ("parse error '%U'", format_unformat_error, input);
15013           return -99;
15014         }
15015     }
15016
15017   if (!bd_set || !ip_set || (!mac_set && is_add))
15018     {
15019       errmsg ("Missing BD, IP or MAC!");
15020       return -99;
15021     }
15022
15023   M (ONE_ADD_DEL_NDP_ENTRY, mp);
15024   mp->is_add = is_add;
15025   clib_memcpy (&mp->entry.mac, mac, 6);
15026   mp->bd = clib_host_to_net_u32 (bd);
15027   clib_memcpy (&mp->entry.ip6, ip6, sizeof (mp->entry.ip6));
15028
15029   /* send */
15030   S (mp);
15031
15032   /* wait for reply */
15033   W (ret);
15034   return ret;
15035 }
15036
15037 static int
15038 api_one_add_del_l2_arp_entry (vat_main_t * vam)
15039 {
15040   vl_api_one_add_del_l2_arp_entry_t *mp;
15041   unformat_input_t *input = vam->input;
15042   u8 is_add = 1;
15043   u8 mac_set = 0;
15044   u8 bd_set = 0;
15045   u8 ip_set = 0;
15046   u8 mac[6] = { 0, };
15047   u32 ip4 = 0, bd = ~0;
15048   int ret;
15049
15050   /* Parse args required to build the message */
15051   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15052     {
15053       if (unformat (input, "del"))
15054         is_add = 0;
15055       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15056         mac_set = 1;
15057       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
15058         ip_set = 1;
15059       else if (unformat (input, "bd %d", &bd))
15060         bd_set = 1;
15061       else
15062         {
15063           errmsg ("parse error '%U'", format_unformat_error, input);
15064           return -99;
15065         }
15066     }
15067
15068   if (!bd_set || !ip_set || (!mac_set && is_add))
15069     {
15070       errmsg ("Missing BD, IP or MAC!");
15071       return -99;
15072     }
15073
15074   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
15075   mp->is_add = is_add;
15076   clib_memcpy (&mp->entry.mac, mac, 6);
15077   mp->bd = clib_host_to_net_u32 (bd);
15078   clib_memcpy (mp->entry.ip4, &ip4, sizeof (mp->entry.ip4));
15079
15080   /* send */
15081   S (mp);
15082
15083   /* wait for reply */
15084   W (ret);
15085   return ret;
15086 }
15087
15088 static int
15089 api_one_ndp_bd_get (vat_main_t * vam)
15090 {
15091   vl_api_one_ndp_bd_get_t *mp;
15092   int ret;
15093
15094   M (ONE_NDP_BD_GET, mp);
15095
15096   /* send */
15097   S (mp);
15098
15099   /* wait for reply */
15100   W (ret);
15101   return ret;
15102 }
15103
15104 static int
15105 api_one_ndp_entries_get (vat_main_t * vam)
15106 {
15107   vl_api_one_ndp_entries_get_t *mp;
15108   unformat_input_t *input = vam->input;
15109   u8 bd_set = 0;
15110   u32 bd = ~0;
15111   int ret;
15112
15113   /* Parse args required to build the message */
15114   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15115     {
15116       if (unformat (input, "bd %d", &bd))
15117         bd_set = 1;
15118       else
15119         {
15120           errmsg ("parse error '%U'", format_unformat_error, input);
15121           return -99;
15122         }
15123     }
15124
15125   if (!bd_set)
15126     {
15127       errmsg ("Expected bridge domain!");
15128       return -99;
15129     }
15130
15131   M (ONE_NDP_ENTRIES_GET, mp);
15132   mp->bd = clib_host_to_net_u32 (bd);
15133
15134   /* send */
15135   S (mp);
15136
15137   /* wait for reply */
15138   W (ret);
15139   return ret;
15140 }
15141
15142 static int
15143 api_one_l2_arp_bd_get (vat_main_t * vam)
15144 {
15145   vl_api_one_l2_arp_bd_get_t *mp;
15146   int ret;
15147
15148   M (ONE_L2_ARP_BD_GET, mp);
15149
15150   /* send */
15151   S (mp);
15152
15153   /* wait for reply */
15154   W (ret);
15155   return ret;
15156 }
15157
15158 static int
15159 api_one_l2_arp_entries_get (vat_main_t * vam)
15160 {
15161   vl_api_one_l2_arp_entries_get_t *mp;
15162   unformat_input_t *input = vam->input;
15163   u8 bd_set = 0;
15164   u32 bd = ~0;
15165   int ret;
15166
15167   /* Parse args required to build the message */
15168   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15169     {
15170       if (unformat (input, "bd %d", &bd))
15171         bd_set = 1;
15172       else
15173         {
15174           errmsg ("parse error '%U'", format_unformat_error, input);
15175           return -99;
15176         }
15177     }
15178
15179   if (!bd_set)
15180     {
15181       errmsg ("Expected bridge domain!");
15182       return -99;
15183     }
15184
15185   M (ONE_L2_ARP_ENTRIES_GET, mp);
15186   mp->bd = clib_host_to_net_u32 (bd);
15187
15188   /* send */
15189   S (mp);
15190
15191   /* wait for reply */
15192   W (ret);
15193   return ret;
15194 }
15195
15196 static int
15197 api_one_stats_enable_disable (vat_main_t * vam)
15198 {
15199   vl_api_one_stats_enable_disable_t *mp;
15200   unformat_input_t *input = vam->input;
15201   u8 is_set = 0;
15202   u8 is_enable = 0;
15203   int ret;
15204
15205   /* Parse args required to build the message */
15206   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15207     {
15208       if (unformat (input, "enable"))
15209         {
15210           is_set = 1;
15211           is_enable = 1;
15212         }
15213       else if (unformat (input, "disable"))
15214         {
15215           is_set = 1;
15216         }
15217       else
15218         break;
15219     }
15220
15221   if (!is_set)
15222     {
15223       errmsg ("Value not set");
15224       return -99;
15225     }
15226
15227   M (ONE_STATS_ENABLE_DISABLE, mp);
15228   mp->is_enable = is_enable;
15229
15230   /* send */
15231   S (mp);
15232
15233   /* wait for reply */
15234   W (ret);
15235   return ret;
15236 }
15237
15238 static int
15239 api_show_one_stats_enable_disable (vat_main_t * vam)
15240 {
15241   vl_api_show_one_stats_enable_disable_t *mp;
15242   int ret;
15243
15244   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
15245
15246   /* send */
15247   S (mp);
15248
15249   /* wait for reply */
15250   W (ret);
15251   return ret;
15252 }
15253
15254 static int
15255 api_show_one_map_request_mode (vat_main_t * vam)
15256 {
15257   vl_api_show_one_map_request_mode_t *mp;
15258   int ret;
15259
15260   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
15261
15262   /* send */
15263   S (mp);
15264
15265   /* wait for reply */
15266   W (ret);
15267   return ret;
15268 }
15269
15270 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
15271
15272 static int
15273 api_one_map_request_mode (vat_main_t * vam)
15274 {
15275   unformat_input_t *input = vam->input;
15276   vl_api_one_map_request_mode_t *mp;
15277   u8 mode = 0;
15278   int ret;
15279
15280   /* Parse args required to build the message */
15281   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15282     {
15283       if (unformat (input, "dst-only"))
15284         mode = 0;
15285       else if (unformat (input, "src-dst"))
15286         mode = 1;
15287       else
15288         {
15289           errmsg ("parse error '%U'", format_unformat_error, input);
15290           return -99;
15291         }
15292     }
15293
15294   M (ONE_MAP_REQUEST_MODE, mp);
15295
15296   mp->mode = mode;
15297
15298   /* send */
15299   S (mp);
15300
15301   /* wait for reply */
15302   W (ret);
15303   return ret;
15304 }
15305
15306 #define api_lisp_map_request_mode api_one_map_request_mode
15307
15308 /**
15309  * Enable/disable ONE proxy ITR.
15310  *
15311  * @param vam vpp API test context
15312  * @return return code
15313  */
15314 static int
15315 api_one_pitr_set_locator_set (vat_main_t * vam)
15316 {
15317   u8 ls_name_set = 0;
15318   unformat_input_t *input = vam->input;
15319   vl_api_one_pitr_set_locator_set_t *mp;
15320   u8 is_add = 1;
15321   u8 *ls_name = 0;
15322   int ret;
15323
15324   /* Parse args required to build the message */
15325   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15326     {
15327       if (unformat (input, "del"))
15328         is_add = 0;
15329       else if (unformat (input, "locator-set %s", &ls_name))
15330         ls_name_set = 1;
15331       else
15332         {
15333           errmsg ("parse error '%U'", format_unformat_error, input);
15334           return -99;
15335         }
15336     }
15337
15338   if (!ls_name_set)
15339     {
15340       errmsg ("locator-set name not set!");
15341       return -99;
15342     }
15343
15344   M (ONE_PITR_SET_LOCATOR_SET, mp);
15345
15346   mp->is_add = is_add;
15347   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15348   vec_free (ls_name);
15349
15350   /* send */
15351   S (mp);
15352
15353   /* wait for reply */
15354   W (ret);
15355   return ret;
15356 }
15357
15358 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
15359
15360 static int
15361 api_one_nsh_set_locator_set (vat_main_t * vam)
15362 {
15363   u8 ls_name_set = 0;
15364   unformat_input_t *input = vam->input;
15365   vl_api_one_nsh_set_locator_set_t *mp;
15366   u8 is_add = 1;
15367   u8 *ls_name = 0;
15368   int ret;
15369
15370   /* Parse args required to build the message */
15371   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15372     {
15373       if (unformat (input, "del"))
15374         is_add = 0;
15375       else if (unformat (input, "ls %s", &ls_name))
15376         ls_name_set = 1;
15377       else
15378         {
15379           errmsg ("parse error '%U'", format_unformat_error, input);
15380           return -99;
15381         }
15382     }
15383
15384   if (!ls_name_set && is_add)
15385     {
15386       errmsg ("locator-set name not set!");
15387       return -99;
15388     }
15389
15390   M (ONE_NSH_SET_LOCATOR_SET, mp);
15391
15392   mp->is_add = is_add;
15393   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15394   vec_free (ls_name);
15395
15396   /* send */
15397   S (mp);
15398
15399   /* wait for reply */
15400   W (ret);
15401   return ret;
15402 }
15403
15404 static int
15405 api_show_one_pitr (vat_main_t * vam)
15406 {
15407   vl_api_show_one_pitr_t *mp;
15408   int ret;
15409
15410   if (!vam->json_output)
15411     {
15412       print (vam->ofp, "%=20s", "lisp status:");
15413     }
15414
15415   M (SHOW_ONE_PITR, mp);
15416   /* send it... */
15417   S (mp);
15418
15419   /* Wait for a reply... */
15420   W (ret);
15421   return ret;
15422 }
15423
15424 #define api_show_lisp_pitr api_show_one_pitr
15425
15426 static int
15427 api_one_use_petr (vat_main_t * vam)
15428 {
15429   unformat_input_t *input = vam->input;
15430   vl_api_one_use_petr_t *mp;
15431   u8 is_add = 0;
15432   ip_address_t ip;
15433   int ret;
15434
15435   clib_memset (&ip, 0, sizeof (ip));
15436
15437   /* Parse args required to build the message */
15438   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15439     {
15440       if (unformat (input, "disable"))
15441         is_add = 0;
15442       else
15443         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
15444         {
15445           is_add = 1;
15446           ip_addr_version (&ip) = AF_IP4;
15447         }
15448       else
15449         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
15450         {
15451           is_add = 1;
15452           ip_addr_version (&ip) = AF_IP6;
15453         }
15454       else
15455         {
15456           errmsg ("parse error '%U'", format_unformat_error, input);
15457           return -99;
15458         }
15459     }
15460
15461   M (ONE_USE_PETR, mp);
15462
15463   mp->is_add = is_add;
15464   if (is_add)
15465     {
15466       mp->ip_address.af = ip_addr_version (&ip) == AF_IP4 ? 0 : 1;
15467       if (mp->ip_address.af)
15468         clib_memcpy (mp->ip_address.un.ip6, &ip, 16);
15469       else
15470         clib_memcpy (mp->ip_address.un.ip4, &ip, 4);
15471     }
15472
15473   /* send */
15474   S (mp);
15475
15476   /* wait for reply */
15477   W (ret);
15478   return ret;
15479 }
15480
15481 #define api_lisp_use_petr api_one_use_petr
15482
15483 static int
15484 api_show_one_nsh_mapping (vat_main_t * vam)
15485 {
15486   vl_api_show_one_use_petr_t *mp;
15487   int ret;
15488
15489   if (!vam->json_output)
15490     {
15491       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
15492     }
15493
15494   M (SHOW_ONE_NSH_MAPPING, mp);
15495   /* send it... */
15496   S (mp);
15497
15498   /* Wait for a reply... */
15499   W (ret);
15500   return ret;
15501 }
15502
15503 static int
15504 api_show_one_use_petr (vat_main_t * vam)
15505 {
15506   vl_api_show_one_use_petr_t *mp;
15507   int ret;
15508
15509   if (!vam->json_output)
15510     {
15511       print (vam->ofp, "%=20s", "Proxy-ETR status:");
15512     }
15513
15514   M (SHOW_ONE_USE_PETR, mp);
15515   /* send it... */
15516   S (mp);
15517
15518   /* Wait for a reply... */
15519   W (ret);
15520   return ret;
15521 }
15522
15523 #define api_show_lisp_use_petr api_show_one_use_petr
15524
15525 /**
15526  * Add/delete mapping between vni and vrf
15527  */
15528 static int
15529 api_one_eid_table_add_del_map (vat_main_t * vam)
15530 {
15531   unformat_input_t *input = vam->input;
15532   vl_api_one_eid_table_add_del_map_t *mp;
15533   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
15534   u32 vni, vrf, bd_index;
15535   int ret;
15536
15537   /* Parse args required to build the message */
15538   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15539     {
15540       if (unformat (input, "del"))
15541         is_add = 0;
15542       else if (unformat (input, "vrf %d", &vrf))
15543         vrf_set = 1;
15544       else if (unformat (input, "bd_index %d", &bd_index))
15545         bd_index_set = 1;
15546       else if (unformat (input, "vni %d", &vni))
15547         vni_set = 1;
15548       else
15549         break;
15550     }
15551
15552   if (!vni_set || (!vrf_set && !bd_index_set))
15553     {
15554       errmsg ("missing arguments!");
15555       return -99;
15556     }
15557
15558   if (vrf_set && bd_index_set)
15559     {
15560       errmsg ("error: both vrf and bd entered!");
15561       return -99;
15562     }
15563
15564   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
15565
15566   mp->is_add = is_add;
15567   mp->vni = htonl (vni);
15568   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
15569   mp->is_l2 = bd_index_set;
15570
15571   /* send */
15572   S (mp);
15573
15574   /* wait for reply */
15575   W (ret);
15576   return ret;
15577 }
15578
15579 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
15580
15581 uword
15582 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
15583 {
15584   u32 *action = va_arg (*args, u32 *);
15585   u8 *s = 0;
15586
15587   if (unformat (input, "%s", &s))
15588     {
15589       if (!strcmp ((char *) s, "no-action"))
15590         action[0] = 0;
15591       else if (!strcmp ((char *) s, "natively-forward"))
15592         action[0] = 1;
15593       else if (!strcmp ((char *) s, "send-map-request"))
15594         action[0] = 2;
15595       else if (!strcmp ((char *) s, "drop"))
15596         action[0] = 3;
15597       else
15598         {
15599           clib_warning ("invalid action: '%s'", s);
15600           action[0] = 3;
15601         }
15602     }
15603   else
15604     return 0;
15605
15606   vec_free (s);
15607   return 1;
15608 }
15609
15610 /**
15611  * Add/del remote mapping to/from ONE control plane
15612  *
15613  * @param vam vpp API test context
15614  * @return return code
15615  */
15616 static int
15617 api_one_add_del_remote_mapping (vat_main_t * vam)
15618 {
15619   unformat_input_t *input = vam->input;
15620   vl_api_one_add_del_remote_mapping_t *mp;
15621   u32 vni = 0;
15622   lisp_eid_vat_t _eid, *eid = &_eid;
15623   lisp_eid_vat_t _seid, *seid = &_seid;
15624   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
15625   u32 action = ~0, p, w, data_len;
15626   ip4_address_t rloc4;
15627   ip6_address_t rloc6;
15628   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
15629   int ret;
15630
15631   clib_memset (&rloc, 0, sizeof (rloc));
15632
15633   /* Parse args required to build the message */
15634   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15635     {
15636       if (unformat (input, "del-all"))
15637         {
15638           del_all = 1;
15639         }
15640       else if (unformat (input, "del"))
15641         {
15642           is_add = 0;
15643         }
15644       else if (unformat (input, "add"))
15645         {
15646           is_add = 1;
15647         }
15648       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15649         {
15650           eid_set = 1;
15651         }
15652       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
15653         {
15654           seid_set = 1;
15655         }
15656       else if (unformat (input, "vni %d", &vni))
15657         {
15658           ;
15659         }
15660       else if (unformat (input, "p %d w %d", &p, &w))
15661         {
15662           if (!curr_rloc)
15663             {
15664               errmsg ("No RLOC configured for setting priority/weight!");
15665               return -99;
15666             }
15667           curr_rloc->priority = p;
15668           curr_rloc->weight = w;
15669         }
15670       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
15671         {
15672           rloc.ip_address.af = 0;
15673           clib_memcpy (&rloc.ip_address.un.ip6, &rloc6, sizeof (rloc6));
15674           vec_add1 (rlocs, rloc);
15675           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15676         }
15677       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
15678         {
15679           rloc.ip_address.af = 1;
15680           clib_memcpy (&rloc.ip_address.un.ip4, &rloc4, sizeof (rloc4));
15681           vec_add1 (rlocs, rloc);
15682           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15683         }
15684       else if (unformat (input, "action %U",
15685                          unformat_negative_mapping_action, &action))
15686         {
15687           ;
15688         }
15689       else
15690         {
15691           clib_warning ("parse error '%U'", format_unformat_error, input);
15692           return -99;
15693         }
15694     }
15695
15696   if (0 == eid_set)
15697     {
15698       errmsg ("missing params!");
15699       return -99;
15700     }
15701
15702   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
15703     {
15704       errmsg ("no action set for negative map-reply!");
15705       return -99;
15706     }
15707
15708   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
15709
15710   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
15711   mp->is_add = is_add;
15712   mp->vni = htonl (vni);
15713   mp->action = (u8) action;
15714   mp->is_src_dst = seid_set;
15715   mp->del_all = del_all;
15716   lisp_eid_put_vat (&mp->deid, eid);
15717   lisp_eid_put_vat (&mp->seid, seid);
15718
15719   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
15720   clib_memcpy (mp->rlocs, rlocs, data_len);
15721   vec_free (rlocs);
15722
15723   /* send it... */
15724   S (mp);
15725
15726   /* Wait for a reply... */
15727   W (ret);
15728   return ret;
15729 }
15730
15731 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
15732
15733 /**
15734  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
15735  * forwarding entries in data-plane accordingly.
15736  *
15737  * @param vam vpp API test context
15738  * @return return code
15739  */
15740 static int
15741 api_one_add_del_adjacency (vat_main_t * vam)
15742 {
15743   unformat_input_t *input = vam->input;
15744   vl_api_one_add_del_adjacency_t *mp;
15745   u32 vni = 0;
15746   u8 is_add = 1;
15747   int ret;
15748   lisp_eid_vat_t leid, reid;
15749
15750   leid.type = reid.type = (u8) ~ 0;
15751
15752   /* Parse args required to build the message */
15753   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15754     {
15755       if (unformat (input, "del"))
15756         {
15757           is_add = 0;
15758         }
15759       else if (unformat (input, "add"))
15760         {
15761           is_add = 1;
15762         }
15763       else if (unformat (input, "reid %U/%d", unformat_ip46_address,
15764                          &reid.addr.ip, &reid.len))
15765         {
15766           reid.type = 0;        /* ipv4 */
15767         }
15768       else if (unformat (input, "reid %U", unformat_ethernet_address,
15769                          &reid.addr.mac))
15770         {
15771           reid.type = 1;        /* mac */
15772         }
15773       else if (unformat (input, "leid %U/%d", unformat_ip46_address,
15774                          &leid.addr.ip, &leid.len))
15775         {
15776           leid.type = 0;        /* ipv4 */
15777         }
15778       else if (unformat (input, "leid %U", unformat_ethernet_address,
15779                          &leid.addr.mac))
15780         {
15781           leid.type = 1;        /* mac */
15782         }
15783       else if (unformat (input, "vni %d", &vni))
15784         {
15785           ;
15786         }
15787       else
15788         {
15789           errmsg ("parse error '%U'", format_unformat_error, input);
15790           return -99;
15791         }
15792     }
15793
15794   if ((u8) ~ 0 == reid.type)
15795     {
15796       errmsg ("missing params!");
15797       return -99;
15798     }
15799
15800   if (leid.type != reid.type)
15801     {
15802       errmsg ("remote and local EIDs are of different types!");
15803       return -99;
15804     }
15805
15806   M (ONE_ADD_DEL_ADJACENCY, mp);
15807   mp->is_add = is_add;
15808   mp->vni = htonl (vni);
15809   lisp_eid_put_vat (&mp->leid, &leid);
15810   lisp_eid_put_vat (&mp->reid, &reid);
15811
15812   /* send it... */
15813   S (mp);
15814
15815   /* Wait for a reply... */
15816   W (ret);
15817   return ret;
15818 }
15819
15820 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
15821
15822 uword
15823 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
15824 {
15825   u32 *mode = va_arg (*args, u32 *);
15826
15827   if (unformat (input, "lisp"))
15828     *mode = 0;
15829   else if (unformat (input, "vxlan"))
15830     *mode = 1;
15831   else
15832     return 0;
15833
15834   return 1;
15835 }
15836
15837 static int
15838 api_gpe_get_encap_mode (vat_main_t * vam)
15839 {
15840   vl_api_gpe_get_encap_mode_t *mp;
15841   int ret;
15842
15843   /* Construct the API message */
15844   M (GPE_GET_ENCAP_MODE, mp);
15845
15846   /* send it... */
15847   S (mp);
15848
15849   /* Wait for a reply... */
15850   W (ret);
15851   return ret;
15852 }
15853
15854 static int
15855 api_gpe_set_encap_mode (vat_main_t * vam)
15856 {
15857   unformat_input_t *input = vam->input;
15858   vl_api_gpe_set_encap_mode_t *mp;
15859   int ret;
15860   u32 mode = 0;
15861
15862   /* Parse args required to build the message */
15863   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15864     {
15865       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
15866         ;
15867       else
15868         break;
15869     }
15870
15871   /* Construct the API message */
15872   M (GPE_SET_ENCAP_MODE, mp);
15873
15874   mp->is_vxlan = mode;
15875
15876   /* send it... */
15877   S (mp);
15878
15879   /* Wait for a reply... */
15880   W (ret);
15881   return ret;
15882 }
15883
15884 static int
15885 api_lisp_gpe_add_del_iface (vat_main_t * vam)
15886 {
15887   unformat_input_t *input = vam->input;
15888   vl_api_gpe_add_del_iface_t *mp;
15889   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
15890   u32 dp_table = 0, vni = 0;
15891   int ret;
15892
15893   /* Parse args required to build the message */
15894   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15895     {
15896       if (unformat (input, "up"))
15897         {
15898           action_set = 1;
15899           is_add = 1;
15900         }
15901       else if (unformat (input, "down"))
15902         {
15903           action_set = 1;
15904           is_add = 0;
15905         }
15906       else if (unformat (input, "table_id %d", &dp_table))
15907         {
15908           dp_table_set = 1;
15909         }
15910       else if (unformat (input, "bd_id %d", &dp_table))
15911         {
15912           dp_table_set = 1;
15913           is_l2 = 1;
15914         }
15915       else if (unformat (input, "vni %d", &vni))
15916         {
15917           vni_set = 1;
15918         }
15919       else
15920         break;
15921     }
15922
15923   if (action_set == 0)
15924     {
15925       errmsg ("Action not set");
15926       return -99;
15927     }
15928   if (dp_table_set == 0 || vni_set == 0)
15929     {
15930       errmsg ("vni and dp_table must be set");
15931       return -99;
15932     }
15933
15934   /* Construct the API message */
15935   M (GPE_ADD_DEL_IFACE, mp);
15936
15937   mp->is_add = is_add;
15938   mp->dp_table = clib_host_to_net_u32 (dp_table);
15939   mp->is_l2 = is_l2;
15940   mp->vni = clib_host_to_net_u32 (vni);
15941
15942   /* send it... */
15943   S (mp);
15944
15945   /* Wait for a reply... */
15946   W (ret);
15947   return ret;
15948 }
15949
15950 static int
15951 api_one_map_register_fallback_threshold (vat_main_t * vam)
15952 {
15953   unformat_input_t *input = vam->input;
15954   vl_api_one_map_register_fallback_threshold_t *mp;
15955   u32 value = 0;
15956   u8 is_set = 0;
15957   int ret;
15958
15959   /* Parse args required to build the message */
15960   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15961     {
15962       if (unformat (input, "%u", &value))
15963         is_set = 1;
15964       else
15965         {
15966           clib_warning ("parse error '%U'", format_unformat_error, input);
15967           return -99;
15968         }
15969     }
15970
15971   if (!is_set)
15972     {
15973       errmsg ("fallback threshold value is missing!");
15974       return -99;
15975     }
15976
15977   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
15978   mp->value = clib_host_to_net_u32 (value);
15979
15980   /* send it... */
15981   S (mp);
15982
15983   /* Wait for a reply... */
15984   W (ret);
15985   return ret;
15986 }
15987
15988 static int
15989 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
15990 {
15991   vl_api_show_one_map_register_fallback_threshold_t *mp;
15992   int ret;
15993
15994   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
15995
15996   /* send it... */
15997   S (mp);
15998
15999   /* Wait for a reply... */
16000   W (ret);
16001   return ret;
16002 }
16003
16004 uword
16005 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
16006 {
16007   u32 *proto = va_arg (*args, u32 *);
16008
16009   if (unformat (input, "udp"))
16010     *proto = 1;
16011   else if (unformat (input, "api"))
16012     *proto = 2;
16013   else
16014     return 0;
16015
16016   return 1;
16017 }
16018
16019 static int
16020 api_one_set_transport_protocol (vat_main_t * vam)
16021 {
16022   unformat_input_t *input = vam->input;
16023   vl_api_one_set_transport_protocol_t *mp;
16024   u8 is_set = 0;
16025   u32 protocol = 0;
16026   int ret;
16027
16028   /* Parse args required to build the message */
16029   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16030     {
16031       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
16032         is_set = 1;
16033       else
16034         {
16035           clib_warning ("parse error '%U'", format_unformat_error, input);
16036           return -99;
16037         }
16038     }
16039
16040   if (!is_set)
16041     {
16042       errmsg ("Transport protocol missing!");
16043       return -99;
16044     }
16045
16046   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
16047   mp->protocol = (u8) protocol;
16048
16049   /* send it... */
16050   S (mp);
16051
16052   /* Wait for a reply... */
16053   W (ret);
16054   return ret;
16055 }
16056
16057 static int
16058 api_one_get_transport_protocol (vat_main_t * vam)
16059 {
16060   vl_api_one_get_transport_protocol_t *mp;
16061   int ret;
16062
16063   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
16064
16065   /* send it... */
16066   S (mp);
16067
16068   /* Wait for a reply... */
16069   W (ret);
16070   return ret;
16071 }
16072
16073 static int
16074 api_one_map_register_set_ttl (vat_main_t * vam)
16075 {
16076   unformat_input_t *input = vam->input;
16077   vl_api_one_map_register_set_ttl_t *mp;
16078   u32 ttl = 0;
16079   u8 is_set = 0;
16080   int ret;
16081
16082   /* Parse args required to build the message */
16083   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16084     {
16085       if (unformat (input, "%u", &ttl))
16086         is_set = 1;
16087       else
16088         {
16089           clib_warning ("parse error '%U'", format_unformat_error, input);
16090           return -99;
16091         }
16092     }
16093
16094   if (!is_set)
16095     {
16096       errmsg ("TTL value missing!");
16097       return -99;
16098     }
16099
16100   M (ONE_MAP_REGISTER_SET_TTL, mp);
16101   mp->ttl = clib_host_to_net_u32 (ttl);
16102
16103   /* send it... */
16104   S (mp);
16105
16106   /* Wait for a reply... */
16107   W (ret);
16108   return ret;
16109 }
16110
16111 static int
16112 api_show_one_map_register_ttl (vat_main_t * vam)
16113 {
16114   vl_api_show_one_map_register_ttl_t *mp;
16115   int ret;
16116
16117   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
16118
16119   /* send it... */
16120   S (mp);
16121
16122   /* Wait for a reply... */
16123   W (ret);
16124   return ret;
16125 }
16126
16127 /**
16128  * Add/del map request itr rlocs from ONE control plane and updates
16129  *
16130  * @param vam vpp API test context
16131  * @return return code
16132  */
16133 static int
16134 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
16135 {
16136   unformat_input_t *input = vam->input;
16137   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
16138   u8 *locator_set_name = 0;
16139   u8 locator_set_name_set = 0;
16140   u8 is_add = 1;
16141   int ret;
16142
16143   /* Parse args required to build the message */
16144   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16145     {
16146       if (unformat (input, "del"))
16147         {
16148           is_add = 0;
16149         }
16150       else if (unformat (input, "%_%v%_", &locator_set_name))
16151         {
16152           locator_set_name_set = 1;
16153         }
16154       else
16155         {
16156           clib_warning ("parse error '%U'", format_unformat_error, input);
16157           return -99;
16158         }
16159     }
16160
16161   if (is_add && !locator_set_name_set)
16162     {
16163       errmsg ("itr-rloc is not set!");
16164       return -99;
16165     }
16166
16167   if (is_add && vec_len (locator_set_name) > 64)
16168     {
16169       errmsg ("itr-rloc locator-set name too long");
16170       vec_free (locator_set_name);
16171       return -99;
16172     }
16173
16174   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
16175   mp->is_add = is_add;
16176   if (is_add)
16177     {
16178       clib_memcpy (mp->locator_set_name, locator_set_name,
16179                    vec_len (locator_set_name));
16180     }
16181   else
16182     {
16183       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
16184     }
16185   vec_free (locator_set_name);
16186
16187   /* send it... */
16188   S (mp);
16189
16190   /* Wait for a reply... */
16191   W (ret);
16192   return ret;
16193 }
16194
16195 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
16196
16197 static int
16198 api_one_locator_dump (vat_main_t * vam)
16199 {
16200   unformat_input_t *input = vam->input;
16201   vl_api_one_locator_dump_t *mp;
16202   vl_api_control_ping_t *mp_ping;
16203   u8 is_index_set = 0, is_name_set = 0;
16204   u8 *ls_name = 0;
16205   u32 ls_index = ~0;
16206   int ret;
16207
16208   /* Parse args required to build the message */
16209   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16210     {
16211       if (unformat (input, "ls_name %_%v%_", &ls_name))
16212         {
16213           is_name_set = 1;
16214         }
16215       else if (unformat (input, "ls_index %d", &ls_index))
16216         {
16217           is_index_set = 1;
16218         }
16219       else
16220         {
16221           errmsg ("parse error '%U'", format_unformat_error, input);
16222           return -99;
16223         }
16224     }
16225
16226   if (!is_index_set && !is_name_set)
16227     {
16228       errmsg ("error: expected one of index or name!");
16229       return -99;
16230     }
16231
16232   if (is_index_set && is_name_set)
16233     {
16234       errmsg ("error: only one param expected!");
16235       return -99;
16236     }
16237
16238   if (vec_len (ls_name) > 62)
16239     {
16240       errmsg ("error: locator set name too long!");
16241       return -99;
16242     }
16243
16244   if (!vam->json_output)
16245     {
16246       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
16247     }
16248
16249   M (ONE_LOCATOR_DUMP, mp);
16250   mp->is_index_set = is_index_set;
16251
16252   if (is_index_set)
16253     mp->ls_index = clib_host_to_net_u32 (ls_index);
16254   else
16255     {
16256       vec_add1 (ls_name, 0);
16257       strncpy ((char *) mp->ls_name, (char *) ls_name,
16258                sizeof (mp->ls_name) - 1);
16259     }
16260
16261   /* send it... */
16262   S (mp);
16263
16264   /* Use a control ping for synchronization */
16265   MPING (CONTROL_PING, mp_ping);
16266   S (mp_ping);
16267
16268   /* Wait for a reply... */
16269   W (ret);
16270   return ret;
16271 }
16272
16273 #define api_lisp_locator_dump api_one_locator_dump
16274
16275 static int
16276 api_one_locator_set_dump (vat_main_t * vam)
16277 {
16278   vl_api_one_locator_set_dump_t *mp;
16279   vl_api_control_ping_t *mp_ping;
16280   unformat_input_t *input = vam->input;
16281   u8 filter = 0;
16282   int ret;
16283
16284   /* Parse args required to build the message */
16285   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16286     {
16287       if (unformat (input, "local"))
16288         {
16289           filter = 1;
16290         }
16291       else if (unformat (input, "remote"))
16292         {
16293           filter = 2;
16294         }
16295       else
16296         {
16297           errmsg ("parse error '%U'", format_unformat_error, input);
16298           return -99;
16299         }
16300     }
16301
16302   if (!vam->json_output)
16303     {
16304       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
16305     }
16306
16307   M (ONE_LOCATOR_SET_DUMP, mp);
16308
16309   mp->filter = filter;
16310
16311   /* send it... */
16312   S (mp);
16313
16314   /* Use a control ping for synchronization */
16315   MPING (CONTROL_PING, mp_ping);
16316   S (mp_ping);
16317
16318   /* Wait for a reply... */
16319   W (ret);
16320   return ret;
16321 }
16322
16323 #define api_lisp_locator_set_dump api_one_locator_set_dump
16324
16325 static int
16326 api_one_eid_table_map_dump (vat_main_t * vam)
16327 {
16328   u8 is_l2 = 0;
16329   u8 mode_set = 0;
16330   unformat_input_t *input = vam->input;
16331   vl_api_one_eid_table_map_dump_t *mp;
16332   vl_api_control_ping_t *mp_ping;
16333   int ret;
16334
16335   /* Parse args required to build the message */
16336   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16337     {
16338       if (unformat (input, "l2"))
16339         {
16340           is_l2 = 1;
16341           mode_set = 1;
16342         }
16343       else if (unformat (input, "l3"))
16344         {
16345           is_l2 = 0;
16346           mode_set = 1;
16347         }
16348       else
16349         {
16350           errmsg ("parse error '%U'", format_unformat_error, input);
16351           return -99;
16352         }
16353     }
16354
16355   if (!mode_set)
16356     {
16357       errmsg ("expected one of 'l2' or 'l3' parameter!");
16358       return -99;
16359     }
16360
16361   if (!vam->json_output)
16362     {
16363       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
16364     }
16365
16366   M (ONE_EID_TABLE_MAP_DUMP, mp);
16367   mp->is_l2 = is_l2;
16368
16369   /* send it... */
16370   S (mp);
16371
16372   /* Use a control ping for synchronization */
16373   MPING (CONTROL_PING, mp_ping);
16374   S (mp_ping);
16375
16376   /* Wait for a reply... */
16377   W (ret);
16378   return ret;
16379 }
16380
16381 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
16382
16383 static int
16384 api_one_eid_table_vni_dump (vat_main_t * vam)
16385 {
16386   vl_api_one_eid_table_vni_dump_t *mp;
16387   vl_api_control_ping_t *mp_ping;
16388   int ret;
16389
16390   if (!vam->json_output)
16391     {
16392       print (vam->ofp, "VNI");
16393     }
16394
16395   M (ONE_EID_TABLE_VNI_DUMP, mp);
16396
16397   /* send it... */
16398   S (mp);
16399
16400   /* Use a control ping for synchronization */
16401   MPING (CONTROL_PING, mp_ping);
16402   S (mp_ping);
16403
16404   /* Wait for a reply... */
16405   W (ret);
16406   return ret;
16407 }
16408
16409 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
16410
16411 static int
16412 api_one_eid_table_dump (vat_main_t * vam)
16413 {
16414   unformat_input_t *i = vam->input;
16415   vl_api_one_eid_table_dump_t *mp;
16416   vl_api_control_ping_t *mp_ping;
16417   u8 filter = 0;
16418   int ret;
16419   u32 vni, t = 0;
16420   lisp_eid_vat_t eid;
16421   u8 eid_set = 0;
16422
16423   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16424     {
16425       if (unformat
16426           (i, "eid %U/%d", unformat_ip46_address, &eid.addr.ip, &eid.len))
16427         {
16428           eid_set = 1;
16429           eid.type = 0;
16430         }
16431       else
16432         if (unformat (i, "eid %U", unformat_ethernet_address, &eid.addr.mac))
16433         {
16434           eid_set = 1;
16435           eid.type = 1;
16436         }
16437       else if (unformat (i, "eid %U", unformat_nsh_address, &eid.addr.nsh))
16438         {
16439           eid_set = 1;
16440           eid.type = 2;
16441         }
16442       else if (unformat (i, "vni %d", &t))
16443         {
16444           vni = t;
16445         }
16446       else if (unformat (i, "local"))
16447         {
16448           filter = 1;
16449         }
16450       else if (unformat (i, "remote"))
16451         {
16452           filter = 2;
16453         }
16454       else
16455         {
16456           errmsg ("parse error '%U'", format_unformat_error, i);
16457           return -99;
16458         }
16459     }
16460
16461   if (!vam->json_output)
16462     {
16463       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
16464              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
16465     }
16466
16467   M (ONE_EID_TABLE_DUMP, mp);
16468
16469   mp->filter = filter;
16470   if (eid_set)
16471     {
16472       mp->eid_set = 1;
16473       mp->vni = htonl (vni);
16474       lisp_eid_put_vat (&mp->eid, &eid);
16475     }
16476
16477   /* send it... */
16478   S (mp);
16479
16480   /* Use a control ping for synchronization */
16481   MPING (CONTROL_PING, mp_ping);
16482   S (mp_ping);
16483
16484   /* Wait for a reply... */
16485   W (ret);
16486   return ret;
16487 }
16488
16489 #define api_lisp_eid_table_dump api_one_eid_table_dump
16490
16491 static int
16492 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
16493 {
16494   unformat_input_t *i = vam->input;
16495   vl_api_gpe_fwd_entries_get_t *mp;
16496   u8 vni_set = 0;
16497   u32 vni = ~0;
16498   int ret;
16499
16500   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16501     {
16502       if (unformat (i, "vni %d", &vni))
16503         {
16504           vni_set = 1;
16505         }
16506       else
16507         {
16508           errmsg ("parse error '%U'", format_unformat_error, i);
16509           return -99;
16510         }
16511     }
16512
16513   if (!vni_set)
16514     {
16515       errmsg ("vni not set!");
16516       return -99;
16517     }
16518
16519   if (!vam->json_output)
16520     {
16521       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
16522              "leid", "reid");
16523     }
16524
16525   M (GPE_FWD_ENTRIES_GET, mp);
16526   mp->vni = clib_host_to_net_u32 (vni);
16527
16528   /* send it... */
16529   S (mp);
16530
16531   /* Wait for a reply... */
16532   W (ret);
16533   return ret;
16534 }
16535
16536 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
16537 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
16538 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
16539 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
16540 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
16541 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
16542 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
16543 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
16544
16545 static int
16546 api_one_adjacencies_get (vat_main_t * vam)
16547 {
16548   unformat_input_t *i = vam->input;
16549   vl_api_one_adjacencies_get_t *mp;
16550   u8 vni_set = 0;
16551   u32 vni = ~0;
16552   int ret;
16553
16554   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16555     {
16556       if (unformat (i, "vni %d", &vni))
16557         {
16558           vni_set = 1;
16559         }
16560       else
16561         {
16562           errmsg ("parse error '%U'", format_unformat_error, i);
16563           return -99;
16564         }
16565     }
16566
16567   if (!vni_set)
16568     {
16569       errmsg ("vni not set!");
16570       return -99;
16571     }
16572
16573   if (!vam->json_output)
16574     {
16575       print (vam->ofp, "%s %40s", "leid", "reid");
16576     }
16577
16578   M (ONE_ADJACENCIES_GET, mp);
16579   mp->vni = clib_host_to_net_u32 (vni);
16580
16581   /* send it... */
16582   S (mp);
16583
16584   /* Wait for a reply... */
16585   W (ret);
16586   return ret;
16587 }
16588
16589 #define api_lisp_adjacencies_get api_one_adjacencies_get
16590
16591 static int
16592 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
16593 {
16594   unformat_input_t *i = vam->input;
16595   vl_api_gpe_native_fwd_rpaths_get_t *mp;
16596   int ret;
16597   u8 ip_family_set = 0, is_ip4 = 1;
16598
16599   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16600     {
16601       if (unformat (i, "ip4"))
16602         {
16603           ip_family_set = 1;
16604           is_ip4 = 1;
16605         }
16606       else if (unformat (i, "ip6"))
16607         {
16608           ip_family_set = 1;
16609           is_ip4 = 0;
16610         }
16611       else
16612         {
16613           errmsg ("parse error '%U'", format_unformat_error, i);
16614           return -99;
16615         }
16616     }
16617
16618   if (!ip_family_set)
16619     {
16620       errmsg ("ip family not set!");
16621       return -99;
16622     }
16623
16624   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
16625   mp->is_ip4 = is_ip4;
16626
16627   /* send it... */
16628   S (mp);
16629
16630   /* Wait for a reply... */
16631   W (ret);
16632   return ret;
16633 }
16634
16635 static int
16636 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
16637 {
16638   vl_api_gpe_fwd_entry_vnis_get_t *mp;
16639   int ret;
16640
16641   if (!vam->json_output)
16642     {
16643       print (vam->ofp, "VNIs");
16644     }
16645
16646   M (GPE_FWD_ENTRY_VNIS_GET, mp);
16647
16648   /* send it... */
16649   S (mp);
16650
16651   /* Wait for a reply... */
16652   W (ret);
16653   return ret;
16654 }
16655
16656 static int
16657 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
16658 {
16659   unformat_input_t *i = vam->input;
16660   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
16661   int ret = 0;
16662   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
16663   struct in_addr ip4;
16664   struct in6_addr ip6;
16665   u32 table_id = 0, nh_sw_if_index = ~0;
16666
16667   clib_memset (&ip4, 0, sizeof (ip4));
16668   clib_memset (&ip6, 0, sizeof (ip6));
16669
16670   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16671     {
16672       if (unformat (i, "del"))
16673         is_add = 0;
16674       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
16675                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16676         {
16677           ip_set = 1;
16678           is_ip4 = 1;
16679         }
16680       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
16681                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16682         {
16683           ip_set = 1;
16684           is_ip4 = 0;
16685         }
16686       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
16687         {
16688           ip_set = 1;
16689           is_ip4 = 1;
16690           nh_sw_if_index = ~0;
16691         }
16692       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
16693         {
16694           ip_set = 1;
16695           is_ip4 = 0;
16696           nh_sw_if_index = ~0;
16697         }
16698       else if (unformat (i, "table %d", &table_id))
16699         ;
16700       else
16701         {
16702           errmsg ("parse error '%U'", format_unformat_error, i);
16703           return -99;
16704         }
16705     }
16706
16707   if (!ip_set)
16708     {
16709       errmsg ("nh addr not set!");
16710       return -99;
16711     }
16712
16713   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
16714   mp->is_add = is_add;
16715   mp->table_id = clib_host_to_net_u32 (table_id);
16716   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
16717   mp->nh_addr.af = is_ip4 ? 0 : 1;
16718   if (is_ip4)
16719     clib_memcpy (mp->nh_addr.un.ip4, &ip4, sizeof (ip4));
16720   else
16721     clib_memcpy (mp->nh_addr.un.ip6, &ip6, sizeof (ip6));
16722
16723   /* send it... */
16724   S (mp);
16725
16726   /* Wait for a reply... */
16727   W (ret);
16728   return ret;
16729 }
16730
16731 static int
16732 api_one_map_server_dump (vat_main_t * vam)
16733 {
16734   vl_api_one_map_server_dump_t *mp;
16735   vl_api_control_ping_t *mp_ping;
16736   int ret;
16737
16738   if (!vam->json_output)
16739     {
16740       print (vam->ofp, "%=20s", "Map server");
16741     }
16742
16743   M (ONE_MAP_SERVER_DUMP, mp);
16744   /* send it... */
16745   S (mp);
16746
16747   /* Use a control ping for synchronization */
16748   MPING (CONTROL_PING, mp_ping);
16749   S (mp_ping);
16750
16751   /* Wait for a reply... */
16752   W (ret);
16753   return ret;
16754 }
16755
16756 #define api_lisp_map_server_dump api_one_map_server_dump
16757
16758 static int
16759 api_one_map_resolver_dump (vat_main_t * vam)
16760 {
16761   vl_api_one_map_resolver_dump_t *mp;
16762   vl_api_control_ping_t *mp_ping;
16763   int ret;
16764
16765   if (!vam->json_output)
16766     {
16767       print (vam->ofp, "%=20s", "Map resolver");
16768     }
16769
16770   M (ONE_MAP_RESOLVER_DUMP, mp);
16771   /* send it... */
16772   S (mp);
16773
16774   /* Use a control ping for synchronization */
16775   MPING (CONTROL_PING, mp_ping);
16776   S (mp_ping);
16777
16778   /* Wait for a reply... */
16779   W (ret);
16780   return ret;
16781 }
16782
16783 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
16784
16785 static int
16786 api_one_stats_flush (vat_main_t * vam)
16787 {
16788   vl_api_one_stats_flush_t *mp;
16789   int ret = 0;
16790
16791   M (ONE_STATS_FLUSH, mp);
16792   S (mp);
16793   W (ret);
16794   return ret;
16795 }
16796
16797 static int
16798 api_one_stats_dump (vat_main_t * vam)
16799 {
16800   vl_api_one_stats_dump_t *mp;
16801   vl_api_control_ping_t *mp_ping;
16802   int ret;
16803
16804   M (ONE_STATS_DUMP, mp);
16805   /* send it... */
16806   S (mp);
16807
16808   /* Use a control ping for synchronization */
16809   MPING (CONTROL_PING, mp_ping);
16810   S (mp_ping);
16811
16812   /* Wait for a reply... */
16813   W (ret);
16814   return ret;
16815 }
16816
16817 static int
16818 api_show_one_status (vat_main_t * vam)
16819 {
16820   vl_api_show_one_status_t *mp;
16821   int ret;
16822
16823   if (!vam->json_output)
16824     {
16825       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
16826     }
16827
16828   M (SHOW_ONE_STATUS, mp);
16829   /* send it... */
16830   S (mp);
16831   /* Wait for a reply... */
16832   W (ret);
16833   return ret;
16834 }
16835
16836 #define api_show_lisp_status api_show_one_status
16837
16838 static int
16839 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
16840 {
16841   vl_api_gpe_fwd_entry_path_dump_t *mp;
16842   vl_api_control_ping_t *mp_ping;
16843   unformat_input_t *i = vam->input;
16844   u32 fwd_entry_index = ~0;
16845   int ret;
16846
16847   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16848     {
16849       if (unformat (i, "index %d", &fwd_entry_index))
16850         ;
16851       else
16852         break;
16853     }
16854
16855   if (~0 == fwd_entry_index)
16856     {
16857       errmsg ("no index specified!");
16858       return -99;
16859     }
16860
16861   if (!vam->json_output)
16862     {
16863       print (vam->ofp, "first line");
16864     }
16865
16866   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
16867
16868   /* send it... */
16869   S (mp);
16870   /* Use a control ping for synchronization */
16871   MPING (CONTROL_PING, mp_ping);
16872   S (mp_ping);
16873
16874   /* Wait for a reply... */
16875   W (ret);
16876   return ret;
16877 }
16878
16879 static int
16880 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
16881 {
16882   vl_api_one_get_map_request_itr_rlocs_t *mp;
16883   int ret;
16884
16885   if (!vam->json_output)
16886     {
16887       print (vam->ofp, "%=20s", "itr-rlocs:");
16888     }
16889
16890   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
16891   /* send it... */
16892   S (mp);
16893   /* Wait for a reply... */
16894   W (ret);
16895   return ret;
16896 }
16897
16898 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
16899
16900 static int
16901 api_af_packet_create (vat_main_t * vam)
16902 {
16903   unformat_input_t *i = vam->input;
16904   vl_api_af_packet_create_t *mp;
16905   u8 *host_if_name = 0;
16906   u8 hw_addr[6];
16907   u8 random_hw_addr = 1;
16908   int ret;
16909
16910   clib_memset (hw_addr, 0, sizeof (hw_addr));
16911
16912   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16913     {
16914       if (unformat (i, "name %s", &host_if_name))
16915         vec_add1 (host_if_name, 0);
16916       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
16917         random_hw_addr = 0;
16918       else
16919         break;
16920     }
16921
16922   if (!vec_len (host_if_name))
16923     {
16924       errmsg ("host-interface name must be specified");
16925       return -99;
16926     }
16927
16928   if (vec_len (host_if_name) > 64)
16929     {
16930       errmsg ("host-interface name too long");
16931       return -99;
16932     }
16933
16934   M (AF_PACKET_CREATE, mp);
16935
16936   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
16937   clib_memcpy (mp->hw_addr, hw_addr, 6);
16938   mp->use_random_hw_addr = random_hw_addr;
16939   vec_free (host_if_name);
16940
16941   S (mp);
16942
16943   /* *INDENT-OFF* */
16944   W2 (ret,
16945       ({
16946         if (ret == 0)
16947           fprintf (vam->ofp ? vam->ofp : stderr,
16948                    " new sw_if_index = %d\n", vam->sw_if_index);
16949       }));
16950   /* *INDENT-ON* */
16951   return ret;
16952 }
16953
16954 static int
16955 api_af_packet_delete (vat_main_t * vam)
16956 {
16957   unformat_input_t *i = vam->input;
16958   vl_api_af_packet_delete_t *mp;
16959   u8 *host_if_name = 0;
16960   int ret;
16961
16962   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16963     {
16964       if (unformat (i, "name %s", &host_if_name))
16965         vec_add1 (host_if_name, 0);
16966       else
16967         break;
16968     }
16969
16970   if (!vec_len (host_if_name))
16971     {
16972       errmsg ("host-interface name must be specified");
16973       return -99;
16974     }
16975
16976   if (vec_len (host_if_name) > 64)
16977     {
16978       errmsg ("host-interface name too long");
16979       return -99;
16980     }
16981
16982   M (AF_PACKET_DELETE, mp);
16983
16984   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
16985   vec_free (host_if_name);
16986
16987   S (mp);
16988   W (ret);
16989   return ret;
16990 }
16991
16992 static void vl_api_af_packet_details_t_handler
16993   (vl_api_af_packet_details_t * mp)
16994 {
16995   vat_main_t *vam = &vat_main;
16996
16997   print (vam->ofp, "%-16s %d",
16998          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
16999 }
17000
17001 static void vl_api_af_packet_details_t_handler_json
17002   (vl_api_af_packet_details_t * mp)
17003 {
17004   vat_main_t *vam = &vat_main;
17005   vat_json_node_t *node = NULL;
17006
17007   if (VAT_JSON_ARRAY != vam->json_tree.type)
17008     {
17009       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17010       vat_json_init_array (&vam->json_tree);
17011     }
17012   node = vat_json_array_add (&vam->json_tree);
17013
17014   vat_json_init_object (node);
17015   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17016   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
17017 }
17018
17019 static int
17020 api_af_packet_dump (vat_main_t * vam)
17021 {
17022   vl_api_af_packet_dump_t *mp;
17023   vl_api_control_ping_t *mp_ping;
17024   int ret;
17025
17026   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
17027   /* Get list of tap interfaces */
17028   M (AF_PACKET_DUMP, mp);
17029   S (mp);
17030
17031   /* Use a control ping for synchronization */
17032   MPING (CONTROL_PING, mp_ping);
17033   S (mp_ping);
17034
17035   W (ret);
17036   return ret;
17037 }
17038
17039 static int
17040 api_policer_add_del (vat_main_t * vam)
17041 {
17042   unformat_input_t *i = vam->input;
17043   vl_api_policer_add_del_t *mp;
17044   u8 is_add = 1;
17045   u8 *name = 0;
17046   u32 cir = 0;
17047   u32 eir = 0;
17048   u64 cb = 0;
17049   u64 eb = 0;
17050   u8 rate_type = 0;
17051   u8 round_type = 0;
17052   u8 type = 0;
17053   u8 color_aware = 0;
17054   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
17055   int ret;
17056
17057   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
17058   conform_action.dscp = 0;
17059   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
17060   exceed_action.dscp = 0;
17061   violate_action.action_type = SSE2_QOS_ACTION_DROP;
17062   violate_action.dscp = 0;
17063
17064   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17065     {
17066       if (unformat (i, "del"))
17067         is_add = 0;
17068       else if (unformat (i, "name %s", &name))
17069         vec_add1 (name, 0);
17070       else if (unformat (i, "cir %u", &cir))
17071         ;
17072       else if (unformat (i, "eir %u", &eir))
17073         ;
17074       else if (unformat (i, "cb %u", &cb))
17075         ;
17076       else if (unformat (i, "eb %u", &eb))
17077         ;
17078       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
17079                          &rate_type))
17080         ;
17081       else if (unformat (i, "round_type %U", unformat_policer_round_type,
17082                          &round_type))
17083         ;
17084       else if (unformat (i, "type %U", unformat_policer_type, &type))
17085         ;
17086       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
17087                          &conform_action))
17088         ;
17089       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
17090                          &exceed_action))
17091         ;
17092       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
17093                          &violate_action))
17094         ;
17095       else if (unformat (i, "color-aware"))
17096         color_aware = 1;
17097       else
17098         break;
17099     }
17100
17101   if (!vec_len (name))
17102     {
17103       errmsg ("policer name must be specified");
17104       return -99;
17105     }
17106
17107   if (vec_len (name) > 64)
17108     {
17109       errmsg ("policer name too long");
17110       return -99;
17111     }
17112
17113   M (POLICER_ADD_DEL, mp);
17114
17115   clib_memcpy (mp->name, name, vec_len (name));
17116   vec_free (name);
17117   mp->is_add = is_add;
17118   mp->cir = ntohl (cir);
17119   mp->eir = ntohl (eir);
17120   mp->cb = clib_net_to_host_u64 (cb);
17121   mp->eb = clib_net_to_host_u64 (eb);
17122   mp->rate_type = rate_type;
17123   mp->round_type = round_type;
17124   mp->type = type;
17125   mp->conform_action.type = conform_action.action_type;
17126   mp->conform_action.dscp = conform_action.dscp;
17127   mp->exceed_action.type = exceed_action.action_type;
17128   mp->exceed_action.dscp = exceed_action.dscp;
17129   mp->violate_action.type = violate_action.action_type;
17130   mp->violate_action.dscp = violate_action.dscp;
17131   mp->color_aware = color_aware;
17132
17133   S (mp);
17134   W (ret);
17135   return ret;
17136 }
17137
17138 static int
17139 api_policer_dump (vat_main_t * vam)
17140 {
17141   unformat_input_t *i = vam->input;
17142   vl_api_policer_dump_t *mp;
17143   vl_api_control_ping_t *mp_ping;
17144   u8 *match_name = 0;
17145   u8 match_name_valid = 0;
17146   int ret;
17147
17148   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17149     {
17150       if (unformat (i, "name %s", &match_name))
17151         {
17152           vec_add1 (match_name, 0);
17153           match_name_valid = 1;
17154         }
17155       else
17156         break;
17157     }
17158
17159   M (POLICER_DUMP, mp);
17160   mp->match_name_valid = match_name_valid;
17161   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
17162   vec_free (match_name);
17163   /* send it... */
17164   S (mp);
17165
17166   /* Use a control ping for synchronization */
17167   MPING (CONTROL_PING, mp_ping);
17168   S (mp_ping);
17169
17170   /* Wait for a reply... */
17171   W (ret);
17172   return ret;
17173 }
17174
17175 static int
17176 api_policer_classify_set_interface (vat_main_t * vam)
17177 {
17178   unformat_input_t *i = vam->input;
17179   vl_api_policer_classify_set_interface_t *mp;
17180   u32 sw_if_index;
17181   int sw_if_index_set;
17182   u32 ip4_table_index = ~0;
17183   u32 ip6_table_index = ~0;
17184   u32 l2_table_index = ~0;
17185   u8 is_add = 1;
17186   int ret;
17187
17188   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17189     {
17190       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17191         sw_if_index_set = 1;
17192       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17193         sw_if_index_set = 1;
17194       else if (unformat (i, "del"))
17195         is_add = 0;
17196       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17197         ;
17198       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17199         ;
17200       else if (unformat (i, "l2-table %d", &l2_table_index))
17201         ;
17202       else
17203         {
17204           clib_warning ("parse error '%U'", format_unformat_error, i);
17205           return -99;
17206         }
17207     }
17208
17209   if (sw_if_index_set == 0)
17210     {
17211       errmsg ("missing interface name or sw_if_index");
17212       return -99;
17213     }
17214
17215   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
17216
17217   mp->sw_if_index = ntohl (sw_if_index);
17218   mp->ip4_table_index = ntohl (ip4_table_index);
17219   mp->ip6_table_index = ntohl (ip6_table_index);
17220   mp->l2_table_index = ntohl (l2_table_index);
17221   mp->is_add = is_add;
17222
17223   S (mp);
17224   W (ret);
17225   return ret;
17226 }
17227
17228 static int
17229 api_policer_classify_dump (vat_main_t * vam)
17230 {
17231   unformat_input_t *i = vam->input;
17232   vl_api_policer_classify_dump_t *mp;
17233   vl_api_control_ping_t *mp_ping;
17234   u8 type = POLICER_CLASSIFY_N_TABLES;
17235   int ret;
17236
17237   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
17238     ;
17239   else
17240     {
17241       errmsg ("classify table type must be specified");
17242       return -99;
17243     }
17244
17245   if (!vam->json_output)
17246     {
17247       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17248     }
17249
17250   M (POLICER_CLASSIFY_DUMP, mp);
17251   mp->type = type;
17252   /* send it... */
17253   S (mp);
17254
17255   /* Use a control ping for synchronization */
17256   MPING (CONTROL_PING, mp_ping);
17257   S (mp_ping);
17258
17259   /* Wait for a reply... */
17260   W (ret);
17261   return ret;
17262 }
17263
17264 static u8 *
17265 format_fib_api_path_nh_proto (u8 * s, va_list * args)
17266 {
17267   vl_api_fib_path_nh_proto_t proto =
17268     va_arg (*args, vl_api_fib_path_nh_proto_t);
17269
17270   switch (proto)
17271     {
17272     case FIB_API_PATH_NH_PROTO_IP4:
17273       s = format (s, "ip4");
17274       break;
17275     case FIB_API_PATH_NH_PROTO_IP6:
17276       s = format (s, "ip6");
17277       break;
17278     case FIB_API_PATH_NH_PROTO_MPLS:
17279       s = format (s, "mpls");
17280       break;
17281     case FIB_API_PATH_NH_PROTO_BIER:
17282       s = format (s, "bier");
17283       break;
17284     case FIB_API_PATH_NH_PROTO_ETHERNET:
17285       s = format (s, "ethernet");
17286       break;
17287     }
17288
17289   return (s);
17290 }
17291
17292 static u8 *
17293 format_vl_api_ip_address_union (u8 * s, va_list * args)
17294 {
17295   vl_api_address_family_t af = va_arg (*args, int);
17296   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
17297
17298   switch (af)
17299     {
17300     case ADDRESS_IP4:
17301       s = format (s, "%U", format_ip4_address, u->ip4);
17302       break;
17303     case ADDRESS_IP6:
17304       s = format (s, "%U", format_ip6_address, u->ip6);
17305       break;
17306     }
17307   return (s);
17308 }
17309
17310 static u8 *
17311 format_vl_api_fib_path_type (u8 * s, va_list * args)
17312 {
17313   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
17314
17315   switch (t)
17316     {
17317     case FIB_API_PATH_TYPE_NORMAL:
17318       s = format (s, "normal");
17319       break;
17320     case FIB_API_PATH_TYPE_LOCAL:
17321       s = format (s, "local");
17322       break;
17323     case FIB_API_PATH_TYPE_DROP:
17324       s = format (s, "drop");
17325       break;
17326     case FIB_API_PATH_TYPE_UDP_ENCAP:
17327       s = format (s, "udp-encap");
17328       break;
17329     case FIB_API_PATH_TYPE_BIER_IMP:
17330       s = format (s, "bier-imp");
17331       break;
17332     case FIB_API_PATH_TYPE_ICMP_UNREACH:
17333       s = format (s, "unreach");
17334       break;
17335     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
17336       s = format (s, "prohibit");
17337       break;
17338     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
17339       s = format (s, "src-lookup");
17340       break;
17341     case FIB_API_PATH_TYPE_DVR:
17342       s = format (s, "dvr");
17343       break;
17344     case FIB_API_PATH_TYPE_INTERFACE_RX:
17345       s = format (s, "interface-rx");
17346       break;
17347     case FIB_API_PATH_TYPE_CLASSIFY:
17348       s = format (s, "classify");
17349       break;
17350     }
17351
17352   return (s);
17353 }
17354
17355 static void
17356 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
17357 {
17358   print (vam->ofp,
17359          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
17360          ntohl (fp->weight), ntohl (fp->sw_if_index),
17361          format_vl_api_fib_path_type, fp->type,
17362          format_fib_api_path_nh_proto, fp->proto,
17363          format_vl_api_ip_address_union, &fp->nh.address);
17364 }
17365
17366 static void
17367 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
17368                                  vl_api_fib_path_t * fp)
17369 {
17370   struct in_addr ip4;
17371   struct in6_addr ip6;
17372
17373   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17374   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17375   vat_json_object_add_uint (node, "type", fp->type);
17376   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
17377   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
17378     {
17379       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
17380       vat_json_object_add_ip4 (node, "next_hop", ip4);
17381     }
17382   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP6)
17383     {
17384       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
17385       vat_json_object_add_ip6 (node, "next_hop", ip6);
17386     }
17387 }
17388
17389 static void
17390 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
17391 {
17392   vat_main_t *vam = &vat_main;
17393   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17394   vl_api_fib_path_t *fp;
17395   i32 i;
17396
17397   print (vam->ofp, "sw_if_index %d via:",
17398          ntohl (mp->mt_tunnel.mt_sw_if_index));
17399   fp = mp->mt_tunnel.mt_paths;
17400   for (i = 0; i < count; i++)
17401     {
17402       vl_api_fib_path_print (vam, fp);
17403       fp++;
17404     }
17405
17406   print (vam->ofp, "");
17407 }
17408
17409 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
17410 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
17411
17412 static void
17413 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
17414 {
17415   vat_main_t *vam = &vat_main;
17416   vat_json_node_t *node = NULL;
17417   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17418   vl_api_fib_path_t *fp;
17419   i32 i;
17420
17421   if (VAT_JSON_ARRAY != vam->json_tree.type)
17422     {
17423       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17424       vat_json_init_array (&vam->json_tree);
17425     }
17426   node = vat_json_array_add (&vam->json_tree);
17427
17428   vat_json_init_object (node);
17429   vat_json_object_add_uint (node, "sw_if_index",
17430                             ntohl (mp->mt_tunnel.mt_sw_if_index));
17431
17432   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
17433
17434   fp = mp->mt_tunnel.mt_paths;
17435   for (i = 0; i < count; i++)
17436     {
17437       vl_api_mpls_fib_path_json_print (node, fp);
17438       fp++;
17439     }
17440 }
17441
17442 static int
17443 api_mpls_tunnel_dump (vat_main_t * vam)
17444 {
17445   vl_api_mpls_tunnel_dump_t *mp;
17446   vl_api_control_ping_t *mp_ping;
17447   int ret;
17448
17449   M (MPLS_TUNNEL_DUMP, mp);
17450
17451   S (mp);
17452
17453   /* Use a control ping for synchronization */
17454   MPING (CONTROL_PING, mp_ping);
17455   S (mp_ping);
17456
17457   W (ret);
17458   return ret;
17459 }
17460
17461 #define vl_api_mpls_table_details_t_endian vl_noop_handler
17462 #define vl_api_mpls_table_details_t_print vl_noop_handler
17463
17464
17465 static void
17466 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
17467 {
17468   vat_main_t *vam = &vat_main;
17469
17470   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
17471 }
17472
17473 static void vl_api_mpls_table_details_t_handler_json
17474   (vl_api_mpls_table_details_t * mp)
17475 {
17476   vat_main_t *vam = &vat_main;
17477   vat_json_node_t *node = NULL;
17478
17479   if (VAT_JSON_ARRAY != vam->json_tree.type)
17480     {
17481       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17482       vat_json_init_array (&vam->json_tree);
17483     }
17484   node = vat_json_array_add (&vam->json_tree);
17485
17486   vat_json_init_object (node);
17487   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
17488 }
17489
17490 static int
17491 api_mpls_table_dump (vat_main_t * vam)
17492 {
17493   vl_api_mpls_table_dump_t *mp;
17494   vl_api_control_ping_t *mp_ping;
17495   int ret;
17496
17497   M (MPLS_TABLE_DUMP, mp);
17498   S (mp);
17499
17500   /* Use a control ping for synchronization */
17501   MPING (CONTROL_PING, mp_ping);
17502   S (mp_ping);
17503
17504   W (ret);
17505   return ret;
17506 }
17507
17508 #define vl_api_mpls_route_details_t_endian vl_noop_handler
17509 #define vl_api_mpls_route_details_t_print vl_noop_handler
17510
17511 static void
17512 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
17513 {
17514   vat_main_t *vam = &vat_main;
17515   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
17516   vl_api_fib_path_t *fp;
17517   int i;
17518
17519   print (vam->ofp,
17520          "table-id %d, label %u, ess_bit %u",
17521          ntohl (mp->mr_route.mr_table_id),
17522          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
17523   fp = mp->mr_route.mr_paths;
17524   for (i = 0; i < count; i++)
17525     {
17526       vl_api_fib_path_print (vam, fp);
17527       fp++;
17528     }
17529 }
17530
17531 static void vl_api_mpls_route_details_t_handler_json
17532   (vl_api_mpls_route_details_t * mp)
17533 {
17534   vat_main_t *vam = &vat_main;
17535   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
17536   vat_json_node_t *node = NULL;
17537   vl_api_fib_path_t *fp;
17538   int i;
17539
17540   if (VAT_JSON_ARRAY != vam->json_tree.type)
17541     {
17542       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17543       vat_json_init_array (&vam->json_tree);
17544     }
17545   node = vat_json_array_add (&vam->json_tree);
17546
17547   vat_json_init_object (node);
17548   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
17549   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
17550   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
17551   vat_json_object_add_uint (node, "path_count", count);
17552   fp = mp->mr_route.mr_paths;
17553   for (i = 0; i < count; i++)
17554     {
17555       vl_api_mpls_fib_path_json_print (node, fp);
17556       fp++;
17557     }
17558 }
17559
17560 static int
17561 api_mpls_route_dump (vat_main_t * vam)
17562 {
17563   unformat_input_t *input = vam->input;
17564   vl_api_mpls_route_dump_t *mp;
17565   vl_api_control_ping_t *mp_ping;
17566   u32 table_id;
17567   int ret;
17568
17569   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17570     {
17571       if (unformat (input, "table_id %d", &table_id))
17572         ;
17573       else
17574         break;
17575     }
17576   if (table_id == ~0)
17577     {
17578       errmsg ("missing table id");
17579       return -99;
17580     }
17581
17582   M (MPLS_ROUTE_DUMP, mp);
17583
17584   mp->table.mt_table_id = ntohl (table_id);
17585   S (mp);
17586
17587   /* Use a control ping for synchronization */
17588   MPING (CONTROL_PING, mp_ping);
17589   S (mp_ping);
17590
17591   W (ret);
17592   return ret;
17593 }
17594
17595 #define vl_api_ip_table_details_t_endian vl_noop_handler
17596 #define vl_api_ip_table_details_t_print vl_noop_handler
17597
17598 static void
17599 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
17600 {
17601   vat_main_t *vam = &vat_main;
17602
17603   print (vam->ofp,
17604          "%s; table-id %d, prefix %U/%d",
17605          mp->table.name, ntohl (mp->table.table_id));
17606 }
17607
17608
17609 static void vl_api_ip_table_details_t_handler_json
17610   (vl_api_ip_table_details_t * mp)
17611 {
17612   vat_main_t *vam = &vat_main;
17613   vat_json_node_t *node = NULL;
17614
17615   if (VAT_JSON_ARRAY != vam->json_tree.type)
17616     {
17617       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17618       vat_json_init_array (&vam->json_tree);
17619     }
17620   node = vat_json_array_add (&vam->json_tree);
17621
17622   vat_json_init_object (node);
17623   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
17624 }
17625
17626 static int
17627 api_ip_table_dump (vat_main_t * vam)
17628 {
17629   vl_api_ip_table_dump_t *mp;
17630   vl_api_control_ping_t *mp_ping;
17631   int ret;
17632
17633   M (IP_TABLE_DUMP, mp);
17634   S (mp);
17635
17636   /* Use a control ping for synchronization */
17637   MPING (CONTROL_PING, mp_ping);
17638   S (mp_ping);
17639
17640   W (ret);
17641   return ret;
17642 }
17643
17644 static int
17645 api_ip_mtable_dump (vat_main_t * vam)
17646 {
17647   vl_api_ip_mtable_dump_t *mp;
17648   vl_api_control_ping_t *mp_ping;
17649   int ret;
17650
17651   M (IP_MTABLE_DUMP, mp);
17652   S (mp);
17653
17654   /* Use a control ping for synchronization */
17655   MPING (CONTROL_PING, mp_ping);
17656   S (mp_ping);
17657
17658   W (ret);
17659   return ret;
17660 }
17661
17662 static int
17663 api_ip_mroute_dump (vat_main_t * vam)
17664 {
17665   unformat_input_t *input = vam->input;
17666   vl_api_control_ping_t *mp_ping;
17667   vl_api_ip_mroute_dump_t *mp;
17668   int ret, is_ip6;
17669   u32 table_id;
17670
17671   is_ip6 = 0;
17672   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17673     {
17674       if (unformat (input, "table_id %d", &table_id))
17675         ;
17676       else if (unformat (input, "ip6"))
17677         is_ip6 = 1;
17678       else if (unformat (input, "ip4"))
17679         is_ip6 = 0;
17680       else
17681         break;
17682     }
17683   if (table_id == ~0)
17684     {
17685       errmsg ("missing table id");
17686       return -99;
17687     }
17688
17689   M (IP_MROUTE_DUMP, mp);
17690   mp->table.table_id = table_id;
17691   mp->table.is_ip6 = is_ip6;
17692   S (mp);
17693
17694   /* Use a control ping for synchronization */
17695   MPING (CONTROL_PING, mp_ping);
17696   S (mp_ping);
17697
17698   W (ret);
17699   return ret;
17700 }
17701
17702 #define vl_api_ip_route_details_t_endian vl_noop_handler
17703 #define vl_api_ip_route_details_t_print vl_noop_handler
17704
17705 static void
17706 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
17707 {
17708   vat_main_t *vam = &vat_main;
17709   u8 count = mp->route.n_paths;
17710   vl_api_fib_path_t *fp;
17711   int i;
17712
17713   print (vam->ofp,
17714          "table-id %d, prefix %U/%d",
17715          ntohl (mp->route.table_id),
17716          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
17717   for (i = 0; i < count; i++)
17718     {
17719       fp = &mp->route.paths[i];
17720
17721       vl_api_fib_path_print (vam, fp);
17722       fp++;
17723     }
17724 }
17725
17726 static void vl_api_ip_route_details_t_handler_json
17727   (vl_api_ip_route_details_t * mp)
17728 {
17729   vat_main_t *vam = &vat_main;
17730   u8 count = mp->route.n_paths;
17731   vat_json_node_t *node = NULL;
17732   struct in_addr ip4;
17733   struct in6_addr ip6;
17734   vl_api_fib_path_t *fp;
17735   int i;
17736
17737   if (VAT_JSON_ARRAY != vam->json_tree.type)
17738     {
17739       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17740       vat_json_init_array (&vam->json_tree);
17741     }
17742   node = vat_json_array_add (&vam->json_tree);
17743
17744   vat_json_init_object (node);
17745   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
17746   if (ADDRESS_IP6 == mp->route.prefix.address.af)
17747     {
17748       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
17749       vat_json_object_add_ip6 (node, "prefix", ip6);
17750     }
17751   else
17752     {
17753       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
17754       vat_json_object_add_ip4 (node, "prefix", ip4);
17755     }
17756   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
17757   vat_json_object_add_uint (node, "path_count", count);
17758   for (i = 0; i < count; i++)
17759     {
17760       fp = &mp->route.paths[i];
17761       vl_api_mpls_fib_path_json_print (node, fp);
17762     }
17763 }
17764
17765 static int
17766 api_ip_route_dump (vat_main_t * vam)
17767 {
17768   unformat_input_t *input = vam->input;
17769   vl_api_ip_route_dump_t *mp;
17770   vl_api_control_ping_t *mp_ping;
17771   u32 table_id;
17772   u8 is_ip6;
17773   int ret;
17774
17775   is_ip6 = 0;
17776   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17777     {
17778       if (unformat (input, "table_id %d", &table_id))
17779         ;
17780       else if (unformat (input, "ip6"))
17781         is_ip6 = 1;
17782       else if (unformat (input, "ip4"))
17783         is_ip6 = 0;
17784       else
17785         break;
17786     }
17787   if (table_id == ~0)
17788     {
17789       errmsg ("missing table id");
17790       return -99;
17791     }
17792
17793   M (IP_ROUTE_DUMP, mp);
17794
17795   mp->table.table_id = table_id;
17796   mp->table.is_ip6 = is_ip6;
17797
17798   S (mp);
17799
17800   /* Use a control ping for synchronization */
17801   MPING (CONTROL_PING, mp_ping);
17802   S (mp_ping);
17803
17804   W (ret);
17805   return ret;
17806 }
17807
17808 int
17809 api_classify_table_ids (vat_main_t * vam)
17810 {
17811   vl_api_classify_table_ids_t *mp;
17812   int ret;
17813
17814   /* Construct the API message */
17815   M (CLASSIFY_TABLE_IDS, mp);
17816   mp->context = 0;
17817
17818   S (mp);
17819   W (ret);
17820   return ret;
17821 }
17822
17823 int
17824 api_classify_table_by_interface (vat_main_t * vam)
17825 {
17826   unformat_input_t *input = vam->input;
17827   vl_api_classify_table_by_interface_t *mp;
17828
17829   u32 sw_if_index = ~0;
17830   int ret;
17831   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17832     {
17833       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17834         ;
17835       else if (unformat (input, "sw_if_index %d", &sw_if_index))
17836         ;
17837       else
17838         break;
17839     }
17840   if (sw_if_index == ~0)
17841     {
17842       errmsg ("missing interface name or sw_if_index");
17843       return -99;
17844     }
17845
17846   /* Construct the API message */
17847   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
17848   mp->context = 0;
17849   mp->sw_if_index = ntohl (sw_if_index);
17850
17851   S (mp);
17852   W (ret);
17853   return ret;
17854 }
17855
17856 int
17857 api_classify_table_info (vat_main_t * vam)
17858 {
17859   unformat_input_t *input = vam->input;
17860   vl_api_classify_table_info_t *mp;
17861
17862   u32 table_id = ~0;
17863   int ret;
17864   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17865     {
17866       if (unformat (input, "table_id %d", &table_id))
17867         ;
17868       else
17869         break;
17870     }
17871   if (table_id == ~0)
17872     {
17873       errmsg ("missing table id");
17874       return -99;
17875     }
17876
17877   /* Construct the API message */
17878   M (CLASSIFY_TABLE_INFO, mp);
17879   mp->context = 0;
17880   mp->table_id = ntohl (table_id);
17881
17882   S (mp);
17883   W (ret);
17884   return ret;
17885 }
17886
17887 int
17888 api_classify_session_dump (vat_main_t * vam)
17889 {
17890   unformat_input_t *input = vam->input;
17891   vl_api_classify_session_dump_t *mp;
17892   vl_api_control_ping_t *mp_ping;
17893
17894   u32 table_id = ~0;
17895   int ret;
17896   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17897     {
17898       if (unformat (input, "table_id %d", &table_id))
17899         ;
17900       else
17901         break;
17902     }
17903   if (table_id == ~0)
17904     {
17905       errmsg ("missing table id");
17906       return -99;
17907     }
17908
17909   /* Construct the API message */
17910   M (CLASSIFY_SESSION_DUMP, mp);
17911   mp->context = 0;
17912   mp->table_id = ntohl (table_id);
17913   S (mp);
17914
17915   /* Use a control ping for synchronization */
17916   MPING (CONTROL_PING, mp_ping);
17917   S (mp_ping);
17918
17919   W (ret);
17920   return ret;
17921 }
17922
17923 static void
17924 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
17925 {
17926   vat_main_t *vam = &vat_main;
17927
17928   print (vam->ofp, "collector_address %U, collector_port %d, "
17929          "src_address %U, vrf_id %d, path_mtu %u, "
17930          "template_interval %u, udp_checksum %d",
17931          format_ip4_address, mp->collector_address,
17932          ntohs (mp->collector_port),
17933          format_ip4_address, mp->src_address,
17934          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
17935          ntohl (mp->template_interval), mp->udp_checksum);
17936
17937   vam->retval = 0;
17938   vam->result_ready = 1;
17939 }
17940
17941 static void
17942   vl_api_ipfix_exporter_details_t_handler_json
17943   (vl_api_ipfix_exporter_details_t * mp)
17944 {
17945   vat_main_t *vam = &vat_main;
17946   vat_json_node_t node;
17947   struct in_addr collector_address;
17948   struct in_addr src_address;
17949
17950   vat_json_init_object (&node);
17951   clib_memcpy (&collector_address, &mp->collector_address,
17952                sizeof (collector_address));
17953   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
17954   vat_json_object_add_uint (&node, "collector_port",
17955                             ntohs (mp->collector_port));
17956   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
17957   vat_json_object_add_ip4 (&node, "src_address", src_address);
17958   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
17959   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
17960   vat_json_object_add_uint (&node, "template_interval",
17961                             ntohl (mp->template_interval));
17962   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
17963
17964   vat_json_print (vam->ofp, &node);
17965   vat_json_free (&node);
17966   vam->retval = 0;
17967   vam->result_ready = 1;
17968 }
17969
17970 int
17971 api_ipfix_exporter_dump (vat_main_t * vam)
17972 {
17973   vl_api_ipfix_exporter_dump_t *mp;
17974   int ret;
17975
17976   /* Construct the API message */
17977   M (IPFIX_EXPORTER_DUMP, mp);
17978   mp->context = 0;
17979
17980   S (mp);
17981   W (ret);
17982   return ret;
17983 }
17984
17985 static int
17986 api_ipfix_classify_stream_dump (vat_main_t * vam)
17987 {
17988   vl_api_ipfix_classify_stream_dump_t *mp;
17989   int ret;
17990
17991   /* Construct the API message */
17992   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
17993   mp->context = 0;
17994
17995   S (mp);
17996   W (ret);
17997   return ret;
17998   /* NOTREACHED */
17999   return 0;
18000 }
18001
18002 static void
18003   vl_api_ipfix_classify_stream_details_t_handler
18004   (vl_api_ipfix_classify_stream_details_t * mp)
18005 {
18006   vat_main_t *vam = &vat_main;
18007   print (vam->ofp, "domain_id %d, src_port %d",
18008          ntohl (mp->domain_id), ntohs (mp->src_port));
18009   vam->retval = 0;
18010   vam->result_ready = 1;
18011 }
18012
18013 static void
18014   vl_api_ipfix_classify_stream_details_t_handler_json
18015   (vl_api_ipfix_classify_stream_details_t * mp)
18016 {
18017   vat_main_t *vam = &vat_main;
18018   vat_json_node_t node;
18019
18020   vat_json_init_object (&node);
18021   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
18022   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
18023
18024   vat_json_print (vam->ofp, &node);
18025   vat_json_free (&node);
18026   vam->retval = 0;
18027   vam->result_ready = 1;
18028 }
18029
18030 static int
18031 api_ipfix_classify_table_dump (vat_main_t * vam)
18032 {
18033   vl_api_ipfix_classify_table_dump_t *mp;
18034   vl_api_control_ping_t *mp_ping;
18035   int ret;
18036
18037   if (!vam->json_output)
18038     {
18039       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
18040              "transport_protocol");
18041     }
18042
18043   /* Construct the API message */
18044   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
18045
18046   /* send it... */
18047   S (mp);
18048
18049   /* Use a control ping for synchronization */
18050   MPING (CONTROL_PING, mp_ping);
18051   S (mp_ping);
18052
18053   W (ret);
18054   return ret;
18055 }
18056
18057 static void
18058   vl_api_ipfix_classify_table_details_t_handler
18059   (vl_api_ipfix_classify_table_details_t * mp)
18060 {
18061   vat_main_t *vam = &vat_main;
18062   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
18063          mp->transport_protocol);
18064 }
18065
18066 static void
18067   vl_api_ipfix_classify_table_details_t_handler_json
18068   (vl_api_ipfix_classify_table_details_t * mp)
18069 {
18070   vat_json_node_t *node = NULL;
18071   vat_main_t *vam = &vat_main;
18072
18073   if (VAT_JSON_ARRAY != vam->json_tree.type)
18074     {
18075       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18076       vat_json_init_array (&vam->json_tree);
18077     }
18078
18079   node = vat_json_array_add (&vam->json_tree);
18080   vat_json_init_object (node);
18081
18082   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
18083   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
18084   vat_json_object_add_uint (node, "transport_protocol",
18085                             mp->transport_protocol);
18086 }
18087
18088 static int
18089 api_sw_interface_span_enable_disable (vat_main_t * vam)
18090 {
18091   unformat_input_t *i = vam->input;
18092   vl_api_sw_interface_span_enable_disable_t *mp;
18093   u32 src_sw_if_index = ~0;
18094   u32 dst_sw_if_index = ~0;
18095   u8 state = 3;
18096   int ret;
18097   u8 is_l2 = 0;
18098
18099   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18100     {
18101       if (unformat
18102           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
18103         ;
18104       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
18105         ;
18106       else
18107         if (unformat
18108             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
18109         ;
18110       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
18111         ;
18112       else if (unformat (i, "disable"))
18113         state = 0;
18114       else if (unformat (i, "rx"))
18115         state = 1;
18116       else if (unformat (i, "tx"))
18117         state = 2;
18118       else if (unformat (i, "both"))
18119         state = 3;
18120       else if (unformat (i, "l2"))
18121         is_l2 = 1;
18122       else
18123         break;
18124     }
18125
18126   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
18127
18128   mp->sw_if_index_from = htonl (src_sw_if_index);
18129   mp->sw_if_index_to = htonl (dst_sw_if_index);
18130   mp->state = state;
18131   mp->is_l2 = is_l2;
18132
18133   S (mp);
18134   W (ret);
18135   return ret;
18136 }
18137
18138 static void
18139 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
18140                                             * mp)
18141 {
18142   vat_main_t *vam = &vat_main;
18143   u8 *sw_if_from_name = 0;
18144   u8 *sw_if_to_name = 0;
18145   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18146   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18147   char *states[] = { "none", "rx", "tx", "both" };
18148   hash_pair_t *p;
18149
18150   /* *INDENT-OFF* */
18151   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18152   ({
18153     if ((u32) p->value[0] == sw_if_index_from)
18154       {
18155         sw_if_from_name = (u8 *)(p->key);
18156         if (sw_if_to_name)
18157           break;
18158       }
18159     if ((u32) p->value[0] == sw_if_index_to)
18160       {
18161         sw_if_to_name = (u8 *)(p->key);
18162         if (sw_if_from_name)
18163           break;
18164       }
18165   }));
18166   /* *INDENT-ON* */
18167   print (vam->ofp, "%20s => %20s (%s) %s",
18168          sw_if_from_name, sw_if_to_name, states[mp->state],
18169          mp->is_l2 ? "l2" : "device");
18170 }
18171
18172 static void
18173   vl_api_sw_interface_span_details_t_handler_json
18174   (vl_api_sw_interface_span_details_t * mp)
18175 {
18176   vat_main_t *vam = &vat_main;
18177   vat_json_node_t *node = NULL;
18178   u8 *sw_if_from_name = 0;
18179   u8 *sw_if_to_name = 0;
18180   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18181   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18182   hash_pair_t *p;
18183
18184   /* *INDENT-OFF* */
18185   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18186   ({
18187     if ((u32) p->value[0] == sw_if_index_from)
18188       {
18189         sw_if_from_name = (u8 *)(p->key);
18190         if (sw_if_to_name)
18191           break;
18192       }
18193     if ((u32) p->value[0] == sw_if_index_to)
18194       {
18195         sw_if_to_name = (u8 *)(p->key);
18196         if (sw_if_from_name)
18197           break;
18198       }
18199   }));
18200   /* *INDENT-ON* */
18201
18202   if (VAT_JSON_ARRAY != vam->json_tree.type)
18203     {
18204       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18205       vat_json_init_array (&vam->json_tree);
18206     }
18207   node = vat_json_array_add (&vam->json_tree);
18208
18209   vat_json_init_object (node);
18210   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
18211   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
18212   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
18213   if (0 != sw_if_to_name)
18214     {
18215       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
18216     }
18217   vat_json_object_add_uint (node, "state", mp->state);
18218   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
18219 }
18220
18221 static int
18222 api_sw_interface_span_dump (vat_main_t * vam)
18223 {
18224   unformat_input_t *input = vam->input;
18225   vl_api_sw_interface_span_dump_t *mp;
18226   vl_api_control_ping_t *mp_ping;
18227   u8 is_l2 = 0;
18228   int ret;
18229
18230   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18231     {
18232       if (unformat (input, "l2"))
18233         is_l2 = 1;
18234       else
18235         break;
18236     }
18237
18238   M (SW_INTERFACE_SPAN_DUMP, mp);
18239   mp->is_l2 = is_l2;
18240   S (mp);
18241
18242   /* Use a control ping for synchronization */
18243   MPING (CONTROL_PING, mp_ping);
18244   S (mp_ping);
18245
18246   W (ret);
18247   return ret;
18248 }
18249
18250 int
18251 api_pg_create_interface (vat_main_t * vam)
18252 {
18253   unformat_input_t *input = vam->input;
18254   vl_api_pg_create_interface_t *mp;
18255
18256   u32 if_id = ~0, gso_size = 0;
18257   u8 gso_enabled = 0;
18258   int ret;
18259   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18260     {
18261       if (unformat (input, "if_id %d", &if_id))
18262         ;
18263       else if (unformat (input, "gso-enabled"))
18264         {
18265           gso_enabled = 1;
18266           if (unformat (input, "gso-size %u", &gso_size))
18267             ;
18268           else
18269             {
18270               errmsg ("missing gso-size");
18271               return -99;
18272             }
18273         }
18274       else
18275         break;
18276     }
18277   if (if_id == ~0)
18278     {
18279       errmsg ("missing pg interface index");
18280       return -99;
18281     }
18282
18283   /* Construct the API message */
18284   M (PG_CREATE_INTERFACE, mp);
18285   mp->context = 0;
18286   mp->interface_id = ntohl (if_id);
18287   mp->gso_enabled = gso_enabled;
18288
18289   S (mp);
18290   W (ret);
18291   return ret;
18292 }
18293
18294 int
18295 api_pg_capture (vat_main_t * vam)
18296 {
18297   unformat_input_t *input = vam->input;
18298   vl_api_pg_capture_t *mp;
18299
18300   u32 if_id = ~0;
18301   u8 enable = 1;
18302   u32 count = 1;
18303   u8 pcap_file_set = 0;
18304   u8 *pcap_file = 0;
18305   int ret;
18306   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18307     {
18308       if (unformat (input, "if_id %d", &if_id))
18309         ;
18310       else if (unformat (input, "pcap %s", &pcap_file))
18311         pcap_file_set = 1;
18312       else if (unformat (input, "count %d", &count))
18313         ;
18314       else if (unformat (input, "disable"))
18315         enable = 0;
18316       else
18317         break;
18318     }
18319   if (if_id == ~0)
18320     {
18321       errmsg ("missing pg interface index");
18322       return -99;
18323     }
18324   if (pcap_file_set > 0)
18325     {
18326       if (vec_len (pcap_file) > 255)
18327         {
18328           errmsg ("pcap file name is too long");
18329           return -99;
18330         }
18331     }
18332
18333   /* Construct the API message */
18334   M (PG_CAPTURE, mp);
18335   mp->context = 0;
18336   mp->interface_id = ntohl (if_id);
18337   mp->is_enabled = enable;
18338   mp->count = ntohl (count);
18339   if (pcap_file_set != 0)
18340     {
18341       vl_api_vec_to_api_string (pcap_file, &mp->pcap_file_name);
18342     }
18343   vec_free (pcap_file);
18344
18345   S (mp);
18346   W (ret);
18347   return ret;
18348 }
18349
18350 int
18351 api_pg_enable_disable (vat_main_t * vam)
18352 {
18353   unformat_input_t *input = vam->input;
18354   vl_api_pg_enable_disable_t *mp;
18355
18356   u8 enable = 1;
18357   u8 stream_name_set = 0;
18358   u8 *stream_name = 0;
18359   int ret;
18360   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18361     {
18362       if (unformat (input, "stream %s", &stream_name))
18363         stream_name_set = 1;
18364       else if (unformat (input, "disable"))
18365         enable = 0;
18366       else
18367         break;
18368     }
18369
18370   if (stream_name_set > 0)
18371     {
18372       if (vec_len (stream_name) > 255)
18373         {
18374           errmsg ("stream name too long");
18375           return -99;
18376         }
18377     }
18378
18379   /* Construct the API message */
18380   M (PG_ENABLE_DISABLE, mp);
18381   mp->context = 0;
18382   mp->is_enabled = enable;
18383   if (stream_name_set != 0)
18384     {
18385       vl_api_vec_to_api_string (stream_name, &mp->stream_name);
18386     }
18387   vec_free (stream_name);
18388
18389   S (mp);
18390   W (ret);
18391   return ret;
18392 }
18393
18394 int
18395 api_pg_interface_enable_disable_coalesce (vat_main_t * vam)
18396 {
18397   unformat_input_t *input = vam->input;
18398   vl_api_pg_interface_enable_disable_coalesce_t *mp;
18399
18400   u32 sw_if_index = ~0;
18401   u8 enable = 1;
18402   int ret;
18403   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18404     {
18405       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18406         ;
18407       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18408         ;
18409       else if (unformat (input, "disable"))
18410         enable = 0;
18411       else
18412         break;
18413     }
18414
18415   if (sw_if_index == ~0)
18416     {
18417       errmsg ("Interface required but not specified");
18418       return -99;
18419     }
18420
18421   /* Construct the API message */
18422   M (PG_INTERFACE_ENABLE_DISABLE_COALESCE, mp);
18423   mp->context = 0;
18424   mp->coalesce_enabled = enable;
18425   mp->sw_if_index = htonl (sw_if_index);
18426
18427   S (mp);
18428   W (ret);
18429   return ret;
18430 }
18431
18432 int
18433 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
18434 {
18435   unformat_input_t *input = vam->input;
18436   vl_api_ip_source_and_port_range_check_add_del_t *mp;
18437
18438   u16 *low_ports = 0;
18439   u16 *high_ports = 0;
18440   u16 this_low;
18441   u16 this_hi;
18442   vl_api_prefix_t prefix;
18443   u32 tmp, tmp2;
18444   u8 prefix_set = 0;
18445   u32 vrf_id = ~0;
18446   u8 is_add = 1;
18447   int ret;
18448
18449   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18450     {
18451       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
18452         prefix_set = 1;
18453       else if (unformat (input, "vrf %d", &vrf_id))
18454         ;
18455       else if (unformat (input, "del"))
18456         is_add = 0;
18457       else if (unformat (input, "port %d", &tmp))
18458         {
18459           if (tmp == 0 || tmp > 65535)
18460             {
18461               errmsg ("port %d out of range", tmp);
18462               return -99;
18463             }
18464           this_low = tmp;
18465           this_hi = this_low + 1;
18466           vec_add1 (low_ports, this_low);
18467           vec_add1 (high_ports, this_hi);
18468         }
18469       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
18470         {
18471           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
18472             {
18473               errmsg ("incorrect range parameters");
18474               return -99;
18475             }
18476           this_low = tmp;
18477           /* Note: in debug CLI +1 is added to high before
18478              passing to real fn that does "the work"
18479              (ip_source_and_port_range_check_add_del).
18480              This fn is a wrapper around the binary API fn a
18481              control plane will call, which expects this increment
18482              to have occurred. Hence letting the binary API control
18483              plane fn do the increment for consistency between VAT
18484              and other control planes.
18485            */
18486           this_hi = tmp2;
18487           vec_add1 (low_ports, this_low);
18488           vec_add1 (high_ports, this_hi);
18489         }
18490       else
18491         break;
18492     }
18493
18494   if (prefix_set == 0)
18495     {
18496       errmsg ("<address>/<mask> not specified");
18497       return -99;
18498     }
18499
18500   if (vrf_id == ~0)
18501     {
18502       errmsg ("VRF ID required, not specified");
18503       return -99;
18504     }
18505
18506   if (vrf_id == 0)
18507     {
18508       errmsg
18509         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18510       return -99;
18511     }
18512
18513   if (vec_len (low_ports) == 0)
18514     {
18515       errmsg ("At least one port or port range required");
18516       return -99;
18517     }
18518
18519   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
18520
18521   mp->is_add = is_add;
18522
18523   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
18524
18525   mp->number_of_ranges = vec_len (low_ports);
18526
18527   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
18528   vec_free (low_ports);
18529
18530   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
18531   vec_free (high_ports);
18532
18533   mp->vrf_id = ntohl (vrf_id);
18534
18535   S (mp);
18536   W (ret);
18537   return ret;
18538 }
18539
18540 int
18541 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
18542 {
18543   unformat_input_t *input = vam->input;
18544   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
18545   u32 sw_if_index = ~0;
18546   int vrf_set = 0;
18547   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
18548   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
18549   u8 is_add = 1;
18550   int ret;
18551
18552   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18553     {
18554       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18555         ;
18556       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18557         ;
18558       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
18559         vrf_set = 1;
18560       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
18561         vrf_set = 1;
18562       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
18563         vrf_set = 1;
18564       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
18565         vrf_set = 1;
18566       else if (unformat (input, "del"))
18567         is_add = 0;
18568       else
18569         break;
18570     }
18571
18572   if (sw_if_index == ~0)
18573     {
18574       errmsg ("Interface required but not specified");
18575       return -99;
18576     }
18577
18578   if (vrf_set == 0)
18579     {
18580       errmsg ("VRF ID required but not specified");
18581       return -99;
18582     }
18583
18584   if (tcp_out_vrf_id == 0
18585       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
18586     {
18587       errmsg
18588         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18589       return -99;
18590     }
18591
18592   /* Construct the API message */
18593   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
18594
18595   mp->sw_if_index = ntohl (sw_if_index);
18596   mp->is_add = is_add;
18597   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
18598   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
18599   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
18600   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
18601
18602   /* send it... */
18603   S (mp);
18604
18605   /* Wait for a reply... */
18606   W (ret);
18607   return ret;
18608 }
18609
18610 static int
18611 api_set_punt (vat_main_t * vam)
18612 {
18613   unformat_input_t *i = vam->input;
18614   vl_api_address_family_t af;
18615   vl_api_set_punt_t *mp;
18616   u32 protocol = ~0;
18617   u32 port = ~0;
18618   int is_add = 1;
18619   int ret;
18620
18621   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18622     {
18623       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
18624         ;
18625       else if (unformat (i, "protocol %d", &protocol))
18626         ;
18627       else if (unformat (i, "port %d", &port))
18628         ;
18629       else if (unformat (i, "del"))
18630         is_add = 0;
18631       else
18632         {
18633           clib_warning ("parse error '%U'", format_unformat_error, i);
18634           return -99;
18635         }
18636     }
18637
18638   M (SET_PUNT, mp);
18639
18640   mp->is_add = (u8) is_add;
18641   mp->punt.type = PUNT_API_TYPE_L4;
18642   mp->punt.punt.l4.af = af;
18643   mp->punt.punt.l4.protocol = (u8) protocol;
18644   mp->punt.punt.l4.port = htons ((u16) port);
18645
18646   S (mp);
18647   W (ret);
18648   return ret;
18649 }
18650
18651 static int
18652 api_delete_subif (vat_main_t * vam)
18653 {
18654   unformat_input_t *i = vam->input;
18655   vl_api_delete_subif_t *mp;
18656   u32 sw_if_index = ~0;
18657   int ret;
18658
18659   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18660     {
18661       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18662         ;
18663       if (unformat (i, "sw_if_index %d", &sw_if_index))
18664         ;
18665       else
18666         break;
18667     }
18668
18669   if (sw_if_index == ~0)
18670     {
18671       errmsg ("missing sw_if_index");
18672       return -99;
18673     }
18674
18675   /* Construct the API message */
18676   M (DELETE_SUBIF, mp);
18677   mp->sw_if_index = ntohl (sw_if_index);
18678
18679   S (mp);
18680   W (ret);
18681   return ret;
18682 }
18683
18684 #define foreach_pbb_vtr_op      \
18685 _("disable",  L2_VTR_DISABLED)  \
18686 _("pop",  L2_VTR_POP_2)         \
18687 _("push",  L2_VTR_PUSH_2)
18688
18689 static int
18690 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
18691 {
18692   unformat_input_t *i = vam->input;
18693   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
18694   u32 sw_if_index = ~0, vtr_op = ~0;
18695   u16 outer_tag = ~0;
18696   u8 dmac[6], smac[6];
18697   u8 dmac_set = 0, smac_set = 0;
18698   u16 vlanid = 0;
18699   u32 sid = ~0;
18700   u32 tmp;
18701   int ret;
18702
18703   /* Shut up coverity */
18704   clib_memset (dmac, 0, sizeof (dmac));
18705   clib_memset (smac, 0, sizeof (smac));
18706
18707   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18708     {
18709       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18710         ;
18711       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18712         ;
18713       else if (unformat (i, "vtr_op %d", &vtr_op))
18714         ;
18715 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
18716       foreach_pbb_vtr_op
18717 #undef _
18718         else if (unformat (i, "translate_pbb_stag"))
18719         {
18720           if (unformat (i, "%d", &tmp))
18721             {
18722               vtr_op = L2_VTR_TRANSLATE_2_1;
18723               outer_tag = tmp;
18724             }
18725           else
18726             {
18727               errmsg
18728                 ("translate_pbb_stag operation requires outer tag definition");
18729               return -99;
18730             }
18731         }
18732       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
18733         dmac_set++;
18734       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
18735         smac_set++;
18736       else if (unformat (i, "sid %d", &sid))
18737         ;
18738       else if (unformat (i, "vlanid %d", &tmp))
18739         vlanid = tmp;
18740       else
18741         {
18742           clib_warning ("parse error '%U'", format_unformat_error, i);
18743           return -99;
18744         }
18745     }
18746
18747   if ((sw_if_index == ~0) || (vtr_op == ~0))
18748     {
18749       errmsg ("missing sw_if_index or vtr operation");
18750       return -99;
18751     }
18752   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
18753       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
18754     {
18755       errmsg
18756         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
18757       return -99;
18758     }
18759
18760   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
18761   mp->sw_if_index = ntohl (sw_if_index);
18762   mp->vtr_op = ntohl (vtr_op);
18763   mp->outer_tag = ntohs (outer_tag);
18764   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
18765   clib_memcpy (mp->b_smac, smac, sizeof (smac));
18766   mp->b_vlanid = ntohs (vlanid);
18767   mp->i_sid = ntohl (sid);
18768
18769   S (mp);
18770   W (ret);
18771   return ret;
18772 }
18773
18774 static int
18775 api_flow_classify_set_interface (vat_main_t * vam)
18776 {
18777   unformat_input_t *i = vam->input;
18778   vl_api_flow_classify_set_interface_t *mp;
18779   u32 sw_if_index;
18780   int sw_if_index_set;
18781   u32 ip4_table_index = ~0;
18782   u32 ip6_table_index = ~0;
18783   u8 is_add = 1;
18784   int ret;
18785
18786   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18787     {
18788       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18789         sw_if_index_set = 1;
18790       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18791         sw_if_index_set = 1;
18792       else if (unformat (i, "del"))
18793         is_add = 0;
18794       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18795         ;
18796       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18797         ;
18798       else
18799         {
18800           clib_warning ("parse error '%U'", format_unformat_error, i);
18801           return -99;
18802         }
18803     }
18804
18805   if (sw_if_index_set == 0)
18806     {
18807       errmsg ("missing interface name or sw_if_index");
18808       return -99;
18809     }
18810
18811   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
18812
18813   mp->sw_if_index = ntohl (sw_if_index);
18814   mp->ip4_table_index = ntohl (ip4_table_index);
18815   mp->ip6_table_index = ntohl (ip6_table_index);
18816   mp->is_add = is_add;
18817
18818   S (mp);
18819   W (ret);
18820   return ret;
18821 }
18822
18823 static int
18824 api_flow_classify_dump (vat_main_t * vam)
18825 {
18826   unformat_input_t *i = vam->input;
18827   vl_api_flow_classify_dump_t *mp;
18828   vl_api_control_ping_t *mp_ping;
18829   u8 type = FLOW_CLASSIFY_N_TABLES;
18830   int ret;
18831
18832   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
18833     ;
18834   else
18835     {
18836       errmsg ("classify table type must be specified");
18837       return -99;
18838     }
18839
18840   if (!vam->json_output)
18841     {
18842       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18843     }
18844
18845   M (FLOW_CLASSIFY_DUMP, mp);
18846   mp->type = type;
18847   /* send it... */
18848   S (mp);
18849
18850   /* Use a control ping for synchronization */
18851   MPING (CONTROL_PING, mp_ping);
18852   S (mp_ping);
18853
18854   /* Wait for a reply... */
18855   W (ret);
18856   return ret;
18857 }
18858
18859 static int
18860 api_feature_enable_disable (vat_main_t * vam)
18861 {
18862   unformat_input_t *i = vam->input;
18863   vl_api_feature_enable_disable_t *mp;
18864   u8 *arc_name = 0;
18865   u8 *feature_name = 0;
18866   u32 sw_if_index = ~0;
18867   u8 enable = 1;
18868   int ret;
18869
18870   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18871     {
18872       if (unformat (i, "arc_name %s", &arc_name))
18873         ;
18874       else if (unformat (i, "feature_name %s", &feature_name))
18875         ;
18876       else
18877         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18878         ;
18879       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18880         ;
18881       else if (unformat (i, "disable"))
18882         enable = 0;
18883       else
18884         break;
18885     }
18886
18887   if (arc_name == 0)
18888     {
18889       errmsg ("missing arc name");
18890       return -99;
18891     }
18892   if (vec_len (arc_name) > 63)
18893     {
18894       errmsg ("arc name too long");
18895     }
18896
18897   if (feature_name == 0)
18898     {
18899       errmsg ("missing feature name");
18900       return -99;
18901     }
18902   if (vec_len (feature_name) > 63)
18903     {
18904       errmsg ("feature name too long");
18905     }
18906
18907   if (sw_if_index == ~0)
18908     {
18909       errmsg ("missing interface name or sw_if_index");
18910       return -99;
18911     }
18912
18913   /* Construct the API message */
18914   M (FEATURE_ENABLE_DISABLE, mp);
18915   mp->sw_if_index = ntohl (sw_if_index);
18916   mp->enable = enable;
18917   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
18918   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
18919   vec_free (arc_name);
18920   vec_free (feature_name);
18921
18922   S (mp);
18923   W (ret);
18924   return ret;
18925 }
18926
18927 static int
18928 api_feature_gso_enable_disable (vat_main_t * vam)
18929 {
18930   unformat_input_t *i = vam->input;
18931   vl_api_feature_gso_enable_disable_t *mp;
18932   u32 sw_if_index = ~0;
18933   u8 enable = 1;
18934   int ret;
18935
18936   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18937     {
18938       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18939         ;
18940       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18941         ;
18942       else if (unformat (i, "enable"))
18943         enable = 1;
18944       else if (unformat (i, "disable"))
18945         enable = 0;
18946       else
18947         break;
18948     }
18949
18950   if (sw_if_index == ~0)
18951     {
18952       errmsg ("missing interface name or sw_if_index");
18953       return -99;
18954     }
18955
18956   /* Construct the API message */
18957   M (FEATURE_GSO_ENABLE_DISABLE, mp);
18958   mp->sw_if_index = ntohl (sw_if_index);
18959   mp->enable_disable = enable;
18960
18961   S (mp);
18962   W (ret);
18963   return ret;
18964 }
18965
18966 static int
18967 api_sw_interface_tag_add_del (vat_main_t * vam)
18968 {
18969   unformat_input_t *i = vam->input;
18970   vl_api_sw_interface_tag_add_del_t *mp;
18971   u32 sw_if_index = ~0;
18972   u8 *tag = 0;
18973   u8 enable = 1;
18974   int ret;
18975
18976   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18977     {
18978       if (unformat (i, "tag %s", &tag))
18979         ;
18980       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18981         ;
18982       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18983         ;
18984       else if (unformat (i, "del"))
18985         enable = 0;
18986       else
18987         break;
18988     }
18989
18990   if (sw_if_index == ~0)
18991     {
18992       errmsg ("missing interface name or sw_if_index");
18993       return -99;
18994     }
18995
18996   if (enable && (tag == 0))
18997     {
18998       errmsg ("no tag specified");
18999       return -99;
19000     }
19001
19002   /* Construct the API message */
19003   M (SW_INTERFACE_TAG_ADD_DEL, mp);
19004   mp->sw_if_index = ntohl (sw_if_index);
19005   mp->is_add = enable;
19006   if (enable)
19007     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
19008   vec_free (tag);
19009
19010   S (mp);
19011   W (ret);
19012   return ret;
19013 }
19014
19015 static int
19016 api_sw_interface_add_del_mac_address (vat_main_t * vam)
19017 {
19018   unformat_input_t *i = vam->input;
19019   vl_api_mac_address_t mac = { 0 };
19020   vl_api_sw_interface_add_del_mac_address_t *mp;
19021   u32 sw_if_index = ~0;
19022   u8 is_add = 1;
19023   u8 mac_set = 0;
19024   int ret;
19025
19026   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19027     {
19028       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19029         ;
19030       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19031         ;
19032       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
19033         mac_set++;
19034       else if (unformat (i, "del"))
19035         is_add = 0;
19036       else
19037         break;
19038     }
19039
19040   if (sw_if_index == ~0)
19041     {
19042       errmsg ("missing interface name or sw_if_index");
19043       return -99;
19044     }
19045
19046   if (!mac_set)
19047     {
19048       errmsg ("missing MAC address");
19049       return -99;
19050     }
19051
19052   /* Construct the API message */
19053   M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
19054   mp->sw_if_index = ntohl (sw_if_index);
19055   mp->is_add = is_add;
19056   clib_memcpy (&mp->addr, &mac, sizeof (mac));
19057
19058   S (mp);
19059   W (ret);
19060   return ret;
19061 }
19062
19063 static void vl_api_l2_xconnect_details_t_handler
19064   (vl_api_l2_xconnect_details_t * mp)
19065 {
19066   vat_main_t *vam = &vat_main;
19067
19068   print (vam->ofp, "%15d%15d",
19069          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
19070 }
19071
19072 static void vl_api_l2_xconnect_details_t_handler_json
19073   (vl_api_l2_xconnect_details_t * mp)
19074 {
19075   vat_main_t *vam = &vat_main;
19076   vat_json_node_t *node = NULL;
19077
19078   if (VAT_JSON_ARRAY != vam->json_tree.type)
19079     {
19080       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19081       vat_json_init_array (&vam->json_tree);
19082     }
19083   node = vat_json_array_add (&vam->json_tree);
19084
19085   vat_json_init_object (node);
19086   vat_json_object_add_uint (node, "rx_sw_if_index",
19087                             ntohl (mp->rx_sw_if_index));
19088   vat_json_object_add_uint (node, "tx_sw_if_index",
19089                             ntohl (mp->tx_sw_if_index));
19090 }
19091
19092 static int
19093 api_l2_xconnect_dump (vat_main_t * vam)
19094 {
19095   vl_api_l2_xconnect_dump_t *mp;
19096   vl_api_control_ping_t *mp_ping;
19097   int ret;
19098
19099   if (!vam->json_output)
19100     {
19101       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
19102     }
19103
19104   M (L2_XCONNECT_DUMP, mp);
19105
19106   S (mp);
19107
19108   /* Use a control ping for synchronization */
19109   MPING (CONTROL_PING, mp_ping);
19110   S (mp_ping);
19111
19112   W (ret);
19113   return ret;
19114 }
19115
19116 static int
19117 api_hw_interface_set_mtu (vat_main_t * vam)
19118 {
19119   unformat_input_t *i = vam->input;
19120   vl_api_hw_interface_set_mtu_t *mp;
19121   u32 sw_if_index = ~0;
19122   u32 mtu = 0;
19123   int ret;
19124
19125   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19126     {
19127       if (unformat (i, "mtu %d", &mtu))
19128         ;
19129       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19130         ;
19131       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19132         ;
19133       else
19134         break;
19135     }
19136
19137   if (sw_if_index == ~0)
19138     {
19139       errmsg ("missing interface name or sw_if_index");
19140       return -99;
19141     }
19142
19143   if (mtu == 0)
19144     {
19145       errmsg ("no mtu specified");
19146       return -99;
19147     }
19148
19149   /* Construct the API message */
19150   M (HW_INTERFACE_SET_MTU, mp);
19151   mp->sw_if_index = ntohl (sw_if_index);
19152   mp->mtu = ntohs ((u16) mtu);
19153
19154   S (mp);
19155   W (ret);
19156   return ret;
19157 }
19158
19159 static int
19160 api_p2p_ethernet_add (vat_main_t * vam)
19161 {
19162   unformat_input_t *i = vam->input;
19163   vl_api_p2p_ethernet_add_t *mp;
19164   u32 parent_if_index = ~0;
19165   u32 sub_id = ~0;
19166   u8 remote_mac[6];
19167   u8 mac_set = 0;
19168   int ret;
19169
19170   clib_memset (remote_mac, 0, sizeof (remote_mac));
19171   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19172     {
19173       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19174         ;
19175       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19176         ;
19177       else
19178         if (unformat
19179             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19180         mac_set++;
19181       else if (unformat (i, "sub_id %d", &sub_id))
19182         ;
19183       else
19184         {
19185           clib_warning ("parse error '%U'", format_unformat_error, i);
19186           return -99;
19187         }
19188     }
19189
19190   if (parent_if_index == ~0)
19191     {
19192       errmsg ("missing interface name or sw_if_index");
19193       return -99;
19194     }
19195   if (mac_set == 0)
19196     {
19197       errmsg ("missing remote mac address");
19198       return -99;
19199     }
19200   if (sub_id == ~0)
19201     {
19202       errmsg ("missing sub-interface id");
19203       return -99;
19204     }
19205
19206   M (P2P_ETHERNET_ADD, mp);
19207   mp->parent_if_index = ntohl (parent_if_index);
19208   mp->subif_id = ntohl (sub_id);
19209   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19210
19211   S (mp);
19212   W (ret);
19213   return ret;
19214 }
19215
19216 static int
19217 api_p2p_ethernet_del (vat_main_t * vam)
19218 {
19219   unformat_input_t *i = vam->input;
19220   vl_api_p2p_ethernet_del_t *mp;
19221   u32 parent_if_index = ~0;
19222   u8 remote_mac[6];
19223   u8 mac_set = 0;
19224   int ret;
19225
19226   clib_memset (remote_mac, 0, sizeof (remote_mac));
19227   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19228     {
19229       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19230         ;
19231       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19232         ;
19233       else
19234         if (unformat
19235             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19236         mac_set++;
19237       else
19238         {
19239           clib_warning ("parse error '%U'", format_unformat_error, i);
19240           return -99;
19241         }
19242     }
19243
19244   if (parent_if_index == ~0)
19245     {
19246       errmsg ("missing interface name or sw_if_index");
19247       return -99;
19248     }
19249   if (mac_set == 0)
19250     {
19251       errmsg ("missing remote mac address");
19252       return -99;
19253     }
19254
19255   M (P2P_ETHERNET_DEL, mp);
19256   mp->parent_if_index = ntohl (parent_if_index);
19257   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19258
19259   S (mp);
19260   W (ret);
19261   return ret;
19262 }
19263
19264 static int
19265 api_tcp_configure_src_addresses (vat_main_t * vam)
19266 {
19267   vl_api_tcp_configure_src_addresses_t *mp;
19268   unformat_input_t *i = vam->input;
19269   vl_api_address_t first, last;
19270   u8 range_set = 0;
19271   u32 vrf_id = 0;
19272   int ret;
19273
19274   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19275     {
19276       if (unformat (i, "%U - %U",
19277                     unformat_vl_api_address, &first,
19278                     unformat_vl_api_address, &last))
19279         {
19280           if (range_set)
19281             {
19282               errmsg ("one range per message (range already set)");
19283               return -99;
19284             }
19285           range_set = 1;
19286         }
19287       else if (unformat (i, "vrf %d", &vrf_id))
19288         ;
19289       else
19290         break;
19291     }
19292
19293   if (range_set == 0)
19294     {
19295       errmsg ("address range not set");
19296       return -99;
19297     }
19298
19299   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
19300
19301   mp->vrf_id = ntohl (vrf_id);
19302   clib_memcpy (&mp->first_address, &first, sizeof (first));
19303   clib_memcpy (&mp->last_address, &last, sizeof (last));
19304
19305   S (mp);
19306   W (ret);
19307   return ret;
19308 }
19309
19310 static void vl_api_app_namespace_add_del_reply_t_handler
19311   (vl_api_app_namespace_add_del_reply_t * mp)
19312 {
19313   vat_main_t *vam = &vat_main;
19314   i32 retval = ntohl (mp->retval);
19315   if (vam->async_mode)
19316     {
19317       vam->async_errors += (retval < 0);
19318     }
19319   else
19320     {
19321       vam->retval = retval;
19322       if (retval == 0)
19323         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
19324       vam->result_ready = 1;
19325     }
19326 }
19327
19328 static void vl_api_app_namespace_add_del_reply_t_handler_json
19329   (vl_api_app_namespace_add_del_reply_t * mp)
19330 {
19331   vat_main_t *vam = &vat_main;
19332   vat_json_node_t node;
19333
19334   vat_json_init_object (&node);
19335   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
19336   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
19337
19338   vat_json_print (vam->ofp, &node);
19339   vat_json_free (&node);
19340
19341   vam->retval = ntohl (mp->retval);
19342   vam->result_ready = 1;
19343 }
19344
19345 static int
19346 api_app_namespace_add_del (vat_main_t * vam)
19347 {
19348   vl_api_app_namespace_add_del_t *mp;
19349   unformat_input_t *i = vam->input;
19350   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
19351   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
19352   u64 secret;
19353   int ret;
19354
19355   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19356     {
19357       if (unformat (i, "id %_%v%_", &ns_id))
19358         ;
19359       else if (unformat (i, "secret %lu", &secret))
19360         secret_set = 1;
19361       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19362         sw_if_index_set = 1;
19363       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
19364         ;
19365       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
19366         ;
19367       else
19368         break;
19369     }
19370   if (!ns_id || !secret_set || !sw_if_index_set)
19371     {
19372       errmsg ("namespace id, secret and sw_if_index must be set");
19373       return -99;
19374     }
19375   if (vec_len (ns_id) > 64)
19376     {
19377       errmsg ("namespace id too long");
19378       return -99;
19379     }
19380   M (APP_NAMESPACE_ADD_DEL, mp);
19381
19382   vl_api_vec_to_api_string (ns_id, &mp->namespace_id);
19383   mp->secret = clib_host_to_net_u64 (secret);
19384   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
19385   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
19386   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
19387   vec_free (ns_id);
19388   S (mp);
19389   W (ret);
19390   return ret;
19391 }
19392
19393 static int
19394 api_sock_init_shm (vat_main_t * vam)
19395 {
19396 #if VPP_API_TEST_BUILTIN == 0
19397   unformat_input_t *i = vam->input;
19398   vl_api_shm_elem_config_t *config = 0;
19399   u64 size = 64 << 20;
19400   int rv;
19401
19402   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19403     {
19404       if (unformat (i, "size %U", unformat_memory_size, &size))
19405         ;
19406       else
19407         break;
19408     }
19409
19410   /*
19411    * Canned custom ring allocator config.
19412    * Should probably parse all of this
19413    */
19414   vec_validate (config, 6);
19415   config[0].type = VL_API_VLIB_RING;
19416   config[0].size = 256;
19417   config[0].count = 32;
19418
19419   config[1].type = VL_API_VLIB_RING;
19420   config[1].size = 1024;
19421   config[1].count = 16;
19422
19423   config[2].type = VL_API_VLIB_RING;
19424   config[2].size = 4096;
19425   config[2].count = 2;
19426
19427   config[3].type = VL_API_CLIENT_RING;
19428   config[3].size = 256;
19429   config[3].count = 32;
19430
19431   config[4].type = VL_API_CLIENT_RING;
19432   config[4].size = 1024;
19433   config[4].count = 16;
19434
19435   config[5].type = VL_API_CLIENT_RING;
19436   config[5].size = 4096;
19437   config[5].count = 2;
19438
19439   config[6].type = VL_API_QUEUE;
19440   config[6].count = 128;
19441   config[6].size = sizeof (uword);
19442
19443   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
19444   if (!rv)
19445     vam->client_index_invalid = 1;
19446   return rv;
19447 #else
19448   return -99;
19449 #endif
19450 }
19451
19452 static void
19453 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
19454 {
19455   vat_main_t *vam = &vat_main;
19456   fib_prefix_t lcl, rmt;
19457
19458   ip_prefix_decode (&mp->lcl, &lcl);
19459   ip_prefix_decode (&mp->rmt, &rmt);
19460
19461   if (lcl.fp_proto == FIB_PROTOCOL_IP4)
19462     {
19463       print (vam->ofp,
19464              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19465              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19466              mp->scope, format_ip4_address, &lcl.fp_addr.ip4, lcl.fp_len,
19467              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
19468              &rmt.fp_addr.ip4, rmt.fp_len,
19469              clib_net_to_host_u16 (mp->rmt_port),
19470              clib_net_to_host_u32 (mp->action_index), mp->tag);
19471     }
19472   else
19473     {
19474       print (vam->ofp,
19475              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19476              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19477              mp->scope, format_ip6_address, &lcl.fp_addr.ip6, lcl.fp_len,
19478              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
19479              &rmt.fp_addr.ip6, rmt.fp_len,
19480              clib_net_to_host_u16 (mp->rmt_port),
19481              clib_net_to_host_u32 (mp->action_index), mp->tag);
19482     }
19483 }
19484
19485 static void
19486 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
19487                                              mp)
19488 {
19489   vat_main_t *vam = &vat_main;
19490   vat_json_node_t *node = NULL;
19491   struct in6_addr ip6;
19492   struct in_addr ip4;
19493
19494   fib_prefix_t lcl, rmt;
19495
19496   ip_prefix_decode (&mp->lcl, &lcl);
19497   ip_prefix_decode (&mp->rmt, &rmt);
19498
19499   if (VAT_JSON_ARRAY != vam->json_tree.type)
19500     {
19501       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19502       vat_json_init_array (&vam->json_tree);
19503     }
19504   node = vat_json_array_add (&vam->json_tree);
19505   vat_json_init_object (node);
19506
19507   vat_json_object_add_uint (node, "appns_index",
19508                             clib_net_to_host_u32 (mp->appns_index));
19509   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
19510   vat_json_object_add_uint (node, "scope", mp->scope);
19511   vat_json_object_add_uint (node, "action_index",
19512                             clib_net_to_host_u32 (mp->action_index));
19513   vat_json_object_add_uint (node, "lcl_port",
19514                             clib_net_to_host_u16 (mp->lcl_port));
19515   vat_json_object_add_uint (node, "rmt_port",
19516                             clib_net_to_host_u16 (mp->rmt_port));
19517   vat_json_object_add_uint (node, "lcl_plen", lcl.fp_len);
19518   vat_json_object_add_uint (node, "rmt_plen", rmt.fp_len);
19519   vat_json_object_add_string_copy (node, "tag", mp->tag);
19520   if (lcl.fp_proto == FIB_PROTOCOL_IP4)
19521     {
19522       clib_memcpy (&ip4, &lcl.fp_addr.ip4, sizeof (ip4));
19523       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
19524       clib_memcpy (&ip4, &rmt.fp_addr.ip4, sizeof (ip4));
19525       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
19526     }
19527   else
19528     {
19529       clib_memcpy (&ip6, &lcl.fp_addr.ip6, sizeof (ip6));
19530       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
19531       clib_memcpy (&ip6, &rmt.fp_addr.ip6, sizeof (ip6));
19532       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
19533     }
19534 }
19535
19536 static int
19537 api_session_rule_add_del (vat_main_t * vam)
19538 {
19539   vl_api_session_rule_add_del_t *mp;
19540   unformat_input_t *i = vam->input;
19541   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
19542   u32 appns_index = 0, scope = 0;
19543   ip4_address_t lcl_ip4, rmt_ip4;
19544   ip6_address_t lcl_ip6, rmt_ip6;
19545   u8 is_ip4 = 1, conn_set = 0;
19546   u8 is_add = 1, *tag = 0;
19547   int ret;
19548   fib_prefix_t lcl, rmt;
19549
19550   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19551     {
19552       if (unformat (i, "del"))
19553         is_add = 0;
19554       else if (unformat (i, "add"))
19555         ;
19556       else if (unformat (i, "proto tcp"))
19557         proto = 0;
19558       else if (unformat (i, "proto udp"))
19559         proto = 1;
19560       else if (unformat (i, "appns %d", &appns_index))
19561         ;
19562       else if (unformat (i, "scope %d", &scope))
19563         ;
19564       else if (unformat (i, "tag %_%v%_", &tag))
19565         ;
19566       else
19567         if (unformat
19568             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
19569              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
19570              &rmt_port))
19571         {
19572           is_ip4 = 1;
19573           conn_set = 1;
19574         }
19575       else
19576         if (unformat
19577             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
19578              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
19579              &rmt_port))
19580         {
19581           is_ip4 = 0;
19582           conn_set = 1;
19583         }
19584       else if (unformat (i, "action %d", &action))
19585         ;
19586       else
19587         break;
19588     }
19589   if (proto == ~0 || !conn_set || action == ~0)
19590     {
19591       errmsg ("transport proto, connection and action must be set");
19592       return -99;
19593     }
19594
19595   if (scope > 3)
19596     {
19597       errmsg ("scope should be 0-3");
19598       return -99;
19599     }
19600
19601   M (SESSION_RULE_ADD_DEL, mp);
19602
19603   clib_memset (&lcl, 0, sizeof (lcl));
19604   clib_memset (&rmt, 0, sizeof (rmt));
19605   if (is_ip4)
19606     {
19607       ip_set (&lcl.fp_addr, &lcl_ip4, 1);
19608       ip_set (&rmt.fp_addr, &rmt_ip4, 1);
19609       lcl.fp_len = lcl_plen;
19610       rmt.fp_len = rmt_plen;
19611     }
19612   else
19613     {
19614       ip_set (&lcl.fp_addr, &lcl_ip6, 0);
19615       ip_set (&rmt.fp_addr, &rmt_ip6, 0);
19616       lcl.fp_len = lcl_plen;
19617       rmt.fp_len = rmt_plen;
19618     }
19619
19620
19621   ip_prefix_encode (&lcl, &mp->lcl);
19622   ip_prefix_encode (&rmt, &mp->rmt);
19623   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
19624   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
19625   mp->transport_proto =
19626     proto ? TRANSPORT_PROTO_API_UDP : TRANSPORT_PROTO_API_TCP;
19627   mp->action_index = clib_host_to_net_u32 (action);
19628   mp->appns_index = clib_host_to_net_u32 (appns_index);
19629   mp->scope = scope;
19630   mp->is_add = is_add;
19631   if (tag)
19632     {
19633       clib_memcpy (mp->tag, tag, vec_len (tag));
19634       vec_free (tag);
19635     }
19636
19637   S (mp);
19638   W (ret);
19639   return ret;
19640 }
19641
19642 static int
19643 api_session_rules_dump (vat_main_t * vam)
19644 {
19645   vl_api_session_rules_dump_t *mp;
19646   vl_api_control_ping_t *mp_ping;
19647   int ret;
19648
19649   if (!vam->json_output)
19650     {
19651       print (vam->ofp, "%=20s", "Session Rules");
19652     }
19653
19654   M (SESSION_RULES_DUMP, mp);
19655   /* send it... */
19656   S (mp);
19657
19658   /* Use a control ping for synchronization */
19659   MPING (CONTROL_PING, mp_ping);
19660   S (mp_ping);
19661
19662   /* Wait for a reply... */
19663   W (ret);
19664   return ret;
19665 }
19666
19667 static int
19668 api_ip_container_proxy_add_del (vat_main_t * vam)
19669 {
19670   vl_api_ip_container_proxy_add_del_t *mp;
19671   unformat_input_t *i = vam->input;
19672   u32 sw_if_index = ~0;
19673   vl_api_prefix_t pfx = { };
19674   u8 is_add = 1;
19675   int ret;
19676
19677   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19678     {
19679       if (unformat (i, "del"))
19680         is_add = 0;
19681       else if (unformat (i, "add"))
19682         ;
19683       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
19684         ;
19685       else if (unformat (i, "sw_if_index %u", &sw_if_index))
19686         ;
19687       else
19688         break;
19689     }
19690   if (sw_if_index == ~0 || pfx.len == 0)
19691     {
19692       errmsg ("address and sw_if_index must be set");
19693       return -99;
19694     }
19695
19696   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
19697
19698   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
19699   mp->is_add = is_add;
19700   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
19701
19702   S (mp);
19703   W (ret);
19704   return ret;
19705 }
19706
19707 static int
19708 api_qos_record_enable_disable (vat_main_t * vam)
19709 {
19710   unformat_input_t *i = vam->input;
19711   vl_api_qos_record_enable_disable_t *mp;
19712   u32 sw_if_index, qs = 0xff;
19713   u8 sw_if_index_set = 0;
19714   u8 enable = 1;
19715   int ret;
19716
19717   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19718     {
19719       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19720         sw_if_index_set = 1;
19721       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19722         sw_if_index_set = 1;
19723       else if (unformat (i, "%U", unformat_qos_source, &qs))
19724         ;
19725       else if (unformat (i, "disable"))
19726         enable = 0;
19727       else
19728         {
19729           clib_warning ("parse error '%U'", format_unformat_error, i);
19730           return -99;
19731         }
19732     }
19733
19734   if (sw_if_index_set == 0)
19735     {
19736       errmsg ("missing interface name or sw_if_index");
19737       return -99;
19738     }
19739   if (qs == 0xff)
19740     {
19741       errmsg ("input location must be specified");
19742       return -99;
19743     }
19744
19745   M (QOS_RECORD_ENABLE_DISABLE, mp);
19746
19747   mp->record.sw_if_index = ntohl (sw_if_index);
19748   mp->record.input_source = qs;
19749   mp->enable = enable;
19750
19751   S (mp);
19752   W (ret);
19753   return ret;
19754 }
19755
19756
19757 static int
19758 q_or_quit (vat_main_t * vam)
19759 {
19760 #if VPP_API_TEST_BUILTIN == 0
19761   longjmp (vam->jump_buf, 1);
19762 #endif
19763   return 0;                     /* not so much */
19764 }
19765
19766 static int
19767 q (vat_main_t * vam)
19768 {
19769   return q_or_quit (vam);
19770 }
19771
19772 static int
19773 quit (vat_main_t * vam)
19774 {
19775   return q_or_quit (vam);
19776 }
19777
19778 static int
19779 comment (vat_main_t * vam)
19780 {
19781   return 0;
19782 }
19783
19784 static int
19785 elog_save (vat_main_t * vam)
19786 {
19787 #if VPP_API_TEST_BUILTIN == 0
19788   elog_main_t *em = &vam->elog_main;
19789   unformat_input_t *i = vam->input;
19790   char *file, *chroot_file;
19791   clib_error_t *error;
19792
19793   if (!unformat (i, "%s", &file))
19794     {
19795       errmsg ("expected file name, got `%U'", format_unformat_error, i);
19796       return 0;
19797     }
19798
19799   /* It's fairly hard to get "../oopsie" through unformat; just in case */
19800   if (strstr (file, "..") || index (file, '/'))
19801     {
19802       errmsg ("illegal characters in filename '%s'", file);
19803       return 0;
19804     }
19805
19806   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
19807
19808   vec_free (file);
19809
19810   errmsg ("Saving %wd of %wd events to %s",
19811           elog_n_events_in_buffer (em),
19812           elog_buffer_capacity (em), chroot_file);
19813
19814   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
19815   vec_free (chroot_file);
19816
19817   if (error)
19818     clib_error_report (error);
19819 #else
19820   errmsg ("Use the vpp event loger...");
19821 #endif
19822
19823   return 0;
19824 }
19825
19826 static int
19827 elog_setup (vat_main_t * vam)
19828 {
19829 #if VPP_API_TEST_BUILTIN == 0
19830   elog_main_t *em = &vam->elog_main;
19831   unformat_input_t *i = vam->input;
19832   u32 nevents = 128 << 10;
19833
19834   (void) unformat (i, "nevents %d", &nevents);
19835
19836   elog_init (em, nevents);
19837   vl_api_set_elog_main (em);
19838   vl_api_set_elog_trace_api_messages (1);
19839   errmsg ("Event logger initialized with %u events", nevents);
19840 #else
19841   errmsg ("Use the vpp event loger...");
19842 #endif
19843   return 0;
19844 }
19845
19846 static int
19847 elog_enable (vat_main_t * vam)
19848 {
19849 #if VPP_API_TEST_BUILTIN == 0
19850   elog_main_t *em = &vam->elog_main;
19851
19852   elog_enable_disable (em, 1 /* enable */ );
19853   vl_api_set_elog_trace_api_messages (1);
19854   errmsg ("Event logger enabled...");
19855 #else
19856   errmsg ("Use the vpp event loger...");
19857 #endif
19858   return 0;
19859 }
19860
19861 static int
19862 elog_disable (vat_main_t * vam)
19863 {
19864 #if VPP_API_TEST_BUILTIN == 0
19865   elog_main_t *em = &vam->elog_main;
19866
19867   elog_enable_disable (em, 0 /* enable */ );
19868   vl_api_set_elog_trace_api_messages (1);
19869   errmsg ("Event logger disabled...");
19870 #else
19871   errmsg ("Use the vpp event loger...");
19872 #endif
19873   return 0;
19874 }
19875
19876 static int
19877 statseg (vat_main_t * vam)
19878 {
19879   ssvm_private_t *ssvmp = &vam->stat_segment;
19880   ssvm_shared_header_t *shared_header = ssvmp->sh;
19881   vlib_counter_t **counters;
19882   u64 thread0_index1_packets;
19883   u64 thread0_index1_bytes;
19884   f64 vector_rate, input_rate;
19885   uword *p;
19886
19887   uword *counter_vector_by_name;
19888   if (vam->stat_segment_lockp == 0)
19889     {
19890       errmsg ("Stat segment not mapped...");
19891       return -99;
19892     }
19893
19894   /* look up "/if/rx for sw_if_index 1 as a test */
19895
19896   clib_spinlock_lock (vam->stat_segment_lockp);
19897
19898   counter_vector_by_name = (uword *) shared_header->opaque[1];
19899
19900   p = hash_get_mem (counter_vector_by_name, "/if/rx");
19901   if (p == 0)
19902     {
19903       clib_spinlock_unlock (vam->stat_segment_lockp);
19904       errmsg ("/if/tx not found?");
19905       return -99;
19906     }
19907
19908   /* Fish per-thread vector of combined counters from shared memory */
19909   counters = (vlib_counter_t **) p[0];
19910
19911   if (vec_len (counters[0]) < 2)
19912     {
19913       clib_spinlock_unlock (vam->stat_segment_lockp);
19914       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
19915       return -99;
19916     }
19917
19918   /* Read thread 0 sw_if_index 1 counter */
19919   thread0_index1_packets = counters[0][1].packets;
19920   thread0_index1_bytes = counters[0][1].bytes;
19921
19922   p = hash_get_mem (counter_vector_by_name, "vector_rate");
19923   if (p == 0)
19924     {
19925       clib_spinlock_unlock (vam->stat_segment_lockp);
19926       errmsg ("vector_rate not found?");
19927       return -99;
19928     }
19929
19930   vector_rate = *(f64 *) (p[0]);
19931   p = hash_get_mem (counter_vector_by_name, "input_rate");
19932   if (p == 0)
19933     {
19934       clib_spinlock_unlock (vam->stat_segment_lockp);
19935       errmsg ("input_rate not found?");
19936       return -99;
19937     }
19938   input_rate = *(f64 *) (p[0]);
19939
19940   clib_spinlock_unlock (vam->stat_segment_lockp);
19941
19942   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
19943          vector_rate, input_rate);
19944   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
19945          thread0_index1_packets, thread0_index1_bytes);
19946
19947   return 0;
19948 }
19949
19950 static int
19951 cmd_cmp (void *a1, void *a2)
19952 {
19953   u8 **c1 = a1;
19954   u8 **c2 = a2;
19955
19956   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
19957 }
19958
19959 static int
19960 help (vat_main_t * vam)
19961 {
19962   u8 **cmds = 0;
19963   u8 *name = 0;
19964   hash_pair_t *p;
19965   unformat_input_t *i = vam->input;
19966   int j;
19967
19968   if (unformat (i, "%s", &name))
19969     {
19970       uword *hs;
19971
19972       vec_add1 (name, 0);
19973
19974       hs = hash_get_mem (vam->help_by_name, name);
19975       if (hs)
19976         print (vam->ofp, "usage: %s %s", name, hs[0]);
19977       else
19978         print (vam->ofp, "No such msg / command '%s'", name);
19979       vec_free (name);
19980       return 0;
19981     }
19982
19983   print (vam->ofp, "Help is available for the following:");
19984
19985     /* *INDENT-OFF* */
19986     hash_foreach_pair (p, vam->function_by_name,
19987     ({
19988       vec_add1 (cmds, (u8 *)(p->key));
19989     }));
19990     /* *INDENT-ON* */
19991
19992   vec_sort_with_function (cmds, cmd_cmp);
19993
19994   for (j = 0; j < vec_len (cmds); j++)
19995     print (vam->ofp, "%s", cmds[j]);
19996
19997   vec_free (cmds);
19998   return 0;
19999 }
20000
20001 static int
20002 set (vat_main_t * vam)
20003 {
20004   u8 *name = 0, *value = 0;
20005   unformat_input_t *i = vam->input;
20006
20007   if (unformat (i, "%s", &name))
20008     {
20009       /* The input buffer is a vector, not a string. */
20010       value = vec_dup (i->buffer);
20011       vec_delete (value, i->index, 0);
20012       /* Almost certainly has a trailing newline */
20013       if (value[vec_len (value) - 1] == '\n')
20014         value[vec_len (value) - 1] = 0;
20015       /* Make sure it's a proper string, one way or the other */
20016       vec_add1 (value, 0);
20017       (void) clib_macro_set_value (&vam->macro_main,
20018                                    (char *) name, (char *) value);
20019     }
20020   else
20021     errmsg ("usage: set <name> <value>");
20022
20023   vec_free (name);
20024   vec_free (value);
20025   return 0;
20026 }
20027
20028 static int
20029 unset (vat_main_t * vam)
20030 {
20031   u8 *name = 0;
20032
20033   if (unformat (vam->input, "%s", &name))
20034     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
20035       errmsg ("unset: %s wasn't set", name);
20036   vec_free (name);
20037   return 0;
20038 }
20039
20040 typedef struct
20041 {
20042   u8 *name;
20043   u8 *value;
20044 } macro_sort_t;
20045
20046
20047 static int
20048 macro_sort_cmp (void *a1, void *a2)
20049 {
20050   macro_sort_t *s1 = a1;
20051   macro_sort_t *s2 = a2;
20052
20053   return strcmp ((char *) (s1->name), (char *) (s2->name));
20054 }
20055
20056 static int
20057 dump_macro_table (vat_main_t * vam)
20058 {
20059   macro_sort_t *sort_me = 0, *sm;
20060   int i;
20061   hash_pair_t *p;
20062
20063     /* *INDENT-OFF* */
20064     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
20065     ({
20066       vec_add2 (sort_me, sm, 1);
20067       sm->name = (u8 *)(p->key);
20068       sm->value = (u8 *) (p->value[0]);
20069     }));
20070     /* *INDENT-ON* */
20071
20072   vec_sort_with_function (sort_me, macro_sort_cmp);
20073
20074   if (vec_len (sort_me))
20075     print (vam->ofp, "%-15s%s", "Name", "Value");
20076   else
20077     print (vam->ofp, "The macro table is empty...");
20078
20079   for (i = 0; i < vec_len (sort_me); i++)
20080     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
20081   return 0;
20082 }
20083
20084 static int
20085 dump_node_table (vat_main_t * vam)
20086 {
20087   int i, j;
20088   vlib_node_t *node, *next_node;
20089
20090   if (vec_len (vam->graph_nodes) == 0)
20091     {
20092       print (vam->ofp, "Node table empty, issue get_node_graph...");
20093       return 0;
20094     }
20095
20096   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
20097     {
20098       node = vam->graph_nodes[0][i];
20099       print (vam->ofp, "[%d] %s", i, node->name);
20100       for (j = 0; j < vec_len (node->next_nodes); j++)
20101         {
20102           if (node->next_nodes[j] != ~0)
20103             {
20104               next_node = vam->graph_nodes[0][node->next_nodes[j]];
20105               print (vam->ofp, "  [%d] %s", j, next_node->name);
20106             }
20107         }
20108     }
20109   return 0;
20110 }
20111
20112 static int
20113 value_sort_cmp (void *a1, void *a2)
20114 {
20115   name_sort_t *n1 = a1;
20116   name_sort_t *n2 = a2;
20117
20118   if (n1->value < n2->value)
20119     return -1;
20120   if (n1->value > n2->value)
20121     return 1;
20122   return 0;
20123 }
20124
20125
20126 static int
20127 dump_msg_api_table (vat_main_t * vam)
20128 {
20129   api_main_t *am = vlibapi_get_main ();
20130   name_sort_t *nses = 0, *ns;
20131   hash_pair_t *hp;
20132   int i;
20133
20134   /* *INDENT-OFF* */
20135   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
20136   ({
20137     vec_add2 (nses, ns, 1);
20138     ns->name = (u8 *)(hp->key);
20139     ns->value = (u32) hp->value[0];
20140   }));
20141   /* *INDENT-ON* */
20142
20143   vec_sort_with_function (nses, value_sort_cmp);
20144
20145   for (i = 0; i < vec_len (nses); i++)
20146     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
20147   vec_free (nses);
20148   return 0;
20149 }
20150
20151 static int
20152 get_msg_id (vat_main_t * vam)
20153 {
20154   u8 *name_and_crc;
20155   u32 message_index;
20156
20157   if (unformat (vam->input, "%s", &name_and_crc))
20158     {
20159       message_index = vl_msg_api_get_msg_index (name_and_crc);
20160       if (message_index == ~0)
20161         {
20162           print (vam->ofp, " '%s' not found", name_and_crc);
20163           return 0;
20164         }
20165       print (vam->ofp, " '%s' has message index %d",
20166              name_and_crc, message_index);
20167       return 0;
20168     }
20169   errmsg ("name_and_crc required...");
20170   return 0;
20171 }
20172
20173 static int
20174 search_node_table (vat_main_t * vam)
20175 {
20176   unformat_input_t *line_input = vam->input;
20177   u8 *node_to_find;
20178   int j;
20179   vlib_node_t *node, *next_node;
20180   uword *p;
20181
20182   if (vam->graph_node_index_by_name == 0)
20183     {
20184       print (vam->ofp, "Node table empty, issue get_node_graph...");
20185       return 0;
20186     }
20187
20188   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20189     {
20190       if (unformat (line_input, "%s", &node_to_find))
20191         {
20192           vec_add1 (node_to_find, 0);
20193           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
20194           if (p == 0)
20195             {
20196               print (vam->ofp, "%s not found...", node_to_find);
20197               goto out;
20198             }
20199           node = vam->graph_nodes[0][p[0]];
20200           print (vam->ofp, "[%d] %s", p[0], node->name);
20201           for (j = 0; j < vec_len (node->next_nodes); j++)
20202             {
20203               if (node->next_nodes[j] != ~0)
20204                 {
20205                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
20206                   print (vam->ofp, "  [%d] %s", j, next_node->name);
20207                 }
20208             }
20209         }
20210
20211       else
20212         {
20213           clib_warning ("parse error '%U'", format_unformat_error,
20214                         line_input);
20215           return -99;
20216         }
20217
20218     out:
20219       vec_free (node_to_find);
20220
20221     }
20222
20223   return 0;
20224 }
20225
20226
20227 static int
20228 script (vat_main_t * vam)
20229 {
20230 #if (VPP_API_TEST_BUILTIN==0)
20231   u8 *s = 0;
20232   char *save_current_file;
20233   unformat_input_t save_input;
20234   jmp_buf save_jump_buf;
20235   u32 save_line_number;
20236
20237   FILE *new_fp, *save_ifp;
20238
20239   if (unformat (vam->input, "%s", &s))
20240     {
20241       new_fp = fopen ((char *) s, "r");
20242       if (new_fp == 0)
20243         {
20244           errmsg ("Couldn't open script file %s", s);
20245           vec_free (s);
20246           return -99;
20247         }
20248     }
20249   else
20250     {
20251       errmsg ("Missing script name");
20252       return -99;
20253     }
20254
20255   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
20256   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
20257   save_ifp = vam->ifp;
20258   save_line_number = vam->input_line_number;
20259   save_current_file = (char *) vam->current_file;
20260
20261   vam->input_line_number = 0;
20262   vam->ifp = new_fp;
20263   vam->current_file = s;
20264   do_one_file (vam);
20265
20266   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
20267   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
20268   vam->ifp = save_ifp;
20269   vam->input_line_number = save_line_number;
20270   vam->current_file = (u8 *) save_current_file;
20271   vec_free (s);
20272
20273   return 0;
20274 #else
20275   clib_warning ("use the exec command...");
20276   return -99;
20277 #endif
20278 }
20279
20280 static int
20281 echo (vat_main_t * vam)
20282 {
20283   print (vam->ofp, "%v", vam->input->buffer);
20284   return 0;
20285 }
20286
20287 /* List of API message constructors, CLI names map to api_xxx */
20288 #define foreach_vpe_api_msg                                             \
20289 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
20290 _(sw_interface_dump,"")                                                 \
20291 _(sw_interface_set_flags,                                               \
20292   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
20293 _(sw_interface_add_del_address,                                         \
20294   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
20295 _(sw_interface_set_rx_mode,                                             \
20296   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
20297 _(sw_interface_set_rx_placement,                                        \
20298   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
20299 _(sw_interface_rx_placement_dump,                                       \
20300   "[<intfc> | sw_if_index <id>]")                                         \
20301 _(sw_interface_set_table,                                               \
20302   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
20303 _(sw_interface_set_mpls_enable,                                         \
20304   "<intfc> | sw_if_index [disable | dis]")                              \
20305 _(sw_interface_set_vpath,                                               \
20306   "<intfc> | sw_if_index <id> enable | disable")                        \
20307 _(sw_interface_set_vxlan_bypass,                                        \
20308   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20309 _(sw_interface_set_l2_xconnect,                                         \
20310   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20311   "enable | disable")                                                   \
20312 _(sw_interface_set_l2_bridge,                                           \
20313   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
20314   "[shg <split-horizon-group>] [bvi]\n"                                 \
20315   "enable | disable")                                                   \
20316 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
20317 _(bridge_domain_add_del,                                                \
20318   "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") \
20319 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
20320 _(l2fib_add_del,                                                        \
20321   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
20322 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
20323 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
20324 _(l2_flags,                                                             \
20325   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20326 _(bridge_flags,                                                         \
20327   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20328 _(tap_create_v2,                                                        \
20329   "id <num> [hw-addr <mac-addr>] [host-if-name <name>] [host-ns <name>] [num-rx-queues <num>] [rx-ring-size <num>] [tx-ring-size <num>] [host-bridge <name>] [host-mac-addr <mac-addr>] [host-ip4-addr <ip4addr/mask>] [host-ip6-addr <ip6addr/mask>] [host-mtu-size <mtu>] [gso | no-gso | csum-offload | gro-coalesce] [persist] [attach] [tun] [packed] [in-order]") \
20330 _(tap_delete_v2,                                                        \
20331   "<vpp-if-name> | sw_if_index <id>")                                   \
20332 _(sw_interface_tap_v2_dump, "")                                         \
20333 _(virtio_pci_create_v2,                                                    \
20334   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled [gro-coalesce] | csum-offload-enabled] [packed] [in-order]") \
20335 _(virtio_pci_delete,                                                    \
20336   "<vpp-if-name> | sw_if_index <id>")                                   \
20337 _(sw_interface_virtio_pci_dump, "")                                     \
20338 _(bond_create,                                                          \
20339   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
20340   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
20341   "[id <if-id>]")                                                       \
20342 _(bond_create2,                                                         \
20343   "[hw-addr <mac-addr>] {mode round-robin | active-backup | "           \
20344   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
20345   "[id <if-id>] [gso]")                                                 \
20346 _(bond_delete,                                                          \
20347   "<vpp-if-name> | sw_if_index <id>")                                   \
20348 _(bond_add_member,                                                      \
20349   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
20350 _(bond_detach_member,                                                   \
20351   "sw_if_index <n>")                                                    \
20352  _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
20353  _(sw_bond_interface_dump, "<intfc> | sw_if_index <nn>")                \
20354  _(sw_member_interface_dump,                                            \
20355   "<vpp-if-name> | sw_if_index <id>")                                   \
20356 _(ip_table_add_del,                                                     \
20357   "table <n> [ipv6] [add | del]\n")                                     \
20358 _(ip_route_add_del,                                                     \
20359   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
20360   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
20361   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
20362   "[multipath] [count <n>] [del]")                                      \
20363 _(ip_mroute_add_del,                                                    \
20364   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
20365   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
20366 _(mpls_table_add_del,                                                   \
20367   "table <n> [add | del]\n")                                            \
20368 _(mpls_route_add_del,                                                   \
20369   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
20370   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
20371   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
20372   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
20373   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
20374   "[count <n>] [del]")                                                  \
20375 _(mpls_ip_bind_unbind,                                                  \
20376   "<label> <addr/len>")                                                 \
20377 _(mpls_tunnel_add_del,                                                  \
20378   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
20379   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
20380   "[l2-only]  [out-label <n>]")                                         \
20381 _(sr_mpls_policy_add,                                                   \
20382   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
20383 _(sr_mpls_policy_del,                                                   \
20384   "bsid <id>")                                                          \
20385 _(bier_table_add_del,                                                   \
20386   "<label> <sub-domain> <set> <bsl> [del]")                             \
20387 _(bier_route_add_del,                                                   \
20388   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
20389   "[<intfc> | sw_if_index <id>]"                                        \
20390   "[weight <n>] [del] [multipath]")                                     \
20391 _(sw_interface_set_unnumbered,                                          \
20392   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
20393 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
20394 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
20395   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
20396   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
20397   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
20398 _(ip_table_replace_begin, "table <n> [ipv6]")                           \
20399 _(ip_table_flush, "table <n> [ipv6]")                                   \
20400 _(ip_table_replace_end, "table <n> [ipv6]")                             \
20401 _(set_ip_flow_hash,                                                     \
20402   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
20403 _(sw_interface_ip6_enable_disable,                                      \
20404   "<intfc> | sw_if_index <id> enable | disable")                        \
20405 _(l2_patch_add_del,                                                     \
20406   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20407   "enable | disable")                                                   \
20408 _(sr_localsid_add_del,                                                  \
20409   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
20410   "fib-table <num> (end.psp) sw_if_index <num>")                        \
20411 _(classify_add_del_table,                                               \
20412   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
20413   " [del] [del-chain] mask <mask-value>\n"                              \
20414   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
20415   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
20416 _(classify_add_del_session,                                             \
20417   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
20418   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
20419   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
20420   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
20421 _(classify_set_interface_ip_table,                                      \
20422   "<intfc> | sw_if_index <nn> table <nn>")                              \
20423 _(classify_set_interface_l2_tables,                                     \
20424   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20425   "  [other-table <nn>]")                                               \
20426 _(get_node_index, "node <node-name")                                    \
20427 _(add_node_next, "node <node-name> next <next-node-name>")              \
20428 _(l2tpv3_create_tunnel,                                                 \
20429   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
20430   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
20431   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
20432 _(l2tpv3_set_tunnel_cookies,                                            \
20433   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
20434   "[new_remote_cookie <nn>]\n")                                         \
20435 _(l2tpv3_interface_enable_disable,                                      \
20436   "<intfc> | sw_if_index <nn> enable | disable")                        \
20437 _(l2tpv3_set_lookup_key,                                                \
20438   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
20439 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
20440 _(vxlan_offload_rx,                                                     \
20441   "hw { <interface name> | hw_if_index <nn>} "                          \
20442   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
20443 _(vxlan_add_del_tunnel,                                                 \
20444   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20445   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
20446   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20447 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
20448 _(gre_tunnel_add_del,                                                   \
20449   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
20450   "[teb | erspan <session-id>] [del]")                                  \
20451 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
20452 _(l2_fib_clear_table, "")                                               \
20453 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
20454 _(l2_interface_vlan_tag_rewrite,                                        \
20455   "<intfc> | sw_if_index <nn> \n"                                       \
20456   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
20457   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
20458 _(create_vhost_user_if,                                                 \
20459         "socket <filename> [server] [renumber <dev_instance>] "         \
20460         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
20461         "[mac <mac_address>] [packed]")                                 \
20462 _(modify_vhost_user_if,                                                 \
20463         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
20464         "[server] [renumber <dev_instance>] [gso] [packed]")            \
20465 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
20466 _(sw_interface_vhost_user_dump, "<intfc> | sw_if_index <nn>")           \
20467 _(show_version, "")                                                     \
20468 _(show_threads, "")                                                     \
20469 _(vxlan_gpe_add_del_tunnel,                                             \
20470   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
20471   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20472   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
20473   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
20474 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
20475 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
20476 _(interface_name_renumber,                                              \
20477   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
20478 _(input_acl_set_interface,                                              \
20479   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20480   "  [l2-table <nn>] [del]")                                            \
20481 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
20482 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
20483 _(ip_dump, "ipv4 | ipv6")                                               \
20484 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
20485 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
20486   "  spid_id <n> ")                                                     \
20487 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
20488   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
20489   "  integ_alg <alg> integ_key <hex>")                                  \
20490 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
20491   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
20492   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
20493   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
20494 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
20495   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
20496   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
20497   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
20498   "  [instance <n>]")     \
20499 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
20500 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
20501 _(delete_loopback,"sw_if_index <nn>")                                   \
20502 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
20503 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
20504 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
20505 _(want_interface_events,  "enable|disable")                             \
20506 _(get_first_msg_id, "client <name>")                                    \
20507 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
20508 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
20509   "fib-id <nn> [ip4][ip6][default]")                                    \
20510 _(get_node_graph, " ")                                                  \
20511 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
20512 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
20513 _(ioam_disable, "")                                                     \
20514 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
20515                             " sw_if_index <sw_if_index> p <priority> "  \
20516                             "w <weight>] [del]")                        \
20517 _(one_add_del_locator, "locator-set <locator_name> "                    \
20518                         "iface <intf> | sw_if_index <sw_if_index> "     \
20519                         "p <priority> w <weight> [del]")                \
20520 _(one_add_del_local_eid,"vni <vni> eid "                                \
20521                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20522                          "locator-set <locator_name> [del]"             \
20523                          "[key-id sha1|sha256 secret-key <secret-key>]")\
20524 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
20525 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
20526 _(one_enable_disable, "enable|disable")                                 \
20527 _(one_map_register_enable_disable, "enable|disable")                    \
20528 _(one_map_register_fallback_threshold, "<value>")                       \
20529 _(one_rloc_probe_enable_disable, "enable|disable")                      \
20530 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
20531                                "[seid <seid>] "                         \
20532                                "rloc <locator> p <prio> "               \
20533                                "w <weight> [rloc <loc> ... ] "          \
20534                                "action <action> [del-all]")             \
20535 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
20536                           "<local-eid>")                                \
20537 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
20538 _(one_use_petr, "ip-address> | disable")                                \
20539 _(one_map_request_mode, "src-dst|dst-only")                             \
20540 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
20541 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
20542 _(one_locator_set_dump, "[local | remote]")                             \
20543 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
20544 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
20545                        "[local] | [remote]")                            \
20546 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
20547 _(one_ndp_bd_get, "")                                                   \
20548 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
20549 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip <ip4>")        \
20550 _(one_l2_arp_bd_get, "")                                                \
20551 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
20552 _(one_stats_enable_disable, "enable|disable")                           \
20553 _(show_one_stats_enable_disable, "")                                    \
20554 _(one_eid_table_vni_dump, "")                                           \
20555 _(one_eid_table_map_dump, "l2|l3")                                      \
20556 _(one_map_resolver_dump, "")                                            \
20557 _(one_map_server_dump, "")                                              \
20558 _(one_adjacencies_get, "vni <vni>")                                     \
20559 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
20560 _(show_one_rloc_probe_state, "")                                        \
20561 _(show_one_map_register_state, "")                                      \
20562 _(show_one_status, "")                                                  \
20563 _(one_stats_dump, "")                                                   \
20564 _(one_stats_flush, "")                                                  \
20565 _(one_get_map_request_itr_rlocs, "")                                    \
20566 _(one_map_register_set_ttl, "<ttl>")                                    \
20567 _(one_set_transport_protocol, "udp|api")                                \
20568 _(one_get_transport_protocol, "")                                       \
20569 _(one_enable_disable_xtr_mode, "enable|disable")                        \
20570 _(one_show_xtr_mode, "")                                                \
20571 _(one_enable_disable_pitr_mode, "enable|disable")                       \
20572 _(one_show_pitr_mode, "")                                               \
20573 _(one_enable_disable_petr_mode, "enable|disable")                       \
20574 _(one_show_petr_mode, "")                                               \
20575 _(show_one_nsh_mapping, "")                                             \
20576 _(show_one_pitr, "")                                                    \
20577 _(show_one_use_petr, "")                                                \
20578 _(show_one_map_request_mode, "")                                        \
20579 _(show_one_map_register_ttl, "")                                        \
20580 _(show_one_map_register_fallback_threshold, "")                         \
20581 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
20582                             " sw_if_index <sw_if_index> p <priority> "  \
20583                             "w <weight>] [del]")                        \
20584 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
20585                         "iface <intf> | sw_if_index <sw_if_index> "     \
20586                         "p <priority> w <weight> [del]")                \
20587 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
20588                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20589                          "locator-set <locator_name> [del]"             \
20590                          "[key-id sha1|sha256 secret-key <secret-key>]") \
20591 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
20592 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
20593 _(lisp_enable_disable, "enable|disable")                                \
20594 _(lisp_map_register_enable_disable, "enable|disable")                   \
20595 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
20596 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
20597                                "[seid <seid>] "                         \
20598                                "rloc <locator> p <prio> "               \
20599                                "w <weight> [rloc <loc> ... ] "          \
20600                                "action <action> [del-all]")             \
20601 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
20602                           "<local-eid>")                                \
20603 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
20604 _(lisp_use_petr, "<ip-address> | disable")                              \
20605 _(lisp_map_request_mode, "src-dst|dst-only")                            \
20606 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
20607 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
20608 _(lisp_locator_set_dump, "[local | remote]")                            \
20609 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
20610 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
20611                        "[local] | [remote]")                            \
20612 _(lisp_eid_table_vni_dump, "")                                          \
20613 _(lisp_eid_table_map_dump, "l2|l3")                                     \
20614 _(lisp_map_resolver_dump, "")                                           \
20615 _(lisp_map_server_dump, "")                                             \
20616 _(lisp_adjacencies_get, "vni <vni>")                                    \
20617 _(gpe_fwd_entry_vnis_get, "")                                           \
20618 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
20619 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
20620                                 "[table <table-id>]")                   \
20621 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
20622 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
20623 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
20624 _(gpe_get_encap_mode, "")                                               \
20625 _(lisp_gpe_add_del_iface, "up|down")                                    \
20626 _(lisp_gpe_enable_disable, "enable|disable")                            \
20627 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
20628   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
20629 _(show_lisp_rloc_probe_state, "")                                       \
20630 _(show_lisp_map_register_state, "")                                     \
20631 _(show_lisp_status, "")                                                 \
20632 _(lisp_get_map_request_itr_rlocs, "")                                   \
20633 _(show_lisp_pitr, "")                                                   \
20634 _(show_lisp_use_petr, "")                                               \
20635 _(show_lisp_map_request_mode, "")                                       \
20636 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
20637 _(af_packet_delete, "name <host interface name>")                       \
20638 _(af_packet_dump, "")                                                   \
20639 _(policer_add_del, "name <policer name> <params> [del]")                \
20640 _(policer_dump, "[name <policer name>]")                                \
20641 _(policer_classify_set_interface,                                       \
20642   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20643   "  [l2-table <nn>] [del]")                                            \
20644 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
20645 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
20646 _(mpls_table_dump, "")                                                  \
20647 _(mpls_route_dump, "table-id <ID>")                                     \
20648 _(classify_table_ids, "")                                               \
20649 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
20650 _(classify_table_info, "table_id <nn>")                                 \
20651 _(classify_session_dump, "table_id <nn>")                               \
20652 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
20653     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
20654     "[template_interval <nn>] [udp_checksum]")                          \
20655 _(ipfix_exporter_dump, "")                                              \
20656 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
20657 _(ipfix_classify_stream_dump, "")                                       \
20658 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
20659 _(ipfix_classify_table_dump, "")                                        \
20660 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
20661 _(sw_interface_span_dump, "[l2]")                                           \
20662 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
20663 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
20664 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
20665 _(pg_enable_disable, "[stream <id>] disable")                           \
20666 _(pg_interface_enable_disable_coalesce, "<intf> | sw_if_index <nn> enable | disable")  \
20667 _(ip_source_and_port_range_check_add_del,                               \
20668   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
20669 _(ip_source_and_port_range_check_interface_add_del,                     \
20670   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
20671   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
20672 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
20673 _(l2_interface_pbb_tag_rewrite,                                         \
20674   "<intfc> | sw_if_index <nn> \n"                                       \
20675   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
20676   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
20677 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
20678 _(flow_classify_set_interface,                                          \
20679   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
20680 _(flow_classify_dump, "type [ip4|ip6]")                                 \
20681 _(ip_table_dump, "")                                                    \
20682 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
20683 _(ip_mtable_dump, "")                                                   \
20684 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
20685 _(feature_enable_disable, "arc_name <arc_name> "                        \
20686   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
20687 _(feature_gso_enable_disable, "<intfc> | sw_if_index <nn> "             \
20688   "[enable | disable] ")                                                \
20689 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
20690 "[disable]")                                                            \
20691 _(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> "       \
20692   "mac <mac-address> [del]")                                            \
20693 _(l2_xconnect_dump, "")                                                 \
20694 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
20695 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
20696 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
20697 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
20698 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
20699 _(sock_init_shm, "size <nnn>")                                          \
20700 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
20701 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
20702   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
20703 _(session_rules_dump, "")                                               \
20704 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
20705 _(output_acl_set_interface,                                             \
20706   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20707   "  [l2-table <nn>] [del]")                                            \
20708 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
20709
20710 /* List of command functions, CLI names map directly to functions */
20711 #define foreach_cli_function                                    \
20712 _(comment, "usage: comment <ignore-rest-of-line>")              \
20713 _(dump_interface_table, "usage: dump_interface_table")          \
20714 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
20715 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
20716 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
20717 _(dump_macro_table, "usage: dump_macro_table ")                 \
20718 _(dump_node_table, "usage: dump_node_table")                    \
20719 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
20720 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
20721 _(elog_disable, "usage: elog_disable")                          \
20722 _(elog_enable, "usage: elog_enable")                            \
20723 _(elog_save, "usage: elog_save <filename>")                     \
20724 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
20725 _(echo, "usage: echo <message>")                                \
20726 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
20727 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
20728 _(help, "usage: help")                                          \
20729 _(q, "usage: quit")                                             \
20730 _(quit, "usage: quit")                                          \
20731 _(search_node_table, "usage: search_node_table <name>...")      \
20732 _(set, "usage: set <variable-name> <value>")                    \
20733 _(script, "usage: script <file-name>")                          \
20734 _(statseg, "usage: statseg")                                    \
20735 _(unset, "usage: unset <variable-name>")
20736
20737 #define _(N,n)                                  \
20738     static void vl_api_##n##_t_handler_uni      \
20739     (vl_api_##n##_t * mp)                       \
20740     {                                           \
20741         vat_main_t * vam = &vat_main;           \
20742         if (vam->json_output) {                 \
20743             vl_api_##n##_t_handler_json(mp);    \
20744         } else {                                \
20745             vl_api_##n##_t_handler(mp);         \
20746         }                                       \
20747     }
20748 foreach_vpe_api_reply_msg;
20749 #if VPP_API_TEST_BUILTIN == 0
20750 foreach_standalone_reply_msg;
20751 #endif
20752 #undef _
20753
20754 void
20755 vat_api_hookup (vat_main_t * vam)
20756 {
20757 #define _(N,n)                                                  \
20758     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
20759                            vl_api_##n##_t_handler_uni,          \
20760                            vl_noop_handler,                     \
20761                            vl_api_##n##_t_endian,               \
20762                            vl_api_##n##_t_print,                \
20763                            sizeof(vl_api_##n##_t), 1);
20764   foreach_vpe_api_reply_msg;
20765 #if VPP_API_TEST_BUILTIN == 0
20766   foreach_standalone_reply_msg;
20767 #endif
20768 #undef _
20769
20770 #if (VPP_API_TEST_BUILTIN==0)
20771   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
20772
20773   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
20774
20775   vam->function_by_name = hash_create_string (0, sizeof (uword));
20776
20777   vam->help_by_name = hash_create_string (0, sizeof (uword));
20778 #endif
20779
20780   /* API messages we can send */
20781 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
20782   foreach_vpe_api_msg;
20783 #undef _
20784
20785   /* Help strings */
20786 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
20787   foreach_vpe_api_msg;
20788 #undef _
20789
20790   /* CLI functions */
20791 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
20792   foreach_cli_function;
20793 #undef _
20794
20795   /* Help strings */
20796 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
20797   foreach_cli_function;
20798 #undef _
20799 }
20800
20801 #if VPP_API_TEST_BUILTIN
20802 static clib_error_t *
20803 vat_api_hookup_shim (vlib_main_t * vm)
20804 {
20805   vat_api_hookup (&vat_main);
20806   return 0;
20807 }
20808
20809 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
20810 #endif
20811
20812 /*
20813  * fd.io coding-style-patch-verification: ON
20814  *
20815  * Local Variables:
20816  * eval: (c-set-style "gnu")
20817  * End:
20818  */