dhcp: API cleanup
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <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/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/geneve/geneve.h>
33 #include <vnet/gre/gre.h>
34 #include <vnet/vxlan-gpe/vxlan_gpe.h>
35 #include <vnet/lisp-gpe/lisp_gpe.h>
36
37 #include <vpp/api/vpe_msg_enum.h>
38 #include <vnet/l2/l2_classify.h>
39 #include <vnet/l2/l2_vtr.h>
40 #include <vnet/classify/in_out_acl.h>
41 #include <vnet/classify/policer_classify.h>
42 #include <vnet/classify/flow_classify.h>
43 #include <vnet/mpls/mpls.h>
44 #include <vnet/ipsec/ipsec.h>
45 #include <inttypes.h>
46 #include <vnet/cop/cop.h>
47 #include <vnet/ip/ip6_hop_by_hop.h>
48 #include <vnet/ip/ip_source_and_port_range_check.h>
49 #include <vnet/policer/xlate.h>
50 #include <vnet/span/span.h>
51 #include <vnet/policer/policer.h>
52 #include <vnet/policer/police.h>
53 #include <vnet/mfib/mfib_types.h>
54 #include <vnet/dhcp/dhcp_proxy.h>
55 #include <vnet/bonding/node.h>
56 #include <vnet/qos/qos_types.h>
57 #include <vnet/ethernet/ethernet_types_api.h>
58 #include <vnet/ip/ip_types_api.h>
59 #include "vat/json_format.h"
60 #include <vnet/ip/ip_types_api.h>
61 #include <vnet/ethernet/ethernet_types_api.h>
62
63 #include <inttypes.h>
64 #include <sys/stat.h>
65
66 #define vl_typedefs             /* define message structures */
67 #include <vpp/api/vpe_all_api_h.h>
68 #undef vl_typedefs
69
70 /* declare message handlers for each api */
71
72 #define vl_endianfun            /* define message structures */
73 #include <vpp/api/vpe_all_api_h.h>
74 #undef vl_endianfun
75
76 /* instantiate all the print functions we know about */
77 #if VPP_API_TEST_BUILTIN == 0
78 #define vl_print(handle, ...)
79 #else
80 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
81 #endif
82 #define vl_printfun
83 #include <vpp/api/vpe_all_api_h.h>
84 #undef vl_printfun
85
86 #define __plugin_msg_base 0
87 #include <vlibapi/vat_helper_macros.h>
88
89 #include <vnet/format_fns.h>
90
91 void vl_api_set_elog_main (elog_main_t * m);
92 int vl_api_set_elog_trace_api_messages (int enable);
93
94 #if VPP_API_TEST_BUILTIN == 0
95 #include <netdb.h>
96
97 u32
98 vl (void *p)
99 {
100   return vec_len (p);
101 }
102
103 int
104 vat_socket_connect (vat_main_t * vam)
105 {
106   int rv;
107   vam->socket_client_main = &socket_client_main;
108   if ((rv = vl_socket_client_connect ((char *) vam->socket_name,
109                                       "vpp_api_test",
110                                       0 /* default socket rx, tx buffer */ )))
111     return rv;
112   /* vpp expects the client index in network order */
113   vam->my_client_index = htonl (socket_client_main.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 IP6 address. */
269 uword
270 unformat_ip6_address (unformat_input_t * input, va_list * args)
271 {
272   ip6_address_t *result = va_arg (*args, ip6_address_t *);
273   u16 hex_quads[8];
274   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
275   uword c, n_colon, double_colon_index;
276
277   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
278   double_colon_index = ARRAY_LEN (hex_quads);
279   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
280     {
281       hex_digit = 16;
282       if (c >= '0' && c <= '9')
283         hex_digit = c - '0';
284       else if (c >= 'a' && c <= 'f')
285         hex_digit = c + 10 - 'a';
286       else if (c >= 'A' && c <= 'F')
287         hex_digit = c + 10 - 'A';
288       else if (c == ':' && n_colon < 2)
289         n_colon++;
290       else
291         {
292           unformat_put_input (input);
293           break;
294         }
295
296       /* Too many hex quads. */
297       if (n_hex_quads >= ARRAY_LEN (hex_quads))
298         return 0;
299
300       if (hex_digit < 16)
301         {
302           hex_quad = (hex_quad << 4) | hex_digit;
303
304           /* Hex quad must fit in 16 bits. */
305           if (n_hex_digits >= 4)
306             return 0;
307
308           n_colon = 0;
309           n_hex_digits++;
310         }
311
312       /* Save position of :: */
313       if (n_colon == 2)
314         {
315           /* More than one :: ? */
316           if (double_colon_index < ARRAY_LEN (hex_quads))
317             return 0;
318           double_colon_index = n_hex_quads;
319         }
320
321       if (n_colon > 0 && n_hex_digits > 0)
322         {
323           hex_quads[n_hex_quads++] = hex_quad;
324           hex_quad = 0;
325           n_hex_digits = 0;
326         }
327     }
328
329   if (n_hex_digits > 0)
330     hex_quads[n_hex_quads++] = hex_quad;
331
332   {
333     word i;
334
335     /* Expand :: to appropriate number of zero hex quads. */
336     if (double_colon_index < ARRAY_LEN (hex_quads))
337       {
338         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
339
340         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
341           hex_quads[n_zero + i] = hex_quads[i];
342
343         for (i = 0; i < n_zero; i++)
344           hex_quads[double_colon_index + i] = 0;
345
346         n_hex_quads = ARRAY_LEN (hex_quads);
347       }
348
349     /* Too few hex quads given. */
350     if (n_hex_quads < ARRAY_LEN (hex_quads))
351       return 0;
352
353     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
354       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
355
356     return 1;
357   }
358 }
359
360 uword
361 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
362 {
363   u32 *r = va_arg (*args, u32 *);
364
365   if (0);
366 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
367   foreach_ipsec_policy_action
368 #undef _
369     else
370     return 0;
371   return 1;
372 }
373
374 u8 *
375 format_ipsec_crypto_alg (u8 * s, va_list * args)
376 {
377   u32 i = va_arg (*args, u32);
378   u8 *t = 0;
379
380   switch (i)
381     {
382 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
383       foreach_ipsec_crypto_alg
384 #undef _
385     default:
386       return format (s, "unknown");
387     }
388   return format (s, "%s", t);
389 }
390
391 u8 *
392 format_ipsec_integ_alg (u8 * s, va_list * args)
393 {
394   u32 i = va_arg (*args, u32);
395   u8 *t = 0;
396
397   switch (i)
398     {
399 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
400       foreach_ipsec_integ_alg
401 #undef _
402     default:
403       return format (s, "unknown");
404     }
405   return format (s, "%s", t);
406 }
407
408 #else /* VPP_API_TEST_BUILTIN == 1 */
409 static uword
410 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
411 {
412   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
413   vnet_main_t *vnm = vnet_get_main ();
414   u32 *result = va_arg (*args, u32 *);
415
416   return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
417 }
418
419 static uword
420 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
421 {
422   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
423   vnet_main_t *vnm = vnet_get_main ();
424   u32 *result = va_arg (*args, u32 *);
425
426   return unformat (input, "%U", unformat_vnet_hw_interface, vnm, result);
427 }
428
429 #endif /* VPP_API_TEST_BUILTIN */
430
431 uword
432 unformat_ipsec_api_crypto_alg (unformat_input_t * input, va_list * args)
433 {
434   u32 *r = va_arg (*args, u32 *);
435
436   if (0);
437 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_CRYPTO_ALG_##f;
438   foreach_ipsec_crypto_alg
439 #undef _
440     else
441     return 0;
442   return 1;
443 }
444
445 uword
446 unformat_ipsec_api_integ_alg (unformat_input_t * input, va_list * args)
447 {
448   u32 *r = va_arg (*args, u32 *);
449
450   if (0);
451 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_INTEG_ALG_##f;
452   foreach_ipsec_integ_alg
453 #undef _
454     else
455     return 0;
456   return 1;
457 }
458
459 static uword
460 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
461 {
462   u8 *r = va_arg (*args, u8 *);
463
464   if (unformat (input, "kbps"))
465     *r = SSE2_QOS_RATE_KBPS;
466   else if (unformat (input, "pps"))
467     *r = SSE2_QOS_RATE_PPS;
468   else
469     return 0;
470   return 1;
471 }
472
473 static uword
474 unformat_policer_round_type (unformat_input_t * input, va_list * args)
475 {
476   u8 *r = va_arg (*args, u8 *);
477
478   if (unformat (input, "closest"))
479     *r = SSE2_QOS_ROUND_TO_CLOSEST;
480   else if (unformat (input, "up"))
481     *r = SSE2_QOS_ROUND_TO_UP;
482   else if (unformat (input, "down"))
483     *r = SSE2_QOS_ROUND_TO_DOWN;
484   else
485     return 0;
486   return 1;
487 }
488
489 static uword
490 unformat_policer_type (unformat_input_t * input, va_list * args)
491 {
492   u8 *r = va_arg (*args, u8 *);
493
494   if (unformat (input, "1r2c"))
495     *r = SSE2_QOS_POLICER_TYPE_1R2C;
496   else if (unformat (input, "1r3c"))
497     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
498   else if (unformat (input, "2r3c-2698"))
499     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
500   else if (unformat (input, "2r3c-4115"))
501     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
502   else if (unformat (input, "2r3c-mef5cf1"))
503     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
504   else
505     return 0;
506   return 1;
507 }
508
509 static uword
510 unformat_dscp (unformat_input_t * input, va_list * va)
511 {
512   u8 *r = va_arg (*va, u8 *);
513
514   if (0);
515 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
516   foreach_vnet_dscp
517 #undef _
518     else
519     return 0;
520   return 1;
521 }
522
523 static uword
524 unformat_policer_action_type (unformat_input_t * input, va_list * va)
525 {
526   sse2_qos_pol_action_params_st *a
527     = va_arg (*va, sse2_qos_pol_action_params_st *);
528
529   if (unformat (input, "drop"))
530     a->action_type = SSE2_QOS_ACTION_DROP;
531   else if (unformat (input, "transmit"))
532     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
533   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
534     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
535   else
536     return 0;
537   return 1;
538 }
539
540 static uword
541 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
542 {
543   u32 *r = va_arg (*va, u32 *);
544   u32 tid;
545
546   if (unformat (input, "ip4"))
547     tid = POLICER_CLASSIFY_TABLE_IP4;
548   else if (unformat (input, "ip6"))
549     tid = POLICER_CLASSIFY_TABLE_IP6;
550   else if (unformat (input, "l2"))
551     tid = POLICER_CLASSIFY_TABLE_L2;
552   else
553     return 0;
554
555   *r = tid;
556   return 1;
557 }
558
559 static uword
560 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
561 {
562   u32 *r = va_arg (*va, u32 *);
563   u32 tid;
564
565   if (unformat (input, "ip4"))
566     tid = FLOW_CLASSIFY_TABLE_IP4;
567   else if (unformat (input, "ip6"))
568     tid = FLOW_CLASSIFY_TABLE_IP6;
569   else
570     return 0;
571
572   *r = tid;
573   return 1;
574 }
575
576 #if (VPP_API_TEST_BUILTIN==0)
577
578 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
579 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
580 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
581 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
582
583 uword
584 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
585 {
586   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
587   mfib_itf_attribute_t attr;
588
589   old = *iflags;
590   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
591   {
592     if (unformat (input, mfib_itf_flag_long_names[attr]))
593       *iflags |= (1 << attr);
594   }
595   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
596   {
597     if (unformat (input, mfib_itf_flag_names[attr]))
598       *iflags |= (1 << attr);
599   }
600
601   return (old == *iflags ? 0 : 1);
602 }
603
604 uword
605 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
606 {
607   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
608   mfib_entry_attribute_t attr;
609
610   old = *eflags;
611   FOR_EACH_MFIB_ATTRIBUTE (attr)
612   {
613     if (unformat (input, mfib_flag_long_names[attr]))
614       *eflags |= (1 << attr);
615   }
616   FOR_EACH_MFIB_ATTRIBUTE (attr)
617   {
618     if (unformat (input, mfib_flag_names[attr]))
619       *eflags |= (1 << attr);
620   }
621
622   return (old == *eflags ? 0 : 1);
623 }
624
625 u8 *
626 format_ip4_address (u8 * s, va_list * args)
627 {
628   u8 *a = va_arg (*args, u8 *);
629   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
630 }
631
632 u8 *
633 format_ip6_address (u8 * s, va_list * args)
634 {
635   ip6_address_t *a = va_arg (*args, ip6_address_t *);
636   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
637
638   i_max_n_zero = ARRAY_LEN (a->as_u16);
639   max_n_zeros = 0;
640   i_first_zero = i_max_n_zero;
641   n_zeros = 0;
642   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
643     {
644       u32 is_zero = a->as_u16[i] == 0;
645       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
646         {
647           i_first_zero = i;
648           n_zeros = 0;
649         }
650       n_zeros += is_zero;
651       if ((!is_zero && n_zeros > max_n_zeros)
652           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
653         {
654           i_max_n_zero = i_first_zero;
655           max_n_zeros = n_zeros;
656           i_first_zero = ARRAY_LEN (a->as_u16);
657           n_zeros = 0;
658         }
659     }
660
661   last_double_colon = 0;
662   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
663     {
664       if (i == i_max_n_zero && max_n_zeros > 1)
665         {
666           s = format (s, "::");
667           i += max_n_zeros - 1;
668           last_double_colon = 1;
669         }
670       else
671         {
672           s = format (s, "%s%x",
673                       (last_double_colon || i == 0) ? "" : ":",
674                       clib_net_to_host_u16 (a->as_u16[i]));
675           last_double_colon = 0;
676         }
677     }
678
679   return s;
680 }
681
682 /* Format an IP46 address. */
683 u8 *
684 format_ip46_address (u8 * s, va_list * args)
685 {
686   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
687   ip46_type_t type = va_arg (*args, ip46_type_t);
688   int is_ip4 = 1;
689
690   switch (type)
691     {
692     case IP46_TYPE_ANY:
693       is_ip4 = ip46_address_is_ip4 (ip46);
694       break;
695     case IP46_TYPE_IP4:
696       is_ip4 = 1;
697       break;
698     case IP46_TYPE_IP6:
699       is_ip4 = 0;
700       break;
701     }
702
703   return is_ip4 ?
704     format (s, "%U", format_ip4_address, &ip46->ip4) :
705     format (s, "%U", format_ip6_address, &ip46->ip6);
706 }
707
708 u8 *
709 format_ethernet_address (u8 * s, va_list * args)
710 {
711   u8 *a = va_arg (*args, u8 *);
712
713   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
714                  a[0], a[1], a[2], a[3], a[4], a[5]);
715 }
716 #endif
717
718 static void
719 increment_v4_address (vl_api_ip4_address_t * i)
720 {
721   ip4_address_t *a = (ip4_address_t *) i;
722   u32 v;
723
724   v = ntohl (a->as_u32) + 1;
725   a->as_u32 = ntohl (v);
726 }
727
728 static void
729 increment_v6_address (vl_api_ip6_address_t * i)
730 {
731   ip6_address_t *a = (ip6_address_t *) i;
732   u64 v0, v1;
733
734   v0 = clib_net_to_host_u64 (a->as_u64[0]);
735   v1 = clib_net_to_host_u64 (a->as_u64[1]);
736
737   v1 += 1;
738   if (v1 == 0)
739     v0 += 1;
740   a->as_u64[0] = clib_net_to_host_u64 (v0);
741   a->as_u64[1] = clib_net_to_host_u64 (v1);
742 }
743
744 static void
745 increment_address (vl_api_address_t * a)
746 {
747   if (clib_net_to_host_u32 (a->af) == ADDRESS_IP4)
748     increment_v4_address (&a->un.ip4);
749   else if (clib_net_to_host_u32 (a->af) == ADDRESS_IP6)
750     increment_v6_address (&a->un.ip6);
751 }
752
753 static void
754 set_ip4_address (vl_api_address_t * a, u32 v)
755 {
756   if (a->af == ADDRESS_IP4)
757     {
758       ip4_address_t *i = (ip4_address_t *) & a->un.ip4;
759       i->as_u32 = v;
760     }
761 }
762
763 static void
764 increment_mac_address (u8 * mac)
765 {
766   u64 tmp = *((u64 *) mac);
767   tmp = clib_net_to_host_u64 (tmp);
768   tmp += 1 << 16;               /* skip unused (least significant) octets */
769   tmp = clib_host_to_net_u64 (tmp);
770
771   clib_memcpy (mac, &tmp, 6);
772 }
773
774 static void
775 vat_json_object_add_address (vat_json_node_t * node,
776                              const char *str, const vl_api_address_t * addr)
777 {
778   if (ADDRESS_IP6 == addr->af)
779     {
780       struct in6_addr ip6;
781
782       clib_memcpy (&ip6, &addr->un.ip6, sizeof (ip6));
783       vat_json_object_add_ip6 (node, str, ip6);
784     }
785   else
786     {
787       struct in_addr ip4;
788
789       clib_memcpy (&ip4, &addr->un.ip4, sizeof (ip4));
790       vat_json_object_add_ip4 (node, str, ip4);
791     }
792 }
793
794 static void
795 vat_json_object_add_prefix (vat_json_node_t * node,
796                             const vl_api_prefix_t * prefix)
797 {
798   vat_json_object_add_uint (node, "len", prefix->len);
799   vat_json_object_add_address (node, "address", &prefix->address);
800 }
801
802 static void vl_api_create_loopback_reply_t_handler
803   (vl_api_create_loopback_reply_t * mp)
804 {
805   vat_main_t *vam = &vat_main;
806   i32 retval = ntohl (mp->retval);
807
808   vam->retval = retval;
809   vam->regenerate_interface_table = 1;
810   vam->sw_if_index = ntohl (mp->sw_if_index);
811   vam->result_ready = 1;
812 }
813
814 static void vl_api_create_loopback_reply_t_handler_json
815   (vl_api_create_loopback_reply_t * mp)
816 {
817   vat_main_t *vam = &vat_main;
818   vat_json_node_t node;
819
820   vat_json_init_object (&node);
821   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
822   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
823
824   vat_json_print (vam->ofp, &node);
825   vat_json_free (&node);
826   vam->retval = ntohl (mp->retval);
827   vam->result_ready = 1;
828 }
829
830 static void vl_api_create_loopback_instance_reply_t_handler
831   (vl_api_create_loopback_instance_reply_t * mp)
832 {
833   vat_main_t *vam = &vat_main;
834   i32 retval = ntohl (mp->retval);
835
836   vam->retval = retval;
837   vam->regenerate_interface_table = 1;
838   vam->sw_if_index = ntohl (mp->sw_if_index);
839   vam->result_ready = 1;
840 }
841
842 static void vl_api_create_loopback_instance_reply_t_handler_json
843   (vl_api_create_loopback_instance_reply_t * mp)
844 {
845   vat_main_t *vam = &vat_main;
846   vat_json_node_t node;
847
848   vat_json_init_object (&node);
849   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
850   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
851
852   vat_json_print (vam->ofp, &node);
853   vat_json_free (&node);
854   vam->retval = ntohl (mp->retval);
855   vam->result_ready = 1;
856 }
857
858 static void vl_api_af_packet_create_reply_t_handler
859   (vl_api_af_packet_create_reply_t * mp)
860 {
861   vat_main_t *vam = &vat_main;
862   i32 retval = ntohl (mp->retval);
863
864   vam->retval = retval;
865   vam->regenerate_interface_table = 1;
866   vam->sw_if_index = ntohl (mp->sw_if_index);
867   vam->result_ready = 1;
868 }
869
870 static void vl_api_af_packet_create_reply_t_handler_json
871   (vl_api_af_packet_create_reply_t * mp)
872 {
873   vat_main_t *vam = &vat_main;
874   vat_json_node_t node;
875
876   vat_json_init_object (&node);
877   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
878   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
879
880   vat_json_print (vam->ofp, &node);
881   vat_json_free (&node);
882
883   vam->retval = ntohl (mp->retval);
884   vam->result_ready = 1;
885 }
886
887 static void vl_api_create_vlan_subif_reply_t_handler
888   (vl_api_create_vlan_subif_reply_t * mp)
889 {
890   vat_main_t *vam = &vat_main;
891   i32 retval = ntohl (mp->retval);
892
893   vam->retval = retval;
894   vam->regenerate_interface_table = 1;
895   vam->sw_if_index = ntohl (mp->sw_if_index);
896   vam->result_ready = 1;
897 }
898
899 static void vl_api_create_vlan_subif_reply_t_handler_json
900   (vl_api_create_vlan_subif_reply_t * mp)
901 {
902   vat_main_t *vam = &vat_main;
903   vat_json_node_t node;
904
905   vat_json_init_object (&node);
906   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
907   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
908
909   vat_json_print (vam->ofp, &node);
910   vat_json_free (&node);
911
912   vam->retval = ntohl (mp->retval);
913   vam->result_ready = 1;
914 }
915
916 static void vl_api_create_subif_reply_t_handler
917   (vl_api_create_subif_reply_t * mp)
918 {
919   vat_main_t *vam = &vat_main;
920   i32 retval = ntohl (mp->retval);
921
922   vam->retval = retval;
923   vam->regenerate_interface_table = 1;
924   vam->sw_if_index = ntohl (mp->sw_if_index);
925   vam->result_ready = 1;
926 }
927
928 static void vl_api_create_subif_reply_t_handler_json
929   (vl_api_create_subif_reply_t * mp)
930 {
931   vat_main_t *vam = &vat_main;
932   vat_json_node_t node;
933
934   vat_json_init_object (&node);
935   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
936   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
937
938   vat_json_print (vam->ofp, &node);
939   vat_json_free (&node);
940
941   vam->retval = ntohl (mp->retval);
942   vam->result_ready = 1;
943 }
944
945 static void vl_api_interface_name_renumber_reply_t_handler
946   (vl_api_interface_name_renumber_reply_t * mp)
947 {
948   vat_main_t *vam = &vat_main;
949   i32 retval = ntohl (mp->retval);
950
951   vam->retval = retval;
952   vam->regenerate_interface_table = 1;
953   vam->result_ready = 1;
954 }
955
956 static void vl_api_interface_name_renumber_reply_t_handler_json
957   (vl_api_interface_name_renumber_reply_t * mp)
958 {
959   vat_main_t *vam = &vat_main;
960   vat_json_node_t node;
961
962   vat_json_init_object (&node);
963   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
964
965   vat_json_print (vam->ofp, &node);
966   vat_json_free (&node);
967
968   vam->retval = ntohl (mp->retval);
969   vam->result_ready = 1;
970 }
971
972 /*
973  * Special-case: build the interface table, maintain
974  * the next loopback sw_if_index vbl.
975  */
976 static void vl_api_sw_interface_details_t_handler
977   (vl_api_sw_interface_details_t * mp)
978 {
979   vat_main_t *vam = &vat_main;
980   u8 *s = format (0, "%s%c", mp->interface_name, 0);
981
982   hash_set_mem (vam->sw_if_index_by_interface_name, s,
983                 ntohl (mp->sw_if_index));
984
985   /* In sub interface case, fill the sub interface table entry */
986   if (mp->sw_if_index != mp->sup_sw_if_index)
987     {
988       sw_interface_subif_t *sub = NULL;
989
990       vec_add2 (vam->sw_if_subif_table, sub, 1);
991
992       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
993       strncpy ((char *) sub->interface_name, (char *) s,
994                vec_len (sub->interface_name));
995       sub->sw_if_index = ntohl (mp->sw_if_index);
996       sub->sub_id = ntohl (mp->sub_id);
997
998       sub->raw_flags = ntohl (mp->sub_if_flags & SUB_IF_API_FLAG_MASK_VNET);
999
1000       sub->sub_number_of_tags = mp->sub_number_of_tags;
1001       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
1002       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
1003
1004       /* vlan tag rewrite */
1005       sub->vtr_op = ntohl (mp->vtr_op);
1006       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
1007       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
1008       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
1009     }
1010 }
1011
1012 static void vl_api_sw_interface_details_t_handler_json
1013   (vl_api_sw_interface_details_t * mp)
1014 {
1015   vat_main_t *vam = &vat_main;
1016   vat_json_node_t *node = NULL;
1017
1018   if (VAT_JSON_ARRAY != vam->json_tree.type)
1019     {
1020       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1021       vat_json_init_array (&vam->json_tree);
1022     }
1023   node = vat_json_array_add (&vam->json_tree);
1024
1025   vat_json_init_object (node);
1026   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1027   vat_json_object_add_uint (node, "sup_sw_if_index",
1028                             ntohl (mp->sup_sw_if_index));
1029   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
1030                              sizeof (mp->l2_address));
1031   vat_json_object_add_string_copy (node, "interface_name",
1032                                    mp->interface_name);
1033   vat_json_object_add_uint (node, "flags", mp->flags);
1034   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
1035   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
1036   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
1037   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
1038   vat_json_object_add_uint (node, "sub_number_of_tags",
1039                             mp->sub_number_of_tags);
1040   vat_json_object_add_uint (node, "sub_outer_vlan_id",
1041                             ntohs (mp->sub_outer_vlan_id));
1042   vat_json_object_add_uint (node, "sub_inner_vlan_id",
1043                             ntohs (mp->sub_inner_vlan_id));
1044   vat_json_object_add_uint (node, "sub_if_flags", ntohl (mp->sub_if_flags));
1045   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1046   vat_json_object_add_uint (node, "vtr_push_dot1q",
1047                             ntohl (mp->vtr_push_dot1q));
1048   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1049   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1050   if (ntohl (mp->sub_if_flags) & SUB_IF_API_FLAG_DOT1AH)
1051     {
1052       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1053                                        format (0, "%U",
1054                                                format_ethernet_address,
1055                                                &mp->b_dmac));
1056       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1057                                        format (0, "%U",
1058                                                format_ethernet_address,
1059                                                &mp->b_smac));
1060       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1061       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1062     }
1063 }
1064
1065 #if VPP_API_TEST_BUILTIN == 0
1066 static void vl_api_sw_interface_event_t_handler
1067   (vl_api_sw_interface_event_t * mp)
1068 {
1069   vat_main_t *vam = &vat_main;
1070   if (vam->interface_event_display)
1071     errmsg ("interface flags: sw_if_index %d %s %s",
1072             ntohl (mp->sw_if_index),
1073             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_ADMIN_UP) ?
1074             "admin-up" : "admin-down",
1075             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_LINK_UP) ?
1076             "link-up" : "link-down");
1077 }
1078 #endif
1079
1080 __clib_unused static void
1081 vl_api_sw_interface_event_t_handler_json (vl_api_sw_interface_event_t * mp)
1082 {
1083   /* JSON output not supported */
1084 }
1085
1086 static void
1087 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1088 {
1089   vat_main_t *vam = &vat_main;
1090   i32 retval = ntohl (mp->retval);
1091
1092   vam->retval = retval;
1093   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1094   vam->result_ready = 1;
1095 }
1096
1097 static void
1098 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1099 {
1100   vat_main_t *vam = &vat_main;
1101   vat_json_node_t node;
1102   api_main_t *am = &api_main;
1103   void *oldheap;
1104   u8 *reply;
1105
1106   vat_json_init_object (&node);
1107   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1108   vat_json_object_add_uint (&node, "reply_in_shmem",
1109                             ntohl (mp->reply_in_shmem));
1110   /* Toss the shared-memory original... */
1111   pthread_mutex_lock (&am->vlib_rp->mutex);
1112   oldheap = svm_push_data_heap (am->vlib_rp);
1113
1114   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1115   vec_free (reply);
1116
1117   svm_pop_heap (oldheap);
1118   pthread_mutex_unlock (&am->vlib_rp->mutex);
1119
1120   vat_json_print (vam->ofp, &node);
1121   vat_json_free (&node);
1122
1123   vam->retval = ntohl (mp->retval);
1124   vam->result_ready = 1;
1125 }
1126
1127 static void
1128 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1129 {
1130   vat_main_t *vam = &vat_main;
1131   i32 retval = ntohl (mp->retval);
1132   u32 length = vl_api_string_len (&mp->reply);
1133
1134   vec_reset_length (vam->cmd_reply);
1135
1136   vam->retval = retval;
1137   if (retval == 0)
1138     {
1139       vec_validate (vam->cmd_reply, length);
1140       clib_memcpy ((char *) (vam->cmd_reply),
1141                    vl_api_from_api_string (&mp->reply), length);
1142       vam->cmd_reply[length] = 0;
1143     }
1144   vam->result_ready = 1;
1145 }
1146
1147 static void
1148 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1149 {
1150   vat_main_t *vam = &vat_main;
1151   vat_json_node_t node;
1152
1153   vec_reset_length (vam->cmd_reply);
1154
1155   vat_json_init_object (&node);
1156   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1157   vat_json_object_add_string_copy (&node, "reply",
1158                                    vl_api_from_api_string (&mp->reply));
1159
1160   vat_json_print (vam->ofp, &node);
1161   vat_json_free (&node);
1162
1163   vam->retval = ntohl (mp->retval);
1164   vam->result_ready = 1;
1165 }
1166
1167 static void vl_api_classify_add_del_table_reply_t_handler
1168   (vl_api_classify_add_del_table_reply_t * mp)
1169 {
1170   vat_main_t *vam = &vat_main;
1171   i32 retval = ntohl (mp->retval);
1172   if (vam->async_mode)
1173     {
1174       vam->async_errors += (retval < 0);
1175     }
1176   else
1177     {
1178       vam->retval = retval;
1179       if (retval == 0 &&
1180           ((mp->new_table_index != 0xFFFFFFFF) ||
1181            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1182            (mp->match_n_vectors != 0xFFFFFFFF)))
1183         /*
1184          * Note: this is just barely thread-safe, depends on
1185          * the main thread spinning waiting for an answer...
1186          */
1187         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1188                 ntohl (mp->new_table_index),
1189                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1190       vam->result_ready = 1;
1191     }
1192 }
1193
1194 static void vl_api_classify_add_del_table_reply_t_handler_json
1195   (vl_api_classify_add_del_table_reply_t * mp)
1196 {
1197   vat_main_t *vam = &vat_main;
1198   vat_json_node_t node;
1199
1200   vat_json_init_object (&node);
1201   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1202   vat_json_object_add_uint (&node, "new_table_index",
1203                             ntohl (mp->new_table_index));
1204   vat_json_object_add_uint (&node, "skip_n_vectors",
1205                             ntohl (mp->skip_n_vectors));
1206   vat_json_object_add_uint (&node, "match_n_vectors",
1207                             ntohl (mp->match_n_vectors));
1208
1209   vat_json_print (vam->ofp, &node);
1210   vat_json_free (&node);
1211
1212   vam->retval = ntohl (mp->retval);
1213   vam->result_ready = 1;
1214 }
1215
1216 static void vl_api_get_node_index_reply_t_handler
1217   (vl_api_get_node_index_reply_t * mp)
1218 {
1219   vat_main_t *vam = &vat_main;
1220   i32 retval = ntohl (mp->retval);
1221   if (vam->async_mode)
1222     {
1223       vam->async_errors += (retval < 0);
1224     }
1225   else
1226     {
1227       vam->retval = retval;
1228       if (retval == 0)
1229         errmsg ("node index %d", ntohl (mp->node_index));
1230       vam->result_ready = 1;
1231     }
1232 }
1233
1234 static void vl_api_get_node_index_reply_t_handler_json
1235   (vl_api_get_node_index_reply_t * mp)
1236 {
1237   vat_main_t *vam = &vat_main;
1238   vat_json_node_t node;
1239
1240   vat_json_init_object (&node);
1241   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1242   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1243
1244   vat_json_print (vam->ofp, &node);
1245   vat_json_free (&node);
1246
1247   vam->retval = ntohl (mp->retval);
1248   vam->result_ready = 1;
1249 }
1250
1251 static void vl_api_get_next_index_reply_t_handler
1252   (vl_api_get_next_index_reply_t * mp)
1253 {
1254   vat_main_t *vam = &vat_main;
1255   i32 retval = ntohl (mp->retval);
1256   if (vam->async_mode)
1257     {
1258       vam->async_errors += (retval < 0);
1259     }
1260   else
1261     {
1262       vam->retval = retval;
1263       if (retval == 0)
1264         errmsg ("next node index %d", ntohl (mp->next_index));
1265       vam->result_ready = 1;
1266     }
1267 }
1268
1269 static void vl_api_get_next_index_reply_t_handler_json
1270   (vl_api_get_next_index_reply_t * mp)
1271 {
1272   vat_main_t *vam = &vat_main;
1273   vat_json_node_t node;
1274
1275   vat_json_init_object (&node);
1276   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1277   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1278
1279   vat_json_print (vam->ofp, &node);
1280   vat_json_free (&node);
1281
1282   vam->retval = ntohl (mp->retval);
1283   vam->result_ready = 1;
1284 }
1285
1286 static void vl_api_add_node_next_reply_t_handler
1287   (vl_api_add_node_next_reply_t * mp)
1288 {
1289   vat_main_t *vam = &vat_main;
1290   i32 retval = ntohl (mp->retval);
1291   if (vam->async_mode)
1292     {
1293       vam->async_errors += (retval < 0);
1294     }
1295   else
1296     {
1297       vam->retval = retval;
1298       if (retval == 0)
1299         errmsg ("next index %d", ntohl (mp->next_index));
1300       vam->result_ready = 1;
1301     }
1302 }
1303
1304 static void vl_api_add_node_next_reply_t_handler_json
1305   (vl_api_add_node_next_reply_t * mp)
1306 {
1307   vat_main_t *vam = &vat_main;
1308   vat_json_node_t node;
1309
1310   vat_json_init_object (&node);
1311   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1312   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1313
1314   vat_json_print (vam->ofp, &node);
1315   vat_json_free (&node);
1316
1317   vam->retval = ntohl (mp->retval);
1318   vam->result_ready = 1;
1319 }
1320
1321 static void vl_api_show_version_reply_t_handler
1322   (vl_api_show_version_reply_t * mp)
1323 {
1324   vat_main_t *vam = &vat_main;
1325   i32 retval = ntohl (mp->retval);
1326
1327   if (retval >= 0)
1328     {
1329       errmsg ("        program: %s", mp->program);
1330       errmsg ("        version: %s", mp->version);
1331       errmsg ("     build date: %s", mp->build_date);
1332       errmsg ("build directory: %s", mp->build_directory);
1333     }
1334   vam->retval = retval;
1335   vam->result_ready = 1;
1336 }
1337
1338 static void vl_api_show_version_reply_t_handler_json
1339   (vl_api_show_version_reply_t * mp)
1340 {
1341   vat_main_t *vam = &vat_main;
1342   vat_json_node_t node;
1343
1344   vat_json_init_object (&node);
1345   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1346   vat_json_object_add_string_copy (&node, "program", mp->program);
1347   vat_json_object_add_string_copy (&node, "version", mp->version);
1348   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1349   vat_json_object_add_string_copy (&node, "build_directory",
1350                                    mp->build_directory);
1351
1352   vat_json_print (vam->ofp, &node);
1353   vat_json_free (&node);
1354
1355   vam->retval = ntohl (mp->retval);
1356   vam->result_ready = 1;
1357 }
1358
1359 static void vl_api_show_threads_reply_t_handler
1360   (vl_api_show_threads_reply_t * mp)
1361 {
1362   vat_main_t *vam = &vat_main;
1363   i32 retval = ntohl (mp->retval);
1364   int i, count = 0;
1365
1366   if (retval >= 0)
1367     count = ntohl (mp->count);
1368
1369   for (i = 0; i < count; i++)
1370     print (vam->ofp,
1371            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1372            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1373            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1374            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1375            ntohl (mp->thread_data[i].cpu_socket));
1376
1377   vam->retval = retval;
1378   vam->result_ready = 1;
1379 }
1380
1381 static void vl_api_show_threads_reply_t_handler_json
1382   (vl_api_show_threads_reply_t * mp)
1383 {
1384   vat_main_t *vam = &vat_main;
1385   vat_json_node_t node;
1386   vl_api_thread_data_t *td;
1387   i32 retval = ntohl (mp->retval);
1388   int i, count = 0;
1389
1390   if (retval >= 0)
1391     count = ntohl (mp->count);
1392
1393   vat_json_init_object (&node);
1394   vat_json_object_add_int (&node, "retval", retval);
1395   vat_json_object_add_uint (&node, "count", count);
1396
1397   for (i = 0; i < count; i++)
1398     {
1399       td = &mp->thread_data[i];
1400       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1401       vat_json_object_add_string_copy (&node, "name", td->name);
1402       vat_json_object_add_string_copy (&node, "type", td->type);
1403       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1404       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1405       vat_json_object_add_int (&node, "core", ntohl (td->id));
1406       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1407     }
1408
1409   vat_json_print (vam->ofp, &node);
1410   vat_json_free (&node);
1411
1412   vam->retval = retval;
1413   vam->result_ready = 1;
1414 }
1415
1416 static int
1417 api_show_threads (vat_main_t * vam)
1418 {
1419   vl_api_show_threads_t *mp;
1420   int ret;
1421
1422   print (vam->ofp,
1423          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1424          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1425
1426   M (SHOW_THREADS, mp);
1427
1428   S (mp);
1429   W (ret);
1430   return ret;
1431 }
1432
1433 static void
1434 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1435 {
1436   u32 sw_if_index = ntohl (mp->sw_if_index);
1437   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1438           mp->mac_ip ? "mac/ip binding" : "address resolution",
1439           ntohl (mp->pid), format_ip4_address, mp->ip,
1440           format_vl_api_mac_address, &mp->mac, sw_if_index);
1441 }
1442
1443 static void
1444 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1445 {
1446   /* JSON output not supported */
1447 }
1448
1449 static void
1450 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1451 {
1452   u32 sw_if_index = ntohl (mp->sw_if_index);
1453   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1454           mp->mac_ip ? "mac/ip binding" : "address resolution",
1455           ntohl (mp->pid), format_vl_api_ip6_address, mp->ip,
1456           format_vl_api_mac_address, mp->mac, sw_if_index);
1457 }
1458
1459 static void
1460 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1461 {
1462   /* JSON output not supported */
1463 }
1464
1465 static void
1466 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1467 {
1468   u32 n_macs = ntohl (mp->n_macs);
1469   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1470           ntohl (mp->pid), mp->client_index, n_macs);
1471   int i;
1472   for (i = 0; i < n_macs; i++)
1473     {
1474       vl_api_mac_entry_t *mac = &mp->mac[i];
1475       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1476               i + 1, ntohl (mac->sw_if_index),
1477               format_ethernet_address, mac->mac_addr, mac->action);
1478       if (i == 1000)
1479         break;
1480     }
1481 }
1482
1483 static void
1484 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1485 {
1486   /* JSON output not supported */
1487 }
1488
1489 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1490 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1491
1492 /*
1493  * Special-case: build the bridge domain table, maintain
1494  * the next bd id vbl.
1495  */
1496 static void vl_api_bridge_domain_details_t_handler
1497   (vl_api_bridge_domain_details_t * mp)
1498 {
1499   vat_main_t *vam = &vat_main;
1500   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1501   int i;
1502
1503   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1504          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1505
1506   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1507          ntohl (mp->bd_id), mp->learn, mp->forward,
1508          mp->flood, ntohl (mp->bvi_sw_if_index),
1509          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1510
1511   if (n_sw_ifs)
1512     {
1513       vl_api_bridge_domain_sw_if_t *sw_ifs;
1514       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1515              "Interface Name");
1516
1517       sw_ifs = mp->sw_if_details;
1518       for (i = 0; i < n_sw_ifs; i++)
1519         {
1520           u8 *sw_if_name = 0;
1521           u32 sw_if_index;
1522           hash_pair_t *p;
1523
1524           sw_if_index = ntohl (sw_ifs->sw_if_index);
1525
1526           /* *INDENT-OFF* */
1527           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1528                              ({
1529                                if ((u32) p->value[0] == sw_if_index)
1530                                  {
1531                                    sw_if_name = (u8 *)(p->key);
1532                                    break;
1533                                  }
1534                              }));
1535           /* *INDENT-ON* */
1536           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1537                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1538                  "sw_if_index not found!");
1539
1540           sw_ifs++;
1541         }
1542     }
1543 }
1544
1545 static void vl_api_bridge_domain_details_t_handler_json
1546   (vl_api_bridge_domain_details_t * mp)
1547 {
1548   vat_main_t *vam = &vat_main;
1549   vat_json_node_t *node, *array = NULL;
1550   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1551
1552   if (VAT_JSON_ARRAY != vam->json_tree.type)
1553     {
1554       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1555       vat_json_init_array (&vam->json_tree);
1556     }
1557   node = vat_json_array_add (&vam->json_tree);
1558
1559   vat_json_init_object (node);
1560   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1561   vat_json_object_add_uint (node, "flood", mp->flood);
1562   vat_json_object_add_uint (node, "forward", mp->forward);
1563   vat_json_object_add_uint (node, "learn", mp->learn);
1564   vat_json_object_add_uint (node, "bvi_sw_if_index",
1565                             ntohl (mp->bvi_sw_if_index));
1566   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1567   array = vat_json_object_add (node, "sw_if");
1568   vat_json_init_array (array);
1569
1570
1571
1572   if (n_sw_ifs)
1573     {
1574       vl_api_bridge_domain_sw_if_t *sw_ifs;
1575       int i;
1576
1577       sw_ifs = mp->sw_if_details;
1578       for (i = 0; i < n_sw_ifs; i++)
1579         {
1580           node = vat_json_array_add (array);
1581           vat_json_init_object (node);
1582           vat_json_object_add_uint (node, "sw_if_index",
1583                                     ntohl (sw_ifs->sw_if_index));
1584           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1585           sw_ifs++;
1586         }
1587     }
1588 }
1589
1590 static void vl_api_control_ping_reply_t_handler
1591   (vl_api_control_ping_reply_t * mp)
1592 {
1593   vat_main_t *vam = &vat_main;
1594   i32 retval = ntohl (mp->retval);
1595   if (vam->async_mode)
1596     {
1597       vam->async_errors += (retval < 0);
1598     }
1599   else
1600     {
1601       vam->retval = retval;
1602       vam->result_ready = 1;
1603     }
1604   if (vam->socket_client_main)
1605     vam->socket_client_main->control_pings_outstanding--;
1606 }
1607
1608 static void vl_api_control_ping_reply_t_handler_json
1609   (vl_api_control_ping_reply_t * mp)
1610 {
1611   vat_main_t *vam = &vat_main;
1612   i32 retval = ntohl (mp->retval);
1613
1614   if (VAT_JSON_NONE != vam->json_tree.type)
1615     {
1616       vat_json_print (vam->ofp, &vam->json_tree);
1617       vat_json_free (&vam->json_tree);
1618       vam->json_tree.type = VAT_JSON_NONE;
1619     }
1620   else
1621     {
1622       /* just print [] */
1623       vat_json_init_array (&vam->json_tree);
1624       vat_json_print (vam->ofp, &vam->json_tree);
1625       vam->json_tree.type = VAT_JSON_NONE;
1626     }
1627
1628   vam->retval = retval;
1629   vam->result_ready = 1;
1630 }
1631
1632 static void
1633   vl_api_bridge_domain_set_mac_age_reply_t_handler
1634   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1635 {
1636   vat_main_t *vam = &vat_main;
1637   i32 retval = ntohl (mp->retval);
1638   if (vam->async_mode)
1639     {
1640       vam->async_errors += (retval < 0);
1641     }
1642   else
1643     {
1644       vam->retval = retval;
1645       vam->result_ready = 1;
1646     }
1647 }
1648
1649 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1650   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1651 {
1652   vat_main_t *vam = &vat_main;
1653   vat_json_node_t node;
1654
1655   vat_json_init_object (&node);
1656   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1657
1658   vat_json_print (vam->ofp, &node);
1659   vat_json_free (&node);
1660
1661   vam->retval = ntohl (mp->retval);
1662   vam->result_ready = 1;
1663 }
1664
1665 static void
1666 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1667 {
1668   vat_main_t *vam = &vat_main;
1669   i32 retval = ntohl (mp->retval);
1670   if (vam->async_mode)
1671     {
1672       vam->async_errors += (retval < 0);
1673     }
1674   else
1675     {
1676       vam->retval = retval;
1677       vam->result_ready = 1;
1678     }
1679 }
1680
1681 static void vl_api_l2_flags_reply_t_handler_json
1682   (vl_api_l2_flags_reply_t * mp)
1683 {
1684   vat_main_t *vam = &vat_main;
1685   vat_json_node_t node;
1686
1687   vat_json_init_object (&node);
1688   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1689   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1690                             ntohl (mp->resulting_feature_bitmap));
1691
1692   vat_json_print (vam->ofp, &node);
1693   vat_json_free (&node);
1694
1695   vam->retval = ntohl (mp->retval);
1696   vam->result_ready = 1;
1697 }
1698
1699 static void vl_api_bridge_flags_reply_t_handler
1700   (vl_api_bridge_flags_reply_t * mp)
1701 {
1702   vat_main_t *vam = &vat_main;
1703   i32 retval = ntohl (mp->retval);
1704   if (vam->async_mode)
1705     {
1706       vam->async_errors += (retval < 0);
1707     }
1708   else
1709     {
1710       vam->retval = retval;
1711       vam->result_ready = 1;
1712     }
1713 }
1714
1715 static void vl_api_bridge_flags_reply_t_handler_json
1716   (vl_api_bridge_flags_reply_t * mp)
1717 {
1718   vat_main_t *vam = &vat_main;
1719   vat_json_node_t node;
1720
1721   vat_json_init_object (&node);
1722   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1723   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1724                             ntohl (mp->resulting_feature_bitmap));
1725
1726   vat_json_print (vam->ofp, &node);
1727   vat_json_free (&node);
1728
1729   vam->retval = ntohl (mp->retval);
1730   vam->result_ready = 1;
1731 }
1732
1733 static void
1734 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1735 {
1736   vat_main_t *vam = &vat_main;
1737   i32 retval = ntohl (mp->retval);
1738   if (vam->async_mode)
1739     {
1740       vam->async_errors += (retval < 0);
1741     }
1742   else
1743     {
1744       vam->retval = retval;
1745       vam->sw_if_index = ntohl (mp->sw_if_index);
1746       vam->result_ready = 1;
1747     }
1748
1749 }
1750
1751 static void vl_api_tap_create_v2_reply_t_handler_json
1752   (vl_api_tap_create_v2_reply_t * mp)
1753 {
1754   vat_main_t *vam = &vat_main;
1755   vat_json_node_t node;
1756
1757   vat_json_init_object (&node);
1758   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1759   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1760
1761   vat_json_print (vam->ofp, &node);
1762   vat_json_free (&node);
1763
1764   vam->retval = ntohl (mp->retval);
1765   vam->result_ready = 1;
1766
1767 }
1768
1769 static void
1770 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1771 {
1772   vat_main_t *vam = &vat_main;
1773   i32 retval = ntohl (mp->retval);
1774   if (vam->async_mode)
1775     {
1776       vam->async_errors += (retval < 0);
1777     }
1778   else
1779     {
1780       vam->retval = retval;
1781       vam->result_ready = 1;
1782     }
1783 }
1784
1785 static void vl_api_tap_delete_v2_reply_t_handler_json
1786   (vl_api_tap_delete_v2_reply_t * mp)
1787 {
1788   vat_main_t *vam = &vat_main;
1789   vat_json_node_t node;
1790
1791   vat_json_init_object (&node);
1792   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1793
1794   vat_json_print (vam->ofp, &node);
1795   vat_json_free (&node);
1796
1797   vam->retval = ntohl (mp->retval);
1798   vam->result_ready = 1;
1799 }
1800
1801 static void
1802 vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1803                                           mp)
1804 {
1805   vat_main_t *vam = &vat_main;
1806   i32 retval = ntohl (mp->retval);
1807   if (vam->async_mode)
1808     {
1809       vam->async_errors += (retval < 0);
1810     }
1811   else
1812     {
1813       vam->retval = retval;
1814       vam->sw_if_index = ntohl (mp->sw_if_index);
1815       vam->result_ready = 1;
1816     }
1817 }
1818
1819 static void vl_api_virtio_pci_create_reply_t_handler_json
1820   (vl_api_virtio_pci_create_reply_t * mp)
1821 {
1822   vat_main_t *vam = &vat_main;
1823   vat_json_node_t node;
1824
1825   vat_json_init_object (&node);
1826   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1827   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1828
1829   vat_json_print (vam->ofp, &node);
1830   vat_json_free (&node);
1831
1832   vam->retval = ntohl (mp->retval);
1833   vam->result_ready = 1;
1834
1835 }
1836
1837 static void
1838 vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1839                                           mp)
1840 {
1841   vat_main_t *vam = &vat_main;
1842   i32 retval = ntohl (mp->retval);
1843   if (vam->async_mode)
1844     {
1845       vam->async_errors += (retval < 0);
1846     }
1847   else
1848     {
1849       vam->retval = retval;
1850       vam->result_ready = 1;
1851     }
1852 }
1853
1854 static void vl_api_virtio_pci_delete_reply_t_handler_json
1855   (vl_api_virtio_pci_delete_reply_t * mp)
1856 {
1857   vat_main_t *vam = &vat_main;
1858   vat_json_node_t node;
1859
1860   vat_json_init_object (&node);
1861   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1862
1863   vat_json_print (vam->ofp, &node);
1864   vat_json_free (&node);
1865
1866   vam->retval = ntohl (mp->retval);
1867   vam->result_ready = 1;
1868 }
1869
1870 static void
1871 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1872 {
1873   vat_main_t *vam = &vat_main;
1874   i32 retval = ntohl (mp->retval);
1875
1876   if (vam->async_mode)
1877     {
1878       vam->async_errors += (retval < 0);
1879     }
1880   else
1881     {
1882       vam->retval = retval;
1883       vam->sw_if_index = ntohl (mp->sw_if_index);
1884       vam->result_ready = 1;
1885     }
1886 }
1887
1888 static void vl_api_bond_create_reply_t_handler_json
1889   (vl_api_bond_create_reply_t * mp)
1890 {
1891   vat_main_t *vam = &vat_main;
1892   vat_json_node_t node;
1893
1894   vat_json_init_object (&node);
1895   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1896   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1897
1898   vat_json_print (vam->ofp, &node);
1899   vat_json_free (&node);
1900
1901   vam->retval = ntohl (mp->retval);
1902   vam->result_ready = 1;
1903 }
1904
1905 static void
1906 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1907 {
1908   vat_main_t *vam = &vat_main;
1909   i32 retval = ntohl (mp->retval);
1910
1911   if (vam->async_mode)
1912     {
1913       vam->async_errors += (retval < 0);
1914     }
1915   else
1916     {
1917       vam->retval = retval;
1918       vam->result_ready = 1;
1919     }
1920 }
1921
1922 static void vl_api_bond_delete_reply_t_handler_json
1923   (vl_api_bond_delete_reply_t * mp)
1924 {
1925   vat_main_t *vam = &vat_main;
1926   vat_json_node_t node;
1927
1928   vat_json_init_object (&node);
1929   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1930
1931   vat_json_print (vam->ofp, &node);
1932   vat_json_free (&node);
1933
1934   vam->retval = ntohl (mp->retval);
1935   vam->result_ready = 1;
1936 }
1937
1938 static void
1939 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1940 {
1941   vat_main_t *vam = &vat_main;
1942   i32 retval = ntohl (mp->retval);
1943
1944   if (vam->async_mode)
1945     {
1946       vam->async_errors += (retval < 0);
1947     }
1948   else
1949     {
1950       vam->retval = retval;
1951       vam->result_ready = 1;
1952     }
1953 }
1954
1955 static void vl_api_bond_enslave_reply_t_handler_json
1956   (vl_api_bond_enslave_reply_t * mp)
1957 {
1958   vat_main_t *vam = &vat_main;
1959   vat_json_node_t node;
1960
1961   vat_json_init_object (&node);
1962   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1963
1964   vat_json_print (vam->ofp, &node);
1965   vat_json_free (&node);
1966
1967   vam->retval = ntohl (mp->retval);
1968   vam->result_ready = 1;
1969 }
1970
1971 static void
1972 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
1973                                           mp)
1974 {
1975   vat_main_t *vam = &vat_main;
1976   i32 retval = ntohl (mp->retval);
1977
1978   if (vam->async_mode)
1979     {
1980       vam->async_errors += (retval < 0);
1981     }
1982   else
1983     {
1984       vam->retval = retval;
1985       vam->result_ready = 1;
1986     }
1987 }
1988
1989 static void vl_api_bond_detach_slave_reply_t_handler_json
1990   (vl_api_bond_detach_slave_reply_t * mp)
1991 {
1992   vat_main_t *vam = &vat_main;
1993   vat_json_node_t node;
1994
1995   vat_json_init_object (&node);
1996   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1997
1998   vat_json_print (vam->ofp, &node);
1999   vat_json_free (&node);
2000
2001   vam->retval = ntohl (mp->retval);
2002   vam->result_ready = 1;
2003 }
2004
2005 static int
2006 api_sw_interface_set_bond_weight (vat_main_t * vam)
2007 {
2008   unformat_input_t *i = vam->input;
2009   vl_api_sw_interface_set_bond_weight_t *mp;
2010   u32 sw_if_index = ~0;
2011   u32 weight = 0;
2012   u8 weight_enter = 0;
2013   int ret;
2014
2015   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2016     {
2017       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2018         ;
2019       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2020         ;
2021       else if (unformat (i, "weight %u", &weight))
2022         weight_enter = 1;
2023       else
2024         break;
2025     }
2026
2027   if (sw_if_index == ~0)
2028     {
2029       errmsg ("missing interface name or sw_if_index");
2030       return -99;
2031     }
2032   if (weight_enter == 0)
2033     {
2034       errmsg ("missing valid weight");
2035       return -99;
2036     }
2037
2038   /* Construct the API message */
2039   M (SW_INTERFACE_SET_BOND_WEIGHT, mp);
2040   mp->sw_if_index = ntohl (sw_if_index);
2041   mp->weight = ntohl (weight);
2042
2043   S (mp);
2044   W (ret);
2045   return ret;
2046 }
2047
2048 static void vl_api_sw_interface_bond_details_t_handler
2049   (vl_api_sw_interface_bond_details_t * mp)
2050 {
2051   vat_main_t *vam = &vat_main;
2052
2053   print (vam->ofp,
2054          "%-16s %-12d %-12U %-13U %-14u %-14u",
2055          mp->interface_name, ntohl (mp->sw_if_index),
2056          format_bond_mode, ntohl (mp->mode), format_bond_load_balance,
2057          ntohl (mp->lb), ntohl (mp->active_slaves), ntohl (mp->slaves));
2058 }
2059
2060 static void vl_api_sw_interface_bond_details_t_handler_json
2061   (vl_api_sw_interface_bond_details_t * mp)
2062 {
2063   vat_main_t *vam = &vat_main;
2064   vat_json_node_t *node = NULL;
2065
2066   if (VAT_JSON_ARRAY != vam->json_tree.type)
2067     {
2068       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2069       vat_json_init_array (&vam->json_tree);
2070     }
2071   node = vat_json_array_add (&vam->json_tree);
2072
2073   vat_json_init_object (node);
2074   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2075   vat_json_object_add_string_copy (node, "interface_name",
2076                                    mp->interface_name);
2077   vat_json_object_add_uint (node, "mode", ntohl (mp->mode));
2078   vat_json_object_add_uint (node, "load_balance", ntohl (mp->lb));
2079   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
2080   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
2081 }
2082
2083 static int
2084 api_sw_interface_bond_dump (vat_main_t * vam)
2085 {
2086   vl_api_sw_interface_bond_dump_t *mp;
2087   vl_api_control_ping_t *mp_ping;
2088   int ret;
2089
2090   print (vam->ofp,
2091          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2092          "interface name", "sw_if_index", "mode", "load balance",
2093          "active slaves", "slaves");
2094
2095   /* Get list of bond interfaces */
2096   M (SW_INTERFACE_BOND_DUMP, mp);
2097   S (mp);
2098
2099   /* Use a control ping for synchronization */
2100   MPING (CONTROL_PING, mp_ping);
2101   S (mp_ping);
2102
2103   W (ret);
2104   return ret;
2105 }
2106
2107 static void vl_api_sw_interface_slave_details_t_handler
2108   (vl_api_sw_interface_slave_details_t * mp)
2109 {
2110   vat_main_t *vam = &vat_main;
2111
2112   print (vam->ofp,
2113          "%-25s %-12d %-7d %-12d %-10d %-10d", mp->interface_name,
2114          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout,
2115          ntohl (mp->weight), mp->is_local_numa);
2116 }
2117
2118 static void vl_api_sw_interface_slave_details_t_handler_json
2119   (vl_api_sw_interface_slave_details_t * mp)
2120 {
2121   vat_main_t *vam = &vat_main;
2122   vat_json_node_t *node = NULL;
2123
2124   if (VAT_JSON_ARRAY != vam->json_tree.type)
2125     {
2126       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2127       vat_json_init_array (&vam->json_tree);
2128     }
2129   node = vat_json_array_add (&vam->json_tree);
2130
2131   vat_json_init_object (node);
2132   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2133   vat_json_object_add_string_copy (node, "interface_name",
2134                                    mp->interface_name);
2135   vat_json_object_add_uint (node, "passive", mp->is_passive);
2136   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2137   vat_json_object_add_uint (node, "weight", ntohl (mp->weight));
2138   vat_json_object_add_uint (node, "is_local_numa", mp->is_local_numa);
2139 }
2140
2141 static int
2142 api_sw_interface_slave_dump (vat_main_t * vam)
2143 {
2144   unformat_input_t *i = vam->input;
2145   vl_api_sw_interface_slave_dump_t *mp;
2146   vl_api_control_ping_t *mp_ping;
2147   u32 sw_if_index = ~0;
2148   u8 sw_if_index_set = 0;
2149   int ret;
2150
2151   /* Parse args required to build the message */
2152   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2153     {
2154       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2155         sw_if_index_set = 1;
2156       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2157         sw_if_index_set = 1;
2158       else
2159         break;
2160     }
2161
2162   if (sw_if_index_set == 0)
2163     {
2164       errmsg ("missing vpp interface name. ");
2165       return -99;
2166     }
2167
2168   print (vam->ofp,
2169          "\n%-25s %-12s %-7s %-12s %-10s %-10s",
2170          "slave interface name", "sw_if_index", "passive", "long_timeout",
2171          "weight", "local numa");
2172
2173   /* Get list of bond interfaces */
2174   M (SW_INTERFACE_SLAVE_DUMP, mp);
2175   mp->sw_if_index = ntohl (sw_if_index);
2176   S (mp);
2177
2178   /* Use a control ping for synchronization */
2179   MPING (CONTROL_PING, mp_ping);
2180   S (mp_ping);
2181
2182   W (ret);
2183   return ret;
2184 }
2185
2186 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2187   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2188 {
2189   vat_main_t *vam = &vat_main;
2190   i32 retval = ntohl (mp->retval);
2191   if (vam->async_mode)
2192     {
2193       vam->async_errors += (retval < 0);
2194     }
2195   else
2196     {
2197       vam->retval = retval;
2198       vam->sw_if_index = ntohl (mp->sw_if_index);
2199       vam->result_ready = 1;
2200     }
2201   vam->regenerate_interface_table = 1;
2202 }
2203
2204 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2205   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2206 {
2207   vat_main_t *vam = &vat_main;
2208   vat_json_node_t node;
2209
2210   vat_json_init_object (&node);
2211   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2212   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2213                             ntohl (mp->sw_if_index));
2214
2215   vat_json_print (vam->ofp, &node);
2216   vat_json_free (&node);
2217
2218   vam->retval = ntohl (mp->retval);
2219   vam->result_ready = 1;
2220 }
2221
2222 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2223   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2224 {
2225   vat_main_t *vam = &vat_main;
2226   i32 retval = ntohl (mp->retval);
2227   if (vam->async_mode)
2228     {
2229       vam->async_errors += (retval < 0);
2230     }
2231   else
2232     {
2233       vam->retval = retval;
2234       vam->sw_if_index = ntohl (mp->sw_if_index);
2235       vam->result_ready = 1;
2236     }
2237 }
2238
2239 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2240   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2241 {
2242   vat_main_t *vam = &vat_main;
2243   vat_json_node_t node;
2244
2245   vat_json_init_object (&node);
2246   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2247   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2248
2249   vat_json_print (vam->ofp, &node);
2250   vat_json_free (&node);
2251
2252   vam->retval = ntohl (mp->retval);
2253   vam->result_ready = 1;
2254 }
2255
2256 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2257   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2258 {
2259   vat_main_t *vam = &vat_main;
2260   i32 retval = ntohl (mp->retval);
2261   if (vam->async_mode)
2262     {
2263       vam->async_errors += (retval < 0);
2264     }
2265   else
2266     {
2267       vam->retval = retval;
2268       vam->result_ready = 1;
2269     }
2270 }
2271
2272 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2273   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2274 {
2275   vat_main_t *vam = &vat_main;
2276   vat_json_node_t node;
2277
2278   vat_json_init_object (&node);
2279   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2280   vat_json_object_add_uint (&node, "fwd_entry_index",
2281                             clib_net_to_host_u32 (mp->fwd_entry_index));
2282
2283   vat_json_print (vam->ofp, &node);
2284   vat_json_free (&node);
2285
2286   vam->retval = ntohl (mp->retval);
2287   vam->result_ready = 1;
2288 }
2289
2290 u8 *
2291 format_lisp_transport_protocol (u8 * s, va_list * args)
2292 {
2293   u32 proto = va_arg (*args, u32);
2294
2295   switch (proto)
2296     {
2297     case 1:
2298       return format (s, "udp");
2299     case 2:
2300       return format (s, "api");
2301     default:
2302       return 0;
2303     }
2304   return 0;
2305 }
2306
2307 static void vl_api_one_get_transport_protocol_reply_t_handler
2308   (vl_api_one_get_transport_protocol_reply_t * mp)
2309 {
2310   vat_main_t *vam = &vat_main;
2311   i32 retval = ntohl (mp->retval);
2312   if (vam->async_mode)
2313     {
2314       vam->async_errors += (retval < 0);
2315     }
2316   else
2317     {
2318       u32 proto = mp->protocol;
2319       print (vam->ofp, "Transport protocol: %U",
2320              format_lisp_transport_protocol, proto);
2321       vam->retval = retval;
2322       vam->result_ready = 1;
2323     }
2324 }
2325
2326 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2327   (vl_api_one_get_transport_protocol_reply_t * mp)
2328 {
2329   vat_main_t *vam = &vat_main;
2330   vat_json_node_t node;
2331   u8 *s;
2332
2333   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2334   vec_add1 (s, 0);
2335
2336   vat_json_init_object (&node);
2337   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2338   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2339
2340   vec_free (s);
2341   vat_json_print (vam->ofp, &node);
2342   vat_json_free (&node);
2343
2344   vam->retval = ntohl (mp->retval);
2345   vam->result_ready = 1;
2346 }
2347
2348 static void vl_api_one_add_del_locator_set_reply_t_handler
2349   (vl_api_one_add_del_locator_set_reply_t * mp)
2350 {
2351   vat_main_t *vam = &vat_main;
2352   i32 retval = ntohl (mp->retval);
2353   if (vam->async_mode)
2354     {
2355       vam->async_errors += (retval < 0);
2356     }
2357   else
2358     {
2359       vam->retval = retval;
2360       vam->result_ready = 1;
2361     }
2362 }
2363
2364 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2365   (vl_api_one_add_del_locator_set_reply_t * mp)
2366 {
2367   vat_main_t *vam = &vat_main;
2368   vat_json_node_t node;
2369
2370   vat_json_init_object (&node);
2371   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2372   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2373
2374   vat_json_print (vam->ofp, &node);
2375   vat_json_free (&node);
2376
2377   vam->retval = ntohl (mp->retval);
2378   vam->result_ready = 1;
2379 }
2380
2381 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2382   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2383 {
2384   vat_main_t *vam = &vat_main;
2385   i32 retval = ntohl (mp->retval);
2386   if (vam->async_mode)
2387     {
2388       vam->async_errors += (retval < 0);
2389     }
2390   else
2391     {
2392       vam->retval = retval;
2393       vam->sw_if_index = ntohl (mp->sw_if_index);
2394       vam->result_ready = 1;
2395     }
2396   vam->regenerate_interface_table = 1;
2397 }
2398
2399 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2400   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2401 {
2402   vat_main_t *vam = &vat_main;
2403   vat_json_node_t node;
2404
2405   vat_json_init_object (&node);
2406   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2407   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2408
2409   vat_json_print (vam->ofp, &node);
2410   vat_json_free (&node);
2411
2412   vam->retval = ntohl (mp->retval);
2413   vam->result_ready = 1;
2414 }
2415
2416 static void vl_api_vxlan_offload_rx_reply_t_handler
2417   (vl_api_vxlan_offload_rx_reply_t * mp)
2418 {
2419   vat_main_t *vam = &vat_main;
2420   i32 retval = ntohl (mp->retval);
2421   if (vam->async_mode)
2422     {
2423       vam->async_errors += (retval < 0);
2424     }
2425   else
2426     {
2427       vam->retval = retval;
2428       vam->result_ready = 1;
2429     }
2430 }
2431
2432 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2433   (vl_api_vxlan_offload_rx_reply_t * mp)
2434 {
2435   vat_main_t *vam = &vat_main;
2436   vat_json_node_t node;
2437
2438   vat_json_init_object (&node);
2439   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2440
2441   vat_json_print (vam->ofp, &node);
2442   vat_json_free (&node);
2443
2444   vam->retval = ntohl (mp->retval);
2445   vam->result_ready = 1;
2446 }
2447
2448 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2449   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2450 {
2451   vat_main_t *vam = &vat_main;
2452   i32 retval = ntohl (mp->retval);
2453   if (vam->async_mode)
2454     {
2455       vam->async_errors += (retval < 0);
2456     }
2457   else
2458     {
2459       vam->retval = retval;
2460       vam->sw_if_index = ntohl (mp->sw_if_index);
2461       vam->result_ready = 1;
2462     }
2463 }
2464
2465 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2466   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2467 {
2468   vat_main_t *vam = &vat_main;
2469   vat_json_node_t node;
2470
2471   vat_json_init_object (&node);
2472   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2473   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2474
2475   vat_json_print (vam->ofp, &node);
2476   vat_json_free (&node);
2477
2478   vam->retval = ntohl (mp->retval);
2479   vam->result_ready = 1;
2480 }
2481
2482 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2483   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2484 {
2485   vat_main_t *vam = &vat_main;
2486   i32 retval = ntohl (mp->retval);
2487   if (vam->async_mode)
2488     {
2489       vam->async_errors += (retval < 0);
2490     }
2491   else
2492     {
2493       vam->retval = retval;
2494       vam->sw_if_index = ntohl (mp->sw_if_index);
2495       vam->result_ready = 1;
2496     }
2497   vam->regenerate_interface_table = 1;
2498 }
2499
2500 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2501   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2502 {
2503   vat_main_t *vam = &vat_main;
2504   vat_json_node_t node;
2505
2506   vat_json_init_object (&node);
2507   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2508   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2509
2510   vat_json_print (vam->ofp, &node);
2511   vat_json_free (&node);
2512
2513   vam->retval = ntohl (mp->retval);
2514   vam->result_ready = 1;
2515 }
2516
2517 static void vl_api_gre_tunnel_add_del_reply_t_handler
2518   (vl_api_gre_tunnel_add_del_reply_t * mp)
2519 {
2520   vat_main_t *vam = &vat_main;
2521   i32 retval = ntohl (mp->retval);
2522   if (vam->async_mode)
2523     {
2524       vam->async_errors += (retval < 0);
2525     }
2526   else
2527     {
2528       vam->retval = retval;
2529       vam->sw_if_index = ntohl (mp->sw_if_index);
2530       vam->result_ready = 1;
2531     }
2532 }
2533
2534 static void vl_api_gre_tunnel_add_del_reply_t_handler_json
2535   (vl_api_gre_tunnel_add_del_reply_t * mp)
2536 {
2537   vat_main_t *vam = &vat_main;
2538   vat_json_node_t node;
2539
2540   vat_json_init_object (&node);
2541   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2542   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2543
2544   vat_json_print (vam->ofp, &node);
2545   vat_json_free (&node);
2546
2547   vam->retval = ntohl (mp->retval);
2548   vam->result_ready = 1;
2549 }
2550
2551 static void vl_api_create_vhost_user_if_reply_t_handler
2552   (vl_api_create_vhost_user_if_reply_t * mp)
2553 {
2554   vat_main_t *vam = &vat_main;
2555   i32 retval = ntohl (mp->retval);
2556   if (vam->async_mode)
2557     {
2558       vam->async_errors += (retval < 0);
2559     }
2560   else
2561     {
2562       vam->retval = retval;
2563       vam->sw_if_index = ntohl (mp->sw_if_index);
2564       vam->result_ready = 1;
2565     }
2566   vam->regenerate_interface_table = 1;
2567 }
2568
2569 static void vl_api_create_vhost_user_if_reply_t_handler_json
2570   (vl_api_create_vhost_user_if_reply_t * mp)
2571 {
2572   vat_main_t *vam = &vat_main;
2573   vat_json_node_t node;
2574
2575   vat_json_init_object (&node);
2576   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2577   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2578
2579   vat_json_print (vam->ofp, &node);
2580   vat_json_free (&node);
2581
2582   vam->retval = ntohl (mp->retval);
2583   vam->result_ready = 1;
2584 }
2585
2586 static void vl_api_ip_address_details_t_handler
2587   (vl_api_ip_address_details_t * mp)
2588 {
2589   vat_main_t *vam = &vat_main;
2590   static ip_address_details_t empty_ip_address_details = { {0} };
2591   ip_address_details_t *address = NULL;
2592   ip_details_t *current_ip_details = NULL;
2593   ip_details_t *details = NULL;
2594
2595   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2596
2597   if (!details || vam->current_sw_if_index >= vec_len (details)
2598       || !details[vam->current_sw_if_index].present)
2599     {
2600       errmsg ("ip address details arrived but not stored");
2601       errmsg ("ip_dump should be called first");
2602       return;
2603     }
2604
2605   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2606
2607 #define addresses (current_ip_details->addr)
2608
2609   vec_validate_init_empty (addresses, vec_len (addresses),
2610                            empty_ip_address_details);
2611
2612   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2613
2614   clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
2615   address->prefix_length = mp->prefix.len;
2616 #undef addresses
2617 }
2618
2619 static void vl_api_ip_address_details_t_handler_json
2620   (vl_api_ip_address_details_t * mp)
2621 {
2622   vat_main_t *vam = &vat_main;
2623   vat_json_node_t *node = NULL;
2624
2625   if (VAT_JSON_ARRAY != vam->json_tree.type)
2626     {
2627       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2628       vat_json_init_array (&vam->json_tree);
2629     }
2630   node = vat_json_array_add (&vam->json_tree);
2631
2632   vat_json_init_object (node);
2633   vat_json_object_add_prefix (node, &mp->prefix);
2634 }
2635
2636 static void
2637 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2638 {
2639   vat_main_t *vam = &vat_main;
2640   static ip_details_t empty_ip_details = { 0 };
2641   ip_details_t *ip = NULL;
2642   u32 sw_if_index = ~0;
2643
2644   sw_if_index = ntohl (mp->sw_if_index);
2645
2646   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2647                            sw_if_index, empty_ip_details);
2648
2649   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2650                          sw_if_index);
2651
2652   ip->present = 1;
2653 }
2654
2655 static void
2656 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2657 {
2658   vat_main_t *vam = &vat_main;
2659
2660   if (VAT_JSON_ARRAY != vam->json_tree.type)
2661     {
2662       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2663       vat_json_init_array (&vam->json_tree);
2664     }
2665   vat_json_array_add_uint (&vam->json_tree,
2666                            clib_net_to_host_u32 (mp->sw_if_index));
2667 }
2668
2669 static void
2670 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2671 {
2672   u8 *s, i;
2673
2674   s = format (0, "DHCP compl event: pid %d hostname %s host_addr %U "
2675               "host_mac %U router_addr %U",
2676               ntohl (mp->pid), mp->lease.hostname,
2677               format_ip4_address, mp->lease.host_address,
2678               format_ethernet_address, mp->lease.host_mac,
2679               format_ip4_address, mp->lease.router_address);
2680
2681   for (i = 0; i < mp->lease.count; i++)
2682     s =
2683       format (s, " domain_server_addr %U", format_ip4_address,
2684               mp->lease.domain_server[i].address);
2685
2686   errmsg ((char *) s);
2687   vec_free (s);
2688 }
2689
2690 static void vl_api_dhcp_compl_event_t_handler_json
2691   (vl_api_dhcp_compl_event_t * mp)
2692 {
2693   /* JSON output not supported */
2694 }
2695
2696 static void vl_api_get_first_msg_id_reply_t_handler
2697   (vl_api_get_first_msg_id_reply_t * mp)
2698 {
2699   vat_main_t *vam = &vat_main;
2700   i32 retval = ntohl (mp->retval);
2701
2702   if (vam->async_mode)
2703     {
2704       vam->async_errors += (retval < 0);
2705     }
2706   else
2707     {
2708       vam->retval = retval;
2709       vam->result_ready = 1;
2710     }
2711   if (retval >= 0)
2712     {
2713       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2714     }
2715 }
2716
2717 static void vl_api_get_first_msg_id_reply_t_handler_json
2718   (vl_api_get_first_msg_id_reply_t * mp)
2719 {
2720   vat_main_t *vam = &vat_main;
2721   vat_json_node_t node;
2722
2723   vat_json_init_object (&node);
2724   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2725   vat_json_object_add_uint (&node, "first_msg_id",
2726                             (uint) ntohs (mp->first_msg_id));
2727
2728   vat_json_print (vam->ofp, &node);
2729   vat_json_free (&node);
2730
2731   vam->retval = ntohl (mp->retval);
2732   vam->result_ready = 1;
2733 }
2734
2735 static void vl_api_get_node_graph_reply_t_handler
2736   (vl_api_get_node_graph_reply_t * mp)
2737 {
2738   vat_main_t *vam = &vat_main;
2739   api_main_t *am = &api_main;
2740   i32 retval = ntohl (mp->retval);
2741   u8 *pvt_copy, *reply;
2742   void *oldheap;
2743   vlib_node_t *node;
2744   int i;
2745
2746   if (vam->async_mode)
2747     {
2748       vam->async_errors += (retval < 0);
2749     }
2750   else
2751     {
2752       vam->retval = retval;
2753       vam->result_ready = 1;
2754     }
2755
2756   /* "Should never happen..." */
2757   if (retval != 0)
2758     return;
2759
2760   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2761   pvt_copy = vec_dup (reply);
2762
2763   /* Toss the shared-memory original... */
2764   pthread_mutex_lock (&am->vlib_rp->mutex);
2765   oldheap = svm_push_data_heap (am->vlib_rp);
2766
2767   vec_free (reply);
2768
2769   svm_pop_heap (oldheap);
2770   pthread_mutex_unlock (&am->vlib_rp->mutex);
2771
2772   if (vam->graph_nodes)
2773     {
2774       hash_free (vam->graph_node_index_by_name);
2775
2776       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2777         {
2778           node = vam->graph_nodes[0][i];
2779           vec_free (node->name);
2780           vec_free (node->next_nodes);
2781           vec_free (node);
2782         }
2783       vec_free (vam->graph_nodes[0]);
2784       vec_free (vam->graph_nodes);
2785     }
2786
2787   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2788   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2789   vec_free (pvt_copy);
2790
2791   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2792     {
2793       node = vam->graph_nodes[0][i];
2794       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2795     }
2796 }
2797
2798 static void vl_api_get_node_graph_reply_t_handler_json
2799   (vl_api_get_node_graph_reply_t * mp)
2800 {
2801   vat_main_t *vam = &vat_main;
2802   api_main_t *am = &api_main;
2803   void *oldheap;
2804   vat_json_node_t node;
2805   u8 *reply;
2806
2807   /* $$$$ make this real? */
2808   vat_json_init_object (&node);
2809   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2810   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2811
2812   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2813
2814   /* Toss the shared-memory original... */
2815   pthread_mutex_lock (&am->vlib_rp->mutex);
2816   oldheap = svm_push_data_heap (am->vlib_rp);
2817
2818   vec_free (reply);
2819
2820   svm_pop_heap (oldheap);
2821   pthread_mutex_unlock (&am->vlib_rp->mutex);
2822
2823   vat_json_print (vam->ofp, &node);
2824   vat_json_free (&node);
2825
2826   vam->retval = ntohl (mp->retval);
2827   vam->result_ready = 1;
2828 }
2829
2830 static void
2831 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2832 {
2833   vat_main_t *vam = &vat_main;
2834   u8 *s = 0;
2835
2836   if (mp->local)
2837     {
2838       s = format (s, "%=16d%=16d%=16d",
2839                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2840     }
2841   else
2842     {
2843       s = format (s, "%=16U%=16d%=16d",
2844                   mp->is_ipv6 ? format_ip6_address :
2845                   format_ip4_address,
2846                   mp->ip_address, mp->priority, mp->weight);
2847     }
2848
2849   print (vam->ofp, "%v", s);
2850   vec_free (s);
2851 }
2852
2853 static void
2854 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2855 {
2856   vat_main_t *vam = &vat_main;
2857   vat_json_node_t *node = NULL;
2858   struct in6_addr ip6;
2859   struct in_addr ip4;
2860
2861   if (VAT_JSON_ARRAY != vam->json_tree.type)
2862     {
2863       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2864       vat_json_init_array (&vam->json_tree);
2865     }
2866   node = vat_json_array_add (&vam->json_tree);
2867   vat_json_init_object (node);
2868
2869   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2870   vat_json_object_add_uint (node, "priority", mp->priority);
2871   vat_json_object_add_uint (node, "weight", mp->weight);
2872
2873   if (mp->local)
2874     vat_json_object_add_uint (node, "sw_if_index",
2875                               clib_net_to_host_u32 (mp->sw_if_index));
2876   else
2877     {
2878       if (mp->is_ipv6)
2879         {
2880           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2881           vat_json_object_add_ip6 (node, "address", ip6);
2882         }
2883       else
2884         {
2885           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2886           vat_json_object_add_ip4 (node, "address", ip4);
2887         }
2888     }
2889 }
2890
2891 static void
2892 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2893                                           mp)
2894 {
2895   vat_main_t *vam = &vat_main;
2896   u8 *ls_name = 0;
2897
2898   ls_name = format (0, "%s", mp->ls_name);
2899
2900   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2901          ls_name);
2902   vec_free (ls_name);
2903 }
2904
2905 static void
2906   vl_api_one_locator_set_details_t_handler_json
2907   (vl_api_one_locator_set_details_t * mp)
2908 {
2909   vat_main_t *vam = &vat_main;
2910   vat_json_node_t *node = 0;
2911   u8 *ls_name = 0;
2912
2913   ls_name = format (0, "%s", mp->ls_name);
2914   vec_add1 (ls_name, 0);
2915
2916   if (VAT_JSON_ARRAY != vam->json_tree.type)
2917     {
2918       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2919       vat_json_init_array (&vam->json_tree);
2920     }
2921   node = vat_json_array_add (&vam->json_tree);
2922
2923   vat_json_init_object (node);
2924   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2925   vat_json_object_add_uint (node, "ls_index",
2926                             clib_net_to_host_u32 (mp->ls_index));
2927   vec_free (ls_name);
2928 }
2929
2930 typedef struct
2931 {
2932   u32 spi;
2933   u8 si;
2934 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2935
2936 uword
2937 unformat_nsh_address (unformat_input_t * input, va_list * args)
2938 {
2939   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2940   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2941 }
2942
2943 u8 *
2944 format_nsh_address_vat (u8 * s, va_list * args)
2945 {
2946   nsh_t *a = va_arg (*args, nsh_t *);
2947   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2948 }
2949
2950 static u8 *
2951 format_lisp_flat_eid (u8 * s, va_list * args)
2952 {
2953   u32 type = va_arg (*args, u32);
2954   u8 *eid = va_arg (*args, u8 *);
2955   u32 eid_len = va_arg (*args, u32);
2956
2957   switch (type)
2958     {
2959     case 0:
2960       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2961     case 1:
2962       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2963     case 2:
2964       return format (s, "%U", format_ethernet_address, eid);
2965     case 3:
2966       return format (s, "%U", format_nsh_address_vat, eid);
2967     }
2968   return 0;
2969 }
2970
2971 static u8 *
2972 format_lisp_eid_vat (u8 * s, va_list * args)
2973 {
2974   u32 type = va_arg (*args, u32);
2975   u8 *eid = va_arg (*args, u8 *);
2976   u32 eid_len = va_arg (*args, u32);
2977   u8 *seid = va_arg (*args, u8 *);
2978   u32 seid_len = va_arg (*args, u32);
2979   u32 is_src_dst = va_arg (*args, u32);
2980
2981   if (is_src_dst)
2982     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2983
2984   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2985
2986   return s;
2987 }
2988
2989 static void
2990 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2991 {
2992   vat_main_t *vam = &vat_main;
2993   u8 *s = 0, *eid = 0;
2994
2995   if (~0 == mp->locator_set_index)
2996     s = format (0, "action: %d", mp->action);
2997   else
2998     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2999
3000   eid = format (0, "%U", format_lisp_eid_vat,
3001                 mp->eid_type,
3002                 mp->eid,
3003                 mp->eid_prefix_len,
3004                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3005   vec_add1 (eid, 0);
3006
3007   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3008          clib_net_to_host_u32 (mp->vni),
3009          eid,
3010          mp->is_local ? "local" : "remote",
3011          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3012          clib_net_to_host_u16 (mp->key_id), mp->key);
3013
3014   vec_free (s);
3015   vec_free (eid);
3016 }
3017
3018 static void
3019 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3020                                              * mp)
3021 {
3022   vat_main_t *vam = &vat_main;
3023   vat_json_node_t *node = 0;
3024   u8 *eid = 0;
3025
3026   if (VAT_JSON_ARRAY != vam->json_tree.type)
3027     {
3028       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3029       vat_json_init_array (&vam->json_tree);
3030     }
3031   node = vat_json_array_add (&vam->json_tree);
3032
3033   vat_json_init_object (node);
3034   if (~0 == mp->locator_set_index)
3035     vat_json_object_add_uint (node, "action", mp->action);
3036   else
3037     vat_json_object_add_uint (node, "locator_set_index",
3038                               clib_net_to_host_u32 (mp->locator_set_index));
3039
3040   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3041   if (mp->eid_type == 3)
3042     {
3043       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3044       vat_json_init_object (nsh_json);
3045       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3046       vat_json_object_add_uint (nsh_json, "spi",
3047                                 clib_net_to_host_u32 (nsh->spi));
3048       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3049     }
3050   else
3051     {
3052       eid = format (0, "%U", format_lisp_eid_vat,
3053                     mp->eid_type,
3054                     mp->eid,
3055                     mp->eid_prefix_len,
3056                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3057       vec_add1 (eid, 0);
3058       vat_json_object_add_string_copy (node, "eid", eid);
3059       vec_free (eid);
3060     }
3061   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3062   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3063   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3064
3065   if (mp->key_id)
3066     {
3067       vat_json_object_add_uint (node, "key_id",
3068                                 clib_net_to_host_u16 (mp->key_id));
3069       vat_json_object_add_string_copy (node, "key", mp->key);
3070     }
3071 }
3072
3073 static void
3074 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3075 {
3076   vat_main_t *vam = &vat_main;
3077   u8 *seid = 0, *deid = 0;
3078   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3079
3080   deid = format (0, "%U", format_lisp_eid_vat,
3081                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3082
3083   seid = format (0, "%U", format_lisp_eid_vat,
3084                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3085
3086   vec_add1 (deid, 0);
3087   vec_add1 (seid, 0);
3088
3089   if (mp->is_ip4)
3090     format_ip_address_fcn = format_ip4_address;
3091   else
3092     format_ip_address_fcn = format_ip6_address;
3093
3094
3095   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3096          clib_net_to_host_u32 (mp->vni),
3097          seid, deid,
3098          format_ip_address_fcn, mp->lloc,
3099          format_ip_address_fcn, mp->rloc,
3100          clib_net_to_host_u32 (mp->pkt_count),
3101          clib_net_to_host_u32 (mp->bytes));
3102
3103   vec_free (deid);
3104   vec_free (seid);
3105 }
3106
3107 static void
3108 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3109 {
3110   struct in6_addr ip6;
3111   struct in_addr ip4;
3112   vat_main_t *vam = &vat_main;
3113   vat_json_node_t *node = 0;
3114   u8 *deid = 0, *seid = 0;
3115
3116   if (VAT_JSON_ARRAY != vam->json_tree.type)
3117     {
3118       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3119       vat_json_init_array (&vam->json_tree);
3120     }
3121   node = vat_json_array_add (&vam->json_tree);
3122
3123   vat_json_init_object (node);
3124   deid = format (0, "%U", format_lisp_eid_vat,
3125                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3126
3127   seid = format (0, "%U", format_lisp_eid_vat,
3128                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3129
3130   vec_add1 (deid, 0);
3131   vec_add1 (seid, 0);
3132
3133   vat_json_object_add_string_copy (node, "seid", seid);
3134   vat_json_object_add_string_copy (node, "deid", deid);
3135   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3136
3137   if (mp->is_ip4)
3138     {
3139       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3140       vat_json_object_add_ip4 (node, "lloc", ip4);
3141       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3142       vat_json_object_add_ip4 (node, "rloc", ip4);
3143     }
3144   else
3145     {
3146       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3147       vat_json_object_add_ip6 (node, "lloc", ip6);
3148       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3149       vat_json_object_add_ip6 (node, "rloc", ip6);
3150     }
3151   vat_json_object_add_uint (node, "pkt_count",
3152                             clib_net_to_host_u32 (mp->pkt_count));
3153   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3154
3155   vec_free (deid);
3156   vec_free (seid);
3157 }
3158
3159 static void
3160   vl_api_one_eid_table_map_details_t_handler
3161   (vl_api_one_eid_table_map_details_t * mp)
3162 {
3163   vat_main_t *vam = &vat_main;
3164
3165   u8 *line = format (0, "%=10d%=10d",
3166                      clib_net_to_host_u32 (mp->vni),
3167                      clib_net_to_host_u32 (mp->dp_table));
3168   print (vam->ofp, "%v", line);
3169   vec_free (line);
3170 }
3171
3172 static void
3173   vl_api_one_eid_table_map_details_t_handler_json
3174   (vl_api_one_eid_table_map_details_t * mp)
3175 {
3176   vat_main_t *vam = &vat_main;
3177   vat_json_node_t *node = NULL;
3178
3179   if (VAT_JSON_ARRAY != vam->json_tree.type)
3180     {
3181       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3182       vat_json_init_array (&vam->json_tree);
3183     }
3184   node = vat_json_array_add (&vam->json_tree);
3185   vat_json_init_object (node);
3186   vat_json_object_add_uint (node, "dp_table",
3187                             clib_net_to_host_u32 (mp->dp_table));
3188   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3189 }
3190
3191 static void
3192   vl_api_one_eid_table_vni_details_t_handler
3193   (vl_api_one_eid_table_vni_details_t * mp)
3194 {
3195   vat_main_t *vam = &vat_main;
3196
3197   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3198   print (vam->ofp, "%v", line);
3199   vec_free (line);
3200 }
3201
3202 static void
3203   vl_api_one_eid_table_vni_details_t_handler_json
3204   (vl_api_one_eid_table_vni_details_t * mp)
3205 {
3206   vat_main_t *vam = &vat_main;
3207   vat_json_node_t *node = NULL;
3208
3209   if (VAT_JSON_ARRAY != vam->json_tree.type)
3210     {
3211       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3212       vat_json_init_array (&vam->json_tree);
3213     }
3214   node = vat_json_array_add (&vam->json_tree);
3215   vat_json_init_object (node);
3216   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3217 }
3218
3219 static void
3220   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3221   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3222 {
3223   vat_main_t *vam = &vat_main;
3224   int retval = clib_net_to_host_u32 (mp->retval);
3225
3226   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3227   print (vam->ofp, "fallback threshold value: %d", mp->value);
3228
3229   vam->retval = retval;
3230   vam->result_ready = 1;
3231 }
3232
3233 static void
3234   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3235   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3236 {
3237   vat_main_t *vam = &vat_main;
3238   vat_json_node_t _node, *node = &_node;
3239   int retval = clib_net_to_host_u32 (mp->retval);
3240
3241   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3242   vat_json_init_object (node);
3243   vat_json_object_add_uint (node, "value", mp->value);
3244
3245   vat_json_print (vam->ofp, node);
3246   vat_json_free (node);
3247
3248   vam->retval = retval;
3249   vam->result_ready = 1;
3250 }
3251
3252 static void
3253   vl_api_show_one_map_register_state_reply_t_handler
3254   (vl_api_show_one_map_register_state_reply_t * mp)
3255 {
3256   vat_main_t *vam = &vat_main;
3257   int retval = clib_net_to_host_u32 (mp->retval);
3258
3259   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3260
3261   vam->retval = retval;
3262   vam->result_ready = 1;
3263 }
3264
3265 static void
3266   vl_api_show_one_map_register_state_reply_t_handler_json
3267   (vl_api_show_one_map_register_state_reply_t * mp)
3268 {
3269   vat_main_t *vam = &vat_main;
3270   vat_json_node_t _node, *node = &_node;
3271   int retval = clib_net_to_host_u32 (mp->retval);
3272
3273   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3274
3275   vat_json_init_object (node);
3276   vat_json_object_add_string_copy (node, "state", s);
3277
3278   vat_json_print (vam->ofp, node);
3279   vat_json_free (node);
3280
3281   vam->retval = retval;
3282   vam->result_ready = 1;
3283   vec_free (s);
3284 }
3285
3286 static void
3287   vl_api_show_one_rloc_probe_state_reply_t_handler
3288   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3289 {
3290   vat_main_t *vam = &vat_main;
3291   int retval = clib_net_to_host_u32 (mp->retval);
3292
3293   if (retval)
3294     goto end;
3295
3296   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3297 end:
3298   vam->retval = retval;
3299   vam->result_ready = 1;
3300 }
3301
3302 static void
3303   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3304   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3305 {
3306   vat_main_t *vam = &vat_main;
3307   vat_json_node_t _node, *node = &_node;
3308   int retval = clib_net_to_host_u32 (mp->retval);
3309
3310   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3311   vat_json_init_object (node);
3312   vat_json_object_add_string_copy (node, "state", s);
3313
3314   vat_json_print (vam->ofp, node);
3315   vat_json_free (node);
3316
3317   vam->retval = retval;
3318   vam->result_ready = 1;
3319   vec_free (s);
3320 }
3321
3322 static void
3323   vl_api_show_one_stats_enable_disable_reply_t_handler
3324   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3325 {
3326   vat_main_t *vam = &vat_main;
3327   int retval = clib_net_to_host_u32 (mp->retval);
3328
3329   if (retval)
3330     goto end;
3331
3332   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3333 end:
3334   vam->retval = retval;
3335   vam->result_ready = 1;
3336 }
3337
3338 static void
3339   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3340   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3341 {
3342   vat_main_t *vam = &vat_main;
3343   vat_json_node_t _node, *node = &_node;
3344   int retval = clib_net_to_host_u32 (mp->retval);
3345
3346   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3347   vat_json_init_object (node);
3348   vat_json_object_add_string_copy (node, "state", s);
3349
3350   vat_json_print (vam->ofp, node);
3351   vat_json_free (node);
3352
3353   vam->retval = retval;
3354   vam->result_ready = 1;
3355   vec_free (s);
3356 }
3357
3358 static void
3359 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3360 {
3361   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3362   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3363   e->vni = clib_net_to_host_u32 (e->vni);
3364 }
3365
3366 static void
3367   gpe_fwd_entries_get_reply_t_net_to_host
3368   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3369 {
3370   u32 i;
3371
3372   mp->count = clib_net_to_host_u32 (mp->count);
3373   for (i = 0; i < mp->count; i++)
3374     {
3375       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3376     }
3377 }
3378
3379 static u8 *
3380 format_gpe_encap_mode (u8 * s, va_list * args)
3381 {
3382   u32 mode = va_arg (*args, u32);
3383
3384   switch (mode)
3385     {
3386     case 0:
3387       return format (s, "lisp");
3388     case 1:
3389       return format (s, "vxlan");
3390     }
3391   return 0;
3392 }
3393
3394 static void
3395   vl_api_gpe_get_encap_mode_reply_t_handler
3396   (vl_api_gpe_get_encap_mode_reply_t * mp)
3397 {
3398   vat_main_t *vam = &vat_main;
3399
3400   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3401   vam->retval = ntohl (mp->retval);
3402   vam->result_ready = 1;
3403 }
3404
3405 static void
3406   vl_api_gpe_get_encap_mode_reply_t_handler_json
3407   (vl_api_gpe_get_encap_mode_reply_t * mp)
3408 {
3409   vat_main_t *vam = &vat_main;
3410   vat_json_node_t node;
3411
3412   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3413   vec_add1 (encap_mode, 0);
3414
3415   vat_json_init_object (&node);
3416   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3417
3418   vec_free (encap_mode);
3419   vat_json_print (vam->ofp, &node);
3420   vat_json_free (&node);
3421
3422   vam->retval = ntohl (mp->retval);
3423   vam->result_ready = 1;
3424 }
3425
3426 static void
3427   vl_api_gpe_fwd_entry_path_details_t_handler
3428   (vl_api_gpe_fwd_entry_path_details_t * mp)
3429 {
3430   vat_main_t *vam = &vat_main;
3431   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3432
3433   if (mp->lcl_loc.is_ip4)
3434     format_ip_address_fcn = format_ip4_address;
3435   else
3436     format_ip_address_fcn = format_ip6_address;
3437
3438   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3439          format_ip_address_fcn, &mp->lcl_loc,
3440          format_ip_address_fcn, &mp->rmt_loc);
3441 }
3442
3443 static void
3444 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3445 {
3446   struct in6_addr ip6;
3447   struct in_addr ip4;
3448
3449   if (loc->is_ip4)
3450     {
3451       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3452       vat_json_object_add_ip4 (n, "address", ip4);
3453     }
3454   else
3455     {
3456       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3457       vat_json_object_add_ip6 (n, "address", ip6);
3458     }
3459   vat_json_object_add_uint (n, "weight", loc->weight);
3460 }
3461
3462 static void
3463   vl_api_gpe_fwd_entry_path_details_t_handler_json
3464   (vl_api_gpe_fwd_entry_path_details_t * mp)
3465 {
3466   vat_main_t *vam = &vat_main;
3467   vat_json_node_t *node = NULL;
3468   vat_json_node_t *loc_node;
3469
3470   if (VAT_JSON_ARRAY != vam->json_tree.type)
3471     {
3472       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3473       vat_json_init_array (&vam->json_tree);
3474     }
3475   node = vat_json_array_add (&vam->json_tree);
3476   vat_json_init_object (node);
3477
3478   loc_node = vat_json_object_add (node, "local_locator");
3479   vat_json_init_object (loc_node);
3480   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3481
3482   loc_node = vat_json_object_add (node, "remote_locator");
3483   vat_json_init_object (loc_node);
3484   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3485 }
3486
3487 static void
3488   vl_api_gpe_fwd_entries_get_reply_t_handler
3489   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3490 {
3491   vat_main_t *vam = &vat_main;
3492   u32 i;
3493   int retval = clib_net_to_host_u32 (mp->retval);
3494   vl_api_gpe_fwd_entry_t *e;
3495
3496   if (retval)
3497     goto end;
3498
3499   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3500
3501   for (i = 0; i < mp->count; i++)
3502     {
3503       e = &mp->entries[i];
3504       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3505              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3506              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3507     }
3508
3509 end:
3510   vam->retval = retval;
3511   vam->result_ready = 1;
3512 }
3513
3514 static void
3515   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3516   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3517 {
3518   u8 *s = 0;
3519   vat_main_t *vam = &vat_main;
3520   vat_json_node_t *e = 0, root;
3521   u32 i;
3522   int retval = clib_net_to_host_u32 (mp->retval);
3523   vl_api_gpe_fwd_entry_t *fwd;
3524
3525   if (retval)
3526     goto end;
3527
3528   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3529   vat_json_init_array (&root);
3530
3531   for (i = 0; i < mp->count; i++)
3532     {
3533       e = vat_json_array_add (&root);
3534       fwd = &mp->entries[i];
3535
3536       vat_json_init_object (e);
3537       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3538       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3539       vat_json_object_add_int (e, "vni", fwd->vni);
3540       vat_json_object_add_int (e, "action", fwd->action);
3541
3542       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3543                   fwd->leid_prefix_len);
3544       vec_add1 (s, 0);
3545       vat_json_object_add_string_copy (e, "leid", s);
3546       vec_free (s);
3547
3548       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3549                   fwd->reid_prefix_len);
3550       vec_add1 (s, 0);
3551       vat_json_object_add_string_copy (e, "reid", s);
3552       vec_free (s);
3553     }
3554
3555   vat_json_print (vam->ofp, &root);
3556   vat_json_free (&root);
3557
3558 end:
3559   vam->retval = retval;
3560   vam->result_ready = 1;
3561 }
3562
3563 static void
3564   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3565   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3566 {
3567   vat_main_t *vam = &vat_main;
3568   u32 i, n;
3569   int retval = clib_net_to_host_u32 (mp->retval);
3570   vl_api_gpe_native_fwd_rpath_t *r;
3571
3572   if (retval)
3573     goto end;
3574
3575   n = clib_net_to_host_u32 (mp->count);
3576
3577   for (i = 0; i < n; i++)
3578     {
3579       r = &mp->entries[i];
3580       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3581              clib_net_to_host_u32 (r->fib_index),
3582              clib_net_to_host_u32 (r->nh_sw_if_index),
3583              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3584     }
3585
3586 end:
3587   vam->retval = retval;
3588   vam->result_ready = 1;
3589 }
3590
3591 static void
3592   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3593   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3594 {
3595   vat_main_t *vam = &vat_main;
3596   vat_json_node_t root, *e;
3597   u32 i, n;
3598   int retval = clib_net_to_host_u32 (mp->retval);
3599   vl_api_gpe_native_fwd_rpath_t *r;
3600   u8 *s;
3601
3602   if (retval)
3603     goto end;
3604
3605   n = clib_net_to_host_u32 (mp->count);
3606   vat_json_init_array (&root);
3607
3608   for (i = 0; i < n; i++)
3609     {
3610       e = vat_json_array_add (&root);
3611       vat_json_init_object (e);
3612       r = &mp->entries[i];
3613       s =
3614         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3615                 r->nh_addr);
3616       vec_add1 (s, 0);
3617       vat_json_object_add_string_copy (e, "ip4", s);
3618       vec_free (s);
3619
3620       vat_json_object_add_uint (e, "fib_index",
3621                                 clib_net_to_host_u32 (r->fib_index));
3622       vat_json_object_add_uint (e, "nh_sw_if_index",
3623                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3624     }
3625
3626   vat_json_print (vam->ofp, &root);
3627   vat_json_free (&root);
3628
3629 end:
3630   vam->retval = retval;
3631   vam->result_ready = 1;
3632 }
3633
3634 static void
3635   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3636   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3637 {
3638   vat_main_t *vam = &vat_main;
3639   u32 i, n;
3640   int retval = clib_net_to_host_u32 (mp->retval);
3641
3642   if (retval)
3643     goto end;
3644
3645   n = clib_net_to_host_u32 (mp->count);
3646
3647   for (i = 0; i < n; i++)
3648     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3649
3650 end:
3651   vam->retval = retval;
3652   vam->result_ready = 1;
3653 }
3654
3655 static void
3656   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3657   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3658 {
3659   vat_main_t *vam = &vat_main;
3660   vat_json_node_t root;
3661   u32 i, n;
3662   int retval = clib_net_to_host_u32 (mp->retval);
3663
3664   if (retval)
3665     goto end;
3666
3667   n = clib_net_to_host_u32 (mp->count);
3668   vat_json_init_array (&root);
3669
3670   for (i = 0; i < n; i++)
3671     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3672
3673   vat_json_print (vam->ofp, &root);
3674   vat_json_free (&root);
3675
3676 end:
3677   vam->retval = retval;
3678   vam->result_ready = 1;
3679 }
3680
3681 static void
3682   vl_api_one_ndp_entries_get_reply_t_handler
3683   (vl_api_one_ndp_entries_get_reply_t * mp)
3684 {
3685   vat_main_t *vam = &vat_main;
3686   u32 i, n;
3687   int retval = clib_net_to_host_u32 (mp->retval);
3688
3689   if (retval)
3690     goto end;
3691
3692   n = clib_net_to_host_u32 (mp->count);
3693
3694   for (i = 0; i < n; i++)
3695     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3696            format_ethernet_address, mp->entries[i].mac);
3697
3698 end:
3699   vam->retval = retval;
3700   vam->result_ready = 1;
3701 }
3702
3703 static void
3704   vl_api_one_ndp_entries_get_reply_t_handler_json
3705   (vl_api_one_ndp_entries_get_reply_t * mp)
3706 {
3707   u8 *s = 0;
3708   vat_main_t *vam = &vat_main;
3709   vat_json_node_t *e = 0, root;
3710   u32 i, n;
3711   int retval = clib_net_to_host_u32 (mp->retval);
3712   vl_api_one_ndp_entry_t *arp_entry;
3713
3714   if (retval)
3715     goto end;
3716
3717   n = clib_net_to_host_u32 (mp->count);
3718   vat_json_init_array (&root);
3719
3720   for (i = 0; i < n; i++)
3721     {
3722       e = vat_json_array_add (&root);
3723       arp_entry = &mp->entries[i];
3724
3725       vat_json_init_object (e);
3726       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3727       vec_add1 (s, 0);
3728
3729       vat_json_object_add_string_copy (e, "mac", s);
3730       vec_free (s);
3731
3732       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3733       vec_add1 (s, 0);
3734       vat_json_object_add_string_copy (e, "ip6", s);
3735       vec_free (s);
3736     }
3737
3738   vat_json_print (vam->ofp, &root);
3739   vat_json_free (&root);
3740
3741 end:
3742   vam->retval = retval;
3743   vam->result_ready = 1;
3744 }
3745
3746 static void
3747   vl_api_one_l2_arp_entries_get_reply_t_handler
3748   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3749 {
3750   vat_main_t *vam = &vat_main;
3751   u32 i, n;
3752   int retval = clib_net_to_host_u32 (mp->retval);
3753
3754   if (retval)
3755     goto end;
3756
3757   n = clib_net_to_host_u32 (mp->count);
3758
3759   for (i = 0; i < n; i++)
3760     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3761            format_ethernet_address, mp->entries[i].mac);
3762
3763 end:
3764   vam->retval = retval;
3765   vam->result_ready = 1;
3766 }
3767
3768 static void
3769   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3770   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3771 {
3772   u8 *s = 0;
3773   vat_main_t *vam = &vat_main;
3774   vat_json_node_t *e = 0, root;
3775   u32 i, n;
3776   int retval = clib_net_to_host_u32 (mp->retval);
3777   vl_api_one_l2_arp_entry_t *arp_entry;
3778
3779   if (retval)
3780     goto end;
3781
3782   n = clib_net_to_host_u32 (mp->count);
3783   vat_json_init_array (&root);
3784
3785   for (i = 0; i < n; i++)
3786     {
3787       e = vat_json_array_add (&root);
3788       arp_entry = &mp->entries[i];
3789
3790       vat_json_init_object (e);
3791       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3792       vec_add1 (s, 0);
3793
3794       vat_json_object_add_string_copy (e, "mac", s);
3795       vec_free (s);
3796
3797       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3798       vec_add1 (s, 0);
3799       vat_json_object_add_string_copy (e, "ip4", s);
3800       vec_free (s);
3801     }
3802
3803   vat_json_print (vam->ofp, &root);
3804   vat_json_free (&root);
3805
3806 end:
3807   vam->retval = retval;
3808   vam->result_ready = 1;
3809 }
3810
3811 static void
3812 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3813 {
3814   vat_main_t *vam = &vat_main;
3815   u32 i, n;
3816   int retval = clib_net_to_host_u32 (mp->retval);
3817
3818   if (retval)
3819     goto end;
3820
3821   n = clib_net_to_host_u32 (mp->count);
3822
3823   for (i = 0; i < n; i++)
3824     {
3825       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3826     }
3827
3828 end:
3829   vam->retval = retval;
3830   vam->result_ready = 1;
3831 }
3832
3833 static void
3834   vl_api_one_ndp_bd_get_reply_t_handler_json
3835   (vl_api_one_ndp_bd_get_reply_t * mp)
3836 {
3837   vat_main_t *vam = &vat_main;
3838   vat_json_node_t root;
3839   u32 i, n;
3840   int retval = clib_net_to_host_u32 (mp->retval);
3841
3842   if (retval)
3843     goto end;
3844
3845   n = clib_net_to_host_u32 (mp->count);
3846   vat_json_init_array (&root);
3847
3848   for (i = 0; i < n; i++)
3849     {
3850       vat_json_array_add_uint (&root,
3851                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3852     }
3853
3854   vat_json_print (vam->ofp, &root);
3855   vat_json_free (&root);
3856
3857 end:
3858   vam->retval = retval;
3859   vam->result_ready = 1;
3860 }
3861
3862 static void
3863   vl_api_one_l2_arp_bd_get_reply_t_handler
3864   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3865 {
3866   vat_main_t *vam = &vat_main;
3867   u32 i, n;
3868   int retval = clib_net_to_host_u32 (mp->retval);
3869
3870   if (retval)
3871     goto end;
3872
3873   n = clib_net_to_host_u32 (mp->count);
3874
3875   for (i = 0; i < n; i++)
3876     {
3877       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3878     }
3879
3880 end:
3881   vam->retval = retval;
3882   vam->result_ready = 1;
3883 }
3884
3885 static void
3886   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3887   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3888 {
3889   vat_main_t *vam = &vat_main;
3890   vat_json_node_t root;
3891   u32 i, n;
3892   int retval = clib_net_to_host_u32 (mp->retval);
3893
3894   if (retval)
3895     goto end;
3896
3897   n = clib_net_to_host_u32 (mp->count);
3898   vat_json_init_array (&root);
3899
3900   for (i = 0; i < n; i++)
3901     {
3902       vat_json_array_add_uint (&root,
3903                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3904     }
3905
3906   vat_json_print (vam->ofp, &root);
3907   vat_json_free (&root);
3908
3909 end:
3910   vam->retval = retval;
3911   vam->result_ready = 1;
3912 }
3913
3914 static void
3915   vl_api_one_adjacencies_get_reply_t_handler
3916   (vl_api_one_adjacencies_get_reply_t * mp)
3917 {
3918   vat_main_t *vam = &vat_main;
3919   u32 i, n;
3920   int retval = clib_net_to_host_u32 (mp->retval);
3921   vl_api_one_adjacency_t *a;
3922
3923   if (retval)
3924     goto end;
3925
3926   n = clib_net_to_host_u32 (mp->count);
3927
3928   for (i = 0; i < n; i++)
3929     {
3930       a = &mp->adjacencies[i];
3931       print (vam->ofp, "%U %40U",
3932              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3933              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3934     }
3935
3936 end:
3937   vam->retval = retval;
3938   vam->result_ready = 1;
3939 }
3940
3941 static void
3942   vl_api_one_adjacencies_get_reply_t_handler_json
3943   (vl_api_one_adjacencies_get_reply_t * mp)
3944 {
3945   u8 *s = 0;
3946   vat_main_t *vam = &vat_main;
3947   vat_json_node_t *e = 0, root;
3948   u32 i, n;
3949   int retval = clib_net_to_host_u32 (mp->retval);
3950   vl_api_one_adjacency_t *a;
3951
3952   if (retval)
3953     goto end;
3954
3955   n = clib_net_to_host_u32 (mp->count);
3956   vat_json_init_array (&root);
3957
3958   for (i = 0; i < n; i++)
3959     {
3960       e = vat_json_array_add (&root);
3961       a = &mp->adjacencies[i];
3962
3963       vat_json_init_object (e);
3964       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3965                   a->leid_prefix_len);
3966       vec_add1 (s, 0);
3967       vat_json_object_add_string_copy (e, "leid", s);
3968       vec_free (s);
3969
3970       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3971                   a->reid_prefix_len);
3972       vec_add1 (s, 0);
3973       vat_json_object_add_string_copy (e, "reid", s);
3974       vec_free (s);
3975     }
3976
3977   vat_json_print (vam->ofp, &root);
3978   vat_json_free (&root);
3979
3980 end:
3981   vam->retval = retval;
3982   vam->result_ready = 1;
3983 }
3984
3985 static void
3986 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3987 {
3988   vat_main_t *vam = &vat_main;
3989
3990   print (vam->ofp, "%=20U",
3991          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3992          mp->ip_address);
3993 }
3994
3995 static void
3996   vl_api_one_map_server_details_t_handler_json
3997   (vl_api_one_map_server_details_t * mp)
3998 {
3999   vat_main_t *vam = &vat_main;
4000   vat_json_node_t *node = NULL;
4001   struct in6_addr ip6;
4002   struct in_addr ip4;
4003
4004   if (VAT_JSON_ARRAY != vam->json_tree.type)
4005     {
4006       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4007       vat_json_init_array (&vam->json_tree);
4008     }
4009   node = vat_json_array_add (&vam->json_tree);
4010
4011   vat_json_init_object (node);
4012   if (mp->is_ipv6)
4013     {
4014       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4015       vat_json_object_add_ip6 (node, "map-server", ip6);
4016     }
4017   else
4018     {
4019       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4020       vat_json_object_add_ip4 (node, "map-server", ip4);
4021     }
4022 }
4023
4024 static void
4025 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4026                                            * mp)
4027 {
4028   vat_main_t *vam = &vat_main;
4029
4030   print (vam->ofp, "%=20U",
4031          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4032          mp->ip_address);
4033 }
4034
4035 static void
4036   vl_api_one_map_resolver_details_t_handler_json
4037   (vl_api_one_map_resolver_details_t * mp)
4038 {
4039   vat_main_t *vam = &vat_main;
4040   vat_json_node_t *node = NULL;
4041   struct in6_addr ip6;
4042   struct in_addr ip4;
4043
4044   if (VAT_JSON_ARRAY != vam->json_tree.type)
4045     {
4046       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4047       vat_json_init_array (&vam->json_tree);
4048     }
4049   node = vat_json_array_add (&vam->json_tree);
4050
4051   vat_json_init_object (node);
4052   if (mp->is_ipv6)
4053     {
4054       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4055       vat_json_object_add_ip6 (node, "map resolver", ip6);
4056     }
4057   else
4058     {
4059       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4060       vat_json_object_add_ip4 (node, "map resolver", ip4);
4061     }
4062 }
4063
4064 static void
4065 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4066 {
4067   vat_main_t *vam = &vat_main;
4068   i32 retval = ntohl (mp->retval);
4069
4070   if (0 <= retval)
4071     {
4072       print (vam->ofp, "feature: %s\ngpe: %s",
4073              mp->feature_status ? "enabled" : "disabled",
4074              mp->gpe_status ? "enabled" : "disabled");
4075     }
4076
4077   vam->retval = retval;
4078   vam->result_ready = 1;
4079 }
4080
4081 static void
4082   vl_api_show_one_status_reply_t_handler_json
4083   (vl_api_show_one_status_reply_t * mp)
4084 {
4085   vat_main_t *vam = &vat_main;
4086   vat_json_node_t node;
4087   u8 *gpe_status = NULL;
4088   u8 *feature_status = NULL;
4089
4090   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4091   feature_status = format (0, "%s",
4092                            mp->feature_status ? "enabled" : "disabled");
4093   vec_add1 (gpe_status, 0);
4094   vec_add1 (feature_status, 0);
4095
4096   vat_json_init_object (&node);
4097   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4098   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4099
4100   vec_free (gpe_status);
4101   vec_free (feature_status);
4102
4103   vat_json_print (vam->ofp, &node);
4104   vat_json_free (&node);
4105
4106   vam->retval = ntohl (mp->retval);
4107   vam->result_ready = 1;
4108 }
4109
4110 static void
4111   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4112   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4113 {
4114   vat_main_t *vam = &vat_main;
4115   i32 retval = ntohl (mp->retval);
4116
4117   if (retval >= 0)
4118     {
4119       print (vam->ofp, "%=20s", mp->locator_set_name);
4120     }
4121
4122   vam->retval = retval;
4123   vam->result_ready = 1;
4124 }
4125
4126 static void
4127   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4128   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4129 {
4130   vat_main_t *vam = &vat_main;
4131   vat_json_node_t *node = NULL;
4132
4133   if (VAT_JSON_ARRAY != vam->json_tree.type)
4134     {
4135       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4136       vat_json_init_array (&vam->json_tree);
4137     }
4138   node = vat_json_array_add (&vam->json_tree);
4139
4140   vat_json_init_object (node);
4141   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4142
4143   vat_json_print (vam->ofp, node);
4144   vat_json_free (node);
4145
4146   vam->retval = ntohl (mp->retval);
4147   vam->result_ready = 1;
4148 }
4149
4150 static u8 *
4151 format_lisp_map_request_mode (u8 * s, va_list * args)
4152 {
4153   u32 mode = va_arg (*args, u32);
4154
4155   switch (mode)
4156     {
4157     case 0:
4158       return format (0, "dst-only");
4159     case 1:
4160       return format (0, "src-dst");
4161     }
4162   return 0;
4163 }
4164
4165 static void
4166   vl_api_show_one_map_request_mode_reply_t_handler
4167   (vl_api_show_one_map_request_mode_reply_t * mp)
4168 {
4169   vat_main_t *vam = &vat_main;
4170   i32 retval = ntohl (mp->retval);
4171
4172   if (0 <= retval)
4173     {
4174       u32 mode = mp->mode;
4175       print (vam->ofp, "map_request_mode: %U",
4176              format_lisp_map_request_mode, mode);
4177     }
4178
4179   vam->retval = retval;
4180   vam->result_ready = 1;
4181 }
4182
4183 static void
4184   vl_api_show_one_map_request_mode_reply_t_handler_json
4185   (vl_api_show_one_map_request_mode_reply_t * mp)
4186 {
4187   vat_main_t *vam = &vat_main;
4188   vat_json_node_t node;
4189   u8 *s = 0;
4190   u32 mode;
4191
4192   mode = mp->mode;
4193   s = format (0, "%U", format_lisp_map_request_mode, mode);
4194   vec_add1 (s, 0);
4195
4196   vat_json_init_object (&node);
4197   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4198   vat_json_print (vam->ofp, &node);
4199   vat_json_free (&node);
4200
4201   vec_free (s);
4202   vam->retval = ntohl (mp->retval);
4203   vam->result_ready = 1;
4204 }
4205
4206 static void
4207   vl_api_one_show_xtr_mode_reply_t_handler
4208   (vl_api_one_show_xtr_mode_reply_t * mp)
4209 {
4210   vat_main_t *vam = &vat_main;
4211   i32 retval = ntohl (mp->retval);
4212
4213   if (0 <= retval)
4214     {
4215       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4216     }
4217
4218   vam->retval = retval;
4219   vam->result_ready = 1;
4220 }
4221
4222 static void
4223   vl_api_one_show_xtr_mode_reply_t_handler_json
4224   (vl_api_one_show_xtr_mode_reply_t * mp)
4225 {
4226   vat_main_t *vam = &vat_main;
4227   vat_json_node_t node;
4228   u8 *status = 0;
4229
4230   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4231   vec_add1 (status, 0);
4232
4233   vat_json_init_object (&node);
4234   vat_json_object_add_string_copy (&node, "status", status);
4235
4236   vec_free (status);
4237
4238   vat_json_print (vam->ofp, &node);
4239   vat_json_free (&node);
4240
4241   vam->retval = ntohl (mp->retval);
4242   vam->result_ready = 1;
4243 }
4244
4245 static void
4246   vl_api_one_show_pitr_mode_reply_t_handler
4247   (vl_api_one_show_pitr_mode_reply_t * mp)
4248 {
4249   vat_main_t *vam = &vat_main;
4250   i32 retval = ntohl (mp->retval);
4251
4252   if (0 <= retval)
4253     {
4254       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4255     }
4256
4257   vam->retval = retval;
4258   vam->result_ready = 1;
4259 }
4260
4261 static void
4262   vl_api_one_show_pitr_mode_reply_t_handler_json
4263   (vl_api_one_show_pitr_mode_reply_t * mp)
4264 {
4265   vat_main_t *vam = &vat_main;
4266   vat_json_node_t node;
4267   u8 *status = 0;
4268
4269   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4270   vec_add1 (status, 0);
4271
4272   vat_json_init_object (&node);
4273   vat_json_object_add_string_copy (&node, "status", status);
4274
4275   vec_free (status);
4276
4277   vat_json_print (vam->ofp, &node);
4278   vat_json_free (&node);
4279
4280   vam->retval = ntohl (mp->retval);
4281   vam->result_ready = 1;
4282 }
4283
4284 static void
4285   vl_api_one_show_petr_mode_reply_t_handler
4286   (vl_api_one_show_petr_mode_reply_t * mp)
4287 {
4288   vat_main_t *vam = &vat_main;
4289   i32 retval = ntohl (mp->retval);
4290
4291   if (0 <= retval)
4292     {
4293       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4294     }
4295
4296   vam->retval = retval;
4297   vam->result_ready = 1;
4298 }
4299
4300 static void
4301   vl_api_one_show_petr_mode_reply_t_handler_json
4302   (vl_api_one_show_petr_mode_reply_t * mp)
4303 {
4304   vat_main_t *vam = &vat_main;
4305   vat_json_node_t node;
4306   u8 *status = 0;
4307
4308   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4309   vec_add1 (status, 0);
4310
4311   vat_json_init_object (&node);
4312   vat_json_object_add_string_copy (&node, "status", status);
4313
4314   vec_free (status);
4315
4316   vat_json_print (vam->ofp, &node);
4317   vat_json_free (&node);
4318
4319   vam->retval = ntohl (mp->retval);
4320   vam->result_ready = 1;
4321 }
4322
4323 static void
4324   vl_api_show_one_use_petr_reply_t_handler
4325   (vl_api_show_one_use_petr_reply_t * mp)
4326 {
4327   vat_main_t *vam = &vat_main;
4328   i32 retval = ntohl (mp->retval);
4329
4330   if (0 <= retval)
4331     {
4332       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4333       if (mp->status)
4334         {
4335           print (vam->ofp, "Proxy-ETR address; %U",
4336                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4337                  mp->address);
4338         }
4339     }
4340
4341   vam->retval = retval;
4342   vam->result_ready = 1;
4343 }
4344
4345 static void
4346   vl_api_show_one_use_petr_reply_t_handler_json
4347   (vl_api_show_one_use_petr_reply_t * mp)
4348 {
4349   vat_main_t *vam = &vat_main;
4350   vat_json_node_t node;
4351   u8 *status = 0;
4352   struct in_addr ip4;
4353   struct in6_addr ip6;
4354
4355   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4356   vec_add1 (status, 0);
4357
4358   vat_json_init_object (&node);
4359   vat_json_object_add_string_copy (&node, "status", status);
4360   if (mp->status)
4361     {
4362       if (mp->is_ip4)
4363         {
4364           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4365           vat_json_object_add_ip6 (&node, "address", ip6);
4366         }
4367       else
4368         {
4369           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4370           vat_json_object_add_ip4 (&node, "address", ip4);
4371         }
4372     }
4373
4374   vec_free (status);
4375
4376   vat_json_print (vam->ofp, &node);
4377   vat_json_free (&node);
4378
4379   vam->retval = ntohl (mp->retval);
4380   vam->result_ready = 1;
4381 }
4382
4383 static void
4384   vl_api_show_one_nsh_mapping_reply_t_handler
4385   (vl_api_show_one_nsh_mapping_reply_t * mp)
4386 {
4387   vat_main_t *vam = &vat_main;
4388   i32 retval = ntohl (mp->retval);
4389
4390   if (0 <= retval)
4391     {
4392       print (vam->ofp, "%-20s%-16s",
4393              mp->is_set ? "set" : "not-set",
4394              mp->is_set ? (char *) mp->locator_set_name : "");
4395     }
4396
4397   vam->retval = retval;
4398   vam->result_ready = 1;
4399 }
4400
4401 static void
4402   vl_api_show_one_nsh_mapping_reply_t_handler_json
4403   (vl_api_show_one_nsh_mapping_reply_t * mp)
4404 {
4405   vat_main_t *vam = &vat_main;
4406   vat_json_node_t node;
4407   u8 *status = 0;
4408
4409   status = format (0, "%s", mp->is_set ? "yes" : "no");
4410   vec_add1 (status, 0);
4411
4412   vat_json_init_object (&node);
4413   vat_json_object_add_string_copy (&node, "is_set", status);
4414   if (mp->is_set)
4415     {
4416       vat_json_object_add_string_copy (&node, "locator_set",
4417                                        mp->locator_set_name);
4418     }
4419
4420   vec_free (status);
4421
4422   vat_json_print (vam->ofp, &node);
4423   vat_json_free (&node);
4424
4425   vam->retval = ntohl (mp->retval);
4426   vam->result_ready = 1;
4427 }
4428
4429 static void
4430   vl_api_show_one_map_register_ttl_reply_t_handler
4431   (vl_api_show_one_map_register_ttl_reply_t * mp)
4432 {
4433   vat_main_t *vam = &vat_main;
4434   i32 retval = ntohl (mp->retval);
4435
4436   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4437
4438   if (0 <= retval)
4439     {
4440       print (vam->ofp, "ttl: %u", mp->ttl);
4441     }
4442
4443   vam->retval = retval;
4444   vam->result_ready = 1;
4445 }
4446
4447 static void
4448   vl_api_show_one_map_register_ttl_reply_t_handler_json
4449   (vl_api_show_one_map_register_ttl_reply_t * mp)
4450 {
4451   vat_main_t *vam = &vat_main;
4452   vat_json_node_t node;
4453
4454   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4455   vat_json_init_object (&node);
4456   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4457
4458   vat_json_print (vam->ofp, &node);
4459   vat_json_free (&node);
4460
4461   vam->retval = ntohl (mp->retval);
4462   vam->result_ready = 1;
4463 }
4464
4465 static void
4466 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4467 {
4468   vat_main_t *vam = &vat_main;
4469   i32 retval = ntohl (mp->retval);
4470
4471   if (0 <= retval)
4472     {
4473       print (vam->ofp, "%-20s%-16s",
4474              mp->status ? "enabled" : "disabled",
4475              mp->status ? (char *) mp->locator_set_name : "");
4476     }
4477
4478   vam->retval = retval;
4479   vam->result_ready = 1;
4480 }
4481
4482 static void
4483 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4484 {
4485   vat_main_t *vam = &vat_main;
4486   vat_json_node_t node;
4487   u8 *status = 0;
4488
4489   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4490   vec_add1 (status, 0);
4491
4492   vat_json_init_object (&node);
4493   vat_json_object_add_string_copy (&node, "status", status);
4494   if (mp->status)
4495     {
4496       vat_json_object_add_string_copy (&node, "locator_set",
4497                                        mp->locator_set_name);
4498     }
4499
4500   vec_free (status);
4501
4502   vat_json_print (vam->ofp, &node);
4503   vat_json_free (&node);
4504
4505   vam->retval = ntohl (mp->retval);
4506   vam->result_ready = 1;
4507 }
4508
4509 static u8 *
4510 format_policer_type (u8 * s, va_list * va)
4511 {
4512   u32 i = va_arg (*va, u32);
4513
4514   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4515     s = format (s, "1r2c");
4516   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4517     s = format (s, "1r3c");
4518   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4519     s = format (s, "2r3c-2698");
4520   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4521     s = format (s, "2r3c-4115");
4522   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4523     s = format (s, "2r3c-mef5cf1");
4524   else
4525     s = format (s, "ILLEGAL");
4526   return s;
4527 }
4528
4529 static u8 *
4530 format_policer_rate_type (u8 * s, va_list * va)
4531 {
4532   u32 i = va_arg (*va, u32);
4533
4534   if (i == SSE2_QOS_RATE_KBPS)
4535     s = format (s, "kbps");
4536   else if (i == SSE2_QOS_RATE_PPS)
4537     s = format (s, "pps");
4538   else
4539     s = format (s, "ILLEGAL");
4540   return s;
4541 }
4542
4543 static u8 *
4544 format_policer_round_type (u8 * s, va_list * va)
4545 {
4546   u32 i = va_arg (*va, u32);
4547
4548   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4549     s = format (s, "closest");
4550   else if (i == SSE2_QOS_ROUND_TO_UP)
4551     s = format (s, "up");
4552   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4553     s = format (s, "down");
4554   else
4555     s = format (s, "ILLEGAL");
4556   return s;
4557 }
4558
4559 static u8 *
4560 format_policer_action_type (u8 * s, va_list * va)
4561 {
4562   u32 i = va_arg (*va, u32);
4563
4564   if (i == SSE2_QOS_ACTION_DROP)
4565     s = format (s, "drop");
4566   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4567     s = format (s, "transmit");
4568   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4569     s = format (s, "mark-and-transmit");
4570   else
4571     s = format (s, "ILLEGAL");
4572   return s;
4573 }
4574
4575 static u8 *
4576 format_dscp (u8 * s, va_list * va)
4577 {
4578   u32 i = va_arg (*va, u32);
4579   char *t = 0;
4580
4581   switch (i)
4582     {
4583 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4584       foreach_vnet_dscp
4585 #undef _
4586     default:
4587       return format (s, "ILLEGAL");
4588     }
4589   s = format (s, "%s", t);
4590   return s;
4591 }
4592
4593 static void
4594 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4595 {
4596   vat_main_t *vam = &vat_main;
4597   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4598
4599   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4600     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4601   else
4602     conform_dscp_str = format (0, "");
4603
4604   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4605     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4606   else
4607     exceed_dscp_str = format (0, "");
4608
4609   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4610     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4611   else
4612     violate_dscp_str = format (0, "");
4613
4614   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4615          "rate type %U, round type %U, %s rate, %s color-aware, "
4616          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4617          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4618          "conform action %U%s, exceed action %U%s, violate action %U%s",
4619          mp->name,
4620          format_policer_type, mp->type,
4621          ntohl (mp->cir),
4622          ntohl (mp->eir),
4623          clib_net_to_host_u64 (mp->cb),
4624          clib_net_to_host_u64 (mp->eb),
4625          format_policer_rate_type, mp->rate_type,
4626          format_policer_round_type, mp->round_type,
4627          mp->single_rate ? "single" : "dual",
4628          mp->color_aware ? "is" : "not",
4629          ntohl (mp->cir_tokens_per_period),
4630          ntohl (mp->pir_tokens_per_period),
4631          ntohl (mp->scale),
4632          ntohl (mp->current_limit),
4633          ntohl (mp->current_bucket),
4634          ntohl (mp->extended_limit),
4635          ntohl (mp->extended_bucket),
4636          clib_net_to_host_u64 (mp->last_update_time),
4637          format_policer_action_type, mp->conform_action_type,
4638          conform_dscp_str,
4639          format_policer_action_type, mp->exceed_action_type,
4640          exceed_dscp_str,
4641          format_policer_action_type, mp->violate_action_type,
4642          violate_dscp_str);
4643
4644   vec_free (conform_dscp_str);
4645   vec_free (exceed_dscp_str);
4646   vec_free (violate_dscp_str);
4647 }
4648
4649 static void vl_api_policer_details_t_handler_json
4650   (vl_api_policer_details_t * mp)
4651 {
4652   vat_main_t *vam = &vat_main;
4653   vat_json_node_t *node;
4654   u8 *rate_type_str, *round_type_str, *type_str;
4655   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4656
4657   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4658   round_type_str =
4659     format (0, "%U", format_policer_round_type, mp->round_type);
4660   type_str = format (0, "%U", format_policer_type, mp->type);
4661   conform_action_str = format (0, "%U", format_policer_action_type,
4662                                mp->conform_action_type);
4663   exceed_action_str = format (0, "%U", format_policer_action_type,
4664                               mp->exceed_action_type);
4665   violate_action_str = format (0, "%U", format_policer_action_type,
4666                                mp->violate_action_type);
4667
4668   if (VAT_JSON_ARRAY != vam->json_tree.type)
4669     {
4670       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4671       vat_json_init_array (&vam->json_tree);
4672     }
4673   node = vat_json_array_add (&vam->json_tree);
4674
4675   vat_json_init_object (node);
4676   vat_json_object_add_string_copy (node, "name", mp->name);
4677   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4678   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4679   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4680   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4681   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4682   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4683   vat_json_object_add_string_copy (node, "type", type_str);
4684   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4685   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4686   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4687   vat_json_object_add_uint (node, "cir_tokens_per_period",
4688                             ntohl (mp->cir_tokens_per_period));
4689   vat_json_object_add_uint (node, "eir_tokens_per_period",
4690                             ntohl (mp->pir_tokens_per_period));
4691   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4692   vat_json_object_add_uint (node, "current_bucket",
4693                             ntohl (mp->current_bucket));
4694   vat_json_object_add_uint (node, "extended_limit",
4695                             ntohl (mp->extended_limit));
4696   vat_json_object_add_uint (node, "extended_bucket",
4697                             ntohl (mp->extended_bucket));
4698   vat_json_object_add_uint (node, "last_update_time",
4699                             ntohl (mp->last_update_time));
4700   vat_json_object_add_string_copy (node, "conform_action",
4701                                    conform_action_str);
4702   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4703     {
4704       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4705       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4706       vec_free (dscp_str);
4707     }
4708   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4709   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4710     {
4711       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4712       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4713       vec_free (dscp_str);
4714     }
4715   vat_json_object_add_string_copy (node, "violate_action",
4716                                    violate_action_str);
4717   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4718     {
4719       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4720       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4721       vec_free (dscp_str);
4722     }
4723
4724   vec_free (rate_type_str);
4725   vec_free (round_type_str);
4726   vec_free (type_str);
4727   vec_free (conform_action_str);
4728   vec_free (exceed_action_str);
4729   vec_free (violate_action_str);
4730 }
4731
4732 static void
4733 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4734                                            mp)
4735 {
4736   vat_main_t *vam = &vat_main;
4737   int i, count = ntohl (mp->count);
4738
4739   if (count > 0)
4740     print (vam->ofp, "classify table ids (%d) : ", count);
4741   for (i = 0; i < count; i++)
4742     {
4743       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4744       print (vam->ofp, (i < count - 1) ? "," : "");
4745     }
4746   vam->retval = ntohl (mp->retval);
4747   vam->result_ready = 1;
4748 }
4749
4750 static void
4751   vl_api_classify_table_ids_reply_t_handler_json
4752   (vl_api_classify_table_ids_reply_t * mp)
4753 {
4754   vat_main_t *vam = &vat_main;
4755   int i, count = ntohl (mp->count);
4756
4757   if (count > 0)
4758     {
4759       vat_json_node_t node;
4760
4761       vat_json_init_object (&node);
4762       for (i = 0; i < count; i++)
4763         {
4764           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4765         }
4766       vat_json_print (vam->ofp, &node);
4767       vat_json_free (&node);
4768     }
4769   vam->retval = ntohl (mp->retval);
4770   vam->result_ready = 1;
4771 }
4772
4773 static void
4774   vl_api_classify_table_by_interface_reply_t_handler
4775   (vl_api_classify_table_by_interface_reply_t * mp)
4776 {
4777   vat_main_t *vam = &vat_main;
4778   u32 table_id;
4779
4780   table_id = ntohl (mp->l2_table_id);
4781   if (table_id != ~0)
4782     print (vam->ofp, "l2 table id : %d", table_id);
4783   else
4784     print (vam->ofp, "l2 table id : No input ACL tables configured");
4785   table_id = ntohl (mp->ip4_table_id);
4786   if (table_id != ~0)
4787     print (vam->ofp, "ip4 table id : %d", table_id);
4788   else
4789     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4790   table_id = ntohl (mp->ip6_table_id);
4791   if (table_id != ~0)
4792     print (vam->ofp, "ip6 table id : %d", table_id);
4793   else
4794     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4795   vam->retval = ntohl (mp->retval);
4796   vam->result_ready = 1;
4797 }
4798
4799 static void
4800   vl_api_classify_table_by_interface_reply_t_handler_json
4801   (vl_api_classify_table_by_interface_reply_t * mp)
4802 {
4803   vat_main_t *vam = &vat_main;
4804   vat_json_node_t node;
4805
4806   vat_json_init_object (&node);
4807
4808   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4809   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4810   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4811
4812   vat_json_print (vam->ofp, &node);
4813   vat_json_free (&node);
4814
4815   vam->retval = ntohl (mp->retval);
4816   vam->result_ready = 1;
4817 }
4818
4819 static void vl_api_policer_add_del_reply_t_handler
4820   (vl_api_policer_add_del_reply_t * mp)
4821 {
4822   vat_main_t *vam = &vat_main;
4823   i32 retval = ntohl (mp->retval);
4824   if (vam->async_mode)
4825     {
4826       vam->async_errors += (retval < 0);
4827     }
4828   else
4829     {
4830       vam->retval = retval;
4831       vam->result_ready = 1;
4832       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4833         /*
4834          * Note: this is just barely thread-safe, depends on
4835          * the main thread spinning waiting for an answer...
4836          */
4837         errmsg ("policer index %d", ntohl (mp->policer_index));
4838     }
4839 }
4840
4841 static void vl_api_policer_add_del_reply_t_handler_json
4842   (vl_api_policer_add_del_reply_t * mp)
4843 {
4844   vat_main_t *vam = &vat_main;
4845   vat_json_node_t node;
4846
4847   vat_json_init_object (&node);
4848   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4849   vat_json_object_add_uint (&node, "policer_index",
4850                             ntohl (mp->policer_index));
4851
4852   vat_json_print (vam->ofp, &node);
4853   vat_json_free (&node);
4854
4855   vam->retval = ntohl (mp->retval);
4856   vam->result_ready = 1;
4857 }
4858
4859 /* Format hex dump. */
4860 u8 *
4861 format_hex_bytes (u8 * s, va_list * va)
4862 {
4863   u8 *bytes = va_arg (*va, u8 *);
4864   int n_bytes = va_arg (*va, int);
4865   uword i;
4866
4867   /* Print short or long form depending on byte count. */
4868   uword short_form = n_bytes <= 32;
4869   u32 indent = format_get_indent (s);
4870
4871   if (n_bytes == 0)
4872     return s;
4873
4874   for (i = 0; i < n_bytes; i++)
4875     {
4876       if (!short_form && (i % 32) == 0)
4877         s = format (s, "%08x: ", i);
4878       s = format (s, "%02x", bytes[i]);
4879       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4880         s = format (s, "\n%U", format_white_space, indent);
4881     }
4882
4883   return s;
4884 }
4885
4886 static void
4887 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4888                                             * mp)
4889 {
4890   vat_main_t *vam = &vat_main;
4891   i32 retval = ntohl (mp->retval);
4892   if (retval == 0)
4893     {
4894       print (vam->ofp, "classify table info :");
4895       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4896              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4897              ntohl (mp->miss_next_index));
4898       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4899              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4900              ntohl (mp->match_n_vectors));
4901       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4902              ntohl (mp->mask_length));
4903     }
4904   vam->retval = retval;
4905   vam->result_ready = 1;
4906 }
4907
4908 static void
4909   vl_api_classify_table_info_reply_t_handler_json
4910   (vl_api_classify_table_info_reply_t * mp)
4911 {
4912   vat_main_t *vam = &vat_main;
4913   vat_json_node_t node;
4914
4915   i32 retval = ntohl (mp->retval);
4916   if (retval == 0)
4917     {
4918       vat_json_init_object (&node);
4919
4920       vat_json_object_add_int (&node, "sessions",
4921                                ntohl (mp->active_sessions));
4922       vat_json_object_add_int (&node, "nexttbl",
4923                                ntohl (mp->next_table_index));
4924       vat_json_object_add_int (&node, "nextnode",
4925                                ntohl (mp->miss_next_index));
4926       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4927       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4928       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4929       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4930                       ntohl (mp->mask_length), 0);
4931       vat_json_object_add_string_copy (&node, "mask", s);
4932
4933       vat_json_print (vam->ofp, &node);
4934       vat_json_free (&node);
4935     }
4936   vam->retval = ntohl (mp->retval);
4937   vam->result_ready = 1;
4938 }
4939
4940 static void
4941 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4942                                            mp)
4943 {
4944   vat_main_t *vam = &vat_main;
4945
4946   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4947          ntohl (mp->hit_next_index), ntohl (mp->advance),
4948          ntohl (mp->opaque_index));
4949   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4950          ntohl (mp->match_length));
4951 }
4952
4953 static void
4954   vl_api_classify_session_details_t_handler_json
4955   (vl_api_classify_session_details_t * mp)
4956 {
4957   vat_main_t *vam = &vat_main;
4958   vat_json_node_t *node = NULL;
4959
4960   if (VAT_JSON_ARRAY != vam->json_tree.type)
4961     {
4962       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4963       vat_json_init_array (&vam->json_tree);
4964     }
4965   node = vat_json_array_add (&vam->json_tree);
4966
4967   vat_json_init_object (node);
4968   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4969   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4970   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4971   u8 *s =
4972     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4973             0);
4974   vat_json_object_add_string_copy (node, "match", s);
4975 }
4976
4977 static void vl_api_pg_create_interface_reply_t_handler
4978   (vl_api_pg_create_interface_reply_t * mp)
4979 {
4980   vat_main_t *vam = &vat_main;
4981
4982   vam->retval = ntohl (mp->retval);
4983   vam->result_ready = 1;
4984 }
4985
4986 static void vl_api_pg_create_interface_reply_t_handler_json
4987   (vl_api_pg_create_interface_reply_t * mp)
4988 {
4989   vat_main_t *vam = &vat_main;
4990   vat_json_node_t node;
4991
4992   i32 retval = ntohl (mp->retval);
4993   if (retval == 0)
4994     {
4995       vat_json_init_object (&node);
4996
4997       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4998
4999       vat_json_print (vam->ofp, &node);
5000       vat_json_free (&node);
5001     }
5002   vam->retval = ntohl (mp->retval);
5003   vam->result_ready = 1;
5004 }
5005
5006 static void vl_api_policer_classify_details_t_handler
5007   (vl_api_policer_classify_details_t * mp)
5008 {
5009   vat_main_t *vam = &vat_main;
5010
5011   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5012          ntohl (mp->table_index));
5013 }
5014
5015 static void vl_api_policer_classify_details_t_handler_json
5016   (vl_api_policer_classify_details_t * mp)
5017 {
5018   vat_main_t *vam = &vat_main;
5019   vat_json_node_t *node;
5020
5021   if (VAT_JSON_ARRAY != vam->json_tree.type)
5022     {
5023       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5024       vat_json_init_array (&vam->json_tree);
5025     }
5026   node = vat_json_array_add (&vam->json_tree);
5027
5028   vat_json_init_object (node);
5029   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5030   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5031 }
5032
5033 static void vl_api_flow_classify_details_t_handler
5034   (vl_api_flow_classify_details_t * mp)
5035 {
5036   vat_main_t *vam = &vat_main;
5037
5038   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5039          ntohl (mp->table_index));
5040 }
5041
5042 static void vl_api_flow_classify_details_t_handler_json
5043   (vl_api_flow_classify_details_t * mp)
5044 {
5045   vat_main_t *vam = &vat_main;
5046   vat_json_node_t *node;
5047
5048   if (VAT_JSON_ARRAY != vam->json_tree.type)
5049     {
5050       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5051       vat_json_init_array (&vam->json_tree);
5052     }
5053   node = vat_json_array_add (&vam->json_tree);
5054
5055   vat_json_init_object (node);
5056   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5057   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5058 }
5059
5060 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5061 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5062 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5063 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5064 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5065 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5066 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5067 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5068 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5069 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5070
5071 /*
5072  * Generate boilerplate reply handlers, which
5073  * dig the return value out of the xxx_reply_t API message,
5074  * stick it into vam->retval, and set vam->result_ready
5075  *
5076  * Could also do this by pointing N message decode slots at
5077  * a single function, but that could break in subtle ways.
5078  */
5079
5080 #define foreach_standard_reply_retval_handler           \
5081 _(sw_interface_set_flags_reply)                         \
5082 _(sw_interface_add_del_address_reply)                   \
5083 _(sw_interface_set_rx_mode_reply)                       \
5084 _(sw_interface_set_rx_placement_reply)                  \
5085 _(sw_interface_set_table_reply)                         \
5086 _(sw_interface_set_mpls_enable_reply)                   \
5087 _(sw_interface_set_vpath_reply)                         \
5088 _(sw_interface_set_vxlan_bypass_reply)                  \
5089 _(sw_interface_set_geneve_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_mroute_add_del_reply)                              \
5101 _(mpls_route_add_del_reply)                             \
5102 _(mpls_table_add_del_reply)                             \
5103 _(mpls_ip_bind_unbind_reply)                            \
5104 _(bier_route_add_del_reply)                             \
5105 _(bier_table_add_del_reply)                             \
5106 _(proxy_arp_add_del_reply)                              \
5107 _(proxy_arp_intfc_enable_disable_reply)                 \
5108 _(sw_interface_set_unnumbered_reply)                    \
5109 _(ip_neighbor_add_del_reply)                            \
5110 _(reset_fib_reply)                                      \
5111 _(dhcp_proxy_config_reply)                              \
5112 _(dhcp_proxy_set_vss_reply)                             \
5113 _(dhcp_client_config_reply)                             \
5114 _(set_ip_flow_hash_reply)                               \
5115 _(sw_interface_ip6_enable_disable_reply)                \
5116 _(ip6nd_proxy_add_del_reply)                            \
5117 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5118 _(sw_interface_ip6nd_ra_config_reply)                   \
5119 _(set_arp_neighbor_limit_reply)                         \
5120 _(l2_patch_add_del_reply)                               \
5121 _(sr_mpls_policy_add_reply)                             \
5122 _(sr_mpls_policy_mod_reply)                             \
5123 _(sr_mpls_policy_del_reply)                             \
5124 _(sr_policy_add_reply)                                  \
5125 _(sr_policy_mod_reply)                                  \
5126 _(sr_policy_del_reply)                                  \
5127 _(sr_localsid_add_del_reply)                            \
5128 _(sr_steering_add_del_reply)                            \
5129 _(classify_add_del_session_reply)                       \
5130 _(classify_set_interface_ip_table_reply)                \
5131 _(classify_set_interface_l2_tables_reply)               \
5132 _(l2tpv3_set_tunnel_cookies_reply)                      \
5133 _(l2tpv3_interface_enable_disable_reply)                \
5134 _(l2tpv3_set_lookup_key_reply)                          \
5135 _(l2_fib_clear_table_reply)                             \
5136 _(l2_interface_efp_filter_reply)                        \
5137 _(l2_interface_vlan_tag_rewrite_reply)                  \
5138 _(modify_vhost_user_if_reply)                           \
5139 _(delete_vhost_user_if_reply)                           \
5140 _(ip_probe_neighbor_reply)                              \
5141 _(ip_scan_neighbor_enable_disable_reply)                \
5142 _(want_ip4_arp_events_reply)                            \
5143 _(want_ip6_nd_events_reply)                             \
5144 _(want_l2_macs_events_reply)                            \
5145 _(input_acl_set_interface_reply)                        \
5146 _(ipsec_spd_add_del_reply)                              \
5147 _(ipsec_interface_add_del_spd_reply)                    \
5148 _(ipsec_spd_entry_add_del_reply)                        \
5149 _(ipsec_sad_entry_add_del_reply)                        \
5150 _(ipsec_tunnel_if_add_del_reply)                        \
5151 _(ipsec_tunnel_if_set_sa_reply)                         \
5152 _(delete_loopback_reply)                                \
5153 _(bd_ip_mac_add_del_reply)                              \
5154 _(bd_ip_mac_flush_reply)                                \
5155 _(want_interface_events_reply)                          \
5156 _(cop_interface_enable_disable_reply)                   \
5157 _(cop_whitelist_enable_disable_reply)                   \
5158 _(sw_interface_clear_stats_reply)                       \
5159 _(ioam_enable_reply)                                    \
5160 _(ioam_disable_reply)                                   \
5161 _(one_add_del_locator_reply)                            \
5162 _(one_add_del_local_eid_reply)                          \
5163 _(one_add_del_remote_mapping_reply)                     \
5164 _(one_add_del_adjacency_reply)                          \
5165 _(one_add_del_map_resolver_reply)                       \
5166 _(one_add_del_map_server_reply)                         \
5167 _(one_enable_disable_reply)                             \
5168 _(one_rloc_probe_enable_disable_reply)                  \
5169 _(one_map_register_enable_disable_reply)                \
5170 _(one_map_register_set_ttl_reply)                       \
5171 _(one_set_transport_protocol_reply)                     \
5172 _(one_map_register_fallback_threshold_reply)            \
5173 _(one_pitr_set_locator_set_reply)                       \
5174 _(one_map_request_mode_reply)                           \
5175 _(one_add_del_map_request_itr_rlocs_reply)              \
5176 _(one_eid_table_add_del_map_reply)                      \
5177 _(one_use_petr_reply)                                   \
5178 _(one_stats_enable_disable_reply)                       \
5179 _(one_add_del_l2_arp_entry_reply)                       \
5180 _(one_add_del_ndp_entry_reply)                          \
5181 _(one_stats_flush_reply)                                \
5182 _(one_enable_disable_xtr_mode_reply)                    \
5183 _(one_enable_disable_pitr_mode_reply)                   \
5184 _(one_enable_disable_petr_mode_reply)                   \
5185 _(gpe_enable_disable_reply)                             \
5186 _(gpe_set_encap_mode_reply)                             \
5187 _(gpe_add_del_iface_reply)                              \
5188 _(gpe_add_del_native_fwd_rpath_reply)                   \
5189 _(af_packet_delete_reply)                               \
5190 _(policer_classify_set_interface_reply)                 \
5191 _(netmap_create_reply)                                  \
5192 _(netmap_delete_reply)                                  \
5193 _(set_ipfix_exporter_reply)                             \
5194 _(set_ipfix_classify_stream_reply)                      \
5195 _(ipfix_classify_table_add_del_reply)                   \
5196 _(flow_classify_set_interface_reply)                    \
5197 _(sw_interface_span_enable_disable_reply)               \
5198 _(pg_capture_reply)                                     \
5199 _(pg_enable_disable_reply)                              \
5200 _(ip_source_and_port_range_check_add_del_reply)         \
5201 _(ip_source_and_port_range_check_interface_add_del_reply)\
5202 _(delete_subif_reply)                                   \
5203 _(l2_interface_pbb_tag_rewrite_reply)                   \
5204 _(set_punt_reply)                                       \
5205 _(feature_enable_disable_reply)                         \
5206 _(sw_interface_tag_add_del_reply)                       \
5207 _(hw_interface_set_mtu_reply)                           \
5208 _(p2p_ethernet_add_reply)                               \
5209 _(p2p_ethernet_del_reply)                               \
5210 _(lldp_config_reply)                                    \
5211 _(sw_interface_set_lldp_reply)                          \
5212 _(tcp_configure_src_addresses_reply)                    \
5213 _(session_rule_add_del_reply)                           \
5214 _(ip_container_proxy_add_del_reply)                     \
5215 _(output_acl_set_interface_reply)                       \
5216 _(qos_record_enable_disable_reply)
5217
5218 #define _(n)                                    \
5219     static void vl_api_##n##_t_handler          \
5220     (vl_api_##n##_t * mp)                       \
5221     {                                           \
5222         vat_main_t * vam = &vat_main;           \
5223         i32 retval = ntohl(mp->retval);         \
5224         if (vam->async_mode) {                  \
5225             vam->async_errors += (retval < 0);  \
5226         } else {                                \
5227             vam->retval = retval;               \
5228             vam->result_ready = 1;              \
5229         }                                       \
5230     }
5231 foreach_standard_reply_retval_handler;
5232 #undef _
5233
5234 #define _(n)                                    \
5235     static void vl_api_##n##_t_handler_json     \
5236     (vl_api_##n##_t * mp)                       \
5237     {                                           \
5238         vat_main_t * vam = &vat_main;           \
5239         vat_json_node_t node;                   \
5240         vat_json_init_object(&node);            \
5241         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5242         vat_json_print(vam->ofp, &node);        \
5243         vam->retval = ntohl(mp->retval);        \
5244         vam->result_ready = 1;                  \
5245     }
5246 foreach_standard_reply_retval_handler;
5247 #undef _
5248
5249 /*
5250  * Table of message reply handlers, must include boilerplate handlers
5251  * we just generated
5252  */
5253
5254 #define foreach_vpe_api_reply_msg                                       \
5255 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5256 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5257 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5258 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5259 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5260 _(CLI_REPLY, cli_reply)                                                 \
5261 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5262 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5263   sw_interface_add_del_address_reply)                                   \
5264 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5265 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5266 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5267 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5268 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5269 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5270 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5271 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5272 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5273 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5274   sw_interface_set_l2_xconnect_reply)                                   \
5275 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5276   sw_interface_set_l2_bridge_reply)                                     \
5277 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5278 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5279 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5280 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5281 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5282 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5283 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5284 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5285 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5286 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5287 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5288 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5289 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5290 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5291 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5292 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5293 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5294 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5295 _(SW_INTERFACE_SET_BOND_WEIGHT_REPLY, sw_interface_set_bond_weight_reply) \
5296 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5297 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5298 _(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply)                       \
5299 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5300 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5301 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5302 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5303 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5304 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5305 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5306 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5307 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5308   proxy_arp_intfc_enable_disable_reply)                                 \
5309 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5310 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5311   sw_interface_set_unnumbered_reply)                                    \
5312 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5313 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5314 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5315 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5316 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5317 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5318 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5319 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5320 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5321 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5322   sw_interface_ip6_enable_disable_reply)                                \
5323 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5324 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5325 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5326   sw_interface_ip6nd_ra_prefix_reply)                                   \
5327 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5328   sw_interface_ip6nd_ra_config_reply)                                   \
5329 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5330 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5331 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5332 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5333 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5334 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5335 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5336 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5337 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5338 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5339 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5340 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5341 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5342 classify_set_interface_ip_table_reply)                                  \
5343 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5344   classify_set_interface_l2_tables_reply)                               \
5345 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5346 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5347 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5348 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5349 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5350   l2tpv3_interface_enable_disable_reply)                                \
5351 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5352 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5353 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5354 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5355 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5356 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5357 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5358 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5359 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5360 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5361 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5362 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5363 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5364 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5365 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5366 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5367 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5368 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5369 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5370 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5371 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5372 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5373 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5374 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5375 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5376 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5377 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5378 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5379 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5380 _(L2_MACS_EVENT, l2_macs_event)                                         \
5381 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5382 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5383 _(IP_DETAILS, ip_details)                                               \
5384 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5385 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5386 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5387 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5388 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5389 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5390 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5391 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5392 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5393 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5394 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5395 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5396 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5397 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5398 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5399 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5400 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5401 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5402 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5403 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5404 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5405 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5406 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5407 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5408 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5409 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5410 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5411 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5412 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5413   one_map_register_enable_disable_reply)                                \
5414 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5415 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5416 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5417 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5418   one_map_register_fallback_threshold_reply)                            \
5419 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5420   one_rloc_probe_enable_disable_reply)                                  \
5421 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5422 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5423 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5424 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5425 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5426 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5427 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5428 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5429 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5430 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5431 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5432 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5433 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5434 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5435 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5436 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5437   show_one_stats_enable_disable_reply)                                  \
5438 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5439 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5440 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5441 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5442 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5443 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5444 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5445 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5446   one_enable_disable_pitr_mode_reply)                                   \
5447 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5448   one_enable_disable_petr_mode_reply)                                   \
5449 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5450 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5451 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5452 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5453 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5454 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5455 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5456 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5457 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5458 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5459 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5460 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5461   gpe_add_del_native_fwd_rpath_reply)                                   \
5462 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5463   gpe_fwd_entry_path_details)                                           \
5464 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5465 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5466   one_add_del_map_request_itr_rlocs_reply)                              \
5467 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5468   one_get_map_request_itr_rlocs_reply)                                  \
5469 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5470 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5471 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5472 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5473 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5474 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5475   show_one_map_register_state_reply)                                    \
5476 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5477 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5478   show_one_map_register_fallback_threshold_reply)                       \
5479 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5480 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5481 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5482 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5483 _(POLICER_DETAILS, policer_details)                                     \
5484 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5485 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5486 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5487 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5488 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5489 _(MPLS_TABLE_DETAILS, mpls_table_details)                               \
5490 _(MPLS_ROUTE_DETAILS, mpls_route_details)                               \
5491 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5492 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5493 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5494 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5495 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5496 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5497 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5498 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5499 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5500 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5501 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5502 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5503 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5504 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5505 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5506 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5507 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5508 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5509 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5510  ip_source_and_port_range_check_add_del_reply)                          \
5511 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5512  ip_source_and_port_range_check_interface_add_del_reply)                \
5513 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5514 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5515 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5516 _(IP_TABLE_DETAILS, ip_table_details)                                   \
5517 _(IP_ROUTE_DETAILS, ip_route_details)                                   \
5518 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5519 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5520 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5521 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5522 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5523 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5524 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5525 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5526 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5527 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5528 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5529 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5530 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5531 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5532 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5533 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5534 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5535
5536 #define foreach_standalone_reply_msg                                    \
5537 _(SW_INTERFACE_EVENT, sw_interface_event)
5538
5539 typedef struct
5540 {
5541   u8 *name;
5542   u32 value;
5543 } name_sort_t;
5544
5545 #define STR_VTR_OP_CASE(op)     \
5546     case L2_VTR_ ## op:         \
5547         return "" # op;
5548
5549 static const char *
5550 str_vtr_op (u32 vtr_op)
5551 {
5552   switch (vtr_op)
5553     {
5554       STR_VTR_OP_CASE (DISABLED);
5555       STR_VTR_OP_CASE (PUSH_1);
5556       STR_VTR_OP_CASE (PUSH_2);
5557       STR_VTR_OP_CASE (POP_1);
5558       STR_VTR_OP_CASE (POP_2);
5559       STR_VTR_OP_CASE (TRANSLATE_1_1);
5560       STR_VTR_OP_CASE (TRANSLATE_1_2);
5561       STR_VTR_OP_CASE (TRANSLATE_2_1);
5562       STR_VTR_OP_CASE (TRANSLATE_2_2);
5563     }
5564
5565   return "UNKNOWN";
5566 }
5567
5568 static int
5569 dump_sub_interface_table (vat_main_t * vam)
5570 {
5571   const sw_interface_subif_t *sub = NULL;
5572
5573   if (vam->json_output)
5574     {
5575       clib_warning
5576         ("JSON output supported only for VPE API calls and dump_stats_table");
5577       return -99;
5578     }
5579
5580   print (vam->ofp,
5581          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5582          "Interface", "sw_if_index",
5583          "sub id", "dot1ad", "tags", "outer id",
5584          "inner id", "exact", "default", "outer any", "inner any");
5585
5586   vec_foreach (sub, vam->sw_if_subif_table)
5587   {
5588     print (vam->ofp,
5589            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5590            sub->interface_name,
5591            sub->sw_if_index,
5592            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5593            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5594            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5595            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5596     if (sub->vtr_op != L2_VTR_DISABLED)
5597       {
5598         print (vam->ofp,
5599                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5600                "tag1: %d tag2: %d ]",
5601                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5602                sub->vtr_tag1, sub->vtr_tag2);
5603       }
5604   }
5605
5606   return 0;
5607 }
5608
5609 static int
5610 name_sort_cmp (void *a1, void *a2)
5611 {
5612   name_sort_t *n1 = a1;
5613   name_sort_t *n2 = a2;
5614
5615   return strcmp ((char *) n1->name, (char *) n2->name);
5616 }
5617
5618 static int
5619 dump_interface_table (vat_main_t * vam)
5620 {
5621   hash_pair_t *p;
5622   name_sort_t *nses = 0, *ns;
5623
5624   if (vam->json_output)
5625     {
5626       clib_warning
5627         ("JSON output supported only for VPE API calls and dump_stats_table");
5628       return -99;
5629     }
5630
5631   /* *INDENT-OFF* */
5632   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5633   ({
5634     vec_add2 (nses, ns, 1);
5635     ns->name = (u8 *)(p->key);
5636     ns->value = (u32) p->value[0];
5637   }));
5638   /* *INDENT-ON* */
5639
5640   vec_sort_with_function (nses, name_sort_cmp);
5641
5642   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5643   vec_foreach (ns, nses)
5644   {
5645     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5646   }
5647   vec_free (nses);
5648   return 0;
5649 }
5650
5651 static int
5652 dump_ip_table (vat_main_t * vam, int is_ipv6)
5653 {
5654   const ip_details_t *det = NULL;
5655   const ip_address_details_t *address = NULL;
5656   u32 i = ~0;
5657
5658   print (vam->ofp, "%-12s", "sw_if_index");
5659
5660   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5661   {
5662     i++;
5663     if (!det->present)
5664       {
5665         continue;
5666       }
5667     print (vam->ofp, "%-12d", i);
5668     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5669     if (!det->addr)
5670       {
5671         continue;
5672       }
5673     vec_foreach (address, det->addr)
5674     {
5675       print (vam->ofp,
5676              "            %-30U%-13d",
5677              is_ipv6 ? format_ip6_address : format_ip4_address,
5678              address->ip, address->prefix_length);
5679     }
5680   }
5681
5682   return 0;
5683 }
5684
5685 static int
5686 dump_ipv4_table (vat_main_t * vam)
5687 {
5688   if (vam->json_output)
5689     {
5690       clib_warning
5691         ("JSON output supported only for VPE API calls and dump_stats_table");
5692       return -99;
5693     }
5694
5695   return dump_ip_table (vam, 0);
5696 }
5697
5698 static int
5699 dump_ipv6_table (vat_main_t * vam)
5700 {
5701   if (vam->json_output)
5702     {
5703       clib_warning
5704         ("JSON output supported only for VPE API calls and dump_stats_table");
5705       return -99;
5706     }
5707
5708   return dump_ip_table (vam, 1);
5709 }
5710
5711 /*
5712  * Pass CLI buffers directly in the CLI_INBAND API message,
5713  * instead of an additional shared memory area.
5714  */
5715 static int
5716 exec_inband (vat_main_t * vam)
5717 {
5718   vl_api_cli_inband_t *mp;
5719   unformat_input_t *i = vam->input;
5720   int ret;
5721
5722   if (vec_len (i->buffer) == 0)
5723     return -1;
5724
5725   if (vam->exec_mode == 0 && unformat (i, "mode"))
5726     {
5727       vam->exec_mode = 1;
5728       return 0;
5729     }
5730   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5731     {
5732       vam->exec_mode = 0;
5733       return 0;
5734     }
5735
5736   /*
5737    * In order for the CLI command to work, it
5738    * must be a vector ending in \n, not a C-string ending
5739    * in \n\0.
5740    */
5741   u32 len = vec_len (vam->input->buffer);
5742   M2 (CLI_INBAND, mp, len);
5743   vl_api_to_api_string (len - 1, (const char *) vam->input->buffer, &mp->cmd);
5744
5745   S (mp);
5746   W (ret);
5747   /* json responses may or may not include a useful reply... */
5748   if (vec_len (vam->cmd_reply))
5749     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5750   return ret;
5751 }
5752
5753 int
5754 exec (vat_main_t * vam)
5755 {
5756   return exec_inband (vam);
5757 }
5758
5759 static int
5760 api_create_loopback (vat_main_t * vam)
5761 {
5762   unformat_input_t *i = vam->input;
5763   vl_api_create_loopback_t *mp;
5764   vl_api_create_loopback_instance_t *mp_lbi;
5765   u8 mac_address[6];
5766   u8 mac_set = 0;
5767   u8 is_specified = 0;
5768   u32 user_instance = 0;
5769   int ret;
5770
5771   clib_memset (mac_address, 0, sizeof (mac_address));
5772
5773   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5774     {
5775       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5776         mac_set = 1;
5777       if (unformat (i, "instance %d", &user_instance))
5778         is_specified = 1;
5779       else
5780         break;
5781     }
5782
5783   if (is_specified)
5784     {
5785       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5786       mp_lbi->is_specified = is_specified;
5787       if (is_specified)
5788         mp_lbi->user_instance = htonl (user_instance);
5789       if (mac_set)
5790         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5791       S (mp_lbi);
5792     }
5793   else
5794     {
5795       /* Construct the API message */
5796       M (CREATE_LOOPBACK, mp);
5797       if (mac_set)
5798         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5799       S (mp);
5800     }
5801
5802   W (ret);
5803   return ret;
5804 }
5805
5806 static int
5807 api_delete_loopback (vat_main_t * vam)
5808 {
5809   unformat_input_t *i = vam->input;
5810   vl_api_delete_loopback_t *mp;
5811   u32 sw_if_index = ~0;
5812   int ret;
5813
5814   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5815     {
5816       if (unformat (i, "sw_if_index %d", &sw_if_index))
5817         ;
5818       else
5819         break;
5820     }
5821
5822   if (sw_if_index == ~0)
5823     {
5824       errmsg ("missing sw_if_index");
5825       return -99;
5826     }
5827
5828   /* Construct the API message */
5829   M (DELETE_LOOPBACK, mp);
5830   mp->sw_if_index = ntohl (sw_if_index);
5831
5832   S (mp);
5833   W (ret);
5834   return ret;
5835 }
5836
5837 static int
5838 api_want_interface_events (vat_main_t * vam)
5839 {
5840   unformat_input_t *i = vam->input;
5841   vl_api_want_interface_events_t *mp;
5842   int enable = -1;
5843   int ret;
5844
5845   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5846     {
5847       if (unformat (i, "enable"))
5848         enable = 1;
5849       else if (unformat (i, "disable"))
5850         enable = 0;
5851       else
5852         break;
5853     }
5854
5855   if (enable == -1)
5856     {
5857       errmsg ("missing enable|disable");
5858       return -99;
5859     }
5860
5861   M (WANT_INTERFACE_EVENTS, mp);
5862   mp->enable_disable = enable;
5863
5864   vam->interface_event_display = enable;
5865
5866   S (mp);
5867   W (ret);
5868   return ret;
5869 }
5870
5871
5872 /* Note: non-static, called once to set up the initial intfc table */
5873 int
5874 api_sw_interface_dump (vat_main_t * vam)
5875 {
5876   vl_api_sw_interface_dump_t *mp;
5877   vl_api_control_ping_t *mp_ping;
5878   hash_pair_t *p;
5879   name_sort_t *nses = 0, *ns;
5880   sw_interface_subif_t *sub = NULL;
5881   int ret;
5882
5883   /* Toss the old name table */
5884   /* *INDENT-OFF* */
5885   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5886   ({
5887     vec_add2 (nses, ns, 1);
5888     ns->name = (u8 *)(p->key);
5889     ns->value = (u32) p->value[0];
5890   }));
5891   /* *INDENT-ON* */
5892
5893   hash_free (vam->sw_if_index_by_interface_name);
5894
5895   vec_foreach (ns, nses) vec_free (ns->name);
5896
5897   vec_free (nses);
5898
5899   vec_foreach (sub, vam->sw_if_subif_table)
5900   {
5901     vec_free (sub->interface_name);
5902   }
5903   vec_free (vam->sw_if_subif_table);
5904
5905   /* recreate the interface name hash table */
5906   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5907
5908   /*
5909    * Ask for all interface names. Otherwise, the epic catalog of
5910    * name filters becomes ridiculously long, and vat ends up needing
5911    * to be taught about new interface types.
5912    */
5913   M (SW_INTERFACE_DUMP, mp);
5914   S (mp);
5915
5916   /* Use a control ping for synchronization */
5917   MPING (CONTROL_PING, mp_ping);
5918   S (mp_ping);
5919
5920   W (ret);
5921   return ret;
5922 }
5923
5924 static int
5925 api_sw_interface_set_flags (vat_main_t * vam)
5926 {
5927   unformat_input_t *i = vam->input;
5928   vl_api_sw_interface_set_flags_t *mp;
5929   u32 sw_if_index;
5930   u8 sw_if_index_set = 0;
5931   u8 admin_up = 0;
5932   int ret;
5933
5934   /* Parse args required to build the message */
5935   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5936     {
5937       if (unformat (i, "admin-up"))
5938         admin_up = 1;
5939       else if (unformat (i, "admin-down"))
5940         admin_up = 0;
5941       else
5942         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5943         sw_if_index_set = 1;
5944       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5945         sw_if_index_set = 1;
5946       else
5947         break;
5948     }
5949
5950   if (sw_if_index_set == 0)
5951     {
5952       errmsg ("missing interface name or sw_if_index");
5953       return -99;
5954     }
5955
5956   /* Construct the API message */
5957   M (SW_INTERFACE_SET_FLAGS, mp);
5958   mp->sw_if_index = ntohl (sw_if_index);
5959   mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
5960
5961   /* send it... */
5962   S (mp);
5963
5964   /* Wait for a reply, return the good/bad news... */
5965   W (ret);
5966   return ret;
5967 }
5968
5969 static int
5970 api_sw_interface_set_rx_mode (vat_main_t * vam)
5971 {
5972   unformat_input_t *i = vam->input;
5973   vl_api_sw_interface_set_rx_mode_t *mp;
5974   u32 sw_if_index;
5975   u8 sw_if_index_set = 0;
5976   int ret;
5977   u8 queue_id_valid = 0;
5978   u32 queue_id;
5979   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
5980
5981   /* Parse args required to build the message */
5982   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5983     {
5984       if (unformat (i, "queue %d", &queue_id))
5985         queue_id_valid = 1;
5986       else if (unformat (i, "polling"))
5987         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
5988       else if (unformat (i, "interrupt"))
5989         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
5990       else if (unformat (i, "adaptive"))
5991         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
5992       else
5993         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5994         sw_if_index_set = 1;
5995       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5996         sw_if_index_set = 1;
5997       else
5998         break;
5999     }
6000
6001   if (sw_if_index_set == 0)
6002     {
6003       errmsg ("missing interface name or sw_if_index");
6004       return -99;
6005     }
6006   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6007     {
6008       errmsg ("missing rx-mode");
6009       return -99;
6010     }
6011
6012   /* Construct the API message */
6013   M (SW_INTERFACE_SET_RX_MODE, mp);
6014   mp->sw_if_index = ntohl (sw_if_index);
6015   mp->mode = (vl_api_rx_mode_t) mode;
6016   mp->queue_id_valid = queue_id_valid;
6017   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6018
6019   /* send it... */
6020   S (mp);
6021
6022   /* Wait for a reply, return the good/bad news... */
6023   W (ret);
6024   return ret;
6025 }
6026
6027 static int
6028 api_sw_interface_set_rx_placement (vat_main_t * vam)
6029 {
6030   unformat_input_t *i = vam->input;
6031   vl_api_sw_interface_set_rx_placement_t *mp;
6032   u32 sw_if_index;
6033   u8 sw_if_index_set = 0;
6034   int ret;
6035   u8 is_main = 0;
6036   u32 queue_id, thread_index;
6037
6038   /* Parse args required to build the message */
6039   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6040     {
6041       if (unformat (i, "queue %d", &queue_id))
6042         ;
6043       else if (unformat (i, "main"))
6044         is_main = 1;
6045       else if (unformat (i, "worker %d", &thread_index))
6046         ;
6047       else
6048         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6049         sw_if_index_set = 1;
6050       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6051         sw_if_index_set = 1;
6052       else
6053         break;
6054     }
6055
6056   if (sw_if_index_set == 0)
6057     {
6058       errmsg ("missing interface name or sw_if_index");
6059       return -99;
6060     }
6061
6062   if (is_main)
6063     thread_index = 0;
6064   /* Construct the API message */
6065   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6066   mp->sw_if_index = ntohl (sw_if_index);
6067   mp->worker_id = ntohl (thread_index);
6068   mp->queue_id = ntohl (queue_id);
6069   mp->is_main = is_main;
6070
6071   /* send it... */
6072   S (mp);
6073   /* Wait for a reply, return the good/bad news... */
6074   W (ret);
6075   return ret;
6076 }
6077
6078 static void vl_api_sw_interface_rx_placement_details_t_handler
6079   (vl_api_sw_interface_rx_placement_details_t * mp)
6080 {
6081   vat_main_t *vam = &vat_main;
6082   u32 worker_id = ntohl (mp->worker_id);
6083
6084   print (vam->ofp,
6085          "\n%-11d %-11s %-6d %-5d %-9s",
6086          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6087          worker_id, ntohl (mp->queue_id),
6088          (mp->mode ==
6089           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6090 }
6091
6092 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6093   (vl_api_sw_interface_rx_placement_details_t * mp)
6094 {
6095   vat_main_t *vam = &vat_main;
6096   vat_json_node_t *node = NULL;
6097
6098   if (VAT_JSON_ARRAY != vam->json_tree.type)
6099     {
6100       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6101       vat_json_init_array (&vam->json_tree);
6102     }
6103   node = vat_json_array_add (&vam->json_tree);
6104
6105   vat_json_init_object (node);
6106   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6107   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6108   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6109   vat_json_object_add_uint (node, "mode", mp->mode);
6110 }
6111
6112 static int
6113 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6114 {
6115   unformat_input_t *i = vam->input;
6116   vl_api_sw_interface_rx_placement_dump_t *mp;
6117   vl_api_control_ping_t *mp_ping;
6118   int ret;
6119   u32 sw_if_index;
6120   u8 sw_if_index_set = 0;
6121
6122   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6123     {
6124       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6125         sw_if_index_set++;
6126       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6127         sw_if_index_set++;
6128       else
6129         break;
6130     }
6131
6132   print (vam->ofp,
6133          "\n%-11s %-11s %-6s %-5s %-4s",
6134          "sw_if_index", "main/worker", "thread", "queue", "mode");
6135
6136   /* Dump Interface rx placement */
6137   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6138
6139   if (sw_if_index_set)
6140     mp->sw_if_index = htonl (sw_if_index);
6141   else
6142     mp->sw_if_index = ~0;
6143
6144   S (mp);
6145
6146   /* Use a control ping for synchronization */
6147   MPING (CONTROL_PING, mp_ping);
6148   S (mp_ping);
6149
6150   W (ret);
6151   return ret;
6152 }
6153
6154 static int
6155 api_sw_interface_clear_stats (vat_main_t * vam)
6156 {
6157   unformat_input_t *i = vam->input;
6158   vl_api_sw_interface_clear_stats_t *mp;
6159   u32 sw_if_index;
6160   u8 sw_if_index_set = 0;
6161   int ret;
6162
6163   /* Parse args required to build the message */
6164   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6165     {
6166       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6167         sw_if_index_set = 1;
6168       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6169         sw_if_index_set = 1;
6170       else
6171         break;
6172     }
6173
6174   /* Construct the API message */
6175   M (SW_INTERFACE_CLEAR_STATS, mp);
6176
6177   if (sw_if_index_set == 1)
6178     mp->sw_if_index = ntohl (sw_if_index);
6179   else
6180     mp->sw_if_index = ~0;
6181
6182   /* send it... */
6183   S (mp);
6184
6185   /* Wait for a reply, return the good/bad news... */
6186   W (ret);
6187   return ret;
6188 }
6189
6190 static int
6191 api_sw_interface_add_del_address (vat_main_t * vam)
6192 {
6193   unformat_input_t *i = vam->input;
6194   vl_api_sw_interface_add_del_address_t *mp;
6195   u32 sw_if_index;
6196   u8 sw_if_index_set = 0;
6197   u8 is_add = 1, del_all = 0;
6198   u32 address_length = 0;
6199   u8 v4_address_set = 0;
6200   u8 v6_address_set = 0;
6201   ip4_address_t v4address;
6202   ip6_address_t v6address;
6203   int ret;
6204
6205   /* Parse args required to build the message */
6206   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6207     {
6208       if (unformat (i, "del-all"))
6209         del_all = 1;
6210       else if (unformat (i, "del"))
6211         is_add = 0;
6212       else
6213         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6214         sw_if_index_set = 1;
6215       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6216         sw_if_index_set = 1;
6217       else if (unformat (i, "%U/%d",
6218                          unformat_ip4_address, &v4address, &address_length))
6219         v4_address_set = 1;
6220       else if (unformat (i, "%U/%d",
6221                          unformat_ip6_address, &v6address, &address_length))
6222         v6_address_set = 1;
6223       else
6224         break;
6225     }
6226
6227   if (sw_if_index_set == 0)
6228     {
6229       errmsg ("missing interface name or sw_if_index");
6230       return -99;
6231     }
6232   if (v4_address_set && v6_address_set)
6233     {
6234       errmsg ("both v4 and v6 addresses set");
6235       return -99;
6236     }
6237   if (!v4_address_set && !v6_address_set && !del_all)
6238     {
6239       errmsg ("no addresses set");
6240       return -99;
6241     }
6242
6243   /* Construct the API message */
6244   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6245
6246   mp->sw_if_index = ntohl (sw_if_index);
6247   mp->is_add = is_add;
6248   mp->del_all = del_all;
6249   if (v6_address_set)
6250     {
6251       mp->prefix.address.af = ADDRESS_IP6;
6252       clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
6253     }
6254   else
6255     {
6256       mp->prefix.address.af = ADDRESS_IP4;
6257       clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
6258     }
6259   mp->prefix.len = address_length;
6260
6261   /* send it... */
6262   S (mp);
6263
6264   /* Wait for a reply, return good/bad news  */
6265   W (ret);
6266   return ret;
6267 }
6268
6269 static int
6270 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6271 {
6272   unformat_input_t *i = vam->input;
6273   vl_api_sw_interface_set_mpls_enable_t *mp;
6274   u32 sw_if_index;
6275   u8 sw_if_index_set = 0;
6276   u8 enable = 1;
6277   int ret;
6278
6279   /* Parse args required to build the message */
6280   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6281     {
6282       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6283         sw_if_index_set = 1;
6284       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6285         sw_if_index_set = 1;
6286       else if (unformat (i, "disable"))
6287         enable = 0;
6288       else if (unformat (i, "dis"))
6289         enable = 0;
6290       else
6291         break;
6292     }
6293
6294   if (sw_if_index_set == 0)
6295     {
6296       errmsg ("missing interface name or sw_if_index");
6297       return -99;
6298     }
6299
6300   /* Construct the API message */
6301   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6302
6303   mp->sw_if_index = ntohl (sw_if_index);
6304   mp->enable = enable;
6305
6306   /* send it... */
6307   S (mp);
6308
6309   /* Wait for a reply... */
6310   W (ret);
6311   return ret;
6312 }
6313
6314 static int
6315 api_sw_interface_set_table (vat_main_t * vam)
6316 {
6317   unformat_input_t *i = vam->input;
6318   vl_api_sw_interface_set_table_t *mp;
6319   u32 sw_if_index, vrf_id = 0;
6320   u8 sw_if_index_set = 0;
6321   u8 is_ipv6 = 0;
6322   int ret;
6323
6324   /* Parse args required to build the message */
6325   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6326     {
6327       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6328         sw_if_index_set = 1;
6329       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6330         sw_if_index_set = 1;
6331       else if (unformat (i, "vrf %d", &vrf_id))
6332         ;
6333       else if (unformat (i, "ipv6"))
6334         is_ipv6 = 1;
6335       else
6336         break;
6337     }
6338
6339   if (sw_if_index_set == 0)
6340     {
6341       errmsg ("missing interface name or sw_if_index");
6342       return -99;
6343     }
6344
6345   /* Construct the API message */
6346   M (SW_INTERFACE_SET_TABLE, mp);
6347
6348   mp->sw_if_index = ntohl (sw_if_index);
6349   mp->is_ipv6 = is_ipv6;
6350   mp->vrf_id = ntohl (vrf_id);
6351
6352   /* send it... */
6353   S (mp);
6354
6355   /* Wait for a reply... */
6356   W (ret);
6357   return ret;
6358 }
6359
6360 static void vl_api_sw_interface_get_table_reply_t_handler
6361   (vl_api_sw_interface_get_table_reply_t * mp)
6362 {
6363   vat_main_t *vam = &vat_main;
6364
6365   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6366
6367   vam->retval = ntohl (mp->retval);
6368   vam->result_ready = 1;
6369
6370 }
6371
6372 static void vl_api_sw_interface_get_table_reply_t_handler_json
6373   (vl_api_sw_interface_get_table_reply_t * mp)
6374 {
6375   vat_main_t *vam = &vat_main;
6376   vat_json_node_t node;
6377
6378   vat_json_init_object (&node);
6379   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6380   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6381
6382   vat_json_print (vam->ofp, &node);
6383   vat_json_free (&node);
6384
6385   vam->retval = ntohl (mp->retval);
6386   vam->result_ready = 1;
6387 }
6388
6389 static int
6390 api_sw_interface_get_table (vat_main_t * vam)
6391 {
6392   unformat_input_t *i = vam->input;
6393   vl_api_sw_interface_get_table_t *mp;
6394   u32 sw_if_index;
6395   u8 sw_if_index_set = 0;
6396   u8 is_ipv6 = 0;
6397   int ret;
6398
6399   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6400     {
6401       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6402         sw_if_index_set = 1;
6403       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6404         sw_if_index_set = 1;
6405       else if (unformat (i, "ipv6"))
6406         is_ipv6 = 1;
6407       else
6408         break;
6409     }
6410
6411   if (sw_if_index_set == 0)
6412     {
6413       errmsg ("missing interface name or sw_if_index");
6414       return -99;
6415     }
6416
6417   M (SW_INTERFACE_GET_TABLE, mp);
6418   mp->sw_if_index = htonl (sw_if_index);
6419   mp->is_ipv6 = is_ipv6;
6420
6421   S (mp);
6422   W (ret);
6423   return ret;
6424 }
6425
6426 static int
6427 api_sw_interface_set_vpath (vat_main_t * vam)
6428 {
6429   unformat_input_t *i = vam->input;
6430   vl_api_sw_interface_set_vpath_t *mp;
6431   u32 sw_if_index = 0;
6432   u8 sw_if_index_set = 0;
6433   u8 is_enable = 0;
6434   int ret;
6435
6436   /* Parse args required to build the message */
6437   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6438     {
6439       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6440         sw_if_index_set = 1;
6441       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6442         sw_if_index_set = 1;
6443       else if (unformat (i, "enable"))
6444         is_enable = 1;
6445       else if (unformat (i, "disable"))
6446         is_enable = 0;
6447       else
6448         break;
6449     }
6450
6451   if (sw_if_index_set == 0)
6452     {
6453       errmsg ("missing interface name or sw_if_index");
6454       return -99;
6455     }
6456
6457   /* Construct the API message */
6458   M (SW_INTERFACE_SET_VPATH, mp);
6459
6460   mp->sw_if_index = ntohl (sw_if_index);
6461   mp->enable = is_enable;
6462
6463   /* send it... */
6464   S (mp);
6465
6466   /* Wait for a reply... */
6467   W (ret);
6468   return ret;
6469 }
6470
6471 static int
6472 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6473 {
6474   unformat_input_t *i = vam->input;
6475   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6476   u32 sw_if_index = 0;
6477   u8 sw_if_index_set = 0;
6478   u8 is_enable = 1;
6479   u8 is_ipv6 = 0;
6480   int ret;
6481
6482   /* Parse args required to build the message */
6483   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6484     {
6485       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6486         sw_if_index_set = 1;
6487       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6488         sw_if_index_set = 1;
6489       else if (unformat (i, "enable"))
6490         is_enable = 1;
6491       else if (unformat (i, "disable"))
6492         is_enable = 0;
6493       else if (unformat (i, "ip4"))
6494         is_ipv6 = 0;
6495       else if (unformat (i, "ip6"))
6496         is_ipv6 = 1;
6497       else
6498         break;
6499     }
6500
6501   if (sw_if_index_set == 0)
6502     {
6503       errmsg ("missing interface name or sw_if_index");
6504       return -99;
6505     }
6506
6507   /* Construct the API message */
6508   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6509
6510   mp->sw_if_index = ntohl (sw_if_index);
6511   mp->enable = is_enable;
6512   mp->is_ipv6 = is_ipv6;
6513
6514   /* send it... */
6515   S (mp);
6516
6517   /* Wait for a reply... */
6518   W (ret);
6519   return ret;
6520 }
6521
6522 static int
6523 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6524 {
6525   unformat_input_t *i = vam->input;
6526   vl_api_sw_interface_set_geneve_bypass_t *mp;
6527   u32 sw_if_index = 0;
6528   u8 sw_if_index_set = 0;
6529   u8 is_enable = 1;
6530   u8 is_ipv6 = 0;
6531   int ret;
6532
6533   /* Parse args required to build the message */
6534   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6535     {
6536       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6537         sw_if_index_set = 1;
6538       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6539         sw_if_index_set = 1;
6540       else if (unformat (i, "enable"))
6541         is_enable = 1;
6542       else if (unformat (i, "disable"))
6543         is_enable = 0;
6544       else if (unformat (i, "ip4"))
6545         is_ipv6 = 0;
6546       else if (unformat (i, "ip6"))
6547         is_ipv6 = 1;
6548       else
6549         break;
6550     }
6551
6552   if (sw_if_index_set == 0)
6553     {
6554       errmsg ("missing interface name or sw_if_index");
6555       return -99;
6556     }
6557
6558   /* Construct the API message */
6559   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6560
6561   mp->sw_if_index = ntohl (sw_if_index);
6562   mp->enable = is_enable;
6563   mp->is_ipv6 = is_ipv6;
6564
6565   /* send it... */
6566   S (mp);
6567
6568   /* Wait for a reply... */
6569   W (ret);
6570   return ret;
6571 }
6572
6573 static int
6574 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6575 {
6576   unformat_input_t *i = vam->input;
6577   vl_api_sw_interface_set_l2_xconnect_t *mp;
6578   u32 rx_sw_if_index;
6579   u8 rx_sw_if_index_set = 0;
6580   u32 tx_sw_if_index;
6581   u8 tx_sw_if_index_set = 0;
6582   u8 enable = 1;
6583   int ret;
6584
6585   /* Parse args required to build the message */
6586   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6587     {
6588       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6589         rx_sw_if_index_set = 1;
6590       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6591         tx_sw_if_index_set = 1;
6592       else if (unformat (i, "rx"))
6593         {
6594           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6595             {
6596               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6597                             &rx_sw_if_index))
6598                 rx_sw_if_index_set = 1;
6599             }
6600           else
6601             break;
6602         }
6603       else if (unformat (i, "tx"))
6604         {
6605           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6606             {
6607               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6608                             &tx_sw_if_index))
6609                 tx_sw_if_index_set = 1;
6610             }
6611           else
6612             break;
6613         }
6614       else if (unformat (i, "enable"))
6615         enable = 1;
6616       else if (unformat (i, "disable"))
6617         enable = 0;
6618       else
6619         break;
6620     }
6621
6622   if (rx_sw_if_index_set == 0)
6623     {
6624       errmsg ("missing rx interface name or rx_sw_if_index");
6625       return -99;
6626     }
6627
6628   if (enable && (tx_sw_if_index_set == 0))
6629     {
6630       errmsg ("missing tx interface name or tx_sw_if_index");
6631       return -99;
6632     }
6633
6634   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6635
6636   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6637   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6638   mp->enable = enable;
6639
6640   S (mp);
6641   W (ret);
6642   return ret;
6643 }
6644
6645 static int
6646 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6647 {
6648   unformat_input_t *i = vam->input;
6649   vl_api_sw_interface_set_l2_bridge_t *mp;
6650   vl_api_l2_port_type_t port_type;
6651   u32 rx_sw_if_index;
6652   u8 rx_sw_if_index_set = 0;
6653   u32 bd_id;
6654   u8 bd_id_set = 0;
6655   u32 shg = 0;
6656   u8 enable = 1;
6657   int ret;
6658
6659   port_type = L2_API_PORT_TYPE_NORMAL;
6660
6661   /* Parse args required to build the message */
6662   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6663     {
6664       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6665         rx_sw_if_index_set = 1;
6666       else if (unformat (i, "bd_id %d", &bd_id))
6667         bd_id_set = 1;
6668       else
6669         if (unformat
6670             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6671         rx_sw_if_index_set = 1;
6672       else if (unformat (i, "shg %d", &shg))
6673         ;
6674       else if (unformat (i, "bvi"))
6675         port_type = L2_API_PORT_TYPE_BVI;
6676       else if (unformat (i, "uu-fwd"))
6677         port_type = L2_API_PORT_TYPE_UU_FWD;
6678       else if (unformat (i, "enable"))
6679         enable = 1;
6680       else if (unformat (i, "disable"))
6681         enable = 0;
6682       else
6683         break;
6684     }
6685
6686   if (rx_sw_if_index_set == 0)
6687     {
6688       errmsg ("missing rx interface name or sw_if_index");
6689       return -99;
6690     }
6691
6692   if (enable && (bd_id_set == 0))
6693     {
6694       errmsg ("missing bridge domain");
6695       return -99;
6696     }
6697
6698   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6699
6700   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6701   mp->bd_id = ntohl (bd_id);
6702   mp->shg = (u8) shg;
6703   mp->port_type = ntohl (port_type);
6704   mp->enable = enable;
6705
6706   S (mp);
6707   W (ret);
6708   return ret;
6709 }
6710
6711 static int
6712 api_bridge_domain_dump (vat_main_t * vam)
6713 {
6714   unformat_input_t *i = vam->input;
6715   vl_api_bridge_domain_dump_t *mp;
6716   vl_api_control_ping_t *mp_ping;
6717   u32 bd_id = ~0;
6718   int ret;
6719
6720   /* Parse args required to build the message */
6721   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6722     {
6723       if (unformat (i, "bd_id %d", &bd_id))
6724         ;
6725       else
6726         break;
6727     }
6728
6729   M (BRIDGE_DOMAIN_DUMP, mp);
6730   mp->bd_id = ntohl (bd_id);
6731   S (mp);
6732
6733   /* Use a control ping for synchronization */
6734   MPING (CONTROL_PING, mp_ping);
6735   S (mp_ping);
6736
6737   W (ret);
6738   return ret;
6739 }
6740
6741 static int
6742 api_bridge_domain_add_del (vat_main_t * vam)
6743 {
6744   unformat_input_t *i = vam->input;
6745   vl_api_bridge_domain_add_del_t *mp;
6746   u32 bd_id = ~0;
6747   u8 is_add = 1;
6748   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6749   u8 *bd_tag = NULL;
6750   u32 mac_age = 0;
6751   int ret;
6752
6753   /* Parse args required to build the message */
6754   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6755     {
6756       if (unformat (i, "bd_id %d", &bd_id))
6757         ;
6758       else if (unformat (i, "flood %d", &flood))
6759         ;
6760       else if (unformat (i, "uu-flood %d", &uu_flood))
6761         ;
6762       else if (unformat (i, "forward %d", &forward))
6763         ;
6764       else if (unformat (i, "learn %d", &learn))
6765         ;
6766       else if (unformat (i, "arp-term %d", &arp_term))
6767         ;
6768       else if (unformat (i, "mac-age %d", &mac_age))
6769         ;
6770       else if (unformat (i, "bd-tag %s", &bd_tag))
6771         ;
6772       else if (unformat (i, "del"))
6773         {
6774           is_add = 0;
6775           flood = uu_flood = forward = learn = 0;
6776         }
6777       else
6778         break;
6779     }
6780
6781   if (bd_id == ~0)
6782     {
6783       errmsg ("missing bridge domain");
6784       ret = -99;
6785       goto done;
6786     }
6787
6788   if (mac_age > 255)
6789     {
6790       errmsg ("mac age must be less than 256 ");
6791       ret = -99;
6792       goto done;
6793     }
6794
6795   if ((bd_tag) && (vec_len (bd_tag) > 63))
6796     {
6797       errmsg ("bd-tag cannot be longer than 63");
6798       ret = -99;
6799       goto done;
6800     }
6801
6802   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6803
6804   mp->bd_id = ntohl (bd_id);
6805   mp->flood = flood;
6806   mp->uu_flood = uu_flood;
6807   mp->forward = forward;
6808   mp->learn = learn;
6809   mp->arp_term = arp_term;
6810   mp->is_add = is_add;
6811   mp->mac_age = (u8) mac_age;
6812   if (bd_tag)
6813     {
6814       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6815       mp->bd_tag[vec_len (bd_tag)] = 0;
6816     }
6817   S (mp);
6818   W (ret);
6819
6820 done:
6821   vec_free (bd_tag);
6822   return ret;
6823 }
6824
6825 static int
6826 api_l2fib_flush_bd (vat_main_t * vam)
6827 {
6828   unformat_input_t *i = vam->input;
6829   vl_api_l2fib_flush_bd_t *mp;
6830   u32 bd_id = ~0;
6831   int ret;
6832
6833   /* Parse args required to build the message */
6834   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6835     {
6836       if (unformat (i, "bd_id %d", &bd_id));
6837       else
6838         break;
6839     }
6840
6841   if (bd_id == ~0)
6842     {
6843       errmsg ("missing bridge domain");
6844       return -99;
6845     }
6846
6847   M (L2FIB_FLUSH_BD, mp);
6848
6849   mp->bd_id = htonl (bd_id);
6850
6851   S (mp);
6852   W (ret);
6853   return ret;
6854 }
6855
6856 static int
6857 api_l2fib_flush_int (vat_main_t * vam)
6858 {
6859   unformat_input_t *i = vam->input;
6860   vl_api_l2fib_flush_int_t *mp;
6861   u32 sw_if_index = ~0;
6862   int ret;
6863
6864   /* Parse args required to build the message */
6865   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6866     {
6867       if (unformat (i, "sw_if_index %d", &sw_if_index));
6868       else
6869         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6870       else
6871         break;
6872     }
6873
6874   if (sw_if_index == ~0)
6875     {
6876       errmsg ("missing interface name or sw_if_index");
6877       return -99;
6878     }
6879
6880   M (L2FIB_FLUSH_INT, mp);
6881
6882   mp->sw_if_index = ntohl (sw_if_index);
6883
6884   S (mp);
6885   W (ret);
6886   return ret;
6887 }
6888
6889 static int
6890 api_l2fib_add_del (vat_main_t * vam)
6891 {
6892   unformat_input_t *i = vam->input;
6893   vl_api_l2fib_add_del_t *mp;
6894   f64 timeout;
6895   u8 mac[6] = { 0 };
6896   u8 mac_set = 0;
6897   u32 bd_id;
6898   u8 bd_id_set = 0;
6899   u32 sw_if_index = 0;
6900   u8 sw_if_index_set = 0;
6901   u8 is_add = 1;
6902   u8 static_mac = 0;
6903   u8 filter_mac = 0;
6904   u8 bvi_mac = 0;
6905   int count = 1;
6906   f64 before = 0;
6907   int j;
6908
6909   /* Parse args required to build the message */
6910   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6911     {
6912       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6913         mac_set = 1;
6914       else if (unformat (i, "bd_id %d", &bd_id))
6915         bd_id_set = 1;
6916       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6917         sw_if_index_set = 1;
6918       else if (unformat (i, "sw_if"))
6919         {
6920           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6921             {
6922               if (unformat
6923                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6924                 sw_if_index_set = 1;
6925             }
6926           else
6927             break;
6928         }
6929       else if (unformat (i, "static"))
6930         static_mac = 1;
6931       else if (unformat (i, "filter"))
6932         {
6933           filter_mac = 1;
6934           static_mac = 1;
6935         }
6936       else if (unformat (i, "bvi"))
6937         {
6938           bvi_mac = 1;
6939           static_mac = 1;
6940         }
6941       else if (unformat (i, "del"))
6942         is_add = 0;
6943       else if (unformat (i, "count %d", &count))
6944         ;
6945       else
6946         break;
6947     }
6948
6949   if (mac_set == 0)
6950     {
6951       errmsg ("missing mac address");
6952       return -99;
6953     }
6954
6955   if (bd_id_set == 0)
6956     {
6957       errmsg ("missing bridge domain");
6958       return -99;
6959     }
6960
6961   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6962     {
6963       errmsg ("missing interface name or sw_if_index");
6964       return -99;
6965     }
6966
6967   if (count > 1)
6968     {
6969       /* Turn on async mode */
6970       vam->async_mode = 1;
6971       vam->async_errors = 0;
6972       before = vat_time_now (vam);
6973     }
6974
6975   for (j = 0; j < count; j++)
6976     {
6977       M (L2FIB_ADD_DEL, mp);
6978
6979       clib_memcpy (mp->mac, mac, 6);
6980       mp->bd_id = ntohl (bd_id);
6981       mp->is_add = is_add;
6982       mp->sw_if_index = ntohl (sw_if_index);
6983
6984       if (is_add)
6985         {
6986           mp->static_mac = static_mac;
6987           mp->filter_mac = filter_mac;
6988           mp->bvi_mac = bvi_mac;
6989         }
6990       increment_mac_address (mac);
6991       /* send it... */
6992       S (mp);
6993     }
6994
6995   if (count > 1)
6996     {
6997       vl_api_control_ping_t *mp_ping;
6998       f64 after;
6999
7000       /* Shut off async mode */
7001       vam->async_mode = 0;
7002
7003       MPING (CONTROL_PING, mp_ping);
7004       S (mp_ping);
7005
7006       timeout = vat_time_now (vam) + 1.0;
7007       while (vat_time_now (vam) < timeout)
7008         if (vam->result_ready == 1)
7009           goto out;
7010       vam->retval = -99;
7011
7012     out:
7013       if (vam->retval == -99)
7014         errmsg ("timeout");
7015
7016       if (vam->async_errors > 0)
7017         {
7018           errmsg ("%d asynchronous errors", vam->async_errors);
7019           vam->retval = -98;
7020         }
7021       vam->async_errors = 0;
7022       after = vat_time_now (vam);
7023
7024       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7025              count, after - before, count / (after - before));
7026     }
7027   else
7028     {
7029       int ret;
7030
7031       /* Wait for a reply... */
7032       W (ret);
7033       return ret;
7034     }
7035   /* Return the good/bad news */
7036   return (vam->retval);
7037 }
7038
7039 static int
7040 api_bridge_domain_set_mac_age (vat_main_t * vam)
7041 {
7042   unformat_input_t *i = vam->input;
7043   vl_api_bridge_domain_set_mac_age_t *mp;
7044   u32 bd_id = ~0;
7045   u32 mac_age = 0;
7046   int ret;
7047
7048   /* Parse args required to build the message */
7049   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7050     {
7051       if (unformat (i, "bd_id %d", &bd_id));
7052       else if (unformat (i, "mac-age %d", &mac_age));
7053       else
7054         break;
7055     }
7056
7057   if (bd_id == ~0)
7058     {
7059       errmsg ("missing bridge domain");
7060       return -99;
7061     }
7062
7063   if (mac_age > 255)
7064     {
7065       errmsg ("mac age must be less than 256 ");
7066       return -99;
7067     }
7068
7069   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7070
7071   mp->bd_id = htonl (bd_id);
7072   mp->mac_age = (u8) mac_age;
7073
7074   S (mp);
7075   W (ret);
7076   return ret;
7077 }
7078
7079 static int
7080 api_l2_flags (vat_main_t * vam)
7081 {
7082   unformat_input_t *i = vam->input;
7083   vl_api_l2_flags_t *mp;
7084   u32 sw_if_index;
7085   u32 flags = 0;
7086   u8 sw_if_index_set = 0;
7087   u8 is_set = 0;
7088   int ret;
7089
7090   /* Parse args required to build the message */
7091   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7092     {
7093       if (unformat (i, "sw_if_index %d", &sw_if_index))
7094         sw_if_index_set = 1;
7095       else if (unformat (i, "sw_if"))
7096         {
7097           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7098             {
7099               if (unformat
7100                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7101                 sw_if_index_set = 1;
7102             }
7103           else
7104             break;
7105         }
7106       else if (unformat (i, "learn"))
7107         flags |= L2_LEARN;
7108       else if (unformat (i, "forward"))
7109         flags |= L2_FWD;
7110       else if (unformat (i, "flood"))
7111         flags |= L2_FLOOD;
7112       else if (unformat (i, "uu-flood"))
7113         flags |= L2_UU_FLOOD;
7114       else if (unformat (i, "arp-term"))
7115         flags |= L2_ARP_TERM;
7116       else if (unformat (i, "off"))
7117         is_set = 0;
7118       else if (unformat (i, "disable"))
7119         is_set = 0;
7120       else
7121         break;
7122     }
7123
7124   if (sw_if_index_set == 0)
7125     {
7126       errmsg ("missing interface name or sw_if_index");
7127       return -99;
7128     }
7129
7130   M (L2_FLAGS, mp);
7131
7132   mp->sw_if_index = ntohl (sw_if_index);
7133   mp->feature_bitmap = ntohl (flags);
7134   mp->is_set = is_set;
7135
7136   S (mp);
7137   W (ret);
7138   return ret;
7139 }
7140
7141 static int
7142 api_bridge_flags (vat_main_t * vam)
7143 {
7144   unformat_input_t *i = vam->input;
7145   vl_api_bridge_flags_t *mp;
7146   u32 bd_id;
7147   u8 bd_id_set = 0;
7148   u8 is_set = 1;
7149   bd_flags_t flags = 0;
7150   int ret;
7151
7152   /* Parse args required to build the message */
7153   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7154     {
7155       if (unformat (i, "bd_id %d", &bd_id))
7156         bd_id_set = 1;
7157       else if (unformat (i, "learn"))
7158         flags |= BRIDGE_API_FLAG_LEARN;
7159       else if (unformat (i, "forward"))
7160         flags |= BRIDGE_API_FLAG_FWD;
7161       else if (unformat (i, "flood"))
7162         flags |= BRIDGE_API_FLAG_FLOOD;
7163       else if (unformat (i, "uu-flood"))
7164         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7165       else if (unformat (i, "arp-term"))
7166         flags |= BRIDGE_API_FLAG_ARP_TERM;
7167       else if (unformat (i, "off"))
7168         is_set = 0;
7169       else if (unformat (i, "disable"))
7170         is_set = 0;
7171       else
7172         break;
7173     }
7174
7175   if (bd_id_set == 0)
7176     {
7177       errmsg ("missing bridge domain");
7178       return -99;
7179     }
7180
7181   M (BRIDGE_FLAGS, mp);
7182
7183   mp->bd_id = ntohl (bd_id);
7184   mp->flags = ntohl (flags);
7185   mp->is_set = is_set;
7186
7187   S (mp);
7188   W (ret);
7189   return ret;
7190 }
7191
7192 static int
7193 api_bd_ip_mac_add_del (vat_main_t * vam)
7194 {
7195   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7196   vl_api_mac_address_t mac = { 0 };
7197   unformat_input_t *i = vam->input;
7198   vl_api_bd_ip_mac_add_del_t *mp;
7199   u32 bd_id;
7200   u8 is_add = 1;
7201   u8 bd_id_set = 0;
7202   u8 ip_set = 0;
7203   u8 mac_set = 0;
7204   int ret;
7205
7206
7207   /* Parse args required to build the message */
7208   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7209     {
7210       if (unformat (i, "bd_id %d", &bd_id))
7211         {
7212           bd_id_set++;
7213         }
7214       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7215         {
7216           ip_set++;
7217         }
7218       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7219         {
7220           mac_set++;
7221         }
7222       else if (unformat (i, "del"))
7223         is_add = 0;
7224       else
7225         break;
7226     }
7227
7228   if (bd_id_set == 0)
7229     {
7230       errmsg ("missing bridge domain");
7231       return -99;
7232     }
7233   else if (ip_set == 0)
7234     {
7235       errmsg ("missing IP address");
7236       return -99;
7237     }
7238   else if (mac_set == 0)
7239     {
7240       errmsg ("missing MAC address");
7241       return -99;
7242     }
7243
7244   M (BD_IP_MAC_ADD_DEL, mp);
7245
7246   mp->entry.bd_id = ntohl (bd_id);
7247   mp->is_add = is_add;
7248
7249   clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
7250   clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
7251
7252   S (mp);
7253   W (ret);
7254   return ret;
7255 }
7256
7257 static int
7258 api_bd_ip_mac_flush (vat_main_t * vam)
7259 {
7260   unformat_input_t *i = vam->input;
7261   vl_api_bd_ip_mac_flush_t *mp;
7262   u32 bd_id;
7263   u8 bd_id_set = 0;
7264   int ret;
7265
7266   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7267     {
7268       if (unformat (i, "bd_id %d", &bd_id))
7269         {
7270           bd_id_set++;
7271         }
7272       else
7273         break;
7274     }
7275
7276   if (bd_id_set == 0)
7277     {
7278       errmsg ("missing bridge domain");
7279       return -99;
7280     }
7281
7282   M (BD_IP_MAC_FLUSH, mp);
7283
7284   mp->bd_id = ntohl (bd_id);
7285
7286   S (mp);
7287   W (ret);
7288   return ret;
7289 }
7290
7291 static void vl_api_bd_ip_mac_details_t_handler
7292   (vl_api_bd_ip_mac_details_t * mp)
7293 {
7294   vat_main_t *vam = &vat_main;
7295
7296   print (vam->ofp,
7297          "\n%-5d %U %U",
7298          ntohl (mp->entry.bd_id),
7299          format_vl_api_mac_address, mp->entry.mac,
7300          format_vl_api_address, &mp->entry.ip);
7301 }
7302
7303 static void vl_api_bd_ip_mac_details_t_handler_json
7304   (vl_api_bd_ip_mac_details_t * mp)
7305 {
7306   vat_main_t *vam = &vat_main;
7307   vat_json_node_t *node = NULL;
7308
7309   if (VAT_JSON_ARRAY != vam->json_tree.type)
7310     {
7311       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7312       vat_json_init_array (&vam->json_tree);
7313     }
7314   node = vat_json_array_add (&vam->json_tree);
7315
7316   vat_json_init_object (node);
7317   vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
7318   vat_json_object_add_string_copy (node, "mac_address",
7319                                    format (0, "%U", format_vl_api_mac_address,
7320                                            &mp->entry.mac));
7321   u8 *ip = 0;
7322
7323   ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
7324   vat_json_object_add_string_copy (node, "ip_address", ip);
7325   vec_free (ip);
7326 }
7327
7328 static int
7329 api_bd_ip_mac_dump (vat_main_t * vam)
7330 {
7331   unformat_input_t *i = vam->input;
7332   vl_api_bd_ip_mac_dump_t *mp;
7333   vl_api_control_ping_t *mp_ping;
7334   int ret;
7335   u32 bd_id;
7336   u8 bd_id_set = 0;
7337
7338   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7339     {
7340       if (unformat (i, "bd_id %d", &bd_id))
7341         {
7342           bd_id_set++;
7343         }
7344       else
7345         break;
7346     }
7347
7348   print (vam->ofp,
7349          "\n%-5s %-7s %-20s %-30s",
7350          "bd_id", "is_ipv6", "mac_address", "ip_address");
7351
7352   /* Dump Bridge Domain Ip to Mac entries */
7353   M (BD_IP_MAC_DUMP, mp);
7354
7355   if (bd_id_set)
7356     mp->bd_id = htonl (bd_id);
7357   else
7358     mp->bd_id = ~0;
7359
7360   S (mp);
7361
7362   /* Use a control ping for synchronization */
7363   MPING (CONTROL_PING, mp_ping);
7364   S (mp_ping);
7365
7366   W (ret);
7367   return ret;
7368 }
7369
7370 static int
7371 api_tap_create_v2 (vat_main_t * vam)
7372 {
7373   unformat_input_t *i = vam->input;
7374   vl_api_tap_create_v2_t *mp;
7375 #define TAP_FLAG_GSO (1 << 0)
7376   u8 mac_address[6];
7377   u8 random_mac = 1;
7378   u32 id = ~0;
7379   u8 *host_if_name = 0;
7380   u8 *host_ns = 0;
7381   u8 host_mac_addr[6];
7382   u8 host_mac_addr_set = 0;
7383   u8 *host_bridge = 0;
7384   ip4_address_t host_ip4_addr;
7385   ip4_address_t host_ip4_gw;
7386   u8 host_ip4_gw_set = 0;
7387   u32 host_ip4_prefix_len = 0;
7388   ip6_address_t host_ip6_addr;
7389   ip6_address_t host_ip6_gw;
7390   u8 host_ip6_gw_set = 0;
7391   u32 host_ip6_prefix_len = 0;
7392   u8 host_mtu_set = 0;
7393   u32 host_mtu_size = 0;
7394   u32 tap_flags = 0;
7395   int ret;
7396   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7397
7398   clib_memset (mac_address, 0, sizeof (mac_address));
7399
7400   /* Parse args required to build the message */
7401   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7402     {
7403       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7404         {
7405           random_mac = 0;
7406         }
7407       else if (unformat (i, "id %u", &id))
7408         ;
7409       else if (unformat (i, "host-if-name %s", &host_if_name))
7410         ;
7411       else if (unformat (i, "host-ns %s", &host_ns))
7412         ;
7413       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7414                          host_mac_addr))
7415         host_mac_addr_set = 1;
7416       else if (unformat (i, "host-bridge %s", &host_bridge))
7417         ;
7418       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7419                          &host_ip4_addr, &host_ip4_prefix_len))
7420         ;
7421       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7422                          &host_ip6_addr, &host_ip6_prefix_len))
7423         ;
7424       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7425                          &host_ip4_gw))
7426         host_ip4_gw_set = 1;
7427       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7428                          &host_ip6_gw))
7429         host_ip6_gw_set = 1;
7430       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7431         ;
7432       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7433         ;
7434       else if (unformat (i, "host-mtu-size %d", &host_mtu_size))
7435         host_mtu_set = 1;
7436       else if (unformat (i, "no-gso"))
7437         tap_flags &= ~TAP_FLAG_GSO;
7438       else if (unformat (i, "gso"))
7439         tap_flags |= TAP_FLAG_GSO;
7440       else
7441         break;
7442     }
7443
7444   if (vec_len (host_if_name) > 63)
7445     {
7446       errmsg ("tap name too long. ");
7447       return -99;
7448     }
7449   if (vec_len (host_ns) > 63)
7450     {
7451       errmsg ("host name space too long. ");
7452       return -99;
7453     }
7454   if (vec_len (host_bridge) > 63)
7455     {
7456       errmsg ("host bridge name too long. ");
7457       return -99;
7458     }
7459   if (host_ip4_prefix_len > 32)
7460     {
7461       errmsg ("host ip4 prefix length not valid. ");
7462       return -99;
7463     }
7464   if (host_ip6_prefix_len > 128)
7465     {
7466       errmsg ("host ip6 prefix length not valid. ");
7467       return -99;
7468     }
7469   if (!is_pow2 (rx_ring_sz))
7470     {
7471       errmsg ("rx ring size must be power of 2. ");
7472       return -99;
7473     }
7474   if (rx_ring_sz > 32768)
7475     {
7476       errmsg ("rx ring size must be 32768 or lower. ");
7477       return -99;
7478     }
7479   if (!is_pow2 (tx_ring_sz))
7480     {
7481       errmsg ("tx ring size must be power of 2. ");
7482       return -99;
7483     }
7484   if (tx_ring_sz > 32768)
7485     {
7486       errmsg ("tx ring size must be 32768 or lower. ");
7487       return -99;
7488     }
7489   if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
7490     {
7491       errmsg ("host MTU size must be in between 64 and 65355. ");
7492       return -99;
7493     }
7494
7495   /* Construct the API message */
7496   M (TAP_CREATE_V2, mp);
7497
7498   mp->use_random_mac = random_mac;
7499
7500   mp->id = ntohl (id);
7501   mp->host_namespace_set = host_ns != 0;
7502   mp->host_bridge_set = host_bridge != 0;
7503   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7504   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7505   mp->rx_ring_sz = ntohs (rx_ring_sz);
7506   mp->tx_ring_sz = ntohs (tx_ring_sz);
7507   mp->host_mtu_set = host_mtu_set;
7508   mp->host_mtu_size = ntohl (host_mtu_size);
7509   mp->tap_flags = ntohl (tap_flags);
7510
7511   if (random_mac == 0)
7512     clib_memcpy (mp->mac_address, mac_address, 6);
7513   if (host_mac_addr_set)
7514     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7515   if (host_if_name)
7516     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7517   if (host_ns)
7518     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7519   if (host_bridge)
7520     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7521   if (host_ip4_prefix_len)
7522     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
7523   if (host_ip6_prefix_len)
7524     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
7525   if (host_ip4_gw_set)
7526     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7527   if (host_ip6_gw_set)
7528     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7529
7530   vec_free (host_ns);
7531   vec_free (host_if_name);
7532   vec_free (host_bridge);
7533
7534   /* send it... */
7535   S (mp);
7536
7537   /* Wait for a reply... */
7538   W (ret);
7539   return ret;
7540 }
7541
7542 static int
7543 api_tap_delete_v2 (vat_main_t * vam)
7544 {
7545   unformat_input_t *i = vam->input;
7546   vl_api_tap_delete_v2_t *mp;
7547   u32 sw_if_index = ~0;
7548   u8 sw_if_index_set = 0;
7549   int ret;
7550
7551   /* Parse args required to build the message */
7552   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7553     {
7554       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7555         sw_if_index_set = 1;
7556       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7557         sw_if_index_set = 1;
7558       else
7559         break;
7560     }
7561
7562   if (sw_if_index_set == 0)
7563     {
7564       errmsg ("missing vpp interface name. ");
7565       return -99;
7566     }
7567
7568   /* Construct the API message */
7569   M (TAP_DELETE_V2, mp);
7570
7571   mp->sw_if_index = ntohl (sw_if_index);
7572
7573   /* send it... */
7574   S (mp);
7575
7576   /* Wait for a reply... */
7577   W (ret);
7578   return ret;
7579 }
7580
7581 uword
7582 unformat_vlib_pci_addr (unformat_input_t * input, va_list * args)
7583 {
7584   vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
7585   u32 x[4];
7586
7587   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7588     return 0;
7589
7590   addr->domain = x[0];
7591   addr->bus = x[1];
7592   addr->slot = x[2];
7593   addr->function = x[3];
7594
7595   return 1;
7596 }
7597
7598 static int
7599 api_virtio_pci_create (vat_main_t * vam)
7600 {
7601   unformat_input_t *i = vam->input;
7602   vl_api_virtio_pci_create_t *mp;
7603   u8 mac_address[6];
7604   u8 random_mac = 1;
7605   u8 gso_enabled = 0;
7606   u32 pci_addr = 0;
7607   u64 features = (u64) ~ (0ULL);
7608   int ret;
7609
7610   clib_memset (mac_address, 0, sizeof (mac_address));
7611
7612   /* Parse args required to build the message */
7613   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7614     {
7615       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7616         {
7617           random_mac = 0;
7618         }
7619       else if (unformat (i, "pci-addr %U", unformat_vlib_pci_addr, &pci_addr))
7620         ;
7621       else if (unformat (i, "features 0x%llx", &features))
7622         ;
7623       else if (unformat (i, "gso-enabled"))
7624         gso_enabled = 1;
7625       else
7626         break;
7627     }
7628
7629   if (pci_addr == 0)
7630     {
7631       errmsg ("pci address must be non zero. ");
7632       return -99;
7633     }
7634
7635   /* Construct the API message */
7636   M (VIRTIO_PCI_CREATE, mp);
7637
7638   mp->use_random_mac = random_mac;
7639
7640   mp->pci_addr = htonl (pci_addr);
7641   mp->features = clib_host_to_net_u64 (features);
7642   mp->gso_enabled = gso_enabled;
7643
7644   if (random_mac == 0)
7645     clib_memcpy (mp->mac_address, mac_address, 6);
7646
7647   /* send it... */
7648   S (mp);
7649
7650   /* Wait for a reply... */
7651   W (ret);
7652   return ret;
7653 }
7654
7655 static int
7656 api_virtio_pci_delete (vat_main_t * vam)
7657 {
7658   unformat_input_t *i = vam->input;
7659   vl_api_virtio_pci_delete_t *mp;
7660   u32 sw_if_index = ~0;
7661   u8 sw_if_index_set = 0;
7662   int ret;
7663
7664   /* Parse args required to build the message */
7665   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7666     {
7667       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7668         sw_if_index_set = 1;
7669       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7670         sw_if_index_set = 1;
7671       else
7672         break;
7673     }
7674
7675   if (sw_if_index_set == 0)
7676     {
7677       errmsg ("missing vpp interface name. ");
7678       return -99;
7679     }
7680
7681   /* Construct the API message */
7682   M (VIRTIO_PCI_DELETE, mp);
7683
7684   mp->sw_if_index = htonl (sw_if_index);
7685
7686   /* send it... */
7687   S (mp);
7688
7689   /* Wait for a reply... */
7690   W (ret);
7691   return ret;
7692 }
7693
7694 static int
7695 api_bond_create (vat_main_t * vam)
7696 {
7697   unformat_input_t *i = vam->input;
7698   vl_api_bond_create_t *mp;
7699   u8 mac_address[6];
7700   u8 custom_mac = 0;
7701   int ret;
7702   u8 mode;
7703   u8 lb;
7704   u8 mode_is_set = 0;
7705   u32 id = ~0;
7706   u8 numa_only = 0;
7707
7708   clib_memset (mac_address, 0, sizeof (mac_address));
7709   lb = BOND_LB_L2;
7710
7711   /* Parse args required to build the message */
7712   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7713     {
7714       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7715         mode_is_set = 1;
7716       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7717                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7718         ;
7719       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7720                          mac_address))
7721         custom_mac = 1;
7722       else if (unformat (i, "numa-only"))
7723         numa_only = 1;
7724       else if (unformat (i, "id %u", &id))
7725         ;
7726       else
7727         break;
7728     }
7729
7730   if (mode_is_set == 0)
7731     {
7732       errmsg ("Missing bond mode. ");
7733       return -99;
7734     }
7735
7736   /* Construct the API message */
7737   M (BOND_CREATE, mp);
7738
7739   mp->use_custom_mac = custom_mac;
7740
7741   mp->mode = htonl (mode);
7742   mp->lb = htonl (lb);
7743   mp->id = htonl (id);
7744   mp->numa_only = numa_only;
7745
7746   if (custom_mac)
7747     clib_memcpy (mp->mac_address, mac_address, 6);
7748
7749   /* send it... */
7750   S (mp);
7751
7752   /* Wait for a reply... */
7753   W (ret);
7754   return ret;
7755 }
7756
7757 static int
7758 api_bond_delete (vat_main_t * vam)
7759 {
7760   unformat_input_t *i = vam->input;
7761   vl_api_bond_delete_t *mp;
7762   u32 sw_if_index = ~0;
7763   u8 sw_if_index_set = 0;
7764   int ret;
7765
7766   /* Parse args required to build the message */
7767   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7768     {
7769       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7770         sw_if_index_set = 1;
7771       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7772         sw_if_index_set = 1;
7773       else
7774         break;
7775     }
7776
7777   if (sw_if_index_set == 0)
7778     {
7779       errmsg ("missing vpp interface name. ");
7780       return -99;
7781     }
7782
7783   /* Construct the API message */
7784   M (BOND_DELETE, mp);
7785
7786   mp->sw_if_index = ntohl (sw_if_index);
7787
7788   /* send it... */
7789   S (mp);
7790
7791   /* Wait for a reply... */
7792   W (ret);
7793   return ret;
7794 }
7795
7796 static int
7797 api_bond_enslave (vat_main_t * vam)
7798 {
7799   unformat_input_t *i = vam->input;
7800   vl_api_bond_enslave_t *mp;
7801   u32 bond_sw_if_index;
7802   int ret;
7803   u8 is_passive;
7804   u8 is_long_timeout;
7805   u32 bond_sw_if_index_is_set = 0;
7806   u32 sw_if_index;
7807   u8 sw_if_index_is_set = 0;
7808
7809   /* Parse args required to build the message */
7810   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7811     {
7812       if (unformat (i, "sw_if_index %d", &sw_if_index))
7813         sw_if_index_is_set = 1;
7814       else if (unformat (i, "bond %u", &bond_sw_if_index))
7815         bond_sw_if_index_is_set = 1;
7816       else if (unformat (i, "passive %d", &is_passive))
7817         ;
7818       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7819         ;
7820       else
7821         break;
7822     }
7823
7824   if (bond_sw_if_index_is_set == 0)
7825     {
7826       errmsg ("Missing bond sw_if_index. ");
7827       return -99;
7828     }
7829   if (sw_if_index_is_set == 0)
7830     {
7831       errmsg ("Missing slave sw_if_index. ");
7832       return -99;
7833     }
7834
7835   /* Construct the API message */
7836   M (BOND_ENSLAVE, mp);
7837
7838   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7839   mp->sw_if_index = ntohl (sw_if_index);
7840   mp->is_long_timeout = is_long_timeout;
7841   mp->is_passive = is_passive;
7842
7843   /* send it... */
7844   S (mp);
7845
7846   /* Wait for a reply... */
7847   W (ret);
7848   return ret;
7849 }
7850
7851 static int
7852 api_bond_detach_slave (vat_main_t * vam)
7853 {
7854   unformat_input_t *i = vam->input;
7855   vl_api_bond_detach_slave_t *mp;
7856   u32 sw_if_index = ~0;
7857   u8 sw_if_index_set = 0;
7858   int ret;
7859
7860   /* Parse args required to build the message */
7861   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7862     {
7863       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7864         sw_if_index_set = 1;
7865       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7866         sw_if_index_set = 1;
7867       else
7868         break;
7869     }
7870
7871   if (sw_if_index_set == 0)
7872     {
7873       errmsg ("missing vpp interface name. ");
7874       return -99;
7875     }
7876
7877   /* Construct the API message */
7878   M (BOND_DETACH_SLAVE, mp);
7879
7880   mp->sw_if_index = ntohl (sw_if_index);
7881
7882   /* send it... */
7883   S (mp);
7884
7885   /* Wait for a reply... */
7886   W (ret);
7887   return ret;
7888 }
7889
7890 static int
7891 api_ip_table_add_del (vat_main_t * vam)
7892 {
7893   unformat_input_t *i = vam->input;
7894   vl_api_ip_table_add_del_t *mp;
7895   u32 table_id = ~0;
7896   u8 is_ipv6 = 0;
7897   u8 is_add = 1;
7898   int ret = 0;
7899
7900   /* Parse args required to build the message */
7901   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7902     {
7903       if (unformat (i, "ipv6"))
7904         is_ipv6 = 1;
7905       else if (unformat (i, "del"))
7906         is_add = 0;
7907       else if (unformat (i, "add"))
7908         is_add = 1;
7909       else if (unformat (i, "table %d", &table_id))
7910         ;
7911       else
7912         {
7913           clib_warning ("parse error '%U'", format_unformat_error, i);
7914           return -99;
7915         }
7916     }
7917
7918   if (~0 == table_id)
7919     {
7920       errmsg ("missing table-ID");
7921       return -99;
7922     }
7923
7924   /* Construct the API message */
7925   M (IP_TABLE_ADD_DEL, mp);
7926
7927   mp->table.table_id = ntohl (table_id);
7928   mp->table.is_ip6 = is_ipv6;
7929   mp->is_add = is_add;
7930
7931   /* send it... */
7932   S (mp);
7933
7934   /* Wait for a reply... */
7935   W (ret);
7936
7937   return ret;
7938 }
7939
7940 uword
7941 unformat_fib_path (unformat_input_t * input, va_list * args)
7942 {
7943   vat_main_t *vam = va_arg (*args, vat_main_t *);
7944   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
7945   u32 weight, preference;
7946   mpls_label_t out_label;
7947
7948   clib_memset (path, 0, sizeof (*path));
7949   path->weight = 1;
7950   path->sw_if_index = ~0;
7951   path->rpf_id = ~0;
7952   path->n_labels = 0;
7953
7954   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7955     {
7956       if (unformat (input, "%U %U",
7957                     unformat_vl_api_ip4_address,
7958                     &path->nh.address.ip4,
7959                     api_unformat_sw_if_index, vam, &path->sw_if_index))
7960         {
7961           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7962         }
7963       else if (unformat (input, "%U %U",
7964                          unformat_vl_api_ip6_address,
7965                          &path->nh.address.ip6,
7966                          api_unformat_sw_if_index, vam, &path->sw_if_index))
7967         {
7968           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7969         }
7970       else if (unformat (input, "weight %u", &weight))
7971         {
7972           path->weight = weight;
7973         }
7974       else if (unformat (input, "preference %u", &preference))
7975         {
7976           path->preference = preference;
7977         }
7978       else if (unformat (input, "%U next-hop-table %d",
7979                          unformat_vl_api_ip4_address,
7980                          &path->nh.address.ip4, &path->table_id))
7981         {
7982           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7983         }
7984       else if (unformat (input, "%U next-hop-table %d",
7985                          unformat_vl_api_ip6_address,
7986                          &path->nh.address.ip6, &path->table_id))
7987         {
7988           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7989         }
7990       else if (unformat (input, "%U",
7991                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
7992         {
7993           /*
7994            * the recursive next-hops are by default in the default table
7995            */
7996           path->table_id = 0;
7997           path->sw_if_index = ~0;
7998           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7999         }
8000       else if (unformat (input, "%U",
8001                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
8002         {
8003           /*
8004            * the recursive next-hops are by default in the default table
8005            */
8006           path->table_id = 0;
8007           path->sw_if_index = ~0;
8008           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8009         }
8010       else if (unformat (input, "resolve-via-host"))
8011         {
8012           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
8013         }
8014       else if (unformat (input, "resolve-via-attached"))
8015         {
8016           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
8017         }
8018       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
8019         {
8020           path->type = FIB_API_PATH_TYPE_LOCAL;
8021           path->sw_if_index = ~0;
8022           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8023         }
8024       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
8025         {
8026           path->type = FIB_API_PATH_TYPE_LOCAL;
8027           path->sw_if_index = ~0;
8028           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8029         }
8030       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
8031         ;
8032       else if (unformat (input, "via-label %d", &path->nh.via_label))
8033         {
8034           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
8035           path->sw_if_index = ~0;
8036         }
8037       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
8038         {
8039           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
8040           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
8041         }
8042       else if (unformat (input, "local"))
8043         {
8044           path->type = FIB_API_PATH_TYPE_LOCAL;
8045         }
8046       else if (unformat (input, "out-labels"))
8047         {
8048           while (unformat (input, "%d", &out_label))
8049             {
8050               path->label_stack[path->n_labels].label = out_label;
8051               path->label_stack[path->n_labels].is_uniform = 0;
8052               path->label_stack[path->n_labels].ttl = 64;
8053               path->n_labels++;
8054             }
8055         }
8056       else if (unformat (input, "via"))
8057         {
8058           /* new path, back up and return */
8059           unformat_put_input (input);
8060           unformat_put_input (input);
8061           unformat_put_input (input);
8062           unformat_put_input (input);
8063           break;
8064         }
8065       else
8066         {
8067           return (0);
8068         }
8069     }
8070
8071   path->proto = ntohl (path->proto);
8072   path->type = ntohl (path->type);
8073   path->flags = ntohl (path->flags);
8074   path->table_id = ntohl (path->table_id);
8075   path->sw_if_index = ntohl (path->sw_if_index);
8076
8077   return (1);
8078 }
8079
8080 static int
8081 api_ip_route_add_del (vat_main_t * vam)
8082 {
8083   unformat_input_t *i = vam->input;
8084   vl_api_ip_route_add_del_t *mp;
8085   u32 vrf_id = 0;
8086   u8 is_add = 1;
8087   u8 is_multipath = 0;
8088   u8 prefix_set = 0;
8089   u8 path_count = 0;
8090   vl_api_prefix_t pfx = { };
8091   vl_api_fib_path_t paths[8];
8092   int count = 1;
8093   int j;
8094   f64 before = 0;
8095   u32 random_add_del = 0;
8096   u32 *random_vector = 0;
8097   u32 random_seed = 0xdeaddabe;
8098
8099   /* Parse args required to build the message */
8100   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8101     {
8102       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8103         prefix_set = 1;
8104       else if (unformat (i, "del"))
8105         is_add = 0;
8106       else if (unformat (i, "add"))
8107         is_add = 1;
8108       else if (unformat (i, "vrf %d", &vrf_id))
8109         ;
8110       else if (unformat (i, "count %d", &count))
8111         ;
8112       else if (unformat (i, "random"))
8113         random_add_del = 1;
8114       else if (unformat (i, "multipath"))
8115         is_multipath = 1;
8116       else if (unformat (i, "seed %d", &random_seed))
8117         ;
8118       else
8119         if (unformat
8120             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8121         {
8122           path_count++;
8123           if (8 == path_count)
8124             {
8125               errmsg ("max 8 paths");
8126               return -99;
8127             }
8128         }
8129       else
8130         {
8131           clib_warning ("parse error '%U'", format_unformat_error, i);
8132           return -99;
8133         }
8134     }
8135
8136   if (!path_count)
8137     {
8138       errmsg ("specify a path; via ...");
8139       return -99;
8140     }
8141   if (prefix_set == 0)
8142     {
8143       errmsg ("missing prefix");
8144       return -99;
8145     }
8146
8147   /* Generate a pile of unique, random routes */
8148   if (random_add_del)
8149     {
8150       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
8151       u32 this_random_address;
8152       uword *random_hash;
8153
8154       random_hash = hash_create (count, sizeof (uword));
8155
8156       hash_set (random_hash, i->as_u32, 1);
8157       for (j = 0; j <= count; j++)
8158         {
8159           do
8160             {
8161               this_random_address = random_u32 (&random_seed);
8162               this_random_address =
8163                 clib_host_to_net_u32 (this_random_address);
8164             }
8165           while (hash_get (random_hash, this_random_address));
8166           vec_add1 (random_vector, this_random_address);
8167           hash_set (random_hash, this_random_address, 1);
8168         }
8169       hash_free (random_hash);
8170       set_ip4_address (&pfx.address, random_vector[0]);
8171     }
8172
8173   if (count > 1)
8174     {
8175       /* Turn on async mode */
8176       vam->async_mode = 1;
8177       vam->async_errors = 0;
8178       before = vat_time_now (vam);
8179     }
8180
8181   for (j = 0; j < count; j++)
8182     {
8183       /* Construct the API message */
8184       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8185
8186       mp->is_add = is_add;
8187       mp->is_multipath = is_multipath;
8188
8189       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8190       mp->route.table_id = ntohl (vrf_id);
8191       mp->route.n_paths = path_count;
8192
8193       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
8194
8195       if (random_add_del)
8196         set_ip4_address (&pfx.address, random_vector[j + 1]);
8197       else
8198         increment_address (&pfx.address);
8199       /* send it... */
8200       S (mp);
8201       /* If we receive SIGTERM, stop now... */
8202       if (vam->do_exit)
8203         break;
8204     }
8205
8206   /* When testing multiple add/del ops, use a control-ping to sync */
8207   if (count > 1)
8208     {
8209       vl_api_control_ping_t *mp_ping;
8210       f64 after;
8211       f64 timeout;
8212
8213       /* Shut off async mode */
8214       vam->async_mode = 0;
8215
8216       MPING (CONTROL_PING, mp_ping);
8217       S (mp_ping);
8218
8219       timeout = vat_time_now (vam) + 1.0;
8220       while (vat_time_now (vam) < timeout)
8221         if (vam->result_ready == 1)
8222           goto out;
8223       vam->retval = -99;
8224
8225     out:
8226       if (vam->retval == -99)
8227         errmsg ("timeout");
8228
8229       if (vam->async_errors > 0)
8230         {
8231           errmsg ("%d asynchronous errors", vam->async_errors);
8232           vam->retval = -98;
8233         }
8234       vam->async_errors = 0;
8235       after = vat_time_now (vam);
8236
8237       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8238       if (j > 0)
8239         count = j;
8240
8241       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8242              count, after - before, count / (after - before));
8243     }
8244   else
8245     {
8246       int ret;
8247
8248       /* Wait for a reply... */
8249       W (ret);
8250       return ret;
8251     }
8252
8253   /* Return the good/bad news */
8254   return (vam->retval);
8255 }
8256
8257 static int
8258 api_ip_mroute_add_del (vat_main_t * vam)
8259 {
8260   unformat_input_t *i = vam->input;
8261   u8 path_set = 0, prefix_set = 0, is_add = 1;
8262   vl_api_ip_mroute_add_del_t *mp;
8263   mfib_entry_flags_t eflags = 0;
8264   vl_api_mfib_path_t path;
8265   vl_api_mprefix_t pfx = { };
8266   u32 vrf_id = 0;
8267   int ret;
8268
8269   /* Parse args required to build the message */
8270   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8271     {
8272       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
8273         {
8274           prefix_set = 1;
8275           pfx.grp_address_length = htons (pfx.grp_address_length);
8276         }
8277       else if (unformat (i, "del"))
8278         is_add = 0;
8279       else if (unformat (i, "add"))
8280         is_add = 1;
8281       else if (unformat (i, "vrf %d", &vrf_id))
8282         ;
8283       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
8284         path.itf_flags = htonl (path.itf_flags);
8285       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8286         ;
8287       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
8288         path_set = 1;
8289       else
8290         {
8291           clib_warning ("parse error '%U'", format_unformat_error, i);
8292           return -99;
8293         }
8294     }
8295
8296   if (prefix_set == 0)
8297     {
8298       errmsg ("missing addresses\n");
8299       return -99;
8300     }
8301   if (path_set == 0)
8302     {
8303       errmsg ("missing path\n");
8304       return -99;
8305     }
8306
8307   /* Construct the API message */
8308   M (IP_MROUTE_ADD_DEL, mp);
8309
8310   mp->is_add = is_add;
8311   mp->is_multipath = 1;
8312
8313   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8314   mp->route.table_id = htonl (vrf_id);
8315   mp->route.n_paths = 1;
8316   mp->route.entry_flags = htonl (eflags);
8317
8318   clib_memcpy (&mp->route.paths, &path, sizeof (path));
8319
8320   /* send it... */
8321   S (mp);
8322   /* Wait for a reply... */
8323   W (ret);
8324   return ret;
8325 }
8326
8327 static int
8328 api_mpls_table_add_del (vat_main_t * vam)
8329 {
8330   unformat_input_t *i = vam->input;
8331   vl_api_mpls_table_add_del_t *mp;
8332   u32 table_id = ~0;
8333   u8 is_add = 1;
8334   int ret = 0;
8335
8336   /* Parse args required to build the message */
8337   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8338     {
8339       if (unformat (i, "table %d", &table_id))
8340         ;
8341       else if (unformat (i, "del"))
8342         is_add = 0;
8343       else if (unformat (i, "add"))
8344         is_add = 1;
8345       else
8346         {
8347           clib_warning ("parse error '%U'", format_unformat_error, i);
8348           return -99;
8349         }
8350     }
8351
8352   if (~0 == table_id)
8353     {
8354       errmsg ("missing table-ID");
8355       return -99;
8356     }
8357
8358   /* Construct the API message */
8359   M (MPLS_TABLE_ADD_DEL, mp);
8360
8361   mp->mt_table.mt_table_id = ntohl (table_id);
8362   mp->mt_is_add = is_add;
8363
8364   /* send it... */
8365   S (mp);
8366
8367   /* Wait for a reply... */
8368   W (ret);
8369
8370   return ret;
8371 }
8372
8373 static int
8374 api_mpls_route_add_del (vat_main_t * vam)
8375 {
8376   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
8377   mpls_label_t local_label = MPLS_LABEL_INVALID;
8378   unformat_input_t *i = vam->input;
8379   vl_api_mpls_route_add_del_t *mp;
8380   vl_api_fib_path_t paths[8];
8381   int count = 1, j;
8382   f64 before = 0;
8383
8384   /* Parse args required to build the message */
8385   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8386     {
8387       if (unformat (i, "%d", &local_label))
8388         ;
8389       else if (unformat (i, "eos"))
8390         is_eos = 1;
8391       else if (unformat (i, "non-eos"))
8392         is_eos = 0;
8393       else if (unformat (i, "del"))
8394         is_add = 0;
8395       else if (unformat (i, "add"))
8396         is_add = 1;
8397       else if (unformat (i, "multipath"))
8398         is_multipath = 1;
8399       else if (unformat (i, "count %d", &count))
8400         ;
8401       else
8402         if (unformat
8403             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8404         {
8405           path_count++;
8406           if (8 == path_count)
8407             {
8408               errmsg ("max 8 paths");
8409               return -99;
8410             }
8411         }
8412       else
8413         {
8414           clib_warning ("parse error '%U'", format_unformat_error, i);
8415           return -99;
8416         }
8417     }
8418
8419   if (!path_count)
8420     {
8421       errmsg ("specify a path; via ...");
8422       return -99;
8423     }
8424
8425   if (MPLS_LABEL_INVALID == local_label)
8426     {
8427       errmsg ("missing label");
8428       return -99;
8429     }
8430
8431   if (count > 1)
8432     {
8433       /* Turn on async mode */
8434       vam->async_mode = 1;
8435       vam->async_errors = 0;
8436       before = vat_time_now (vam);
8437     }
8438
8439   for (j = 0; j < count; j++)
8440     {
8441       /* Construct the API message */
8442       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8443
8444       mp->mr_is_add = is_add;
8445       mp->mr_is_multipath = is_multipath;
8446
8447       mp->mr_route.mr_label = local_label;
8448       mp->mr_route.mr_eos = is_eos;
8449       mp->mr_route.mr_table_id = 0;
8450       mp->mr_route.mr_n_paths = path_count;
8451
8452       clib_memcpy (&mp->mr_route.mr_paths, paths,
8453                    sizeof (paths[0]) * path_count);
8454
8455       local_label++;
8456
8457       /* send it... */
8458       S (mp);
8459       /* If we receive SIGTERM, stop now... */
8460       if (vam->do_exit)
8461         break;
8462     }
8463
8464   /* When testing multiple add/del ops, use a control-ping to sync */
8465   if (count > 1)
8466     {
8467       vl_api_control_ping_t *mp_ping;
8468       f64 after;
8469       f64 timeout;
8470
8471       /* Shut off async mode */
8472       vam->async_mode = 0;
8473
8474       MPING (CONTROL_PING, mp_ping);
8475       S (mp_ping);
8476
8477       timeout = vat_time_now (vam) + 1.0;
8478       while (vat_time_now (vam) < timeout)
8479         if (vam->result_ready == 1)
8480           goto out;
8481       vam->retval = -99;
8482
8483     out:
8484       if (vam->retval == -99)
8485         errmsg ("timeout");
8486
8487       if (vam->async_errors > 0)
8488         {
8489           errmsg ("%d asynchronous errors", vam->async_errors);
8490           vam->retval = -98;
8491         }
8492       vam->async_errors = 0;
8493       after = vat_time_now (vam);
8494
8495       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8496       if (j > 0)
8497         count = j;
8498
8499       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8500              count, after - before, count / (after - before));
8501     }
8502   else
8503     {
8504       int ret;
8505
8506       /* Wait for a reply... */
8507       W (ret);
8508       return ret;
8509     }
8510
8511   /* Return the good/bad news */
8512   return (vam->retval);
8513   return (0);
8514 }
8515
8516 static int
8517 api_mpls_ip_bind_unbind (vat_main_t * vam)
8518 {
8519   unformat_input_t *i = vam->input;
8520   vl_api_mpls_ip_bind_unbind_t *mp;
8521   u32 ip_table_id = 0;
8522   u8 is_bind = 1;
8523   vl_api_prefix_t pfx;
8524   u8 prefix_set = 0;
8525   mpls_label_t local_label = MPLS_LABEL_INVALID;
8526   int ret;
8527
8528   /* Parse args required to build the message */
8529   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8530     {
8531       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8532         prefix_set = 1;
8533       else if (unformat (i, "%d", &local_label))
8534         ;
8535       else if (unformat (i, "table-id %d", &ip_table_id))
8536         ;
8537       else if (unformat (i, "unbind"))
8538         is_bind = 0;
8539       else if (unformat (i, "bind"))
8540         is_bind = 1;
8541       else
8542         {
8543           clib_warning ("parse error '%U'", format_unformat_error, i);
8544           return -99;
8545         }
8546     }
8547
8548   if (!prefix_set)
8549     {
8550       errmsg ("IP prefix not set");
8551       return -99;
8552     }
8553
8554   if (MPLS_LABEL_INVALID == local_label)
8555     {
8556       errmsg ("missing label");
8557       return -99;
8558     }
8559
8560   /* Construct the API message */
8561   M (MPLS_IP_BIND_UNBIND, mp);
8562
8563   mp->mb_is_bind = is_bind;
8564   mp->mb_ip_table_id = ntohl (ip_table_id);
8565   mp->mb_mpls_table_id = 0;
8566   mp->mb_label = ntohl (local_label);
8567   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
8568
8569   /* send it... */
8570   S (mp);
8571
8572   /* Wait for a reply... */
8573   W (ret);
8574   return ret;
8575   return (0);
8576 }
8577
8578 static int
8579 api_sr_mpls_policy_add (vat_main_t * vam)
8580 {
8581   unformat_input_t *i = vam->input;
8582   vl_api_sr_mpls_policy_add_t *mp;
8583   u32 bsid = 0;
8584   u32 weight = 1;
8585   u8 type = 0;
8586   u8 n_segments = 0;
8587   u32 sid;
8588   u32 *segments = NULL;
8589   int ret;
8590
8591   /* Parse args required to build the message */
8592   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8593     {
8594       if (unformat (i, "bsid %d", &bsid))
8595         ;
8596       else if (unformat (i, "weight %d", &weight))
8597         ;
8598       else if (unformat (i, "spray"))
8599         type = 1;
8600       else if (unformat (i, "next %d", &sid))
8601         {
8602           n_segments += 1;
8603           vec_add1 (segments, htonl (sid));
8604         }
8605       else
8606         {
8607           clib_warning ("parse error '%U'", format_unformat_error, i);
8608           return -99;
8609         }
8610     }
8611
8612   if (bsid == 0)
8613     {
8614       errmsg ("bsid not set");
8615       return -99;
8616     }
8617
8618   if (n_segments == 0)
8619     {
8620       errmsg ("no sid in segment stack");
8621       return -99;
8622     }
8623
8624   /* Construct the API message */
8625   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8626
8627   mp->bsid = htonl (bsid);
8628   mp->weight = htonl (weight);
8629   mp->type = type;
8630   mp->n_segments = n_segments;
8631   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8632   vec_free (segments);
8633
8634   /* send it... */
8635   S (mp);
8636
8637   /* Wait for a reply... */
8638   W (ret);
8639   return ret;
8640 }
8641
8642 static int
8643 api_sr_mpls_policy_del (vat_main_t * vam)
8644 {
8645   unformat_input_t *i = vam->input;
8646   vl_api_sr_mpls_policy_del_t *mp;
8647   u32 bsid = 0;
8648   int ret;
8649
8650   /* Parse args required to build the message */
8651   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8652     {
8653       if (unformat (i, "bsid %d", &bsid))
8654         ;
8655       else
8656         {
8657           clib_warning ("parse error '%U'", format_unformat_error, i);
8658           return -99;
8659         }
8660     }
8661
8662   if (bsid == 0)
8663     {
8664       errmsg ("bsid not set");
8665       return -99;
8666     }
8667
8668   /* Construct the API message */
8669   M (SR_MPLS_POLICY_DEL, mp);
8670
8671   mp->bsid = htonl (bsid);
8672
8673   /* send it... */
8674   S (mp);
8675
8676   /* Wait for a reply... */
8677   W (ret);
8678   return ret;
8679 }
8680
8681 static int
8682 api_bier_table_add_del (vat_main_t * vam)
8683 {
8684   unformat_input_t *i = vam->input;
8685   vl_api_bier_table_add_del_t *mp;
8686   u8 is_add = 1;
8687   u32 set = 0, sub_domain = 0, hdr_len = 3;
8688   mpls_label_t local_label = MPLS_LABEL_INVALID;
8689   int ret;
8690
8691   /* Parse args required to build the message */
8692   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8693     {
8694       if (unformat (i, "sub-domain %d", &sub_domain))
8695         ;
8696       else if (unformat (i, "set %d", &set))
8697         ;
8698       else if (unformat (i, "label %d", &local_label))
8699         ;
8700       else if (unformat (i, "hdr-len %d", &hdr_len))
8701         ;
8702       else if (unformat (i, "add"))
8703         is_add = 1;
8704       else if (unformat (i, "del"))
8705         is_add = 0;
8706       else
8707         {
8708           clib_warning ("parse error '%U'", format_unformat_error, i);
8709           return -99;
8710         }
8711     }
8712
8713   if (MPLS_LABEL_INVALID == local_label)
8714     {
8715       errmsg ("missing label\n");
8716       return -99;
8717     }
8718
8719   /* Construct the API message */
8720   M (BIER_TABLE_ADD_DEL, mp);
8721
8722   mp->bt_is_add = is_add;
8723   mp->bt_label = ntohl (local_label);
8724   mp->bt_tbl_id.bt_set = set;
8725   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8726   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8727
8728   /* send it... */
8729   S (mp);
8730
8731   /* Wait for a reply... */
8732   W (ret);
8733
8734   return (ret);
8735 }
8736
8737 static int
8738 api_bier_route_add_del (vat_main_t * vam)
8739 {
8740   unformat_input_t *i = vam->input;
8741   vl_api_bier_route_add_del_t *mp;
8742   u8 is_add = 1;
8743   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8744   ip4_address_t v4_next_hop_address;
8745   ip6_address_t v6_next_hop_address;
8746   u8 next_hop_set = 0;
8747   u8 next_hop_proto_is_ip4 = 1;
8748   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8749   int ret;
8750
8751   /* Parse args required to build the message */
8752   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8753     {
8754       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8755         {
8756           next_hop_proto_is_ip4 = 1;
8757           next_hop_set = 1;
8758         }
8759       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8760         {
8761           next_hop_proto_is_ip4 = 0;
8762           next_hop_set = 1;
8763         }
8764       if (unformat (i, "sub-domain %d", &sub_domain))
8765         ;
8766       else if (unformat (i, "set %d", &set))
8767         ;
8768       else if (unformat (i, "hdr-len %d", &hdr_len))
8769         ;
8770       else if (unformat (i, "bp %d", &bp))
8771         ;
8772       else if (unformat (i, "add"))
8773         is_add = 1;
8774       else if (unformat (i, "del"))
8775         is_add = 0;
8776       else if (unformat (i, "out-label %d", &next_hop_out_label))
8777         ;
8778       else
8779         {
8780           clib_warning ("parse error '%U'", format_unformat_error, i);
8781           return -99;
8782         }
8783     }
8784
8785   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8786     {
8787       errmsg ("next hop / label set\n");
8788       return -99;
8789     }
8790   if (0 == bp)
8791     {
8792       errmsg ("bit=position not set\n");
8793       return -99;
8794     }
8795
8796   /* Construct the API message */
8797   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
8798
8799   mp->br_is_add = is_add;
8800   mp->br_route.br_tbl_id.bt_set = set;
8801   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
8802   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
8803   mp->br_route.br_bp = ntohs (bp);
8804   mp->br_route.br_n_paths = 1;
8805   mp->br_route.br_paths[0].n_labels = 1;
8806   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
8807   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
8808                                     FIB_API_PATH_NH_PROTO_IP4 :
8809                                     FIB_API_PATH_NH_PROTO_IP6);
8810
8811   if (next_hop_proto_is_ip4)
8812     {
8813       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
8814                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8815     }
8816   else
8817     {
8818       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
8819                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8820     }
8821
8822   /* send it... */
8823   S (mp);
8824
8825   /* Wait for a reply... */
8826   W (ret);
8827
8828   return (ret);
8829 }
8830
8831 static int
8832 api_proxy_arp_add_del (vat_main_t * vam)
8833 {
8834   unformat_input_t *i = vam->input;
8835   vl_api_proxy_arp_add_del_t *mp;
8836   u32 vrf_id = 0;
8837   u8 is_add = 1;
8838   vl_api_ip4_address_t lo, hi;
8839   u8 range_set = 0;
8840   int ret;
8841
8842   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8843     {
8844       if (unformat (i, "vrf %d", &vrf_id))
8845         ;
8846       else if (unformat (i, "%U - %U", unformat_vl_api_ip4_address, &lo,
8847                          unformat_vl_api_ip4_address, &hi))
8848         range_set = 1;
8849       else if (unformat (i, "del"))
8850         is_add = 0;
8851       else
8852         {
8853           clib_warning ("parse error '%U'", format_unformat_error, i);
8854           return -99;
8855         }
8856     }
8857
8858   if (range_set == 0)
8859     {
8860       errmsg ("address range not set");
8861       return -99;
8862     }
8863
8864   M (PROXY_ARP_ADD_DEL, mp);
8865
8866   mp->proxy.table_id = ntohl (vrf_id);
8867   mp->is_add = is_add;
8868   clib_memcpy (mp->proxy.low, &lo, sizeof (lo));
8869   clib_memcpy (mp->proxy.hi, &hi, sizeof (hi));
8870
8871   S (mp);
8872   W (ret);
8873   return ret;
8874 }
8875
8876 static int
8877 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8878 {
8879   unformat_input_t *i = vam->input;
8880   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8881   u32 sw_if_index;
8882   u8 enable = 1;
8883   u8 sw_if_index_set = 0;
8884   int ret;
8885
8886   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8887     {
8888       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8889         sw_if_index_set = 1;
8890       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8891         sw_if_index_set = 1;
8892       else if (unformat (i, "enable"))
8893         enable = 1;
8894       else if (unformat (i, "disable"))
8895         enable = 0;
8896       else
8897         {
8898           clib_warning ("parse error '%U'", format_unformat_error, i);
8899           return -99;
8900         }
8901     }
8902
8903   if (sw_if_index_set == 0)
8904     {
8905       errmsg ("missing interface name or sw_if_index");
8906       return -99;
8907     }
8908
8909   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8910
8911   mp->sw_if_index = ntohl (sw_if_index);
8912   mp->enable_disable = enable;
8913
8914   S (mp);
8915   W (ret);
8916   return ret;
8917 }
8918
8919 static int
8920 api_mpls_tunnel_add_del (vat_main_t * vam)
8921 {
8922   unformat_input_t *i = vam->input;
8923   vl_api_mpls_tunnel_add_del_t *mp;
8924
8925   vl_api_fib_path_t paths[8];
8926   u32 sw_if_index = ~0;
8927   u8 path_count = 0;
8928   u8 l2_only = 0;
8929   u8 is_add = 1;
8930   int ret;
8931
8932   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8933     {
8934       if (unformat (i, "add"))
8935         is_add = 1;
8936       else
8937         if (unformat
8938             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
8939         is_add = 0;
8940       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8941         is_add = 0;
8942       else if (unformat (i, "l2-only"))
8943         l2_only = 1;
8944       else
8945         if (unformat
8946             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8947         {
8948           path_count++;
8949           if (8 == path_count)
8950             {
8951               errmsg ("max 8 paths");
8952               return -99;
8953             }
8954         }
8955       else
8956         {
8957           clib_warning ("parse error '%U'", format_unformat_error, i);
8958           return -99;
8959         }
8960     }
8961
8962   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8963
8964   mp->mt_is_add = is_add;
8965   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
8966   mp->mt_tunnel.mt_l2_only = l2_only;
8967   mp->mt_tunnel.mt_is_multicast = 0;
8968   mp->mt_tunnel.mt_n_paths = path_count;
8969
8970   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
8971                sizeof (paths[0]) * path_count);
8972
8973   S (mp);
8974   W (ret);
8975   return ret;
8976 }
8977
8978 static int
8979 api_sw_interface_set_unnumbered (vat_main_t * vam)
8980 {
8981   unformat_input_t *i = vam->input;
8982   vl_api_sw_interface_set_unnumbered_t *mp;
8983   u32 sw_if_index;
8984   u32 unnum_sw_index = ~0;
8985   u8 is_add = 1;
8986   u8 sw_if_index_set = 0;
8987   int ret;
8988
8989   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8990     {
8991       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8992         sw_if_index_set = 1;
8993       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8994         sw_if_index_set = 1;
8995       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8996         ;
8997       else if (unformat (i, "del"))
8998         is_add = 0;
8999       else
9000         {
9001           clib_warning ("parse error '%U'", format_unformat_error, i);
9002           return -99;
9003         }
9004     }
9005
9006   if (sw_if_index_set == 0)
9007     {
9008       errmsg ("missing interface name or sw_if_index");
9009       return -99;
9010     }
9011
9012   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9013
9014   mp->sw_if_index = ntohl (sw_if_index);
9015   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9016   mp->is_add = is_add;
9017
9018   S (mp);
9019   W (ret);
9020   return ret;
9021 }
9022
9023 static int
9024 api_ip_neighbor_add_del (vat_main_t * vam)
9025 {
9026   vl_api_mac_address_t mac_address;
9027   unformat_input_t *i = vam->input;
9028   vl_api_ip_neighbor_add_del_t *mp;
9029   vl_api_address_t ip_address;
9030   u32 sw_if_index;
9031   u8 sw_if_index_set = 0;
9032   u8 is_add = 1;
9033   u8 mac_set = 0;
9034   u8 address_set = 0;
9035   int ret;
9036   ip_neighbor_flags_t flags;
9037
9038   flags = IP_NEIGHBOR_FLAG_NONE;
9039   clib_memset (&ip_address, 0, sizeof (ip_address));
9040   clib_memset (&mac_address, 0, sizeof (mac_address));
9041
9042   /* Parse args required to build the message */
9043   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9044     {
9045       if (unformat (i, "mac %U", unformat_vl_api_mac_address, &mac_address))
9046         {
9047           mac_set = 1;
9048         }
9049       else if (unformat (i, "del"))
9050         is_add = 0;
9051       else
9052         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9053         sw_if_index_set = 1;
9054       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9055         sw_if_index_set = 1;
9056       else if (unformat (i, "static"))
9057         flags |= IP_NEIGHBOR_FLAG_STATIC;
9058       else if (unformat (i, "no-fib-entry"))
9059         flags |= IP_NEIGHBOR_FLAG_NO_FIB_ENTRY;
9060       else if (unformat (i, "dst %U", unformat_vl_api_address, &ip_address))
9061         address_set = 1;
9062       else
9063         {
9064           clib_warning ("parse error '%U'", format_unformat_error, i);
9065           return -99;
9066         }
9067     }
9068
9069   if (sw_if_index_set == 0)
9070     {
9071       errmsg ("missing interface name or sw_if_index");
9072       return -99;
9073     }
9074   if (!address_set)
9075     {
9076       errmsg ("no address set");
9077       return -99;
9078     }
9079
9080   /* Construct the API message */
9081   M (IP_NEIGHBOR_ADD_DEL, mp);
9082
9083   mp->neighbor.sw_if_index = ntohl (sw_if_index);
9084   mp->is_add = is_add;
9085   mp->neighbor.flags = htonl (flags);
9086   if (mac_set)
9087     clib_memcpy (&mp->neighbor.mac_address, &mac_address,
9088                  sizeof (mac_address));
9089   if (address_set)
9090     clib_memcpy (&mp->neighbor.ip_address, &ip_address, sizeof (ip_address));
9091
9092   /* send it... */
9093   S (mp);
9094
9095   /* Wait for a reply, return good/bad news  */
9096   W (ret);
9097   return ret;
9098 }
9099
9100 static int
9101 api_create_vlan_subif (vat_main_t * vam)
9102 {
9103   unformat_input_t *i = vam->input;
9104   vl_api_create_vlan_subif_t *mp;
9105   u32 sw_if_index;
9106   u8 sw_if_index_set = 0;
9107   u32 vlan_id;
9108   u8 vlan_id_set = 0;
9109   int ret;
9110
9111   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9112     {
9113       if (unformat (i, "sw_if_index %d", &sw_if_index))
9114         sw_if_index_set = 1;
9115       else
9116         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9117         sw_if_index_set = 1;
9118       else if (unformat (i, "vlan %d", &vlan_id))
9119         vlan_id_set = 1;
9120       else
9121         {
9122           clib_warning ("parse error '%U'", format_unformat_error, i);
9123           return -99;
9124         }
9125     }
9126
9127   if (sw_if_index_set == 0)
9128     {
9129       errmsg ("missing interface name or sw_if_index");
9130       return -99;
9131     }
9132
9133   if (vlan_id_set == 0)
9134     {
9135       errmsg ("missing vlan_id");
9136       return -99;
9137     }
9138   M (CREATE_VLAN_SUBIF, mp);
9139
9140   mp->sw_if_index = ntohl (sw_if_index);
9141   mp->vlan_id = ntohl (vlan_id);
9142
9143   S (mp);
9144   W (ret);
9145   return ret;
9146 }
9147
9148 #define foreach_create_subif_bit                \
9149 _(no_tags)                                      \
9150 _(one_tag)                                      \
9151 _(two_tags)                                     \
9152 _(dot1ad)                                       \
9153 _(exact_match)                                  \
9154 _(default_sub)                                  \
9155 _(outer_vlan_id_any)                            \
9156 _(inner_vlan_id_any)
9157
9158 #define foreach_create_subif_flag               \
9159 _(0, "no_tags")                                 \
9160 _(1, "one_tag")                                 \
9161 _(2, "two_tags")                                \
9162 _(3, "dot1ad")                                  \
9163 _(4, "exact_match")                             \
9164 _(5, "default_sub")                             \
9165 _(6, "outer_vlan_id_any")                       \
9166 _(7, "inner_vlan_id_any")
9167
9168 static int
9169 api_create_subif (vat_main_t * vam)
9170 {
9171   unformat_input_t *i = vam->input;
9172   vl_api_create_subif_t *mp;
9173   u32 sw_if_index;
9174   u8 sw_if_index_set = 0;
9175   u32 sub_id;
9176   u8 sub_id_set = 0;
9177   u32 __attribute__ ((unused)) no_tags = 0;
9178   u32 __attribute__ ((unused)) one_tag = 0;
9179   u32 __attribute__ ((unused)) two_tags = 0;
9180   u32 __attribute__ ((unused)) dot1ad = 0;
9181   u32 __attribute__ ((unused)) exact_match = 0;
9182   u32 __attribute__ ((unused)) default_sub = 0;
9183   u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
9184   u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
9185   u32 tmp;
9186   u16 outer_vlan_id = 0;
9187   u16 inner_vlan_id = 0;
9188   int ret;
9189
9190   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9191     {
9192       if (unformat (i, "sw_if_index %d", &sw_if_index))
9193         sw_if_index_set = 1;
9194       else
9195         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9196         sw_if_index_set = 1;
9197       else if (unformat (i, "sub_id %d", &sub_id))
9198         sub_id_set = 1;
9199       else if (unformat (i, "outer_vlan_id %d", &tmp))
9200         outer_vlan_id = tmp;
9201       else if (unformat (i, "inner_vlan_id %d", &tmp))
9202         inner_vlan_id = tmp;
9203
9204 #define _(a) else if (unformat (i, #a)) a = 1 ;
9205       foreach_create_subif_bit
9206 #undef _
9207         else
9208         {
9209           clib_warning ("parse error '%U'", format_unformat_error, i);
9210           return -99;
9211         }
9212     }
9213
9214   if (sw_if_index_set == 0)
9215     {
9216       errmsg ("missing interface name or sw_if_index");
9217       return -99;
9218     }
9219
9220   if (sub_id_set == 0)
9221     {
9222       errmsg ("missing sub_id");
9223       return -99;
9224     }
9225   M (CREATE_SUBIF, mp);
9226
9227   mp->sw_if_index = ntohl (sw_if_index);
9228   mp->sub_id = ntohl (sub_id);
9229
9230 #define _(a,b) mp->sub_if_flags |= (1 << a);
9231   foreach_create_subif_flag;
9232 #undef _
9233
9234   mp->outer_vlan_id = ntohs (outer_vlan_id);
9235   mp->inner_vlan_id = ntohs (inner_vlan_id);
9236
9237   S (mp);
9238   W (ret);
9239   return ret;
9240 }
9241
9242 static int
9243 api_reset_fib (vat_main_t * vam)
9244 {
9245   unformat_input_t *i = vam->input;
9246   vl_api_reset_fib_t *mp;
9247   u32 vrf_id = 0;
9248   u8 is_ipv6 = 0;
9249   u8 vrf_id_set = 0;
9250
9251   int ret;
9252   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9253     {
9254       if (unformat (i, "vrf %d", &vrf_id))
9255         vrf_id_set = 1;
9256       else if (unformat (i, "ipv6"))
9257         is_ipv6 = 1;
9258       else
9259         {
9260           clib_warning ("parse error '%U'", format_unformat_error, i);
9261           return -99;
9262         }
9263     }
9264
9265   if (vrf_id_set == 0)
9266     {
9267       errmsg ("missing vrf id");
9268       return -99;
9269     }
9270
9271   M (RESET_FIB, mp);
9272
9273   mp->vrf_id = ntohl (vrf_id);
9274   mp->is_ipv6 = is_ipv6;
9275
9276   S (mp);
9277   W (ret);
9278   return ret;
9279 }
9280
9281 static int
9282 api_dhcp_proxy_config (vat_main_t * vam)
9283 {
9284   unformat_input_t *i = vam->input;
9285   vl_api_dhcp_proxy_config_t *mp;
9286   u32 rx_vrf_id = 0;
9287   u32 server_vrf_id = 0;
9288   u8 is_add = 1;
9289   u8 v4_address_set = 0;
9290   u8 v6_address_set = 0;
9291   ip4_address_t v4address;
9292   ip6_address_t v6address;
9293   u8 v4_src_address_set = 0;
9294   u8 v6_src_address_set = 0;
9295   ip4_address_t v4srcaddress;
9296   ip6_address_t v6srcaddress;
9297   int ret;
9298
9299   /* Parse args required to build the message */
9300   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9301     {
9302       if (unformat (i, "del"))
9303         is_add = 0;
9304       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9305         ;
9306       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9307         ;
9308       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9309         v4_address_set = 1;
9310       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9311         v6_address_set = 1;
9312       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9313         v4_src_address_set = 1;
9314       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9315         v6_src_address_set = 1;
9316       else
9317         break;
9318     }
9319
9320   if (v4_address_set && v6_address_set)
9321     {
9322       errmsg ("both v4 and v6 server addresses set");
9323       return -99;
9324     }
9325   if (!v4_address_set && !v6_address_set)
9326     {
9327       errmsg ("no server addresses set");
9328       return -99;
9329     }
9330
9331   if (v4_src_address_set && v6_src_address_set)
9332     {
9333       errmsg ("both v4 and v6  src addresses set");
9334       return -99;
9335     }
9336   if (!v4_src_address_set && !v6_src_address_set)
9337     {
9338       errmsg ("no src addresses set");
9339       return -99;
9340     }
9341
9342   if (!(v4_src_address_set && v4_address_set) &&
9343       !(v6_src_address_set && v6_address_set))
9344     {
9345       errmsg ("no matching server and src addresses set");
9346       return -99;
9347     }
9348
9349   /* Construct the API message */
9350   M (DHCP_PROXY_CONFIG, mp);
9351
9352   mp->is_add = is_add;
9353   mp->rx_vrf_id = ntohl (rx_vrf_id);
9354   mp->server_vrf_id = ntohl (server_vrf_id);
9355   if (v6_address_set)
9356     {
9357       clib_memcpy (&mp->dhcp_server.un, &v6address, sizeof (v6address));
9358       clib_memcpy (&mp->dhcp_src_address.un, &v6srcaddress,
9359                    sizeof (v6address));
9360     }
9361   else
9362     {
9363       clib_memcpy (&mp->dhcp_server.un, &v4address, sizeof (v4address));
9364       clib_memcpy (&mp->dhcp_src_address.un, &v4srcaddress,
9365                    sizeof (v4address));
9366     }
9367
9368   /* send it... */
9369   S (mp);
9370
9371   /* Wait for a reply, return good/bad news  */
9372   W (ret);
9373   return ret;
9374 }
9375
9376 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9377 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9378
9379 static void
9380 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9381 {
9382   vat_main_t *vam = &vat_main;
9383   u32 i, count = mp->count;
9384   vl_api_dhcp_server_t *s;
9385
9386   if (mp->is_ipv6)
9387     print (vam->ofp,
9388            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9389            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9390            ntohl (mp->rx_vrf_id),
9391            format_ip6_address, mp->dhcp_src_address,
9392            mp->vss_type, mp->vss_vpn_ascii_id,
9393            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9394   else
9395     print (vam->ofp,
9396            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9397            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9398            ntohl (mp->rx_vrf_id),
9399            format_ip4_address, mp->dhcp_src_address,
9400            mp->vss_type, mp->vss_vpn_ascii_id,
9401            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9402
9403   for (i = 0; i < count; i++)
9404     {
9405       s = &mp->servers[i];
9406
9407       if (mp->is_ipv6)
9408         print (vam->ofp,
9409                " Server Table-ID %d, Server Address %U",
9410                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9411       else
9412         print (vam->ofp,
9413                " Server Table-ID %d, Server Address %U",
9414                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9415     }
9416 }
9417
9418 static void vl_api_dhcp_proxy_details_t_handler_json
9419   (vl_api_dhcp_proxy_details_t * mp)
9420 {
9421   vat_main_t *vam = &vat_main;
9422   vat_json_node_t *node = NULL;
9423   u32 i, count = mp->count;
9424   struct in_addr ip4;
9425   struct in6_addr ip6;
9426   vl_api_dhcp_server_t *s;
9427
9428   if (VAT_JSON_ARRAY != vam->json_tree.type)
9429     {
9430       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9431       vat_json_init_array (&vam->json_tree);
9432     }
9433   node = vat_json_array_add (&vam->json_tree);
9434
9435   vat_json_init_object (node);
9436   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9437   vat_json_object_add_uint (node, "vss-type", ntohl (mp->vss_type));
9438   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9439                                    mp->vss_vpn_ascii_id);
9440   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9441   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9442
9443   if (mp->is_ipv6)
9444     {
9445       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9446       vat_json_object_add_ip6 (node, "src_address", ip6);
9447     }
9448   else
9449     {
9450       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9451       vat_json_object_add_ip4 (node, "src_address", ip4);
9452     }
9453
9454   for (i = 0; i < count; i++)
9455     {
9456       s = &mp->servers[i];
9457
9458       vat_json_object_add_uint (node, "server-table-id",
9459                                 ntohl (s->server_vrf_id));
9460
9461       if (mp->is_ipv6)
9462         {
9463           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9464           vat_json_object_add_ip4 (node, "src_address", ip4);
9465         }
9466       else
9467         {
9468           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9469           vat_json_object_add_ip6 (node, "server_address", ip6);
9470         }
9471     }
9472 }
9473
9474 static int
9475 api_dhcp_proxy_dump (vat_main_t * vam)
9476 {
9477   unformat_input_t *i = vam->input;
9478   vl_api_control_ping_t *mp_ping;
9479   vl_api_dhcp_proxy_dump_t *mp;
9480   u8 is_ipv6 = 0;
9481   int ret;
9482
9483   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9484     {
9485       if (unformat (i, "ipv6"))
9486         is_ipv6 = 1;
9487       else
9488         {
9489           clib_warning ("parse error '%U'", format_unformat_error, i);
9490           return -99;
9491         }
9492     }
9493
9494   M (DHCP_PROXY_DUMP, mp);
9495
9496   mp->is_ip6 = is_ipv6;
9497   S (mp);
9498
9499   /* Use a control ping for synchronization */
9500   MPING (CONTROL_PING, mp_ping);
9501   S (mp_ping);
9502
9503   W (ret);
9504   return ret;
9505 }
9506
9507 static int
9508 api_dhcp_proxy_set_vss (vat_main_t * vam)
9509 {
9510   unformat_input_t *i = vam->input;
9511   vl_api_dhcp_proxy_set_vss_t *mp;
9512   u8 is_ipv6 = 0;
9513   u8 is_add = 1;
9514   u32 tbl_id = ~0;
9515   u8 vss_type = VSS_TYPE_DEFAULT;
9516   u8 *vpn_ascii_id = 0;
9517   u32 oui = 0;
9518   u32 fib_id = 0;
9519   int ret;
9520
9521   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9522     {
9523       if (unformat (i, "tbl_id %d", &tbl_id))
9524         ;
9525       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
9526         vss_type = VSS_TYPE_ASCII;
9527       else if (unformat (i, "fib_id %d", &fib_id))
9528         vss_type = VSS_TYPE_VPN_ID;
9529       else if (unformat (i, "oui %d", &oui))
9530         vss_type = VSS_TYPE_VPN_ID;
9531       else if (unformat (i, "ipv6"))
9532         is_ipv6 = 1;
9533       else if (unformat (i, "del"))
9534         is_add = 0;
9535       else
9536         break;
9537     }
9538
9539   if (tbl_id == ~0)
9540     {
9541       errmsg ("missing tbl_id ");
9542       vec_free (vpn_ascii_id);
9543       return -99;
9544     }
9545
9546   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
9547     {
9548       errmsg ("vpn_ascii_id cannot be longer than 128 ");
9549       vec_free (vpn_ascii_id);
9550       return -99;
9551     }
9552
9553   M (DHCP_PROXY_SET_VSS, mp);
9554   mp->tbl_id = ntohl (tbl_id);
9555   mp->vss_type = vss_type;
9556   if (vpn_ascii_id)
9557     {
9558       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
9559       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
9560     }
9561   mp->vpn_index = ntohl (fib_id);
9562   mp->oui = ntohl (oui);
9563   mp->is_ipv6 = is_ipv6;
9564   mp->is_add = is_add;
9565
9566   S (mp);
9567   W (ret);
9568
9569   vec_free (vpn_ascii_id);
9570   return ret;
9571 }
9572
9573 static int
9574 api_dhcp_client_config (vat_main_t * vam)
9575 {
9576   unformat_input_t *i = vam->input;
9577   vl_api_dhcp_client_config_t *mp;
9578   u32 sw_if_index;
9579   u8 sw_if_index_set = 0;
9580   u8 is_add = 1;
9581   u8 *hostname = 0;
9582   u8 disable_event = 0;
9583   int ret;
9584
9585   /* Parse args required to build the message */
9586   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9587     {
9588       if (unformat (i, "del"))
9589         is_add = 0;
9590       else
9591         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9592         sw_if_index_set = 1;
9593       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9594         sw_if_index_set = 1;
9595       else if (unformat (i, "hostname %s", &hostname))
9596         ;
9597       else if (unformat (i, "disable_event"))
9598         disable_event = 1;
9599       else
9600         break;
9601     }
9602
9603   if (sw_if_index_set == 0)
9604     {
9605       errmsg ("missing interface name or sw_if_index");
9606       return -99;
9607     }
9608
9609   if (vec_len (hostname) > 63)
9610     {
9611       errmsg ("hostname too long");
9612     }
9613   vec_add1 (hostname, 0);
9614
9615   /* Construct the API message */
9616   M (DHCP_CLIENT_CONFIG, mp);
9617
9618   mp->is_add = is_add;
9619   mp->client.sw_if_index = htonl (sw_if_index);
9620   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
9621   vec_free (hostname);
9622   mp->client.want_dhcp_event = disable_event ? 0 : 1;
9623   mp->client.pid = htonl (getpid ());
9624
9625   /* send it... */
9626   S (mp);
9627
9628   /* Wait for a reply, return good/bad news  */
9629   W (ret);
9630   return ret;
9631 }
9632
9633 static int
9634 api_set_ip_flow_hash (vat_main_t * vam)
9635 {
9636   unformat_input_t *i = vam->input;
9637   vl_api_set_ip_flow_hash_t *mp;
9638   u32 vrf_id = 0;
9639   u8 is_ipv6 = 0;
9640   u8 vrf_id_set = 0;
9641   u8 src = 0;
9642   u8 dst = 0;
9643   u8 sport = 0;
9644   u8 dport = 0;
9645   u8 proto = 0;
9646   u8 reverse = 0;
9647   int ret;
9648
9649   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9650     {
9651       if (unformat (i, "vrf %d", &vrf_id))
9652         vrf_id_set = 1;
9653       else if (unformat (i, "ipv6"))
9654         is_ipv6 = 1;
9655       else if (unformat (i, "src"))
9656         src = 1;
9657       else if (unformat (i, "dst"))
9658         dst = 1;
9659       else if (unformat (i, "sport"))
9660         sport = 1;
9661       else if (unformat (i, "dport"))
9662         dport = 1;
9663       else if (unformat (i, "proto"))
9664         proto = 1;
9665       else if (unformat (i, "reverse"))
9666         reverse = 1;
9667
9668       else
9669         {
9670           clib_warning ("parse error '%U'", format_unformat_error, i);
9671           return -99;
9672         }
9673     }
9674
9675   if (vrf_id_set == 0)
9676     {
9677       errmsg ("missing vrf id");
9678       return -99;
9679     }
9680
9681   M (SET_IP_FLOW_HASH, mp);
9682   mp->src = src;
9683   mp->dst = dst;
9684   mp->sport = sport;
9685   mp->dport = dport;
9686   mp->proto = proto;
9687   mp->reverse = reverse;
9688   mp->vrf_id = ntohl (vrf_id);
9689   mp->is_ipv6 = is_ipv6;
9690
9691   S (mp);
9692   W (ret);
9693   return ret;
9694 }
9695
9696 static int
9697 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9698 {
9699   unformat_input_t *i = vam->input;
9700   vl_api_sw_interface_ip6_enable_disable_t *mp;
9701   u32 sw_if_index;
9702   u8 sw_if_index_set = 0;
9703   u8 enable = 0;
9704   int ret;
9705
9706   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9707     {
9708       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9709         sw_if_index_set = 1;
9710       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9711         sw_if_index_set = 1;
9712       else if (unformat (i, "enable"))
9713         enable = 1;
9714       else if (unformat (i, "disable"))
9715         enable = 0;
9716       else
9717         {
9718           clib_warning ("parse error '%U'", format_unformat_error, i);
9719           return -99;
9720         }
9721     }
9722
9723   if (sw_if_index_set == 0)
9724     {
9725       errmsg ("missing interface name or sw_if_index");
9726       return -99;
9727     }
9728
9729   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9730
9731   mp->sw_if_index = ntohl (sw_if_index);
9732   mp->enable = enable;
9733
9734   S (mp);
9735   W (ret);
9736   return ret;
9737 }
9738
9739 static int
9740 api_ip6nd_proxy_add_del (vat_main_t * vam)
9741 {
9742   unformat_input_t *i = vam->input;
9743   vl_api_ip6nd_proxy_add_del_t *mp;
9744   u32 sw_if_index = ~0;
9745   u8 v6_address_set = 0;
9746   vl_api_ip6_address_t v6address;
9747   u8 is_del = 0;
9748   int ret;
9749
9750   /* Parse args required to build the message */
9751   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9752     {
9753       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9754         ;
9755       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9756         ;
9757       else if (unformat (i, "%U", unformat_vl_api_ip6_address, &v6address))
9758         v6_address_set = 1;
9759       if (unformat (i, "del"))
9760         is_del = 1;
9761       else
9762         {
9763           clib_warning ("parse error '%U'", format_unformat_error, i);
9764           return -99;
9765         }
9766     }
9767
9768   if (sw_if_index == ~0)
9769     {
9770       errmsg ("missing interface name or sw_if_index");
9771       return -99;
9772     }
9773   if (!v6_address_set)
9774     {
9775       errmsg ("no address set");
9776       return -99;
9777     }
9778
9779   /* Construct the API message */
9780   M (IP6ND_PROXY_ADD_DEL, mp);
9781
9782   mp->is_del = is_del;
9783   mp->sw_if_index = ntohl (sw_if_index);
9784   clib_memcpy (mp->ip, v6address, sizeof (v6address));
9785
9786   /* send it... */
9787   S (mp);
9788
9789   /* Wait for a reply, return good/bad news  */
9790   W (ret);
9791   return ret;
9792 }
9793
9794 static int
9795 api_ip6nd_proxy_dump (vat_main_t * vam)
9796 {
9797   vl_api_ip6nd_proxy_dump_t *mp;
9798   vl_api_control_ping_t *mp_ping;
9799   int ret;
9800
9801   M (IP6ND_PROXY_DUMP, mp);
9802
9803   S (mp);
9804
9805   /* Use a control ping for synchronization */
9806   MPING (CONTROL_PING, mp_ping);
9807   S (mp_ping);
9808
9809   W (ret);
9810   return ret;
9811 }
9812
9813 static void vl_api_ip6nd_proxy_details_t_handler
9814   (vl_api_ip6nd_proxy_details_t * mp)
9815 {
9816   vat_main_t *vam = &vat_main;
9817
9818   print (vam->ofp, "host %U sw_if_index %d",
9819          format_vl_api_ip6_address, mp->ip, ntohl (mp->sw_if_index));
9820 }
9821
9822 static void vl_api_ip6nd_proxy_details_t_handler_json
9823   (vl_api_ip6nd_proxy_details_t * mp)
9824 {
9825   vat_main_t *vam = &vat_main;
9826   struct in6_addr ip6;
9827   vat_json_node_t *node = NULL;
9828
9829   if (VAT_JSON_ARRAY != vam->json_tree.type)
9830     {
9831       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9832       vat_json_init_array (&vam->json_tree);
9833     }
9834   node = vat_json_array_add (&vam->json_tree);
9835
9836   vat_json_init_object (node);
9837   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9838
9839   clib_memcpy (&ip6, mp->ip, sizeof (ip6));
9840   vat_json_object_add_ip6 (node, "host", ip6);
9841 }
9842
9843 static int
9844 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
9845 {
9846   unformat_input_t *i = vam->input;
9847   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
9848   u32 sw_if_index;
9849   u8 sw_if_index_set = 0;
9850   u8 v6_address_set = 0;
9851   vl_api_prefix_t pfx;
9852   u8 use_default = 0;
9853   u8 no_advertise = 0;
9854   u8 off_link = 0;
9855   u8 no_autoconfig = 0;
9856   u8 no_onlink = 0;
9857   u8 is_no = 0;
9858   u32 val_lifetime = 0;
9859   u32 pref_lifetime = 0;
9860   int ret;
9861
9862   /* Parse args required to build the message */
9863   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9864     {
9865       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9866         sw_if_index_set = 1;
9867       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9868         sw_if_index_set = 1;
9869       else if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
9870         v6_address_set = 1;
9871       else if (unformat (i, "val_life %d", &val_lifetime))
9872         ;
9873       else if (unformat (i, "pref_life %d", &pref_lifetime))
9874         ;
9875       else if (unformat (i, "def"))
9876         use_default = 1;
9877       else if (unformat (i, "noadv"))
9878         no_advertise = 1;
9879       else if (unformat (i, "offl"))
9880         off_link = 1;
9881       else if (unformat (i, "noauto"))
9882         no_autoconfig = 1;
9883       else if (unformat (i, "nolink"))
9884         no_onlink = 1;
9885       else if (unformat (i, "isno"))
9886         is_no = 1;
9887       else
9888         {
9889           clib_warning ("parse error '%U'", format_unformat_error, i);
9890           return -99;
9891         }
9892     }
9893
9894   if (sw_if_index_set == 0)
9895     {
9896       errmsg ("missing interface name or sw_if_index");
9897       return -99;
9898     }
9899   if (!v6_address_set)
9900     {
9901       errmsg ("no address set");
9902       return -99;
9903     }
9904
9905   /* Construct the API message */
9906   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9907
9908   mp->sw_if_index = ntohl (sw_if_index);
9909   clib_memcpy (&mp->prefix, &pfx, sizeof (pfx));
9910   mp->use_default = use_default;
9911   mp->no_advertise = no_advertise;
9912   mp->off_link = off_link;
9913   mp->no_autoconfig = no_autoconfig;
9914   mp->no_onlink = no_onlink;
9915   mp->is_no = is_no;
9916   mp->val_lifetime = ntohl (val_lifetime);
9917   mp->pref_lifetime = ntohl (pref_lifetime);
9918
9919   /* send it... */
9920   S (mp);
9921
9922   /* Wait for a reply, return good/bad news  */
9923   W (ret);
9924   return ret;
9925 }
9926
9927 static int
9928 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9929 {
9930   unformat_input_t *i = vam->input;
9931   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9932   u32 sw_if_index;
9933   u8 sw_if_index_set = 0;
9934   u8 suppress = 0;
9935   u8 managed = 0;
9936   u8 other = 0;
9937   u8 ll_option = 0;
9938   u8 send_unicast = 0;
9939   u8 cease = 0;
9940   u8 is_no = 0;
9941   u8 default_router = 0;
9942   u32 max_interval = 0;
9943   u32 min_interval = 0;
9944   u32 lifetime = 0;
9945   u32 initial_count = 0;
9946   u32 initial_interval = 0;
9947   int ret;
9948
9949
9950   /* Parse args required to build the message */
9951   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9952     {
9953       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9954         sw_if_index_set = 1;
9955       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9956         sw_if_index_set = 1;
9957       else if (unformat (i, "maxint %d", &max_interval))
9958         ;
9959       else if (unformat (i, "minint %d", &min_interval))
9960         ;
9961       else if (unformat (i, "life %d", &lifetime))
9962         ;
9963       else if (unformat (i, "count %d", &initial_count))
9964         ;
9965       else if (unformat (i, "interval %d", &initial_interval))
9966         ;
9967       else if (unformat (i, "suppress") || unformat (i, "surpress"))
9968         suppress = 1;
9969       else if (unformat (i, "managed"))
9970         managed = 1;
9971       else if (unformat (i, "other"))
9972         other = 1;
9973       else if (unformat (i, "ll"))
9974         ll_option = 1;
9975       else if (unformat (i, "send"))
9976         send_unicast = 1;
9977       else if (unformat (i, "cease"))
9978         cease = 1;
9979       else if (unformat (i, "isno"))
9980         is_no = 1;
9981       else if (unformat (i, "def"))
9982         default_router = 1;
9983       else
9984         {
9985           clib_warning ("parse error '%U'", format_unformat_error, i);
9986           return -99;
9987         }
9988     }
9989
9990   if (sw_if_index_set == 0)
9991     {
9992       errmsg ("missing interface name or sw_if_index");
9993       return -99;
9994     }
9995
9996   /* Construct the API message */
9997   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
9998
9999   mp->sw_if_index = ntohl (sw_if_index);
10000   mp->max_interval = ntohl (max_interval);
10001   mp->min_interval = ntohl (min_interval);
10002   mp->lifetime = ntohl (lifetime);
10003   mp->initial_count = ntohl (initial_count);
10004   mp->initial_interval = ntohl (initial_interval);
10005   mp->suppress = suppress;
10006   mp->managed = managed;
10007   mp->other = other;
10008   mp->ll_option = ll_option;
10009   mp->send_unicast = send_unicast;
10010   mp->cease = cease;
10011   mp->is_no = is_no;
10012   mp->default_router = default_router;
10013
10014   /* send it... */
10015   S (mp);
10016
10017   /* Wait for a reply, return good/bad news  */
10018   W (ret);
10019   return ret;
10020 }
10021
10022 static int
10023 api_set_arp_neighbor_limit (vat_main_t * vam)
10024 {
10025   unformat_input_t *i = vam->input;
10026   vl_api_set_arp_neighbor_limit_t *mp;
10027   u32 arp_nbr_limit;
10028   u8 limit_set = 0;
10029   u8 is_ipv6 = 0;
10030   int ret;
10031
10032   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10033     {
10034       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10035         limit_set = 1;
10036       else if (unformat (i, "ipv6"))
10037         is_ipv6 = 1;
10038       else
10039         {
10040           clib_warning ("parse error '%U'", format_unformat_error, i);
10041           return -99;
10042         }
10043     }
10044
10045   if (limit_set == 0)
10046     {
10047       errmsg ("missing limit value");
10048       return -99;
10049     }
10050
10051   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10052
10053   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10054   mp->is_ipv6 = is_ipv6;
10055
10056   S (mp);
10057   W (ret);
10058   return ret;
10059 }
10060
10061 static int
10062 api_l2_patch_add_del (vat_main_t * vam)
10063 {
10064   unformat_input_t *i = vam->input;
10065   vl_api_l2_patch_add_del_t *mp;
10066   u32 rx_sw_if_index;
10067   u8 rx_sw_if_index_set = 0;
10068   u32 tx_sw_if_index;
10069   u8 tx_sw_if_index_set = 0;
10070   u8 is_add = 1;
10071   int ret;
10072
10073   /* Parse args required to build the message */
10074   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10075     {
10076       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10077         rx_sw_if_index_set = 1;
10078       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10079         tx_sw_if_index_set = 1;
10080       else if (unformat (i, "rx"))
10081         {
10082           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10083             {
10084               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10085                             &rx_sw_if_index))
10086                 rx_sw_if_index_set = 1;
10087             }
10088           else
10089             break;
10090         }
10091       else if (unformat (i, "tx"))
10092         {
10093           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10094             {
10095               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10096                             &tx_sw_if_index))
10097                 tx_sw_if_index_set = 1;
10098             }
10099           else
10100             break;
10101         }
10102       else if (unformat (i, "del"))
10103         is_add = 0;
10104       else
10105         break;
10106     }
10107
10108   if (rx_sw_if_index_set == 0)
10109     {
10110       errmsg ("missing rx interface name or rx_sw_if_index");
10111       return -99;
10112     }
10113
10114   if (tx_sw_if_index_set == 0)
10115     {
10116       errmsg ("missing tx interface name or tx_sw_if_index");
10117       return -99;
10118     }
10119
10120   M (L2_PATCH_ADD_DEL, mp);
10121
10122   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10123   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10124   mp->is_add = is_add;
10125
10126   S (mp);
10127   W (ret);
10128   return ret;
10129 }
10130
10131 u8 is_del;
10132 u8 localsid_addr[16];
10133 u8 end_psp;
10134 u8 behavior;
10135 u32 sw_if_index;
10136 u32 vlan_index;
10137 u32 fib_table;
10138 u8 nh_addr[16];
10139
10140 static int
10141 api_sr_localsid_add_del (vat_main_t * vam)
10142 {
10143   unformat_input_t *i = vam->input;
10144   vl_api_sr_localsid_add_del_t *mp;
10145
10146   u8 is_del;
10147   ip6_address_t localsid;
10148   u8 end_psp = 0;
10149   u8 behavior = ~0;
10150   u32 sw_if_index;
10151   u32 fib_table = ~(u32) 0;
10152   ip6_address_t nh_addr6;
10153   ip4_address_t nh_addr4;
10154   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
10155   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
10156
10157   bool nexthop_set = 0;
10158
10159   int ret;
10160
10161   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10162     {
10163       if (unformat (i, "del"))
10164         is_del = 1;
10165       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10166       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
10167         nexthop_set = 1;
10168       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
10169         nexthop_set = 1;
10170       else if (unformat (i, "behavior %u", &behavior));
10171       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10172       else if (unformat (i, "fib-table %u", &fib_table));
10173       else if (unformat (i, "end.psp %u", &behavior));
10174       else
10175         break;
10176     }
10177
10178   M (SR_LOCALSID_ADD_DEL, mp);
10179
10180   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
10181   if (nexthop_set)
10182     {
10183       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
10184       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
10185     }
10186   mp->behavior = behavior;
10187   mp->sw_if_index = ntohl (sw_if_index);
10188   mp->fib_table = ntohl (fib_table);
10189   mp->end_psp = end_psp;
10190   mp->is_del = is_del;
10191
10192   S (mp);
10193   W (ret);
10194   return ret;
10195 }
10196
10197 static int
10198 api_ioam_enable (vat_main_t * vam)
10199 {
10200   unformat_input_t *input = vam->input;
10201   vl_api_ioam_enable_t *mp;
10202   u32 id = 0;
10203   int has_trace_option = 0;
10204   int has_pot_option = 0;
10205   int has_seqno_option = 0;
10206   int has_analyse_option = 0;
10207   int ret;
10208
10209   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10210     {
10211       if (unformat (input, "trace"))
10212         has_trace_option = 1;
10213       else if (unformat (input, "pot"))
10214         has_pot_option = 1;
10215       else if (unformat (input, "seqno"))
10216         has_seqno_option = 1;
10217       else if (unformat (input, "analyse"))
10218         has_analyse_option = 1;
10219       else
10220         break;
10221     }
10222   M (IOAM_ENABLE, mp);
10223   mp->id = htons (id);
10224   mp->seqno = has_seqno_option;
10225   mp->analyse = has_analyse_option;
10226   mp->pot_enable = has_pot_option;
10227   mp->trace_enable = has_trace_option;
10228
10229   S (mp);
10230   W (ret);
10231   return ret;
10232 }
10233
10234
10235 static int
10236 api_ioam_disable (vat_main_t * vam)
10237 {
10238   vl_api_ioam_disable_t *mp;
10239   int ret;
10240
10241   M (IOAM_DISABLE, mp);
10242   S (mp);
10243   W (ret);
10244   return ret;
10245 }
10246
10247 #define foreach_tcp_proto_field                 \
10248 _(src_port)                                     \
10249 _(dst_port)
10250
10251 #define foreach_udp_proto_field                 \
10252 _(src_port)                                     \
10253 _(dst_port)
10254
10255 #define foreach_ip4_proto_field                 \
10256 _(src_address)                                  \
10257 _(dst_address)                                  \
10258 _(tos)                                          \
10259 _(length)                                       \
10260 _(fragment_id)                                  \
10261 _(ttl)                                          \
10262 _(protocol)                                     \
10263 _(checksum)
10264
10265 typedef struct
10266 {
10267   u16 src_port, dst_port;
10268 } tcpudp_header_t;
10269
10270 #if VPP_API_TEST_BUILTIN == 0
10271 uword
10272 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10273 {
10274   u8 **maskp = va_arg (*args, u8 **);
10275   u8 *mask = 0;
10276   u8 found_something = 0;
10277   tcp_header_t *tcp;
10278
10279 #define _(a) u8 a=0;
10280   foreach_tcp_proto_field;
10281 #undef _
10282
10283   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10284     {
10285       if (0);
10286 #define _(a) else if (unformat (input, #a)) a=1;
10287       foreach_tcp_proto_field
10288 #undef _
10289         else
10290         break;
10291     }
10292
10293 #define _(a) found_something += a;
10294   foreach_tcp_proto_field;
10295 #undef _
10296
10297   if (found_something == 0)
10298     return 0;
10299
10300   vec_validate (mask, sizeof (*tcp) - 1);
10301
10302   tcp = (tcp_header_t *) mask;
10303
10304 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
10305   foreach_tcp_proto_field;
10306 #undef _
10307
10308   *maskp = mask;
10309   return 1;
10310 }
10311
10312 uword
10313 unformat_udp_mask (unformat_input_t * input, va_list * args)
10314 {
10315   u8 **maskp = va_arg (*args, u8 **);
10316   u8 *mask = 0;
10317   u8 found_something = 0;
10318   udp_header_t *udp;
10319
10320 #define _(a) u8 a=0;
10321   foreach_udp_proto_field;
10322 #undef _
10323
10324   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10325     {
10326       if (0);
10327 #define _(a) else if (unformat (input, #a)) a=1;
10328       foreach_udp_proto_field
10329 #undef _
10330         else
10331         break;
10332     }
10333
10334 #define _(a) found_something += a;
10335   foreach_udp_proto_field;
10336 #undef _
10337
10338   if (found_something == 0)
10339     return 0;
10340
10341   vec_validate (mask, sizeof (*udp) - 1);
10342
10343   udp = (udp_header_t *) mask;
10344
10345 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
10346   foreach_udp_proto_field;
10347 #undef _
10348
10349   *maskp = mask;
10350   return 1;
10351 }
10352
10353 uword
10354 unformat_l4_mask (unformat_input_t * input, va_list * args)
10355 {
10356   u8 **maskp = va_arg (*args, u8 **);
10357   u16 src_port = 0, dst_port = 0;
10358   tcpudp_header_t *tcpudp;
10359
10360   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10361     {
10362       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10363         return 1;
10364       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10365         return 1;
10366       else if (unformat (input, "src_port"))
10367         src_port = 0xFFFF;
10368       else if (unformat (input, "dst_port"))
10369         dst_port = 0xFFFF;
10370       else
10371         return 0;
10372     }
10373
10374   if (!src_port && !dst_port)
10375     return 0;
10376
10377   u8 *mask = 0;
10378   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10379
10380   tcpudp = (tcpudp_header_t *) mask;
10381   tcpudp->src_port = src_port;
10382   tcpudp->dst_port = dst_port;
10383
10384   *maskp = mask;
10385
10386   return 1;
10387 }
10388
10389 uword
10390 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10391 {
10392   u8 **maskp = va_arg (*args, u8 **);
10393   u8 *mask = 0;
10394   u8 found_something = 0;
10395   ip4_header_t *ip;
10396
10397 #define _(a) u8 a=0;
10398   foreach_ip4_proto_field;
10399 #undef _
10400   u8 version = 0;
10401   u8 hdr_length = 0;
10402
10403
10404   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10405     {
10406       if (unformat (input, "version"))
10407         version = 1;
10408       else if (unformat (input, "hdr_length"))
10409         hdr_length = 1;
10410       else if (unformat (input, "src"))
10411         src_address = 1;
10412       else if (unformat (input, "dst"))
10413         dst_address = 1;
10414       else if (unformat (input, "proto"))
10415         protocol = 1;
10416
10417 #define _(a) else if (unformat (input, #a)) a=1;
10418       foreach_ip4_proto_field
10419 #undef _
10420         else
10421         break;
10422     }
10423
10424 #define _(a) found_something += a;
10425   foreach_ip4_proto_field;
10426 #undef _
10427
10428   if (found_something == 0)
10429     return 0;
10430
10431   vec_validate (mask, sizeof (*ip) - 1);
10432
10433   ip = (ip4_header_t *) mask;
10434
10435 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10436   foreach_ip4_proto_field;
10437 #undef _
10438
10439   ip->ip_version_and_header_length = 0;
10440
10441   if (version)
10442     ip->ip_version_and_header_length |= 0xF0;
10443
10444   if (hdr_length)
10445     ip->ip_version_and_header_length |= 0x0F;
10446
10447   *maskp = mask;
10448   return 1;
10449 }
10450
10451 #define foreach_ip6_proto_field                 \
10452 _(src_address)                                  \
10453 _(dst_address)                                  \
10454 _(payload_length)                               \
10455 _(hop_limit)                                    \
10456 _(protocol)
10457
10458 uword
10459 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10460 {
10461   u8 **maskp = va_arg (*args, u8 **);
10462   u8 *mask = 0;
10463   u8 found_something = 0;
10464   ip6_header_t *ip;
10465   u32 ip_version_traffic_class_and_flow_label;
10466
10467 #define _(a) u8 a=0;
10468   foreach_ip6_proto_field;
10469 #undef _
10470   u8 version = 0;
10471   u8 traffic_class = 0;
10472   u8 flow_label = 0;
10473
10474   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10475     {
10476       if (unformat (input, "version"))
10477         version = 1;
10478       else if (unformat (input, "traffic-class"))
10479         traffic_class = 1;
10480       else if (unformat (input, "flow-label"))
10481         flow_label = 1;
10482       else if (unformat (input, "src"))
10483         src_address = 1;
10484       else if (unformat (input, "dst"))
10485         dst_address = 1;
10486       else if (unformat (input, "proto"))
10487         protocol = 1;
10488
10489 #define _(a) else if (unformat (input, #a)) a=1;
10490       foreach_ip6_proto_field
10491 #undef _
10492         else
10493         break;
10494     }
10495
10496 #define _(a) found_something += a;
10497   foreach_ip6_proto_field;
10498 #undef _
10499
10500   if (found_something == 0)
10501     return 0;
10502
10503   vec_validate (mask, sizeof (*ip) - 1);
10504
10505   ip = (ip6_header_t *) mask;
10506
10507 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10508   foreach_ip6_proto_field;
10509 #undef _
10510
10511   ip_version_traffic_class_and_flow_label = 0;
10512
10513   if (version)
10514     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10515
10516   if (traffic_class)
10517     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10518
10519   if (flow_label)
10520     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10521
10522   ip->ip_version_traffic_class_and_flow_label =
10523     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10524
10525   *maskp = mask;
10526   return 1;
10527 }
10528
10529 uword
10530 unformat_l3_mask (unformat_input_t * input, va_list * args)
10531 {
10532   u8 **maskp = va_arg (*args, u8 **);
10533
10534   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10535     {
10536       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10537         return 1;
10538       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10539         return 1;
10540       else
10541         break;
10542     }
10543   return 0;
10544 }
10545
10546 uword
10547 unformat_l2_mask (unformat_input_t * input, va_list * args)
10548 {
10549   u8 **maskp = va_arg (*args, u8 **);
10550   u8 *mask = 0;
10551   u8 src = 0;
10552   u8 dst = 0;
10553   u8 proto = 0;
10554   u8 tag1 = 0;
10555   u8 tag2 = 0;
10556   u8 ignore_tag1 = 0;
10557   u8 ignore_tag2 = 0;
10558   u8 cos1 = 0;
10559   u8 cos2 = 0;
10560   u8 dot1q = 0;
10561   u8 dot1ad = 0;
10562   int len = 14;
10563
10564   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10565     {
10566       if (unformat (input, "src"))
10567         src = 1;
10568       else if (unformat (input, "dst"))
10569         dst = 1;
10570       else if (unformat (input, "proto"))
10571         proto = 1;
10572       else if (unformat (input, "tag1"))
10573         tag1 = 1;
10574       else if (unformat (input, "tag2"))
10575         tag2 = 1;
10576       else if (unformat (input, "ignore-tag1"))
10577         ignore_tag1 = 1;
10578       else if (unformat (input, "ignore-tag2"))
10579         ignore_tag2 = 1;
10580       else if (unformat (input, "cos1"))
10581         cos1 = 1;
10582       else if (unformat (input, "cos2"))
10583         cos2 = 1;
10584       else if (unformat (input, "dot1q"))
10585         dot1q = 1;
10586       else if (unformat (input, "dot1ad"))
10587         dot1ad = 1;
10588       else
10589         break;
10590     }
10591   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10592        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10593     return 0;
10594
10595   if (tag1 || ignore_tag1 || cos1 || dot1q)
10596     len = 18;
10597   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10598     len = 22;
10599
10600   vec_validate (mask, len - 1);
10601
10602   if (dst)
10603     clib_memset (mask, 0xff, 6);
10604
10605   if (src)
10606     clib_memset (mask + 6, 0xff, 6);
10607
10608   if (tag2 || dot1ad)
10609     {
10610       /* inner vlan tag */
10611       if (tag2)
10612         {
10613           mask[19] = 0xff;
10614           mask[18] = 0x0f;
10615         }
10616       if (cos2)
10617         mask[18] |= 0xe0;
10618       if (proto)
10619         mask[21] = mask[20] = 0xff;
10620       if (tag1)
10621         {
10622           mask[15] = 0xff;
10623           mask[14] = 0x0f;
10624         }
10625       if (cos1)
10626         mask[14] |= 0xe0;
10627       *maskp = mask;
10628       return 1;
10629     }
10630   if (tag1 | dot1q)
10631     {
10632       if (tag1)
10633         {
10634           mask[15] = 0xff;
10635           mask[14] = 0x0f;
10636         }
10637       if (cos1)
10638         mask[14] |= 0xe0;
10639       if (proto)
10640         mask[16] = mask[17] = 0xff;
10641
10642       *maskp = mask;
10643       return 1;
10644     }
10645   if (cos2)
10646     mask[18] |= 0xe0;
10647   if (cos1)
10648     mask[14] |= 0xe0;
10649   if (proto)
10650     mask[12] = mask[13] = 0xff;
10651
10652   *maskp = mask;
10653   return 1;
10654 }
10655
10656 uword
10657 unformat_classify_mask (unformat_input_t * input, va_list * args)
10658 {
10659   u8 **maskp = va_arg (*args, u8 **);
10660   u32 *skipp = va_arg (*args, u32 *);
10661   u32 *matchp = va_arg (*args, u32 *);
10662   u32 match;
10663   u8 *mask = 0;
10664   u8 *l2 = 0;
10665   u8 *l3 = 0;
10666   u8 *l4 = 0;
10667   int i;
10668
10669   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10670     {
10671       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10672         ;
10673       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10674         ;
10675       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10676         ;
10677       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10678         ;
10679       else
10680         break;
10681     }
10682
10683   if (l4 && !l3)
10684     {
10685       vec_free (mask);
10686       vec_free (l2);
10687       vec_free (l4);
10688       return 0;
10689     }
10690
10691   if (mask || l2 || l3 || l4)
10692     {
10693       if (l2 || l3 || l4)
10694         {
10695           /* "With a free Ethernet header in every package" */
10696           if (l2 == 0)
10697             vec_validate (l2, 13);
10698           mask = l2;
10699           if (vec_len (l3))
10700             {
10701               vec_append (mask, l3);
10702               vec_free (l3);
10703             }
10704           if (vec_len (l4))
10705             {
10706               vec_append (mask, l4);
10707               vec_free (l4);
10708             }
10709         }
10710
10711       /* Scan forward looking for the first significant mask octet */
10712       for (i = 0; i < vec_len (mask); i++)
10713         if (mask[i])
10714           break;
10715
10716       /* compute (skip, match) params */
10717       *skipp = i / sizeof (u32x4);
10718       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10719
10720       /* Pad mask to an even multiple of the vector size */
10721       while (vec_len (mask) % sizeof (u32x4))
10722         vec_add1 (mask, 0);
10723
10724       match = vec_len (mask) / sizeof (u32x4);
10725
10726       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10727         {
10728           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10729           if (*tmp || *(tmp + 1))
10730             break;
10731           match--;
10732         }
10733       if (match == 0)
10734         clib_warning ("BUG: match 0");
10735
10736       _vec_len (mask) = match * sizeof (u32x4);
10737
10738       *matchp = match;
10739       *maskp = mask;
10740
10741       return 1;
10742     }
10743
10744   return 0;
10745 }
10746 #endif /* VPP_API_TEST_BUILTIN */
10747
10748 #define foreach_l2_next                         \
10749 _(drop, DROP)                                   \
10750 _(ethernet, ETHERNET_INPUT)                     \
10751 _(ip4, IP4_INPUT)                               \
10752 _(ip6, IP6_INPUT)
10753
10754 uword
10755 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10756 {
10757   u32 *miss_next_indexp = va_arg (*args, u32 *);
10758   u32 next_index = 0;
10759   u32 tmp;
10760
10761 #define _(n,N) \
10762   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10763   foreach_l2_next;
10764 #undef _
10765
10766   if (unformat (input, "%d", &tmp))
10767     {
10768       next_index = tmp;
10769       goto out;
10770     }
10771
10772   return 0;
10773
10774 out:
10775   *miss_next_indexp = next_index;
10776   return 1;
10777 }
10778
10779 #define foreach_ip_next                         \
10780 _(drop, DROP)                                   \
10781 _(local, LOCAL)                                 \
10782 _(rewrite, REWRITE)
10783
10784 uword
10785 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10786 {
10787   u32 *miss_next_indexp = va_arg (*args, u32 *);
10788   u32 next_index = 0;
10789   u32 tmp;
10790
10791 #define _(n,N) \
10792   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10793   foreach_ip_next;
10794 #undef _
10795
10796   if (unformat (input, "%d", &tmp))
10797     {
10798       next_index = tmp;
10799       goto out;
10800     }
10801
10802   return 0;
10803
10804 out:
10805   *miss_next_indexp = next_index;
10806   return 1;
10807 }
10808
10809 #define foreach_acl_next                        \
10810 _(deny, DENY)
10811
10812 uword
10813 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10814 {
10815   u32 *miss_next_indexp = va_arg (*args, u32 *);
10816   u32 next_index = 0;
10817   u32 tmp;
10818
10819 #define _(n,N) \
10820   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10821   foreach_acl_next;
10822 #undef _
10823
10824   if (unformat (input, "permit"))
10825     {
10826       next_index = ~0;
10827       goto out;
10828     }
10829   else if (unformat (input, "%d", &tmp))
10830     {
10831       next_index = tmp;
10832       goto out;
10833     }
10834
10835   return 0;
10836
10837 out:
10838   *miss_next_indexp = next_index;
10839   return 1;
10840 }
10841
10842 uword
10843 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10844 {
10845   u32 *r = va_arg (*args, u32 *);
10846
10847   if (unformat (input, "conform-color"))
10848     *r = POLICE_CONFORM;
10849   else if (unformat (input, "exceed-color"))
10850     *r = POLICE_EXCEED;
10851   else
10852     return 0;
10853
10854   return 1;
10855 }
10856
10857 static int
10858 api_classify_add_del_table (vat_main_t * vam)
10859 {
10860   unformat_input_t *i = vam->input;
10861   vl_api_classify_add_del_table_t *mp;
10862
10863   u32 nbuckets = 2;
10864   u32 skip = ~0;
10865   u32 match = ~0;
10866   int is_add = 1;
10867   int del_chain = 0;
10868   u32 table_index = ~0;
10869   u32 next_table_index = ~0;
10870   u32 miss_next_index = ~0;
10871   u32 memory_size = 32 << 20;
10872   u8 *mask = 0;
10873   u32 current_data_flag = 0;
10874   int current_data_offset = 0;
10875   int ret;
10876
10877   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10878     {
10879       if (unformat (i, "del"))
10880         is_add = 0;
10881       else if (unformat (i, "del-chain"))
10882         {
10883           is_add = 0;
10884           del_chain = 1;
10885         }
10886       else if (unformat (i, "buckets %d", &nbuckets))
10887         ;
10888       else if (unformat (i, "memory_size %d", &memory_size))
10889         ;
10890       else if (unformat (i, "skip %d", &skip))
10891         ;
10892       else if (unformat (i, "match %d", &match))
10893         ;
10894       else if (unformat (i, "table %d", &table_index))
10895         ;
10896       else if (unformat (i, "mask %U", unformat_classify_mask,
10897                          &mask, &skip, &match))
10898         ;
10899       else if (unformat (i, "next-table %d", &next_table_index))
10900         ;
10901       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10902                          &miss_next_index))
10903         ;
10904       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10905                          &miss_next_index))
10906         ;
10907       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10908                          &miss_next_index))
10909         ;
10910       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10911         ;
10912       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10913         ;
10914       else
10915         break;
10916     }
10917
10918   if (is_add && mask == 0)
10919     {
10920       errmsg ("Mask required");
10921       return -99;
10922     }
10923
10924   if (is_add && skip == ~0)
10925     {
10926       errmsg ("skip count required");
10927       return -99;
10928     }
10929
10930   if (is_add && match == ~0)
10931     {
10932       errmsg ("match count required");
10933       return -99;
10934     }
10935
10936   if (!is_add && table_index == ~0)
10937     {
10938       errmsg ("table index required for delete");
10939       return -99;
10940     }
10941
10942   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10943
10944   mp->is_add = is_add;
10945   mp->del_chain = del_chain;
10946   mp->table_index = ntohl (table_index);
10947   mp->nbuckets = ntohl (nbuckets);
10948   mp->memory_size = ntohl (memory_size);
10949   mp->skip_n_vectors = ntohl (skip);
10950   mp->match_n_vectors = ntohl (match);
10951   mp->next_table_index = ntohl (next_table_index);
10952   mp->miss_next_index = ntohl (miss_next_index);
10953   mp->current_data_flag = ntohl (current_data_flag);
10954   mp->current_data_offset = ntohl (current_data_offset);
10955   mp->mask_len = ntohl (vec_len (mask));
10956   clib_memcpy (mp->mask, mask, vec_len (mask));
10957
10958   vec_free (mask);
10959
10960   S (mp);
10961   W (ret);
10962   return ret;
10963 }
10964
10965 #if VPP_API_TEST_BUILTIN == 0
10966 uword
10967 unformat_l4_match (unformat_input_t * input, va_list * args)
10968 {
10969   u8 **matchp = va_arg (*args, u8 **);
10970
10971   u8 *proto_header = 0;
10972   int src_port = 0;
10973   int dst_port = 0;
10974
10975   tcpudp_header_t h;
10976
10977   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10978     {
10979       if (unformat (input, "src_port %d", &src_port))
10980         ;
10981       else if (unformat (input, "dst_port %d", &dst_port))
10982         ;
10983       else
10984         return 0;
10985     }
10986
10987   h.src_port = clib_host_to_net_u16 (src_port);
10988   h.dst_port = clib_host_to_net_u16 (dst_port);
10989   vec_validate (proto_header, sizeof (h) - 1);
10990   memcpy (proto_header, &h, sizeof (h));
10991
10992   *matchp = proto_header;
10993
10994   return 1;
10995 }
10996
10997 uword
10998 unformat_ip4_match (unformat_input_t * input, va_list * args)
10999 {
11000   u8 **matchp = va_arg (*args, u8 **);
11001   u8 *match = 0;
11002   ip4_header_t *ip;
11003   int version = 0;
11004   u32 version_val;
11005   int hdr_length = 0;
11006   u32 hdr_length_val;
11007   int src = 0, dst = 0;
11008   ip4_address_t src_val, dst_val;
11009   int proto = 0;
11010   u32 proto_val;
11011   int tos = 0;
11012   u32 tos_val;
11013   int length = 0;
11014   u32 length_val;
11015   int fragment_id = 0;
11016   u32 fragment_id_val;
11017   int ttl = 0;
11018   int ttl_val;
11019   int checksum = 0;
11020   u32 checksum_val;
11021
11022   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11023     {
11024       if (unformat (input, "version %d", &version_val))
11025         version = 1;
11026       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11027         hdr_length = 1;
11028       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11029         src = 1;
11030       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11031         dst = 1;
11032       else if (unformat (input, "proto %d", &proto_val))
11033         proto = 1;
11034       else if (unformat (input, "tos %d", &tos_val))
11035         tos = 1;
11036       else if (unformat (input, "length %d", &length_val))
11037         length = 1;
11038       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11039         fragment_id = 1;
11040       else if (unformat (input, "ttl %d", &ttl_val))
11041         ttl = 1;
11042       else if (unformat (input, "checksum %d", &checksum_val))
11043         checksum = 1;
11044       else
11045         break;
11046     }
11047
11048   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11049       + ttl + checksum == 0)
11050     return 0;
11051
11052   /*
11053    * Aligned because we use the real comparison functions
11054    */
11055   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11056
11057   ip = (ip4_header_t *) match;
11058
11059   /* These are realistically matched in practice */
11060   if (src)
11061     ip->src_address.as_u32 = src_val.as_u32;
11062
11063   if (dst)
11064     ip->dst_address.as_u32 = dst_val.as_u32;
11065
11066   if (proto)
11067     ip->protocol = proto_val;
11068
11069
11070   /* These are not, but they're included for completeness */
11071   if (version)
11072     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11073
11074   if (hdr_length)
11075     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11076
11077   if (tos)
11078     ip->tos = tos_val;
11079
11080   if (length)
11081     ip->length = clib_host_to_net_u16 (length_val);
11082
11083   if (ttl)
11084     ip->ttl = ttl_val;
11085
11086   if (checksum)
11087     ip->checksum = clib_host_to_net_u16 (checksum_val);
11088
11089   *matchp = match;
11090   return 1;
11091 }
11092
11093 uword
11094 unformat_ip6_match (unformat_input_t * input, va_list * args)
11095 {
11096   u8 **matchp = va_arg (*args, u8 **);
11097   u8 *match = 0;
11098   ip6_header_t *ip;
11099   int version = 0;
11100   u32 version_val;
11101   u8 traffic_class = 0;
11102   u32 traffic_class_val = 0;
11103   u8 flow_label = 0;
11104   u8 flow_label_val;
11105   int src = 0, dst = 0;
11106   ip6_address_t src_val, dst_val;
11107   int proto = 0;
11108   u32 proto_val;
11109   int payload_length = 0;
11110   u32 payload_length_val;
11111   int hop_limit = 0;
11112   int hop_limit_val;
11113   u32 ip_version_traffic_class_and_flow_label;
11114
11115   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11116     {
11117       if (unformat (input, "version %d", &version_val))
11118         version = 1;
11119       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11120         traffic_class = 1;
11121       else if (unformat (input, "flow_label %d", &flow_label_val))
11122         flow_label = 1;
11123       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11124         src = 1;
11125       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11126         dst = 1;
11127       else if (unformat (input, "proto %d", &proto_val))
11128         proto = 1;
11129       else if (unformat (input, "payload_length %d", &payload_length_val))
11130         payload_length = 1;
11131       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11132         hop_limit = 1;
11133       else
11134         break;
11135     }
11136
11137   if (version + traffic_class + flow_label + src + dst + proto +
11138       payload_length + hop_limit == 0)
11139     return 0;
11140
11141   /*
11142    * Aligned because we use the real comparison functions
11143    */
11144   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11145
11146   ip = (ip6_header_t *) match;
11147
11148   if (src)
11149     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11150
11151   if (dst)
11152     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11153
11154   if (proto)
11155     ip->protocol = proto_val;
11156
11157   ip_version_traffic_class_and_flow_label = 0;
11158
11159   if (version)
11160     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11161
11162   if (traffic_class)
11163     ip_version_traffic_class_and_flow_label |=
11164       (traffic_class_val & 0xFF) << 20;
11165
11166   if (flow_label)
11167     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11168
11169   ip->ip_version_traffic_class_and_flow_label =
11170     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11171
11172   if (payload_length)
11173     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11174
11175   if (hop_limit)
11176     ip->hop_limit = hop_limit_val;
11177
11178   *matchp = match;
11179   return 1;
11180 }
11181
11182 uword
11183 unformat_l3_match (unformat_input_t * input, va_list * args)
11184 {
11185   u8 **matchp = va_arg (*args, u8 **);
11186
11187   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11188     {
11189       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11190         return 1;
11191       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11192         return 1;
11193       else
11194         break;
11195     }
11196   return 0;
11197 }
11198
11199 uword
11200 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11201 {
11202   u8 *tagp = va_arg (*args, u8 *);
11203   u32 tag;
11204
11205   if (unformat (input, "%d", &tag))
11206     {
11207       tagp[0] = (tag >> 8) & 0x0F;
11208       tagp[1] = tag & 0xFF;
11209       return 1;
11210     }
11211
11212   return 0;
11213 }
11214
11215 uword
11216 unformat_l2_match (unformat_input_t * input, va_list * args)
11217 {
11218   u8 **matchp = va_arg (*args, u8 **);
11219   u8 *match = 0;
11220   u8 src = 0;
11221   u8 src_val[6];
11222   u8 dst = 0;
11223   u8 dst_val[6];
11224   u8 proto = 0;
11225   u16 proto_val;
11226   u8 tag1 = 0;
11227   u8 tag1_val[2];
11228   u8 tag2 = 0;
11229   u8 tag2_val[2];
11230   int len = 14;
11231   u8 ignore_tag1 = 0;
11232   u8 ignore_tag2 = 0;
11233   u8 cos1 = 0;
11234   u8 cos2 = 0;
11235   u32 cos1_val = 0;
11236   u32 cos2_val = 0;
11237
11238   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11239     {
11240       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11241         src = 1;
11242       else
11243         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11244         dst = 1;
11245       else if (unformat (input, "proto %U",
11246                          unformat_ethernet_type_host_byte_order, &proto_val))
11247         proto = 1;
11248       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11249         tag1 = 1;
11250       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11251         tag2 = 1;
11252       else if (unformat (input, "ignore-tag1"))
11253         ignore_tag1 = 1;
11254       else if (unformat (input, "ignore-tag2"))
11255         ignore_tag2 = 1;
11256       else if (unformat (input, "cos1 %d", &cos1_val))
11257         cos1 = 1;
11258       else if (unformat (input, "cos2 %d", &cos2_val))
11259         cos2 = 1;
11260       else
11261         break;
11262     }
11263   if ((src + dst + proto + tag1 + tag2 +
11264        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11265     return 0;
11266
11267   if (tag1 || ignore_tag1 || cos1)
11268     len = 18;
11269   if (tag2 || ignore_tag2 || cos2)
11270     len = 22;
11271
11272   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11273
11274   if (dst)
11275     clib_memcpy (match, dst_val, 6);
11276
11277   if (src)
11278     clib_memcpy (match + 6, src_val, 6);
11279
11280   if (tag2)
11281     {
11282       /* inner vlan tag */
11283       match[19] = tag2_val[1];
11284       match[18] = tag2_val[0];
11285       if (cos2)
11286         match[18] |= (cos2_val & 0x7) << 5;
11287       if (proto)
11288         {
11289           match[21] = proto_val & 0xff;
11290           match[20] = proto_val >> 8;
11291         }
11292       if (tag1)
11293         {
11294           match[15] = tag1_val[1];
11295           match[14] = tag1_val[0];
11296         }
11297       if (cos1)
11298         match[14] |= (cos1_val & 0x7) << 5;
11299       *matchp = match;
11300       return 1;
11301     }
11302   if (tag1)
11303     {
11304       match[15] = tag1_val[1];
11305       match[14] = tag1_val[0];
11306       if (proto)
11307         {
11308           match[17] = proto_val & 0xff;
11309           match[16] = proto_val >> 8;
11310         }
11311       if (cos1)
11312         match[14] |= (cos1_val & 0x7) << 5;
11313
11314       *matchp = match;
11315       return 1;
11316     }
11317   if (cos2)
11318     match[18] |= (cos2_val & 0x7) << 5;
11319   if (cos1)
11320     match[14] |= (cos1_val & 0x7) << 5;
11321   if (proto)
11322     {
11323       match[13] = proto_val & 0xff;
11324       match[12] = proto_val >> 8;
11325     }
11326
11327   *matchp = match;
11328   return 1;
11329 }
11330
11331 uword
11332 unformat_qos_source (unformat_input_t * input, va_list * args)
11333 {
11334   int *qs = va_arg (*args, int *);
11335
11336   if (unformat (input, "ip"))
11337     *qs = QOS_SOURCE_IP;
11338   else if (unformat (input, "mpls"))
11339     *qs = QOS_SOURCE_MPLS;
11340   else if (unformat (input, "ext"))
11341     *qs = QOS_SOURCE_EXT;
11342   else if (unformat (input, "vlan"))
11343     *qs = QOS_SOURCE_VLAN;
11344   else
11345     return 0;
11346
11347   return 1;
11348 }
11349 #endif
11350
11351 uword
11352 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11353 {
11354   u8 **matchp = va_arg (*args, u8 **);
11355   u32 skip_n_vectors = va_arg (*args, u32);
11356   u32 match_n_vectors = va_arg (*args, u32);
11357
11358   u8 *match = 0;
11359   u8 *l2 = 0;
11360   u8 *l3 = 0;
11361   u8 *l4 = 0;
11362
11363   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11364     {
11365       if (unformat (input, "hex %U", unformat_hex_string, &match))
11366         ;
11367       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11368         ;
11369       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11370         ;
11371       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11372         ;
11373       else
11374         break;
11375     }
11376
11377   if (l4 && !l3)
11378     {
11379       vec_free (match);
11380       vec_free (l2);
11381       vec_free (l4);
11382       return 0;
11383     }
11384
11385   if (match || l2 || l3 || l4)
11386     {
11387       if (l2 || l3 || l4)
11388         {
11389           /* "Win a free Ethernet header in every packet" */
11390           if (l2 == 0)
11391             vec_validate_aligned (l2, 13, sizeof (u32x4));
11392           match = l2;
11393           if (vec_len (l3))
11394             {
11395               vec_append_aligned (match, l3, sizeof (u32x4));
11396               vec_free (l3);
11397             }
11398           if (vec_len (l4))
11399             {
11400               vec_append_aligned (match, l4, sizeof (u32x4));
11401               vec_free (l4);
11402             }
11403         }
11404
11405       /* Make sure the vector is big enough even if key is all 0's */
11406       vec_validate_aligned
11407         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11408          sizeof (u32x4));
11409
11410       /* Set size, include skipped vectors */
11411       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11412
11413       *matchp = match;
11414
11415       return 1;
11416     }
11417
11418   return 0;
11419 }
11420
11421 static int
11422 api_classify_add_del_session (vat_main_t * vam)
11423 {
11424   unformat_input_t *i = vam->input;
11425   vl_api_classify_add_del_session_t *mp;
11426   int is_add = 1;
11427   u32 table_index = ~0;
11428   u32 hit_next_index = ~0;
11429   u32 opaque_index = ~0;
11430   u8 *match = 0;
11431   i32 advance = 0;
11432   u32 skip_n_vectors = 0;
11433   u32 match_n_vectors = 0;
11434   u32 action = 0;
11435   u32 metadata = 0;
11436   int ret;
11437
11438   /*
11439    * Warning: you have to supply skip_n and match_n
11440    * because the API client cant simply look at the classify
11441    * table object.
11442    */
11443
11444   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11445     {
11446       if (unformat (i, "del"))
11447         is_add = 0;
11448       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11449                          &hit_next_index))
11450         ;
11451       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11452                          &hit_next_index))
11453         ;
11454       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11455                          &hit_next_index))
11456         ;
11457       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11458         ;
11459       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11460         ;
11461       else if (unformat (i, "opaque-index %d", &opaque_index))
11462         ;
11463       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11464         ;
11465       else if (unformat (i, "match_n %d", &match_n_vectors))
11466         ;
11467       else if (unformat (i, "match %U", api_unformat_classify_match,
11468                          &match, skip_n_vectors, match_n_vectors))
11469         ;
11470       else if (unformat (i, "advance %d", &advance))
11471         ;
11472       else if (unformat (i, "table-index %d", &table_index))
11473         ;
11474       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11475         action = 1;
11476       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11477         action = 2;
11478       else if (unformat (i, "action %d", &action))
11479         ;
11480       else if (unformat (i, "metadata %d", &metadata))
11481         ;
11482       else
11483         break;
11484     }
11485
11486   if (table_index == ~0)
11487     {
11488       errmsg ("Table index required");
11489       return -99;
11490     }
11491
11492   if (is_add && match == 0)
11493     {
11494       errmsg ("Match value required");
11495       return -99;
11496     }
11497
11498   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11499
11500   mp->is_add = is_add;
11501   mp->table_index = ntohl (table_index);
11502   mp->hit_next_index = ntohl (hit_next_index);
11503   mp->opaque_index = ntohl (opaque_index);
11504   mp->advance = ntohl (advance);
11505   mp->action = action;
11506   mp->metadata = ntohl (metadata);
11507   mp->match_len = ntohl (vec_len (match));
11508   clib_memcpy (mp->match, match, vec_len (match));
11509   vec_free (match);
11510
11511   S (mp);
11512   W (ret);
11513   return ret;
11514 }
11515
11516 static int
11517 api_classify_set_interface_ip_table (vat_main_t * vam)
11518 {
11519   unformat_input_t *i = vam->input;
11520   vl_api_classify_set_interface_ip_table_t *mp;
11521   u32 sw_if_index;
11522   int sw_if_index_set;
11523   u32 table_index = ~0;
11524   u8 is_ipv6 = 0;
11525   int ret;
11526
11527   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11528     {
11529       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11530         sw_if_index_set = 1;
11531       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11532         sw_if_index_set = 1;
11533       else if (unformat (i, "table %d", &table_index))
11534         ;
11535       else
11536         {
11537           clib_warning ("parse error '%U'", format_unformat_error, i);
11538           return -99;
11539         }
11540     }
11541
11542   if (sw_if_index_set == 0)
11543     {
11544       errmsg ("missing interface name or sw_if_index");
11545       return -99;
11546     }
11547
11548
11549   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11550
11551   mp->sw_if_index = ntohl (sw_if_index);
11552   mp->table_index = ntohl (table_index);
11553   mp->is_ipv6 = is_ipv6;
11554
11555   S (mp);
11556   W (ret);
11557   return ret;
11558 }
11559
11560 static int
11561 api_classify_set_interface_l2_tables (vat_main_t * vam)
11562 {
11563   unformat_input_t *i = vam->input;
11564   vl_api_classify_set_interface_l2_tables_t *mp;
11565   u32 sw_if_index;
11566   int sw_if_index_set;
11567   u32 ip4_table_index = ~0;
11568   u32 ip6_table_index = ~0;
11569   u32 other_table_index = ~0;
11570   u32 is_input = 1;
11571   int ret;
11572
11573   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11574     {
11575       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11576         sw_if_index_set = 1;
11577       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11578         sw_if_index_set = 1;
11579       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11580         ;
11581       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11582         ;
11583       else if (unformat (i, "other-table %d", &other_table_index))
11584         ;
11585       else if (unformat (i, "is-input %d", &is_input))
11586         ;
11587       else
11588         {
11589           clib_warning ("parse error '%U'", format_unformat_error, i);
11590           return -99;
11591         }
11592     }
11593
11594   if (sw_if_index_set == 0)
11595     {
11596       errmsg ("missing interface name or sw_if_index");
11597       return -99;
11598     }
11599
11600
11601   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11602
11603   mp->sw_if_index = ntohl (sw_if_index);
11604   mp->ip4_table_index = ntohl (ip4_table_index);
11605   mp->ip6_table_index = ntohl (ip6_table_index);
11606   mp->other_table_index = ntohl (other_table_index);
11607   mp->is_input = (u8) is_input;
11608
11609   S (mp);
11610   W (ret);
11611   return ret;
11612 }
11613
11614 static int
11615 api_set_ipfix_exporter (vat_main_t * vam)
11616 {
11617   unformat_input_t *i = vam->input;
11618   vl_api_set_ipfix_exporter_t *mp;
11619   ip4_address_t collector_address;
11620   u8 collector_address_set = 0;
11621   u32 collector_port = ~0;
11622   ip4_address_t src_address;
11623   u8 src_address_set = 0;
11624   u32 vrf_id = ~0;
11625   u32 path_mtu = ~0;
11626   u32 template_interval = ~0;
11627   u8 udp_checksum = 0;
11628   int ret;
11629
11630   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11631     {
11632       if (unformat (i, "collector_address %U", unformat_ip4_address,
11633                     &collector_address))
11634         collector_address_set = 1;
11635       else if (unformat (i, "collector_port %d", &collector_port))
11636         ;
11637       else if (unformat (i, "src_address %U", unformat_ip4_address,
11638                          &src_address))
11639         src_address_set = 1;
11640       else if (unformat (i, "vrf_id %d", &vrf_id))
11641         ;
11642       else if (unformat (i, "path_mtu %d", &path_mtu))
11643         ;
11644       else if (unformat (i, "template_interval %d", &template_interval))
11645         ;
11646       else if (unformat (i, "udp_checksum"))
11647         udp_checksum = 1;
11648       else
11649         break;
11650     }
11651
11652   if (collector_address_set == 0)
11653     {
11654       errmsg ("collector_address required");
11655       return -99;
11656     }
11657
11658   if (src_address_set == 0)
11659     {
11660       errmsg ("src_address required");
11661       return -99;
11662     }
11663
11664   M (SET_IPFIX_EXPORTER, mp);
11665
11666   memcpy (mp->collector_address, collector_address.data,
11667           sizeof (collector_address.data));
11668   mp->collector_port = htons ((u16) collector_port);
11669   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11670   mp->vrf_id = htonl (vrf_id);
11671   mp->path_mtu = htonl (path_mtu);
11672   mp->template_interval = htonl (template_interval);
11673   mp->udp_checksum = udp_checksum;
11674
11675   S (mp);
11676   W (ret);
11677   return ret;
11678 }
11679
11680 static int
11681 api_set_ipfix_classify_stream (vat_main_t * vam)
11682 {
11683   unformat_input_t *i = vam->input;
11684   vl_api_set_ipfix_classify_stream_t *mp;
11685   u32 domain_id = 0;
11686   u32 src_port = UDP_DST_PORT_ipfix;
11687   int ret;
11688
11689   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11690     {
11691       if (unformat (i, "domain %d", &domain_id))
11692         ;
11693       else if (unformat (i, "src_port %d", &src_port))
11694         ;
11695       else
11696         {
11697           errmsg ("unknown input `%U'", format_unformat_error, i);
11698           return -99;
11699         }
11700     }
11701
11702   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11703
11704   mp->domain_id = htonl (domain_id);
11705   mp->src_port = htons ((u16) src_port);
11706
11707   S (mp);
11708   W (ret);
11709   return ret;
11710 }
11711
11712 static int
11713 api_ipfix_classify_table_add_del (vat_main_t * vam)
11714 {
11715   unformat_input_t *i = vam->input;
11716   vl_api_ipfix_classify_table_add_del_t *mp;
11717   int is_add = -1;
11718   u32 classify_table_index = ~0;
11719   u8 ip_version = 0;
11720   u8 transport_protocol = 255;
11721   int ret;
11722
11723   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11724     {
11725       if (unformat (i, "add"))
11726         is_add = 1;
11727       else if (unformat (i, "del"))
11728         is_add = 0;
11729       else if (unformat (i, "table %d", &classify_table_index))
11730         ;
11731       else if (unformat (i, "ip4"))
11732         ip_version = 4;
11733       else if (unformat (i, "ip6"))
11734         ip_version = 6;
11735       else if (unformat (i, "tcp"))
11736         transport_protocol = 6;
11737       else if (unformat (i, "udp"))
11738         transport_protocol = 17;
11739       else
11740         {
11741           errmsg ("unknown input `%U'", format_unformat_error, i);
11742           return -99;
11743         }
11744     }
11745
11746   if (is_add == -1)
11747     {
11748       errmsg ("expecting: add|del");
11749       return -99;
11750     }
11751   if (classify_table_index == ~0)
11752     {
11753       errmsg ("classifier table not specified");
11754       return -99;
11755     }
11756   if (ip_version == 0)
11757     {
11758       errmsg ("IP version not specified");
11759       return -99;
11760     }
11761
11762   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11763
11764   mp->is_add = is_add;
11765   mp->table_id = htonl (classify_table_index);
11766   mp->ip_version = ip_version;
11767   mp->transport_protocol = transport_protocol;
11768
11769   S (mp);
11770   W (ret);
11771   return ret;
11772 }
11773
11774 static int
11775 api_get_node_index (vat_main_t * vam)
11776 {
11777   unformat_input_t *i = vam->input;
11778   vl_api_get_node_index_t *mp;
11779   u8 *name = 0;
11780   int ret;
11781
11782   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11783     {
11784       if (unformat (i, "node %s", &name))
11785         ;
11786       else
11787         break;
11788     }
11789   if (name == 0)
11790     {
11791       errmsg ("node name required");
11792       return -99;
11793     }
11794   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11795     {
11796       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11797       return -99;
11798     }
11799
11800   M (GET_NODE_INDEX, mp);
11801   clib_memcpy (mp->node_name, name, vec_len (name));
11802   vec_free (name);
11803
11804   S (mp);
11805   W (ret);
11806   return ret;
11807 }
11808
11809 static int
11810 api_get_next_index (vat_main_t * vam)
11811 {
11812   unformat_input_t *i = vam->input;
11813   vl_api_get_next_index_t *mp;
11814   u8 *node_name = 0, *next_node_name = 0;
11815   int ret;
11816
11817   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11818     {
11819       if (unformat (i, "node-name %s", &node_name))
11820         ;
11821       else if (unformat (i, "next-node-name %s", &next_node_name))
11822         break;
11823     }
11824
11825   if (node_name == 0)
11826     {
11827       errmsg ("node name required");
11828       return -99;
11829     }
11830   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11831     {
11832       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11833       return -99;
11834     }
11835
11836   if (next_node_name == 0)
11837     {
11838       errmsg ("next node name required");
11839       return -99;
11840     }
11841   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11842     {
11843       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11844       return -99;
11845     }
11846
11847   M (GET_NEXT_INDEX, mp);
11848   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11849   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11850   vec_free (node_name);
11851   vec_free (next_node_name);
11852
11853   S (mp);
11854   W (ret);
11855   return ret;
11856 }
11857
11858 static int
11859 api_add_node_next (vat_main_t * vam)
11860 {
11861   unformat_input_t *i = vam->input;
11862   vl_api_add_node_next_t *mp;
11863   u8 *name = 0;
11864   u8 *next = 0;
11865   int ret;
11866
11867   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11868     {
11869       if (unformat (i, "node %s", &name))
11870         ;
11871       else if (unformat (i, "next %s", &next))
11872         ;
11873       else
11874         break;
11875     }
11876   if (name == 0)
11877     {
11878       errmsg ("node name required");
11879       return -99;
11880     }
11881   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11882     {
11883       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11884       return -99;
11885     }
11886   if (next == 0)
11887     {
11888       errmsg ("next node required");
11889       return -99;
11890     }
11891   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11892     {
11893       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11894       return -99;
11895     }
11896
11897   M (ADD_NODE_NEXT, mp);
11898   clib_memcpy (mp->node_name, name, vec_len (name));
11899   clib_memcpy (mp->next_name, next, vec_len (next));
11900   vec_free (name);
11901   vec_free (next);
11902
11903   S (mp);
11904   W (ret);
11905   return ret;
11906 }
11907
11908 static int
11909 api_l2tpv3_create_tunnel (vat_main_t * vam)
11910 {
11911   unformat_input_t *i = vam->input;
11912   ip6_address_t client_address, our_address;
11913   int client_address_set = 0;
11914   int our_address_set = 0;
11915   u32 local_session_id = 0;
11916   u32 remote_session_id = 0;
11917   u64 local_cookie = 0;
11918   u64 remote_cookie = 0;
11919   u8 l2_sublayer_present = 0;
11920   vl_api_l2tpv3_create_tunnel_t *mp;
11921   int ret;
11922
11923   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11924     {
11925       if (unformat (i, "client_address %U", unformat_ip6_address,
11926                     &client_address))
11927         client_address_set = 1;
11928       else if (unformat (i, "our_address %U", unformat_ip6_address,
11929                          &our_address))
11930         our_address_set = 1;
11931       else if (unformat (i, "local_session_id %d", &local_session_id))
11932         ;
11933       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11934         ;
11935       else if (unformat (i, "local_cookie %lld", &local_cookie))
11936         ;
11937       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11938         ;
11939       else if (unformat (i, "l2-sublayer-present"))
11940         l2_sublayer_present = 1;
11941       else
11942         break;
11943     }
11944
11945   if (client_address_set == 0)
11946     {
11947       errmsg ("client_address required");
11948       return -99;
11949     }
11950
11951   if (our_address_set == 0)
11952     {
11953       errmsg ("our_address required");
11954       return -99;
11955     }
11956
11957   M (L2TPV3_CREATE_TUNNEL, mp);
11958
11959   clib_memcpy (mp->client_address, client_address.as_u8,
11960                sizeof (mp->client_address));
11961
11962   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
11963
11964   mp->local_session_id = ntohl (local_session_id);
11965   mp->remote_session_id = ntohl (remote_session_id);
11966   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11967   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11968   mp->l2_sublayer_present = l2_sublayer_present;
11969   mp->is_ipv6 = 1;
11970
11971   S (mp);
11972   W (ret);
11973   return ret;
11974 }
11975
11976 static int
11977 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11978 {
11979   unformat_input_t *i = vam->input;
11980   u32 sw_if_index;
11981   u8 sw_if_index_set = 0;
11982   u64 new_local_cookie = 0;
11983   u64 new_remote_cookie = 0;
11984   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11985   int ret;
11986
11987   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11988     {
11989       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11990         sw_if_index_set = 1;
11991       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11992         sw_if_index_set = 1;
11993       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11994         ;
11995       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11996         ;
11997       else
11998         break;
11999     }
12000
12001   if (sw_if_index_set == 0)
12002     {
12003       errmsg ("missing interface name or sw_if_index");
12004       return -99;
12005     }
12006
12007   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12008
12009   mp->sw_if_index = ntohl (sw_if_index);
12010   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12011   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12012
12013   S (mp);
12014   W (ret);
12015   return ret;
12016 }
12017
12018 static int
12019 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12020 {
12021   unformat_input_t *i = vam->input;
12022   vl_api_l2tpv3_interface_enable_disable_t *mp;
12023   u32 sw_if_index;
12024   u8 sw_if_index_set = 0;
12025   u8 enable_disable = 1;
12026   int ret;
12027
12028   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12029     {
12030       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12031         sw_if_index_set = 1;
12032       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12033         sw_if_index_set = 1;
12034       else if (unformat (i, "enable"))
12035         enable_disable = 1;
12036       else if (unformat (i, "disable"))
12037         enable_disable = 0;
12038       else
12039         break;
12040     }
12041
12042   if (sw_if_index_set == 0)
12043     {
12044       errmsg ("missing interface name or sw_if_index");
12045       return -99;
12046     }
12047
12048   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12049
12050   mp->sw_if_index = ntohl (sw_if_index);
12051   mp->enable_disable = enable_disable;
12052
12053   S (mp);
12054   W (ret);
12055   return ret;
12056 }
12057
12058 static int
12059 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12060 {
12061   unformat_input_t *i = vam->input;
12062   vl_api_l2tpv3_set_lookup_key_t *mp;
12063   u8 key = ~0;
12064   int ret;
12065
12066   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12067     {
12068       if (unformat (i, "lookup_v6_src"))
12069         key = L2T_LOOKUP_SRC_ADDRESS;
12070       else if (unformat (i, "lookup_v6_dst"))
12071         key = L2T_LOOKUP_DST_ADDRESS;
12072       else if (unformat (i, "lookup_session_id"))
12073         key = L2T_LOOKUP_SESSION_ID;
12074       else
12075         break;
12076     }
12077
12078   if (key == (u8) ~ 0)
12079     {
12080       errmsg ("l2tp session lookup key unset");
12081       return -99;
12082     }
12083
12084   M (L2TPV3_SET_LOOKUP_KEY, mp);
12085
12086   mp->key = key;
12087
12088   S (mp);
12089   W (ret);
12090   return ret;
12091 }
12092
12093 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12094   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12095 {
12096   vat_main_t *vam = &vat_main;
12097
12098   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12099          format_ip6_address, mp->our_address,
12100          format_ip6_address, mp->client_address,
12101          clib_net_to_host_u32 (mp->sw_if_index));
12102
12103   print (vam->ofp,
12104          "   local cookies %016llx %016llx remote cookie %016llx",
12105          clib_net_to_host_u64 (mp->local_cookie[0]),
12106          clib_net_to_host_u64 (mp->local_cookie[1]),
12107          clib_net_to_host_u64 (mp->remote_cookie));
12108
12109   print (vam->ofp, "   local session-id %d remote session-id %d",
12110          clib_net_to_host_u32 (mp->local_session_id),
12111          clib_net_to_host_u32 (mp->remote_session_id));
12112
12113   print (vam->ofp, "   l2 specific sublayer %s\n",
12114          mp->l2_sublayer_present ? "preset" : "absent");
12115
12116 }
12117
12118 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12119   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12120 {
12121   vat_main_t *vam = &vat_main;
12122   vat_json_node_t *node = NULL;
12123   struct in6_addr addr;
12124
12125   if (VAT_JSON_ARRAY != vam->json_tree.type)
12126     {
12127       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12128       vat_json_init_array (&vam->json_tree);
12129     }
12130   node = vat_json_array_add (&vam->json_tree);
12131
12132   vat_json_init_object (node);
12133
12134   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12135   vat_json_object_add_ip6 (node, "our_address", addr);
12136   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12137   vat_json_object_add_ip6 (node, "client_address", addr);
12138
12139   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12140   vat_json_init_array (lc);
12141   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12142   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12143   vat_json_object_add_uint (node, "remote_cookie",
12144                             clib_net_to_host_u64 (mp->remote_cookie));
12145
12146   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12147   vat_json_object_add_uint (node, "local_session_id",
12148                             clib_net_to_host_u32 (mp->local_session_id));
12149   vat_json_object_add_uint (node, "remote_session_id",
12150                             clib_net_to_host_u32 (mp->remote_session_id));
12151   vat_json_object_add_string_copy (node, "l2_sublayer",
12152                                    mp->l2_sublayer_present ? (u8 *) "present"
12153                                    : (u8 *) "absent");
12154 }
12155
12156 static int
12157 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12158 {
12159   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12160   vl_api_control_ping_t *mp_ping;
12161   int ret;
12162
12163   /* Get list of l2tpv3-tunnel interfaces */
12164   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12165   S (mp);
12166
12167   /* Use a control ping for synchronization */
12168   MPING (CONTROL_PING, mp_ping);
12169   S (mp_ping);
12170
12171   W (ret);
12172   return ret;
12173 }
12174
12175
12176 static void vl_api_sw_interface_tap_v2_details_t_handler
12177   (vl_api_sw_interface_tap_v2_details_t * mp)
12178 {
12179   vat_main_t *vam = &vat_main;
12180
12181   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12182                     mp->host_ip4_prefix_len);
12183   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12184                     mp->host_ip6_prefix_len);
12185
12186   print (vam->ofp,
12187          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
12188          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12189          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12190          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12191          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
12192
12193   vec_free (ip4);
12194   vec_free (ip6);
12195 }
12196
12197 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12198   (vl_api_sw_interface_tap_v2_details_t * mp)
12199 {
12200   vat_main_t *vam = &vat_main;
12201   vat_json_node_t *node = NULL;
12202
12203   if (VAT_JSON_ARRAY != vam->json_tree.type)
12204     {
12205       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12206       vat_json_init_array (&vam->json_tree);
12207     }
12208   node = vat_json_array_add (&vam->json_tree);
12209
12210   vat_json_init_object (node);
12211   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12212   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12213   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
12214   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12215   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12216   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12217   vat_json_object_add_string_copy (node, "host_mac_addr",
12218                                    format (0, "%U", format_ethernet_address,
12219                                            &mp->host_mac_addr));
12220   vat_json_object_add_string_copy (node, "host_namespace",
12221                                    mp->host_namespace);
12222   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12223   vat_json_object_add_string_copy (node, "host_ip4_addr",
12224                                    format (0, "%U/%d", format_ip4_address,
12225                                            mp->host_ip4_addr,
12226                                            mp->host_ip4_prefix_len));
12227   vat_json_object_add_string_copy (node, "host_ip6_addr",
12228                                    format (0, "%U/%d", format_ip6_address,
12229                                            mp->host_ip6_addr,
12230                                            mp->host_ip6_prefix_len));
12231
12232 }
12233
12234 static int
12235 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12236 {
12237   vl_api_sw_interface_tap_v2_dump_t *mp;
12238   vl_api_control_ping_t *mp_ping;
12239   int ret;
12240
12241   print (vam->ofp,
12242          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12243          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12244          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12245          "host_ip6_addr");
12246
12247   /* Get list of tap interfaces */
12248   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12249   S (mp);
12250
12251   /* Use a control ping for synchronization */
12252   MPING (CONTROL_PING, mp_ping);
12253   S (mp_ping);
12254
12255   W (ret);
12256   return ret;
12257 }
12258
12259 static void vl_api_sw_interface_virtio_pci_details_t_handler
12260   (vl_api_sw_interface_virtio_pci_details_t * mp)
12261 {
12262   vat_main_t *vam = &vat_main;
12263
12264   typedef union
12265   {
12266     struct
12267     {
12268       u16 domain;
12269       u8 bus;
12270       u8 slot:5;
12271       u8 function:3;
12272     };
12273     u32 as_u32;
12274   } pci_addr_t;
12275   pci_addr_t addr;
12276   addr.as_u32 = ntohl (mp->pci_addr);
12277   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
12278                          addr.slot, addr.function);
12279
12280   print (vam->ofp,
12281          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
12282          pci_addr, ntohl (mp->sw_if_index),
12283          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12284          format_ethernet_address, mp->mac_addr,
12285          clib_net_to_host_u64 (mp->features));
12286   vec_free (pci_addr);
12287 }
12288
12289 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
12290   (vl_api_sw_interface_virtio_pci_details_t * mp)
12291 {
12292   vat_main_t *vam = &vat_main;
12293   vat_json_node_t *node = NULL;
12294
12295   if (VAT_JSON_ARRAY != vam->json_tree.type)
12296     {
12297       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12298       vat_json_init_array (&vam->json_tree);
12299     }
12300   node = vat_json_array_add (&vam->json_tree);
12301
12302   vat_json_init_object (node);
12303   vat_json_object_add_uint (node, "pci-addr", ntohl (mp->pci_addr));
12304   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12305   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12306   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12307   vat_json_object_add_uint (node, "features",
12308                             clib_net_to_host_u64 (mp->features));
12309   vat_json_object_add_string_copy (node, "mac_addr",
12310                                    format (0, "%U", format_ethernet_address,
12311                                            &mp->mac_addr));
12312 }
12313
12314 static int
12315 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
12316 {
12317   vl_api_sw_interface_virtio_pci_dump_t *mp;
12318   vl_api_control_ping_t *mp_ping;
12319   int ret;
12320
12321   print (vam->ofp,
12322          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
12323          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
12324          "mac_addr", "features");
12325
12326   /* Get list of tap interfaces */
12327   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
12328   S (mp);
12329
12330   /* Use a control ping for synchronization */
12331   MPING (CONTROL_PING, mp_ping);
12332   S (mp_ping);
12333
12334   W (ret);
12335   return ret;
12336 }
12337
12338 static int
12339 api_vxlan_offload_rx (vat_main_t * vam)
12340 {
12341   unformat_input_t *line_input = vam->input;
12342   vl_api_vxlan_offload_rx_t *mp;
12343   u32 hw_if_index = ~0, rx_if_index = ~0;
12344   u8 is_add = 1;
12345   int ret;
12346
12347   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12348     {
12349       if (unformat (line_input, "del"))
12350         is_add = 0;
12351       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
12352                          &hw_if_index))
12353         ;
12354       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
12355         ;
12356       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
12357                          &rx_if_index))
12358         ;
12359       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
12360         ;
12361       else
12362         {
12363           errmsg ("parse error '%U'", format_unformat_error, line_input);
12364           return -99;
12365         }
12366     }
12367
12368   if (hw_if_index == ~0)
12369     {
12370       errmsg ("no hw interface");
12371       return -99;
12372     }
12373
12374   if (rx_if_index == ~0)
12375     {
12376       errmsg ("no rx tunnel");
12377       return -99;
12378     }
12379
12380   M (VXLAN_OFFLOAD_RX, mp);
12381
12382   mp->hw_if_index = ntohl (hw_if_index);
12383   mp->sw_if_index = ntohl (rx_if_index);
12384   mp->enable = is_add;
12385
12386   S (mp);
12387   W (ret);
12388   return ret;
12389 }
12390
12391 static uword unformat_vxlan_decap_next
12392   (unformat_input_t * input, va_list * args)
12393 {
12394   u32 *result = va_arg (*args, u32 *);
12395   u32 tmp;
12396
12397   if (unformat (input, "l2"))
12398     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12399   else if (unformat (input, "%d", &tmp))
12400     *result = tmp;
12401   else
12402     return 0;
12403   return 1;
12404 }
12405
12406 static int
12407 api_vxlan_add_del_tunnel (vat_main_t * vam)
12408 {
12409   unformat_input_t *line_input = vam->input;
12410   vl_api_vxlan_add_del_tunnel_t *mp;
12411   ip46_address_t src, dst;
12412   u8 is_add = 1;
12413   u8 ipv4_set = 0, ipv6_set = 0;
12414   u8 src_set = 0;
12415   u8 dst_set = 0;
12416   u8 grp_set = 0;
12417   u32 instance = ~0;
12418   u32 mcast_sw_if_index = ~0;
12419   u32 encap_vrf_id = 0;
12420   u32 decap_next_index = ~0;
12421   u32 vni = 0;
12422   int ret;
12423
12424   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12425   clib_memset (&src, 0, sizeof src);
12426   clib_memset (&dst, 0, sizeof dst);
12427
12428   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12429     {
12430       if (unformat (line_input, "del"))
12431         is_add = 0;
12432       else if (unformat (line_input, "instance %d", &instance))
12433         ;
12434       else
12435         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12436         {
12437           ipv4_set = 1;
12438           src_set = 1;
12439         }
12440       else
12441         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12442         {
12443           ipv4_set = 1;
12444           dst_set = 1;
12445         }
12446       else
12447         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12448         {
12449           ipv6_set = 1;
12450           src_set = 1;
12451         }
12452       else
12453         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12454         {
12455           ipv6_set = 1;
12456           dst_set = 1;
12457         }
12458       else if (unformat (line_input, "group %U %U",
12459                          unformat_ip4_address, &dst.ip4,
12460                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12461         {
12462           grp_set = dst_set = 1;
12463           ipv4_set = 1;
12464         }
12465       else if (unformat (line_input, "group %U",
12466                          unformat_ip4_address, &dst.ip4))
12467         {
12468           grp_set = dst_set = 1;
12469           ipv4_set = 1;
12470         }
12471       else if (unformat (line_input, "group %U %U",
12472                          unformat_ip6_address, &dst.ip6,
12473                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12474         {
12475           grp_set = dst_set = 1;
12476           ipv6_set = 1;
12477         }
12478       else if (unformat (line_input, "group %U",
12479                          unformat_ip6_address, &dst.ip6))
12480         {
12481           grp_set = dst_set = 1;
12482           ipv6_set = 1;
12483         }
12484       else
12485         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12486         ;
12487       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12488         ;
12489       else if (unformat (line_input, "decap-next %U",
12490                          unformat_vxlan_decap_next, &decap_next_index))
12491         ;
12492       else if (unformat (line_input, "vni %d", &vni))
12493         ;
12494       else
12495         {
12496           errmsg ("parse error '%U'", format_unformat_error, line_input);
12497           return -99;
12498         }
12499     }
12500
12501   if (src_set == 0)
12502     {
12503       errmsg ("tunnel src address not specified");
12504       return -99;
12505     }
12506   if (dst_set == 0)
12507     {
12508       errmsg ("tunnel dst address not specified");
12509       return -99;
12510     }
12511
12512   if (grp_set && !ip46_address_is_multicast (&dst))
12513     {
12514       errmsg ("tunnel group address not multicast");
12515       return -99;
12516     }
12517   if (grp_set && mcast_sw_if_index == ~0)
12518     {
12519       errmsg ("tunnel nonexistent multicast device");
12520       return -99;
12521     }
12522   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12523     {
12524       errmsg ("tunnel dst address must be unicast");
12525       return -99;
12526     }
12527
12528
12529   if (ipv4_set && ipv6_set)
12530     {
12531       errmsg ("both IPv4 and IPv6 addresses specified");
12532       return -99;
12533     }
12534
12535   if ((vni == 0) || (vni >> 24))
12536     {
12537       errmsg ("vni not specified or out of range");
12538       return -99;
12539     }
12540
12541   M (VXLAN_ADD_DEL_TUNNEL, mp);
12542
12543   if (ipv6_set)
12544     {
12545       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12546       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12547     }
12548   else
12549     {
12550       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12551       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12552     }
12553
12554   mp->instance = htonl (instance);
12555   mp->encap_vrf_id = ntohl (encap_vrf_id);
12556   mp->decap_next_index = ntohl (decap_next_index);
12557   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12558   mp->vni = ntohl (vni);
12559   mp->is_add = is_add;
12560   mp->is_ipv6 = ipv6_set;
12561
12562   S (mp);
12563   W (ret);
12564   return ret;
12565 }
12566
12567 static void vl_api_vxlan_tunnel_details_t_handler
12568   (vl_api_vxlan_tunnel_details_t * mp)
12569 {
12570   vat_main_t *vam = &vat_main;
12571   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12572   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12573
12574   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
12575          ntohl (mp->sw_if_index),
12576          ntohl (mp->instance),
12577          format_ip46_address, &src, IP46_TYPE_ANY,
12578          format_ip46_address, &dst, IP46_TYPE_ANY,
12579          ntohl (mp->encap_vrf_id),
12580          ntohl (mp->decap_next_index), ntohl (mp->vni),
12581          ntohl (mp->mcast_sw_if_index));
12582 }
12583
12584 static void vl_api_vxlan_tunnel_details_t_handler_json
12585   (vl_api_vxlan_tunnel_details_t * mp)
12586 {
12587   vat_main_t *vam = &vat_main;
12588   vat_json_node_t *node = NULL;
12589
12590   if (VAT_JSON_ARRAY != vam->json_tree.type)
12591     {
12592       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12593       vat_json_init_array (&vam->json_tree);
12594     }
12595   node = vat_json_array_add (&vam->json_tree);
12596
12597   vat_json_init_object (node);
12598   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12599
12600   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
12601
12602   if (mp->is_ipv6)
12603     {
12604       struct in6_addr ip6;
12605
12606       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12607       vat_json_object_add_ip6 (node, "src_address", ip6);
12608       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12609       vat_json_object_add_ip6 (node, "dst_address", ip6);
12610     }
12611   else
12612     {
12613       struct in_addr ip4;
12614
12615       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12616       vat_json_object_add_ip4 (node, "src_address", ip4);
12617       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12618       vat_json_object_add_ip4 (node, "dst_address", ip4);
12619     }
12620   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12621   vat_json_object_add_uint (node, "decap_next_index",
12622                             ntohl (mp->decap_next_index));
12623   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12624   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12625   vat_json_object_add_uint (node, "mcast_sw_if_index",
12626                             ntohl (mp->mcast_sw_if_index));
12627 }
12628
12629 static int
12630 api_vxlan_tunnel_dump (vat_main_t * vam)
12631 {
12632   unformat_input_t *i = vam->input;
12633   vl_api_vxlan_tunnel_dump_t *mp;
12634   vl_api_control_ping_t *mp_ping;
12635   u32 sw_if_index;
12636   u8 sw_if_index_set = 0;
12637   int ret;
12638
12639   /* Parse args required to build the message */
12640   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12641     {
12642       if (unformat (i, "sw_if_index %d", &sw_if_index))
12643         sw_if_index_set = 1;
12644       else
12645         break;
12646     }
12647
12648   if (sw_if_index_set == 0)
12649     {
12650       sw_if_index = ~0;
12651     }
12652
12653   if (!vam->json_output)
12654     {
12655       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
12656              "sw_if_index", "instance", "src_address", "dst_address",
12657              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12658     }
12659
12660   /* Get list of vxlan-tunnel interfaces */
12661   M (VXLAN_TUNNEL_DUMP, mp);
12662
12663   mp->sw_if_index = htonl (sw_if_index);
12664
12665   S (mp);
12666
12667   /* Use a control ping for synchronization */
12668   MPING (CONTROL_PING, mp_ping);
12669   S (mp_ping);
12670
12671   W (ret);
12672   return ret;
12673 }
12674
12675 static uword unformat_geneve_decap_next
12676   (unformat_input_t * input, va_list * args)
12677 {
12678   u32 *result = va_arg (*args, u32 *);
12679   u32 tmp;
12680
12681   if (unformat (input, "l2"))
12682     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12683   else if (unformat (input, "%d", &tmp))
12684     *result = tmp;
12685   else
12686     return 0;
12687   return 1;
12688 }
12689
12690 static int
12691 api_geneve_add_del_tunnel (vat_main_t * vam)
12692 {
12693   unformat_input_t *line_input = vam->input;
12694   vl_api_geneve_add_del_tunnel_t *mp;
12695   ip46_address_t src, dst;
12696   u8 is_add = 1;
12697   u8 ipv4_set = 0, ipv6_set = 0;
12698   u8 src_set = 0;
12699   u8 dst_set = 0;
12700   u8 grp_set = 0;
12701   u32 mcast_sw_if_index = ~0;
12702   u32 encap_vrf_id = 0;
12703   u32 decap_next_index = ~0;
12704   u32 vni = 0;
12705   int ret;
12706
12707   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12708   clib_memset (&src, 0, sizeof src);
12709   clib_memset (&dst, 0, sizeof dst);
12710
12711   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12712     {
12713       if (unformat (line_input, "del"))
12714         is_add = 0;
12715       else
12716         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12717         {
12718           ipv4_set = 1;
12719           src_set = 1;
12720         }
12721       else
12722         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12723         {
12724           ipv4_set = 1;
12725           dst_set = 1;
12726         }
12727       else
12728         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12729         {
12730           ipv6_set = 1;
12731           src_set = 1;
12732         }
12733       else
12734         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12735         {
12736           ipv6_set = 1;
12737           dst_set = 1;
12738         }
12739       else if (unformat (line_input, "group %U %U",
12740                          unformat_ip4_address, &dst.ip4,
12741                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12742         {
12743           grp_set = dst_set = 1;
12744           ipv4_set = 1;
12745         }
12746       else if (unformat (line_input, "group %U",
12747                          unformat_ip4_address, &dst.ip4))
12748         {
12749           grp_set = dst_set = 1;
12750           ipv4_set = 1;
12751         }
12752       else if (unformat (line_input, "group %U %U",
12753                          unformat_ip6_address, &dst.ip6,
12754                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12755         {
12756           grp_set = dst_set = 1;
12757           ipv6_set = 1;
12758         }
12759       else if (unformat (line_input, "group %U",
12760                          unformat_ip6_address, &dst.ip6))
12761         {
12762           grp_set = dst_set = 1;
12763           ipv6_set = 1;
12764         }
12765       else
12766         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12767         ;
12768       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12769         ;
12770       else if (unformat (line_input, "decap-next %U",
12771                          unformat_geneve_decap_next, &decap_next_index))
12772         ;
12773       else if (unformat (line_input, "vni %d", &vni))
12774         ;
12775       else
12776         {
12777           errmsg ("parse error '%U'", format_unformat_error, line_input);
12778           return -99;
12779         }
12780     }
12781
12782   if (src_set == 0)
12783     {
12784       errmsg ("tunnel src address not specified");
12785       return -99;
12786     }
12787   if (dst_set == 0)
12788     {
12789       errmsg ("tunnel dst address not specified");
12790       return -99;
12791     }
12792
12793   if (grp_set && !ip46_address_is_multicast (&dst))
12794     {
12795       errmsg ("tunnel group address not multicast");
12796       return -99;
12797     }
12798   if (grp_set && mcast_sw_if_index == ~0)
12799     {
12800       errmsg ("tunnel nonexistent multicast device");
12801       return -99;
12802     }
12803   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12804     {
12805       errmsg ("tunnel dst address must be unicast");
12806       return -99;
12807     }
12808
12809
12810   if (ipv4_set && ipv6_set)
12811     {
12812       errmsg ("both IPv4 and IPv6 addresses specified");
12813       return -99;
12814     }
12815
12816   if ((vni == 0) || (vni >> 24))
12817     {
12818       errmsg ("vni not specified or out of range");
12819       return -99;
12820     }
12821
12822   M (GENEVE_ADD_DEL_TUNNEL, mp);
12823
12824   if (ipv6_set)
12825     {
12826       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12827       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12828     }
12829   else
12830     {
12831       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12832       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12833     }
12834   mp->encap_vrf_id = ntohl (encap_vrf_id);
12835   mp->decap_next_index = ntohl (decap_next_index);
12836   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12837   mp->vni = ntohl (vni);
12838   mp->is_add = is_add;
12839   mp->is_ipv6 = ipv6_set;
12840
12841   S (mp);
12842   W (ret);
12843   return ret;
12844 }
12845
12846 static void vl_api_geneve_tunnel_details_t_handler
12847   (vl_api_geneve_tunnel_details_t * mp)
12848 {
12849   vat_main_t *vam = &vat_main;
12850   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12851   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12852
12853   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12854          ntohl (mp->sw_if_index),
12855          format_ip46_address, &src, IP46_TYPE_ANY,
12856          format_ip46_address, &dst, IP46_TYPE_ANY,
12857          ntohl (mp->encap_vrf_id),
12858          ntohl (mp->decap_next_index), ntohl (mp->vni),
12859          ntohl (mp->mcast_sw_if_index));
12860 }
12861
12862 static void vl_api_geneve_tunnel_details_t_handler_json
12863   (vl_api_geneve_tunnel_details_t * mp)
12864 {
12865   vat_main_t *vam = &vat_main;
12866   vat_json_node_t *node = NULL;
12867
12868   if (VAT_JSON_ARRAY != vam->json_tree.type)
12869     {
12870       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12871       vat_json_init_array (&vam->json_tree);
12872     }
12873   node = vat_json_array_add (&vam->json_tree);
12874
12875   vat_json_init_object (node);
12876   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12877   if (mp->is_ipv6)
12878     {
12879       struct in6_addr ip6;
12880
12881       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12882       vat_json_object_add_ip6 (node, "src_address", ip6);
12883       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12884       vat_json_object_add_ip6 (node, "dst_address", ip6);
12885     }
12886   else
12887     {
12888       struct in_addr ip4;
12889
12890       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12891       vat_json_object_add_ip4 (node, "src_address", ip4);
12892       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12893       vat_json_object_add_ip4 (node, "dst_address", ip4);
12894     }
12895   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12896   vat_json_object_add_uint (node, "decap_next_index",
12897                             ntohl (mp->decap_next_index));
12898   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12899   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12900   vat_json_object_add_uint (node, "mcast_sw_if_index",
12901                             ntohl (mp->mcast_sw_if_index));
12902 }
12903
12904 static int
12905 api_geneve_tunnel_dump (vat_main_t * vam)
12906 {
12907   unformat_input_t *i = vam->input;
12908   vl_api_geneve_tunnel_dump_t *mp;
12909   vl_api_control_ping_t *mp_ping;
12910   u32 sw_if_index;
12911   u8 sw_if_index_set = 0;
12912   int ret;
12913
12914   /* Parse args required to build the message */
12915   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12916     {
12917       if (unformat (i, "sw_if_index %d", &sw_if_index))
12918         sw_if_index_set = 1;
12919       else
12920         break;
12921     }
12922
12923   if (sw_if_index_set == 0)
12924     {
12925       sw_if_index = ~0;
12926     }
12927
12928   if (!vam->json_output)
12929     {
12930       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12931              "sw_if_index", "local_address", "remote_address",
12932              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12933     }
12934
12935   /* Get list of geneve-tunnel interfaces */
12936   M (GENEVE_TUNNEL_DUMP, mp);
12937
12938   mp->sw_if_index = htonl (sw_if_index);
12939
12940   S (mp);
12941
12942   /* Use a control ping for synchronization */
12943   M (CONTROL_PING, mp_ping);
12944   S (mp_ping);
12945
12946   W (ret);
12947   return ret;
12948 }
12949
12950 static int
12951 api_gre_tunnel_add_del (vat_main_t * vam)
12952 {
12953   unformat_input_t *line_input = vam->input;
12954   vl_api_address_t src = { }, dst =
12955   {
12956   };
12957   vl_api_gre_tunnel_add_del_t *mp;
12958   vl_api_gre_tunnel_type_t t_type;
12959   u8 is_add = 1;
12960   u8 src_set = 0;
12961   u8 dst_set = 0;
12962   u32 outer_fib_id = 0;
12963   u32 session_id = 0;
12964   u32 instance = ~0;
12965   int ret;
12966
12967   t_type = GRE_API_TUNNEL_TYPE_L3;
12968
12969   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12970     {
12971       if (unformat (line_input, "del"))
12972         is_add = 0;
12973       else if (unformat (line_input, "instance %d", &instance))
12974         ;
12975       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
12976         {
12977           src_set = 1;
12978         }
12979       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
12980         {
12981           dst_set = 1;
12982         }
12983       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
12984         ;
12985       else if (unformat (line_input, "teb"))
12986         t_type = GRE_API_TUNNEL_TYPE_TEB;
12987       else if (unformat (line_input, "erspan %d", &session_id))
12988         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
12989       else
12990         {
12991           errmsg ("parse error '%U'", format_unformat_error, line_input);
12992           return -99;
12993         }
12994     }
12995
12996   if (src_set == 0)
12997     {
12998       errmsg ("tunnel src address not specified");
12999       return -99;
13000     }
13001   if (dst_set == 0)
13002     {
13003       errmsg ("tunnel dst address not specified");
13004       return -99;
13005     }
13006
13007   M (GRE_TUNNEL_ADD_DEL, mp);
13008
13009   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
13010   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
13011
13012   mp->tunnel.instance = htonl (instance);
13013   mp->tunnel.outer_fib_id = htonl (outer_fib_id);
13014   mp->is_add = is_add;
13015   mp->tunnel.session_id = htons ((u16) session_id);
13016   mp->tunnel.type = htonl (t_type);
13017
13018   S (mp);
13019   W (ret);
13020   return ret;
13021 }
13022
13023 static void vl_api_gre_tunnel_details_t_handler
13024   (vl_api_gre_tunnel_details_t * mp)
13025 {
13026   vat_main_t *vam = &vat_main;
13027
13028   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13029          ntohl (mp->tunnel.sw_if_index),
13030          ntohl (mp->tunnel.instance),
13031          format_vl_api_address, &mp->tunnel.src,
13032          format_vl_api_address, &mp->tunnel.dst,
13033          mp->tunnel.type, ntohl (mp->tunnel.outer_fib_id),
13034          ntohl (mp->tunnel.session_id));
13035 }
13036
13037 static void vl_api_gre_tunnel_details_t_handler_json
13038   (vl_api_gre_tunnel_details_t * mp)
13039 {
13040   vat_main_t *vam = &vat_main;
13041   vat_json_node_t *node = NULL;
13042
13043   if (VAT_JSON_ARRAY != vam->json_tree.type)
13044     {
13045       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13046       vat_json_init_array (&vam->json_tree);
13047     }
13048   node = vat_json_array_add (&vam->json_tree);
13049
13050   vat_json_init_object (node);
13051   vat_json_object_add_uint (node, "sw_if_index",
13052                             ntohl (mp->tunnel.sw_if_index));
13053   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
13054
13055   vat_json_object_add_address (node, "src", &mp->tunnel.src);
13056   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
13057   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
13058   vat_json_object_add_uint (node, "outer_fib_id",
13059                             ntohl (mp->tunnel.outer_fib_id));
13060   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
13061 }
13062
13063 static int
13064 api_gre_tunnel_dump (vat_main_t * vam)
13065 {
13066   unformat_input_t *i = vam->input;
13067   vl_api_gre_tunnel_dump_t *mp;
13068   vl_api_control_ping_t *mp_ping;
13069   u32 sw_if_index;
13070   u8 sw_if_index_set = 0;
13071   int ret;
13072
13073   /* Parse args required to build the message */
13074   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13075     {
13076       if (unformat (i, "sw_if_index %d", &sw_if_index))
13077         sw_if_index_set = 1;
13078       else
13079         break;
13080     }
13081
13082   if (sw_if_index_set == 0)
13083     {
13084       sw_if_index = ~0;
13085     }
13086
13087   if (!vam->json_output)
13088     {
13089       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13090              "sw_if_index", "instance", "src_address", "dst_address",
13091              "tunnel_type", "outer_fib_id", "session_id");
13092     }
13093
13094   /* Get list of gre-tunnel interfaces */
13095   M (GRE_TUNNEL_DUMP, mp);
13096
13097   mp->sw_if_index = htonl (sw_if_index);
13098
13099   S (mp);
13100
13101   /* Use a control ping for synchronization */
13102   MPING (CONTROL_PING, mp_ping);
13103   S (mp_ping);
13104
13105   W (ret);
13106   return ret;
13107 }
13108
13109 static int
13110 api_l2_fib_clear_table (vat_main_t * vam)
13111 {
13112 //  unformat_input_t * i = vam->input;
13113   vl_api_l2_fib_clear_table_t *mp;
13114   int ret;
13115
13116   M (L2_FIB_CLEAR_TABLE, mp);
13117
13118   S (mp);
13119   W (ret);
13120   return ret;
13121 }
13122
13123 static int
13124 api_l2_interface_efp_filter (vat_main_t * vam)
13125 {
13126   unformat_input_t *i = vam->input;
13127   vl_api_l2_interface_efp_filter_t *mp;
13128   u32 sw_if_index;
13129   u8 enable = 1;
13130   u8 sw_if_index_set = 0;
13131   int ret;
13132
13133   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13134     {
13135       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13136         sw_if_index_set = 1;
13137       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13138         sw_if_index_set = 1;
13139       else if (unformat (i, "enable"))
13140         enable = 1;
13141       else if (unformat (i, "disable"))
13142         enable = 0;
13143       else
13144         {
13145           clib_warning ("parse error '%U'", format_unformat_error, i);
13146           return -99;
13147         }
13148     }
13149
13150   if (sw_if_index_set == 0)
13151     {
13152       errmsg ("missing sw_if_index");
13153       return -99;
13154     }
13155
13156   M (L2_INTERFACE_EFP_FILTER, mp);
13157
13158   mp->sw_if_index = ntohl (sw_if_index);
13159   mp->enable_disable = enable;
13160
13161   S (mp);
13162   W (ret);
13163   return ret;
13164 }
13165
13166 #define foreach_vtr_op                          \
13167 _("disable",  L2_VTR_DISABLED)                  \
13168 _("push-1",  L2_VTR_PUSH_1)                     \
13169 _("push-2",  L2_VTR_PUSH_2)                     \
13170 _("pop-1",  L2_VTR_POP_1)                       \
13171 _("pop-2",  L2_VTR_POP_2)                       \
13172 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13173 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13174 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13175 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13176
13177 static int
13178 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13179 {
13180   unformat_input_t *i = vam->input;
13181   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13182   u32 sw_if_index;
13183   u8 sw_if_index_set = 0;
13184   u8 vtr_op_set = 0;
13185   u32 vtr_op = 0;
13186   u32 push_dot1q = 1;
13187   u32 tag1 = ~0;
13188   u32 tag2 = ~0;
13189   int ret;
13190
13191   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13192     {
13193       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13194         sw_if_index_set = 1;
13195       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13196         sw_if_index_set = 1;
13197       else if (unformat (i, "vtr_op %d", &vtr_op))
13198         vtr_op_set = 1;
13199 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13200       foreach_vtr_op
13201 #undef _
13202         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13203         ;
13204       else if (unformat (i, "tag1 %d", &tag1))
13205         ;
13206       else if (unformat (i, "tag2 %d", &tag2))
13207         ;
13208       else
13209         {
13210           clib_warning ("parse error '%U'", format_unformat_error, i);
13211           return -99;
13212         }
13213     }
13214
13215   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13216     {
13217       errmsg ("missing vtr operation or sw_if_index");
13218       return -99;
13219     }
13220
13221   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13222   mp->sw_if_index = ntohl (sw_if_index);
13223   mp->vtr_op = ntohl (vtr_op);
13224   mp->push_dot1q = ntohl (push_dot1q);
13225   mp->tag1 = ntohl (tag1);
13226   mp->tag2 = ntohl (tag2);
13227
13228   S (mp);
13229   W (ret);
13230   return ret;
13231 }
13232
13233 static int
13234 api_create_vhost_user_if (vat_main_t * vam)
13235 {
13236   unformat_input_t *i = vam->input;
13237   vl_api_create_vhost_user_if_t *mp;
13238   u8 *file_name;
13239   u8 is_server = 0;
13240   u8 file_name_set = 0;
13241   u32 custom_dev_instance = ~0;
13242   u8 hwaddr[6];
13243   u8 use_custom_mac = 0;
13244   u8 disable_mrg_rxbuf = 0;
13245   u8 disable_indirect_desc = 0;
13246   u8 *tag = 0;
13247   u8 enable_gso = 0;
13248   int ret;
13249
13250   /* Shut up coverity */
13251   clib_memset (hwaddr, 0, sizeof (hwaddr));
13252
13253   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13254     {
13255       if (unformat (i, "socket %s", &file_name))
13256         {
13257           file_name_set = 1;
13258         }
13259       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13260         ;
13261       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13262         use_custom_mac = 1;
13263       else if (unformat (i, "server"))
13264         is_server = 1;
13265       else if (unformat (i, "disable_mrg_rxbuf"))
13266         disable_mrg_rxbuf = 1;
13267       else if (unformat (i, "disable_indirect_desc"))
13268         disable_indirect_desc = 1;
13269       else if (unformat (i, "gso"))
13270         enable_gso = 1;
13271       else if (unformat (i, "tag %s", &tag))
13272         ;
13273       else
13274         break;
13275     }
13276
13277   if (file_name_set == 0)
13278     {
13279       errmsg ("missing socket file name");
13280       return -99;
13281     }
13282
13283   if (vec_len (file_name) > 255)
13284     {
13285       errmsg ("socket file name too long");
13286       return -99;
13287     }
13288   vec_add1 (file_name, 0);
13289
13290   M (CREATE_VHOST_USER_IF, mp);
13291
13292   mp->is_server = is_server;
13293   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
13294   mp->disable_indirect_desc = disable_indirect_desc;
13295   mp->enable_gso = enable_gso;
13296   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13297   vec_free (file_name);
13298   if (custom_dev_instance != ~0)
13299     {
13300       mp->renumber = 1;
13301       mp->custom_dev_instance = ntohl (custom_dev_instance);
13302     }
13303
13304   mp->use_custom_mac = use_custom_mac;
13305   clib_memcpy (mp->mac_address, hwaddr, 6);
13306   if (tag)
13307     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13308   vec_free (tag);
13309
13310   S (mp);
13311   W (ret);
13312   return ret;
13313 }
13314
13315 static int
13316 api_modify_vhost_user_if (vat_main_t * vam)
13317 {
13318   unformat_input_t *i = vam->input;
13319   vl_api_modify_vhost_user_if_t *mp;
13320   u8 *file_name;
13321   u8 is_server = 0;
13322   u8 file_name_set = 0;
13323   u32 custom_dev_instance = ~0;
13324   u8 sw_if_index_set = 0;
13325   u32 sw_if_index = (u32) ~ 0;
13326   u8 enable_gso = 0;
13327   int ret;
13328
13329   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13330     {
13331       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13332         sw_if_index_set = 1;
13333       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13334         sw_if_index_set = 1;
13335       else if (unformat (i, "socket %s", &file_name))
13336         {
13337           file_name_set = 1;
13338         }
13339       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13340         ;
13341       else if (unformat (i, "server"))
13342         is_server = 1;
13343       else if (unformat (i, "gso"))
13344         enable_gso = 1;
13345       else
13346         break;
13347     }
13348
13349   if (sw_if_index_set == 0)
13350     {
13351       errmsg ("missing sw_if_index or interface name");
13352       return -99;
13353     }
13354
13355   if (file_name_set == 0)
13356     {
13357       errmsg ("missing socket file name");
13358       return -99;
13359     }
13360
13361   if (vec_len (file_name) > 255)
13362     {
13363       errmsg ("socket file name too long");
13364       return -99;
13365     }
13366   vec_add1 (file_name, 0);
13367
13368   M (MODIFY_VHOST_USER_IF, mp);
13369
13370   mp->sw_if_index = ntohl (sw_if_index);
13371   mp->is_server = is_server;
13372   mp->enable_gso = enable_gso;
13373   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13374   vec_free (file_name);
13375   if (custom_dev_instance != ~0)
13376     {
13377       mp->renumber = 1;
13378       mp->custom_dev_instance = ntohl (custom_dev_instance);
13379     }
13380
13381   S (mp);
13382   W (ret);
13383   return ret;
13384 }
13385
13386 static int
13387 api_delete_vhost_user_if (vat_main_t * vam)
13388 {
13389   unformat_input_t *i = vam->input;
13390   vl_api_delete_vhost_user_if_t *mp;
13391   u32 sw_if_index = ~0;
13392   u8 sw_if_index_set = 0;
13393   int ret;
13394
13395   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13396     {
13397       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13398         sw_if_index_set = 1;
13399       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13400         sw_if_index_set = 1;
13401       else
13402         break;
13403     }
13404
13405   if (sw_if_index_set == 0)
13406     {
13407       errmsg ("missing sw_if_index or interface name");
13408       return -99;
13409     }
13410
13411
13412   M (DELETE_VHOST_USER_IF, mp);
13413
13414   mp->sw_if_index = ntohl (sw_if_index);
13415
13416   S (mp);
13417   W (ret);
13418   return ret;
13419 }
13420
13421 static void vl_api_sw_interface_vhost_user_details_t_handler
13422   (vl_api_sw_interface_vhost_user_details_t * mp)
13423 {
13424   vat_main_t *vam = &vat_main;
13425
13426   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13427          (char *) mp->interface_name,
13428          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13429          clib_net_to_host_u64 (mp->features), mp->is_server,
13430          ntohl (mp->num_regions), (char *) mp->sock_filename);
13431   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13432 }
13433
13434 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13435   (vl_api_sw_interface_vhost_user_details_t * mp)
13436 {
13437   vat_main_t *vam = &vat_main;
13438   vat_json_node_t *node = NULL;
13439
13440   if (VAT_JSON_ARRAY != vam->json_tree.type)
13441     {
13442       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13443       vat_json_init_array (&vam->json_tree);
13444     }
13445   node = vat_json_array_add (&vam->json_tree);
13446
13447   vat_json_init_object (node);
13448   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13449   vat_json_object_add_string_copy (node, "interface_name",
13450                                    mp->interface_name);
13451   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13452                             ntohl (mp->virtio_net_hdr_sz));
13453   vat_json_object_add_uint (node, "features",
13454                             clib_net_to_host_u64 (mp->features));
13455   vat_json_object_add_uint (node, "is_server", mp->is_server);
13456   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13457   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13458   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13459 }
13460
13461 static int
13462 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13463 {
13464   vl_api_sw_interface_vhost_user_dump_t *mp;
13465   vl_api_control_ping_t *mp_ping;
13466   int ret;
13467   print (vam->ofp,
13468          "Interface name            idx hdr_sz features server regions filename");
13469
13470   /* Get list of vhost-user interfaces */
13471   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13472   S (mp);
13473
13474   /* Use a control ping for synchronization */
13475   MPING (CONTROL_PING, mp_ping);
13476   S (mp_ping);
13477
13478   W (ret);
13479   return ret;
13480 }
13481
13482 static int
13483 api_show_version (vat_main_t * vam)
13484 {
13485   vl_api_show_version_t *mp;
13486   int ret;
13487
13488   M (SHOW_VERSION, mp);
13489
13490   S (mp);
13491   W (ret);
13492   return ret;
13493 }
13494
13495
13496 static int
13497 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13498 {
13499   unformat_input_t *line_input = vam->input;
13500   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13501   ip4_address_t local4, remote4;
13502   ip6_address_t local6, remote6;
13503   u8 is_add = 1;
13504   u8 ipv4_set = 0, ipv6_set = 0;
13505   u8 local_set = 0;
13506   u8 remote_set = 0;
13507   u8 grp_set = 0;
13508   u32 mcast_sw_if_index = ~0;
13509   u32 encap_vrf_id = 0;
13510   u32 decap_vrf_id = 0;
13511   u8 protocol = ~0;
13512   u32 vni;
13513   u8 vni_set = 0;
13514   int ret;
13515
13516   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13517   clib_memset (&local4, 0, sizeof local4);
13518   clib_memset (&remote4, 0, sizeof remote4);
13519   clib_memset (&local6, 0, sizeof local6);
13520   clib_memset (&remote6, 0, sizeof remote6);
13521
13522   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13523     {
13524       if (unformat (line_input, "del"))
13525         is_add = 0;
13526       else if (unformat (line_input, "local %U",
13527                          unformat_ip4_address, &local4))
13528         {
13529           local_set = 1;
13530           ipv4_set = 1;
13531         }
13532       else if (unformat (line_input, "remote %U",
13533                          unformat_ip4_address, &remote4))
13534         {
13535           remote_set = 1;
13536           ipv4_set = 1;
13537         }
13538       else if (unformat (line_input, "local %U",
13539                          unformat_ip6_address, &local6))
13540         {
13541           local_set = 1;
13542           ipv6_set = 1;
13543         }
13544       else if (unformat (line_input, "remote %U",
13545                          unformat_ip6_address, &remote6))
13546         {
13547           remote_set = 1;
13548           ipv6_set = 1;
13549         }
13550       else if (unformat (line_input, "group %U %U",
13551                          unformat_ip4_address, &remote4,
13552                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13553         {
13554           grp_set = remote_set = 1;
13555           ipv4_set = 1;
13556         }
13557       else if (unformat (line_input, "group %U",
13558                          unformat_ip4_address, &remote4))
13559         {
13560           grp_set = remote_set = 1;
13561           ipv4_set = 1;
13562         }
13563       else if (unformat (line_input, "group %U %U",
13564                          unformat_ip6_address, &remote6,
13565                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13566         {
13567           grp_set = remote_set = 1;
13568           ipv6_set = 1;
13569         }
13570       else if (unformat (line_input, "group %U",
13571                          unformat_ip6_address, &remote6))
13572         {
13573           grp_set = remote_set = 1;
13574           ipv6_set = 1;
13575         }
13576       else
13577         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13578         ;
13579       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13580         ;
13581       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13582         ;
13583       else if (unformat (line_input, "vni %d", &vni))
13584         vni_set = 1;
13585       else if (unformat (line_input, "next-ip4"))
13586         protocol = 1;
13587       else if (unformat (line_input, "next-ip6"))
13588         protocol = 2;
13589       else if (unformat (line_input, "next-ethernet"))
13590         protocol = 3;
13591       else if (unformat (line_input, "next-nsh"))
13592         protocol = 4;
13593       else
13594         {
13595           errmsg ("parse error '%U'", format_unformat_error, line_input);
13596           return -99;
13597         }
13598     }
13599
13600   if (local_set == 0)
13601     {
13602       errmsg ("tunnel local address not specified");
13603       return -99;
13604     }
13605   if (remote_set == 0)
13606     {
13607       errmsg ("tunnel remote address not specified");
13608       return -99;
13609     }
13610   if (grp_set && mcast_sw_if_index == ~0)
13611     {
13612       errmsg ("tunnel nonexistent multicast device");
13613       return -99;
13614     }
13615   if (ipv4_set && ipv6_set)
13616     {
13617       errmsg ("both IPv4 and IPv6 addresses specified");
13618       return -99;
13619     }
13620
13621   if (vni_set == 0)
13622     {
13623       errmsg ("vni not specified");
13624       return -99;
13625     }
13626
13627   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13628
13629
13630   if (ipv6_set)
13631     {
13632       clib_memcpy (&mp->local, &local6, sizeof (local6));
13633       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13634     }
13635   else
13636     {
13637       clib_memcpy (&mp->local, &local4, sizeof (local4));
13638       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13639     }
13640
13641   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13642   mp->encap_vrf_id = ntohl (encap_vrf_id);
13643   mp->decap_vrf_id = ntohl (decap_vrf_id);
13644   mp->protocol = protocol;
13645   mp->vni = ntohl (vni);
13646   mp->is_add = is_add;
13647   mp->is_ipv6 = ipv6_set;
13648
13649   S (mp);
13650   W (ret);
13651   return ret;
13652 }
13653
13654 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13655   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13656 {
13657   vat_main_t *vam = &vat_main;
13658   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13659   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13660
13661   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13662          ntohl (mp->sw_if_index),
13663          format_ip46_address, &local, IP46_TYPE_ANY,
13664          format_ip46_address, &remote, IP46_TYPE_ANY,
13665          ntohl (mp->vni), mp->protocol,
13666          ntohl (mp->mcast_sw_if_index),
13667          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13668 }
13669
13670
13671 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13672   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13673 {
13674   vat_main_t *vam = &vat_main;
13675   vat_json_node_t *node = NULL;
13676   struct in_addr ip4;
13677   struct in6_addr ip6;
13678
13679   if (VAT_JSON_ARRAY != vam->json_tree.type)
13680     {
13681       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13682       vat_json_init_array (&vam->json_tree);
13683     }
13684   node = vat_json_array_add (&vam->json_tree);
13685
13686   vat_json_init_object (node);
13687   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13688   if (mp->is_ipv6)
13689     {
13690       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13691       vat_json_object_add_ip6 (node, "local", ip6);
13692       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13693       vat_json_object_add_ip6 (node, "remote", ip6);
13694     }
13695   else
13696     {
13697       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13698       vat_json_object_add_ip4 (node, "local", ip4);
13699       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13700       vat_json_object_add_ip4 (node, "remote", ip4);
13701     }
13702   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13703   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13704   vat_json_object_add_uint (node, "mcast_sw_if_index",
13705                             ntohl (mp->mcast_sw_if_index));
13706   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13707   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13708   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13709 }
13710
13711 static int
13712 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13713 {
13714   unformat_input_t *i = vam->input;
13715   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13716   vl_api_control_ping_t *mp_ping;
13717   u32 sw_if_index;
13718   u8 sw_if_index_set = 0;
13719   int ret;
13720
13721   /* Parse args required to build the message */
13722   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13723     {
13724       if (unformat (i, "sw_if_index %d", &sw_if_index))
13725         sw_if_index_set = 1;
13726       else
13727         break;
13728     }
13729
13730   if (sw_if_index_set == 0)
13731     {
13732       sw_if_index = ~0;
13733     }
13734
13735   if (!vam->json_output)
13736     {
13737       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13738              "sw_if_index", "local", "remote", "vni",
13739              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13740     }
13741
13742   /* Get list of vxlan-tunnel interfaces */
13743   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13744
13745   mp->sw_if_index = htonl (sw_if_index);
13746
13747   S (mp);
13748
13749   /* Use a control ping for synchronization */
13750   MPING (CONTROL_PING, mp_ping);
13751   S (mp_ping);
13752
13753   W (ret);
13754   return ret;
13755 }
13756
13757 static void vl_api_l2_fib_table_details_t_handler
13758   (vl_api_l2_fib_table_details_t * mp)
13759 {
13760   vat_main_t *vam = &vat_main;
13761
13762   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13763          "       %d       %d     %d",
13764          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
13765          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13766          mp->bvi_mac);
13767 }
13768
13769 static void vl_api_l2_fib_table_details_t_handler_json
13770   (vl_api_l2_fib_table_details_t * mp)
13771 {
13772   vat_main_t *vam = &vat_main;
13773   vat_json_node_t *node = NULL;
13774
13775   if (VAT_JSON_ARRAY != vam->json_tree.type)
13776     {
13777       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13778       vat_json_init_array (&vam->json_tree);
13779     }
13780   node = vat_json_array_add (&vam->json_tree);
13781
13782   vat_json_init_object (node);
13783   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13784   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
13785   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13786   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13787   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13788   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13789 }
13790
13791 static int
13792 api_l2_fib_table_dump (vat_main_t * vam)
13793 {
13794   unformat_input_t *i = vam->input;
13795   vl_api_l2_fib_table_dump_t *mp;
13796   vl_api_control_ping_t *mp_ping;
13797   u32 bd_id;
13798   u8 bd_id_set = 0;
13799   int ret;
13800
13801   /* Parse args required to build the message */
13802   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13803     {
13804       if (unformat (i, "bd_id %d", &bd_id))
13805         bd_id_set = 1;
13806       else
13807         break;
13808     }
13809
13810   if (bd_id_set == 0)
13811     {
13812       errmsg ("missing bridge domain");
13813       return -99;
13814     }
13815
13816   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13817
13818   /* Get list of l2 fib entries */
13819   M (L2_FIB_TABLE_DUMP, mp);
13820
13821   mp->bd_id = ntohl (bd_id);
13822   S (mp);
13823
13824   /* Use a control ping for synchronization */
13825   MPING (CONTROL_PING, mp_ping);
13826   S (mp_ping);
13827
13828   W (ret);
13829   return ret;
13830 }
13831
13832
13833 static int
13834 api_interface_name_renumber (vat_main_t * vam)
13835 {
13836   unformat_input_t *line_input = vam->input;
13837   vl_api_interface_name_renumber_t *mp;
13838   u32 sw_if_index = ~0;
13839   u32 new_show_dev_instance = ~0;
13840   int ret;
13841
13842   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13843     {
13844       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13845                     &sw_if_index))
13846         ;
13847       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13848         ;
13849       else if (unformat (line_input, "new_show_dev_instance %d",
13850                          &new_show_dev_instance))
13851         ;
13852       else
13853         break;
13854     }
13855
13856   if (sw_if_index == ~0)
13857     {
13858       errmsg ("missing interface name or sw_if_index");
13859       return -99;
13860     }
13861
13862   if (new_show_dev_instance == ~0)
13863     {
13864       errmsg ("missing new_show_dev_instance");
13865       return -99;
13866     }
13867
13868   M (INTERFACE_NAME_RENUMBER, mp);
13869
13870   mp->sw_if_index = ntohl (sw_if_index);
13871   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13872
13873   S (mp);
13874   W (ret);
13875   return ret;
13876 }
13877
13878 static int
13879 api_ip_probe_neighbor (vat_main_t * vam)
13880 {
13881   unformat_input_t *i = vam->input;
13882   vl_api_ip_probe_neighbor_t *mp;
13883   vl_api_address_t dst_adr = { };
13884   u8 int_set = 0;
13885   u8 adr_set = 0;
13886   u32 sw_if_index;
13887   int ret;
13888
13889   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13890     {
13891       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13892         int_set = 1;
13893       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13894         int_set = 1;
13895       else if (unformat (i, "address %U", unformat_vl_api_address, &dst_adr))
13896         adr_set = 1;
13897       else
13898         break;
13899     }
13900
13901   if (int_set == 0)
13902     {
13903       errmsg ("missing interface");
13904       return -99;
13905     }
13906
13907   if (adr_set == 0)
13908     {
13909       errmsg ("missing addresses");
13910       return -99;
13911     }
13912
13913   M (IP_PROBE_NEIGHBOR, mp);
13914
13915   mp->sw_if_index = ntohl (sw_if_index);
13916   clib_memcpy (&mp->dst, &dst_adr, sizeof (dst_adr));
13917
13918   S (mp);
13919   W (ret);
13920   return ret;
13921 }
13922
13923 static int
13924 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
13925 {
13926   unformat_input_t *i = vam->input;
13927   vl_api_ip_scan_neighbor_enable_disable_t *mp;
13928   u8 mode = IP_SCAN_V46_NEIGHBORS;
13929   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
13930   int ret;
13931
13932   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13933     {
13934       if (unformat (i, "ip4"))
13935         mode = IP_SCAN_V4_NEIGHBORS;
13936       else if (unformat (i, "ip6"))
13937         mode = IP_SCAN_V6_NEIGHBORS;
13938       if (unformat (i, "both"))
13939         mode = IP_SCAN_V46_NEIGHBORS;
13940       else if (unformat (i, "disable"))
13941         mode = IP_SCAN_DISABLED;
13942       else if (unformat (i, "interval %d", &interval))
13943         ;
13944       else if (unformat (i, "max-time %d", &time))
13945         ;
13946       else if (unformat (i, "max-update %d", &update))
13947         ;
13948       else if (unformat (i, "delay %d", &delay))
13949         ;
13950       else if (unformat (i, "stale %d", &stale))
13951         ;
13952       else
13953         break;
13954     }
13955
13956   if (interval > 255)
13957     {
13958       errmsg ("interval cannot exceed 255 minutes.");
13959       return -99;
13960     }
13961   if (time > 255)
13962     {
13963       errmsg ("max-time cannot exceed 255 usec.");
13964       return -99;
13965     }
13966   if (update > 255)
13967     {
13968       errmsg ("max-update cannot exceed 255.");
13969       return -99;
13970     }
13971   if (delay > 255)
13972     {
13973       errmsg ("delay cannot exceed 255 msec.");
13974       return -99;
13975     }
13976   if (stale > 255)
13977     {
13978       errmsg ("stale cannot exceed 255 minutes.");
13979       return -99;
13980     }
13981
13982   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
13983   mp->mode = mode;
13984   mp->scan_interval = interval;
13985   mp->max_proc_time = time;
13986   mp->max_update = update;
13987   mp->scan_int_delay = delay;
13988   mp->stale_threshold = stale;
13989
13990   S (mp);
13991   W (ret);
13992   return ret;
13993 }
13994
13995 static int
13996 api_want_ip4_arp_events (vat_main_t * vam)
13997 {
13998   unformat_input_t *line_input = vam->input;
13999   vl_api_want_ip4_arp_events_t *mp;
14000   ip4_address_t address;
14001   int address_set = 0;
14002   u32 enable_disable = 1;
14003   int ret;
14004
14005   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14006     {
14007       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14008         address_set = 1;
14009       else if (unformat (line_input, "del"))
14010         enable_disable = 0;
14011       else
14012         break;
14013     }
14014
14015   if (address_set == 0)
14016     {
14017       errmsg ("missing addresses");
14018       return -99;
14019     }
14020
14021   M (WANT_IP4_ARP_EVENTS, mp);
14022   mp->enable_disable = enable_disable;
14023   mp->pid = htonl (getpid ());
14024   clib_memcpy (mp->ip, &address, sizeof (address));
14025
14026   S (mp);
14027   W (ret);
14028   return ret;
14029 }
14030
14031 static int
14032 api_want_ip6_nd_events (vat_main_t * vam)
14033 {
14034   unformat_input_t *line_input = vam->input;
14035   vl_api_want_ip6_nd_events_t *mp;
14036   vl_api_ip6_address_t address;
14037   int address_set = 0;
14038   u32 enable_disable = 1;
14039   int ret;
14040
14041   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14042     {
14043       if (unformat
14044           (line_input, "address %U", unformat_vl_api_ip6_address, &address))
14045         address_set = 1;
14046       else if (unformat (line_input, "del"))
14047         enable_disable = 0;
14048       else
14049         break;
14050     }
14051
14052   if (address_set == 0)
14053     {
14054       errmsg ("missing addresses");
14055       return -99;
14056     }
14057
14058   M (WANT_IP6_ND_EVENTS, mp);
14059   mp->enable_disable = enable_disable;
14060   mp->pid = htonl (getpid ());
14061   clib_memcpy (&mp->ip, &address, sizeof (address));
14062
14063   S (mp);
14064   W (ret);
14065   return ret;
14066 }
14067
14068 static int
14069 api_want_l2_macs_events (vat_main_t * vam)
14070 {
14071   unformat_input_t *line_input = vam->input;
14072   vl_api_want_l2_macs_events_t *mp;
14073   u8 enable_disable = 1;
14074   u32 scan_delay = 0;
14075   u32 max_macs_in_event = 0;
14076   u32 learn_limit = 0;
14077   int ret;
14078
14079   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14080     {
14081       if (unformat (line_input, "learn-limit %d", &learn_limit))
14082         ;
14083       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14084         ;
14085       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14086         ;
14087       else if (unformat (line_input, "disable"))
14088         enable_disable = 0;
14089       else
14090         break;
14091     }
14092
14093   M (WANT_L2_MACS_EVENTS, mp);
14094   mp->enable_disable = enable_disable;
14095   mp->pid = htonl (getpid ());
14096   mp->learn_limit = htonl (learn_limit);
14097   mp->scan_delay = (u8) scan_delay;
14098   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14099   S (mp);
14100   W (ret);
14101   return ret;
14102 }
14103
14104 static int
14105 api_input_acl_set_interface (vat_main_t * vam)
14106 {
14107   unformat_input_t *i = vam->input;
14108   vl_api_input_acl_set_interface_t *mp;
14109   u32 sw_if_index;
14110   int sw_if_index_set;
14111   u32 ip4_table_index = ~0;
14112   u32 ip6_table_index = ~0;
14113   u32 l2_table_index = ~0;
14114   u8 is_add = 1;
14115   int ret;
14116
14117   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14118     {
14119       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14120         sw_if_index_set = 1;
14121       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14122         sw_if_index_set = 1;
14123       else if (unformat (i, "del"))
14124         is_add = 0;
14125       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14126         ;
14127       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14128         ;
14129       else if (unformat (i, "l2-table %d", &l2_table_index))
14130         ;
14131       else
14132         {
14133           clib_warning ("parse error '%U'", format_unformat_error, i);
14134           return -99;
14135         }
14136     }
14137
14138   if (sw_if_index_set == 0)
14139     {
14140       errmsg ("missing interface name or sw_if_index");
14141       return -99;
14142     }
14143
14144   M (INPUT_ACL_SET_INTERFACE, mp);
14145
14146   mp->sw_if_index = ntohl (sw_if_index);
14147   mp->ip4_table_index = ntohl (ip4_table_index);
14148   mp->ip6_table_index = ntohl (ip6_table_index);
14149   mp->l2_table_index = ntohl (l2_table_index);
14150   mp->is_add = is_add;
14151
14152   S (mp);
14153   W (ret);
14154   return ret;
14155 }
14156
14157 static int
14158 api_output_acl_set_interface (vat_main_t * vam)
14159 {
14160   unformat_input_t *i = vam->input;
14161   vl_api_output_acl_set_interface_t *mp;
14162   u32 sw_if_index;
14163   int sw_if_index_set;
14164   u32 ip4_table_index = ~0;
14165   u32 ip6_table_index = ~0;
14166   u32 l2_table_index = ~0;
14167   u8 is_add = 1;
14168   int ret;
14169
14170   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14171     {
14172       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14173         sw_if_index_set = 1;
14174       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14175         sw_if_index_set = 1;
14176       else if (unformat (i, "del"))
14177         is_add = 0;
14178       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14179         ;
14180       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14181         ;
14182       else if (unformat (i, "l2-table %d", &l2_table_index))
14183         ;
14184       else
14185         {
14186           clib_warning ("parse error '%U'", format_unformat_error, i);
14187           return -99;
14188         }
14189     }
14190
14191   if (sw_if_index_set == 0)
14192     {
14193       errmsg ("missing interface name or sw_if_index");
14194       return -99;
14195     }
14196
14197   M (OUTPUT_ACL_SET_INTERFACE, mp);
14198
14199   mp->sw_if_index = ntohl (sw_if_index);
14200   mp->ip4_table_index = ntohl (ip4_table_index);
14201   mp->ip6_table_index = ntohl (ip6_table_index);
14202   mp->l2_table_index = ntohl (l2_table_index);
14203   mp->is_add = is_add;
14204
14205   S (mp);
14206   W (ret);
14207   return ret;
14208 }
14209
14210 static int
14211 api_ip_address_dump (vat_main_t * vam)
14212 {
14213   unformat_input_t *i = vam->input;
14214   vl_api_ip_address_dump_t *mp;
14215   vl_api_control_ping_t *mp_ping;
14216   u32 sw_if_index = ~0;
14217   u8 sw_if_index_set = 0;
14218   u8 ipv4_set = 0;
14219   u8 ipv6_set = 0;
14220   int ret;
14221
14222   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14223     {
14224       if (unformat (i, "sw_if_index %d", &sw_if_index))
14225         sw_if_index_set = 1;
14226       else
14227         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14228         sw_if_index_set = 1;
14229       else if (unformat (i, "ipv4"))
14230         ipv4_set = 1;
14231       else if (unformat (i, "ipv6"))
14232         ipv6_set = 1;
14233       else
14234         break;
14235     }
14236
14237   if (ipv4_set && ipv6_set)
14238     {
14239       errmsg ("ipv4 and ipv6 flags cannot be both set");
14240       return -99;
14241     }
14242
14243   if ((!ipv4_set) && (!ipv6_set))
14244     {
14245       errmsg ("no ipv4 nor ipv6 flag set");
14246       return -99;
14247     }
14248
14249   if (sw_if_index_set == 0)
14250     {
14251       errmsg ("missing interface name or sw_if_index");
14252       return -99;
14253     }
14254
14255   vam->current_sw_if_index = sw_if_index;
14256   vam->is_ipv6 = ipv6_set;
14257
14258   M (IP_ADDRESS_DUMP, mp);
14259   mp->sw_if_index = ntohl (sw_if_index);
14260   mp->is_ipv6 = ipv6_set;
14261   S (mp);
14262
14263   /* Use a control ping for synchronization */
14264   MPING (CONTROL_PING, mp_ping);
14265   S (mp_ping);
14266
14267   W (ret);
14268   return ret;
14269 }
14270
14271 static int
14272 api_ip_dump (vat_main_t * vam)
14273 {
14274   vl_api_ip_dump_t *mp;
14275   vl_api_control_ping_t *mp_ping;
14276   unformat_input_t *in = vam->input;
14277   int ipv4_set = 0;
14278   int ipv6_set = 0;
14279   int is_ipv6;
14280   int i;
14281   int ret;
14282
14283   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14284     {
14285       if (unformat (in, "ipv4"))
14286         ipv4_set = 1;
14287       else if (unformat (in, "ipv6"))
14288         ipv6_set = 1;
14289       else
14290         break;
14291     }
14292
14293   if (ipv4_set && ipv6_set)
14294     {
14295       errmsg ("ipv4 and ipv6 flags cannot be both set");
14296       return -99;
14297     }
14298
14299   if ((!ipv4_set) && (!ipv6_set))
14300     {
14301       errmsg ("no ipv4 nor ipv6 flag set");
14302       return -99;
14303     }
14304
14305   is_ipv6 = ipv6_set;
14306   vam->is_ipv6 = is_ipv6;
14307
14308   /* free old data */
14309   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14310     {
14311       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14312     }
14313   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14314
14315   M (IP_DUMP, mp);
14316   mp->is_ipv6 = ipv6_set;
14317   S (mp);
14318
14319   /* Use a control ping for synchronization */
14320   MPING (CONTROL_PING, mp_ping);
14321   S (mp_ping);
14322
14323   W (ret);
14324   return ret;
14325 }
14326
14327 static int
14328 api_ipsec_spd_add_del (vat_main_t * vam)
14329 {
14330   unformat_input_t *i = vam->input;
14331   vl_api_ipsec_spd_add_del_t *mp;
14332   u32 spd_id = ~0;
14333   u8 is_add = 1;
14334   int ret;
14335
14336   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14337     {
14338       if (unformat (i, "spd_id %d", &spd_id))
14339         ;
14340       else if (unformat (i, "del"))
14341         is_add = 0;
14342       else
14343         {
14344           clib_warning ("parse error '%U'", format_unformat_error, i);
14345           return -99;
14346         }
14347     }
14348   if (spd_id == ~0)
14349     {
14350       errmsg ("spd_id must be set");
14351       return -99;
14352     }
14353
14354   M (IPSEC_SPD_ADD_DEL, mp);
14355
14356   mp->spd_id = ntohl (spd_id);
14357   mp->is_add = is_add;
14358
14359   S (mp);
14360   W (ret);
14361   return ret;
14362 }
14363
14364 static int
14365 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14366 {
14367   unformat_input_t *i = vam->input;
14368   vl_api_ipsec_interface_add_del_spd_t *mp;
14369   u32 sw_if_index;
14370   u8 sw_if_index_set = 0;
14371   u32 spd_id = (u32) ~ 0;
14372   u8 is_add = 1;
14373   int ret;
14374
14375   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14376     {
14377       if (unformat (i, "del"))
14378         is_add = 0;
14379       else if (unformat (i, "spd_id %d", &spd_id))
14380         ;
14381       else
14382         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14383         sw_if_index_set = 1;
14384       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14385         sw_if_index_set = 1;
14386       else
14387         {
14388           clib_warning ("parse error '%U'", format_unformat_error, i);
14389           return -99;
14390         }
14391
14392     }
14393
14394   if (spd_id == (u32) ~ 0)
14395     {
14396       errmsg ("spd_id must be set");
14397       return -99;
14398     }
14399
14400   if (sw_if_index_set == 0)
14401     {
14402       errmsg ("missing interface name or sw_if_index");
14403       return -99;
14404     }
14405
14406   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14407
14408   mp->spd_id = ntohl (spd_id);
14409   mp->sw_if_index = ntohl (sw_if_index);
14410   mp->is_add = is_add;
14411
14412   S (mp);
14413   W (ret);
14414   return ret;
14415 }
14416
14417 static int
14418 api_ipsec_spd_entry_add_del (vat_main_t * vam)
14419 {
14420   unformat_input_t *i = vam->input;
14421   vl_api_ipsec_spd_entry_add_del_t *mp;
14422   u8 is_add = 1, is_outbound = 0;
14423   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14424   i32 priority = 0;
14425   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14426   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14427   vl_api_address_t laddr_start = { }, laddr_stop =
14428   {
14429   }, raddr_start =
14430   {
14431   }, raddr_stop =
14432   {
14433   };
14434   int ret;
14435
14436   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14437     {
14438       if (unformat (i, "del"))
14439         is_add = 0;
14440       if (unformat (i, "outbound"))
14441         is_outbound = 1;
14442       if (unformat (i, "inbound"))
14443         is_outbound = 0;
14444       else if (unformat (i, "spd_id %d", &spd_id))
14445         ;
14446       else if (unformat (i, "sa_id %d", &sa_id))
14447         ;
14448       else if (unformat (i, "priority %d", &priority))
14449         ;
14450       else if (unformat (i, "protocol %d", &protocol))
14451         ;
14452       else if (unformat (i, "lport_start %d", &lport_start))
14453         ;
14454       else if (unformat (i, "lport_stop %d", &lport_stop))
14455         ;
14456       else if (unformat (i, "rport_start %d", &rport_start))
14457         ;
14458       else if (unformat (i, "rport_stop %d", &rport_stop))
14459         ;
14460       else if (unformat (i, "laddr_start %U",
14461                          unformat_vl_api_address, &laddr_start))
14462         ;
14463       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
14464                          &laddr_stop))
14465         ;
14466       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
14467                          &raddr_start))
14468         ;
14469       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
14470                          &raddr_stop))
14471         ;
14472       else
14473         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14474         {
14475           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14476             {
14477               clib_warning ("unsupported action: 'resolve'");
14478               return -99;
14479             }
14480         }
14481       else
14482         {
14483           clib_warning ("parse error '%U'", format_unformat_error, i);
14484           return -99;
14485         }
14486
14487     }
14488
14489   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
14490
14491   mp->is_add = is_add;
14492
14493   mp->entry.spd_id = ntohl (spd_id);
14494   mp->entry.priority = ntohl (priority);
14495   mp->entry.is_outbound = is_outbound;
14496
14497   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
14498                sizeof (vl_api_address_t));
14499   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
14500                sizeof (vl_api_address_t));
14501   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
14502                sizeof (vl_api_address_t));
14503   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
14504                sizeof (vl_api_address_t));
14505
14506   mp->entry.protocol = (u8) protocol;
14507   mp->entry.local_port_start = ntohs ((u16) lport_start);
14508   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
14509   mp->entry.remote_port_start = ntohs ((u16) rport_start);
14510   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
14511   mp->entry.policy = (u8) policy;
14512   mp->entry.sa_id = ntohl (sa_id);
14513
14514   S (mp);
14515   W (ret);
14516   return ret;
14517 }
14518
14519 static int
14520 api_ipsec_sad_entry_add_del (vat_main_t * vam)
14521 {
14522   unformat_input_t *i = vam->input;
14523   vl_api_ipsec_sad_entry_add_del_t *mp;
14524   u32 sad_id = 0, spi = 0;
14525   u8 *ck = 0, *ik = 0;
14526   u8 is_add = 1;
14527
14528   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
14529   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
14530   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
14531   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
14532   vl_api_address_t tun_src, tun_dst;
14533   int ret;
14534
14535   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14536     {
14537       if (unformat (i, "del"))
14538         is_add = 0;
14539       else if (unformat (i, "sad_id %d", &sad_id))
14540         ;
14541       else if (unformat (i, "spi %d", &spi))
14542         ;
14543       else if (unformat (i, "esp"))
14544         protocol = IPSEC_API_PROTO_ESP;
14545       else
14546         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
14547         {
14548           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14549           if (ADDRESS_IP6 == tun_src.af)
14550             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14551         }
14552       else
14553         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
14554         {
14555           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14556           if (ADDRESS_IP6 == tun_src.af)
14557             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14558         }
14559       else
14560         if (unformat (i, "crypto_alg %U",
14561                       unformat_ipsec_api_crypto_alg, &crypto_alg))
14562         ;
14563       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14564         ;
14565       else if (unformat (i, "integ_alg %U",
14566                          unformat_ipsec_api_integ_alg, &integ_alg))
14567         ;
14568       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14569         ;
14570       else
14571         {
14572           clib_warning ("parse error '%U'", format_unformat_error, i);
14573           return -99;
14574         }
14575
14576     }
14577
14578   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
14579
14580   mp->is_add = is_add;
14581   mp->entry.sad_id = ntohl (sad_id);
14582   mp->entry.protocol = protocol;
14583   mp->entry.spi = ntohl (spi);
14584   mp->entry.flags = flags;
14585
14586   mp->entry.crypto_algorithm = crypto_alg;
14587   mp->entry.integrity_algorithm = integ_alg;
14588   mp->entry.crypto_key.length = vec_len (ck);
14589   mp->entry.integrity_key.length = vec_len (ik);
14590
14591   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
14592     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
14593
14594   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
14595     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
14596
14597   if (ck)
14598     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
14599   if (ik)
14600     clib_memcpy (mp->entry.integrity_key.data, ik,
14601                  mp->entry.integrity_key.length);
14602
14603   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
14604     {
14605       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
14606                    sizeof (mp->entry.tunnel_src));
14607       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
14608                    sizeof (mp->entry.tunnel_dst));
14609     }
14610
14611   S (mp);
14612   W (ret);
14613   return ret;
14614 }
14615
14616 static int
14617 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14618 {
14619   unformat_input_t *i = vam->input;
14620   vl_api_ipsec_tunnel_if_add_del_t *mp;
14621   u32 local_spi = 0, remote_spi = 0;
14622   u32 crypto_alg = 0, integ_alg = 0;
14623   u8 *lck = NULL, *rck = NULL;
14624   u8 *lik = NULL, *rik = NULL;
14625   vl_api_address_t local_ip = { 0 };
14626   vl_api_address_t remote_ip = { 0 };
14627   f64 before = 0;
14628   u8 is_add = 1;
14629   u8 esn = 0;
14630   u8 anti_replay = 0;
14631   u8 renumber = 0;
14632   u32 instance = ~0;
14633   u32 count = 1, jj;
14634   int ret = -1;
14635
14636   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14637     {
14638       if (unformat (i, "del"))
14639         is_add = 0;
14640       else if (unformat (i, "esn"))
14641         esn = 1;
14642       else if (unformat (i, "anti-replay"))
14643         anti_replay = 1;
14644       else if (unformat (i, "count %d", &count))
14645         ;
14646       else if (unformat (i, "local_spi %d", &local_spi))
14647         ;
14648       else if (unformat (i, "remote_spi %d", &remote_spi))
14649         ;
14650       else
14651         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
14652         ;
14653       else
14654         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
14655         ;
14656       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14657         ;
14658       else
14659         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14660         ;
14661       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14662         ;
14663       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14664         ;
14665       else
14666         if (unformat
14667             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
14668         {
14669           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
14670             {
14671               errmsg ("unsupported crypto-alg: '%U'\n",
14672                       format_ipsec_crypto_alg, crypto_alg);
14673               return -99;
14674             }
14675         }
14676       else
14677         if (unformat
14678             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
14679         {
14680           if (integ_alg >= IPSEC_INTEG_N_ALG)
14681             {
14682               errmsg ("unsupported integ-alg: '%U'\n",
14683                       format_ipsec_integ_alg, integ_alg);
14684               return -99;
14685             }
14686         }
14687       else if (unformat (i, "instance %u", &instance))
14688         renumber = 1;
14689       else
14690         {
14691           errmsg ("parse error '%U'\n", format_unformat_error, i);
14692           return -99;
14693         }
14694     }
14695
14696   if (count > 1)
14697     {
14698       /* Turn on async mode */
14699       vam->async_mode = 1;
14700       vam->async_errors = 0;
14701       before = vat_time_now (vam);
14702     }
14703
14704   for (jj = 0; jj < count; jj++)
14705     {
14706       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14707
14708       mp->is_add = is_add;
14709       mp->esn = esn;
14710       mp->anti_replay = anti_replay;
14711
14712       if (jj > 0)
14713         increment_address (&remote_ip);
14714
14715       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
14716       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
14717
14718       mp->local_spi = htonl (local_spi + jj);
14719       mp->remote_spi = htonl (remote_spi + jj);
14720       mp->crypto_alg = (u8) crypto_alg;
14721
14722       mp->local_crypto_key_len = 0;
14723       if (lck)
14724         {
14725           mp->local_crypto_key_len = vec_len (lck);
14726           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14727             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14728           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14729         }
14730
14731       mp->remote_crypto_key_len = 0;
14732       if (rck)
14733         {
14734           mp->remote_crypto_key_len = vec_len (rck);
14735           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14736             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14737           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14738         }
14739
14740       mp->integ_alg = (u8) integ_alg;
14741
14742       mp->local_integ_key_len = 0;
14743       if (lik)
14744         {
14745           mp->local_integ_key_len = vec_len (lik);
14746           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14747             mp->local_integ_key_len = sizeof (mp->local_integ_key);
14748           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14749         }
14750
14751       mp->remote_integ_key_len = 0;
14752       if (rik)
14753         {
14754           mp->remote_integ_key_len = vec_len (rik);
14755           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14756             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14757           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14758         }
14759
14760       if (renumber)
14761         {
14762           mp->renumber = renumber;
14763           mp->show_instance = ntohl (instance);
14764         }
14765       S (mp);
14766     }
14767
14768   /* When testing multiple add/del ops, use a control-ping to sync */
14769   if (count > 1)
14770     {
14771       vl_api_control_ping_t *mp_ping;
14772       f64 after;
14773       f64 timeout;
14774
14775       /* Shut off async mode */
14776       vam->async_mode = 0;
14777
14778       MPING (CONTROL_PING, mp_ping);
14779       S (mp_ping);
14780
14781       timeout = vat_time_now (vam) + 1.0;
14782       while (vat_time_now (vam) < timeout)
14783         if (vam->result_ready == 1)
14784           goto out;
14785       vam->retval = -99;
14786
14787     out:
14788       if (vam->retval == -99)
14789         errmsg ("timeout");
14790
14791       if (vam->async_errors > 0)
14792         {
14793           errmsg ("%d asynchronous errors", vam->async_errors);
14794           vam->retval = -98;
14795         }
14796       vam->async_errors = 0;
14797       after = vat_time_now (vam);
14798
14799       /* slim chance, but we might have eaten SIGTERM on the first iteration */
14800       if (jj > 0)
14801         count = jj;
14802
14803       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
14804              count, after - before, count / (after - before));
14805     }
14806   else
14807     {
14808       /* Wait for a reply... */
14809       W (ret);
14810       return ret;
14811     }
14812
14813   return ret;
14814 }
14815
14816 static void
14817 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14818 {
14819   vat_main_t *vam = &vat_main;
14820
14821   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14822          "crypto_key %U integ_alg %u integ_key %U flags %x "
14823          "tunnel_src_addr %U tunnel_dst_addr %U "
14824          "salt %u seq_outbound %lu last_seq_inbound %lu "
14825          "replay_window %lu\n",
14826          ntohl (mp->entry.sad_id),
14827          ntohl (mp->sw_if_index),
14828          ntohl (mp->entry.spi),
14829          ntohl (mp->entry.protocol),
14830          ntohl (mp->entry.crypto_algorithm),
14831          format_hex_bytes, mp->entry.crypto_key.data,
14832          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
14833          format_hex_bytes, mp->entry.integrity_key.data,
14834          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
14835          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
14836          &mp->entry.tunnel_dst, ntohl (mp->salt),
14837          clib_net_to_host_u64 (mp->seq_outbound),
14838          clib_net_to_host_u64 (mp->last_seq_inbound),
14839          clib_net_to_host_u64 (mp->replay_window));
14840 }
14841
14842 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14843 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14844
14845 static void vl_api_ipsec_sa_details_t_handler_json
14846   (vl_api_ipsec_sa_details_t * mp)
14847 {
14848   vat_main_t *vam = &vat_main;
14849   vat_json_node_t *node = NULL;
14850   vl_api_ipsec_sad_flags_t flags;
14851
14852   if (VAT_JSON_ARRAY != vam->json_tree.type)
14853     {
14854       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14855       vat_json_init_array (&vam->json_tree);
14856     }
14857   node = vat_json_array_add (&vam->json_tree);
14858
14859   vat_json_init_object (node);
14860   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
14861   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14862   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
14863   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
14864   vat_json_object_add_uint (node, "crypto_alg",
14865                             ntohl (mp->entry.crypto_algorithm));
14866   vat_json_object_add_uint (node, "integ_alg",
14867                             ntohl (mp->entry.integrity_algorithm));
14868   flags = ntohl (mp->entry.flags);
14869   vat_json_object_add_uint (node, "use_esn",
14870                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
14871   vat_json_object_add_uint (node, "use_anti_replay",
14872                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
14873   vat_json_object_add_uint (node, "is_tunnel",
14874                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
14875   vat_json_object_add_uint (node, "is_tunnel_ip6",
14876                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
14877   vat_json_object_add_uint (node, "udp_encap",
14878                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
14879   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
14880                              mp->entry.crypto_key.length);
14881   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
14882                              mp->entry.integrity_key.length);
14883   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
14884   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
14885   vat_json_object_add_uint (node, "replay_window",
14886                             clib_net_to_host_u64 (mp->replay_window));
14887 }
14888
14889 static int
14890 api_ipsec_sa_dump (vat_main_t * vam)
14891 {
14892   unformat_input_t *i = vam->input;
14893   vl_api_ipsec_sa_dump_t *mp;
14894   vl_api_control_ping_t *mp_ping;
14895   u32 sa_id = ~0;
14896   int ret;
14897
14898   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14899     {
14900       if (unformat (i, "sa_id %d", &sa_id))
14901         ;
14902       else
14903         {
14904           clib_warning ("parse error '%U'", format_unformat_error, i);
14905           return -99;
14906         }
14907     }
14908
14909   M (IPSEC_SA_DUMP, mp);
14910
14911   mp->sa_id = ntohl (sa_id);
14912
14913   S (mp);
14914
14915   /* Use a control ping for synchronization */
14916   M (CONTROL_PING, mp_ping);
14917   S (mp_ping);
14918
14919   W (ret);
14920   return ret;
14921 }
14922
14923 static int
14924 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
14925 {
14926   unformat_input_t *i = vam->input;
14927   vl_api_ipsec_tunnel_if_set_sa_t *mp;
14928   u32 sw_if_index = ~0;
14929   u32 sa_id = ~0;
14930   u8 is_outbound = (u8) ~ 0;
14931   int ret;
14932
14933   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14934     {
14935       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14936         ;
14937       else if (unformat (i, "sa_id %d", &sa_id))
14938         ;
14939       else if (unformat (i, "outbound"))
14940         is_outbound = 1;
14941       else if (unformat (i, "inbound"))
14942         is_outbound = 0;
14943       else
14944         {
14945           clib_warning ("parse error '%U'", format_unformat_error, i);
14946           return -99;
14947         }
14948     }
14949
14950   if (sw_if_index == ~0)
14951     {
14952       errmsg ("interface must be specified");
14953       return -99;
14954     }
14955
14956   if (sa_id == ~0)
14957     {
14958       errmsg ("SA ID must be specified");
14959       return -99;
14960     }
14961
14962   M (IPSEC_TUNNEL_IF_SET_SA, mp);
14963
14964   mp->sw_if_index = htonl (sw_if_index);
14965   mp->sa_id = htonl (sa_id);
14966   mp->is_outbound = is_outbound;
14967
14968   S (mp);
14969   W (ret);
14970
14971   return ret;
14972 }
14973
14974 static int
14975 api_get_first_msg_id (vat_main_t * vam)
14976 {
14977   vl_api_get_first_msg_id_t *mp;
14978   unformat_input_t *i = vam->input;
14979   u8 *name;
14980   u8 name_set = 0;
14981   int ret;
14982
14983   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14984     {
14985       if (unformat (i, "client %s", &name))
14986         name_set = 1;
14987       else
14988         break;
14989     }
14990
14991   if (name_set == 0)
14992     {
14993       errmsg ("missing client name");
14994       return -99;
14995     }
14996   vec_add1 (name, 0);
14997
14998   if (vec_len (name) > 63)
14999     {
15000       errmsg ("client name too long");
15001       return -99;
15002     }
15003
15004   M (GET_FIRST_MSG_ID, mp);
15005   clib_memcpy (mp->name, name, vec_len (name));
15006   S (mp);
15007   W (ret);
15008   return ret;
15009 }
15010
15011 static int
15012 api_cop_interface_enable_disable (vat_main_t * vam)
15013 {
15014   unformat_input_t *line_input = vam->input;
15015   vl_api_cop_interface_enable_disable_t *mp;
15016   u32 sw_if_index = ~0;
15017   u8 enable_disable = 1;
15018   int ret;
15019
15020   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15021     {
15022       if (unformat (line_input, "disable"))
15023         enable_disable = 0;
15024       if (unformat (line_input, "enable"))
15025         enable_disable = 1;
15026       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15027                          vam, &sw_if_index))
15028         ;
15029       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15030         ;
15031       else
15032         break;
15033     }
15034
15035   if (sw_if_index == ~0)
15036     {
15037       errmsg ("missing interface name or sw_if_index");
15038       return -99;
15039     }
15040
15041   /* Construct the API message */
15042   M (COP_INTERFACE_ENABLE_DISABLE, mp);
15043   mp->sw_if_index = ntohl (sw_if_index);
15044   mp->enable_disable = enable_disable;
15045
15046   /* send it... */
15047   S (mp);
15048   /* Wait for the reply */
15049   W (ret);
15050   return ret;
15051 }
15052
15053 static int
15054 api_cop_whitelist_enable_disable (vat_main_t * vam)
15055 {
15056   unformat_input_t *line_input = vam->input;
15057   vl_api_cop_whitelist_enable_disable_t *mp;
15058   u32 sw_if_index = ~0;
15059   u8 ip4 = 0, ip6 = 0, default_cop = 0;
15060   u32 fib_id = 0;
15061   int ret;
15062
15063   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15064     {
15065       if (unformat (line_input, "ip4"))
15066         ip4 = 1;
15067       else if (unformat (line_input, "ip6"))
15068         ip6 = 1;
15069       else if (unformat (line_input, "default"))
15070         default_cop = 1;
15071       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15072                          vam, &sw_if_index))
15073         ;
15074       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15075         ;
15076       else if (unformat (line_input, "fib-id %d", &fib_id))
15077         ;
15078       else
15079         break;
15080     }
15081
15082   if (sw_if_index == ~0)
15083     {
15084       errmsg ("missing interface name or sw_if_index");
15085       return -99;
15086     }
15087
15088   /* Construct the API message */
15089   M (COP_WHITELIST_ENABLE_DISABLE, mp);
15090   mp->sw_if_index = ntohl (sw_if_index);
15091   mp->fib_id = ntohl (fib_id);
15092   mp->ip4 = ip4;
15093   mp->ip6 = ip6;
15094   mp->default_cop = default_cop;
15095
15096   /* send it... */
15097   S (mp);
15098   /* Wait for the reply */
15099   W (ret);
15100   return ret;
15101 }
15102
15103 static int
15104 api_get_node_graph (vat_main_t * vam)
15105 {
15106   vl_api_get_node_graph_t *mp;
15107   int ret;
15108
15109   M (GET_NODE_GRAPH, mp);
15110
15111   /* send it... */
15112   S (mp);
15113   /* Wait for the reply */
15114   W (ret);
15115   return ret;
15116 }
15117
15118 /* *INDENT-OFF* */
15119 /** Used for parsing LISP eids */
15120 typedef CLIB_PACKED(struct{
15121   u8 addr[16];   /**< eid address */
15122   u32 len;       /**< prefix length if IP */
15123   u8 type;      /**< type of eid */
15124 }) lisp_eid_vat_t;
15125 /* *INDENT-ON* */
15126
15127 static uword
15128 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
15129 {
15130   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
15131
15132   clib_memset (a, 0, sizeof (a[0]));
15133
15134   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
15135     {
15136       a->type = 0;              /* ipv4 type */
15137     }
15138   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
15139     {
15140       a->type = 1;              /* ipv6 type */
15141     }
15142   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
15143     {
15144       a->type = 2;              /* mac type */
15145     }
15146   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
15147     {
15148       a->type = 3;              /* NSH type */
15149       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
15150       nsh->spi = clib_host_to_net_u32 (nsh->spi);
15151     }
15152   else
15153     {
15154       return 0;
15155     }
15156
15157   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
15158     {
15159       return 0;
15160     }
15161
15162   return 1;
15163 }
15164
15165 static int
15166 lisp_eid_size_vat (u8 type)
15167 {
15168   switch (type)
15169     {
15170     case 0:
15171       return 4;
15172     case 1:
15173       return 16;
15174     case 2:
15175       return 6;
15176     case 3:
15177       return 5;
15178     }
15179   return 0;
15180 }
15181
15182 static void
15183 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
15184 {
15185   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
15186 }
15187
15188 static int
15189 api_one_add_del_locator_set (vat_main_t * vam)
15190 {
15191   unformat_input_t *input = vam->input;
15192   vl_api_one_add_del_locator_set_t *mp;
15193   u8 is_add = 1;
15194   u8 *locator_set_name = NULL;
15195   u8 locator_set_name_set = 0;
15196   vl_api_local_locator_t locator, *locators = 0;
15197   u32 sw_if_index, priority, weight;
15198   u32 data_len = 0;
15199
15200   int ret;
15201   /* Parse args required to build the message */
15202   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15203     {
15204       if (unformat (input, "del"))
15205         {
15206           is_add = 0;
15207         }
15208       else if (unformat (input, "locator-set %s", &locator_set_name))
15209         {
15210           locator_set_name_set = 1;
15211         }
15212       else if (unformat (input, "sw_if_index %u p %u w %u",
15213                          &sw_if_index, &priority, &weight))
15214         {
15215           locator.sw_if_index = htonl (sw_if_index);
15216           locator.priority = priority;
15217           locator.weight = weight;
15218           vec_add1 (locators, locator);
15219         }
15220       else
15221         if (unformat
15222             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
15223              &sw_if_index, &priority, &weight))
15224         {
15225           locator.sw_if_index = htonl (sw_if_index);
15226           locator.priority = priority;
15227           locator.weight = weight;
15228           vec_add1 (locators, locator);
15229         }
15230       else
15231         break;
15232     }
15233
15234   if (locator_set_name_set == 0)
15235     {
15236       errmsg ("missing locator-set name");
15237       vec_free (locators);
15238       return -99;
15239     }
15240
15241   if (vec_len (locator_set_name) > 64)
15242     {
15243       errmsg ("locator-set name too long");
15244       vec_free (locator_set_name);
15245       vec_free (locators);
15246       return -99;
15247     }
15248   vec_add1 (locator_set_name, 0);
15249
15250   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
15251
15252   /* Construct the API message */
15253   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
15254
15255   mp->is_add = is_add;
15256   clib_memcpy (mp->locator_set_name, locator_set_name,
15257                vec_len (locator_set_name));
15258   vec_free (locator_set_name);
15259
15260   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
15261   if (locators)
15262     clib_memcpy (mp->locators, locators, data_len);
15263   vec_free (locators);
15264
15265   /* send it... */
15266   S (mp);
15267
15268   /* Wait for a reply... */
15269   W (ret);
15270   return ret;
15271 }
15272
15273 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
15274
15275 static int
15276 api_one_add_del_locator (vat_main_t * vam)
15277 {
15278   unformat_input_t *input = vam->input;
15279   vl_api_one_add_del_locator_t *mp;
15280   u32 tmp_if_index = ~0;
15281   u32 sw_if_index = ~0;
15282   u8 sw_if_index_set = 0;
15283   u8 sw_if_index_if_name_set = 0;
15284   u32 priority = ~0;
15285   u8 priority_set = 0;
15286   u32 weight = ~0;
15287   u8 weight_set = 0;
15288   u8 is_add = 1;
15289   u8 *locator_set_name = NULL;
15290   u8 locator_set_name_set = 0;
15291   int ret;
15292
15293   /* Parse args required to build the message */
15294   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15295     {
15296       if (unformat (input, "del"))
15297         {
15298           is_add = 0;
15299         }
15300       else if (unformat (input, "locator-set %s", &locator_set_name))
15301         {
15302           locator_set_name_set = 1;
15303         }
15304       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
15305                          &tmp_if_index))
15306         {
15307           sw_if_index_if_name_set = 1;
15308           sw_if_index = tmp_if_index;
15309         }
15310       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
15311         {
15312           sw_if_index_set = 1;
15313           sw_if_index = tmp_if_index;
15314         }
15315       else if (unformat (input, "p %d", &priority))
15316         {
15317           priority_set = 1;
15318         }
15319       else if (unformat (input, "w %d", &weight))
15320         {
15321           weight_set = 1;
15322         }
15323       else
15324         break;
15325     }
15326
15327   if (locator_set_name_set == 0)
15328     {
15329       errmsg ("missing locator-set name");
15330       return -99;
15331     }
15332
15333   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
15334     {
15335       errmsg ("missing sw_if_index");
15336       vec_free (locator_set_name);
15337       return -99;
15338     }
15339
15340   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
15341     {
15342       errmsg ("cannot use both params interface name and sw_if_index");
15343       vec_free (locator_set_name);
15344       return -99;
15345     }
15346
15347   if (priority_set == 0)
15348     {
15349       errmsg ("missing locator-set priority");
15350       vec_free (locator_set_name);
15351       return -99;
15352     }
15353
15354   if (weight_set == 0)
15355     {
15356       errmsg ("missing locator-set weight");
15357       vec_free (locator_set_name);
15358       return -99;
15359     }
15360
15361   if (vec_len (locator_set_name) > 64)
15362     {
15363       errmsg ("locator-set name too long");
15364       vec_free (locator_set_name);
15365       return -99;
15366     }
15367   vec_add1 (locator_set_name, 0);
15368
15369   /* Construct the API message */
15370   M (ONE_ADD_DEL_LOCATOR, mp);
15371
15372   mp->is_add = is_add;
15373   mp->sw_if_index = ntohl (sw_if_index);
15374   mp->priority = priority;
15375   mp->weight = weight;
15376   clib_memcpy (mp->locator_set_name, locator_set_name,
15377                vec_len (locator_set_name));
15378   vec_free (locator_set_name);
15379
15380   /* send it... */
15381   S (mp);
15382
15383   /* Wait for a reply... */
15384   W (ret);
15385   return ret;
15386 }
15387
15388 #define api_lisp_add_del_locator api_one_add_del_locator
15389
15390 uword
15391 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15392 {
15393   u32 *key_id = va_arg (*args, u32 *);
15394   u8 *s = 0;
15395
15396   if (unformat (input, "%s", &s))
15397     {
15398       if (!strcmp ((char *) s, "sha1"))
15399         key_id[0] = HMAC_SHA_1_96;
15400       else if (!strcmp ((char *) s, "sha256"))
15401         key_id[0] = HMAC_SHA_256_128;
15402       else
15403         {
15404           clib_warning ("invalid key_id: '%s'", s);
15405           key_id[0] = HMAC_NO_KEY;
15406         }
15407     }
15408   else
15409     return 0;
15410
15411   vec_free (s);
15412   return 1;
15413 }
15414
15415 static int
15416 api_one_add_del_local_eid (vat_main_t * vam)
15417 {
15418   unformat_input_t *input = vam->input;
15419   vl_api_one_add_del_local_eid_t *mp;
15420   u8 is_add = 1;
15421   u8 eid_set = 0;
15422   lisp_eid_vat_t _eid, *eid = &_eid;
15423   u8 *locator_set_name = 0;
15424   u8 locator_set_name_set = 0;
15425   u32 vni = 0;
15426   u16 key_id = 0;
15427   u8 *key = 0;
15428   int ret;
15429
15430   /* Parse args required to build the message */
15431   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15432     {
15433       if (unformat (input, "del"))
15434         {
15435           is_add = 0;
15436         }
15437       else if (unformat (input, "vni %d", &vni))
15438         {
15439           ;
15440         }
15441       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15442         {
15443           eid_set = 1;
15444         }
15445       else if (unformat (input, "locator-set %s", &locator_set_name))
15446         {
15447           locator_set_name_set = 1;
15448         }
15449       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15450         ;
15451       else if (unformat (input, "secret-key %_%v%_", &key))
15452         ;
15453       else
15454         break;
15455     }
15456
15457   if (locator_set_name_set == 0)
15458     {
15459       errmsg ("missing locator-set name");
15460       return -99;
15461     }
15462
15463   if (0 == eid_set)
15464     {
15465       errmsg ("EID address not set!");
15466       vec_free (locator_set_name);
15467       return -99;
15468     }
15469
15470   if (key && (0 == key_id))
15471     {
15472       errmsg ("invalid key_id!");
15473       return -99;
15474     }
15475
15476   if (vec_len (key) > 64)
15477     {
15478       errmsg ("key too long");
15479       vec_free (key);
15480       return -99;
15481     }
15482
15483   if (vec_len (locator_set_name) > 64)
15484     {
15485       errmsg ("locator-set name too long");
15486       vec_free (locator_set_name);
15487       return -99;
15488     }
15489   vec_add1 (locator_set_name, 0);
15490
15491   /* Construct the API message */
15492   M (ONE_ADD_DEL_LOCAL_EID, mp);
15493
15494   mp->is_add = is_add;
15495   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15496   mp->eid_type = eid->type;
15497   mp->prefix_len = eid->len;
15498   mp->vni = clib_host_to_net_u32 (vni);
15499   mp->key_id = clib_host_to_net_u16 (key_id);
15500   clib_memcpy (mp->locator_set_name, locator_set_name,
15501                vec_len (locator_set_name));
15502   clib_memcpy (mp->key, key, vec_len (key));
15503
15504   vec_free (locator_set_name);
15505   vec_free (key);
15506
15507   /* send it... */
15508   S (mp);
15509
15510   /* Wait for a reply... */
15511   W (ret);
15512   return ret;
15513 }
15514
15515 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15516
15517 static int
15518 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
15519 {
15520   u32 dp_table = 0, vni = 0;;
15521   unformat_input_t *input = vam->input;
15522   vl_api_gpe_add_del_fwd_entry_t *mp;
15523   u8 is_add = 1;
15524   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
15525   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
15526   u8 rmt_eid_set = 0, lcl_eid_set = 0;
15527   u32 action = ~0, w;
15528   ip4_address_t rmt_rloc4, lcl_rloc4;
15529   ip6_address_t rmt_rloc6, lcl_rloc6;
15530   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
15531   int ret;
15532
15533   clib_memset (&rloc, 0, sizeof (rloc));
15534
15535   /* Parse args required to build the message */
15536   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15537     {
15538       if (unformat (input, "del"))
15539         is_add = 0;
15540       else if (unformat (input, "add"))
15541         is_add = 1;
15542       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
15543         {
15544           rmt_eid_set = 1;
15545         }
15546       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
15547         {
15548           lcl_eid_set = 1;
15549         }
15550       else if (unformat (input, "vrf %d", &dp_table))
15551         ;
15552       else if (unformat (input, "bd %d", &dp_table))
15553         ;
15554       else if (unformat (input, "vni %d", &vni))
15555         ;
15556       else if (unformat (input, "w %d", &w))
15557         {
15558           if (!curr_rloc)
15559             {
15560               errmsg ("No RLOC configured for setting priority/weight!");
15561               return -99;
15562             }
15563           curr_rloc->weight = w;
15564         }
15565       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
15566                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
15567         {
15568           rloc.is_ip4 = 1;
15569
15570           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
15571           rloc.weight = 0;
15572           vec_add1 (lcl_locs, rloc);
15573
15574           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
15575           vec_add1 (rmt_locs, rloc);
15576           /* weight saved in rmt loc */
15577           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15578         }
15579       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
15580                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
15581         {
15582           rloc.is_ip4 = 0;
15583           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
15584           rloc.weight = 0;
15585           vec_add1 (lcl_locs, rloc);
15586
15587           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
15588           vec_add1 (rmt_locs, rloc);
15589           /* weight saved in rmt loc */
15590           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15591         }
15592       else if (unformat (input, "action %d", &action))
15593         {
15594           ;
15595         }
15596       else
15597         {
15598           clib_warning ("parse error '%U'", format_unformat_error, input);
15599           return -99;
15600         }
15601     }
15602
15603   if (!rmt_eid_set)
15604     {
15605       errmsg ("remote eid addresses not set");
15606       return -99;
15607     }
15608
15609   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
15610     {
15611       errmsg ("eid types don't match");
15612       return -99;
15613     }
15614
15615   if (0 == rmt_locs && (u32) ~ 0 == action)
15616     {
15617       errmsg ("action not set for negative mapping");
15618       return -99;
15619     }
15620
15621   /* Construct the API message */
15622   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
15623       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
15624
15625   mp->is_add = is_add;
15626   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
15627   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
15628   mp->eid_type = rmt_eid->type;
15629   mp->dp_table = clib_host_to_net_u32 (dp_table);
15630   mp->vni = clib_host_to_net_u32 (vni);
15631   mp->rmt_len = rmt_eid->len;
15632   mp->lcl_len = lcl_eid->len;
15633   mp->action = action;
15634
15635   if (0 != rmt_locs && 0 != lcl_locs)
15636     {
15637       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
15638       clib_memcpy (mp->locs, lcl_locs,
15639                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
15640
15641       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
15642       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
15643                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
15644     }
15645   vec_free (lcl_locs);
15646   vec_free (rmt_locs);
15647
15648   /* send it... */
15649   S (mp);
15650
15651   /* Wait for a reply... */
15652   W (ret);
15653   return ret;
15654 }
15655
15656 static int
15657 api_one_add_del_map_server (vat_main_t * vam)
15658 {
15659   unformat_input_t *input = vam->input;
15660   vl_api_one_add_del_map_server_t *mp;
15661   u8 is_add = 1;
15662   u8 ipv4_set = 0;
15663   u8 ipv6_set = 0;
15664   ip4_address_t ipv4;
15665   ip6_address_t ipv6;
15666   int ret;
15667
15668   /* Parse args required to build the message */
15669   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15670     {
15671       if (unformat (input, "del"))
15672         {
15673           is_add = 0;
15674         }
15675       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15676         {
15677           ipv4_set = 1;
15678         }
15679       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15680         {
15681           ipv6_set = 1;
15682         }
15683       else
15684         break;
15685     }
15686
15687   if (ipv4_set && ipv6_set)
15688     {
15689       errmsg ("both eid v4 and v6 addresses set");
15690       return -99;
15691     }
15692
15693   if (!ipv4_set && !ipv6_set)
15694     {
15695       errmsg ("eid addresses not set");
15696       return -99;
15697     }
15698
15699   /* Construct the API message */
15700   M (ONE_ADD_DEL_MAP_SERVER, mp);
15701
15702   mp->is_add = is_add;
15703   if (ipv6_set)
15704     {
15705       mp->is_ipv6 = 1;
15706       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15707     }
15708   else
15709     {
15710       mp->is_ipv6 = 0;
15711       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15712     }
15713
15714   /* send it... */
15715   S (mp);
15716
15717   /* Wait for a reply... */
15718   W (ret);
15719   return ret;
15720 }
15721
15722 #define api_lisp_add_del_map_server api_one_add_del_map_server
15723
15724 static int
15725 api_one_add_del_map_resolver (vat_main_t * vam)
15726 {
15727   unformat_input_t *input = vam->input;
15728   vl_api_one_add_del_map_resolver_t *mp;
15729   u8 is_add = 1;
15730   u8 ipv4_set = 0;
15731   u8 ipv6_set = 0;
15732   ip4_address_t ipv4;
15733   ip6_address_t ipv6;
15734   int ret;
15735
15736   /* Parse args required to build the message */
15737   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15738     {
15739       if (unformat (input, "del"))
15740         {
15741           is_add = 0;
15742         }
15743       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15744         {
15745           ipv4_set = 1;
15746         }
15747       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15748         {
15749           ipv6_set = 1;
15750         }
15751       else
15752         break;
15753     }
15754
15755   if (ipv4_set && ipv6_set)
15756     {
15757       errmsg ("both eid v4 and v6 addresses set");
15758       return -99;
15759     }
15760
15761   if (!ipv4_set && !ipv6_set)
15762     {
15763       errmsg ("eid addresses not set");
15764       return -99;
15765     }
15766
15767   /* Construct the API message */
15768   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
15769
15770   mp->is_add = is_add;
15771   if (ipv6_set)
15772     {
15773       mp->is_ipv6 = 1;
15774       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15775     }
15776   else
15777     {
15778       mp->is_ipv6 = 0;
15779       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15780     }
15781
15782   /* send it... */
15783   S (mp);
15784
15785   /* Wait for a reply... */
15786   W (ret);
15787   return ret;
15788 }
15789
15790 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
15791
15792 static int
15793 api_lisp_gpe_enable_disable (vat_main_t * vam)
15794 {
15795   unformat_input_t *input = vam->input;
15796   vl_api_gpe_enable_disable_t *mp;
15797   u8 is_set = 0;
15798   u8 is_en = 1;
15799   int ret;
15800
15801   /* Parse args required to build the message */
15802   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15803     {
15804       if (unformat (input, "enable"))
15805         {
15806           is_set = 1;
15807           is_en = 1;
15808         }
15809       else if (unformat (input, "disable"))
15810         {
15811           is_set = 1;
15812           is_en = 0;
15813         }
15814       else
15815         break;
15816     }
15817
15818   if (is_set == 0)
15819     {
15820       errmsg ("Value not set");
15821       return -99;
15822     }
15823
15824   /* Construct the API message */
15825   M (GPE_ENABLE_DISABLE, mp);
15826
15827   mp->is_en = is_en;
15828
15829   /* send it... */
15830   S (mp);
15831
15832   /* Wait for a reply... */
15833   W (ret);
15834   return ret;
15835 }
15836
15837 static int
15838 api_one_rloc_probe_enable_disable (vat_main_t * vam)
15839 {
15840   unformat_input_t *input = vam->input;
15841   vl_api_one_rloc_probe_enable_disable_t *mp;
15842   u8 is_set = 0;
15843   u8 is_en = 0;
15844   int ret;
15845
15846   /* Parse args required to build the message */
15847   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15848     {
15849       if (unformat (input, "enable"))
15850         {
15851           is_set = 1;
15852           is_en = 1;
15853         }
15854       else if (unformat (input, "disable"))
15855         is_set = 1;
15856       else
15857         break;
15858     }
15859
15860   if (!is_set)
15861     {
15862       errmsg ("Value not set");
15863       return -99;
15864     }
15865
15866   /* Construct the API message */
15867   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
15868
15869   mp->is_enabled = is_en;
15870
15871   /* send it... */
15872   S (mp);
15873
15874   /* Wait for a reply... */
15875   W (ret);
15876   return ret;
15877 }
15878
15879 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
15880
15881 static int
15882 api_one_map_register_enable_disable (vat_main_t * vam)
15883 {
15884   unformat_input_t *input = vam->input;
15885   vl_api_one_map_register_enable_disable_t *mp;
15886   u8 is_set = 0;
15887   u8 is_en = 0;
15888   int ret;
15889
15890   /* Parse args required to build the message */
15891   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15892     {
15893       if (unformat (input, "enable"))
15894         {
15895           is_set = 1;
15896           is_en = 1;
15897         }
15898       else if (unformat (input, "disable"))
15899         is_set = 1;
15900       else
15901         break;
15902     }
15903
15904   if (!is_set)
15905     {
15906       errmsg ("Value not set");
15907       return -99;
15908     }
15909
15910   /* Construct the API message */
15911   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
15912
15913   mp->is_enabled = is_en;
15914
15915   /* send it... */
15916   S (mp);
15917
15918   /* Wait for a reply... */
15919   W (ret);
15920   return ret;
15921 }
15922
15923 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
15924
15925 static int
15926 api_one_enable_disable (vat_main_t * vam)
15927 {
15928   unformat_input_t *input = vam->input;
15929   vl_api_one_enable_disable_t *mp;
15930   u8 is_set = 0;
15931   u8 is_en = 0;
15932   int ret;
15933
15934   /* Parse args required to build the message */
15935   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15936     {
15937       if (unformat (input, "enable"))
15938         {
15939           is_set = 1;
15940           is_en = 1;
15941         }
15942       else if (unformat (input, "disable"))
15943         {
15944           is_set = 1;
15945         }
15946       else
15947         break;
15948     }
15949
15950   if (!is_set)
15951     {
15952       errmsg ("Value not set");
15953       return -99;
15954     }
15955
15956   /* Construct the API message */
15957   M (ONE_ENABLE_DISABLE, mp);
15958
15959   mp->is_en = is_en;
15960
15961   /* send it... */
15962   S (mp);
15963
15964   /* Wait for a reply... */
15965   W (ret);
15966   return ret;
15967 }
15968
15969 #define api_lisp_enable_disable api_one_enable_disable
15970
15971 static int
15972 api_one_enable_disable_xtr_mode (vat_main_t * vam)
15973 {
15974   unformat_input_t *input = vam->input;
15975   vl_api_one_enable_disable_xtr_mode_t *mp;
15976   u8 is_set = 0;
15977   u8 is_en = 0;
15978   int ret;
15979
15980   /* Parse args required to build the message */
15981   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15982     {
15983       if (unformat (input, "enable"))
15984         {
15985           is_set = 1;
15986           is_en = 1;
15987         }
15988       else if (unformat (input, "disable"))
15989         {
15990           is_set = 1;
15991         }
15992       else
15993         break;
15994     }
15995
15996   if (!is_set)
15997     {
15998       errmsg ("Value not set");
15999       return -99;
16000     }
16001
16002   /* Construct the API message */
16003   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
16004
16005   mp->is_en = is_en;
16006
16007   /* send it... */
16008   S (mp);
16009
16010   /* Wait for a reply... */
16011   W (ret);
16012   return ret;
16013 }
16014
16015 static int
16016 api_one_show_xtr_mode (vat_main_t * vam)
16017 {
16018   vl_api_one_show_xtr_mode_t *mp;
16019   int ret;
16020
16021   /* Construct the API message */
16022   M (ONE_SHOW_XTR_MODE, mp);
16023
16024   /* send it... */
16025   S (mp);
16026
16027   /* Wait for a reply... */
16028   W (ret);
16029   return ret;
16030 }
16031
16032 static int
16033 api_one_enable_disable_pitr_mode (vat_main_t * vam)
16034 {
16035   unformat_input_t *input = vam->input;
16036   vl_api_one_enable_disable_pitr_mode_t *mp;
16037   u8 is_set = 0;
16038   u8 is_en = 0;
16039   int ret;
16040
16041   /* Parse args required to build the message */
16042   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16043     {
16044       if (unformat (input, "enable"))
16045         {
16046           is_set = 1;
16047           is_en = 1;
16048         }
16049       else if (unformat (input, "disable"))
16050         {
16051           is_set = 1;
16052         }
16053       else
16054         break;
16055     }
16056
16057   if (!is_set)
16058     {
16059       errmsg ("Value not set");
16060       return -99;
16061     }
16062
16063   /* Construct the API message */
16064   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
16065
16066   mp->is_en = is_en;
16067
16068   /* send it... */
16069   S (mp);
16070
16071   /* Wait for a reply... */
16072   W (ret);
16073   return ret;
16074 }
16075
16076 static int
16077 api_one_show_pitr_mode (vat_main_t * vam)
16078 {
16079   vl_api_one_show_pitr_mode_t *mp;
16080   int ret;
16081
16082   /* Construct the API message */
16083   M (ONE_SHOW_PITR_MODE, mp);
16084
16085   /* send it... */
16086   S (mp);
16087
16088   /* Wait for a reply... */
16089   W (ret);
16090   return ret;
16091 }
16092
16093 static int
16094 api_one_enable_disable_petr_mode (vat_main_t * vam)
16095 {
16096   unformat_input_t *input = vam->input;
16097   vl_api_one_enable_disable_petr_mode_t *mp;
16098   u8 is_set = 0;
16099   u8 is_en = 0;
16100   int ret;
16101
16102   /* Parse args required to build the message */
16103   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16104     {
16105       if (unformat (input, "enable"))
16106         {
16107           is_set = 1;
16108           is_en = 1;
16109         }
16110       else if (unformat (input, "disable"))
16111         {
16112           is_set = 1;
16113         }
16114       else
16115         break;
16116     }
16117
16118   if (!is_set)
16119     {
16120       errmsg ("Value not set");
16121       return -99;
16122     }
16123
16124   /* Construct the API message */
16125   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
16126
16127   mp->is_en = is_en;
16128
16129   /* send it... */
16130   S (mp);
16131
16132   /* Wait for a reply... */
16133   W (ret);
16134   return ret;
16135 }
16136
16137 static int
16138 api_one_show_petr_mode (vat_main_t * vam)
16139 {
16140   vl_api_one_show_petr_mode_t *mp;
16141   int ret;
16142
16143   /* Construct the API message */
16144   M (ONE_SHOW_PETR_MODE, mp);
16145
16146   /* send it... */
16147   S (mp);
16148
16149   /* Wait for a reply... */
16150   W (ret);
16151   return ret;
16152 }
16153
16154 static int
16155 api_show_one_map_register_state (vat_main_t * vam)
16156 {
16157   vl_api_show_one_map_register_state_t *mp;
16158   int ret;
16159
16160   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
16161
16162   /* send */
16163   S (mp);
16164
16165   /* wait for reply */
16166   W (ret);
16167   return ret;
16168 }
16169
16170 #define api_show_lisp_map_register_state api_show_one_map_register_state
16171
16172 static int
16173 api_show_one_rloc_probe_state (vat_main_t * vam)
16174 {
16175   vl_api_show_one_rloc_probe_state_t *mp;
16176   int ret;
16177
16178   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
16179
16180   /* send */
16181   S (mp);
16182
16183   /* wait for reply */
16184   W (ret);
16185   return ret;
16186 }
16187
16188 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
16189
16190 static int
16191 api_one_add_del_ndp_entry (vat_main_t * vam)
16192 {
16193   vl_api_one_add_del_ndp_entry_t *mp;
16194   unformat_input_t *input = vam->input;
16195   u8 is_add = 1;
16196   u8 mac_set = 0;
16197   u8 bd_set = 0;
16198   u8 ip_set = 0;
16199   u8 mac[6] = { 0, };
16200   u8 ip6[16] = { 0, };
16201   u32 bd = ~0;
16202   int ret;
16203
16204   /* Parse args required to build the message */
16205   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16206     {
16207       if (unformat (input, "del"))
16208         is_add = 0;
16209       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16210         mac_set = 1;
16211       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
16212         ip_set = 1;
16213       else if (unformat (input, "bd %d", &bd))
16214         bd_set = 1;
16215       else
16216         {
16217           errmsg ("parse error '%U'", format_unformat_error, input);
16218           return -99;
16219         }
16220     }
16221
16222   if (!bd_set || !ip_set || (!mac_set && is_add))
16223     {
16224       errmsg ("Missing BD, IP or MAC!");
16225       return -99;
16226     }
16227
16228   M (ONE_ADD_DEL_NDP_ENTRY, mp);
16229   mp->is_add = is_add;
16230   clib_memcpy (mp->mac, mac, 6);
16231   mp->bd = clib_host_to_net_u32 (bd);
16232   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
16233
16234   /* send */
16235   S (mp);
16236
16237   /* wait for reply */
16238   W (ret);
16239   return ret;
16240 }
16241
16242 static int
16243 api_one_add_del_l2_arp_entry (vat_main_t * vam)
16244 {
16245   vl_api_one_add_del_l2_arp_entry_t *mp;
16246   unformat_input_t *input = vam->input;
16247   u8 is_add = 1;
16248   u8 mac_set = 0;
16249   u8 bd_set = 0;
16250   u8 ip_set = 0;
16251   u8 mac[6] = { 0, };
16252   u32 ip4 = 0, bd = ~0;
16253   int ret;
16254
16255   /* Parse args required to build the message */
16256   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16257     {
16258       if (unformat (input, "del"))
16259         is_add = 0;
16260       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16261         mac_set = 1;
16262       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
16263         ip_set = 1;
16264       else if (unformat (input, "bd %d", &bd))
16265         bd_set = 1;
16266       else
16267         {
16268           errmsg ("parse error '%U'", format_unformat_error, input);
16269           return -99;
16270         }
16271     }
16272
16273   if (!bd_set || !ip_set || (!mac_set && is_add))
16274     {
16275       errmsg ("Missing BD, IP or MAC!");
16276       return -99;
16277     }
16278
16279   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
16280   mp->is_add = is_add;
16281   clib_memcpy (mp->mac, mac, 6);
16282   mp->bd = clib_host_to_net_u32 (bd);
16283   mp->ip4 = ip4;
16284
16285   /* send */
16286   S (mp);
16287
16288   /* wait for reply */
16289   W (ret);
16290   return ret;
16291 }
16292
16293 static int
16294 api_one_ndp_bd_get (vat_main_t * vam)
16295 {
16296   vl_api_one_ndp_bd_get_t *mp;
16297   int ret;
16298
16299   M (ONE_NDP_BD_GET, mp);
16300
16301   /* send */
16302   S (mp);
16303
16304   /* wait for reply */
16305   W (ret);
16306   return ret;
16307 }
16308
16309 static int
16310 api_one_ndp_entries_get (vat_main_t * vam)
16311 {
16312   vl_api_one_ndp_entries_get_t *mp;
16313   unformat_input_t *input = vam->input;
16314   u8 bd_set = 0;
16315   u32 bd = ~0;
16316   int ret;
16317
16318   /* Parse args required to build the message */
16319   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16320     {
16321       if (unformat (input, "bd %d", &bd))
16322         bd_set = 1;
16323       else
16324         {
16325           errmsg ("parse error '%U'", format_unformat_error, input);
16326           return -99;
16327         }
16328     }
16329
16330   if (!bd_set)
16331     {
16332       errmsg ("Expected bridge domain!");
16333       return -99;
16334     }
16335
16336   M (ONE_NDP_ENTRIES_GET, mp);
16337   mp->bd = clib_host_to_net_u32 (bd);
16338
16339   /* send */
16340   S (mp);
16341
16342   /* wait for reply */
16343   W (ret);
16344   return ret;
16345 }
16346
16347 static int
16348 api_one_l2_arp_bd_get (vat_main_t * vam)
16349 {
16350   vl_api_one_l2_arp_bd_get_t *mp;
16351   int ret;
16352
16353   M (ONE_L2_ARP_BD_GET, mp);
16354
16355   /* send */
16356   S (mp);
16357
16358   /* wait for reply */
16359   W (ret);
16360   return ret;
16361 }
16362
16363 static int
16364 api_one_l2_arp_entries_get (vat_main_t * vam)
16365 {
16366   vl_api_one_l2_arp_entries_get_t *mp;
16367   unformat_input_t *input = vam->input;
16368   u8 bd_set = 0;
16369   u32 bd = ~0;
16370   int ret;
16371
16372   /* Parse args required to build the message */
16373   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16374     {
16375       if (unformat (input, "bd %d", &bd))
16376         bd_set = 1;
16377       else
16378         {
16379           errmsg ("parse error '%U'", format_unformat_error, input);
16380           return -99;
16381         }
16382     }
16383
16384   if (!bd_set)
16385     {
16386       errmsg ("Expected bridge domain!");
16387       return -99;
16388     }
16389
16390   M (ONE_L2_ARP_ENTRIES_GET, mp);
16391   mp->bd = clib_host_to_net_u32 (bd);
16392
16393   /* send */
16394   S (mp);
16395
16396   /* wait for reply */
16397   W (ret);
16398   return ret;
16399 }
16400
16401 static int
16402 api_one_stats_enable_disable (vat_main_t * vam)
16403 {
16404   vl_api_one_stats_enable_disable_t *mp;
16405   unformat_input_t *input = vam->input;
16406   u8 is_set = 0;
16407   u8 is_en = 0;
16408   int ret;
16409
16410   /* Parse args required to build the message */
16411   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16412     {
16413       if (unformat (input, "enable"))
16414         {
16415           is_set = 1;
16416           is_en = 1;
16417         }
16418       else if (unformat (input, "disable"))
16419         {
16420           is_set = 1;
16421         }
16422       else
16423         break;
16424     }
16425
16426   if (!is_set)
16427     {
16428       errmsg ("Value not set");
16429       return -99;
16430     }
16431
16432   M (ONE_STATS_ENABLE_DISABLE, mp);
16433   mp->is_en = is_en;
16434
16435   /* send */
16436   S (mp);
16437
16438   /* wait for reply */
16439   W (ret);
16440   return ret;
16441 }
16442
16443 static int
16444 api_show_one_stats_enable_disable (vat_main_t * vam)
16445 {
16446   vl_api_show_one_stats_enable_disable_t *mp;
16447   int ret;
16448
16449   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16450
16451   /* send */
16452   S (mp);
16453
16454   /* wait for reply */
16455   W (ret);
16456   return ret;
16457 }
16458
16459 static int
16460 api_show_one_map_request_mode (vat_main_t * vam)
16461 {
16462   vl_api_show_one_map_request_mode_t *mp;
16463   int ret;
16464
16465   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16466
16467   /* send */
16468   S (mp);
16469
16470   /* wait for reply */
16471   W (ret);
16472   return ret;
16473 }
16474
16475 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16476
16477 static int
16478 api_one_map_request_mode (vat_main_t * vam)
16479 {
16480   unformat_input_t *input = vam->input;
16481   vl_api_one_map_request_mode_t *mp;
16482   u8 mode = 0;
16483   int ret;
16484
16485   /* Parse args required to build the message */
16486   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16487     {
16488       if (unformat (input, "dst-only"))
16489         mode = 0;
16490       else if (unformat (input, "src-dst"))
16491         mode = 1;
16492       else
16493         {
16494           errmsg ("parse error '%U'", format_unformat_error, input);
16495           return -99;
16496         }
16497     }
16498
16499   M (ONE_MAP_REQUEST_MODE, mp);
16500
16501   mp->mode = mode;
16502
16503   /* send */
16504   S (mp);
16505
16506   /* wait for reply */
16507   W (ret);
16508   return ret;
16509 }
16510
16511 #define api_lisp_map_request_mode api_one_map_request_mode
16512
16513 /**
16514  * Enable/disable ONE proxy ITR.
16515  *
16516  * @param vam vpp API test context
16517  * @return return code
16518  */
16519 static int
16520 api_one_pitr_set_locator_set (vat_main_t * vam)
16521 {
16522   u8 ls_name_set = 0;
16523   unformat_input_t *input = vam->input;
16524   vl_api_one_pitr_set_locator_set_t *mp;
16525   u8 is_add = 1;
16526   u8 *ls_name = 0;
16527   int ret;
16528
16529   /* Parse args required to build the message */
16530   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16531     {
16532       if (unformat (input, "del"))
16533         is_add = 0;
16534       else if (unformat (input, "locator-set %s", &ls_name))
16535         ls_name_set = 1;
16536       else
16537         {
16538           errmsg ("parse error '%U'", format_unformat_error, input);
16539           return -99;
16540         }
16541     }
16542
16543   if (!ls_name_set)
16544     {
16545       errmsg ("locator-set name not set!");
16546       return -99;
16547     }
16548
16549   M (ONE_PITR_SET_LOCATOR_SET, mp);
16550
16551   mp->is_add = is_add;
16552   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16553   vec_free (ls_name);
16554
16555   /* send */
16556   S (mp);
16557
16558   /* wait for reply */
16559   W (ret);
16560   return ret;
16561 }
16562
16563 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
16564
16565 static int
16566 api_one_nsh_set_locator_set (vat_main_t * vam)
16567 {
16568   u8 ls_name_set = 0;
16569   unformat_input_t *input = vam->input;
16570   vl_api_one_nsh_set_locator_set_t *mp;
16571   u8 is_add = 1;
16572   u8 *ls_name = 0;
16573   int ret;
16574
16575   /* Parse args required to build the message */
16576   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16577     {
16578       if (unformat (input, "del"))
16579         is_add = 0;
16580       else if (unformat (input, "ls %s", &ls_name))
16581         ls_name_set = 1;
16582       else
16583         {
16584           errmsg ("parse error '%U'", format_unformat_error, input);
16585           return -99;
16586         }
16587     }
16588
16589   if (!ls_name_set && is_add)
16590     {
16591       errmsg ("locator-set name not set!");
16592       return -99;
16593     }
16594
16595   M (ONE_NSH_SET_LOCATOR_SET, mp);
16596
16597   mp->is_add = is_add;
16598   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16599   vec_free (ls_name);
16600
16601   /* send */
16602   S (mp);
16603
16604   /* wait for reply */
16605   W (ret);
16606   return ret;
16607 }
16608
16609 static int
16610 api_show_one_pitr (vat_main_t * vam)
16611 {
16612   vl_api_show_one_pitr_t *mp;
16613   int ret;
16614
16615   if (!vam->json_output)
16616     {
16617       print (vam->ofp, "%=20s", "lisp status:");
16618     }
16619
16620   M (SHOW_ONE_PITR, mp);
16621   /* send it... */
16622   S (mp);
16623
16624   /* Wait for a reply... */
16625   W (ret);
16626   return ret;
16627 }
16628
16629 #define api_show_lisp_pitr api_show_one_pitr
16630
16631 static int
16632 api_one_use_petr (vat_main_t * vam)
16633 {
16634   unformat_input_t *input = vam->input;
16635   vl_api_one_use_petr_t *mp;
16636   u8 is_add = 0;
16637   ip_address_t ip;
16638   int ret;
16639
16640   clib_memset (&ip, 0, sizeof (ip));
16641
16642   /* Parse args required to build the message */
16643   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16644     {
16645       if (unformat (input, "disable"))
16646         is_add = 0;
16647       else
16648         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
16649         {
16650           is_add = 1;
16651           ip_addr_version (&ip) = IP4;
16652         }
16653       else
16654         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
16655         {
16656           is_add = 1;
16657           ip_addr_version (&ip) = IP6;
16658         }
16659       else
16660         {
16661           errmsg ("parse error '%U'", format_unformat_error, input);
16662           return -99;
16663         }
16664     }
16665
16666   M (ONE_USE_PETR, mp);
16667
16668   mp->is_add = is_add;
16669   if (is_add)
16670     {
16671       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
16672       if (mp->is_ip4)
16673         clib_memcpy (mp->address, &ip, 4);
16674       else
16675         clib_memcpy (mp->address, &ip, 16);
16676     }
16677
16678   /* send */
16679   S (mp);
16680
16681   /* wait for reply */
16682   W (ret);
16683   return ret;
16684 }
16685
16686 #define api_lisp_use_petr api_one_use_petr
16687
16688 static int
16689 api_show_one_nsh_mapping (vat_main_t * vam)
16690 {
16691   vl_api_show_one_use_petr_t *mp;
16692   int ret;
16693
16694   if (!vam->json_output)
16695     {
16696       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
16697     }
16698
16699   M (SHOW_ONE_NSH_MAPPING, mp);
16700   /* send it... */
16701   S (mp);
16702
16703   /* Wait for a reply... */
16704   W (ret);
16705   return ret;
16706 }
16707
16708 static int
16709 api_show_one_use_petr (vat_main_t * vam)
16710 {
16711   vl_api_show_one_use_petr_t *mp;
16712   int ret;
16713
16714   if (!vam->json_output)
16715     {
16716       print (vam->ofp, "%=20s", "Proxy-ETR status:");
16717     }
16718
16719   M (SHOW_ONE_USE_PETR, mp);
16720   /* send it... */
16721   S (mp);
16722
16723   /* Wait for a reply... */
16724   W (ret);
16725   return ret;
16726 }
16727
16728 #define api_show_lisp_use_petr api_show_one_use_petr
16729
16730 /**
16731  * Add/delete mapping between vni and vrf
16732  */
16733 static int
16734 api_one_eid_table_add_del_map (vat_main_t * vam)
16735 {
16736   unformat_input_t *input = vam->input;
16737   vl_api_one_eid_table_add_del_map_t *mp;
16738   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
16739   u32 vni, vrf, bd_index;
16740   int ret;
16741
16742   /* Parse args required to build the message */
16743   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16744     {
16745       if (unformat (input, "del"))
16746         is_add = 0;
16747       else if (unformat (input, "vrf %d", &vrf))
16748         vrf_set = 1;
16749       else if (unformat (input, "bd_index %d", &bd_index))
16750         bd_index_set = 1;
16751       else if (unformat (input, "vni %d", &vni))
16752         vni_set = 1;
16753       else
16754         break;
16755     }
16756
16757   if (!vni_set || (!vrf_set && !bd_index_set))
16758     {
16759       errmsg ("missing arguments!");
16760       return -99;
16761     }
16762
16763   if (vrf_set && bd_index_set)
16764     {
16765       errmsg ("error: both vrf and bd entered!");
16766       return -99;
16767     }
16768
16769   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
16770
16771   mp->is_add = is_add;
16772   mp->vni = htonl (vni);
16773   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
16774   mp->is_l2 = bd_index_set;
16775
16776   /* send */
16777   S (mp);
16778
16779   /* wait for reply */
16780   W (ret);
16781   return ret;
16782 }
16783
16784 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
16785
16786 uword
16787 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
16788 {
16789   u32 *action = va_arg (*args, u32 *);
16790   u8 *s = 0;
16791
16792   if (unformat (input, "%s", &s))
16793     {
16794       if (!strcmp ((char *) s, "no-action"))
16795         action[0] = 0;
16796       else if (!strcmp ((char *) s, "natively-forward"))
16797         action[0] = 1;
16798       else if (!strcmp ((char *) s, "send-map-request"))
16799         action[0] = 2;
16800       else if (!strcmp ((char *) s, "drop"))
16801         action[0] = 3;
16802       else
16803         {
16804           clib_warning ("invalid action: '%s'", s);
16805           action[0] = 3;
16806         }
16807     }
16808   else
16809     return 0;
16810
16811   vec_free (s);
16812   return 1;
16813 }
16814
16815 /**
16816  * Add/del remote mapping to/from ONE control plane
16817  *
16818  * @param vam vpp API test context
16819  * @return return code
16820  */
16821 static int
16822 api_one_add_del_remote_mapping (vat_main_t * vam)
16823 {
16824   unformat_input_t *input = vam->input;
16825   vl_api_one_add_del_remote_mapping_t *mp;
16826   u32 vni = 0;
16827   lisp_eid_vat_t _eid, *eid = &_eid;
16828   lisp_eid_vat_t _seid, *seid = &_seid;
16829   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
16830   u32 action = ~0, p, w, data_len;
16831   ip4_address_t rloc4;
16832   ip6_address_t rloc6;
16833   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
16834   int ret;
16835
16836   clib_memset (&rloc, 0, sizeof (rloc));
16837
16838   /* Parse args required to build the message */
16839   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16840     {
16841       if (unformat (input, "del-all"))
16842         {
16843           del_all = 1;
16844         }
16845       else if (unformat (input, "del"))
16846         {
16847           is_add = 0;
16848         }
16849       else if (unformat (input, "add"))
16850         {
16851           is_add = 1;
16852         }
16853       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16854         {
16855           eid_set = 1;
16856         }
16857       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
16858         {
16859           seid_set = 1;
16860         }
16861       else if (unformat (input, "vni %d", &vni))
16862         {
16863           ;
16864         }
16865       else if (unformat (input, "p %d w %d", &p, &w))
16866         {
16867           if (!curr_rloc)
16868             {
16869               errmsg ("No RLOC configured for setting priority/weight!");
16870               return -99;
16871             }
16872           curr_rloc->priority = p;
16873           curr_rloc->weight = w;
16874         }
16875       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
16876         {
16877           rloc.is_ip4 = 1;
16878           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
16879           vec_add1 (rlocs, rloc);
16880           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16881         }
16882       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
16883         {
16884           rloc.is_ip4 = 0;
16885           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
16886           vec_add1 (rlocs, rloc);
16887           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16888         }
16889       else if (unformat (input, "action %U",
16890                          unformat_negative_mapping_action, &action))
16891         {
16892           ;
16893         }
16894       else
16895         {
16896           clib_warning ("parse error '%U'", format_unformat_error, input);
16897           return -99;
16898         }
16899     }
16900
16901   if (0 == eid_set)
16902     {
16903       errmsg ("missing params!");
16904       return -99;
16905     }
16906
16907   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
16908     {
16909       errmsg ("no action set for negative map-reply!");
16910       return -99;
16911     }
16912
16913   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
16914
16915   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
16916   mp->is_add = is_add;
16917   mp->vni = htonl (vni);
16918   mp->action = (u8) action;
16919   mp->is_src_dst = seid_set;
16920   mp->eid_len = eid->len;
16921   mp->seid_len = seid->len;
16922   mp->del_all = del_all;
16923   mp->eid_type = eid->type;
16924   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16925   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
16926
16927   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
16928   clib_memcpy (mp->rlocs, rlocs, data_len);
16929   vec_free (rlocs);
16930
16931   /* send it... */
16932   S (mp);
16933
16934   /* Wait for a reply... */
16935   W (ret);
16936   return ret;
16937 }
16938
16939 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
16940
16941 /**
16942  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
16943  * forwarding entries in data-plane accordingly.
16944  *
16945  * @param vam vpp API test context
16946  * @return return code
16947  */
16948 static int
16949 api_one_add_del_adjacency (vat_main_t * vam)
16950 {
16951   unformat_input_t *input = vam->input;
16952   vl_api_one_add_del_adjacency_t *mp;
16953   u32 vni = 0;
16954   ip4_address_t leid4, reid4;
16955   ip6_address_t leid6, reid6;
16956   u8 reid_mac[6] = { 0 };
16957   u8 leid_mac[6] = { 0 };
16958   u8 reid_type, leid_type;
16959   u32 leid_len = 0, reid_len = 0, len;
16960   u8 is_add = 1;
16961   int ret;
16962
16963   leid_type = reid_type = (u8) ~ 0;
16964
16965   /* Parse args required to build the message */
16966   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16967     {
16968       if (unformat (input, "del"))
16969         {
16970           is_add = 0;
16971         }
16972       else if (unformat (input, "add"))
16973         {
16974           is_add = 1;
16975         }
16976       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
16977                          &reid4, &len))
16978         {
16979           reid_type = 0;        /* ipv4 */
16980           reid_len = len;
16981         }
16982       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
16983                          &reid6, &len))
16984         {
16985           reid_type = 1;        /* ipv6 */
16986           reid_len = len;
16987         }
16988       else if (unformat (input, "reid %U", unformat_ethernet_address,
16989                          reid_mac))
16990         {
16991           reid_type = 2;        /* mac */
16992         }
16993       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
16994                          &leid4, &len))
16995         {
16996           leid_type = 0;        /* ipv4 */
16997           leid_len = len;
16998         }
16999       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17000                          &leid6, &len))
17001         {
17002           leid_type = 1;        /* ipv6 */
17003           leid_len = len;
17004         }
17005       else if (unformat (input, "leid %U", unformat_ethernet_address,
17006                          leid_mac))
17007         {
17008           leid_type = 2;        /* mac */
17009         }
17010       else if (unformat (input, "vni %d", &vni))
17011         {
17012           ;
17013         }
17014       else
17015         {
17016           errmsg ("parse error '%U'", format_unformat_error, input);
17017           return -99;
17018         }
17019     }
17020
17021   if ((u8) ~ 0 == reid_type)
17022     {
17023       errmsg ("missing params!");
17024       return -99;
17025     }
17026
17027   if (leid_type != reid_type)
17028     {
17029       errmsg ("remote and local EIDs are of different types!");
17030       return -99;
17031     }
17032
17033   M (ONE_ADD_DEL_ADJACENCY, mp);
17034   mp->is_add = is_add;
17035   mp->vni = htonl (vni);
17036   mp->leid_len = leid_len;
17037   mp->reid_len = reid_len;
17038   mp->eid_type = reid_type;
17039
17040   switch (mp->eid_type)
17041     {
17042     case 0:
17043       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
17044       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
17045       break;
17046     case 1:
17047       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
17048       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
17049       break;
17050     case 2:
17051       clib_memcpy (mp->leid, leid_mac, 6);
17052       clib_memcpy (mp->reid, reid_mac, 6);
17053       break;
17054     default:
17055       errmsg ("unknown EID type %d!", mp->eid_type);
17056       return 0;
17057     }
17058
17059   /* send it... */
17060   S (mp);
17061
17062   /* Wait for a reply... */
17063   W (ret);
17064   return ret;
17065 }
17066
17067 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
17068
17069 uword
17070 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
17071 {
17072   u32 *mode = va_arg (*args, u32 *);
17073
17074   if (unformat (input, "lisp"))
17075     *mode = 0;
17076   else if (unformat (input, "vxlan"))
17077     *mode = 1;
17078   else
17079     return 0;
17080
17081   return 1;
17082 }
17083
17084 static int
17085 api_gpe_get_encap_mode (vat_main_t * vam)
17086 {
17087   vl_api_gpe_get_encap_mode_t *mp;
17088   int ret;
17089
17090   /* Construct the API message */
17091   M (GPE_GET_ENCAP_MODE, mp);
17092
17093   /* send it... */
17094   S (mp);
17095
17096   /* Wait for a reply... */
17097   W (ret);
17098   return ret;
17099 }
17100
17101 static int
17102 api_gpe_set_encap_mode (vat_main_t * vam)
17103 {
17104   unformat_input_t *input = vam->input;
17105   vl_api_gpe_set_encap_mode_t *mp;
17106   int ret;
17107   u32 mode = 0;
17108
17109   /* Parse args required to build the message */
17110   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17111     {
17112       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
17113         ;
17114       else
17115         break;
17116     }
17117
17118   /* Construct the API message */
17119   M (GPE_SET_ENCAP_MODE, mp);
17120
17121   mp->mode = mode;
17122
17123   /* send it... */
17124   S (mp);
17125
17126   /* Wait for a reply... */
17127   W (ret);
17128   return ret;
17129 }
17130
17131 static int
17132 api_lisp_gpe_add_del_iface (vat_main_t * vam)
17133 {
17134   unformat_input_t *input = vam->input;
17135   vl_api_gpe_add_del_iface_t *mp;
17136   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
17137   u32 dp_table = 0, vni = 0;
17138   int ret;
17139
17140   /* Parse args required to build the message */
17141   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17142     {
17143       if (unformat (input, "up"))
17144         {
17145           action_set = 1;
17146           is_add = 1;
17147         }
17148       else if (unformat (input, "down"))
17149         {
17150           action_set = 1;
17151           is_add = 0;
17152         }
17153       else if (unformat (input, "table_id %d", &dp_table))
17154         {
17155           dp_table_set = 1;
17156         }
17157       else if (unformat (input, "bd_id %d", &dp_table))
17158         {
17159           dp_table_set = 1;
17160           is_l2 = 1;
17161         }
17162       else if (unformat (input, "vni %d", &vni))
17163         {
17164           vni_set = 1;
17165         }
17166       else
17167         break;
17168     }
17169
17170   if (action_set == 0)
17171     {
17172       errmsg ("Action not set");
17173       return -99;
17174     }
17175   if (dp_table_set == 0 || vni_set == 0)
17176     {
17177       errmsg ("vni and dp_table must be set");
17178       return -99;
17179     }
17180
17181   /* Construct the API message */
17182   M (GPE_ADD_DEL_IFACE, mp);
17183
17184   mp->is_add = is_add;
17185   mp->dp_table = clib_host_to_net_u32 (dp_table);
17186   mp->is_l2 = is_l2;
17187   mp->vni = clib_host_to_net_u32 (vni);
17188
17189   /* send it... */
17190   S (mp);
17191
17192   /* Wait for a reply... */
17193   W (ret);
17194   return ret;
17195 }
17196
17197 static int
17198 api_one_map_register_fallback_threshold (vat_main_t * vam)
17199 {
17200   unformat_input_t *input = vam->input;
17201   vl_api_one_map_register_fallback_threshold_t *mp;
17202   u32 value = 0;
17203   u8 is_set = 0;
17204   int ret;
17205
17206   /* Parse args required to build the message */
17207   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17208     {
17209       if (unformat (input, "%u", &value))
17210         is_set = 1;
17211       else
17212         {
17213           clib_warning ("parse error '%U'", format_unformat_error, input);
17214           return -99;
17215         }
17216     }
17217
17218   if (!is_set)
17219     {
17220       errmsg ("fallback threshold value is missing!");
17221       return -99;
17222     }
17223
17224   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17225   mp->value = clib_host_to_net_u32 (value);
17226
17227   /* send it... */
17228   S (mp);
17229
17230   /* Wait for a reply... */
17231   W (ret);
17232   return ret;
17233 }
17234
17235 static int
17236 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
17237 {
17238   vl_api_show_one_map_register_fallback_threshold_t *mp;
17239   int ret;
17240
17241   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17242
17243   /* send it... */
17244   S (mp);
17245
17246   /* Wait for a reply... */
17247   W (ret);
17248   return ret;
17249 }
17250
17251 uword
17252 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
17253 {
17254   u32 *proto = va_arg (*args, u32 *);
17255
17256   if (unformat (input, "udp"))
17257     *proto = 1;
17258   else if (unformat (input, "api"))
17259     *proto = 2;
17260   else
17261     return 0;
17262
17263   return 1;
17264 }
17265
17266 static int
17267 api_one_set_transport_protocol (vat_main_t * vam)
17268 {
17269   unformat_input_t *input = vam->input;
17270   vl_api_one_set_transport_protocol_t *mp;
17271   u8 is_set = 0;
17272   u32 protocol = 0;
17273   int ret;
17274
17275   /* Parse args required to build the message */
17276   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17277     {
17278       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
17279         is_set = 1;
17280       else
17281         {
17282           clib_warning ("parse error '%U'", format_unformat_error, input);
17283           return -99;
17284         }
17285     }
17286
17287   if (!is_set)
17288     {
17289       errmsg ("Transport protocol missing!");
17290       return -99;
17291     }
17292
17293   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
17294   mp->protocol = (u8) protocol;
17295
17296   /* send it... */
17297   S (mp);
17298
17299   /* Wait for a reply... */
17300   W (ret);
17301   return ret;
17302 }
17303
17304 static int
17305 api_one_get_transport_protocol (vat_main_t * vam)
17306 {
17307   vl_api_one_get_transport_protocol_t *mp;
17308   int ret;
17309
17310   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
17311
17312   /* send it... */
17313   S (mp);
17314
17315   /* Wait for a reply... */
17316   W (ret);
17317   return ret;
17318 }
17319
17320 static int
17321 api_one_map_register_set_ttl (vat_main_t * vam)
17322 {
17323   unformat_input_t *input = vam->input;
17324   vl_api_one_map_register_set_ttl_t *mp;
17325   u32 ttl = 0;
17326   u8 is_set = 0;
17327   int ret;
17328
17329   /* Parse args required to build the message */
17330   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17331     {
17332       if (unformat (input, "%u", &ttl))
17333         is_set = 1;
17334       else
17335         {
17336           clib_warning ("parse error '%U'", format_unformat_error, input);
17337           return -99;
17338         }
17339     }
17340
17341   if (!is_set)
17342     {
17343       errmsg ("TTL value missing!");
17344       return -99;
17345     }
17346
17347   M (ONE_MAP_REGISTER_SET_TTL, mp);
17348   mp->ttl = clib_host_to_net_u32 (ttl);
17349
17350   /* send it... */
17351   S (mp);
17352
17353   /* Wait for a reply... */
17354   W (ret);
17355   return ret;
17356 }
17357
17358 static int
17359 api_show_one_map_register_ttl (vat_main_t * vam)
17360 {
17361   vl_api_show_one_map_register_ttl_t *mp;
17362   int ret;
17363
17364   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
17365
17366   /* send it... */
17367   S (mp);
17368
17369   /* Wait for a reply... */
17370   W (ret);
17371   return ret;
17372 }
17373
17374 /**
17375  * Add/del map request itr rlocs from ONE control plane and updates
17376  *
17377  * @param vam vpp API test context
17378  * @return return code
17379  */
17380 static int
17381 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17382 {
17383   unformat_input_t *input = vam->input;
17384   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17385   u8 *locator_set_name = 0;
17386   u8 locator_set_name_set = 0;
17387   u8 is_add = 1;
17388   int ret;
17389
17390   /* Parse args required to build the message */
17391   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17392     {
17393       if (unformat (input, "del"))
17394         {
17395           is_add = 0;
17396         }
17397       else if (unformat (input, "%_%v%_", &locator_set_name))
17398         {
17399           locator_set_name_set = 1;
17400         }
17401       else
17402         {
17403           clib_warning ("parse error '%U'", format_unformat_error, input);
17404           return -99;
17405         }
17406     }
17407
17408   if (is_add && !locator_set_name_set)
17409     {
17410       errmsg ("itr-rloc is not set!");
17411       return -99;
17412     }
17413
17414   if (is_add && vec_len (locator_set_name) > 64)
17415     {
17416       errmsg ("itr-rloc locator-set name too long");
17417       vec_free (locator_set_name);
17418       return -99;
17419     }
17420
17421   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17422   mp->is_add = is_add;
17423   if (is_add)
17424     {
17425       clib_memcpy (mp->locator_set_name, locator_set_name,
17426                    vec_len (locator_set_name));
17427     }
17428   else
17429     {
17430       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17431     }
17432   vec_free (locator_set_name);
17433
17434   /* send it... */
17435   S (mp);
17436
17437   /* Wait for a reply... */
17438   W (ret);
17439   return ret;
17440 }
17441
17442 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17443
17444 static int
17445 api_one_locator_dump (vat_main_t * vam)
17446 {
17447   unformat_input_t *input = vam->input;
17448   vl_api_one_locator_dump_t *mp;
17449   vl_api_control_ping_t *mp_ping;
17450   u8 is_index_set = 0, is_name_set = 0;
17451   u8 *ls_name = 0;
17452   u32 ls_index = ~0;
17453   int ret;
17454
17455   /* Parse args required to build the message */
17456   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17457     {
17458       if (unformat (input, "ls_name %_%v%_", &ls_name))
17459         {
17460           is_name_set = 1;
17461         }
17462       else if (unformat (input, "ls_index %d", &ls_index))
17463         {
17464           is_index_set = 1;
17465         }
17466       else
17467         {
17468           errmsg ("parse error '%U'", format_unformat_error, input);
17469           return -99;
17470         }
17471     }
17472
17473   if (!is_index_set && !is_name_set)
17474     {
17475       errmsg ("error: expected one of index or name!");
17476       return -99;
17477     }
17478
17479   if (is_index_set && is_name_set)
17480     {
17481       errmsg ("error: only one param expected!");
17482       return -99;
17483     }
17484
17485   if (vec_len (ls_name) > 62)
17486     {
17487       errmsg ("error: locator set name too long!");
17488       return -99;
17489     }
17490
17491   if (!vam->json_output)
17492     {
17493       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17494     }
17495
17496   M (ONE_LOCATOR_DUMP, mp);
17497   mp->is_index_set = is_index_set;
17498
17499   if (is_index_set)
17500     mp->ls_index = clib_host_to_net_u32 (ls_index);
17501   else
17502     {
17503       vec_add1 (ls_name, 0);
17504       strncpy ((char *) mp->ls_name, (char *) ls_name,
17505                sizeof (mp->ls_name) - 1);
17506     }
17507
17508   /* send it... */
17509   S (mp);
17510
17511   /* Use a control ping for synchronization */
17512   MPING (CONTROL_PING, mp_ping);
17513   S (mp_ping);
17514
17515   /* Wait for a reply... */
17516   W (ret);
17517   return ret;
17518 }
17519
17520 #define api_lisp_locator_dump api_one_locator_dump
17521
17522 static int
17523 api_one_locator_set_dump (vat_main_t * vam)
17524 {
17525   vl_api_one_locator_set_dump_t *mp;
17526   vl_api_control_ping_t *mp_ping;
17527   unformat_input_t *input = vam->input;
17528   u8 filter = 0;
17529   int ret;
17530
17531   /* Parse args required to build the message */
17532   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17533     {
17534       if (unformat (input, "local"))
17535         {
17536           filter = 1;
17537         }
17538       else if (unformat (input, "remote"))
17539         {
17540           filter = 2;
17541         }
17542       else
17543         {
17544           errmsg ("parse error '%U'", format_unformat_error, input);
17545           return -99;
17546         }
17547     }
17548
17549   if (!vam->json_output)
17550     {
17551       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
17552     }
17553
17554   M (ONE_LOCATOR_SET_DUMP, mp);
17555
17556   mp->filter = filter;
17557
17558   /* send it... */
17559   S (mp);
17560
17561   /* Use a control ping for synchronization */
17562   MPING (CONTROL_PING, mp_ping);
17563   S (mp_ping);
17564
17565   /* Wait for a reply... */
17566   W (ret);
17567   return ret;
17568 }
17569
17570 #define api_lisp_locator_set_dump api_one_locator_set_dump
17571
17572 static int
17573 api_one_eid_table_map_dump (vat_main_t * vam)
17574 {
17575   u8 is_l2 = 0;
17576   u8 mode_set = 0;
17577   unformat_input_t *input = vam->input;
17578   vl_api_one_eid_table_map_dump_t *mp;
17579   vl_api_control_ping_t *mp_ping;
17580   int ret;
17581
17582   /* Parse args required to build the message */
17583   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17584     {
17585       if (unformat (input, "l2"))
17586         {
17587           is_l2 = 1;
17588           mode_set = 1;
17589         }
17590       else if (unformat (input, "l3"))
17591         {
17592           is_l2 = 0;
17593           mode_set = 1;
17594         }
17595       else
17596         {
17597           errmsg ("parse error '%U'", format_unformat_error, input);
17598           return -99;
17599         }
17600     }
17601
17602   if (!mode_set)
17603     {
17604       errmsg ("expected one of 'l2' or 'l3' parameter!");
17605       return -99;
17606     }
17607
17608   if (!vam->json_output)
17609     {
17610       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
17611     }
17612
17613   M (ONE_EID_TABLE_MAP_DUMP, mp);
17614   mp->is_l2 = is_l2;
17615
17616   /* send it... */
17617   S (mp);
17618
17619   /* Use a control ping for synchronization */
17620   MPING (CONTROL_PING, mp_ping);
17621   S (mp_ping);
17622
17623   /* Wait for a reply... */
17624   W (ret);
17625   return ret;
17626 }
17627
17628 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
17629
17630 static int
17631 api_one_eid_table_vni_dump (vat_main_t * vam)
17632 {
17633   vl_api_one_eid_table_vni_dump_t *mp;
17634   vl_api_control_ping_t *mp_ping;
17635   int ret;
17636
17637   if (!vam->json_output)
17638     {
17639       print (vam->ofp, "VNI");
17640     }
17641
17642   M (ONE_EID_TABLE_VNI_DUMP, mp);
17643
17644   /* send it... */
17645   S (mp);
17646
17647   /* Use a control ping for synchronization */
17648   MPING (CONTROL_PING, mp_ping);
17649   S (mp_ping);
17650
17651   /* Wait for a reply... */
17652   W (ret);
17653   return ret;
17654 }
17655
17656 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
17657
17658 static int
17659 api_one_eid_table_dump (vat_main_t * vam)
17660 {
17661   unformat_input_t *i = vam->input;
17662   vl_api_one_eid_table_dump_t *mp;
17663   vl_api_control_ping_t *mp_ping;
17664   struct in_addr ip4;
17665   struct in6_addr ip6;
17666   u8 mac[6];
17667   u8 eid_type = ~0, eid_set = 0;
17668   u32 prefix_length = ~0, t, vni = 0;
17669   u8 filter = 0;
17670   int ret;
17671   lisp_nsh_api_t nsh;
17672
17673   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17674     {
17675       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
17676         {
17677           eid_set = 1;
17678           eid_type = 0;
17679           prefix_length = t;
17680         }
17681       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
17682         {
17683           eid_set = 1;
17684           eid_type = 1;
17685           prefix_length = t;
17686         }
17687       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
17688         {
17689           eid_set = 1;
17690           eid_type = 2;
17691         }
17692       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
17693         {
17694           eid_set = 1;
17695           eid_type = 3;
17696         }
17697       else if (unformat (i, "vni %d", &t))
17698         {
17699           vni = t;
17700         }
17701       else if (unformat (i, "local"))
17702         {
17703           filter = 1;
17704         }
17705       else if (unformat (i, "remote"))
17706         {
17707           filter = 2;
17708         }
17709       else
17710         {
17711           errmsg ("parse error '%U'", format_unformat_error, i);
17712           return -99;
17713         }
17714     }
17715
17716   if (!vam->json_output)
17717     {
17718       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
17719              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
17720     }
17721
17722   M (ONE_EID_TABLE_DUMP, mp);
17723
17724   mp->filter = filter;
17725   if (eid_set)
17726     {
17727       mp->eid_set = 1;
17728       mp->vni = htonl (vni);
17729       mp->eid_type = eid_type;
17730       switch (eid_type)
17731         {
17732         case 0:
17733           mp->prefix_length = prefix_length;
17734           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
17735           break;
17736         case 1:
17737           mp->prefix_length = prefix_length;
17738           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
17739           break;
17740         case 2:
17741           clib_memcpy (mp->eid, mac, sizeof (mac));
17742           break;
17743         case 3:
17744           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
17745           break;
17746         default:
17747           errmsg ("unknown EID type %d!", eid_type);
17748           return -99;
17749         }
17750     }
17751
17752   /* send it... */
17753   S (mp);
17754
17755   /* Use a control ping for synchronization */
17756   MPING (CONTROL_PING, mp_ping);
17757   S (mp_ping);
17758
17759   /* Wait for a reply... */
17760   W (ret);
17761   return ret;
17762 }
17763
17764 #define api_lisp_eid_table_dump api_one_eid_table_dump
17765
17766 static int
17767 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
17768 {
17769   unformat_input_t *i = vam->input;
17770   vl_api_gpe_fwd_entries_get_t *mp;
17771   u8 vni_set = 0;
17772   u32 vni = ~0;
17773   int ret;
17774
17775   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17776     {
17777       if (unformat (i, "vni %d", &vni))
17778         {
17779           vni_set = 1;
17780         }
17781       else
17782         {
17783           errmsg ("parse error '%U'", format_unformat_error, i);
17784           return -99;
17785         }
17786     }
17787
17788   if (!vni_set)
17789     {
17790       errmsg ("vni not set!");
17791       return -99;
17792     }
17793
17794   if (!vam->json_output)
17795     {
17796       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
17797              "leid", "reid");
17798     }
17799
17800   M (GPE_FWD_ENTRIES_GET, mp);
17801   mp->vni = clib_host_to_net_u32 (vni);
17802
17803   /* send it... */
17804   S (mp);
17805
17806   /* Wait for a reply... */
17807   W (ret);
17808   return ret;
17809 }
17810
17811 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
17812 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
17813 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
17814 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
17815 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
17816 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
17817 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
17818 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
17819
17820 static int
17821 api_one_adjacencies_get (vat_main_t * vam)
17822 {
17823   unformat_input_t *i = vam->input;
17824   vl_api_one_adjacencies_get_t *mp;
17825   u8 vni_set = 0;
17826   u32 vni = ~0;
17827   int ret;
17828
17829   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17830     {
17831       if (unformat (i, "vni %d", &vni))
17832         {
17833           vni_set = 1;
17834         }
17835       else
17836         {
17837           errmsg ("parse error '%U'", format_unformat_error, i);
17838           return -99;
17839         }
17840     }
17841
17842   if (!vni_set)
17843     {
17844       errmsg ("vni not set!");
17845       return -99;
17846     }
17847
17848   if (!vam->json_output)
17849     {
17850       print (vam->ofp, "%s %40s", "leid", "reid");
17851     }
17852
17853   M (ONE_ADJACENCIES_GET, mp);
17854   mp->vni = clib_host_to_net_u32 (vni);
17855
17856   /* send it... */
17857   S (mp);
17858
17859   /* Wait for a reply... */
17860   W (ret);
17861   return ret;
17862 }
17863
17864 #define api_lisp_adjacencies_get api_one_adjacencies_get
17865
17866 static int
17867 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
17868 {
17869   unformat_input_t *i = vam->input;
17870   vl_api_gpe_native_fwd_rpaths_get_t *mp;
17871   int ret;
17872   u8 ip_family_set = 0, is_ip4 = 1;
17873
17874   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17875     {
17876       if (unformat (i, "ip4"))
17877         {
17878           ip_family_set = 1;
17879           is_ip4 = 1;
17880         }
17881       else if (unformat (i, "ip6"))
17882         {
17883           ip_family_set = 1;
17884           is_ip4 = 0;
17885         }
17886       else
17887         {
17888           errmsg ("parse error '%U'", format_unformat_error, i);
17889           return -99;
17890         }
17891     }
17892
17893   if (!ip_family_set)
17894     {
17895       errmsg ("ip family not set!");
17896       return -99;
17897     }
17898
17899   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
17900   mp->is_ip4 = is_ip4;
17901
17902   /* send it... */
17903   S (mp);
17904
17905   /* Wait for a reply... */
17906   W (ret);
17907   return ret;
17908 }
17909
17910 static int
17911 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
17912 {
17913   vl_api_gpe_fwd_entry_vnis_get_t *mp;
17914   int ret;
17915
17916   if (!vam->json_output)
17917     {
17918       print (vam->ofp, "VNIs");
17919     }
17920
17921   M (GPE_FWD_ENTRY_VNIS_GET, mp);
17922
17923   /* send it... */
17924   S (mp);
17925
17926   /* Wait for a reply... */
17927   W (ret);
17928   return ret;
17929 }
17930
17931 static int
17932 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
17933 {
17934   unformat_input_t *i = vam->input;
17935   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
17936   int ret = 0;
17937   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
17938   struct in_addr ip4;
17939   struct in6_addr ip6;
17940   u32 table_id = 0, nh_sw_if_index = ~0;
17941
17942   clib_memset (&ip4, 0, sizeof (ip4));
17943   clib_memset (&ip6, 0, sizeof (ip6));
17944
17945   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17946     {
17947       if (unformat (i, "del"))
17948         is_add = 0;
17949       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
17950                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17951         {
17952           ip_set = 1;
17953           is_ip4 = 1;
17954         }
17955       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
17956                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17957         {
17958           ip_set = 1;
17959           is_ip4 = 0;
17960         }
17961       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
17962         {
17963           ip_set = 1;
17964           is_ip4 = 1;
17965           nh_sw_if_index = ~0;
17966         }
17967       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
17968         {
17969           ip_set = 1;
17970           is_ip4 = 0;
17971           nh_sw_if_index = ~0;
17972         }
17973       else if (unformat (i, "table %d", &table_id))
17974         ;
17975       else
17976         {
17977           errmsg ("parse error '%U'", format_unformat_error, i);
17978           return -99;
17979         }
17980     }
17981
17982   if (!ip_set)
17983     {
17984       errmsg ("nh addr not set!");
17985       return -99;
17986     }
17987
17988   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
17989   mp->is_add = is_add;
17990   mp->table_id = clib_host_to_net_u32 (table_id);
17991   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
17992   mp->is_ip4 = is_ip4;
17993   if (is_ip4)
17994     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
17995   else
17996     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
17997
17998   /* send it... */
17999   S (mp);
18000
18001   /* Wait for a reply... */
18002   W (ret);
18003   return ret;
18004 }
18005
18006 static int
18007 api_one_map_server_dump (vat_main_t * vam)
18008 {
18009   vl_api_one_map_server_dump_t *mp;
18010   vl_api_control_ping_t *mp_ping;
18011   int ret;
18012
18013   if (!vam->json_output)
18014     {
18015       print (vam->ofp, "%=20s", "Map server");
18016     }
18017
18018   M (ONE_MAP_SERVER_DUMP, mp);
18019   /* send it... */
18020   S (mp);
18021
18022   /* Use a control ping for synchronization */
18023   MPING (CONTROL_PING, mp_ping);
18024   S (mp_ping);
18025
18026   /* Wait for a reply... */
18027   W (ret);
18028   return ret;
18029 }
18030
18031 #define api_lisp_map_server_dump api_one_map_server_dump
18032
18033 static int
18034 api_one_map_resolver_dump (vat_main_t * vam)
18035 {
18036   vl_api_one_map_resolver_dump_t *mp;
18037   vl_api_control_ping_t *mp_ping;
18038   int ret;
18039
18040   if (!vam->json_output)
18041     {
18042       print (vam->ofp, "%=20s", "Map resolver");
18043     }
18044
18045   M (ONE_MAP_RESOLVER_DUMP, mp);
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   /* Wait for a reply... */
18054   W (ret);
18055   return ret;
18056 }
18057
18058 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
18059
18060 static int
18061 api_one_stats_flush (vat_main_t * vam)
18062 {
18063   vl_api_one_stats_flush_t *mp;
18064   int ret = 0;
18065
18066   M (ONE_STATS_FLUSH, mp);
18067   S (mp);
18068   W (ret);
18069   return ret;
18070 }
18071
18072 static int
18073 api_one_stats_dump (vat_main_t * vam)
18074 {
18075   vl_api_one_stats_dump_t *mp;
18076   vl_api_control_ping_t *mp_ping;
18077   int ret;
18078
18079   M (ONE_STATS_DUMP, mp);
18080   /* send it... */
18081   S (mp);
18082
18083   /* Use a control ping for synchronization */
18084   MPING (CONTROL_PING, mp_ping);
18085   S (mp_ping);
18086
18087   /* Wait for a reply... */
18088   W (ret);
18089   return ret;
18090 }
18091
18092 static int
18093 api_show_one_status (vat_main_t * vam)
18094 {
18095   vl_api_show_one_status_t *mp;
18096   int ret;
18097
18098   if (!vam->json_output)
18099     {
18100       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
18101     }
18102
18103   M (SHOW_ONE_STATUS, mp);
18104   /* send it... */
18105   S (mp);
18106   /* Wait for a reply... */
18107   W (ret);
18108   return ret;
18109 }
18110
18111 #define api_show_lisp_status api_show_one_status
18112
18113 static int
18114 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
18115 {
18116   vl_api_gpe_fwd_entry_path_dump_t *mp;
18117   vl_api_control_ping_t *mp_ping;
18118   unformat_input_t *i = vam->input;
18119   u32 fwd_entry_index = ~0;
18120   int ret;
18121
18122   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18123     {
18124       if (unformat (i, "index %d", &fwd_entry_index))
18125         ;
18126       else
18127         break;
18128     }
18129
18130   if (~0 == fwd_entry_index)
18131     {
18132       errmsg ("no index specified!");
18133       return -99;
18134     }
18135
18136   if (!vam->json_output)
18137     {
18138       print (vam->ofp, "first line");
18139     }
18140
18141   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
18142
18143   /* send it... */
18144   S (mp);
18145   /* Use a control ping for synchronization */
18146   MPING (CONTROL_PING, mp_ping);
18147   S (mp_ping);
18148
18149   /* Wait for a reply... */
18150   W (ret);
18151   return ret;
18152 }
18153
18154 static int
18155 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
18156 {
18157   vl_api_one_get_map_request_itr_rlocs_t *mp;
18158   int ret;
18159
18160   if (!vam->json_output)
18161     {
18162       print (vam->ofp, "%=20s", "itr-rlocs:");
18163     }
18164
18165   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
18166   /* send it... */
18167   S (mp);
18168   /* Wait for a reply... */
18169   W (ret);
18170   return ret;
18171 }
18172
18173 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
18174
18175 static int
18176 api_af_packet_create (vat_main_t * vam)
18177 {
18178   unformat_input_t *i = vam->input;
18179   vl_api_af_packet_create_t *mp;
18180   u8 *host_if_name = 0;
18181   u8 hw_addr[6];
18182   u8 random_hw_addr = 1;
18183   int ret;
18184
18185   clib_memset (hw_addr, 0, sizeof (hw_addr));
18186
18187   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18188     {
18189       if (unformat (i, "name %s", &host_if_name))
18190         vec_add1 (host_if_name, 0);
18191       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18192         random_hw_addr = 0;
18193       else
18194         break;
18195     }
18196
18197   if (!vec_len (host_if_name))
18198     {
18199       errmsg ("host-interface name must be specified");
18200       return -99;
18201     }
18202
18203   if (vec_len (host_if_name) > 64)
18204     {
18205       errmsg ("host-interface name too long");
18206       return -99;
18207     }
18208
18209   M (AF_PACKET_CREATE, mp);
18210
18211   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18212   clib_memcpy (mp->hw_addr, hw_addr, 6);
18213   mp->use_random_hw_addr = random_hw_addr;
18214   vec_free (host_if_name);
18215
18216   S (mp);
18217
18218   /* *INDENT-OFF* */
18219   W2 (ret,
18220       ({
18221         if (ret == 0)
18222           fprintf (vam->ofp ? vam->ofp : stderr,
18223                    " new sw_if_index = %d\n", vam->sw_if_index);
18224       }));
18225   /* *INDENT-ON* */
18226   return ret;
18227 }
18228
18229 static int
18230 api_af_packet_delete (vat_main_t * vam)
18231 {
18232   unformat_input_t *i = vam->input;
18233   vl_api_af_packet_delete_t *mp;
18234   u8 *host_if_name = 0;
18235   int ret;
18236
18237   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18238     {
18239       if (unformat (i, "name %s", &host_if_name))
18240         vec_add1 (host_if_name, 0);
18241       else
18242         break;
18243     }
18244
18245   if (!vec_len (host_if_name))
18246     {
18247       errmsg ("host-interface name must be specified");
18248       return -99;
18249     }
18250
18251   if (vec_len (host_if_name) > 64)
18252     {
18253       errmsg ("host-interface name too long");
18254       return -99;
18255     }
18256
18257   M (AF_PACKET_DELETE, mp);
18258
18259   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18260   vec_free (host_if_name);
18261
18262   S (mp);
18263   W (ret);
18264   return ret;
18265 }
18266
18267 static void vl_api_af_packet_details_t_handler
18268   (vl_api_af_packet_details_t * mp)
18269 {
18270   vat_main_t *vam = &vat_main;
18271
18272   print (vam->ofp, "%-16s %d",
18273          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
18274 }
18275
18276 static void vl_api_af_packet_details_t_handler_json
18277   (vl_api_af_packet_details_t * mp)
18278 {
18279   vat_main_t *vam = &vat_main;
18280   vat_json_node_t *node = NULL;
18281
18282   if (VAT_JSON_ARRAY != vam->json_tree.type)
18283     {
18284       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18285       vat_json_init_array (&vam->json_tree);
18286     }
18287   node = vat_json_array_add (&vam->json_tree);
18288
18289   vat_json_init_object (node);
18290   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
18291   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
18292 }
18293
18294 static int
18295 api_af_packet_dump (vat_main_t * vam)
18296 {
18297   vl_api_af_packet_dump_t *mp;
18298   vl_api_control_ping_t *mp_ping;
18299   int ret;
18300
18301   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
18302   /* Get list of tap interfaces */
18303   M (AF_PACKET_DUMP, mp);
18304   S (mp);
18305
18306   /* Use a control ping for synchronization */
18307   MPING (CONTROL_PING, mp_ping);
18308   S (mp_ping);
18309
18310   W (ret);
18311   return ret;
18312 }
18313
18314 static int
18315 api_policer_add_del (vat_main_t * vam)
18316 {
18317   unformat_input_t *i = vam->input;
18318   vl_api_policer_add_del_t *mp;
18319   u8 is_add = 1;
18320   u8 *name = 0;
18321   u32 cir = 0;
18322   u32 eir = 0;
18323   u64 cb = 0;
18324   u64 eb = 0;
18325   u8 rate_type = 0;
18326   u8 round_type = 0;
18327   u8 type = 0;
18328   u8 color_aware = 0;
18329   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
18330   int ret;
18331
18332   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
18333   conform_action.dscp = 0;
18334   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
18335   exceed_action.dscp = 0;
18336   violate_action.action_type = SSE2_QOS_ACTION_DROP;
18337   violate_action.dscp = 0;
18338
18339   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18340     {
18341       if (unformat (i, "del"))
18342         is_add = 0;
18343       else if (unformat (i, "name %s", &name))
18344         vec_add1 (name, 0);
18345       else if (unformat (i, "cir %u", &cir))
18346         ;
18347       else if (unformat (i, "eir %u", &eir))
18348         ;
18349       else if (unformat (i, "cb %u", &cb))
18350         ;
18351       else if (unformat (i, "eb %u", &eb))
18352         ;
18353       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
18354                          &rate_type))
18355         ;
18356       else if (unformat (i, "round_type %U", unformat_policer_round_type,
18357                          &round_type))
18358         ;
18359       else if (unformat (i, "type %U", unformat_policer_type, &type))
18360         ;
18361       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
18362                          &conform_action))
18363         ;
18364       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
18365                          &exceed_action))
18366         ;
18367       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
18368                          &violate_action))
18369         ;
18370       else if (unformat (i, "color-aware"))
18371         color_aware = 1;
18372       else
18373         break;
18374     }
18375
18376   if (!vec_len (name))
18377     {
18378       errmsg ("policer name must be specified");
18379       return -99;
18380     }
18381
18382   if (vec_len (name) > 64)
18383     {
18384       errmsg ("policer name too long");
18385       return -99;
18386     }
18387
18388   M (POLICER_ADD_DEL, mp);
18389
18390   clib_memcpy (mp->name, name, vec_len (name));
18391   vec_free (name);
18392   mp->is_add = is_add;
18393   mp->cir = ntohl (cir);
18394   mp->eir = ntohl (eir);
18395   mp->cb = clib_net_to_host_u64 (cb);
18396   mp->eb = clib_net_to_host_u64 (eb);
18397   mp->rate_type = rate_type;
18398   mp->round_type = round_type;
18399   mp->type = type;
18400   mp->conform_action_type = conform_action.action_type;
18401   mp->conform_dscp = conform_action.dscp;
18402   mp->exceed_action_type = exceed_action.action_type;
18403   mp->exceed_dscp = exceed_action.dscp;
18404   mp->violate_action_type = violate_action.action_type;
18405   mp->violate_dscp = violate_action.dscp;
18406   mp->color_aware = color_aware;
18407
18408   S (mp);
18409   W (ret);
18410   return ret;
18411 }
18412
18413 static int
18414 api_policer_dump (vat_main_t * vam)
18415 {
18416   unformat_input_t *i = vam->input;
18417   vl_api_policer_dump_t *mp;
18418   vl_api_control_ping_t *mp_ping;
18419   u8 *match_name = 0;
18420   u8 match_name_valid = 0;
18421   int ret;
18422
18423   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18424     {
18425       if (unformat (i, "name %s", &match_name))
18426         {
18427           vec_add1 (match_name, 0);
18428           match_name_valid = 1;
18429         }
18430       else
18431         break;
18432     }
18433
18434   M (POLICER_DUMP, mp);
18435   mp->match_name_valid = match_name_valid;
18436   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18437   vec_free (match_name);
18438   /* send it... */
18439   S (mp);
18440
18441   /* Use a control ping for synchronization */
18442   MPING (CONTROL_PING, mp_ping);
18443   S (mp_ping);
18444
18445   /* Wait for a reply... */
18446   W (ret);
18447   return ret;
18448 }
18449
18450 static int
18451 api_policer_classify_set_interface (vat_main_t * vam)
18452 {
18453   unformat_input_t *i = vam->input;
18454   vl_api_policer_classify_set_interface_t *mp;
18455   u32 sw_if_index;
18456   int sw_if_index_set;
18457   u32 ip4_table_index = ~0;
18458   u32 ip6_table_index = ~0;
18459   u32 l2_table_index = ~0;
18460   u8 is_add = 1;
18461   int ret;
18462
18463   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18464     {
18465       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18466         sw_if_index_set = 1;
18467       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18468         sw_if_index_set = 1;
18469       else if (unformat (i, "del"))
18470         is_add = 0;
18471       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18472         ;
18473       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18474         ;
18475       else if (unformat (i, "l2-table %d", &l2_table_index))
18476         ;
18477       else
18478         {
18479           clib_warning ("parse error '%U'", format_unformat_error, i);
18480           return -99;
18481         }
18482     }
18483
18484   if (sw_if_index_set == 0)
18485     {
18486       errmsg ("missing interface name or sw_if_index");
18487       return -99;
18488     }
18489
18490   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18491
18492   mp->sw_if_index = ntohl (sw_if_index);
18493   mp->ip4_table_index = ntohl (ip4_table_index);
18494   mp->ip6_table_index = ntohl (ip6_table_index);
18495   mp->l2_table_index = ntohl (l2_table_index);
18496   mp->is_add = is_add;
18497
18498   S (mp);
18499   W (ret);
18500   return ret;
18501 }
18502
18503 static int
18504 api_policer_classify_dump (vat_main_t * vam)
18505 {
18506   unformat_input_t *i = vam->input;
18507   vl_api_policer_classify_dump_t *mp;
18508   vl_api_control_ping_t *mp_ping;
18509   u8 type = POLICER_CLASSIFY_N_TABLES;
18510   int ret;
18511
18512   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
18513     ;
18514   else
18515     {
18516       errmsg ("classify table type must be specified");
18517       return -99;
18518     }
18519
18520   if (!vam->json_output)
18521     {
18522       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18523     }
18524
18525   M (POLICER_CLASSIFY_DUMP, mp);
18526   mp->type = type;
18527   /* send it... */
18528   S (mp);
18529
18530   /* Use a control ping for synchronization */
18531   MPING (CONTROL_PING, mp_ping);
18532   S (mp_ping);
18533
18534   /* Wait for a reply... */
18535   W (ret);
18536   return ret;
18537 }
18538
18539 static int
18540 api_netmap_create (vat_main_t * vam)
18541 {
18542   unformat_input_t *i = vam->input;
18543   vl_api_netmap_create_t *mp;
18544   u8 *if_name = 0;
18545   u8 hw_addr[6];
18546   u8 random_hw_addr = 1;
18547   u8 is_pipe = 0;
18548   u8 is_master = 0;
18549   int ret;
18550
18551   clib_memset (hw_addr, 0, sizeof (hw_addr));
18552
18553   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18554     {
18555       if (unformat (i, "name %s", &if_name))
18556         vec_add1 (if_name, 0);
18557       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18558         random_hw_addr = 0;
18559       else if (unformat (i, "pipe"))
18560         is_pipe = 1;
18561       else if (unformat (i, "master"))
18562         is_master = 1;
18563       else if (unformat (i, "slave"))
18564         is_master = 0;
18565       else
18566         break;
18567     }
18568
18569   if (!vec_len (if_name))
18570     {
18571       errmsg ("interface name must be specified");
18572       return -99;
18573     }
18574
18575   if (vec_len (if_name) > 64)
18576     {
18577       errmsg ("interface name too long");
18578       return -99;
18579     }
18580
18581   M (NETMAP_CREATE, mp);
18582
18583   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18584   clib_memcpy (mp->hw_addr, hw_addr, 6);
18585   mp->use_random_hw_addr = random_hw_addr;
18586   mp->is_pipe = is_pipe;
18587   mp->is_master = is_master;
18588   vec_free (if_name);
18589
18590   S (mp);
18591   W (ret);
18592   return ret;
18593 }
18594
18595 static int
18596 api_netmap_delete (vat_main_t * vam)
18597 {
18598   unformat_input_t *i = vam->input;
18599   vl_api_netmap_delete_t *mp;
18600   u8 *if_name = 0;
18601   int ret;
18602
18603   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18604     {
18605       if (unformat (i, "name %s", &if_name))
18606         vec_add1 (if_name, 0);
18607       else
18608         break;
18609     }
18610
18611   if (!vec_len (if_name))
18612     {
18613       errmsg ("interface name must be specified");
18614       return -99;
18615     }
18616
18617   if (vec_len (if_name) > 64)
18618     {
18619       errmsg ("interface name too long");
18620       return -99;
18621     }
18622
18623   M (NETMAP_DELETE, mp);
18624
18625   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18626   vec_free (if_name);
18627
18628   S (mp);
18629   W (ret);
18630   return ret;
18631 }
18632
18633 static u8 *
18634 format_fib_api_path_nh_proto (u8 * s, va_list * args)
18635 {
18636   vl_api_fib_path_nh_proto_t proto =
18637     va_arg (*args, vl_api_fib_path_nh_proto_t);
18638
18639   switch (proto)
18640     {
18641     case FIB_API_PATH_NH_PROTO_IP4:
18642       s = format (s, "ip4");
18643       break;
18644     case FIB_API_PATH_NH_PROTO_IP6:
18645       s = format (s, "ip6");
18646       break;
18647     case FIB_API_PATH_NH_PROTO_MPLS:
18648       s = format (s, "mpls");
18649       break;
18650     case FIB_API_PATH_NH_PROTO_BIER:
18651       s = format (s, "bier");
18652       break;
18653     case FIB_API_PATH_NH_PROTO_ETHERNET:
18654       s = format (s, "ethernet");
18655       break;
18656     }
18657
18658   return (s);
18659 }
18660
18661 static u8 *
18662 format_vl_api_ip_address_union (u8 * s, va_list * args)
18663 {
18664   vl_api_address_family_t af = va_arg (*args, vl_api_address_family_t);
18665   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
18666
18667   switch (af)
18668     {
18669     case ADDRESS_IP4:
18670       s = format (s, "%U", format_ip4_address, u->ip4);
18671       break;
18672     case ADDRESS_IP6:
18673       s = format (s, "%U", format_ip6_address, u->ip6);
18674       break;
18675     }
18676   return (s);
18677 }
18678
18679 static u8 *
18680 format_vl_api_fib_path_type (u8 * s, va_list * args)
18681 {
18682   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
18683
18684   switch (t)
18685     {
18686     case FIB_API_PATH_TYPE_NORMAL:
18687       s = format (s, "normal");
18688       break;
18689     case FIB_API_PATH_TYPE_LOCAL:
18690       s = format (s, "local");
18691       break;
18692     case FIB_API_PATH_TYPE_DROP:
18693       s = format (s, "drop");
18694       break;
18695     case FIB_API_PATH_TYPE_UDP_ENCAP:
18696       s = format (s, "udp-encap");
18697       break;
18698     case FIB_API_PATH_TYPE_BIER_IMP:
18699       s = format (s, "bier-imp");
18700       break;
18701     case FIB_API_PATH_TYPE_ICMP_UNREACH:
18702       s = format (s, "unreach");
18703       break;
18704     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
18705       s = format (s, "prohibit");
18706       break;
18707     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
18708       s = format (s, "src-lookup");
18709       break;
18710     case FIB_API_PATH_TYPE_DVR:
18711       s = format (s, "dvr");
18712       break;
18713     case FIB_API_PATH_TYPE_INTERFACE_RX:
18714       s = format (s, "interface-rx");
18715       break;
18716     case FIB_API_PATH_TYPE_CLASSIFY:
18717       s = format (s, "classify");
18718       break;
18719     }
18720
18721   return (s);
18722 }
18723
18724 static void
18725 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
18726 {
18727   print (vam->ofp,
18728          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
18729          ntohl (fp->weight), ntohl (fp->sw_if_index),
18730          format_vl_api_fib_path_type, fp->type,
18731          format_fib_api_path_nh_proto, fp->proto,
18732          format_vl_api_ip_address_union, &fp->nh.address);
18733 }
18734
18735 static void
18736 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
18737                                  vl_api_fib_path_t * fp)
18738 {
18739   struct in_addr ip4;
18740   struct in6_addr ip6;
18741
18742   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18743   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18744   vat_json_object_add_uint (node, "type", fp->type);
18745   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
18746   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18747     {
18748       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
18749       vat_json_object_add_ip4 (node, "next_hop", ip4);
18750     }
18751   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18752     {
18753       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
18754       vat_json_object_add_ip6 (node, "next_hop", ip6);
18755     }
18756 }
18757
18758 static void
18759 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
18760 {
18761   vat_main_t *vam = &vat_main;
18762   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18763   vl_api_fib_path_t *fp;
18764   i32 i;
18765
18766   print (vam->ofp, "sw_if_index %d via:",
18767          ntohl (mp->mt_tunnel.mt_sw_if_index));
18768   fp = mp->mt_tunnel.mt_paths;
18769   for (i = 0; i < count; i++)
18770     {
18771       vl_api_fib_path_print (vam, fp);
18772       fp++;
18773     }
18774
18775   print (vam->ofp, "");
18776 }
18777
18778 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
18779 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
18780
18781 static void
18782 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
18783 {
18784   vat_main_t *vam = &vat_main;
18785   vat_json_node_t *node = NULL;
18786   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18787   vl_api_fib_path_t *fp;
18788   i32 i;
18789
18790   if (VAT_JSON_ARRAY != vam->json_tree.type)
18791     {
18792       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18793       vat_json_init_array (&vam->json_tree);
18794     }
18795   node = vat_json_array_add (&vam->json_tree);
18796
18797   vat_json_init_object (node);
18798   vat_json_object_add_uint (node, "sw_if_index",
18799                             ntohl (mp->mt_tunnel.mt_sw_if_index));
18800
18801   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
18802
18803   fp = mp->mt_tunnel.mt_paths;
18804   for (i = 0; i < count; i++)
18805     {
18806       vl_api_mpls_fib_path_json_print (node, fp);
18807       fp++;
18808     }
18809 }
18810
18811 static int
18812 api_mpls_tunnel_dump (vat_main_t * vam)
18813 {
18814   vl_api_mpls_tunnel_dump_t *mp;
18815   vl_api_control_ping_t *mp_ping;
18816   int ret;
18817
18818   M (MPLS_TUNNEL_DUMP, mp);
18819
18820   S (mp);
18821
18822   /* Use a control ping for synchronization */
18823   MPING (CONTROL_PING, mp_ping);
18824   S (mp_ping);
18825
18826   W (ret);
18827   return ret;
18828 }
18829
18830 #define vl_api_mpls_table_details_t_endian vl_noop_handler
18831 #define vl_api_mpls_table_details_t_print vl_noop_handler
18832
18833
18834 static void
18835 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
18836 {
18837   vat_main_t *vam = &vat_main;
18838
18839   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
18840 }
18841
18842 static void vl_api_mpls_table_details_t_handler_json
18843   (vl_api_mpls_table_details_t * mp)
18844 {
18845   vat_main_t *vam = &vat_main;
18846   vat_json_node_t *node = NULL;
18847
18848   if (VAT_JSON_ARRAY != vam->json_tree.type)
18849     {
18850       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18851       vat_json_init_array (&vam->json_tree);
18852     }
18853   node = vat_json_array_add (&vam->json_tree);
18854
18855   vat_json_init_object (node);
18856   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
18857 }
18858
18859 static int
18860 api_mpls_table_dump (vat_main_t * vam)
18861 {
18862   vl_api_mpls_table_dump_t *mp;
18863   vl_api_control_ping_t *mp_ping;
18864   int ret;
18865
18866   M (MPLS_TABLE_DUMP, mp);
18867   S (mp);
18868
18869   /* Use a control ping for synchronization */
18870   MPING (CONTROL_PING, mp_ping);
18871   S (mp_ping);
18872
18873   W (ret);
18874   return ret;
18875 }
18876
18877 #define vl_api_mpls_route_details_t_endian vl_noop_handler
18878 #define vl_api_mpls_route_details_t_print vl_noop_handler
18879
18880 static void
18881 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
18882 {
18883   vat_main_t *vam = &vat_main;
18884   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
18885   vl_api_fib_path_t *fp;
18886   int i;
18887
18888   print (vam->ofp,
18889          "table-id %d, label %u, ess_bit %u",
18890          ntohl (mp->mr_route.mr_table_id),
18891          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
18892   fp = mp->mr_route.mr_paths;
18893   for (i = 0; i < count; i++)
18894     {
18895       vl_api_fib_path_print (vam, fp);
18896       fp++;
18897     }
18898 }
18899
18900 static void vl_api_mpls_route_details_t_handler_json
18901   (vl_api_mpls_route_details_t * mp)
18902 {
18903   vat_main_t *vam = &vat_main;
18904   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
18905   vat_json_node_t *node = NULL;
18906   vl_api_fib_path_t *fp;
18907   int i;
18908
18909   if (VAT_JSON_ARRAY != vam->json_tree.type)
18910     {
18911       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18912       vat_json_init_array (&vam->json_tree);
18913     }
18914   node = vat_json_array_add (&vam->json_tree);
18915
18916   vat_json_init_object (node);
18917   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
18918   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
18919   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
18920   vat_json_object_add_uint (node, "path_count", count);
18921   fp = mp->mr_route.mr_paths;
18922   for (i = 0; i < count; i++)
18923     {
18924       vl_api_mpls_fib_path_json_print (node, fp);
18925       fp++;
18926     }
18927 }
18928
18929 static int
18930 api_mpls_route_dump (vat_main_t * vam)
18931 {
18932   unformat_input_t *input = vam->input;
18933   vl_api_mpls_route_dump_t *mp;
18934   vl_api_control_ping_t *mp_ping;
18935   u32 table_id;
18936   int ret;
18937
18938   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18939     {
18940       if (unformat (input, "table_id %d", &table_id))
18941         ;
18942       else
18943         break;
18944     }
18945   if (table_id == ~0)
18946     {
18947       errmsg ("missing table id");
18948       return -99;
18949     }
18950
18951   M (MPLS_ROUTE_DUMP, mp);
18952
18953   mp->table.mt_table_id = ntohl (table_id);
18954   S (mp);
18955
18956   /* Use a control ping for synchronization */
18957   MPING (CONTROL_PING, mp_ping);
18958   S (mp_ping);
18959
18960   W (ret);
18961   return ret;
18962 }
18963
18964 #define vl_api_ip_table_details_t_endian vl_noop_handler
18965 #define vl_api_ip_table_details_t_print vl_noop_handler
18966
18967 static void
18968 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
18969 {
18970   vat_main_t *vam = &vat_main;
18971
18972   print (vam->ofp,
18973          "%s; table-id %d, prefix %U/%d",
18974          mp->table.name, ntohl (mp->table.table_id));
18975 }
18976
18977
18978 static void vl_api_ip_table_details_t_handler_json
18979   (vl_api_ip_table_details_t * mp)
18980 {
18981   vat_main_t *vam = &vat_main;
18982   vat_json_node_t *node = NULL;
18983
18984   if (VAT_JSON_ARRAY != vam->json_tree.type)
18985     {
18986       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18987       vat_json_init_array (&vam->json_tree);
18988     }
18989   node = vat_json_array_add (&vam->json_tree);
18990
18991   vat_json_init_object (node);
18992   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
18993 }
18994
18995 static int
18996 api_ip_table_dump (vat_main_t * vam)
18997 {
18998   vl_api_ip_table_dump_t *mp;
18999   vl_api_control_ping_t *mp_ping;
19000   int ret;
19001
19002   M (IP_TABLE_DUMP, mp);
19003   S (mp);
19004
19005   /* Use a control ping for synchronization */
19006   MPING (CONTROL_PING, mp_ping);
19007   S (mp_ping);
19008
19009   W (ret);
19010   return ret;
19011 }
19012
19013 static int
19014 api_ip_mtable_dump (vat_main_t * vam)
19015 {
19016   vl_api_ip_mtable_dump_t *mp;
19017   vl_api_control_ping_t *mp_ping;
19018   int ret;
19019
19020   M (IP_MTABLE_DUMP, mp);
19021   S (mp);
19022
19023   /* Use a control ping for synchronization */
19024   MPING (CONTROL_PING, mp_ping);
19025   S (mp_ping);
19026
19027   W (ret);
19028   return ret;
19029 }
19030
19031 static int
19032 api_ip_mroute_dump (vat_main_t * vam)
19033 {
19034   unformat_input_t *input = vam->input;
19035   vl_api_control_ping_t *mp_ping;
19036   vl_api_ip_mroute_dump_t *mp;
19037   int ret, is_ip6;
19038   u32 table_id;
19039
19040   is_ip6 = 0;
19041   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19042     {
19043       if (unformat (input, "table_id %d", &table_id))
19044         ;
19045       else if (unformat (input, "ip6"))
19046         is_ip6 = 1;
19047       else if (unformat (input, "ip4"))
19048         is_ip6 = 0;
19049       else
19050         break;
19051     }
19052   if (table_id == ~0)
19053     {
19054       errmsg ("missing table id");
19055       return -99;
19056     }
19057
19058   M (IP_MROUTE_DUMP, mp);
19059   mp->table.table_id = table_id;
19060   mp->table.is_ip6 = is_ip6;
19061   S (mp);
19062
19063   /* Use a control ping for synchronization */
19064   MPING (CONTROL_PING, mp_ping);
19065   S (mp_ping);
19066
19067   W (ret);
19068   return ret;
19069 }
19070
19071 static void vl_api_ip_neighbor_details_t_handler
19072   (vl_api_ip_neighbor_details_t * mp)
19073 {
19074   vat_main_t *vam = &vat_main;
19075
19076   print (vam->ofp, "%c %U %U",
19077          (ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ? 'S' : 'D',
19078          format_vl_api_mac_address, &mp->neighbor.mac_address,
19079          format_vl_api_address, &mp->neighbor.ip_address);
19080 }
19081
19082 static void vl_api_ip_neighbor_details_t_handler_json
19083   (vl_api_ip_neighbor_details_t * mp)
19084 {
19085
19086   vat_main_t *vam = &vat_main;
19087   vat_json_node_t *node;
19088
19089   if (VAT_JSON_ARRAY != vam->json_tree.type)
19090     {
19091       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19092       vat_json_init_array (&vam->json_tree);
19093     }
19094   node = vat_json_array_add (&vam->json_tree);
19095
19096   vat_json_init_object (node);
19097   vat_json_object_add_string_copy
19098     (node, "flag",
19099      ((ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ?
19100       (u8 *) "static" : (u8 *) "dynamic"));
19101
19102   vat_json_object_add_string_copy (node, "link_layer",
19103                                    format (0, "%U", format_vl_api_mac_address,
19104                                            &mp->neighbor.mac_address));
19105   vat_json_object_add_address (node, "ip", &mp->neighbor.ip_address);
19106 }
19107
19108 static int
19109 api_ip_neighbor_dump (vat_main_t * vam)
19110 {
19111   unformat_input_t *i = vam->input;
19112   vl_api_ip_neighbor_dump_t *mp;
19113   vl_api_control_ping_t *mp_ping;
19114   u8 is_ipv6 = 0;
19115   u32 sw_if_index = ~0;
19116   int ret;
19117
19118   /* Parse args required to build the message */
19119   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19120     {
19121       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19122         ;
19123       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19124         ;
19125       else if (unformat (i, "ip6"))
19126         is_ipv6 = 1;
19127       else
19128         break;
19129     }
19130
19131   if (sw_if_index == ~0)
19132     {
19133       errmsg ("missing interface name or sw_if_index");
19134       return -99;
19135     }
19136
19137   M (IP_NEIGHBOR_DUMP, mp);
19138   mp->is_ipv6 = (u8) is_ipv6;
19139   mp->sw_if_index = ntohl (sw_if_index);
19140   S (mp);
19141
19142   /* Use a control ping for synchronization */
19143   MPING (CONTROL_PING, mp_ping);
19144   S (mp_ping);
19145
19146   W (ret);
19147   return ret;
19148 }
19149
19150 #define vl_api_ip_route_details_t_endian vl_noop_handler
19151 #define vl_api_ip_route_details_t_print vl_noop_handler
19152
19153 static void
19154 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
19155 {
19156   vat_main_t *vam = &vat_main;
19157   u8 count = mp->route.n_paths;
19158   vl_api_fib_path_t *fp;
19159   int i;
19160
19161   print (vam->ofp,
19162          "table-id %d, prefix %U/%d",
19163          ntohl (mp->route.table_id),
19164          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
19165   for (i = 0; i < count; i++)
19166     {
19167       fp = &mp->route.paths[i];
19168
19169       vl_api_fib_path_print (vam, fp);
19170       fp++;
19171     }
19172 }
19173
19174 static void vl_api_ip_route_details_t_handler_json
19175   (vl_api_ip_route_details_t * mp)
19176 {
19177   vat_main_t *vam = &vat_main;
19178   u8 count = mp->route.n_paths;
19179   vat_json_node_t *node = NULL;
19180   struct in_addr ip4;
19181   struct in6_addr ip6;
19182   vl_api_fib_path_t *fp;
19183   int i;
19184
19185   if (VAT_JSON_ARRAY != vam->json_tree.type)
19186     {
19187       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19188       vat_json_init_array (&vam->json_tree);
19189     }
19190   node = vat_json_array_add (&vam->json_tree);
19191
19192   vat_json_init_object (node);
19193   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
19194   if (ADDRESS_IP6 == mp->route.prefix.address.af)
19195     {
19196       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
19197       vat_json_object_add_ip6 (node, "prefix", ip6);
19198     }
19199   else
19200     {
19201       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
19202       vat_json_object_add_ip4 (node, "prefix", ip4);
19203     }
19204   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
19205   vat_json_object_add_uint (node, "path_count", count);
19206   for (i = 0; i < count; i++)
19207     {
19208       fp = &mp->route.paths[i];
19209       vl_api_mpls_fib_path_json_print (node, fp);
19210     }
19211 }
19212
19213 static int
19214 api_ip_route_dump (vat_main_t * vam)
19215 {
19216   unformat_input_t *input = vam->input;
19217   vl_api_ip_route_dump_t *mp;
19218   vl_api_control_ping_t *mp_ping;
19219   u32 table_id;
19220   u8 is_ip6;
19221   int ret;
19222
19223   is_ip6 = 0;
19224   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19225     {
19226       if (unformat (input, "table_id %d", &table_id))
19227         ;
19228       else if (unformat (input, "ip6"))
19229         is_ip6 = 1;
19230       else if (unformat (input, "ip4"))
19231         is_ip6 = 0;
19232       else
19233         break;
19234     }
19235   if (table_id == ~0)
19236     {
19237       errmsg ("missing table id");
19238       return -99;
19239     }
19240
19241   M (IP_ROUTE_DUMP, mp);
19242
19243   mp->table.table_id = table_id;
19244   mp->table.is_ip6 = is_ip6;
19245
19246   S (mp);
19247
19248   /* Use a control ping for synchronization */
19249   MPING (CONTROL_PING, mp_ping);
19250   S (mp_ping);
19251
19252   W (ret);
19253   return ret;
19254 }
19255
19256 int
19257 api_classify_table_ids (vat_main_t * vam)
19258 {
19259   vl_api_classify_table_ids_t *mp;
19260   int ret;
19261
19262   /* Construct the API message */
19263   M (CLASSIFY_TABLE_IDS, mp);
19264   mp->context = 0;
19265
19266   S (mp);
19267   W (ret);
19268   return ret;
19269 }
19270
19271 int
19272 api_classify_table_by_interface (vat_main_t * vam)
19273 {
19274   unformat_input_t *input = vam->input;
19275   vl_api_classify_table_by_interface_t *mp;
19276
19277   u32 sw_if_index = ~0;
19278   int ret;
19279   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19280     {
19281       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19282         ;
19283       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19284         ;
19285       else
19286         break;
19287     }
19288   if (sw_if_index == ~0)
19289     {
19290       errmsg ("missing interface name or sw_if_index");
19291       return -99;
19292     }
19293
19294   /* Construct the API message */
19295   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
19296   mp->context = 0;
19297   mp->sw_if_index = ntohl (sw_if_index);
19298
19299   S (mp);
19300   W (ret);
19301   return ret;
19302 }
19303
19304 int
19305 api_classify_table_info (vat_main_t * vam)
19306 {
19307   unformat_input_t *input = vam->input;
19308   vl_api_classify_table_info_t *mp;
19309
19310   u32 table_id = ~0;
19311   int ret;
19312   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19313     {
19314       if (unformat (input, "table_id %d", &table_id))
19315         ;
19316       else
19317         break;
19318     }
19319   if (table_id == ~0)
19320     {
19321       errmsg ("missing table id");
19322       return -99;
19323     }
19324
19325   /* Construct the API message */
19326   M (CLASSIFY_TABLE_INFO, mp);
19327   mp->context = 0;
19328   mp->table_id = ntohl (table_id);
19329
19330   S (mp);
19331   W (ret);
19332   return ret;
19333 }
19334
19335 int
19336 api_classify_session_dump (vat_main_t * vam)
19337 {
19338   unformat_input_t *input = vam->input;
19339   vl_api_classify_session_dump_t *mp;
19340   vl_api_control_ping_t *mp_ping;
19341
19342   u32 table_id = ~0;
19343   int ret;
19344   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19345     {
19346       if (unformat (input, "table_id %d", &table_id))
19347         ;
19348       else
19349         break;
19350     }
19351   if (table_id == ~0)
19352     {
19353       errmsg ("missing table id");
19354       return -99;
19355     }
19356
19357   /* Construct the API message */
19358   M (CLASSIFY_SESSION_DUMP, mp);
19359   mp->context = 0;
19360   mp->table_id = ntohl (table_id);
19361   S (mp);
19362
19363   /* Use a control ping for synchronization */
19364   MPING (CONTROL_PING, mp_ping);
19365   S (mp_ping);
19366
19367   W (ret);
19368   return ret;
19369 }
19370
19371 static void
19372 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19373 {
19374   vat_main_t *vam = &vat_main;
19375
19376   print (vam->ofp, "collector_address %U, collector_port %d, "
19377          "src_address %U, vrf_id %d, path_mtu %u, "
19378          "template_interval %u, udp_checksum %d",
19379          format_ip4_address, mp->collector_address,
19380          ntohs (mp->collector_port),
19381          format_ip4_address, mp->src_address,
19382          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19383          ntohl (mp->template_interval), mp->udp_checksum);
19384
19385   vam->retval = 0;
19386   vam->result_ready = 1;
19387 }
19388
19389 static void
19390   vl_api_ipfix_exporter_details_t_handler_json
19391   (vl_api_ipfix_exporter_details_t * mp)
19392 {
19393   vat_main_t *vam = &vat_main;
19394   vat_json_node_t node;
19395   struct in_addr collector_address;
19396   struct in_addr src_address;
19397
19398   vat_json_init_object (&node);
19399   clib_memcpy (&collector_address, &mp->collector_address,
19400                sizeof (collector_address));
19401   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19402   vat_json_object_add_uint (&node, "collector_port",
19403                             ntohs (mp->collector_port));
19404   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19405   vat_json_object_add_ip4 (&node, "src_address", src_address);
19406   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19407   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19408   vat_json_object_add_uint (&node, "template_interval",
19409                             ntohl (mp->template_interval));
19410   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19411
19412   vat_json_print (vam->ofp, &node);
19413   vat_json_free (&node);
19414   vam->retval = 0;
19415   vam->result_ready = 1;
19416 }
19417
19418 int
19419 api_ipfix_exporter_dump (vat_main_t * vam)
19420 {
19421   vl_api_ipfix_exporter_dump_t *mp;
19422   int ret;
19423
19424   /* Construct the API message */
19425   M (IPFIX_EXPORTER_DUMP, mp);
19426   mp->context = 0;
19427
19428   S (mp);
19429   W (ret);
19430   return ret;
19431 }
19432
19433 static int
19434 api_ipfix_classify_stream_dump (vat_main_t * vam)
19435 {
19436   vl_api_ipfix_classify_stream_dump_t *mp;
19437   int ret;
19438
19439   /* Construct the API message */
19440   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19441   mp->context = 0;
19442
19443   S (mp);
19444   W (ret);
19445   return ret;
19446   /* NOTREACHED */
19447   return 0;
19448 }
19449
19450 static void
19451   vl_api_ipfix_classify_stream_details_t_handler
19452   (vl_api_ipfix_classify_stream_details_t * mp)
19453 {
19454   vat_main_t *vam = &vat_main;
19455   print (vam->ofp, "domain_id %d, src_port %d",
19456          ntohl (mp->domain_id), ntohs (mp->src_port));
19457   vam->retval = 0;
19458   vam->result_ready = 1;
19459 }
19460
19461 static void
19462   vl_api_ipfix_classify_stream_details_t_handler_json
19463   (vl_api_ipfix_classify_stream_details_t * mp)
19464 {
19465   vat_main_t *vam = &vat_main;
19466   vat_json_node_t node;
19467
19468   vat_json_init_object (&node);
19469   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19470   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19471
19472   vat_json_print (vam->ofp, &node);
19473   vat_json_free (&node);
19474   vam->retval = 0;
19475   vam->result_ready = 1;
19476 }
19477
19478 static int
19479 api_ipfix_classify_table_dump (vat_main_t * vam)
19480 {
19481   vl_api_ipfix_classify_table_dump_t *mp;
19482   vl_api_control_ping_t *mp_ping;
19483   int ret;
19484
19485   if (!vam->json_output)
19486     {
19487       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19488              "transport_protocol");
19489     }
19490
19491   /* Construct the API message */
19492   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19493
19494   /* send it... */
19495   S (mp);
19496
19497   /* Use a control ping for synchronization */
19498   MPING (CONTROL_PING, mp_ping);
19499   S (mp_ping);
19500
19501   W (ret);
19502   return ret;
19503 }
19504
19505 static void
19506   vl_api_ipfix_classify_table_details_t_handler
19507   (vl_api_ipfix_classify_table_details_t * mp)
19508 {
19509   vat_main_t *vam = &vat_main;
19510   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19511          mp->transport_protocol);
19512 }
19513
19514 static void
19515   vl_api_ipfix_classify_table_details_t_handler_json
19516   (vl_api_ipfix_classify_table_details_t * mp)
19517 {
19518   vat_json_node_t *node = NULL;
19519   vat_main_t *vam = &vat_main;
19520
19521   if (VAT_JSON_ARRAY != vam->json_tree.type)
19522     {
19523       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19524       vat_json_init_array (&vam->json_tree);
19525     }
19526
19527   node = vat_json_array_add (&vam->json_tree);
19528   vat_json_init_object (node);
19529
19530   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19531   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19532   vat_json_object_add_uint (node, "transport_protocol",
19533                             mp->transport_protocol);
19534 }
19535
19536 static int
19537 api_sw_interface_span_enable_disable (vat_main_t * vam)
19538 {
19539   unformat_input_t *i = vam->input;
19540   vl_api_sw_interface_span_enable_disable_t *mp;
19541   u32 src_sw_if_index = ~0;
19542   u32 dst_sw_if_index = ~0;
19543   u8 state = 3;
19544   int ret;
19545   u8 is_l2 = 0;
19546
19547   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19548     {
19549       if (unformat
19550           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19551         ;
19552       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19553         ;
19554       else
19555         if (unformat
19556             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19557         ;
19558       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19559         ;
19560       else if (unformat (i, "disable"))
19561         state = 0;
19562       else if (unformat (i, "rx"))
19563         state = 1;
19564       else if (unformat (i, "tx"))
19565         state = 2;
19566       else if (unformat (i, "both"))
19567         state = 3;
19568       else if (unformat (i, "l2"))
19569         is_l2 = 1;
19570       else
19571         break;
19572     }
19573
19574   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19575
19576   mp->sw_if_index_from = htonl (src_sw_if_index);
19577   mp->sw_if_index_to = htonl (dst_sw_if_index);
19578   mp->state = state;
19579   mp->is_l2 = is_l2;
19580
19581   S (mp);
19582   W (ret);
19583   return ret;
19584 }
19585
19586 static void
19587 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19588                                             * mp)
19589 {
19590   vat_main_t *vam = &vat_main;
19591   u8 *sw_if_from_name = 0;
19592   u8 *sw_if_to_name = 0;
19593   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19594   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19595   char *states[] = { "none", "rx", "tx", "both" };
19596   hash_pair_t *p;
19597
19598   /* *INDENT-OFF* */
19599   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19600   ({
19601     if ((u32) p->value[0] == sw_if_index_from)
19602       {
19603         sw_if_from_name = (u8 *)(p->key);
19604         if (sw_if_to_name)
19605           break;
19606       }
19607     if ((u32) p->value[0] == sw_if_index_to)
19608       {
19609         sw_if_to_name = (u8 *)(p->key);
19610         if (sw_if_from_name)
19611           break;
19612       }
19613   }));
19614   /* *INDENT-ON* */
19615   print (vam->ofp, "%20s => %20s (%s) %s",
19616          sw_if_from_name, sw_if_to_name, states[mp->state],
19617          mp->is_l2 ? "l2" : "device");
19618 }
19619
19620 static void
19621   vl_api_sw_interface_span_details_t_handler_json
19622   (vl_api_sw_interface_span_details_t * mp)
19623 {
19624   vat_main_t *vam = &vat_main;
19625   vat_json_node_t *node = NULL;
19626   u8 *sw_if_from_name = 0;
19627   u8 *sw_if_to_name = 0;
19628   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19629   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19630   hash_pair_t *p;
19631
19632   /* *INDENT-OFF* */
19633   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19634   ({
19635     if ((u32) p->value[0] == sw_if_index_from)
19636       {
19637         sw_if_from_name = (u8 *)(p->key);
19638         if (sw_if_to_name)
19639           break;
19640       }
19641     if ((u32) p->value[0] == sw_if_index_to)
19642       {
19643         sw_if_to_name = (u8 *)(p->key);
19644         if (sw_if_from_name)
19645           break;
19646       }
19647   }));
19648   /* *INDENT-ON* */
19649
19650   if (VAT_JSON_ARRAY != vam->json_tree.type)
19651     {
19652       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19653       vat_json_init_array (&vam->json_tree);
19654     }
19655   node = vat_json_array_add (&vam->json_tree);
19656
19657   vat_json_init_object (node);
19658   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
19659   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
19660   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
19661   if (0 != sw_if_to_name)
19662     {
19663       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
19664     }
19665   vat_json_object_add_uint (node, "state", mp->state);
19666   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
19667 }
19668
19669 static int
19670 api_sw_interface_span_dump (vat_main_t * vam)
19671 {
19672   unformat_input_t *input = vam->input;
19673   vl_api_sw_interface_span_dump_t *mp;
19674   vl_api_control_ping_t *mp_ping;
19675   u8 is_l2 = 0;
19676   int ret;
19677
19678   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19679     {
19680       if (unformat (input, "l2"))
19681         is_l2 = 1;
19682       else
19683         break;
19684     }
19685
19686   M (SW_INTERFACE_SPAN_DUMP, mp);
19687   mp->is_l2 = is_l2;
19688   S (mp);
19689
19690   /* Use a control ping for synchronization */
19691   MPING (CONTROL_PING, mp_ping);
19692   S (mp_ping);
19693
19694   W (ret);
19695   return ret;
19696 }
19697
19698 int
19699 api_pg_create_interface (vat_main_t * vam)
19700 {
19701   unformat_input_t *input = vam->input;
19702   vl_api_pg_create_interface_t *mp;
19703
19704   u32 if_id = ~0, gso_size = 0;
19705   u8 gso_enabled = 0;
19706   int ret;
19707   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19708     {
19709       if (unformat (input, "if_id %d", &if_id))
19710         ;
19711       else if (unformat (input, "gso-enabled"))
19712         {
19713           gso_enabled = 1;
19714           if (unformat (input, "gso-size %u", &gso_size))
19715             ;
19716           else
19717             {
19718               errmsg ("missing gso-size");
19719               return -99;
19720             }
19721         }
19722       else
19723         break;
19724     }
19725   if (if_id == ~0)
19726     {
19727       errmsg ("missing pg interface index");
19728       return -99;
19729     }
19730
19731   /* Construct the API message */
19732   M (PG_CREATE_INTERFACE, mp);
19733   mp->context = 0;
19734   mp->interface_id = ntohl (if_id);
19735   mp->gso_enabled = gso_enabled;
19736
19737   S (mp);
19738   W (ret);
19739   return ret;
19740 }
19741
19742 int
19743 api_pg_capture (vat_main_t * vam)
19744 {
19745   unformat_input_t *input = vam->input;
19746   vl_api_pg_capture_t *mp;
19747
19748   u32 if_id = ~0;
19749   u8 enable = 1;
19750   u32 count = 1;
19751   u8 pcap_file_set = 0;
19752   u8 *pcap_file = 0;
19753   int ret;
19754   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19755     {
19756       if (unformat (input, "if_id %d", &if_id))
19757         ;
19758       else if (unformat (input, "pcap %s", &pcap_file))
19759         pcap_file_set = 1;
19760       else if (unformat (input, "count %d", &count))
19761         ;
19762       else if (unformat (input, "disable"))
19763         enable = 0;
19764       else
19765         break;
19766     }
19767   if (if_id == ~0)
19768     {
19769       errmsg ("missing pg interface index");
19770       return -99;
19771     }
19772   if (pcap_file_set > 0)
19773     {
19774       if (vec_len (pcap_file) > 255)
19775         {
19776           errmsg ("pcap file name is too long");
19777           return -99;
19778         }
19779     }
19780
19781   u32 name_len = vec_len (pcap_file);
19782   /* Construct the API message */
19783   M (PG_CAPTURE, mp);
19784   mp->context = 0;
19785   mp->interface_id = ntohl (if_id);
19786   mp->is_enabled = enable;
19787   mp->count = ntohl (count);
19788   mp->pcap_name_length = ntohl (name_len);
19789   if (pcap_file_set != 0)
19790     {
19791       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
19792     }
19793   vec_free (pcap_file);
19794
19795   S (mp);
19796   W (ret);
19797   return ret;
19798 }
19799
19800 int
19801 api_pg_enable_disable (vat_main_t * vam)
19802 {
19803   unformat_input_t *input = vam->input;
19804   vl_api_pg_enable_disable_t *mp;
19805
19806   u8 enable = 1;
19807   u8 stream_name_set = 0;
19808   u8 *stream_name = 0;
19809   int ret;
19810   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19811     {
19812       if (unformat (input, "stream %s", &stream_name))
19813         stream_name_set = 1;
19814       else if (unformat (input, "disable"))
19815         enable = 0;
19816       else
19817         break;
19818     }
19819
19820   if (stream_name_set > 0)
19821     {
19822       if (vec_len (stream_name) > 255)
19823         {
19824           errmsg ("stream name too long");
19825           return -99;
19826         }
19827     }
19828
19829   u32 name_len = vec_len (stream_name);
19830   /* Construct the API message */
19831   M (PG_ENABLE_DISABLE, mp);
19832   mp->context = 0;
19833   mp->is_enabled = enable;
19834   if (stream_name_set != 0)
19835     {
19836       mp->stream_name_length = ntohl (name_len);
19837       clib_memcpy (mp->stream_name, stream_name, name_len);
19838     }
19839   vec_free (stream_name);
19840
19841   S (mp);
19842   W (ret);
19843   return ret;
19844 }
19845
19846 int
19847 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
19848 {
19849   unformat_input_t *input = vam->input;
19850   vl_api_ip_source_and_port_range_check_add_del_t *mp;
19851
19852   u16 *low_ports = 0;
19853   u16 *high_ports = 0;
19854   u16 this_low;
19855   u16 this_hi;
19856   vl_api_prefix_t prefix;
19857   u32 tmp, tmp2;
19858   u8 prefix_set = 0;
19859   u32 vrf_id = ~0;
19860   u8 is_add = 1;
19861   int ret;
19862
19863   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19864     {
19865       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
19866         prefix_set = 1;
19867       else if (unformat (input, "vrf %d", &vrf_id))
19868         ;
19869       else if (unformat (input, "del"))
19870         is_add = 0;
19871       else if (unformat (input, "port %d", &tmp))
19872         {
19873           if (tmp == 0 || tmp > 65535)
19874             {
19875               errmsg ("port %d out of range", tmp);
19876               return -99;
19877             }
19878           this_low = tmp;
19879           this_hi = this_low + 1;
19880           vec_add1 (low_ports, this_low);
19881           vec_add1 (high_ports, this_hi);
19882         }
19883       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
19884         {
19885           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
19886             {
19887               errmsg ("incorrect range parameters");
19888               return -99;
19889             }
19890           this_low = tmp;
19891           /* Note: in debug CLI +1 is added to high before
19892              passing to real fn that does "the work"
19893              (ip_source_and_port_range_check_add_del).
19894              This fn is a wrapper around the binary API fn a
19895              control plane will call, which expects this increment
19896              to have occurred. Hence letting the binary API control
19897              plane fn do the increment for consistency between VAT
19898              and other control planes.
19899            */
19900           this_hi = tmp2;
19901           vec_add1 (low_ports, this_low);
19902           vec_add1 (high_ports, this_hi);
19903         }
19904       else
19905         break;
19906     }
19907
19908   if (prefix_set == 0)
19909     {
19910       errmsg ("<address>/<mask> not specified");
19911       return -99;
19912     }
19913
19914   if (vrf_id == ~0)
19915     {
19916       errmsg ("VRF ID required, not specified");
19917       return -99;
19918     }
19919
19920   if (vrf_id == 0)
19921     {
19922       errmsg
19923         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19924       return -99;
19925     }
19926
19927   if (vec_len (low_ports) == 0)
19928     {
19929       errmsg ("At least one port or port range required");
19930       return -99;
19931     }
19932
19933   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
19934
19935   mp->is_add = is_add;
19936
19937   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
19938
19939   mp->number_of_ranges = vec_len (low_ports);
19940
19941   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
19942   vec_free (low_ports);
19943
19944   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
19945   vec_free (high_ports);
19946
19947   mp->vrf_id = ntohl (vrf_id);
19948
19949   S (mp);
19950   W (ret);
19951   return ret;
19952 }
19953
19954 int
19955 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
19956 {
19957   unformat_input_t *input = vam->input;
19958   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
19959   u32 sw_if_index = ~0;
19960   int vrf_set = 0;
19961   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
19962   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
19963   u8 is_add = 1;
19964   int ret;
19965
19966   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19967     {
19968       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19969         ;
19970       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19971         ;
19972       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
19973         vrf_set = 1;
19974       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
19975         vrf_set = 1;
19976       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
19977         vrf_set = 1;
19978       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
19979         vrf_set = 1;
19980       else if (unformat (input, "del"))
19981         is_add = 0;
19982       else
19983         break;
19984     }
19985
19986   if (sw_if_index == ~0)
19987     {
19988       errmsg ("Interface required but not specified");
19989       return -99;
19990     }
19991
19992   if (vrf_set == 0)
19993     {
19994       errmsg ("VRF ID required but not specified");
19995       return -99;
19996     }
19997
19998   if (tcp_out_vrf_id == 0
19999       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
20000     {
20001       errmsg
20002         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20003       return -99;
20004     }
20005
20006   /* Construct the API message */
20007   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20008
20009   mp->sw_if_index = ntohl (sw_if_index);
20010   mp->is_add = is_add;
20011   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20012   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20013   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20014   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20015
20016   /* send it... */
20017   S (mp);
20018
20019   /* Wait for a reply... */
20020   W (ret);
20021   return ret;
20022 }
20023
20024 static int
20025 api_set_punt (vat_main_t * vam)
20026 {
20027   unformat_input_t *i = vam->input;
20028   vl_api_address_family_t af;
20029   vl_api_set_punt_t *mp;
20030   u32 protocol = ~0;
20031   u32 port = ~0;
20032   int is_add = 1;
20033   int ret;
20034
20035   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20036     {
20037       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
20038         ;
20039       else if (unformat (i, "protocol %d", &protocol))
20040         ;
20041       else if (unformat (i, "port %d", &port))
20042         ;
20043       else if (unformat (i, "del"))
20044         is_add = 0;
20045       else
20046         {
20047           clib_warning ("parse error '%U'", format_unformat_error, i);
20048           return -99;
20049         }
20050     }
20051
20052   M (SET_PUNT, mp);
20053
20054   mp->is_add = (u8) is_add;
20055   mp->punt.type = PUNT_API_TYPE_L4;
20056   mp->punt.punt.l4.af = af;
20057   mp->punt.punt.l4.protocol = (u8) protocol;
20058   mp->punt.punt.l4.port = htons ((u16) port);
20059
20060   S (mp);
20061   W (ret);
20062   return ret;
20063 }
20064
20065 static int
20066 api_delete_subif (vat_main_t * vam)
20067 {
20068   unformat_input_t *i = vam->input;
20069   vl_api_delete_subif_t *mp;
20070   u32 sw_if_index = ~0;
20071   int ret;
20072
20073   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20074     {
20075       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20076         ;
20077       if (unformat (i, "sw_if_index %d", &sw_if_index))
20078         ;
20079       else
20080         break;
20081     }
20082
20083   if (sw_if_index == ~0)
20084     {
20085       errmsg ("missing sw_if_index");
20086       return -99;
20087     }
20088
20089   /* Construct the API message */
20090   M (DELETE_SUBIF, mp);
20091   mp->sw_if_index = ntohl (sw_if_index);
20092
20093   S (mp);
20094   W (ret);
20095   return ret;
20096 }
20097
20098 #define foreach_pbb_vtr_op      \
20099 _("disable",  L2_VTR_DISABLED)  \
20100 _("pop",  L2_VTR_POP_2)         \
20101 _("push",  L2_VTR_PUSH_2)
20102
20103 static int
20104 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
20105 {
20106   unformat_input_t *i = vam->input;
20107   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
20108   u32 sw_if_index = ~0, vtr_op = ~0;
20109   u16 outer_tag = ~0;
20110   u8 dmac[6], smac[6];
20111   u8 dmac_set = 0, smac_set = 0;
20112   u16 vlanid = 0;
20113   u32 sid = ~0;
20114   u32 tmp;
20115   int ret;
20116
20117   /* Shut up coverity */
20118   clib_memset (dmac, 0, sizeof (dmac));
20119   clib_memset (smac, 0, sizeof (smac));
20120
20121   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20122     {
20123       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20124         ;
20125       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20126         ;
20127       else if (unformat (i, "vtr_op %d", &vtr_op))
20128         ;
20129 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
20130       foreach_pbb_vtr_op
20131 #undef _
20132         else if (unformat (i, "translate_pbb_stag"))
20133         {
20134           if (unformat (i, "%d", &tmp))
20135             {
20136               vtr_op = L2_VTR_TRANSLATE_2_1;
20137               outer_tag = tmp;
20138             }
20139           else
20140             {
20141               errmsg
20142                 ("translate_pbb_stag operation requires outer tag definition");
20143               return -99;
20144             }
20145         }
20146       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
20147         dmac_set++;
20148       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
20149         smac_set++;
20150       else if (unformat (i, "sid %d", &sid))
20151         ;
20152       else if (unformat (i, "vlanid %d", &tmp))
20153         vlanid = tmp;
20154       else
20155         {
20156           clib_warning ("parse error '%U'", format_unformat_error, i);
20157           return -99;
20158         }
20159     }
20160
20161   if ((sw_if_index == ~0) || (vtr_op == ~0))
20162     {
20163       errmsg ("missing sw_if_index or vtr operation");
20164       return -99;
20165     }
20166   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
20167       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
20168     {
20169       errmsg
20170         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
20171       return -99;
20172     }
20173
20174   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
20175   mp->sw_if_index = ntohl (sw_if_index);
20176   mp->vtr_op = ntohl (vtr_op);
20177   mp->outer_tag = ntohs (outer_tag);
20178   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
20179   clib_memcpy (mp->b_smac, smac, sizeof (smac));
20180   mp->b_vlanid = ntohs (vlanid);
20181   mp->i_sid = ntohl (sid);
20182
20183   S (mp);
20184   W (ret);
20185   return ret;
20186 }
20187
20188 static int
20189 api_flow_classify_set_interface (vat_main_t * vam)
20190 {
20191   unformat_input_t *i = vam->input;
20192   vl_api_flow_classify_set_interface_t *mp;
20193   u32 sw_if_index;
20194   int sw_if_index_set;
20195   u32 ip4_table_index = ~0;
20196   u32 ip6_table_index = ~0;
20197   u8 is_add = 1;
20198   int ret;
20199
20200   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20201     {
20202       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20203         sw_if_index_set = 1;
20204       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20205         sw_if_index_set = 1;
20206       else if (unformat (i, "del"))
20207         is_add = 0;
20208       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20209         ;
20210       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20211         ;
20212       else
20213         {
20214           clib_warning ("parse error '%U'", format_unformat_error, i);
20215           return -99;
20216         }
20217     }
20218
20219   if (sw_if_index_set == 0)
20220     {
20221       errmsg ("missing interface name or sw_if_index");
20222       return -99;
20223     }
20224
20225   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
20226
20227   mp->sw_if_index = ntohl (sw_if_index);
20228   mp->ip4_table_index = ntohl (ip4_table_index);
20229   mp->ip6_table_index = ntohl (ip6_table_index);
20230   mp->is_add = is_add;
20231
20232   S (mp);
20233   W (ret);
20234   return ret;
20235 }
20236
20237 static int
20238 api_flow_classify_dump (vat_main_t * vam)
20239 {
20240   unformat_input_t *i = vam->input;
20241   vl_api_flow_classify_dump_t *mp;
20242   vl_api_control_ping_t *mp_ping;
20243   u8 type = FLOW_CLASSIFY_N_TABLES;
20244   int ret;
20245
20246   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
20247     ;
20248   else
20249     {
20250       errmsg ("classify table type must be specified");
20251       return -99;
20252     }
20253
20254   if (!vam->json_output)
20255     {
20256       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20257     }
20258
20259   M (FLOW_CLASSIFY_DUMP, mp);
20260   mp->type = type;
20261   /* send it... */
20262   S (mp);
20263
20264   /* Use a control ping for synchronization */
20265   MPING (CONTROL_PING, mp_ping);
20266   S (mp_ping);
20267
20268   /* Wait for a reply... */
20269   W (ret);
20270   return ret;
20271 }
20272
20273 static int
20274 api_feature_enable_disable (vat_main_t * vam)
20275 {
20276   unformat_input_t *i = vam->input;
20277   vl_api_feature_enable_disable_t *mp;
20278   u8 *arc_name = 0;
20279   u8 *feature_name = 0;
20280   u32 sw_if_index = ~0;
20281   u8 enable = 1;
20282   int ret;
20283
20284   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20285     {
20286       if (unformat (i, "arc_name %s", &arc_name))
20287         ;
20288       else if (unformat (i, "feature_name %s", &feature_name))
20289         ;
20290       else
20291         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20292         ;
20293       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20294         ;
20295       else if (unformat (i, "disable"))
20296         enable = 0;
20297       else
20298         break;
20299     }
20300
20301   if (arc_name == 0)
20302     {
20303       errmsg ("missing arc name");
20304       return -99;
20305     }
20306   if (vec_len (arc_name) > 63)
20307     {
20308       errmsg ("arc name too long");
20309     }
20310
20311   if (feature_name == 0)
20312     {
20313       errmsg ("missing feature name");
20314       return -99;
20315     }
20316   if (vec_len (feature_name) > 63)
20317     {
20318       errmsg ("feature name too long");
20319     }
20320
20321   if (sw_if_index == ~0)
20322     {
20323       errmsg ("missing interface name or sw_if_index");
20324       return -99;
20325     }
20326
20327   /* Construct the API message */
20328   M (FEATURE_ENABLE_DISABLE, mp);
20329   mp->sw_if_index = ntohl (sw_if_index);
20330   mp->enable = enable;
20331   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
20332   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
20333   vec_free (arc_name);
20334   vec_free (feature_name);
20335
20336   S (mp);
20337   W (ret);
20338   return ret;
20339 }
20340
20341 static int
20342 api_sw_interface_tag_add_del (vat_main_t * vam)
20343 {
20344   unformat_input_t *i = vam->input;
20345   vl_api_sw_interface_tag_add_del_t *mp;
20346   u32 sw_if_index = ~0;
20347   u8 *tag = 0;
20348   u8 enable = 1;
20349   int ret;
20350
20351   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20352     {
20353       if (unformat (i, "tag %s", &tag))
20354         ;
20355       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20356         ;
20357       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20358         ;
20359       else if (unformat (i, "del"))
20360         enable = 0;
20361       else
20362         break;
20363     }
20364
20365   if (sw_if_index == ~0)
20366     {
20367       errmsg ("missing interface name or sw_if_index");
20368       return -99;
20369     }
20370
20371   if (enable && (tag == 0))
20372     {
20373       errmsg ("no tag specified");
20374       return -99;
20375     }
20376
20377   /* Construct the API message */
20378   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20379   mp->sw_if_index = ntohl (sw_if_index);
20380   mp->is_add = enable;
20381   if (enable)
20382     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
20383   vec_free (tag);
20384
20385   S (mp);
20386   W (ret);
20387   return ret;
20388 }
20389
20390 static void vl_api_l2_xconnect_details_t_handler
20391   (vl_api_l2_xconnect_details_t * mp)
20392 {
20393   vat_main_t *vam = &vat_main;
20394
20395   print (vam->ofp, "%15d%15d",
20396          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20397 }
20398
20399 static void vl_api_l2_xconnect_details_t_handler_json
20400   (vl_api_l2_xconnect_details_t * mp)
20401 {
20402   vat_main_t *vam = &vat_main;
20403   vat_json_node_t *node = NULL;
20404
20405   if (VAT_JSON_ARRAY != vam->json_tree.type)
20406     {
20407       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20408       vat_json_init_array (&vam->json_tree);
20409     }
20410   node = vat_json_array_add (&vam->json_tree);
20411
20412   vat_json_init_object (node);
20413   vat_json_object_add_uint (node, "rx_sw_if_index",
20414                             ntohl (mp->rx_sw_if_index));
20415   vat_json_object_add_uint (node, "tx_sw_if_index",
20416                             ntohl (mp->tx_sw_if_index));
20417 }
20418
20419 static int
20420 api_l2_xconnect_dump (vat_main_t * vam)
20421 {
20422   vl_api_l2_xconnect_dump_t *mp;
20423   vl_api_control_ping_t *mp_ping;
20424   int ret;
20425
20426   if (!vam->json_output)
20427     {
20428       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20429     }
20430
20431   M (L2_XCONNECT_DUMP, mp);
20432
20433   S (mp);
20434
20435   /* Use a control ping for synchronization */
20436   MPING (CONTROL_PING, mp_ping);
20437   S (mp_ping);
20438
20439   W (ret);
20440   return ret;
20441 }
20442
20443 static int
20444 api_hw_interface_set_mtu (vat_main_t * vam)
20445 {
20446   unformat_input_t *i = vam->input;
20447   vl_api_hw_interface_set_mtu_t *mp;
20448   u32 sw_if_index = ~0;
20449   u32 mtu = 0;
20450   int ret;
20451
20452   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20453     {
20454       if (unformat (i, "mtu %d", &mtu))
20455         ;
20456       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20457         ;
20458       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20459         ;
20460       else
20461         break;
20462     }
20463
20464   if (sw_if_index == ~0)
20465     {
20466       errmsg ("missing interface name or sw_if_index");
20467       return -99;
20468     }
20469
20470   if (mtu == 0)
20471     {
20472       errmsg ("no mtu specified");
20473       return -99;
20474     }
20475
20476   /* Construct the API message */
20477   M (HW_INTERFACE_SET_MTU, mp);
20478   mp->sw_if_index = ntohl (sw_if_index);
20479   mp->mtu = ntohs ((u16) mtu);
20480
20481   S (mp);
20482   W (ret);
20483   return ret;
20484 }
20485
20486 static int
20487 api_p2p_ethernet_add (vat_main_t * vam)
20488 {
20489   unformat_input_t *i = vam->input;
20490   vl_api_p2p_ethernet_add_t *mp;
20491   u32 parent_if_index = ~0;
20492   u32 sub_id = ~0;
20493   u8 remote_mac[6];
20494   u8 mac_set = 0;
20495   int ret;
20496
20497   clib_memset (remote_mac, 0, sizeof (remote_mac));
20498   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20499     {
20500       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20501         ;
20502       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20503         ;
20504       else
20505         if (unformat
20506             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20507         mac_set++;
20508       else if (unformat (i, "sub_id %d", &sub_id))
20509         ;
20510       else
20511         {
20512           clib_warning ("parse error '%U'", format_unformat_error, i);
20513           return -99;
20514         }
20515     }
20516
20517   if (parent_if_index == ~0)
20518     {
20519       errmsg ("missing interface name or sw_if_index");
20520       return -99;
20521     }
20522   if (mac_set == 0)
20523     {
20524       errmsg ("missing remote mac address");
20525       return -99;
20526     }
20527   if (sub_id == ~0)
20528     {
20529       errmsg ("missing sub-interface id");
20530       return -99;
20531     }
20532
20533   M (P2P_ETHERNET_ADD, mp);
20534   mp->parent_if_index = ntohl (parent_if_index);
20535   mp->subif_id = ntohl (sub_id);
20536   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20537
20538   S (mp);
20539   W (ret);
20540   return ret;
20541 }
20542
20543 static int
20544 api_p2p_ethernet_del (vat_main_t * vam)
20545 {
20546   unformat_input_t *i = vam->input;
20547   vl_api_p2p_ethernet_del_t *mp;
20548   u32 parent_if_index = ~0;
20549   u8 remote_mac[6];
20550   u8 mac_set = 0;
20551   int ret;
20552
20553   clib_memset (remote_mac, 0, sizeof (remote_mac));
20554   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20555     {
20556       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20557         ;
20558       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20559         ;
20560       else
20561         if (unformat
20562             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20563         mac_set++;
20564       else
20565         {
20566           clib_warning ("parse error '%U'", format_unformat_error, i);
20567           return -99;
20568         }
20569     }
20570
20571   if (parent_if_index == ~0)
20572     {
20573       errmsg ("missing interface name or sw_if_index");
20574       return -99;
20575     }
20576   if (mac_set == 0)
20577     {
20578       errmsg ("missing remote mac address");
20579       return -99;
20580     }
20581
20582   M (P2P_ETHERNET_DEL, mp);
20583   mp->parent_if_index = ntohl (parent_if_index);
20584   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20585
20586   S (mp);
20587   W (ret);
20588   return ret;
20589 }
20590
20591 static int
20592 api_lldp_config (vat_main_t * vam)
20593 {
20594   unformat_input_t *i = vam->input;
20595   vl_api_lldp_config_t *mp;
20596   int tx_hold = 0;
20597   int tx_interval = 0;
20598   u8 *sys_name = NULL;
20599   int ret;
20600
20601   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20602     {
20603       if (unformat (i, "system-name %s", &sys_name))
20604         ;
20605       else if (unformat (i, "tx-hold %d", &tx_hold))
20606         ;
20607       else if (unformat (i, "tx-interval %d", &tx_interval))
20608         ;
20609       else
20610         {
20611           clib_warning ("parse error '%U'", format_unformat_error, i);
20612           return -99;
20613         }
20614     }
20615
20616   vec_add1 (sys_name, 0);
20617
20618   M (LLDP_CONFIG, mp);
20619   mp->tx_hold = htonl (tx_hold);
20620   mp->tx_interval = htonl (tx_interval);
20621   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
20622   vec_free (sys_name);
20623
20624   S (mp);
20625   W (ret);
20626   return ret;
20627 }
20628
20629 static int
20630 api_sw_interface_set_lldp (vat_main_t * vam)
20631 {
20632   unformat_input_t *i = vam->input;
20633   vl_api_sw_interface_set_lldp_t *mp;
20634   u32 sw_if_index = ~0;
20635   u32 enable = 1;
20636   u8 *port_desc = NULL, *mgmt_oid = NULL;
20637   ip4_address_t ip4_addr;
20638   ip6_address_t ip6_addr;
20639   int ret;
20640
20641   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
20642   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
20643
20644   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20645     {
20646       if (unformat (i, "disable"))
20647         enable = 0;
20648       else
20649         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20650         ;
20651       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20652         ;
20653       else if (unformat (i, "port-desc %s", &port_desc))
20654         ;
20655       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
20656         ;
20657       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
20658         ;
20659       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
20660         ;
20661       else
20662         break;
20663     }
20664
20665   if (sw_if_index == ~0)
20666     {
20667       errmsg ("missing interface name or sw_if_index");
20668       return -99;
20669     }
20670
20671   /* Construct the API message */
20672   vec_add1 (port_desc, 0);
20673   vec_add1 (mgmt_oid, 0);
20674   M (SW_INTERFACE_SET_LLDP, mp);
20675   mp->sw_if_index = ntohl (sw_if_index);
20676   mp->enable = enable;
20677   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
20678   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
20679   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
20680   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
20681   vec_free (port_desc);
20682   vec_free (mgmt_oid);
20683
20684   S (mp);
20685   W (ret);
20686   return ret;
20687 }
20688
20689 static int
20690 api_tcp_configure_src_addresses (vat_main_t * vam)
20691 {
20692   vl_api_tcp_configure_src_addresses_t *mp;
20693   unformat_input_t *i = vam->input;
20694   ip4_address_t v4first, v4last;
20695   ip6_address_t v6first, v6last;
20696   u8 range_set = 0;
20697   u32 vrf_id = 0;
20698   int ret;
20699
20700   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20701     {
20702       if (unformat (i, "%U - %U",
20703                     unformat_ip4_address, &v4first,
20704                     unformat_ip4_address, &v4last))
20705         {
20706           if (range_set)
20707             {
20708               errmsg ("one range per message (range already set)");
20709               return -99;
20710             }
20711           range_set = 1;
20712         }
20713       else if (unformat (i, "%U - %U",
20714                          unformat_ip6_address, &v6first,
20715                          unformat_ip6_address, &v6last))
20716         {
20717           if (range_set)
20718             {
20719               errmsg ("one range per message (range already set)");
20720               return -99;
20721             }
20722           range_set = 2;
20723         }
20724       else if (unformat (i, "vrf %d", &vrf_id))
20725         ;
20726       else
20727         break;
20728     }
20729
20730   if (range_set == 0)
20731     {
20732       errmsg ("address range not set");
20733       return -99;
20734     }
20735
20736   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
20737   mp->vrf_id = ntohl (vrf_id);
20738   /* ipv6? */
20739   if (range_set == 2)
20740     {
20741       mp->is_ipv6 = 1;
20742       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
20743       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
20744     }
20745   else
20746     {
20747       mp->is_ipv6 = 0;
20748       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
20749       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
20750     }
20751   S (mp);
20752   W (ret);
20753   return ret;
20754 }
20755
20756 static void vl_api_app_namespace_add_del_reply_t_handler
20757   (vl_api_app_namespace_add_del_reply_t * mp)
20758 {
20759   vat_main_t *vam = &vat_main;
20760   i32 retval = ntohl (mp->retval);
20761   if (vam->async_mode)
20762     {
20763       vam->async_errors += (retval < 0);
20764     }
20765   else
20766     {
20767       vam->retval = retval;
20768       if (retval == 0)
20769         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
20770       vam->result_ready = 1;
20771     }
20772 }
20773
20774 static void vl_api_app_namespace_add_del_reply_t_handler_json
20775   (vl_api_app_namespace_add_del_reply_t * mp)
20776 {
20777   vat_main_t *vam = &vat_main;
20778   vat_json_node_t node;
20779
20780   vat_json_init_object (&node);
20781   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
20782   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
20783
20784   vat_json_print (vam->ofp, &node);
20785   vat_json_free (&node);
20786
20787   vam->retval = ntohl (mp->retval);
20788   vam->result_ready = 1;
20789 }
20790
20791 static int
20792 api_app_namespace_add_del (vat_main_t * vam)
20793 {
20794   vl_api_app_namespace_add_del_t *mp;
20795   unformat_input_t *i = vam->input;
20796   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
20797   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
20798   u64 secret;
20799   int ret;
20800
20801   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20802     {
20803       if (unformat (i, "id %_%v%_", &ns_id))
20804         ;
20805       else if (unformat (i, "secret %lu", &secret))
20806         secret_set = 1;
20807       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20808         sw_if_index_set = 1;
20809       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
20810         ;
20811       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
20812         ;
20813       else
20814         break;
20815     }
20816   if (!ns_id || !secret_set || !sw_if_index_set)
20817     {
20818       errmsg ("namespace id, secret and sw_if_index must be set");
20819       return -99;
20820     }
20821   if (vec_len (ns_id) > 64)
20822     {
20823       errmsg ("namespace id too long");
20824       return -99;
20825     }
20826   M (APP_NAMESPACE_ADD_DEL, mp);
20827
20828   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
20829   mp->namespace_id_len = vec_len (ns_id);
20830   mp->secret = clib_host_to_net_u64 (secret);
20831   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20832   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
20833   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
20834   vec_free (ns_id);
20835   S (mp);
20836   W (ret);
20837   return ret;
20838 }
20839
20840 static int
20841 api_sock_init_shm (vat_main_t * vam)
20842 {
20843 #if VPP_API_TEST_BUILTIN == 0
20844   unformat_input_t *i = vam->input;
20845   vl_api_shm_elem_config_t *config = 0;
20846   u64 size = 64 << 20;
20847   int rv;
20848
20849   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20850     {
20851       if (unformat (i, "size %U", unformat_memory_size, &size))
20852         ;
20853       else
20854         break;
20855     }
20856
20857   /*
20858    * Canned custom ring allocator config.
20859    * Should probably parse all of this
20860    */
20861   vec_validate (config, 6);
20862   config[0].type = VL_API_VLIB_RING;
20863   config[0].size = 256;
20864   config[0].count = 32;
20865
20866   config[1].type = VL_API_VLIB_RING;
20867   config[1].size = 1024;
20868   config[1].count = 16;
20869
20870   config[2].type = VL_API_VLIB_RING;
20871   config[2].size = 4096;
20872   config[2].count = 2;
20873
20874   config[3].type = VL_API_CLIENT_RING;
20875   config[3].size = 256;
20876   config[3].count = 32;
20877
20878   config[4].type = VL_API_CLIENT_RING;
20879   config[4].size = 1024;
20880   config[4].count = 16;
20881
20882   config[5].type = VL_API_CLIENT_RING;
20883   config[5].size = 4096;
20884   config[5].count = 2;
20885
20886   config[6].type = VL_API_QUEUE;
20887   config[6].count = 128;
20888   config[6].size = sizeof (uword);
20889
20890   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
20891   if (!rv)
20892     vam->client_index_invalid = 1;
20893   return rv;
20894 #else
20895   return -99;
20896 #endif
20897 }
20898
20899 static void
20900 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
20901 {
20902   vat_main_t *vam = &vat_main;
20903
20904   if (mp->is_ip4)
20905     {
20906       print (vam->ofp,
20907              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
20908              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
20909              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
20910              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
20911              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
20912              clib_net_to_host_u32 (mp->action_index), mp->tag);
20913     }
20914   else
20915     {
20916       print (vam->ofp,
20917              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
20918              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
20919              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
20920              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
20921              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
20922              clib_net_to_host_u32 (mp->action_index), mp->tag);
20923     }
20924 }
20925
20926 static void
20927 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
20928                                              mp)
20929 {
20930   vat_main_t *vam = &vat_main;
20931   vat_json_node_t *node = NULL;
20932   struct in6_addr ip6;
20933   struct in_addr ip4;
20934
20935   if (VAT_JSON_ARRAY != vam->json_tree.type)
20936     {
20937       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20938       vat_json_init_array (&vam->json_tree);
20939     }
20940   node = vat_json_array_add (&vam->json_tree);
20941   vat_json_init_object (node);
20942
20943   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
20944   vat_json_object_add_uint (node, "appns_index",
20945                             clib_net_to_host_u32 (mp->appns_index));
20946   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
20947   vat_json_object_add_uint (node, "scope", mp->scope);
20948   vat_json_object_add_uint (node, "action_index",
20949                             clib_net_to_host_u32 (mp->action_index));
20950   vat_json_object_add_uint (node, "lcl_port",
20951                             clib_net_to_host_u16 (mp->lcl_port));
20952   vat_json_object_add_uint (node, "rmt_port",
20953                             clib_net_to_host_u16 (mp->rmt_port));
20954   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
20955   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
20956   vat_json_object_add_string_copy (node, "tag", mp->tag);
20957   if (mp->is_ip4)
20958     {
20959       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
20960       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
20961       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
20962       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
20963     }
20964   else
20965     {
20966       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
20967       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
20968       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
20969       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
20970     }
20971 }
20972
20973 static int
20974 api_session_rule_add_del (vat_main_t * vam)
20975 {
20976   vl_api_session_rule_add_del_t *mp;
20977   unformat_input_t *i = vam->input;
20978   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
20979   u32 appns_index = 0, scope = 0;
20980   ip4_address_t lcl_ip4, rmt_ip4;
20981   ip6_address_t lcl_ip6, rmt_ip6;
20982   u8 is_ip4 = 1, conn_set = 0;
20983   u8 is_add = 1, *tag = 0;
20984   int ret;
20985
20986   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20987     {
20988       if (unformat (i, "del"))
20989         is_add = 0;
20990       else if (unformat (i, "add"))
20991         ;
20992       else if (unformat (i, "proto tcp"))
20993         proto = 0;
20994       else if (unformat (i, "proto udp"))
20995         proto = 1;
20996       else if (unformat (i, "appns %d", &appns_index))
20997         ;
20998       else if (unformat (i, "scope %d", &scope))
20999         ;
21000       else if (unformat (i, "tag %_%v%_", &tag))
21001         ;
21002       else
21003         if (unformat
21004             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
21005              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
21006              &rmt_port))
21007         {
21008           is_ip4 = 1;
21009           conn_set = 1;
21010         }
21011       else
21012         if (unformat
21013             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
21014              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
21015              &rmt_port))
21016         {
21017           is_ip4 = 0;
21018           conn_set = 1;
21019         }
21020       else if (unformat (i, "action %d", &action))
21021         ;
21022       else
21023         break;
21024     }
21025   if (proto == ~0 || !conn_set || action == ~0)
21026     {
21027       errmsg ("transport proto, connection and action must be set");
21028       return -99;
21029     }
21030
21031   if (scope > 3)
21032     {
21033       errmsg ("scope should be 0-3");
21034       return -99;
21035     }
21036
21037   M (SESSION_RULE_ADD_DEL, mp);
21038
21039   mp->is_ip4 = is_ip4;
21040   mp->transport_proto = proto;
21041   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
21042   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
21043   mp->lcl_plen = lcl_plen;
21044   mp->rmt_plen = rmt_plen;
21045   mp->action_index = clib_host_to_net_u32 (action);
21046   mp->appns_index = clib_host_to_net_u32 (appns_index);
21047   mp->scope = scope;
21048   mp->is_add = is_add;
21049   if (is_ip4)
21050     {
21051       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
21052       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
21053     }
21054   else
21055     {
21056       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
21057       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
21058     }
21059   if (tag)
21060     {
21061       clib_memcpy (mp->tag, tag, vec_len (tag));
21062       vec_free (tag);
21063     }
21064
21065   S (mp);
21066   W (ret);
21067   return ret;
21068 }
21069
21070 static int
21071 api_session_rules_dump (vat_main_t * vam)
21072 {
21073   vl_api_session_rules_dump_t *mp;
21074   vl_api_control_ping_t *mp_ping;
21075   int ret;
21076
21077   if (!vam->json_output)
21078     {
21079       print (vam->ofp, "%=20s", "Session Rules");
21080     }
21081
21082   M (SESSION_RULES_DUMP, mp);
21083   /* send it... */
21084   S (mp);
21085
21086   /* Use a control ping for synchronization */
21087   MPING (CONTROL_PING, mp_ping);
21088   S (mp_ping);
21089
21090   /* Wait for a reply... */
21091   W (ret);
21092   return ret;
21093 }
21094
21095 static int
21096 api_ip_container_proxy_add_del (vat_main_t * vam)
21097 {
21098   vl_api_ip_container_proxy_add_del_t *mp;
21099   unformat_input_t *i = vam->input;
21100   u32 sw_if_index = ~0;
21101   vl_api_prefix_t pfx = { };
21102   u8 is_add = 1;
21103   int ret;
21104
21105   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21106     {
21107       if (unformat (i, "del"))
21108         is_add = 0;
21109       else if (unformat (i, "add"))
21110         ;
21111       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
21112         ;
21113       else if (unformat (i, "sw_if_index %u", &sw_if_index))
21114         ;
21115       else
21116         break;
21117     }
21118   if (sw_if_index == ~0 || pfx.len == 0)
21119     {
21120       errmsg ("address and sw_if_index must be set");
21121       return -99;
21122     }
21123
21124   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
21125
21126   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21127   mp->is_add = is_add;
21128   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
21129
21130   S (mp);
21131   W (ret);
21132   return ret;
21133 }
21134
21135 static int
21136 api_qos_record_enable_disable (vat_main_t * vam)
21137 {
21138   unformat_input_t *i = vam->input;
21139   vl_api_qos_record_enable_disable_t *mp;
21140   u32 sw_if_index, qs = 0xff;
21141   u8 sw_if_index_set = 0;
21142   u8 enable = 1;
21143   int ret;
21144
21145   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21146     {
21147       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21148         sw_if_index_set = 1;
21149       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21150         sw_if_index_set = 1;
21151       else if (unformat (i, "%U", unformat_qos_source, &qs))
21152         ;
21153       else if (unformat (i, "disable"))
21154         enable = 0;
21155       else
21156         {
21157           clib_warning ("parse error '%U'", format_unformat_error, i);
21158           return -99;
21159         }
21160     }
21161
21162   if (sw_if_index_set == 0)
21163     {
21164       errmsg ("missing interface name or sw_if_index");
21165       return -99;
21166     }
21167   if (qs == 0xff)
21168     {
21169       errmsg ("input location must be specified");
21170       return -99;
21171     }
21172
21173   M (QOS_RECORD_ENABLE_DISABLE, mp);
21174
21175   mp->record.sw_if_index = ntohl (sw_if_index);
21176   mp->record.input_source = qs;
21177   mp->enable = enable;
21178
21179   S (mp);
21180   W (ret);
21181   return ret;
21182 }
21183
21184
21185 static int
21186 q_or_quit (vat_main_t * vam)
21187 {
21188 #if VPP_API_TEST_BUILTIN == 0
21189   longjmp (vam->jump_buf, 1);
21190 #endif
21191   return 0;                     /* not so much */
21192 }
21193
21194 static int
21195 q (vat_main_t * vam)
21196 {
21197   return q_or_quit (vam);
21198 }
21199
21200 static int
21201 quit (vat_main_t * vam)
21202 {
21203   return q_or_quit (vam);
21204 }
21205
21206 static int
21207 comment (vat_main_t * vam)
21208 {
21209   return 0;
21210 }
21211
21212 static int
21213 elog_save (vat_main_t * vam)
21214 {
21215 #if VPP_API_TEST_BUILTIN == 0
21216   elog_main_t *em = &vam->elog_main;
21217   unformat_input_t *i = vam->input;
21218   char *file, *chroot_file;
21219   clib_error_t *error;
21220
21221   if (!unformat (i, "%s", &file))
21222     {
21223       errmsg ("expected file name, got `%U'", format_unformat_error, i);
21224       return 0;
21225     }
21226
21227   /* It's fairly hard to get "../oopsie" through unformat; just in case */
21228   if (strstr (file, "..") || index (file, '/'))
21229     {
21230       errmsg ("illegal characters in filename '%s'", file);
21231       return 0;
21232     }
21233
21234   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
21235
21236   vec_free (file);
21237
21238   errmsg ("Saving %wd of %wd events to %s",
21239           elog_n_events_in_buffer (em),
21240           elog_buffer_capacity (em), chroot_file);
21241
21242   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
21243   vec_free (chroot_file);
21244
21245   if (error)
21246     clib_error_report (error);
21247 #else
21248   errmsg ("Use the vpp event loger...");
21249 #endif
21250
21251   return 0;
21252 }
21253
21254 static int
21255 elog_setup (vat_main_t * vam)
21256 {
21257 #if VPP_API_TEST_BUILTIN == 0
21258   elog_main_t *em = &vam->elog_main;
21259   unformat_input_t *i = vam->input;
21260   u32 nevents = 128 << 10;
21261
21262   (void) unformat (i, "nevents %d", &nevents);
21263
21264   elog_init (em, nevents);
21265   vl_api_set_elog_main (em);
21266   vl_api_set_elog_trace_api_messages (1);
21267   errmsg ("Event logger initialized with %u events", nevents);
21268 #else
21269   errmsg ("Use the vpp event loger...");
21270 #endif
21271   return 0;
21272 }
21273
21274 static int
21275 elog_enable (vat_main_t * vam)
21276 {
21277 #if VPP_API_TEST_BUILTIN == 0
21278   elog_main_t *em = &vam->elog_main;
21279
21280   elog_enable_disable (em, 1 /* enable */ );
21281   vl_api_set_elog_trace_api_messages (1);
21282   errmsg ("Event logger enabled...");
21283 #else
21284   errmsg ("Use the vpp event loger...");
21285 #endif
21286   return 0;
21287 }
21288
21289 static int
21290 elog_disable (vat_main_t * vam)
21291 {
21292 #if VPP_API_TEST_BUILTIN == 0
21293   elog_main_t *em = &vam->elog_main;
21294
21295   elog_enable_disable (em, 0 /* enable */ );
21296   vl_api_set_elog_trace_api_messages (1);
21297   errmsg ("Event logger disabled...");
21298 #else
21299   errmsg ("Use the vpp event loger...");
21300 #endif
21301   return 0;
21302 }
21303
21304 static int
21305 statseg (vat_main_t * vam)
21306 {
21307   ssvm_private_t *ssvmp = &vam->stat_segment;
21308   ssvm_shared_header_t *shared_header = ssvmp->sh;
21309   vlib_counter_t **counters;
21310   u64 thread0_index1_packets;
21311   u64 thread0_index1_bytes;
21312   f64 vector_rate, input_rate;
21313   uword *p;
21314
21315   uword *counter_vector_by_name;
21316   if (vam->stat_segment_lockp == 0)
21317     {
21318       errmsg ("Stat segment not mapped...");
21319       return -99;
21320     }
21321
21322   /* look up "/if/rx for sw_if_index 1 as a test */
21323
21324   clib_spinlock_lock (vam->stat_segment_lockp);
21325
21326   counter_vector_by_name = (uword *) shared_header->opaque[1];
21327
21328   p = hash_get_mem (counter_vector_by_name, "/if/rx");
21329   if (p == 0)
21330     {
21331       clib_spinlock_unlock (vam->stat_segment_lockp);
21332       errmsg ("/if/tx not found?");
21333       return -99;
21334     }
21335
21336   /* Fish per-thread vector of combined counters from shared memory */
21337   counters = (vlib_counter_t **) p[0];
21338
21339   if (vec_len (counters[0]) < 2)
21340     {
21341       clib_spinlock_unlock (vam->stat_segment_lockp);
21342       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
21343       return -99;
21344     }
21345
21346   /* Read thread 0 sw_if_index 1 counter */
21347   thread0_index1_packets = counters[0][1].packets;
21348   thread0_index1_bytes = counters[0][1].bytes;
21349
21350   p = hash_get_mem (counter_vector_by_name, "vector_rate");
21351   if (p == 0)
21352     {
21353       clib_spinlock_unlock (vam->stat_segment_lockp);
21354       errmsg ("vector_rate not found?");
21355       return -99;
21356     }
21357
21358   vector_rate = *(f64 *) (p[0]);
21359   p = hash_get_mem (counter_vector_by_name, "input_rate");
21360   if (p == 0)
21361     {
21362       clib_spinlock_unlock (vam->stat_segment_lockp);
21363       errmsg ("input_rate not found?");
21364       return -99;
21365     }
21366   input_rate = *(f64 *) (p[0]);
21367
21368   clib_spinlock_unlock (vam->stat_segment_lockp);
21369
21370   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
21371          vector_rate, input_rate);
21372   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
21373          thread0_index1_packets, thread0_index1_bytes);
21374
21375   return 0;
21376 }
21377
21378 static int
21379 cmd_cmp (void *a1, void *a2)
21380 {
21381   u8 **c1 = a1;
21382   u8 **c2 = a2;
21383
21384   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21385 }
21386
21387 static int
21388 help (vat_main_t * vam)
21389 {
21390   u8 **cmds = 0;
21391   u8 *name = 0;
21392   hash_pair_t *p;
21393   unformat_input_t *i = vam->input;
21394   int j;
21395
21396   if (unformat (i, "%s", &name))
21397     {
21398       uword *hs;
21399
21400       vec_add1 (name, 0);
21401
21402       hs = hash_get_mem (vam->help_by_name, name);
21403       if (hs)
21404         print (vam->ofp, "usage: %s %s", name, hs[0]);
21405       else
21406         print (vam->ofp, "No such msg / command '%s'", name);
21407       vec_free (name);
21408       return 0;
21409     }
21410
21411   print (vam->ofp, "Help is available for the following:");
21412
21413     /* *INDENT-OFF* */
21414     hash_foreach_pair (p, vam->function_by_name,
21415     ({
21416       vec_add1 (cmds, (u8 *)(p->key));
21417     }));
21418     /* *INDENT-ON* */
21419
21420   vec_sort_with_function (cmds, cmd_cmp);
21421
21422   for (j = 0; j < vec_len (cmds); j++)
21423     print (vam->ofp, "%s", cmds[j]);
21424
21425   vec_free (cmds);
21426   return 0;
21427 }
21428
21429 static int
21430 set (vat_main_t * vam)
21431 {
21432   u8 *name = 0, *value = 0;
21433   unformat_input_t *i = vam->input;
21434
21435   if (unformat (i, "%s", &name))
21436     {
21437       /* The input buffer is a vector, not a string. */
21438       value = vec_dup (i->buffer);
21439       vec_delete (value, i->index, 0);
21440       /* Almost certainly has a trailing newline */
21441       if (value[vec_len (value) - 1] == '\n')
21442         value[vec_len (value) - 1] = 0;
21443       /* Make sure it's a proper string, one way or the other */
21444       vec_add1 (value, 0);
21445       (void) clib_macro_set_value (&vam->macro_main,
21446                                    (char *) name, (char *) value);
21447     }
21448   else
21449     errmsg ("usage: set <name> <value>");
21450
21451   vec_free (name);
21452   vec_free (value);
21453   return 0;
21454 }
21455
21456 static int
21457 unset (vat_main_t * vam)
21458 {
21459   u8 *name = 0;
21460
21461   if (unformat (vam->input, "%s", &name))
21462     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
21463       errmsg ("unset: %s wasn't set", name);
21464   vec_free (name);
21465   return 0;
21466 }
21467
21468 typedef struct
21469 {
21470   u8 *name;
21471   u8 *value;
21472 } macro_sort_t;
21473
21474
21475 static int
21476 macro_sort_cmp (void *a1, void *a2)
21477 {
21478   macro_sort_t *s1 = a1;
21479   macro_sort_t *s2 = a2;
21480
21481   return strcmp ((char *) (s1->name), (char *) (s2->name));
21482 }
21483
21484 static int
21485 dump_macro_table (vat_main_t * vam)
21486 {
21487   macro_sort_t *sort_me = 0, *sm;
21488   int i;
21489   hash_pair_t *p;
21490
21491     /* *INDENT-OFF* */
21492     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
21493     ({
21494       vec_add2 (sort_me, sm, 1);
21495       sm->name = (u8 *)(p->key);
21496       sm->value = (u8 *) (p->value[0]);
21497     }));
21498     /* *INDENT-ON* */
21499
21500   vec_sort_with_function (sort_me, macro_sort_cmp);
21501
21502   if (vec_len (sort_me))
21503     print (vam->ofp, "%-15s%s", "Name", "Value");
21504   else
21505     print (vam->ofp, "The macro table is empty...");
21506
21507   for (i = 0; i < vec_len (sort_me); i++)
21508     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
21509   return 0;
21510 }
21511
21512 static int
21513 dump_node_table (vat_main_t * vam)
21514 {
21515   int i, j;
21516   vlib_node_t *node, *next_node;
21517
21518   if (vec_len (vam->graph_nodes) == 0)
21519     {
21520       print (vam->ofp, "Node table empty, issue get_node_graph...");
21521       return 0;
21522     }
21523
21524   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
21525     {
21526       node = vam->graph_nodes[0][i];
21527       print (vam->ofp, "[%d] %s", i, node->name);
21528       for (j = 0; j < vec_len (node->next_nodes); j++)
21529         {
21530           if (node->next_nodes[j] != ~0)
21531             {
21532               next_node = vam->graph_nodes[0][node->next_nodes[j]];
21533               print (vam->ofp, "  [%d] %s", j, next_node->name);
21534             }
21535         }
21536     }
21537   return 0;
21538 }
21539
21540 static int
21541 value_sort_cmp (void *a1, void *a2)
21542 {
21543   name_sort_t *n1 = a1;
21544   name_sort_t *n2 = a2;
21545
21546   if (n1->value < n2->value)
21547     return -1;
21548   if (n1->value > n2->value)
21549     return 1;
21550   return 0;
21551 }
21552
21553
21554 static int
21555 dump_msg_api_table (vat_main_t * vam)
21556 {
21557   api_main_t *am = &api_main;
21558   name_sort_t *nses = 0, *ns;
21559   hash_pair_t *hp;
21560   int i;
21561
21562   /* *INDENT-OFF* */
21563   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
21564   ({
21565     vec_add2 (nses, ns, 1);
21566     ns->name = (u8 *)(hp->key);
21567     ns->value = (u32) hp->value[0];
21568   }));
21569   /* *INDENT-ON* */
21570
21571   vec_sort_with_function (nses, value_sort_cmp);
21572
21573   for (i = 0; i < vec_len (nses); i++)
21574     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
21575   vec_free (nses);
21576   return 0;
21577 }
21578
21579 static int
21580 get_msg_id (vat_main_t * vam)
21581 {
21582   u8 *name_and_crc;
21583   u32 message_index;
21584
21585   if (unformat (vam->input, "%s", &name_and_crc))
21586     {
21587       message_index = vl_msg_api_get_msg_index (name_and_crc);
21588       if (message_index == ~0)
21589         {
21590           print (vam->ofp, " '%s' not found", name_and_crc);
21591           return 0;
21592         }
21593       print (vam->ofp, " '%s' has message index %d",
21594              name_and_crc, message_index);
21595       return 0;
21596     }
21597   errmsg ("name_and_crc required...");
21598   return 0;
21599 }
21600
21601 static int
21602 search_node_table (vat_main_t * vam)
21603 {
21604   unformat_input_t *line_input = vam->input;
21605   u8 *node_to_find;
21606   int j;
21607   vlib_node_t *node, *next_node;
21608   uword *p;
21609
21610   if (vam->graph_node_index_by_name == 0)
21611     {
21612       print (vam->ofp, "Node table empty, issue get_node_graph...");
21613       return 0;
21614     }
21615
21616   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21617     {
21618       if (unformat (line_input, "%s", &node_to_find))
21619         {
21620           vec_add1 (node_to_find, 0);
21621           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
21622           if (p == 0)
21623             {
21624               print (vam->ofp, "%s not found...", node_to_find);
21625               goto out;
21626             }
21627           node = vam->graph_nodes[0][p[0]];
21628           print (vam->ofp, "[%d] %s", p[0], node->name);
21629           for (j = 0; j < vec_len (node->next_nodes); j++)
21630             {
21631               if (node->next_nodes[j] != ~0)
21632                 {
21633                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
21634                   print (vam->ofp, "  [%d] %s", j, next_node->name);
21635                 }
21636             }
21637         }
21638
21639       else
21640         {
21641           clib_warning ("parse error '%U'", format_unformat_error,
21642                         line_input);
21643           return -99;
21644         }
21645
21646     out:
21647       vec_free (node_to_find);
21648
21649     }
21650
21651   return 0;
21652 }
21653
21654
21655 static int
21656 script (vat_main_t * vam)
21657 {
21658 #if (VPP_API_TEST_BUILTIN==0)
21659   u8 *s = 0;
21660   char *save_current_file;
21661   unformat_input_t save_input;
21662   jmp_buf save_jump_buf;
21663   u32 save_line_number;
21664
21665   FILE *new_fp, *save_ifp;
21666
21667   if (unformat (vam->input, "%s", &s))
21668     {
21669       new_fp = fopen ((char *) s, "r");
21670       if (new_fp == 0)
21671         {
21672           errmsg ("Couldn't open script file %s", s);
21673           vec_free (s);
21674           return -99;
21675         }
21676     }
21677   else
21678     {
21679       errmsg ("Missing script name");
21680       return -99;
21681     }
21682
21683   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
21684   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
21685   save_ifp = vam->ifp;
21686   save_line_number = vam->input_line_number;
21687   save_current_file = (char *) vam->current_file;
21688
21689   vam->input_line_number = 0;
21690   vam->ifp = new_fp;
21691   vam->current_file = s;
21692   do_one_file (vam);
21693
21694   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
21695   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
21696   vam->ifp = save_ifp;
21697   vam->input_line_number = save_line_number;
21698   vam->current_file = (u8 *) save_current_file;
21699   vec_free (s);
21700
21701   return 0;
21702 #else
21703   clib_warning ("use the exec command...");
21704   return -99;
21705 #endif
21706 }
21707
21708 static int
21709 echo (vat_main_t * vam)
21710 {
21711   print (vam->ofp, "%v", vam->input->buffer);
21712   return 0;
21713 }
21714
21715 /* List of API message constructors, CLI names map to api_xxx */
21716 #define foreach_vpe_api_msg                                             \
21717 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
21718 _(sw_interface_dump,"")                                                 \
21719 _(sw_interface_set_flags,                                               \
21720   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
21721 _(sw_interface_add_del_address,                                         \
21722   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
21723 _(sw_interface_set_rx_mode,                                             \
21724   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
21725 _(sw_interface_set_rx_placement,                                        \
21726   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
21727 _(sw_interface_rx_placement_dump,                                       \
21728   "[<intfc> | sw_if_index <id>]")                                         \
21729 _(sw_interface_set_table,                                               \
21730   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
21731 _(sw_interface_set_mpls_enable,                                         \
21732   "<intfc> | sw_if_index [disable | dis]")                              \
21733 _(sw_interface_set_vpath,                                               \
21734   "<intfc> | sw_if_index <id> enable | disable")                        \
21735 _(sw_interface_set_vxlan_bypass,                                        \
21736   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21737 _(sw_interface_set_geneve_bypass,                                       \
21738   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21739 _(sw_interface_set_l2_xconnect,                                         \
21740   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21741   "enable | disable")                                                   \
21742 _(sw_interface_set_l2_bridge,                                           \
21743   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
21744   "[shg <split-horizon-group>] [bvi]\n"                                 \
21745   "enable | disable")                                                   \
21746 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
21747 _(bridge_domain_add_del,                                                \
21748   "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") \
21749 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
21750 _(l2fib_add_del,                                                        \
21751   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
21752 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
21753 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
21754 _(l2_flags,                                                             \
21755   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21756 _(bridge_flags,                                                         \
21757   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21758 _(tap_create_v2,                                                        \
21759   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>] [host-mtu-size <mtu>] [gso | no-gso]") \
21760 _(tap_delete_v2,                                                        \
21761   "<vpp-if-name> | sw_if_index <id>")                                   \
21762 _(sw_interface_tap_v2_dump, "")                                         \
21763 _(virtio_pci_create,                                                    \
21764   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled]") \
21765 _(virtio_pci_delete,                                                    \
21766   "<vpp-if-name> | sw_if_index <id>")                                   \
21767 _(sw_interface_virtio_pci_dump, "")                                     \
21768 _(bond_create,                                                          \
21769   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
21770   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
21771   "[id <if-id>]")                                                       \
21772 _(bond_delete,                                                          \
21773   "<vpp-if-name> | sw_if_index <id>")                                   \
21774 _(bond_enslave,                                                         \
21775   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
21776 _(bond_detach_slave,                                                    \
21777   "sw_if_index <n>")                                                    \
21778  _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
21779 _(sw_interface_bond_dump, "")                                           \
21780 _(sw_interface_slave_dump,                                              \
21781   "<vpp-if-name> | sw_if_index <id>")                                   \
21782 _(ip_table_add_del,                                                     \
21783   "table <n> [ipv6] [add | del]\n")                                     \
21784 _(ip_route_add_del,                                                     \
21785   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
21786   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
21787   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
21788   "[multipath] [count <n>] [del]")                                      \
21789 _(ip_mroute_add_del,                                                    \
21790   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
21791   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
21792 _(mpls_table_add_del,                                                   \
21793   "table <n> [add | del]\n")                                            \
21794 _(mpls_route_add_del,                                                   \
21795   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
21796   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
21797   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
21798   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
21799   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
21800   "[count <n>] [del]")                                                  \
21801 _(mpls_ip_bind_unbind,                                                  \
21802   "<label> <addr/len>")                                                 \
21803 _(mpls_tunnel_add_del,                                                  \
21804   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
21805   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
21806   "[l2-only]  [out-label <n>]")                                         \
21807 _(sr_mpls_policy_add,                                                   \
21808   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
21809 _(sr_mpls_policy_del,                                                   \
21810   "bsid <id>")                                                          \
21811 _(bier_table_add_del,                                                   \
21812   "<label> <sub-domain> <set> <bsl> [del]")                             \
21813 _(bier_route_add_del,                                                   \
21814   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
21815   "[<intfc> | sw_if_index <id>]"                                        \
21816   "[weight <n>] [del] [multipath]")                                     \
21817 _(proxy_arp_add_del,                                                    \
21818   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
21819 _(proxy_arp_intfc_enable_disable,                                       \
21820   "<intfc> | sw_if_index <id> enable | disable")                        \
21821 _(sw_interface_set_unnumbered,                                          \
21822   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
21823 _(ip_neighbor_add_del,                                                  \
21824   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
21825   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
21826 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
21827 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
21828   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
21829   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
21830   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
21831 _(reset_fib, "vrf <n> [ipv6]")                                          \
21832 _(dhcp_proxy_config,                                                    \
21833   "svr <v46-address> src <v46-address>\n"                               \
21834    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
21835 _(dhcp_proxy_set_vss,                                                   \
21836   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
21837 _(dhcp_proxy_dump, "ip6")                                               \
21838 _(dhcp_client_config,                                                   \
21839   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
21840 _(set_ip_flow_hash,                                                     \
21841   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
21842 _(sw_interface_ip6_enable_disable,                                      \
21843   "<intfc> | sw_if_index <id> enable | disable")                        \
21844 _(ip6nd_proxy_add_del,                                                  \
21845   "<intfc> | sw_if_index <id> <ip6-address>")                           \
21846 _(ip6nd_proxy_dump, "")                                                 \
21847 _(sw_interface_ip6nd_ra_prefix,                                         \
21848   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
21849   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
21850   "[nolink] [isno]")                                                    \
21851 _(sw_interface_ip6nd_ra_config,                                         \
21852   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
21853   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
21854   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
21855 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
21856 _(l2_patch_add_del,                                                     \
21857   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21858   "enable | disable")                                                   \
21859 _(sr_localsid_add_del,                                                  \
21860   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
21861   "fib-table <num> (end.psp) sw_if_index <num>")                        \
21862 _(classify_add_del_table,                                               \
21863   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
21864   " [del] [del-chain] mask <mask-value>\n"                              \
21865   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
21866   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
21867 _(classify_add_del_session,                                             \
21868   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
21869   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
21870   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
21871   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
21872 _(classify_set_interface_ip_table,                                      \
21873   "<intfc> | sw_if_index <nn> table <nn>")                              \
21874 _(classify_set_interface_l2_tables,                                     \
21875   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21876   "  [other-table <nn>]")                                               \
21877 _(get_node_index, "node <node-name")                                    \
21878 _(add_node_next, "node <node-name> next <next-node-name>")              \
21879 _(l2tpv3_create_tunnel,                                                 \
21880   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
21881   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
21882   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
21883 _(l2tpv3_set_tunnel_cookies,                                            \
21884   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
21885   "[new_remote_cookie <nn>]\n")                                         \
21886 _(l2tpv3_interface_enable_disable,                                      \
21887   "<intfc> | sw_if_index <nn> enable | disable")                        \
21888 _(l2tpv3_set_lookup_key,                                                \
21889   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
21890 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
21891 _(vxlan_offload_rx,                                                     \
21892   "hw { <interface name> | hw_if_index <nn>} "                          \
21893   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
21894 _(vxlan_add_del_tunnel,                                                 \
21895   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21896   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
21897   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21898 _(geneve_add_del_tunnel,                                                \
21899   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21900   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21901   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21902 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
21903 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
21904 _(gre_tunnel_add_del,                                                   \
21905   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
21906   "[teb | erspan <session-id>] [del]")                                  \
21907 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
21908 _(l2_fib_clear_table, "")                                               \
21909 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
21910 _(l2_interface_vlan_tag_rewrite,                                        \
21911   "<intfc> | sw_if_index <nn> \n"                                       \
21912   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
21913   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
21914 _(create_vhost_user_if,                                                 \
21915         "socket <filename> [server] [renumber <dev_instance>] "         \
21916         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
21917         "[mac <mac_address>]")                                          \
21918 _(modify_vhost_user_if,                                                 \
21919         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
21920         "[server] [renumber <dev_instance>] [gso]")                     \
21921 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
21922 _(sw_interface_vhost_user_dump, "")                                     \
21923 _(show_version, "")                                                     \
21924 _(show_threads, "")                                                     \
21925 _(vxlan_gpe_add_del_tunnel,                                             \
21926   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
21927   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21928   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
21929   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
21930 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
21931 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
21932 _(interface_name_renumber,                                              \
21933   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
21934 _(input_acl_set_interface,                                              \
21935   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21936   "  [l2-table <nn>] [del]")                                            \
21937 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
21938 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
21939   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
21940 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
21941 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
21942 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
21943 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
21944 _(ip_dump, "ipv4 | ipv6")                                               \
21945 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
21946 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
21947   "  spid_id <n> ")                                                     \
21948 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
21949   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
21950   "  integ_alg <alg> integ_key <hex>")                                  \
21951 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
21952   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
21953   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
21954   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
21955 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
21956   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
21957   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
21958   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
21959   "  [instance <n>]")     \
21960 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
21961 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
21962 _(delete_loopback,"sw_if_index <nn>")                                   \
21963 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
21964 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
21965 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
21966 _(want_interface_events,  "enable|disable")                             \
21967 _(get_first_msg_id, "client <name>")                                    \
21968 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
21969 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
21970   "fib-id <nn> [ip4][ip6][default]")                                    \
21971 _(get_node_graph, " ")                                                  \
21972 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
21973 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
21974 _(ioam_disable, "")                                                     \
21975 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
21976                             " sw_if_index <sw_if_index> p <priority> "  \
21977                             "w <weight>] [del]")                        \
21978 _(one_add_del_locator, "locator-set <locator_name> "                    \
21979                         "iface <intf> | sw_if_index <sw_if_index> "     \
21980                         "p <priority> w <weight> [del]")                \
21981 _(one_add_del_local_eid,"vni <vni> eid "                                \
21982                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21983                          "locator-set <locator_name> [del]"             \
21984                          "[key-id sha1|sha256 secret-key <secret-key>]")\
21985 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
21986 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
21987 _(one_enable_disable, "enable|disable")                                 \
21988 _(one_map_register_enable_disable, "enable|disable")                    \
21989 _(one_map_register_fallback_threshold, "<value>")                       \
21990 _(one_rloc_probe_enable_disable, "enable|disable")                      \
21991 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
21992                                "[seid <seid>] "                         \
21993                                "rloc <locator> p <prio> "               \
21994                                "w <weight> [rloc <loc> ... ] "          \
21995                                "action <action> [del-all]")             \
21996 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
21997                           "<local-eid>")                                \
21998 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
21999 _(one_use_petr, "ip-address> | disable")                                \
22000 _(one_map_request_mode, "src-dst|dst-only")                             \
22001 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
22002 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
22003 _(one_locator_set_dump, "[local | remote]")                             \
22004 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
22005 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
22006                        "[local] | [remote]")                            \
22007 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
22008 _(one_ndp_bd_get, "")                                                   \
22009 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
22010 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
22011 _(one_l2_arp_bd_get, "")                                                \
22012 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
22013 _(one_stats_enable_disable, "enable|disable")                           \
22014 _(show_one_stats_enable_disable, "")                                    \
22015 _(one_eid_table_vni_dump, "")                                           \
22016 _(one_eid_table_map_dump, "l2|l3")                                      \
22017 _(one_map_resolver_dump, "")                                            \
22018 _(one_map_server_dump, "")                                              \
22019 _(one_adjacencies_get, "vni <vni>")                                     \
22020 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
22021 _(show_one_rloc_probe_state, "")                                        \
22022 _(show_one_map_register_state, "")                                      \
22023 _(show_one_status, "")                                                  \
22024 _(one_stats_dump, "")                                                   \
22025 _(one_stats_flush, "")                                                  \
22026 _(one_get_map_request_itr_rlocs, "")                                    \
22027 _(one_map_register_set_ttl, "<ttl>")                                    \
22028 _(one_set_transport_protocol, "udp|api")                                \
22029 _(one_get_transport_protocol, "")                                       \
22030 _(one_enable_disable_xtr_mode, "enable|disable")                        \
22031 _(one_show_xtr_mode, "")                                                \
22032 _(one_enable_disable_pitr_mode, "enable|disable")                       \
22033 _(one_show_pitr_mode, "")                                               \
22034 _(one_enable_disable_petr_mode, "enable|disable")                       \
22035 _(one_show_petr_mode, "")                                               \
22036 _(show_one_nsh_mapping, "")                                             \
22037 _(show_one_pitr, "")                                                    \
22038 _(show_one_use_petr, "")                                                \
22039 _(show_one_map_request_mode, "")                                        \
22040 _(show_one_map_register_ttl, "")                                        \
22041 _(show_one_map_register_fallback_threshold, "")                         \
22042 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
22043                             " sw_if_index <sw_if_index> p <priority> "  \
22044                             "w <weight>] [del]")                        \
22045 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
22046                         "iface <intf> | sw_if_index <sw_if_index> "     \
22047                         "p <priority> w <weight> [del]")                \
22048 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
22049                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22050                          "locator-set <locator_name> [del]"             \
22051                          "[key-id sha1|sha256 secret-key <secret-key>]") \
22052 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
22053 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
22054 _(lisp_enable_disable, "enable|disable")                                \
22055 _(lisp_map_register_enable_disable, "enable|disable")                   \
22056 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
22057 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
22058                                "[seid <seid>] "                         \
22059                                "rloc <locator> p <prio> "               \
22060                                "w <weight> [rloc <loc> ... ] "          \
22061                                "action <action> [del-all]")             \
22062 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
22063                           "<local-eid>")                                \
22064 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
22065 _(lisp_use_petr, "<ip-address> | disable")                              \
22066 _(lisp_map_request_mode, "src-dst|dst-only")                            \
22067 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
22068 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
22069 _(lisp_locator_set_dump, "[local | remote]")                            \
22070 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
22071 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
22072                        "[local] | [remote]")                            \
22073 _(lisp_eid_table_vni_dump, "")                                          \
22074 _(lisp_eid_table_map_dump, "l2|l3")                                     \
22075 _(lisp_map_resolver_dump, "")                                           \
22076 _(lisp_map_server_dump, "")                                             \
22077 _(lisp_adjacencies_get, "vni <vni>")                                    \
22078 _(gpe_fwd_entry_vnis_get, "")                                           \
22079 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
22080 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
22081                                 "[table <table-id>]")                   \
22082 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
22083 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
22084 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
22085 _(gpe_get_encap_mode, "")                                               \
22086 _(lisp_gpe_add_del_iface, "up|down")                                    \
22087 _(lisp_gpe_enable_disable, "enable|disable")                            \
22088 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
22089   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
22090 _(show_lisp_rloc_probe_state, "")                                       \
22091 _(show_lisp_map_register_state, "")                                     \
22092 _(show_lisp_status, "")                                                 \
22093 _(lisp_get_map_request_itr_rlocs, "")                                   \
22094 _(show_lisp_pitr, "")                                                   \
22095 _(show_lisp_use_petr, "")                                               \
22096 _(show_lisp_map_request_mode, "")                                       \
22097 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
22098 _(af_packet_delete, "name <host interface name>")                       \
22099 _(af_packet_dump, "")                                                   \
22100 _(policer_add_del, "name <policer name> <params> [del]")                \
22101 _(policer_dump, "[name <policer name>]")                                \
22102 _(policer_classify_set_interface,                                       \
22103   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22104   "  [l2-table <nn>] [del]")                                            \
22105 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
22106 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
22107     "[master|slave]")                                                   \
22108 _(netmap_delete, "name <interface name>")                               \
22109 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
22110 _(mpls_table_dump, "")                                                  \
22111 _(mpls_route_dump, "table-id <ID>")                                     \
22112 _(classify_table_ids, "")                                               \
22113 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
22114 _(classify_table_info, "table_id <nn>")                                 \
22115 _(classify_session_dump, "table_id <nn>")                               \
22116 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
22117     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
22118     "[template_interval <nn>] [udp_checksum]")                          \
22119 _(ipfix_exporter_dump, "")                                              \
22120 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
22121 _(ipfix_classify_stream_dump, "")                                       \
22122 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
22123 _(ipfix_classify_table_dump, "")                                        \
22124 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
22125 _(sw_interface_span_dump, "[l2]")                                           \
22126 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
22127 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
22128 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
22129 _(pg_enable_disable, "[stream <id>] disable")                           \
22130 _(ip_source_and_port_range_check_add_del,                               \
22131   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
22132 _(ip_source_and_port_range_check_interface_add_del,                     \
22133   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
22134   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
22135 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
22136 _(l2_interface_pbb_tag_rewrite,                                         \
22137   "<intfc> | sw_if_index <nn> \n"                                       \
22138   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
22139   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
22140 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
22141 _(flow_classify_set_interface,                                          \
22142   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
22143 _(flow_classify_dump, "type [ip4|ip6]")                                 \
22144 _(ip_table_dump, "")                                                    \
22145 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
22146 _(ip_mtable_dump, "")                                                   \
22147 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
22148 _(feature_enable_disable, "arc_name <arc_name> "                        \
22149   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
22150 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
22151 "[disable]")                                                            \
22152 _(l2_xconnect_dump, "")                                                 \
22153 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
22154 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
22155 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
22156 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
22157 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
22158 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
22159 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
22160   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
22161 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
22162 _(sock_init_shm, "size <nnn>")                                          \
22163 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
22164 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
22165   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
22166 _(session_rules_dump, "")                                               \
22167 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
22168 _(output_acl_set_interface,                                             \
22169   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22170   "  [l2-table <nn>] [del]")                                            \
22171 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
22172
22173 /* List of command functions, CLI names map directly to functions */
22174 #define foreach_cli_function                                    \
22175 _(comment, "usage: comment <ignore-rest-of-line>")              \
22176 _(dump_interface_table, "usage: dump_interface_table")          \
22177 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
22178 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
22179 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
22180 _(dump_macro_table, "usage: dump_macro_table ")                 \
22181 _(dump_node_table, "usage: dump_node_table")                    \
22182 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
22183 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
22184 _(elog_disable, "usage: elog_disable")                          \
22185 _(elog_enable, "usage: elog_enable")                            \
22186 _(elog_save, "usage: elog_save <filename>")                     \
22187 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
22188 _(echo, "usage: echo <message>")                                \
22189 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
22190 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
22191 _(help, "usage: help")                                          \
22192 _(q, "usage: quit")                                             \
22193 _(quit, "usage: quit")                                          \
22194 _(search_node_table, "usage: search_node_table <name>...")      \
22195 _(set, "usage: set <variable-name> <value>")                    \
22196 _(script, "usage: script <file-name>")                          \
22197 _(statseg, "usage: statseg")                                    \
22198 _(unset, "usage: unset <variable-name>")
22199
22200 #define _(N,n)                                  \
22201     static void vl_api_##n##_t_handler_uni      \
22202     (vl_api_##n##_t * mp)                       \
22203     {                                           \
22204         vat_main_t * vam = &vat_main;           \
22205         if (vam->json_output) {                 \
22206             vl_api_##n##_t_handler_json(mp);    \
22207         } else {                                \
22208             vl_api_##n##_t_handler(mp);         \
22209         }                                       \
22210     }
22211 foreach_vpe_api_reply_msg;
22212 #if VPP_API_TEST_BUILTIN == 0
22213 foreach_standalone_reply_msg;
22214 #endif
22215 #undef _
22216
22217 void
22218 vat_api_hookup (vat_main_t * vam)
22219 {
22220 #define _(N,n)                                                  \
22221     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
22222                            vl_api_##n##_t_handler_uni,          \
22223                            vl_noop_handler,                     \
22224                            vl_api_##n##_t_endian,               \
22225                            vl_api_##n##_t_print,                \
22226                            sizeof(vl_api_##n##_t), 1);
22227   foreach_vpe_api_reply_msg;
22228 #if VPP_API_TEST_BUILTIN == 0
22229   foreach_standalone_reply_msg;
22230 #endif
22231 #undef _
22232
22233 #if (VPP_API_TEST_BUILTIN==0)
22234   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
22235
22236   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
22237
22238   vam->function_by_name = hash_create_string (0, sizeof (uword));
22239
22240   vam->help_by_name = hash_create_string (0, sizeof (uword));
22241 #endif
22242
22243   /* API messages we can send */
22244 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
22245   foreach_vpe_api_msg;
22246 #undef _
22247
22248   /* Help strings */
22249 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22250   foreach_vpe_api_msg;
22251 #undef _
22252
22253   /* CLI functions */
22254 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
22255   foreach_cli_function;
22256 #undef _
22257
22258   /* Help strings */
22259 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22260   foreach_cli_function;
22261 #undef _
22262 }
22263
22264 #if VPP_API_TEST_BUILTIN
22265 static clib_error_t *
22266 vat_api_hookup_shim (vlib_main_t * vm)
22267 {
22268   vat_api_hookup (&vat_main);
22269   return 0;
22270 }
22271
22272 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
22273 #endif
22274
22275 /*
22276  * fd.io coding-style-patch-verification: ON
22277  *
22278  * Local Variables:
22279  * eval: (c-set-style "gnu")
22280  * End:
22281  */