api: autogenerate api trace print/endian
[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 %s hostname %s host_addr %U "
2675               "host_mac %U router_addr %U",
2676               ntohl (mp->pid), mp->lease.is_ipv6 ? "ipv6" : "ipv4",
2677               mp->lease.hostname,
2678               format_ip4_address, mp->lease.host_address,
2679               format_ethernet_address, mp->lease.host_mac,
2680               format_ip4_address, mp->lease.router_address);
2681
2682   for (i = 0; i < mp->lease.count; i++)
2683     s =
2684       format (s, " domain_server_addr %U", format_ip4_address,
2685               mp->lease.domain_server[i].address);
2686
2687   errmsg ((char *) s);
2688   vec_free (s);
2689 }
2690
2691 static void vl_api_dhcp_compl_event_t_handler_json
2692   (vl_api_dhcp_compl_event_t * mp)
2693 {
2694   /* JSON output not supported */
2695 }
2696
2697 static void vl_api_get_first_msg_id_reply_t_handler
2698   (vl_api_get_first_msg_id_reply_t * mp)
2699 {
2700   vat_main_t *vam = &vat_main;
2701   i32 retval = ntohl (mp->retval);
2702
2703   if (vam->async_mode)
2704     {
2705       vam->async_errors += (retval < 0);
2706     }
2707   else
2708     {
2709       vam->retval = retval;
2710       vam->result_ready = 1;
2711     }
2712   if (retval >= 0)
2713     {
2714       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2715     }
2716 }
2717
2718 static void vl_api_get_first_msg_id_reply_t_handler_json
2719   (vl_api_get_first_msg_id_reply_t * mp)
2720 {
2721   vat_main_t *vam = &vat_main;
2722   vat_json_node_t node;
2723
2724   vat_json_init_object (&node);
2725   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2726   vat_json_object_add_uint (&node, "first_msg_id",
2727                             (uint) ntohs (mp->first_msg_id));
2728
2729   vat_json_print (vam->ofp, &node);
2730   vat_json_free (&node);
2731
2732   vam->retval = ntohl (mp->retval);
2733   vam->result_ready = 1;
2734 }
2735
2736 static void vl_api_get_node_graph_reply_t_handler
2737   (vl_api_get_node_graph_reply_t * mp)
2738 {
2739   vat_main_t *vam = &vat_main;
2740   api_main_t *am = &api_main;
2741   i32 retval = ntohl (mp->retval);
2742   u8 *pvt_copy, *reply;
2743   void *oldheap;
2744   vlib_node_t *node;
2745   int i;
2746
2747   if (vam->async_mode)
2748     {
2749       vam->async_errors += (retval < 0);
2750     }
2751   else
2752     {
2753       vam->retval = retval;
2754       vam->result_ready = 1;
2755     }
2756
2757   /* "Should never happen..." */
2758   if (retval != 0)
2759     return;
2760
2761   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2762   pvt_copy = vec_dup (reply);
2763
2764   /* Toss the shared-memory original... */
2765   pthread_mutex_lock (&am->vlib_rp->mutex);
2766   oldheap = svm_push_data_heap (am->vlib_rp);
2767
2768   vec_free (reply);
2769
2770   svm_pop_heap (oldheap);
2771   pthread_mutex_unlock (&am->vlib_rp->mutex);
2772
2773   if (vam->graph_nodes)
2774     {
2775       hash_free (vam->graph_node_index_by_name);
2776
2777       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2778         {
2779           node = vam->graph_nodes[0][i];
2780           vec_free (node->name);
2781           vec_free (node->next_nodes);
2782           vec_free (node);
2783         }
2784       vec_free (vam->graph_nodes[0]);
2785       vec_free (vam->graph_nodes);
2786     }
2787
2788   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2789   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2790   vec_free (pvt_copy);
2791
2792   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2793     {
2794       node = vam->graph_nodes[0][i];
2795       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2796     }
2797 }
2798
2799 static void vl_api_get_node_graph_reply_t_handler_json
2800   (vl_api_get_node_graph_reply_t * mp)
2801 {
2802   vat_main_t *vam = &vat_main;
2803   api_main_t *am = &api_main;
2804   void *oldheap;
2805   vat_json_node_t node;
2806   u8 *reply;
2807
2808   /* $$$$ make this real? */
2809   vat_json_init_object (&node);
2810   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2811   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2812
2813   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2814
2815   /* Toss the shared-memory original... */
2816   pthread_mutex_lock (&am->vlib_rp->mutex);
2817   oldheap = svm_push_data_heap (am->vlib_rp);
2818
2819   vec_free (reply);
2820
2821   svm_pop_heap (oldheap);
2822   pthread_mutex_unlock (&am->vlib_rp->mutex);
2823
2824   vat_json_print (vam->ofp, &node);
2825   vat_json_free (&node);
2826
2827   vam->retval = ntohl (mp->retval);
2828   vam->result_ready = 1;
2829 }
2830
2831 static void
2832 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2833 {
2834   vat_main_t *vam = &vat_main;
2835   u8 *s = 0;
2836
2837   if (mp->local)
2838     {
2839       s = format (s, "%=16d%=16d%=16d",
2840                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2841     }
2842   else
2843     {
2844       s = format (s, "%=16U%=16d%=16d",
2845                   mp->is_ipv6 ? format_ip6_address :
2846                   format_ip4_address,
2847                   mp->ip_address, mp->priority, mp->weight);
2848     }
2849
2850   print (vam->ofp, "%v", s);
2851   vec_free (s);
2852 }
2853
2854 static void
2855 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2856 {
2857   vat_main_t *vam = &vat_main;
2858   vat_json_node_t *node = NULL;
2859   struct in6_addr ip6;
2860   struct in_addr ip4;
2861
2862   if (VAT_JSON_ARRAY != vam->json_tree.type)
2863     {
2864       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2865       vat_json_init_array (&vam->json_tree);
2866     }
2867   node = vat_json_array_add (&vam->json_tree);
2868   vat_json_init_object (node);
2869
2870   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2871   vat_json_object_add_uint (node, "priority", mp->priority);
2872   vat_json_object_add_uint (node, "weight", mp->weight);
2873
2874   if (mp->local)
2875     vat_json_object_add_uint (node, "sw_if_index",
2876                               clib_net_to_host_u32 (mp->sw_if_index));
2877   else
2878     {
2879       if (mp->is_ipv6)
2880         {
2881           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2882           vat_json_object_add_ip6 (node, "address", ip6);
2883         }
2884       else
2885         {
2886           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2887           vat_json_object_add_ip4 (node, "address", ip4);
2888         }
2889     }
2890 }
2891
2892 static void
2893 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2894                                           mp)
2895 {
2896   vat_main_t *vam = &vat_main;
2897   u8 *ls_name = 0;
2898
2899   ls_name = format (0, "%s", mp->ls_name);
2900
2901   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2902          ls_name);
2903   vec_free (ls_name);
2904 }
2905
2906 static void
2907   vl_api_one_locator_set_details_t_handler_json
2908   (vl_api_one_locator_set_details_t * mp)
2909 {
2910   vat_main_t *vam = &vat_main;
2911   vat_json_node_t *node = 0;
2912   u8 *ls_name = 0;
2913
2914   ls_name = format (0, "%s", mp->ls_name);
2915   vec_add1 (ls_name, 0);
2916
2917   if (VAT_JSON_ARRAY != vam->json_tree.type)
2918     {
2919       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2920       vat_json_init_array (&vam->json_tree);
2921     }
2922   node = vat_json_array_add (&vam->json_tree);
2923
2924   vat_json_init_object (node);
2925   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2926   vat_json_object_add_uint (node, "ls_index",
2927                             clib_net_to_host_u32 (mp->ls_index));
2928   vec_free (ls_name);
2929 }
2930
2931 typedef struct
2932 {
2933   u32 spi;
2934   u8 si;
2935 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2936
2937 uword
2938 unformat_nsh_address (unformat_input_t * input, va_list * args)
2939 {
2940   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2941   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2942 }
2943
2944 u8 *
2945 format_nsh_address_vat (u8 * s, va_list * args)
2946 {
2947   nsh_t *a = va_arg (*args, nsh_t *);
2948   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2949 }
2950
2951 static u8 *
2952 format_lisp_flat_eid (u8 * s, va_list * args)
2953 {
2954   u32 type = va_arg (*args, u32);
2955   u8 *eid = va_arg (*args, u8 *);
2956   u32 eid_len = va_arg (*args, u32);
2957
2958   switch (type)
2959     {
2960     case 0:
2961       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2962     case 1:
2963       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2964     case 2:
2965       return format (s, "%U", format_ethernet_address, eid);
2966     case 3:
2967       return format (s, "%U", format_nsh_address_vat, eid);
2968     }
2969   return 0;
2970 }
2971
2972 static u8 *
2973 format_lisp_eid_vat (u8 * s, va_list * args)
2974 {
2975   u32 type = va_arg (*args, u32);
2976   u8 *eid = va_arg (*args, u8 *);
2977   u32 eid_len = va_arg (*args, u32);
2978   u8 *seid = va_arg (*args, u8 *);
2979   u32 seid_len = va_arg (*args, u32);
2980   u32 is_src_dst = va_arg (*args, u32);
2981
2982   if (is_src_dst)
2983     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2984
2985   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2986
2987   return s;
2988 }
2989
2990 static void
2991 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2992 {
2993   vat_main_t *vam = &vat_main;
2994   u8 *s = 0, *eid = 0;
2995
2996   if (~0 == mp->locator_set_index)
2997     s = format (0, "action: %d", mp->action);
2998   else
2999     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3000
3001   eid = format (0, "%U", format_lisp_eid_vat,
3002                 mp->eid_type,
3003                 mp->eid,
3004                 mp->eid_prefix_len,
3005                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3006   vec_add1 (eid, 0);
3007
3008   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3009          clib_net_to_host_u32 (mp->vni),
3010          eid,
3011          mp->is_local ? "local" : "remote",
3012          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3013          clib_net_to_host_u16 (mp->key_id), mp->key);
3014
3015   vec_free (s);
3016   vec_free (eid);
3017 }
3018
3019 static void
3020 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3021                                              * mp)
3022 {
3023   vat_main_t *vam = &vat_main;
3024   vat_json_node_t *node = 0;
3025   u8 *eid = 0;
3026
3027   if (VAT_JSON_ARRAY != vam->json_tree.type)
3028     {
3029       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3030       vat_json_init_array (&vam->json_tree);
3031     }
3032   node = vat_json_array_add (&vam->json_tree);
3033
3034   vat_json_init_object (node);
3035   if (~0 == mp->locator_set_index)
3036     vat_json_object_add_uint (node, "action", mp->action);
3037   else
3038     vat_json_object_add_uint (node, "locator_set_index",
3039                               clib_net_to_host_u32 (mp->locator_set_index));
3040
3041   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3042   if (mp->eid_type == 3)
3043     {
3044       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3045       vat_json_init_object (nsh_json);
3046       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3047       vat_json_object_add_uint (nsh_json, "spi",
3048                                 clib_net_to_host_u32 (nsh->spi));
3049       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3050     }
3051   else
3052     {
3053       eid = format (0, "%U", format_lisp_eid_vat,
3054                     mp->eid_type,
3055                     mp->eid,
3056                     mp->eid_prefix_len,
3057                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3058       vec_add1 (eid, 0);
3059       vat_json_object_add_string_copy (node, "eid", eid);
3060       vec_free (eid);
3061     }
3062   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3063   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3064   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3065
3066   if (mp->key_id)
3067     {
3068       vat_json_object_add_uint (node, "key_id",
3069                                 clib_net_to_host_u16 (mp->key_id));
3070       vat_json_object_add_string_copy (node, "key", mp->key);
3071     }
3072 }
3073
3074 static void
3075 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3076 {
3077   vat_main_t *vam = &vat_main;
3078   u8 *seid = 0, *deid = 0;
3079   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3080
3081   deid = format (0, "%U", format_lisp_eid_vat,
3082                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3083
3084   seid = format (0, "%U", format_lisp_eid_vat,
3085                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3086
3087   vec_add1 (deid, 0);
3088   vec_add1 (seid, 0);
3089
3090   if (mp->is_ip4)
3091     format_ip_address_fcn = format_ip4_address;
3092   else
3093     format_ip_address_fcn = format_ip6_address;
3094
3095
3096   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3097          clib_net_to_host_u32 (mp->vni),
3098          seid, deid,
3099          format_ip_address_fcn, mp->lloc,
3100          format_ip_address_fcn, mp->rloc,
3101          clib_net_to_host_u32 (mp->pkt_count),
3102          clib_net_to_host_u32 (mp->bytes));
3103
3104   vec_free (deid);
3105   vec_free (seid);
3106 }
3107
3108 static void
3109 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3110 {
3111   struct in6_addr ip6;
3112   struct in_addr ip4;
3113   vat_main_t *vam = &vat_main;
3114   vat_json_node_t *node = 0;
3115   u8 *deid = 0, *seid = 0;
3116
3117   if (VAT_JSON_ARRAY != vam->json_tree.type)
3118     {
3119       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3120       vat_json_init_array (&vam->json_tree);
3121     }
3122   node = vat_json_array_add (&vam->json_tree);
3123
3124   vat_json_init_object (node);
3125   deid = format (0, "%U", format_lisp_eid_vat,
3126                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3127
3128   seid = format (0, "%U", format_lisp_eid_vat,
3129                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3130
3131   vec_add1 (deid, 0);
3132   vec_add1 (seid, 0);
3133
3134   vat_json_object_add_string_copy (node, "seid", seid);
3135   vat_json_object_add_string_copy (node, "deid", deid);
3136   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3137
3138   if (mp->is_ip4)
3139     {
3140       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3141       vat_json_object_add_ip4 (node, "lloc", ip4);
3142       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3143       vat_json_object_add_ip4 (node, "rloc", ip4);
3144     }
3145   else
3146     {
3147       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3148       vat_json_object_add_ip6 (node, "lloc", ip6);
3149       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3150       vat_json_object_add_ip6 (node, "rloc", ip6);
3151     }
3152   vat_json_object_add_uint (node, "pkt_count",
3153                             clib_net_to_host_u32 (mp->pkt_count));
3154   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3155
3156   vec_free (deid);
3157   vec_free (seid);
3158 }
3159
3160 static void
3161   vl_api_one_eid_table_map_details_t_handler
3162   (vl_api_one_eid_table_map_details_t * mp)
3163 {
3164   vat_main_t *vam = &vat_main;
3165
3166   u8 *line = format (0, "%=10d%=10d",
3167                      clib_net_to_host_u32 (mp->vni),
3168                      clib_net_to_host_u32 (mp->dp_table));
3169   print (vam->ofp, "%v", line);
3170   vec_free (line);
3171 }
3172
3173 static void
3174   vl_api_one_eid_table_map_details_t_handler_json
3175   (vl_api_one_eid_table_map_details_t * mp)
3176 {
3177   vat_main_t *vam = &vat_main;
3178   vat_json_node_t *node = NULL;
3179
3180   if (VAT_JSON_ARRAY != vam->json_tree.type)
3181     {
3182       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3183       vat_json_init_array (&vam->json_tree);
3184     }
3185   node = vat_json_array_add (&vam->json_tree);
3186   vat_json_init_object (node);
3187   vat_json_object_add_uint (node, "dp_table",
3188                             clib_net_to_host_u32 (mp->dp_table));
3189   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3190 }
3191
3192 static void
3193   vl_api_one_eid_table_vni_details_t_handler
3194   (vl_api_one_eid_table_vni_details_t * mp)
3195 {
3196   vat_main_t *vam = &vat_main;
3197
3198   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3199   print (vam->ofp, "%v", line);
3200   vec_free (line);
3201 }
3202
3203 static void
3204   vl_api_one_eid_table_vni_details_t_handler_json
3205   (vl_api_one_eid_table_vni_details_t * mp)
3206 {
3207   vat_main_t *vam = &vat_main;
3208   vat_json_node_t *node = NULL;
3209
3210   if (VAT_JSON_ARRAY != vam->json_tree.type)
3211     {
3212       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3213       vat_json_init_array (&vam->json_tree);
3214     }
3215   node = vat_json_array_add (&vam->json_tree);
3216   vat_json_init_object (node);
3217   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3218 }
3219
3220 static void
3221   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3222   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3223 {
3224   vat_main_t *vam = &vat_main;
3225   int retval = clib_net_to_host_u32 (mp->retval);
3226
3227   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3228   print (vam->ofp, "fallback threshold value: %d", mp->value);
3229
3230   vam->retval = retval;
3231   vam->result_ready = 1;
3232 }
3233
3234 static void
3235   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3236   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3237 {
3238   vat_main_t *vam = &vat_main;
3239   vat_json_node_t _node, *node = &_node;
3240   int retval = clib_net_to_host_u32 (mp->retval);
3241
3242   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3243   vat_json_init_object (node);
3244   vat_json_object_add_uint (node, "value", mp->value);
3245
3246   vat_json_print (vam->ofp, node);
3247   vat_json_free (node);
3248
3249   vam->retval = retval;
3250   vam->result_ready = 1;
3251 }
3252
3253 static void
3254   vl_api_show_one_map_register_state_reply_t_handler
3255   (vl_api_show_one_map_register_state_reply_t * mp)
3256 {
3257   vat_main_t *vam = &vat_main;
3258   int retval = clib_net_to_host_u32 (mp->retval);
3259
3260   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3261
3262   vam->retval = retval;
3263   vam->result_ready = 1;
3264 }
3265
3266 static void
3267   vl_api_show_one_map_register_state_reply_t_handler_json
3268   (vl_api_show_one_map_register_state_reply_t * mp)
3269 {
3270   vat_main_t *vam = &vat_main;
3271   vat_json_node_t _node, *node = &_node;
3272   int retval = clib_net_to_host_u32 (mp->retval);
3273
3274   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3275
3276   vat_json_init_object (node);
3277   vat_json_object_add_string_copy (node, "state", s);
3278
3279   vat_json_print (vam->ofp, node);
3280   vat_json_free (node);
3281
3282   vam->retval = retval;
3283   vam->result_ready = 1;
3284   vec_free (s);
3285 }
3286
3287 static void
3288   vl_api_show_one_rloc_probe_state_reply_t_handler
3289   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3290 {
3291   vat_main_t *vam = &vat_main;
3292   int retval = clib_net_to_host_u32 (mp->retval);
3293
3294   if (retval)
3295     goto end;
3296
3297   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3298 end:
3299   vam->retval = retval;
3300   vam->result_ready = 1;
3301 }
3302
3303 static void
3304   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3305   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3306 {
3307   vat_main_t *vam = &vat_main;
3308   vat_json_node_t _node, *node = &_node;
3309   int retval = clib_net_to_host_u32 (mp->retval);
3310
3311   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3312   vat_json_init_object (node);
3313   vat_json_object_add_string_copy (node, "state", s);
3314
3315   vat_json_print (vam->ofp, node);
3316   vat_json_free (node);
3317
3318   vam->retval = retval;
3319   vam->result_ready = 1;
3320   vec_free (s);
3321 }
3322
3323 static void
3324   vl_api_show_one_stats_enable_disable_reply_t_handler
3325   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3326 {
3327   vat_main_t *vam = &vat_main;
3328   int retval = clib_net_to_host_u32 (mp->retval);
3329
3330   if (retval)
3331     goto end;
3332
3333   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3334 end:
3335   vam->retval = retval;
3336   vam->result_ready = 1;
3337 }
3338
3339 static void
3340   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3341   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3342 {
3343   vat_main_t *vam = &vat_main;
3344   vat_json_node_t _node, *node = &_node;
3345   int retval = clib_net_to_host_u32 (mp->retval);
3346
3347   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3348   vat_json_init_object (node);
3349   vat_json_object_add_string_copy (node, "state", s);
3350
3351   vat_json_print (vam->ofp, node);
3352   vat_json_free (node);
3353
3354   vam->retval = retval;
3355   vam->result_ready = 1;
3356   vec_free (s);
3357 }
3358
3359 static void
3360 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3361 {
3362   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3363   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3364   e->vni = clib_net_to_host_u32 (e->vni);
3365 }
3366
3367 static void
3368   gpe_fwd_entries_get_reply_t_net_to_host
3369   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3370 {
3371   u32 i;
3372
3373   mp->count = clib_net_to_host_u32 (mp->count);
3374   for (i = 0; i < mp->count; i++)
3375     {
3376       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3377     }
3378 }
3379
3380 static u8 *
3381 format_gpe_encap_mode (u8 * s, va_list * args)
3382 {
3383   u32 mode = va_arg (*args, u32);
3384
3385   switch (mode)
3386     {
3387     case 0:
3388       return format (s, "lisp");
3389     case 1:
3390       return format (s, "vxlan");
3391     }
3392   return 0;
3393 }
3394
3395 static void
3396   vl_api_gpe_get_encap_mode_reply_t_handler
3397   (vl_api_gpe_get_encap_mode_reply_t * mp)
3398 {
3399   vat_main_t *vam = &vat_main;
3400
3401   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3402   vam->retval = ntohl (mp->retval);
3403   vam->result_ready = 1;
3404 }
3405
3406 static void
3407   vl_api_gpe_get_encap_mode_reply_t_handler_json
3408   (vl_api_gpe_get_encap_mode_reply_t * mp)
3409 {
3410   vat_main_t *vam = &vat_main;
3411   vat_json_node_t node;
3412
3413   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3414   vec_add1 (encap_mode, 0);
3415
3416   vat_json_init_object (&node);
3417   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3418
3419   vec_free (encap_mode);
3420   vat_json_print (vam->ofp, &node);
3421   vat_json_free (&node);
3422
3423   vam->retval = ntohl (mp->retval);
3424   vam->result_ready = 1;
3425 }
3426
3427 static void
3428   vl_api_gpe_fwd_entry_path_details_t_handler
3429   (vl_api_gpe_fwd_entry_path_details_t * mp)
3430 {
3431   vat_main_t *vam = &vat_main;
3432   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3433
3434   if (mp->lcl_loc.is_ip4)
3435     format_ip_address_fcn = format_ip4_address;
3436   else
3437     format_ip_address_fcn = format_ip6_address;
3438
3439   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3440          format_ip_address_fcn, &mp->lcl_loc,
3441          format_ip_address_fcn, &mp->rmt_loc);
3442 }
3443
3444 static void
3445 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3446 {
3447   struct in6_addr ip6;
3448   struct in_addr ip4;
3449
3450   if (loc->is_ip4)
3451     {
3452       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3453       vat_json_object_add_ip4 (n, "address", ip4);
3454     }
3455   else
3456     {
3457       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3458       vat_json_object_add_ip6 (n, "address", ip6);
3459     }
3460   vat_json_object_add_uint (n, "weight", loc->weight);
3461 }
3462
3463 static void
3464   vl_api_gpe_fwd_entry_path_details_t_handler_json
3465   (vl_api_gpe_fwd_entry_path_details_t * mp)
3466 {
3467   vat_main_t *vam = &vat_main;
3468   vat_json_node_t *node = NULL;
3469   vat_json_node_t *loc_node;
3470
3471   if (VAT_JSON_ARRAY != vam->json_tree.type)
3472     {
3473       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3474       vat_json_init_array (&vam->json_tree);
3475     }
3476   node = vat_json_array_add (&vam->json_tree);
3477   vat_json_init_object (node);
3478
3479   loc_node = vat_json_object_add (node, "local_locator");
3480   vat_json_init_object (loc_node);
3481   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3482
3483   loc_node = vat_json_object_add (node, "remote_locator");
3484   vat_json_init_object (loc_node);
3485   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3486 }
3487
3488 static void
3489   vl_api_gpe_fwd_entries_get_reply_t_handler
3490   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3491 {
3492   vat_main_t *vam = &vat_main;
3493   u32 i;
3494   int retval = clib_net_to_host_u32 (mp->retval);
3495   vl_api_gpe_fwd_entry_t *e;
3496
3497   if (retval)
3498     goto end;
3499
3500   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3501
3502   for (i = 0; i < mp->count; i++)
3503     {
3504       e = &mp->entries[i];
3505       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3506              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3507              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3508     }
3509
3510 end:
3511   vam->retval = retval;
3512   vam->result_ready = 1;
3513 }
3514
3515 static void
3516   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3517   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3518 {
3519   u8 *s = 0;
3520   vat_main_t *vam = &vat_main;
3521   vat_json_node_t *e = 0, root;
3522   u32 i;
3523   int retval = clib_net_to_host_u32 (mp->retval);
3524   vl_api_gpe_fwd_entry_t *fwd;
3525
3526   if (retval)
3527     goto end;
3528
3529   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3530   vat_json_init_array (&root);
3531
3532   for (i = 0; i < mp->count; i++)
3533     {
3534       e = vat_json_array_add (&root);
3535       fwd = &mp->entries[i];
3536
3537       vat_json_init_object (e);
3538       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3539       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3540       vat_json_object_add_int (e, "vni", fwd->vni);
3541       vat_json_object_add_int (e, "action", fwd->action);
3542
3543       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3544                   fwd->leid_prefix_len);
3545       vec_add1 (s, 0);
3546       vat_json_object_add_string_copy (e, "leid", s);
3547       vec_free (s);
3548
3549       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3550                   fwd->reid_prefix_len);
3551       vec_add1 (s, 0);
3552       vat_json_object_add_string_copy (e, "reid", s);
3553       vec_free (s);
3554     }
3555
3556   vat_json_print (vam->ofp, &root);
3557   vat_json_free (&root);
3558
3559 end:
3560   vam->retval = retval;
3561   vam->result_ready = 1;
3562 }
3563
3564 static void
3565   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3566   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3567 {
3568   vat_main_t *vam = &vat_main;
3569   u32 i, n;
3570   int retval = clib_net_to_host_u32 (mp->retval);
3571   vl_api_gpe_native_fwd_rpath_t *r;
3572
3573   if (retval)
3574     goto end;
3575
3576   n = clib_net_to_host_u32 (mp->count);
3577
3578   for (i = 0; i < n; i++)
3579     {
3580       r = &mp->entries[i];
3581       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3582              clib_net_to_host_u32 (r->fib_index),
3583              clib_net_to_host_u32 (r->nh_sw_if_index),
3584              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3585     }
3586
3587 end:
3588   vam->retval = retval;
3589   vam->result_ready = 1;
3590 }
3591
3592 static void
3593   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3594   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3595 {
3596   vat_main_t *vam = &vat_main;
3597   vat_json_node_t root, *e;
3598   u32 i, n;
3599   int retval = clib_net_to_host_u32 (mp->retval);
3600   vl_api_gpe_native_fwd_rpath_t *r;
3601   u8 *s;
3602
3603   if (retval)
3604     goto end;
3605
3606   n = clib_net_to_host_u32 (mp->count);
3607   vat_json_init_array (&root);
3608
3609   for (i = 0; i < n; i++)
3610     {
3611       e = vat_json_array_add (&root);
3612       vat_json_init_object (e);
3613       r = &mp->entries[i];
3614       s =
3615         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3616                 r->nh_addr);
3617       vec_add1 (s, 0);
3618       vat_json_object_add_string_copy (e, "ip4", s);
3619       vec_free (s);
3620
3621       vat_json_object_add_uint (e, "fib_index",
3622                                 clib_net_to_host_u32 (r->fib_index));
3623       vat_json_object_add_uint (e, "nh_sw_if_index",
3624                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3625     }
3626
3627   vat_json_print (vam->ofp, &root);
3628   vat_json_free (&root);
3629
3630 end:
3631   vam->retval = retval;
3632   vam->result_ready = 1;
3633 }
3634
3635 static void
3636   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3637   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3638 {
3639   vat_main_t *vam = &vat_main;
3640   u32 i, n;
3641   int retval = clib_net_to_host_u32 (mp->retval);
3642
3643   if (retval)
3644     goto end;
3645
3646   n = clib_net_to_host_u32 (mp->count);
3647
3648   for (i = 0; i < n; i++)
3649     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3650
3651 end:
3652   vam->retval = retval;
3653   vam->result_ready = 1;
3654 }
3655
3656 static void
3657   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3658   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3659 {
3660   vat_main_t *vam = &vat_main;
3661   vat_json_node_t root;
3662   u32 i, n;
3663   int retval = clib_net_to_host_u32 (mp->retval);
3664
3665   if (retval)
3666     goto end;
3667
3668   n = clib_net_to_host_u32 (mp->count);
3669   vat_json_init_array (&root);
3670
3671   for (i = 0; i < n; i++)
3672     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3673
3674   vat_json_print (vam->ofp, &root);
3675   vat_json_free (&root);
3676
3677 end:
3678   vam->retval = retval;
3679   vam->result_ready = 1;
3680 }
3681
3682 static void
3683   vl_api_one_ndp_entries_get_reply_t_handler
3684   (vl_api_one_ndp_entries_get_reply_t * mp)
3685 {
3686   vat_main_t *vam = &vat_main;
3687   u32 i, n;
3688   int retval = clib_net_to_host_u32 (mp->retval);
3689
3690   if (retval)
3691     goto end;
3692
3693   n = clib_net_to_host_u32 (mp->count);
3694
3695   for (i = 0; i < n; i++)
3696     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3697            format_ethernet_address, mp->entries[i].mac);
3698
3699 end:
3700   vam->retval = retval;
3701   vam->result_ready = 1;
3702 }
3703
3704 static void
3705   vl_api_one_ndp_entries_get_reply_t_handler_json
3706   (vl_api_one_ndp_entries_get_reply_t * mp)
3707 {
3708   u8 *s = 0;
3709   vat_main_t *vam = &vat_main;
3710   vat_json_node_t *e = 0, root;
3711   u32 i, n;
3712   int retval = clib_net_to_host_u32 (mp->retval);
3713   vl_api_one_ndp_entry_t *arp_entry;
3714
3715   if (retval)
3716     goto end;
3717
3718   n = clib_net_to_host_u32 (mp->count);
3719   vat_json_init_array (&root);
3720
3721   for (i = 0; i < n; i++)
3722     {
3723       e = vat_json_array_add (&root);
3724       arp_entry = &mp->entries[i];
3725
3726       vat_json_init_object (e);
3727       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3728       vec_add1 (s, 0);
3729
3730       vat_json_object_add_string_copy (e, "mac", s);
3731       vec_free (s);
3732
3733       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3734       vec_add1 (s, 0);
3735       vat_json_object_add_string_copy (e, "ip6", s);
3736       vec_free (s);
3737     }
3738
3739   vat_json_print (vam->ofp, &root);
3740   vat_json_free (&root);
3741
3742 end:
3743   vam->retval = retval;
3744   vam->result_ready = 1;
3745 }
3746
3747 static void
3748   vl_api_one_l2_arp_entries_get_reply_t_handler
3749   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3750 {
3751   vat_main_t *vam = &vat_main;
3752   u32 i, n;
3753   int retval = clib_net_to_host_u32 (mp->retval);
3754
3755   if (retval)
3756     goto end;
3757
3758   n = clib_net_to_host_u32 (mp->count);
3759
3760   for (i = 0; i < n; i++)
3761     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3762            format_ethernet_address, mp->entries[i].mac);
3763
3764 end:
3765   vam->retval = retval;
3766   vam->result_ready = 1;
3767 }
3768
3769 static void
3770   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3771   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3772 {
3773   u8 *s = 0;
3774   vat_main_t *vam = &vat_main;
3775   vat_json_node_t *e = 0, root;
3776   u32 i, n;
3777   int retval = clib_net_to_host_u32 (mp->retval);
3778   vl_api_one_l2_arp_entry_t *arp_entry;
3779
3780   if (retval)
3781     goto end;
3782
3783   n = clib_net_to_host_u32 (mp->count);
3784   vat_json_init_array (&root);
3785
3786   for (i = 0; i < n; i++)
3787     {
3788       e = vat_json_array_add (&root);
3789       arp_entry = &mp->entries[i];
3790
3791       vat_json_init_object (e);
3792       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3793       vec_add1 (s, 0);
3794
3795       vat_json_object_add_string_copy (e, "mac", s);
3796       vec_free (s);
3797
3798       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3799       vec_add1 (s, 0);
3800       vat_json_object_add_string_copy (e, "ip4", s);
3801       vec_free (s);
3802     }
3803
3804   vat_json_print (vam->ofp, &root);
3805   vat_json_free (&root);
3806
3807 end:
3808   vam->retval = retval;
3809   vam->result_ready = 1;
3810 }
3811
3812 static void
3813 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3814 {
3815   vat_main_t *vam = &vat_main;
3816   u32 i, n;
3817   int retval = clib_net_to_host_u32 (mp->retval);
3818
3819   if (retval)
3820     goto end;
3821
3822   n = clib_net_to_host_u32 (mp->count);
3823
3824   for (i = 0; i < n; i++)
3825     {
3826       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3827     }
3828
3829 end:
3830   vam->retval = retval;
3831   vam->result_ready = 1;
3832 }
3833
3834 static void
3835   vl_api_one_ndp_bd_get_reply_t_handler_json
3836   (vl_api_one_ndp_bd_get_reply_t * mp)
3837 {
3838   vat_main_t *vam = &vat_main;
3839   vat_json_node_t root;
3840   u32 i, n;
3841   int retval = clib_net_to_host_u32 (mp->retval);
3842
3843   if (retval)
3844     goto end;
3845
3846   n = clib_net_to_host_u32 (mp->count);
3847   vat_json_init_array (&root);
3848
3849   for (i = 0; i < n; i++)
3850     {
3851       vat_json_array_add_uint (&root,
3852                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3853     }
3854
3855   vat_json_print (vam->ofp, &root);
3856   vat_json_free (&root);
3857
3858 end:
3859   vam->retval = retval;
3860   vam->result_ready = 1;
3861 }
3862
3863 static void
3864   vl_api_one_l2_arp_bd_get_reply_t_handler
3865   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3866 {
3867   vat_main_t *vam = &vat_main;
3868   u32 i, n;
3869   int retval = clib_net_to_host_u32 (mp->retval);
3870
3871   if (retval)
3872     goto end;
3873
3874   n = clib_net_to_host_u32 (mp->count);
3875
3876   for (i = 0; i < n; i++)
3877     {
3878       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3879     }
3880
3881 end:
3882   vam->retval = retval;
3883   vam->result_ready = 1;
3884 }
3885
3886 static void
3887   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3888   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3889 {
3890   vat_main_t *vam = &vat_main;
3891   vat_json_node_t root;
3892   u32 i, n;
3893   int retval = clib_net_to_host_u32 (mp->retval);
3894
3895   if (retval)
3896     goto end;
3897
3898   n = clib_net_to_host_u32 (mp->count);
3899   vat_json_init_array (&root);
3900
3901   for (i = 0; i < n; i++)
3902     {
3903       vat_json_array_add_uint (&root,
3904                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3905     }
3906
3907   vat_json_print (vam->ofp, &root);
3908   vat_json_free (&root);
3909
3910 end:
3911   vam->retval = retval;
3912   vam->result_ready = 1;
3913 }
3914
3915 static void
3916   vl_api_one_adjacencies_get_reply_t_handler
3917   (vl_api_one_adjacencies_get_reply_t * mp)
3918 {
3919   vat_main_t *vam = &vat_main;
3920   u32 i, n;
3921   int retval = clib_net_to_host_u32 (mp->retval);
3922   vl_api_one_adjacency_t *a;
3923
3924   if (retval)
3925     goto end;
3926
3927   n = clib_net_to_host_u32 (mp->count);
3928
3929   for (i = 0; i < n; i++)
3930     {
3931       a = &mp->adjacencies[i];
3932       print (vam->ofp, "%U %40U",
3933              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3934              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3935     }
3936
3937 end:
3938   vam->retval = retval;
3939   vam->result_ready = 1;
3940 }
3941
3942 static void
3943   vl_api_one_adjacencies_get_reply_t_handler_json
3944   (vl_api_one_adjacencies_get_reply_t * mp)
3945 {
3946   u8 *s = 0;
3947   vat_main_t *vam = &vat_main;
3948   vat_json_node_t *e = 0, root;
3949   u32 i, n;
3950   int retval = clib_net_to_host_u32 (mp->retval);
3951   vl_api_one_adjacency_t *a;
3952
3953   if (retval)
3954     goto end;
3955
3956   n = clib_net_to_host_u32 (mp->count);
3957   vat_json_init_array (&root);
3958
3959   for (i = 0; i < n; i++)
3960     {
3961       e = vat_json_array_add (&root);
3962       a = &mp->adjacencies[i];
3963
3964       vat_json_init_object (e);
3965       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3966                   a->leid_prefix_len);
3967       vec_add1 (s, 0);
3968       vat_json_object_add_string_copy (e, "leid", s);
3969       vec_free (s);
3970
3971       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3972                   a->reid_prefix_len);
3973       vec_add1 (s, 0);
3974       vat_json_object_add_string_copy (e, "reid", s);
3975       vec_free (s);
3976     }
3977
3978   vat_json_print (vam->ofp, &root);
3979   vat_json_free (&root);
3980
3981 end:
3982   vam->retval = retval;
3983   vam->result_ready = 1;
3984 }
3985
3986 static void
3987 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3988 {
3989   vat_main_t *vam = &vat_main;
3990
3991   print (vam->ofp, "%=20U",
3992          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3993          mp->ip_address);
3994 }
3995
3996 static void
3997   vl_api_one_map_server_details_t_handler_json
3998   (vl_api_one_map_server_details_t * mp)
3999 {
4000   vat_main_t *vam = &vat_main;
4001   vat_json_node_t *node = NULL;
4002   struct in6_addr ip6;
4003   struct in_addr ip4;
4004
4005   if (VAT_JSON_ARRAY != vam->json_tree.type)
4006     {
4007       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4008       vat_json_init_array (&vam->json_tree);
4009     }
4010   node = vat_json_array_add (&vam->json_tree);
4011
4012   vat_json_init_object (node);
4013   if (mp->is_ipv6)
4014     {
4015       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4016       vat_json_object_add_ip6 (node, "map-server", ip6);
4017     }
4018   else
4019     {
4020       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4021       vat_json_object_add_ip4 (node, "map-server", ip4);
4022     }
4023 }
4024
4025 static void
4026 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4027                                            * mp)
4028 {
4029   vat_main_t *vam = &vat_main;
4030
4031   print (vam->ofp, "%=20U",
4032          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4033          mp->ip_address);
4034 }
4035
4036 static void
4037   vl_api_one_map_resolver_details_t_handler_json
4038   (vl_api_one_map_resolver_details_t * mp)
4039 {
4040   vat_main_t *vam = &vat_main;
4041   vat_json_node_t *node = NULL;
4042   struct in6_addr ip6;
4043   struct in_addr ip4;
4044
4045   if (VAT_JSON_ARRAY != vam->json_tree.type)
4046     {
4047       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4048       vat_json_init_array (&vam->json_tree);
4049     }
4050   node = vat_json_array_add (&vam->json_tree);
4051
4052   vat_json_init_object (node);
4053   if (mp->is_ipv6)
4054     {
4055       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4056       vat_json_object_add_ip6 (node, "map resolver", ip6);
4057     }
4058   else
4059     {
4060       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4061       vat_json_object_add_ip4 (node, "map resolver", ip4);
4062     }
4063 }
4064
4065 static void
4066 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4067 {
4068   vat_main_t *vam = &vat_main;
4069   i32 retval = ntohl (mp->retval);
4070
4071   if (0 <= retval)
4072     {
4073       print (vam->ofp, "feature: %s\ngpe: %s",
4074              mp->feature_status ? "enabled" : "disabled",
4075              mp->gpe_status ? "enabled" : "disabled");
4076     }
4077
4078   vam->retval = retval;
4079   vam->result_ready = 1;
4080 }
4081
4082 static void
4083   vl_api_show_one_status_reply_t_handler_json
4084   (vl_api_show_one_status_reply_t * mp)
4085 {
4086   vat_main_t *vam = &vat_main;
4087   vat_json_node_t node;
4088   u8 *gpe_status = NULL;
4089   u8 *feature_status = NULL;
4090
4091   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4092   feature_status = format (0, "%s",
4093                            mp->feature_status ? "enabled" : "disabled");
4094   vec_add1 (gpe_status, 0);
4095   vec_add1 (feature_status, 0);
4096
4097   vat_json_init_object (&node);
4098   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4099   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4100
4101   vec_free (gpe_status);
4102   vec_free (feature_status);
4103
4104   vat_json_print (vam->ofp, &node);
4105   vat_json_free (&node);
4106
4107   vam->retval = ntohl (mp->retval);
4108   vam->result_ready = 1;
4109 }
4110
4111 static void
4112   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4113   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4114 {
4115   vat_main_t *vam = &vat_main;
4116   i32 retval = ntohl (mp->retval);
4117
4118   if (retval >= 0)
4119     {
4120       print (vam->ofp, "%=20s", mp->locator_set_name);
4121     }
4122
4123   vam->retval = retval;
4124   vam->result_ready = 1;
4125 }
4126
4127 static void
4128   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4129   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4130 {
4131   vat_main_t *vam = &vat_main;
4132   vat_json_node_t *node = NULL;
4133
4134   if (VAT_JSON_ARRAY != vam->json_tree.type)
4135     {
4136       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4137       vat_json_init_array (&vam->json_tree);
4138     }
4139   node = vat_json_array_add (&vam->json_tree);
4140
4141   vat_json_init_object (node);
4142   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4143
4144   vat_json_print (vam->ofp, node);
4145   vat_json_free (node);
4146
4147   vam->retval = ntohl (mp->retval);
4148   vam->result_ready = 1;
4149 }
4150
4151 static u8 *
4152 format_lisp_map_request_mode (u8 * s, va_list * args)
4153 {
4154   u32 mode = va_arg (*args, u32);
4155
4156   switch (mode)
4157     {
4158     case 0:
4159       return format (0, "dst-only");
4160     case 1:
4161       return format (0, "src-dst");
4162     }
4163   return 0;
4164 }
4165
4166 static void
4167   vl_api_show_one_map_request_mode_reply_t_handler
4168   (vl_api_show_one_map_request_mode_reply_t * mp)
4169 {
4170   vat_main_t *vam = &vat_main;
4171   i32 retval = ntohl (mp->retval);
4172
4173   if (0 <= retval)
4174     {
4175       u32 mode = mp->mode;
4176       print (vam->ofp, "map_request_mode: %U",
4177              format_lisp_map_request_mode, mode);
4178     }
4179
4180   vam->retval = retval;
4181   vam->result_ready = 1;
4182 }
4183
4184 static void
4185   vl_api_show_one_map_request_mode_reply_t_handler_json
4186   (vl_api_show_one_map_request_mode_reply_t * mp)
4187 {
4188   vat_main_t *vam = &vat_main;
4189   vat_json_node_t node;
4190   u8 *s = 0;
4191   u32 mode;
4192
4193   mode = mp->mode;
4194   s = format (0, "%U", format_lisp_map_request_mode, mode);
4195   vec_add1 (s, 0);
4196
4197   vat_json_init_object (&node);
4198   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4199   vat_json_print (vam->ofp, &node);
4200   vat_json_free (&node);
4201
4202   vec_free (s);
4203   vam->retval = ntohl (mp->retval);
4204   vam->result_ready = 1;
4205 }
4206
4207 static void
4208   vl_api_one_show_xtr_mode_reply_t_handler
4209   (vl_api_one_show_xtr_mode_reply_t * mp)
4210 {
4211   vat_main_t *vam = &vat_main;
4212   i32 retval = ntohl (mp->retval);
4213
4214   if (0 <= retval)
4215     {
4216       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4217     }
4218
4219   vam->retval = retval;
4220   vam->result_ready = 1;
4221 }
4222
4223 static void
4224   vl_api_one_show_xtr_mode_reply_t_handler_json
4225   (vl_api_one_show_xtr_mode_reply_t * mp)
4226 {
4227   vat_main_t *vam = &vat_main;
4228   vat_json_node_t node;
4229   u8 *status = 0;
4230
4231   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4232   vec_add1 (status, 0);
4233
4234   vat_json_init_object (&node);
4235   vat_json_object_add_string_copy (&node, "status", status);
4236
4237   vec_free (status);
4238
4239   vat_json_print (vam->ofp, &node);
4240   vat_json_free (&node);
4241
4242   vam->retval = ntohl (mp->retval);
4243   vam->result_ready = 1;
4244 }
4245
4246 static void
4247   vl_api_one_show_pitr_mode_reply_t_handler
4248   (vl_api_one_show_pitr_mode_reply_t * mp)
4249 {
4250   vat_main_t *vam = &vat_main;
4251   i32 retval = ntohl (mp->retval);
4252
4253   if (0 <= retval)
4254     {
4255       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4256     }
4257
4258   vam->retval = retval;
4259   vam->result_ready = 1;
4260 }
4261
4262 static void
4263   vl_api_one_show_pitr_mode_reply_t_handler_json
4264   (vl_api_one_show_pitr_mode_reply_t * mp)
4265 {
4266   vat_main_t *vam = &vat_main;
4267   vat_json_node_t node;
4268   u8 *status = 0;
4269
4270   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4271   vec_add1 (status, 0);
4272
4273   vat_json_init_object (&node);
4274   vat_json_object_add_string_copy (&node, "status", status);
4275
4276   vec_free (status);
4277
4278   vat_json_print (vam->ofp, &node);
4279   vat_json_free (&node);
4280
4281   vam->retval = ntohl (mp->retval);
4282   vam->result_ready = 1;
4283 }
4284
4285 static void
4286   vl_api_one_show_petr_mode_reply_t_handler
4287   (vl_api_one_show_petr_mode_reply_t * mp)
4288 {
4289   vat_main_t *vam = &vat_main;
4290   i32 retval = ntohl (mp->retval);
4291
4292   if (0 <= retval)
4293     {
4294       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4295     }
4296
4297   vam->retval = retval;
4298   vam->result_ready = 1;
4299 }
4300
4301 static void
4302   vl_api_one_show_petr_mode_reply_t_handler_json
4303   (vl_api_one_show_petr_mode_reply_t * mp)
4304 {
4305   vat_main_t *vam = &vat_main;
4306   vat_json_node_t node;
4307   u8 *status = 0;
4308
4309   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4310   vec_add1 (status, 0);
4311
4312   vat_json_init_object (&node);
4313   vat_json_object_add_string_copy (&node, "status", status);
4314
4315   vec_free (status);
4316
4317   vat_json_print (vam->ofp, &node);
4318   vat_json_free (&node);
4319
4320   vam->retval = ntohl (mp->retval);
4321   vam->result_ready = 1;
4322 }
4323
4324 static void
4325   vl_api_show_one_use_petr_reply_t_handler
4326   (vl_api_show_one_use_petr_reply_t * mp)
4327 {
4328   vat_main_t *vam = &vat_main;
4329   i32 retval = ntohl (mp->retval);
4330
4331   if (0 <= retval)
4332     {
4333       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4334       if (mp->status)
4335         {
4336           print (vam->ofp, "Proxy-ETR address; %U",
4337                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4338                  mp->address);
4339         }
4340     }
4341
4342   vam->retval = retval;
4343   vam->result_ready = 1;
4344 }
4345
4346 static void
4347   vl_api_show_one_use_petr_reply_t_handler_json
4348   (vl_api_show_one_use_petr_reply_t * mp)
4349 {
4350   vat_main_t *vam = &vat_main;
4351   vat_json_node_t node;
4352   u8 *status = 0;
4353   struct in_addr ip4;
4354   struct in6_addr ip6;
4355
4356   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4357   vec_add1 (status, 0);
4358
4359   vat_json_init_object (&node);
4360   vat_json_object_add_string_copy (&node, "status", status);
4361   if (mp->status)
4362     {
4363       if (mp->is_ip4)
4364         {
4365           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4366           vat_json_object_add_ip6 (&node, "address", ip6);
4367         }
4368       else
4369         {
4370           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4371           vat_json_object_add_ip4 (&node, "address", ip4);
4372         }
4373     }
4374
4375   vec_free (status);
4376
4377   vat_json_print (vam->ofp, &node);
4378   vat_json_free (&node);
4379
4380   vam->retval = ntohl (mp->retval);
4381   vam->result_ready = 1;
4382 }
4383
4384 static void
4385   vl_api_show_one_nsh_mapping_reply_t_handler
4386   (vl_api_show_one_nsh_mapping_reply_t * mp)
4387 {
4388   vat_main_t *vam = &vat_main;
4389   i32 retval = ntohl (mp->retval);
4390
4391   if (0 <= retval)
4392     {
4393       print (vam->ofp, "%-20s%-16s",
4394              mp->is_set ? "set" : "not-set",
4395              mp->is_set ? (char *) mp->locator_set_name : "");
4396     }
4397
4398   vam->retval = retval;
4399   vam->result_ready = 1;
4400 }
4401
4402 static void
4403   vl_api_show_one_nsh_mapping_reply_t_handler_json
4404   (vl_api_show_one_nsh_mapping_reply_t * mp)
4405 {
4406   vat_main_t *vam = &vat_main;
4407   vat_json_node_t node;
4408   u8 *status = 0;
4409
4410   status = format (0, "%s", mp->is_set ? "yes" : "no");
4411   vec_add1 (status, 0);
4412
4413   vat_json_init_object (&node);
4414   vat_json_object_add_string_copy (&node, "is_set", status);
4415   if (mp->is_set)
4416     {
4417       vat_json_object_add_string_copy (&node, "locator_set",
4418                                        mp->locator_set_name);
4419     }
4420
4421   vec_free (status);
4422
4423   vat_json_print (vam->ofp, &node);
4424   vat_json_free (&node);
4425
4426   vam->retval = ntohl (mp->retval);
4427   vam->result_ready = 1;
4428 }
4429
4430 static void
4431   vl_api_show_one_map_register_ttl_reply_t_handler
4432   (vl_api_show_one_map_register_ttl_reply_t * mp)
4433 {
4434   vat_main_t *vam = &vat_main;
4435   i32 retval = ntohl (mp->retval);
4436
4437   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4438
4439   if (0 <= retval)
4440     {
4441       print (vam->ofp, "ttl: %u", mp->ttl);
4442     }
4443
4444   vam->retval = retval;
4445   vam->result_ready = 1;
4446 }
4447
4448 static void
4449   vl_api_show_one_map_register_ttl_reply_t_handler_json
4450   (vl_api_show_one_map_register_ttl_reply_t * mp)
4451 {
4452   vat_main_t *vam = &vat_main;
4453   vat_json_node_t node;
4454
4455   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4456   vat_json_init_object (&node);
4457   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4458
4459   vat_json_print (vam->ofp, &node);
4460   vat_json_free (&node);
4461
4462   vam->retval = ntohl (mp->retval);
4463   vam->result_ready = 1;
4464 }
4465
4466 static void
4467 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4468 {
4469   vat_main_t *vam = &vat_main;
4470   i32 retval = ntohl (mp->retval);
4471
4472   if (0 <= retval)
4473     {
4474       print (vam->ofp, "%-20s%-16s",
4475              mp->status ? "enabled" : "disabled",
4476              mp->status ? (char *) mp->locator_set_name : "");
4477     }
4478
4479   vam->retval = retval;
4480   vam->result_ready = 1;
4481 }
4482
4483 static void
4484 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4485 {
4486   vat_main_t *vam = &vat_main;
4487   vat_json_node_t node;
4488   u8 *status = 0;
4489
4490   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4491   vec_add1 (status, 0);
4492
4493   vat_json_init_object (&node);
4494   vat_json_object_add_string_copy (&node, "status", status);
4495   if (mp->status)
4496     {
4497       vat_json_object_add_string_copy (&node, "locator_set",
4498                                        mp->locator_set_name);
4499     }
4500
4501   vec_free (status);
4502
4503   vat_json_print (vam->ofp, &node);
4504   vat_json_free (&node);
4505
4506   vam->retval = ntohl (mp->retval);
4507   vam->result_ready = 1;
4508 }
4509
4510 static u8 *
4511 format_policer_type (u8 * s, va_list * va)
4512 {
4513   u32 i = va_arg (*va, u32);
4514
4515   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4516     s = format (s, "1r2c");
4517   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4518     s = format (s, "1r3c");
4519   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4520     s = format (s, "2r3c-2698");
4521   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4522     s = format (s, "2r3c-4115");
4523   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4524     s = format (s, "2r3c-mef5cf1");
4525   else
4526     s = format (s, "ILLEGAL");
4527   return s;
4528 }
4529
4530 static u8 *
4531 format_policer_rate_type (u8 * s, va_list * va)
4532 {
4533   u32 i = va_arg (*va, u32);
4534
4535   if (i == SSE2_QOS_RATE_KBPS)
4536     s = format (s, "kbps");
4537   else if (i == SSE2_QOS_RATE_PPS)
4538     s = format (s, "pps");
4539   else
4540     s = format (s, "ILLEGAL");
4541   return s;
4542 }
4543
4544 static u8 *
4545 format_policer_round_type (u8 * s, va_list * va)
4546 {
4547   u32 i = va_arg (*va, u32);
4548
4549   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4550     s = format (s, "closest");
4551   else if (i == SSE2_QOS_ROUND_TO_UP)
4552     s = format (s, "up");
4553   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4554     s = format (s, "down");
4555   else
4556     s = format (s, "ILLEGAL");
4557   return s;
4558 }
4559
4560 static u8 *
4561 format_policer_action_type (u8 * s, va_list * va)
4562 {
4563   u32 i = va_arg (*va, u32);
4564
4565   if (i == SSE2_QOS_ACTION_DROP)
4566     s = format (s, "drop");
4567   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4568     s = format (s, "transmit");
4569   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4570     s = format (s, "mark-and-transmit");
4571   else
4572     s = format (s, "ILLEGAL");
4573   return s;
4574 }
4575
4576 static u8 *
4577 format_dscp (u8 * s, va_list * va)
4578 {
4579   u32 i = va_arg (*va, u32);
4580   char *t = 0;
4581
4582   switch (i)
4583     {
4584 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4585       foreach_vnet_dscp
4586 #undef _
4587     default:
4588       return format (s, "ILLEGAL");
4589     }
4590   s = format (s, "%s", t);
4591   return s;
4592 }
4593
4594 static void
4595 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4596 {
4597   vat_main_t *vam = &vat_main;
4598   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4599
4600   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4601     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4602   else
4603     conform_dscp_str = format (0, "");
4604
4605   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4606     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4607   else
4608     exceed_dscp_str = format (0, "");
4609
4610   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4611     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4612   else
4613     violate_dscp_str = format (0, "");
4614
4615   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4616          "rate type %U, round type %U, %s rate, %s color-aware, "
4617          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4618          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4619          "conform action %U%s, exceed action %U%s, violate action %U%s",
4620          mp->name,
4621          format_policer_type, mp->type,
4622          ntohl (mp->cir),
4623          ntohl (mp->eir),
4624          clib_net_to_host_u64 (mp->cb),
4625          clib_net_to_host_u64 (mp->eb),
4626          format_policer_rate_type, mp->rate_type,
4627          format_policer_round_type, mp->round_type,
4628          mp->single_rate ? "single" : "dual",
4629          mp->color_aware ? "is" : "not",
4630          ntohl (mp->cir_tokens_per_period),
4631          ntohl (mp->pir_tokens_per_period),
4632          ntohl (mp->scale),
4633          ntohl (mp->current_limit),
4634          ntohl (mp->current_bucket),
4635          ntohl (mp->extended_limit),
4636          ntohl (mp->extended_bucket),
4637          clib_net_to_host_u64 (mp->last_update_time),
4638          format_policer_action_type, mp->conform_action_type,
4639          conform_dscp_str,
4640          format_policer_action_type, mp->exceed_action_type,
4641          exceed_dscp_str,
4642          format_policer_action_type, mp->violate_action_type,
4643          violate_dscp_str);
4644
4645   vec_free (conform_dscp_str);
4646   vec_free (exceed_dscp_str);
4647   vec_free (violate_dscp_str);
4648 }
4649
4650 static void vl_api_policer_details_t_handler_json
4651   (vl_api_policer_details_t * mp)
4652 {
4653   vat_main_t *vam = &vat_main;
4654   vat_json_node_t *node;
4655   u8 *rate_type_str, *round_type_str, *type_str;
4656   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4657
4658   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4659   round_type_str =
4660     format (0, "%U", format_policer_round_type, mp->round_type);
4661   type_str = format (0, "%U", format_policer_type, mp->type);
4662   conform_action_str = format (0, "%U", format_policer_action_type,
4663                                mp->conform_action_type);
4664   exceed_action_str = format (0, "%U", format_policer_action_type,
4665                               mp->exceed_action_type);
4666   violate_action_str = format (0, "%U", format_policer_action_type,
4667                                mp->violate_action_type);
4668
4669   if (VAT_JSON_ARRAY != vam->json_tree.type)
4670     {
4671       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4672       vat_json_init_array (&vam->json_tree);
4673     }
4674   node = vat_json_array_add (&vam->json_tree);
4675
4676   vat_json_init_object (node);
4677   vat_json_object_add_string_copy (node, "name", mp->name);
4678   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4679   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4680   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4681   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4682   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4683   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4684   vat_json_object_add_string_copy (node, "type", type_str);
4685   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4686   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4687   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4688   vat_json_object_add_uint (node, "cir_tokens_per_period",
4689                             ntohl (mp->cir_tokens_per_period));
4690   vat_json_object_add_uint (node, "eir_tokens_per_period",
4691                             ntohl (mp->pir_tokens_per_period));
4692   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4693   vat_json_object_add_uint (node, "current_bucket",
4694                             ntohl (mp->current_bucket));
4695   vat_json_object_add_uint (node, "extended_limit",
4696                             ntohl (mp->extended_limit));
4697   vat_json_object_add_uint (node, "extended_bucket",
4698                             ntohl (mp->extended_bucket));
4699   vat_json_object_add_uint (node, "last_update_time",
4700                             ntohl (mp->last_update_time));
4701   vat_json_object_add_string_copy (node, "conform_action",
4702                                    conform_action_str);
4703   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4704     {
4705       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4706       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4707       vec_free (dscp_str);
4708     }
4709   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4710   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4711     {
4712       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4713       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4714       vec_free (dscp_str);
4715     }
4716   vat_json_object_add_string_copy (node, "violate_action",
4717                                    violate_action_str);
4718   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4719     {
4720       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4721       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4722       vec_free (dscp_str);
4723     }
4724
4725   vec_free (rate_type_str);
4726   vec_free (round_type_str);
4727   vec_free (type_str);
4728   vec_free (conform_action_str);
4729   vec_free (exceed_action_str);
4730   vec_free (violate_action_str);
4731 }
4732
4733 static void
4734 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4735                                            mp)
4736 {
4737   vat_main_t *vam = &vat_main;
4738   int i, count = ntohl (mp->count);
4739
4740   if (count > 0)
4741     print (vam->ofp, "classify table ids (%d) : ", count);
4742   for (i = 0; i < count; i++)
4743     {
4744       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4745       print (vam->ofp, (i < count - 1) ? "," : "");
4746     }
4747   vam->retval = ntohl (mp->retval);
4748   vam->result_ready = 1;
4749 }
4750
4751 static void
4752   vl_api_classify_table_ids_reply_t_handler_json
4753   (vl_api_classify_table_ids_reply_t * mp)
4754 {
4755   vat_main_t *vam = &vat_main;
4756   int i, count = ntohl (mp->count);
4757
4758   if (count > 0)
4759     {
4760       vat_json_node_t node;
4761
4762       vat_json_init_object (&node);
4763       for (i = 0; i < count; i++)
4764         {
4765           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4766         }
4767       vat_json_print (vam->ofp, &node);
4768       vat_json_free (&node);
4769     }
4770   vam->retval = ntohl (mp->retval);
4771   vam->result_ready = 1;
4772 }
4773
4774 static void
4775   vl_api_classify_table_by_interface_reply_t_handler
4776   (vl_api_classify_table_by_interface_reply_t * mp)
4777 {
4778   vat_main_t *vam = &vat_main;
4779   u32 table_id;
4780
4781   table_id = ntohl (mp->l2_table_id);
4782   if (table_id != ~0)
4783     print (vam->ofp, "l2 table id : %d", table_id);
4784   else
4785     print (vam->ofp, "l2 table id : No input ACL tables configured");
4786   table_id = ntohl (mp->ip4_table_id);
4787   if (table_id != ~0)
4788     print (vam->ofp, "ip4 table id : %d", table_id);
4789   else
4790     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4791   table_id = ntohl (mp->ip6_table_id);
4792   if (table_id != ~0)
4793     print (vam->ofp, "ip6 table id : %d", table_id);
4794   else
4795     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4796   vam->retval = ntohl (mp->retval);
4797   vam->result_ready = 1;
4798 }
4799
4800 static void
4801   vl_api_classify_table_by_interface_reply_t_handler_json
4802   (vl_api_classify_table_by_interface_reply_t * mp)
4803 {
4804   vat_main_t *vam = &vat_main;
4805   vat_json_node_t node;
4806
4807   vat_json_init_object (&node);
4808
4809   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4810   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4811   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4812
4813   vat_json_print (vam->ofp, &node);
4814   vat_json_free (&node);
4815
4816   vam->retval = ntohl (mp->retval);
4817   vam->result_ready = 1;
4818 }
4819
4820 static void vl_api_policer_add_del_reply_t_handler
4821   (vl_api_policer_add_del_reply_t * mp)
4822 {
4823   vat_main_t *vam = &vat_main;
4824   i32 retval = ntohl (mp->retval);
4825   if (vam->async_mode)
4826     {
4827       vam->async_errors += (retval < 0);
4828     }
4829   else
4830     {
4831       vam->retval = retval;
4832       vam->result_ready = 1;
4833       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4834         /*
4835          * Note: this is just barely thread-safe, depends on
4836          * the main thread spinning waiting for an answer...
4837          */
4838         errmsg ("policer index %d", ntohl (mp->policer_index));
4839     }
4840 }
4841
4842 static void vl_api_policer_add_del_reply_t_handler_json
4843   (vl_api_policer_add_del_reply_t * mp)
4844 {
4845   vat_main_t *vam = &vat_main;
4846   vat_json_node_t node;
4847
4848   vat_json_init_object (&node);
4849   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4850   vat_json_object_add_uint (&node, "policer_index",
4851                             ntohl (mp->policer_index));
4852
4853   vat_json_print (vam->ofp, &node);
4854   vat_json_free (&node);
4855
4856   vam->retval = ntohl (mp->retval);
4857   vam->result_ready = 1;
4858 }
4859
4860 /* Format hex dump. */
4861 u8 *
4862 format_hex_bytes (u8 * s, va_list * va)
4863 {
4864   u8 *bytes = va_arg (*va, u8 *);
4865   int n_bytes = va_arg (*va, int);
4866   uword i;
4867
4868   /* Print short or long form depending on byte count. */
4869   uword short_form = n_bytes <= 32;
4870   u32 indent = format_get_indent (s);
4871
4872   if (n_bytes == 0)
4873     return s;
4874
4875   for (i = 0; i < n_bytes; i++)
4876     {
4877       if (!short_form && (i % 32) == 0)
4878         s = format (s, "%08x: ", i);
4879       s = format (s, "%02x", bytes[i]);
4880       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4881         s = format (s, "\n%U", format_white_space, indent);
4882     }
4883
4884   return s;
4885 }
4886
4887 static void
4888 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4889                                             * mp)
4890 {
4891   vat_main_t *vam = &vat_main;
4892   i32 retval = ntohl (mp->retval);
4893   if (retval == 0)
4894     {
4895       print (vam->ofp, "classify table info :");
4896       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4897              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4898              ntohl (mp->miss_next_index));
4899       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4900              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4901              ntohl (mp->match_n_vectors));
4902       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4903              ntohl (mp->mask_length));
4904     }
4905   vam->retval = retval;
4906   vam->result_ready = 1;
4907 }
4908
4909 static void
4910   vl_api_classify_table_info_reply_t_handler_json
4911   (vl_api_classify_table_info_reply_t * mp)
4912 {
4913   vat_main_t *vam = &vat_main;
4914   vat_json_node_t node;
4915
4916   i32 retval = ntohl (mp->retval);
4917   if (retval == 0)
4918     {
4919       vat_json_init_object (&node);
4920
4921       vat_json_object_add_int (&node, "sessions",
4922                                ntohl (mp->active_sessions));
4923       vat_json_object_add_int (&node, "nexttbl",
4924                                ntohl (mp->next_table_index));
4925       vat_json_object_add_int (&node, "nextnode",
4926                                ntohl (mp->miss_next_index));
4927       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4928       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4929       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4930       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4931                       ntohl (mp->mask_length), 0);
4932       vat_json_object_add_string_copy (&node, "mask", s);
4933
4934       vat_json_print (vam->ofp, &node);
4935       vat_json_free (&node);
4936     }
4937   vam->retval = ntohl (mp->retval);
4938   vam->result_ready = 1;
4939 }
4940
4941 static void
4942 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4943                                            mp)
4944 {
4945   vat_main_t *vam = &vat_main;
4946
4947   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4948          ntohl (mp->hit_next_index), ntohl (mp->advance),
4949          ntohl (mp->opaque_index));
4950   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4951          ntohl (mp->match_length));
4952 }
4953
4954 static void
4955   vl_api_classify_session_details_t_handler_json
4956   (vl_api_classify_session_details_t * mp)
4957 {
4958   vat_main_t *vam = &vat_main;
4959   vat_json_node_t *node = NULL;
4960
4961   if (VAT_JSON_ARRAY != vam->json_tree.type)
4962     {
4963       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4964       vat_json_init_array (&vam->json_tree);
4965     }
4966   node = vat_json_array_add (&vam->json_tree);
4967
4968   vat_json_init_object (node);
4969   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4970   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4971   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4972   u8 *s =
4973     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4974             0);
4975   vat_json_object_add_string_copy (node, "match", s);
4976 }
4977
4978 static void vl_api_pg_create_interface_reply_t_handler
4979   (vl_api_pg_create_interface_reply_t * mp)
4980 {
4981   vat_main_t *vam = &vat_main;
4982
4983   vam->retval = ntohl (mp->retval);
4984   vam->result_ready = 1;
4985 }
4986
4987 static void vl_api_pg_create_interface_reply_t_handler_json
4988   (vl_api_pg_create_interface_reply_t * mp)
4989 {
4990   vat_main_t *vam = &vat_main;
4991   vat_json_node_t node;
4992
4993   i32 retval = ntohl (mp->retval);
4994   if (retval == 0)
4995     {
4996       vat_json_init_object (&node);
4997
4998       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4999
5000       vat_json_print (vam->ofp, &node);
5001       vat_json_free (&node);
5002     }
5003   vam->retval = ntohl (mp->retval);
5004   vam->result_ready = 1;
5005 }
5006
5007 static void vl_api_policer_classify_details_t_handler
5008   (vl_api_policer_classify_details_t * mp)
5009 {
5010   vat_main_t *vam = &vat_main;
5011
5012   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5013          ntohl (mp->table_index));
5014 }
5015
5016 static void vl_api_policer_classify_details_t_handler_json
5017   (vl_api_policer_classify_details_t * mp)
5018 {
5019   vat_main_t *vam = &vat_main;
5020   vat_json_node_t *node;
5021
5022   if (VAT_JSON_ARRAY != vam->json_tree.type)
5023     {
5024       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5025       vat_json_init_array (&vam->json_tree);
5026     }
5027   node = vat_json_array_add (&vam->json_tree);
5028
5029   vat_json_init_object (node);
5030   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5031   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5032 }
5033
5034 static void vl_api_flow_classify_details_t_handler
5035   (vl_api_flow_classify_details_t * mp)
5036 {
5037   vat_main_t *vam = &vat_main;
5038
5039   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5040          ntohl (mp->table_index));
5041 }
5042
5043 static void vl_api_flow_classify_details_t_handler_json
5044   (vl_api_flow_classify_details_t * mp)
5045 {
5046   vat_main_t *vam = &vat_main;
5047   vat_json_node_t *node;
5048
5049   if (VAT_JSON_ARRAY != vam->json_tree.type)
5050     {
5051       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5052       vat_json_init_array (&vam->json_tree);
5053     }
5054   node = vat_json_array_add (&vam->json_tree);
5055
5056   vat_json_init_object (node);
5057   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5058   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5059 }
5060
5061 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5062 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5063 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5064 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5065 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5066 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5067 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5068 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5069 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5070 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5071
5072 /*
5073  * Generate boilerplate reply handlers, which
5074  * dig the return value out of the xxx_reply_t API message,
5075  * stick it into vam->retval, and set vam->result_ready
5076  *
5077  * Could also do this by pointing N message decode slots at
5078  * a single function, but that could break in subtle ways.
5079  */
5080
5081 #define foreach_standard_reply_retval_handler           \
5082 _(sw_interface_set_flags_reply)                         \
5083 _(sw_interface_add_del_address_reply)                   \
5084 _(sw_interface_set_rx_mode_reply)                       \
5085 _(sw_interface_set_rx_placement_reply)                  \
5086 _(sw_interface_set_table_reply)                         \
5087 _(sw_interface_set_mpls_enable_reply)                   \
5088 _(sw_interface_set_vpath_reply)                         \
5089 _(sw_interface_set_vxlan_bypass_reply)                  \
5090 _(sw_interface_set_geneve_bypass_reply)                 \
5091 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5092 _(sw_interface_set_l2_bridge_reply)                     \
5093 _(sw_interface_set_bond_weight_reply)                   \
5094 _(bridge_domain_add_del_reply)                          \
5095 _(sw_interface_set_l2_xconnect_reply)                   \
5096 _(l2fib_add_del_reply)                                  \
5097 _(l2fib_flush_int_reply)                                \
5098 _(l2fib_flush_bd_reply)                                 \
5099 _(ip_route_add_del_reply)                               \
5100 _(ip_table_add_del_reply)                               \
5101 _(ip_mroute_add_del_reply)                              \
5102 _(mpls_route_add_del_reply)                             \
5103 _(mpls_table_add_del_reply)                             \
5104 _(mpls_ip_bind_unbind_reply)                            \
5105 _(bier_route_add_del_reply)                             \
5106 _(bier_table_add_del_reply)                             \
5107 _(proxy_arp_add_del_reply)                              \
5108 _(proxy_arp_intfc_enable_disable_reply)                 \
5109 _(sw_interface_set_unnumbered_reply)                    \
5110 _(ip_neighbor_add_del_reply)                            \
5111 _(reset_fib_reply)                                      \
5112 _(dhcp_proxy_config_reply)                              \
5113 _(dhcp_proxy_set_vss_reply)                             \
5114 _(dhcp_client_config_reply)                             \
5115 _(set_ip_flow_hash_reply)                               \
5116 _(sw_interface_ip6_enable_disable_reply)                \
5117 _(ip6nd_proxy_add_del_reply)                            \
5118 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5119 _(sw_interface_ip6nd_ra_config_reply)                   \
5120 _(set_arp_neighbor_limit_reply)                         \
5121 _(l2_patch_add_del_reply)                               \
5122 _(sr_mpls_policy_add_reply)                             \
5123 _(sr_mpls_policy_mod_reply)                             \
5124 _(sr_mpls_policy_del_reply)                             \
5125 _(sr_policy_add_reply)                                  \
5126 _(sr_policy_mod_reply)                                  \
5127 _(sr_policy_del_reply)                                  \
5128 _(sr_localsid_add_del_reply)                            \
5129 _(sr_steering_add_del_reply)                            \
5130 _(classify_add_del_session_reply)                       \
5131 _(classify_set_interface_ip_table_reply)                \
5132 _(classify_set_interface_l2_tables_reply)               \
5133 _(l2tpv3_set_tunnel_cookies_reply)                      \
5134 _(l2tpv3_interface_enable_disable_reply)                \
5135 _(l2tpv3_set_lookup_key_reply)                          \
5136 _(l2_fib_clear_table_reply)                             \
5137 _(l2_interface_efp_filter_reply)                        \
5138 _(l2_interface_vlan_tag_rewrite_reply)                  \
5139 _(modify_vhost_user_if_reply)                           \
5140 _(delete_vhost_user_if_reply)                           \
5141 _(ip_probe_neighbor_reply)                              \
5142 _(ip_scan_neighbor_enable_disable_reply)                \
5143 _(want_ip4_arp_events_reply)                            \
5144 _(want_ip6_nd_events_reply)                             \
5145 _(want_l2_macs_events_reply)                            \
5146 _(input_acl_set_interface_reply)                        \
5147 _(ipsec_spd_add_del_reply)                              \
5148 _(ipsec_interface_add_del_spd_reply)                    \
5149 _(ipsec_spd_entry_add_del_reply)                        \
5150 _(ipsec_sad_entry_add_del_reply)                        \
5151 _(ipsec_tunnel_if_add_del_reply)                        \
5152 _(ipsec_tunnel_if_set_sa_reply)                         \
5153 _(delete_loopback_reply)                                \
5154 _(bd_ip_mac_add_del_reply)                              \
5155 _(bd_ip_mac_flush_reply)                                \
5156 _(want_interface_events_reply)                          \
5157 _(cop_interface_enable_disable_reply)                   \
5158 _(cop_whitelist_enable_disable_reply)                   \
5159 _(sw_interface_clear_stats_reply)                       \
5160 _(ioam_enable_reply)                                    \
5161 _(ioam_disable_reply)                                   \
5162 _(one_add_del_locator_reply)                            \
5163 _(one_add_del_local_eid_reply)                          \
5164 _(one_add_del_remote_mapping_reply)                     \
5165 _(one_add_del_adjacency_reply)                          \
5166 _(one_add_del_map_resolver_reply)                       \
5167 _(one_add_del_map_server_reply)                         \
5168 _(one_enable_disable_reply)                             \
5169 _(one_rloc_probe_enable_disable_reply)                  \
5170 _(one_map_register_enable_disable_reply)                \
5171 _(one_map_register_set_ttl_reply)                       \
5172 _(one_set_transport_protocol_reply)                     \
5173 _(one_map_register_fallback_threshold_reply)            \
5174 _(one_pitr_set_locator_set_reply)                       \
5175 _(one_map_request_mode_reply)                           \
5176 _(one_add_del_map_request_itr_rlocs_reply)              \
5177 _(one_eid_table_add_del_map_reply)                      \
5178 _(one_use_petr_reply)                                   \
5179 _(one_stats_enable_disable_reply)                       \
5180 _(one_add_del_l2_arp_entry_reply)                       \
5181 _(one_add_del_ndp_entry_reply)                          \
5182 _(one_stats_flush_reply)                                \
5183 _(one_enable_disable_xtr_mode_reply)                    \
5184 _(one_enable_disable_pitr_mode_reply)                   \
5185 _(one_enable_disable_petr_mode_reply)                   \
5186 _(gpe_enable_disable_reply)                             \
5187 _(gpe_set_encap_mode_reply)                             \
5188 _(gpe_add_del_iface_reply)                              \
5189 _(gpe_add_del_native_fwd_rpath_reply)                   \
5190 _(af_packet_delete_reply)                               \
5191 _(policer_classify_set_interface_reply)                 \
5192 _(netmap_create_reply)                                  \
5193 _(netmap_delete_reply)                                  \
5194 _(set_ipfix_exporter_reply)                             \
5195 _(set_ipfix_classify_stream_reply)                      \
5196 _(ipfix_classify_table_add_del_reply)                   \
5197 _(flow_classify_set_interface_reply)                    \
5198 _(sw_interface_span_enable_disable_reply)               \
5199 _(pg_capture_reply)                                     \
5200 _(pg_enable_disable_reply)                              \
5201 _(ip_source_and_port_range_check_add_del_reply)         \
5202 _(ip_source_and_port_range_check_interface_add_del_reply)\
5203 _(delete_subif_reply)                                   \
5204 _(l2_interface_pbb_tag_rewrite_reply)                   \
5205 _(set_punt_reply)                                       \
5206 _(feature_enable_disable_reply)                         \
5207 _(sw_interface_tag_add_del_reply)                       \
5208 _(hw_interface_set_mtu_reply)                           \
5209 _(p2p_ethernet_add_reply)                               \
5210 _(p2p_ethernet_del_reply)                               \
5211 _(lldp_config_reply)                                    \
5212 _(sw_interface_set_lldp_reply)                          \
5213 _(tcp_configure_src_addresses_reply)                    \
5214 _(session_rule_add_del_reply)                           \
5215 _(ip_container_proxy_add_del_reply)                     \
5216 _(output_acl_set_interface_reply)                       \
5217 _(qos_record_enable_disable_reply)
5218
5219 #define _(n)                                    \
5220     static void vl_api_##n##_t_handler          \
5221     (vl_api_##n##_t * mp)                       \
5222     {                                           \
5223         vat_main_t * vam = &vat_main;           \
5224         i32 retval = ntohl(mp->retval);         \
5225         if (vam->async_mode) {                  \
5226             vam->async_errors += (retval < 0);  \
5227         } else {                                \
5228             vam->retval = retval;               \
5229             vam->result_ready = 1;              \
5230         }                                       \
5231     }
5232 foreach_standard_reply_retval_handler;
5233 #undef _
5234
5235 #define _(n)                                    \
5236     static void vl_api_##n##_t_handler_json     \
5237     (vl_api_##n##_t * mp)                       \
5238     {                                           \
5239         vat_main_t * vam = &vat_main;           \
5240         vat_json_node_t node;                   \
5241         vat_json_init_object(&node);            \
5242         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5243         vat_json_print(vam->ofp, &node);        \
5244         vam->retval = ntohl(mp->retval);        \
5245         vam->result_ready = 1;                  \
5246     }
5247 foreach_standard_reply_retval_handler;
5248 #undef _
5249
5250 /*
5251  * Table of message reply handlers, must include boilerplate handlers
5252  * we just generated
5253  */
5254
5255 #define foreach_vpe_api_reply_msg                                       \
5256 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5257 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5258 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5259 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5260 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5261 _(CLI_REPLY, cli_reply)                                                 \
5262 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5263 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5264   sw_interface_add_del_address_reply)                                   \
5265 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5266 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5267 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5268 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5269 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5270 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5271 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5272 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5273 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5274 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5275   sw_interface_set_l2_xconnect_reply)                                   \
5276 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5277   sw_interface_set_l2_bridge_reply)                                     \
5278 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5279 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5280 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5281 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5282 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5283 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5284 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5285 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5286 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5287 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5288 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5289 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5290 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5291 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5292 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5293 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5294 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5295 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5296 _(SW_INTERFACE_SET_BOND_WEIGHT_REPLY, sw_interface_set_bond_weight_reply) \
5297 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5298 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5299 _(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply)                       \
5300 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5301 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5302 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5303 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5304 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5305 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5306 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5307 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5308 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5309   proxy_arp_intfc_enable_disable_reply)                                 \
5310 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5311 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5312   sw_interface_set_unnumbered_reply)                                    \
5313 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5314 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5315 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5316 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5317 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5318 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5319 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5320 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5321 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5322 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5323   sw_interface_ip6_enable_disable_reply)                                \
5324 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5325 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5326 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5327   sw_interface_ip6nd_ra_prefix_reply)                                   \
5328 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5329   sw_interface_ip6nd_ra_config_reply)                                   \
5330 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5331 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5332 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5333 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5334 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5335 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5336 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5337 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5338 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5339 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5340 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5341 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5342 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5343 classify_set_interface_ip_table_reply)                                  \
5344 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5345   classify_set_interface_l2_tables_reply)                               \
5346 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5347 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5348 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5349 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5350 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5351   l2tpv3_interface_enable_disable_reply)                                \
5352 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5353 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5354 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5355 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5356 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5357 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5358 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5359 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5360 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5361 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5362 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5363 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5364 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5365 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5366 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5367 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5368 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5369 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5370 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5371 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5372 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5373 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5374 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5375 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5376 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5377 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5378 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5379 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5380 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5381 _(L2_MACS_EVENT, l2_macs_event)                                         \
5382 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5383 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5384 _(IP_DETAILS, ip_details)                                               \
5385 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5386 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5387 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5388 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5389 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5390 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5391 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5392 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5393 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5394 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5395 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5396 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5397 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5398 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5399 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5400 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5401 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5402 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5403 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5404 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5405 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5406 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5407 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5408 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5409 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5410 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5411 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5412 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5413 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5414   one_map_register_enable_disable_reply)                                \
5415 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5416 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5417 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5418 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5419   one_map_register_fallback_threshold_reply)                            \
5420 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5421   one_rloc_probe_enable_disable_reply)                                  \
5422 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5423 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5424 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5425 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5426 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5427 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5428 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5429 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5430 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5431 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5432 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5433 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5434 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5435 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5436 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5437 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5438   show_one_stats_enable_disable_reply)                                  \
5439 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5440 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5441 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5442 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5443 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5444 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5445 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5446 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5447   one_enable_disable_pitr_mode_reply)                                   \
5448 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5449   one_enable_disable_petr_mode_reply)                                   \
5450 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5451 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5452 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5453 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5454 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5455 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5456 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5457 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5458 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5459 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5460 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5461 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5462   gpe_add_del_native_fwd_rpath_reply)                                   \
5463 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5464   gpe_fwd_entry_path_details)                                           \
5465 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5466 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5467   one_add_del_map_request_itr_rlocs_reply)                              \
5468 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5469   one_get_map_request_itr_rlocs_reply)                                  \
5470 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5471 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5472 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5473 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5474 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5475 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5476   show_one_map_register_state_reply)                                    \
5477 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5478 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5479   show_one_map_register_fallback_threshold_reply)                       \
5480 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5481 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5482 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5483 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5484 _(POLICER_DETAILS, policer_details)                                     \
5485 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5486 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5487 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5488 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5489 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5490 _(MPLS_TABLE_DETAILS, mpls_table_details)                               \
5491 _(MPLS_ROUTE_DETAILS, mpls_route_details)                               \
5492 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5493 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5494 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5495 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5496 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5497 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5498 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5499 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5500 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5501 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5502 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5503 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5504 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5505 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5506 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5507 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5508 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5509 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5510 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5511  ip_source_and_port_range_check_add_del_reply)                          \
5512 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5513  ip_source_and_port_range_check_interface_add_del_reply)                \
5514 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5515 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5516 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5517 _(IP_TABLE_DETAILS, ip_table_details)                                   \
5518 _(IP_ROUTE_DETAILS, ip_route_details)                                   \
5519 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5520 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5521 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5522 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5523 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5524 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5525 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5526 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5527 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5528 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5529 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5530 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5531 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5532 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5533 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5534 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5535 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5536
5537 #define foreach_standalone_reply_msg                                    \
5538 _(SW_INTERFACE_EVENT, sw_interface_event)
5539
5540 typedef struct
5541 {
5542   u8 *name;
5543   u32 value;
5544 } name_sort_t;
5545
5546 #define STR_VTR_OP_CASE(op)     \
5547     case L2_VTR_ ## op:         \
5548         return "" # op;
5549
5550 static const char *
5551 str_vtr_op (u32 vtr_op)
5552 {
5553   switch (vtr_op)
5554     {
5555       STR_VTR_OP_CASE (DISABLED);
5556       STR_VTR_OP_CASE (PUSH_1);
5557       STR_VTR_OP_CASE (PUSH_2);
5558       STR_VTR_OP_CASE (POP_1);
5559       STR_VTR_OP_CASE (POP_2);
5560       STR_VTR_OP_CASE (TRANSLATE_1_1);
5561       STR_VTR_OP_CASE (TRANSLATE_1_2);
5562       STR_VTR_OP_CASE (TRANSLATE_2_1);
5563       STR_VTR_OP_CASE (TRANSLATE_2_2);
5564     }
5565
5566   return "UNKNOWN";
5567 }
5568
5569 static int
5570 dump_sub_interface_table (vat_main_t * vam)
5571 {
5572   const sw_interface_subif_t *sub = NULL;
5573
5574   if (vam->json_output)
5575     {
5576       clib_warning
5577         ("JSON output supported only for VPE API calls and dump_stats_table");
5578       return -99;
5579     }
5580
5581   print (vam->ofp,
5582          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5583          "Interface", "sw_if_index",
5584          "sub id", "dot1ad", "tags", "outer id",
5585          "inner id", "exact", "default", "outer any", "inner any");
5586
5587   vec_foreach (sub, vam->sw_if_subif_table)
5588   {
5589     print (vam->ofp,
5590            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5591            sub->interface_name,
5592            sub->sw_if_index,
5593            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5594            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5595            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5596            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5597     if (sub->vtr_op != L2_VTR_DISABLED)
5598       {
5599         print (vam->ofp,
5600                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5601                "tag1: %d tag2: %d ]",
5602                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5603                sub->vtr_tag1, sub->vtr_tag2);
5604       }
5605   }
5606
5607   return 0;
5608 }
5609
5610 static int
5611 name_sort_cmp (void *a1, void *a2)
5612 {
5613   name_sort_t *n1 = a1;
5614   name_sort_t *n2 = a2;
5615
5616   return strcmp ((char *) n1->name, (char *) n2->name);
5617 }
5618
5619 static int
5620 dump_interface_table (vat_main_t * vam)
5621 {
5622   hash_pair_t *p;
5623   name_sort_t *nses = 0, *ns;
5624
5625   if (vam->json_output)
5626     {
5627       clib_warning
5628         ("JSON output supported only for VPE API calls and dump_stats_table");
5629       return -99;
5630     }
5631
5632   /* *INDENT-OFF* */
5633   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5634   ({
5635     vec_add2 (nses, ns, 1);
5636     ns->name = (u8 *)(p->key);
5637     ns->value = (u32) p->value[0];
5638   }));
5639   /* *INDENT-ON* */
5640
5641   vec_sort_with_function (nses, name_sort_cmp);
5642
5643   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5644   vec_foreach (ns, nses)
5645   {
5646     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5647   }
5648   vec_free (nses);
5649   return 0;
5650 }
5651
5652 static int
5653 dump_ip_table (vat_main_t * vam, int is_ipv6)
5654 {
5655   const ip_details_t *det = NULL;
5656   const ip_address_details_t *address = NULL;
5657   u32 i = ~0;
5658
5659   print (vam->ofp, "%-12s", "sw_if_index");
5660
5661   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5662   {
5663     i++;
5664     if (!det->present)
5665       {
5666         continue;
5667       }
5668     print (vam->ofp, "%-12d", i);
5669     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5670     if (!det->addr)
5671       {
5672         continue;
5673       }
5674     vec_foreach (address, det->addr)
5675     {
5676       print (vam->ofp,
5677              "            %-30U%-13d",
5678              is_ipv6 ? format_ip6_address : format_ip4_address,
5679              address->ip, address->prefix_length);
5680     }
5681   }
5682
5683   return 0;
5684 }
5685
5686 static int
5687 dump_ipv4_table (vat_main_t * vam)
5688 {
5689   if (vam->json_output)
5690     {
5691       clib_warning
5692         ("JSON output supported only for VPE API calls and dump_stats_table");
5693       return -99;
5694     }
5695
5696   return dump_ip_table (vam, 0);
5697 }
5698
5699 static int
5700 dump_ipv6_table (vat_main_t * vam)
5701 {
5702   if (vam->json_output)
5703     {
5704       clib_warning
5705         ("JSON output supported only for VPE API calls and dump_stats_table");
5706       return -99;
5707     }
5708
5709   return dump_ip_table (vam, 1);
5710 }
5711
5712 /*
5713  * Pass CLI buffers directly in the CLI_INBAND API message,
5714  * instead of an additional shared memory area.
5715  */
5716 static int
5717 exec_inband (vat_main_t * vam)
5718 {
5719   vl_api_cli_inband_t *mp;
5720   unformat_input_t *i = vam->input;
5721   int ret;
5722
5723   if (vec_len (i->buffer) == 0)
5724     return -1;
5725
5726   if (vam->exec_mode == 0 && unformat (i, "mode"))
5727     {
5728       vam->exec_mode = 1;
5729       return 0;
5730     }
5731   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5732     {
5733       vam->exec_mode = 0;
5734       return 0;
5735     }
5736
5737   /*
5738    * In order for the CLI command to work, it
5739    * must be a vector ending in \n, not a C-string ending
5740    * in \n\0.
5741    */
5742   u32 len = vec_len (vam->input->buffer);
5743   M2 (CLI_INBAND, mp, len);
5744   vl_api_to_api_string (len - 1, (const char *) vam->input->buffer, &mp->cmd);
5745
5746   S (mp);
5747   W (ret);
5748   /* json responses may or may not include a useful reply... */
5749   if (vec_len (vam->cmd_reply))
5750     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5751   return ret;
5752 }
5753
5754 int
5755 exec (vat_main_t * vam)
5756 {
5757   return exec_inband (vam);
5758 }
5759
5760 static int
5761 api_create_loopback (vat_main_t * vam)
5762 {
5763   unformat_input_t *i = vam->input;
5764   vl_api_create_loopback_t *mp;
5765   vl_api_create_loopback_instance_t *mp_lbi;
5766   u8 mac_address[6];
5767   u8 mac_set = 0;
5768   u8 is_specified = 0;
5769   u32 user_instance = 0;
5770   int ret;
5771
5772   clib_memset (mac_address, 0, sizeof (mac_address));
5773
5774   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5775     {
5776       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5777         mac_set = 1;
5778       if (unformat (i, "instance %d", &user_instance))
5779         is_specified = 1;
5780       else
5781         break;
5782     }
5783
5784   if (is_specified)
5785     {
5786       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5787       mp_lbi->is_specified = is_specified;
5788       if (is_specified)
5789         mp_lbi->user_instance = htonl (user_instance);
5790       if (mac_set)
5791         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5792       S (mp_lbi);
5793     }
5794   else
5795     {
5796       /* Construct the API message */
5797       M (CREATE_LOOPBACK, mp);
5798       if (mac_set)
5799         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5800       S (mp);
5801     }
5802
5803   W (ret);
5804   return ret;
5805 }
5806
5807 static int
5808 api_delete_loopback (vat_main_t * vam)
5809 {
5810   unformat_input_t *i = vam->input;
5811   vl_api_delete_loopback_t *mp;
5812   u32 sw_if_index = ~0;
5813   int ret;
5814
5815   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5816     {
5817       if (unformat (i, "sw_if_index %d", &sw_if_index))
5818         ;
5819       else
5820         break;
5821     }
5822
5823   if (sw_if_index == ~0)
5824     {
5825       errmsg ("missing sw_if_index");
5826       return -99;
5827     }
5828
5829   /* Construct the API message */
5830   M (DELETE_LOOPBACK, mp);
5831   mp->sw_if_index = ntohl (sw_if_index);
5832
5833   S (mp);
5834   W (ret);
5835   return ret;
5836 }
5837
5838 static int
5839 api_want_interface_events (vat_main_t * vam)
5840 {
5841   unformat_input_t *i = vam->input;
5842   vl_api_want_interface_events_t *mp;
5843   int enable = -1;
5844   int ret;
5845
5846   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5847     {
5848       if (unformat (i, "enable"))
5849         enable = 1;
5850       else if (unformat (i, "disable"))
5851         enable = 0;
5852       else
5853         break;
5854     }
5855
5856   if (enable == -1)
5857     {
5858       errmsg ("missing enable|disable");
5859       return -99;
5860     }
5861
5862   M (WANT_INTERFACE_EVENTS, mp);
5863   mp->enable_disable = enable;
5864
5865   vam->interface_event_display = enable;
5866
5867   S (mp);
5868   W (ret);
5869   return ret;
5870 }
5871
5872
5873 /* Note: non-static, called once to set up the initial intfc table */
5874 int
5875 api_sw_interface_dump (vat_main_t * vam)
5876 {
5877   vl_api_sw_interface_dump_t *mp;
5878   vl_api_control_ping_t *mp_ping;
5879   hash_pair_t *p;
5880   name_sort_t *nses = 0, *ns;
5881   sw_interface_subif_t *sub = NULL;
5882   int ret;
5883
5884   /* Toss the old name table */
5885   /* *INDENT-OFF* */
5886   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5887   ({
5888     vec_add2 (nses, ns, 1);
5889     ns->name = (u8 *)(p->key);
5890     ns->value = (u32) p->value[0];
5891   }));
5892   /* *INDENT-ON* */
5893
5894   hash_free (vam->sw_if_index_by_interface_name);
5895
5896   vec_foreach (ns, nses) vec_free (ns->name);
5897
5898   vec_free (nses);
5899
5900   vec_foreach (sub, vam->sw_if_subif_table)
5901   {
5902     vec_free (sub->interface_name);
5903   }
5904   vec_free (vam->sw_if_subif_table);
5905
5906   /* recreate the interface name hash table */
5907   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5908
5909   /*
5910    * Ask for all interface names. Otherwise, the epic catalog of
5911    * name filters becomes ridiculously long, and vat ends up needing
5912    * to be taught about new interface types.
5913    */
5914   M (SW_INTERFACE_DUMP, mp);
5915   S (mp);
5916
5917   /* Use a control ping for synchronization */
5918   MPING (CONTROL_PING, mp_ping);
5919   S (mp_ping);
5920
5921   W (ret);
5922   return ret;
5923 }
5924
5925 static int
5926 api_sw_interface_set_flags (vat_main_t * vam)
5927 {
5928   unformat_input_t *i = vam->input;
5929   vl_api_sw_interface_set_flags_t *mp;
5930   u32 sw_if_index;
5931   u8 sw_if_index_set = 0;
5932   u8 admin_up = 0;
5933   int ret;
5934
5935   /* Parse args required to build the message */
5936   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5937     {
5938       if (unformat (i, "admin-up"))
5939         admin_up = 1;
5940       else if (unformat (i, "admin-down"))
5941         admin_up = 0;
5942       else
5943         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5944         sw_if_index_set = 1;
5945       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5946         sw_if_index_set = 1;
5947       else
5948         break;
5949     }
5950
5951   if (sw_if_index_set == 0)
5952     {
5953       errmsg ("missing interface name or sw_if_index");
5954       return -99;
5955     }
5956
5957   /* Construct the API message */
5958   M (SW_INTERFACE_SET_FLAGS, mp);
5959   mp->sw_if_index = ntohl (sw_if_index);
5960   mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
5961
5962   /* send it... */
5963   S (mp);
5964
5965   /* Wait for a reply, return the good/bad news... */
5966   W (ret);
5967   return ret;
5968 }
5969
5970 static int
5971 api_sw_interface_set_rx_mode (vat_main_t * vam)
5972 {
5973   unformat_input_t *i = vam->input;
5974   vl_api_sw_interface_set_rx_mode_t *mp;
5975   u32 sw_if_index;
5976   u8 sw_if_index_set = 0;
5977   int ret;
5978   u8 queue_id_valid = 0;
5979   u32 queue_id;
5980   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
5981
5982   /* Parse args required to build the message */
5983   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5984     {
5985       if (unformat (i, "queue %d", &queue_id))
5986         queue_id_valid = 1;
5987       else if (unformat (i, "polling"))
5988         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
5989       else if (unformat (i, "interrupt"))
5990         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
5991       else if (unformat (i, "adaptive"))
5992         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
5993       else
5994         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5995         sw_if_index_set = 1;
5996       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5997         sw_if_index_set = 1;
5998       else
5999         break;
6000     }
6001
6002   if (sw_if_index_set == 0)
6003     {
6004       errmsg ("missing interface name or sw_if_index");
6005       return -99;
6006     }
6007   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6008     {
6009       errmsg ("missing rx-mode");
6010       return -99;
6011     }
6012
6013   /* Construct the API message */
6014   M (SW_INTERFACE_SET_RX_MODE, mp);
6015   mp->sw_if_index = ntohl (sw_if_index);
6016   mp->mode = (vl_api_rx_mode_t) mode;
6017   mp->queue_id_valid = queue_id_valid;
6018   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6019
6020   /* send it... */
6021   S (mp);
6022
6023   /* Wait for a reply, return the good/bad news... */
6024   W (ret);
6025   return ret;
6026 }
6027
6028 static int
6029 api_sw_interface_set_rx_placement (vat_main_t * vam)
6030 {
6031   unformat_input_t *i = vam->input;
6032   vl_api_sw_interface_set_rx_placement_t *mp;
6033   u32 sw_if_index;
6034   u8 sw_if_index_set = 0;
6035   int ret;
6036   u8 is_main = 0;
6037   u32 queue_id, thread_index;
6038
6039   /* Parse args required to build the message */
6040   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6041     {
6042       if (unformat (i, "queue %d", &queue_id))
6043         ;
6044       else if (unformat (i, "main"))
6045         is_main = 1;
6046       else if (unformat (i, "worker %d", &thread_index))
6047         ;
6048       else
6049         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6050         sw_if_index_set = 1;
6051       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6052         sw_if_index_set = 1;
6053       else
6054         break;
6055     }
6056
6057   if (sw_if_index_set == 0)
6058     {
6059       errmsg ("missing interface name or sw_if_index");
6060       return -99;
6061     }
6062
6063   if (is_main)
6064     thread_index = 0;
6065   /* Construct the API message */
6066   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6067   mp->sw_if_index = ntohl (sw_if_index);
6068   mp->worker_id = ntohl (thread_index);
6069   mp->queue_id = ntohl (queue_id);
6070   mp->is_main = is_main;
6071
6072   /* send it... */
6073   S (mp);
6074   /* Wait for a reply, return the good/bad news... */
6075   W (ret);
6076   return ret;
6077 }
6078
6079 static void vl_api_sw_interface_rx_placement_details_t_handler
6080   (vl_api_sw_interface_rx_placement_details_t * mp)
6081 {
6082   vat_main_t *vam = &vat_main;
6083   u32 worker_id = ntohl (mp->worker_id);
6084
6085   print (vam->ofp,
6086          "\n%-11d %-11s %-6d %-5d %-9s",
6087          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6088          worker_id, ntohl (mp->queue_id),
6089          (mp->mode ==
6090           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6091 }
6092
6093 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6094   (vl_api_sw_interface_rx_placement_details_t * mp)
6095 {
6096   vat_main_t *vam = &vat_main;
6097   vat_json_node_t *node = NULL;
6098
6099   if (VAT_JSON_ARRAY != vam->json_tree.type)
6100     {
6101       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6102       vat_json_init_array (&vam->json_tree);
6103     }
6104   node = vat_json_array_add (&vam->json_tree);
6105
6106   vat_json_init_object (node);
6107   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6108   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6109   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6110   vat_json_object_add_uint (node, "mode", mp->mode);
6111 }
6112
6113 static int
6114 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6115 {
6116   unformat_input_t *i = vam->input;
6117   vl_api_sw_interface_rx_placement_dump_t *mp;
6118   vl_api_control_ping_t *mp_ping;
6119   int ret;
6120   u32 sw_if_index;
6121   u8 sw_if_index_set = 0;
6122
6123   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6124     {
6125       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6126         sw_if_index_set++;
6127       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6128         sw_if_index_set++;
6129       else
6130         break;
6131     }
6132
6133   print (vam->ofp,
6134          "\n%-11s %-11s %-6s %-5s %-4s",
6135          "sw_if_index", "main/worker", "thread", "queue", "mode");
6136
6137   /* Dump Interface rx placement */
6138   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6139
6140   if (sw_if_index_set)
6141     mp->sw_if_index = htonl (sw_if_index);
6142   else
6143     mp->sw_if_index = ~0;
6144
6145   S (mp);
6146
6147   /* Use a control ping for synchronization */
6148   MPING (CONTROL_PING, mp_ping);
6149   S (mp_ping);
6150
6151   W (ret);
6152   return ret;
6153 }
6154
6155 static int
6156 api_sw_interface_clear_stats (vat_main_t * vam)
6157 {
6158   unformat_input_t *i = vam->input;
6159   vl_api_sw_interface_clear_stats_t *mp;
6160   u32 sw_if_index;
6161   u8 sw_if_index_set = 0;
6162   int ret;
6163
6164   /* Parse args required to build the message */
6165   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6166     {
6167       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6168         sw_if_index_set = 1;
6169       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6170         sw_if_index_set = 1;
6171       else
6172         break;
6173     }
6174
6175   /* Construct the API message */
6176   M (SW_INTERFACE_CLEAR_STATS, mp);
6177
6178   if (sw_if_index_set == 1)
6179     mp->sw_if_index = ntohl (sw_if_index);
6180   else
6181     mp->sw_if_index = ~0;
6182
6183   /* send it... */
6184   S (mp);
6185
6186   /* Wait for a reply, return the good/bad news... */
6187   W (ret);
6188   return ret;
6189 }
6190
6191 static int
6192 api_sw_interface_add_del_address (vat_main_t * vam)
6193 {
6194   unformat_input_t *i = vam->input;
6195   vl_api_sw_interface_add_del_address_t *mp;
6196   u32 sw_if_index;
6197   u8 sw_if_index_set = 0;
6198   u8 is_add = 1, del_all = 0;
6199   u32 address_length = 0;
6200   u8 v4_address_set = 0;
6201   u8 v6_address_set = 0;
6202   ip4_address_t v4address;
6203   ip6_address_t v6address;
6204   int ret;
6205
6206   /* Parse args required to build the message */
6207   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6208     {
6209       if (unformat (i, "del-all"))
6210         del_all = 1;
6211       else if (unformat (i, "del"))
6212         is_add = 0;
6213       else
6214         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6215         sw_if_index_set = 1;
6216       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6217         sw_if_index_set = 1;
6218       else if (unformat (i, "%U/%d",
6219                          unformat_ip4_address, &v4address, &address_length))
6220         v4_address_set = 1;
6221       else if (unformat (i, "%U/%d",
6222                          unformat_ip6_address, &v6address, &address_length))
6223         v6_address_set = 1;
6224       else
6225         break;
6226     }
6227
6228   if (sw_if_index_set == 0)
6229     {
6230       errmsg ("missing interface name or sw_if_index");
6231       return -99;
6232     }
6233   if (v4_address_set && v6_address_set)
6234     {
6235       errmsg ("both v4 and v6 addresses set");
6236       return -99;
6237     }
6238   if (!v4_address_set && !v6_address_set && !del_all)
6239     {
6240       errmsg ("no addresses set");
6241       return -99;
6242     }
6243
6244   /* Construct the API message */
6245   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6246
6247   mp->sw_if_index = ntohl (sw_if_index);
6248   mp->is_add = is_add;
6249   mp->del_all = del_all;
6250   if (v6_address_set)
6251     {
6252       mp->prefix.address.af = ADDRESS_IP6;
6253       clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
6254     }
6255   else
6256     {
6257       mp->prefix.address.af = ADDRESS_IP4;
6258       clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
6259     }
6260   mp->prefix.len = address_length;
6261
6262   /* send it... */
6263   S (mp);
6264
6265   /* Wait for a reply, return good/bad news  */
6266   W (ret);
6267   return ret;
6268 }
6269
6270 static int
6271 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6272 {
6273   unformat_input_t *i = vam->input;
6274   vl_api_sw_interface_set_mpls_enable_t *mp;
6275   u32 sw_if_index;
6276   u8 sw_if_index_set = 0;
6277   u8 enable = 1;
6278   int ret;
6279
6280   /* Parse args required to build the message */
6281   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6282     {
6283       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6284         sw_if_index_set = 1;
6285       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6286         sw_if_index_set = 1;
6287       else if (unformat (i, "disable"))
6288         enable = 0;
6289       else if (unformat (i, "dis"))
6290         enable = 0;
6291       else
6292         break;
6293     }
6294
6295   if (sw_if_index_set == 0)
6296     {
6297       errmsg ("missing interface name or sw_if_index");
6298       return -99;
6299     }
6300
6301   /* Construct the API message */
6302   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6303
6304   mp->sw_if_index = ntohl (sw_if_index);
6305   mp->enable = enable;
6306
6307   /* send it... */
6308   S (mp);
6309
6310   /* Wait for a reply... */
6311   W (ret);
6312   return ret;
6313 }
6314
6315 static int
6316 api_sw_interface_set_table (vat_main_t * vam)
6317 {
6318   unformat_input_t *i = vam->input;
6319   vl_api_sw_interface_set_table_t *mp;
6320   u32 sw_if_index, vrf_id = 0;
6321   u8 sw_if_index_set = 0;
6322   u8 is_ipv6 = 0;
6323   int ret;
6324
6325   /* Parse args required to build the message */
6326   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6327     {
6328       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6329         sw_if_index_set = 1;
6330       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6331         sw_if_index_set = 1;
6332       else if (unformat (i, "vrf %d", &vrf_id))
6333         ;
6334       else if (unformat (i, "ipv6"))
6335         is_ipv6 = 1;
6336       else
6337         break;
6338     }
6339
6340   if (sw_if_index_set == 0)
6341     {
6342       errmsg ("missing interface name or sw_if_index");
6343       return -99;
6344     }
6345
6346   /* Construct the API message */
6347   M (SW_INTERFACE_SET_TABLE, mp);
6348
6349   mp->sw_if_index = ntohl (sw_if_index);
6350   mp->is_ipv6 = is_ipv6;
6351   mp->vrf_id = ntohl (vrf_id);
6352
6353   /* send it... */
6354   S (mp);
6355
6356   /* Wait for a reply... */
6357   W (ret);
6358   return ret;
6359 }
6360
6361 static void vl_api_sw_interface_get_table_reply_t_handler
6362   (vl_api_sw_interface_get_table_reply_t * mp)
6363 {
6364   vat_main_t *vam = &vat_main;
6365
6366   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6367
6368   vam->retval = ntohl (mp->retval);
6369   vam->result_ready = 1;
6370
6371 }
6372
6373 static void vl_api_sw_interface_get_table_reply_t_handler_json
6374   (vl_api_sw_interface_get_table_reply_t * mp)
6375 {
6376   vat_main_t *vam = &vat_main;
6377   vat_json_node_t node;
6378
6379   vat_json_init_object (&node);
6380   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6381   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6382
6383   vat_json_print (vam->ofp, &node);
6384   vat_json_free (&node);
6385
6386   vam->retval = ntohl (mp->retval);
6387   vam->result_ready = 1;
6388 }
6389
6390 static int
6391 api_sw_interface_get_table (vat_main_t * vam)
6392 {
6393   unformat_input_t *i = vam->input;
6394   vl_api_sw_interface_get_table_t *mp;
6395   u32 sw_if_index;
6396   u8 sw_if_index_set = 0;
6397   u8 is_ipv6 = 0;
6398   int ret;
6399
6400   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6401     {
6402       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6403         sw_if_index_set = 1;
6404       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6405         sw_if_index_set = 1;
6406       else if (unformat (i, "ipv6"))
6407         is_ipv6 = 1;
6408       else
6409         break;
6410     }
6411
6412   if (sw_if_index_set == 0)
6413     {
6414       errmsg ("missing interface name or sw_if_index");
6415       return -99;
6416     }
6417
6418   M (SW_INTERFACE_GET_TABLE, mp);
6419   mp->sw_if_index = htonl (sw_if_index);
6420   mp->is_ipv6 = is_ipv6;
6421
6422   S (mp);
6423   W (ret);
6424   return ret;
6425 }
6426
6427 static int
6428 api_sw_interface_set_vpath (vat_main_t * vam)
6429 {
6430   unformat_input_t *i = vam->input;
6431   vl_api_sw_interface_set_vpath_t *mp;
6432   u32 sw_if_index = 0;
6433   u8 sw_if_index_set = 0;
6434   u8 is_enable = 0;
6435   int ret;
6436
6437   /* Parse args required to build the message */
6438   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6439     {
6440       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6441         sw_if_index_set = 1;
6442       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6443         sw_if_index_set = 1;
6444       else if (unformat (i, "enable"))
6445         is_enable = 1;
6446       else if (unformat (i, "disable"))
6447         is_enable = 0;
6448       else
6449         break;
6450     }
6451
6452   if (sw_if_index_set == 0)
6453     {
6454       errmsg ("missing interface name or sw_if_index");
6455       return -99;
6456     }
6457
6458   /* Construct the API message */
6459   M (SW_INTERFACE_SET_VPATH, mp);
6460
6461   mp->sw_if_index = ntohl (sw_if_index);
6462   mp->enable = is_enable;
6463
6464   /* send it... */
6465   S (mp);
6466
6467   /* Wait for a reply... */
6468   W (ret);
6469   return ret;
6470 }
6471
6472 static int
6473 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6474 {
6475   unformat_input_t *i = vam->input;
6476   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6477   u32 sw_if_index = 0;
6478   u8 sw_if_index_set = 0;
6479   u8 is_enable = 1;
6480   u8 is_ipv6 = 0;
6481   int ret;
6482
6483   /* Parse args required to build the message */
6484   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6485     {
6486       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6487         sw_if_index_set = 1;
6488       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6489         sw_if_index_set = 1;
6490       else if (unformat (i, "enable"))
6491         is_enable = 1;
6492       else if (unformat (i, "disable"))
6493         is_enable = 0;
6494       else if (unformat (i, "ip4"))
6495         is_ipv6 = 0;
6496       else if (unformat (i, "ip6"))
6497         is_ipv6 = 1;
6498       else
6499         break;
6500     }
6501
6502   if (sw_if_index_set == 0)
6503     {
6504       errmsg ("missing interface name or sw_if_index");
6505       return -99;
6506     }
6507
6508   /* Construct the API message */
6509   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6510
6511   mp->sw_if_index = ntohl (sw_if_index);
6512   mp->enable = is_enable;
6513   mp->is_ipv6 = is_ipv6;
6514
6515   /* send it... */
6516   S (mp);
6517
6518   /* Wait for a reply... */
6519   W (ret);
6520   return ret;
6521 }
6522
6523 static int
6524 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6525 {
6526   unformat_input_t *i = vam->input;
6527   vl_api_sw_interface_set_geneve_bypass_t *mp;
6528   u32 sw_if_index = 0;
6529   u8 sw_if_index_set = 0;
6530   u8 is_enable = 1;
6531   u8 is_ipv6 = 0;
6532   int ret;
6533
6534   /* Parse args required to build the message */
6535   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6536     {
6537       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6538         sw_if_index_set = 1;
6539       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6540         sw_if_index_set = 1;
6541       else if (unformat (i, "enable"))
6542         is_enable = 1;
6543       else if (unformat (i, "disable"))
6544         is_enable = 0;
6545       else if (unformat (i, "ip4"))
6546         is_ipv6 = 0;
6547       else if (unformat (i, "ip6"))
6548         is_ipv6 = 1;
6549       else
6550         break;
6551     }
6552
6553   if (sw_if_index_set == 0)
6554     {
6555       errmsg ("missing interface name or sw_if_index");
6556       return -99;
6557     }
6558
6559   /* Construct the API message */
6560   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6561
6562   mp->sw_if_index = ntohl (sw_if_index);
6563   mp->enable = is_enable;
6564   mp->is_ipv6 = is_ipv6;
6565
6566   /* send it... */
6567   S (mp);
6568
6569   /* Wait for a reply... */
6570   W (ret);
6571   return ret;
6572 }
6573
6574 static int
6575 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6576 {
6577   unformat_input_t *i = vam->input;
6578   vl_api_sw_interface_set_l2_xconnect_t *mp;
6579   u32 rx_sw_if_index;
6580   u8 rx_sw_if_index_set = 0;
6581   u32 tx_sw_if_index;
6582   u8 tx_sw_if_index_set = 0;
6583   u8 enable = 1;
6584   int ret;
6585
6586   /* Parse args required to build the message */
6587   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6588     {
6589       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6590         rx_sw_if_index_set = 1;
6591       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6592         tx_sw_if_index_set = 1;
6593       else if (unformat (i, "rx"))
6594         {
6595           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6596             {
6597               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6598                             &rx_sw_if_index))
6599                 rx_sw_if_index_set = 1;
6600             }
6601           else
6602             break;
6603         }
6604       else if (unformat (i, "tx"))
6605         {
6606           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6607             {
6608               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6609                             &tx_sw_if_index))
6610                 tx_sw_if_index_set = 1;
6611             }
6612           else
6613             break;
6614         }
6615       else if (unformat (i, "enable"))
6616         enable = 1;
6617       else if (unformat (i, "disable"))
6618         enable = 0;
6619       else
6620         break;
6621     }
6622
6623   if (rx_sw_if_index_set == 0)
6624     {
6625       errmsg ("missing rx interface name or rx_sw_if_index");
6626       return -99;
6627     }
6628
6629   if (enable && (tx_sw_if_index_set == 0))
6630     {
6631       errmsg ("missing tx interface name or tx_sw_if_index");
6632       return -99;
6633     }
6634
6635   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6636
6637   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6638   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6639   mp->enable = enable;
6640
6641   S (mp);
6642   W (ret);
6643   return ret;
6644 }
6645
6646 static int
6647 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6648 {
6649   unformat_input_t *i = vam->input;
6650   vl_api_sw_interface_set_l2_bridge_t *mp;
6651   vl_api_l2_port_type_t port_type;
6652   u32 rx_sw_if_index;
6653   u8 rx_sw_if_index_set = 0;
6654   u32 bd_id;
6655   u8 bd_id_set = 0;
6656   u32 shg = 0;
6657   u8 enable = 1;
6658   int ret;
6659
6660   port_type = L2_API_PORT_TYPE_NORMAL;
6661
6662   /* Parse args required to build the message */
6663   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6664     {
6665       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6666         rx_sw_if_index_set = 1;
6667       else if (unformat (i, "bd_id %d", &bd_id))
6668         bd_id_set = 1;
6669       else
6670         if (unformat
6671             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6672         rx_sw_if_index_set = 1;
6673       else if (unformat (i, "shg %d", &shg))
6674         ;
6675       else if (unformat (i, "bvi"))
6676         port_type = L2_API_PORT_TYPE_BVI;
6677       else if (unformat (i, "uu-fwd"))
6678         port_type = L2_API_PORT_TYPE_UU_FWD;
6679       else if (unformat (i, "enable"))
6680         enable = 1;
6681       else if (unformat (i, "disable"))
6682         enable = 0;
6683       else
6684         break;
6685     }
6686
6687   if (rx_sw_if_index_set == 0)
6688     {
6689       errmsg ("missing rx interface name or sw_if_index");
6690       return -99;
6691     }
6692
6693   if (enable && (bd_id_set == 0))
6694     {
6695       errmsg ("missing bridge domain");
6696       return -99;
6697     }
6698
6699   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6700
6701   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6702   mp->bd_id = ntohl (bd_id);
6703   mp->shg = (u8) shg;
6704   mp->port_type = ntohl (port_type);
6705   mp->enable = enable;
6706
6707   S (mp);
6708   W (ret);
6709   return ret;
6710 }
6711
6712 static int
6713 api_bridge_domain_dump (vat_main_t * vam)
6714 {
6715   unformat_input_t *i = vam->input;
6716   vl_api_bridge_domain_dump_t *mp;
6717   vl_api_control_ping_t *mp_ping;
6718   u32 bd_id = ~0;
6719   int ret;
6720
6721   /* Parse args required to build the message */
6722   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6723     {
6724       if (unformat (i, "bd_id %d", &bd_id))
6725         ;
6726       else
6727         break;
6728     }
6729
6730   M (BRIDGE_DOMAIN_DUMP, mp);
6731   mp->bd_id = ntohl (bd_id);
6732   S (mp);
6733
6734   /* Use a control ping for synchronization */
6735   MPING (CONTROL_PING, mp_ping);
6736   S (mp_ping);
6737
6738   W (ret);
6739   return ret;
6740 }
6741
6742 static int
6743 api_bridge_domain_add_del (vat_main_t * vam)
6744 {
6745   unformat_input_t *i = vam->input;
6746   vl_api_bridge_domain_add_del_t *mp;
6747   u32 bd_id = ~0;
6748   u8 is_add = 1;
6749   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6750   u8 *bd_tag = NULL;
6751   u32 mac_age = 0;
6752   int ret;
6753
6754   /* Parse args required to build the message */
6755   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6756     {
6757       if (unformat (i, "bd_id %d", &bd_id))
6758         ;
6759       else if (unformat (i, "flood %d", &flood))
6760         ;
6761       else if (unformat (i, "uu-flood %d", &uu_flood))
6762         ;
6763       else if (unformat (i, "forward %d", &forward))
6764         ;
6765       else if (unformat (i, "learn %d", &learn))
6766         ;
6767       else if (unformat (i, "arp-term %d", &arp_term))
6768         ;
6769       else if (unformat (i, "mac-age %d", &mac_age))
6770         ;
6771       else if (unformat (i, "bd-tag %s", &bd_tag))
6772         ;
6773       else if (unformat (i, "del"))
6774         {
6775           is_add = 0;
6776           flood = uu_flood = forward = learn = 0;
6777         }
6778       else
6779         break;
6780     }
6781
6782   if (bd_id == ~0)
6783     {
6784       errmsg ("missing bridge domain");
6785       ret = -99;
6786       goto done;
6787     }
6788
6789   if (mac_age > 255)
6790     {
6791       errmsg ("mac age must be less than 256 ");
6792       ret = -99;
6793       goto done;
6794     }
6795
6796   if ((bd_tag) && (vec_len (bd_tag) > 63))
6797     {
6798       errmsg ("bd-tag cannot be longer than 63");
6799       ret = -99;
6800       goto done;
6801     }
6802
6803   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6804
6805   mp->bd_id = ntohl (bd_id);
6806   mp->flood = flood;
6807   mp->uu_flood = uu_flood;
6808   mp->forward = forward;
6809   mp->learn = learn;
6810   mp->arp_term = arp_term;
6811   mp->is_add = is_add;
6812   mp->mac_age = (u8) mac_age;
6813   if (bd_tag)
6814     {
6815       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6816       mp->bd_tag[vec_len (bd_tag)] = 0;
6817     }
6818   S (mp);
6819   W (ret);
6820
6821 done:
6822   vec_free (bd_tag);
6823   return ret;
6824 }
6825
6826 static int
6827 api_l2fib_flush_bd (vat_main_t * vam)
6828 {
6829   unformat_input_t *i = vam->input;
6830   vl_api_l2fib_flush_bd_t *mp;
6831   u32 bd_id = ~0;
6832   int ret;
6833
6834   /* Parse args required to build the message */
6835   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6836     {
6837       if (unformat (i, "bd_id %d", &bd_id));
6838       else
6839         break;
6840     }
6841
6842   if (bd_id == ~0)
6843     {
6844       errmsg ("missing bridge domain");
6845       return -99;
6846     }
6847
6848   M (L2FIB_FLUSH_BD, mp);
6849
6850   mp->bd_id = htonl (bd_id);
6851
6852   S (mp);
6853   W (ret);
6854   return ret;
6855 }
6856
6857 static int
6858 api_l2fib_flush_int (vat_main_t * vam)
6859 {
6860   unformat_input_t *i = vam->input;
6861   vl_api_l2fib_flush_int_t *mp;
6862   u32 sw_if_index = ~0;
6863   int ret;
6864
6865   /* Parse args required to build the message */
6866   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6867     {
6868       if (unformat (i, "sw_if_index %d", &sw_if_index));
6869       else
6870         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6871       else
6872         break;
6873     }
6874
6875   if (sw_if_index == ~0)
6876     {
6877       errmsg ("missing interface name or sw_if_index");
6878       return -99;
6879     }
6880
6881   M (L2FIB_FLUSH_INT, mp);
6882
6883   mp->sw_if_index = ntohl (sw_if_index);
6884
6885   S (mp);
6886   W (ret);
6887   return ret;
6888 }
6889
6890 static int
6891 api_l2fib_add_del (vat_main_t * vam)
6892 {
6893   unformat_input_t *i = vam->input;
6894   vl_api_l2fib_add_del_t *mp;
6895   f64 timeout;
6896   u8 mac[6] = { 0 };
6897   u8 mac_set = 0;
6898   u32 bd_id;
6899   u8 bd_id_set = 0;
6900   u32 sw_if_index = 0;
6901   u8 sw_if_index_set = 0;
6902   u8 is_add = 1;
6903   u8 static_mac = 0;
6904   u8 filter_mac = 0;
6905   u8 bvi_mac = 0;
6906   int count = 1;
6907   f64 before = 0;
6908   int j;
6909
6910   /* Parse args required to build the message */
6911   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6912     {
6913       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6914         mac_set = 1;
6915       else if (unformat (i, "bd_id %d", &bd_id))
6916         bd_id_set = 1;
6917       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6918         sw_if_index_set = 1;
6919       else if (unformat (i, "sw_if"))
6920         {
6921           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6922             {
6923               if (unformat
6924                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6925                 sw_if_index_set = 1;
6926             }
6927           else
6928             break;
6929         }
6930       else if (unformat (i, "static"))
6931         static_mac = 1;
6932       else if (unformat (i, "filter"))
6933         {
6934           filter_mac = 1;
6935           static_mac = 1;
6936         }
6937       else if (unformat (i, "bvi"))
6938         {
6939           bvi_mac = 1;
6940           static_mac = 1;
6941         }
6942       else if (unformat (i, "del"))
6943         is_add = 0;
6944       else if (unformat (i, "count %d", &count))
6945         ;
6946       else
6947         break;
6948     }
6949
6950   if (mac_set == 0)
6951     {
6952       errmsg ("missing mac address");
6953       return -99;
6954     }
6955
6956   if (bd_id_set == 0)
6957     {
6958       errmsg ("missing bridge domain");
6959       return -99;
6960     }
6961
6962   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6963     {
6964       errmsg ("missing interface name or sw_if_index");
6965       return -99;
6966     }
6967
6968   if (count > 1)
6969     {
6970       /* Turn on async mode */
6971       vam->async_mode = 1;
6972       vam->async_errors = 0;
6973       before = vat_time_now (vam);
6974     }
6975
6976   for (j = 0; j < count; j++)
6977     {
6978       M (L2FIB_ADD_DEL, mp);
6979
6980       clib_memcpy (mp->mac, mac, 6);
6981       mp->bd_id = ntohl (bd_id);
6982       mp->is_add = is_add;
6983       mp->sw_if_index = ntohl (sw_if_index);
6984
6985       if (is_add)
6986         {
6987           mp->static_mac = static_mac;
6988           mp->filter_mac = filter_mac;
6989           mp->bvi_mac = bvi_mac;
6990         }
6991       increment_mac_address (mac);
6992       /* send it... */
6993       S (mp);
6994     }
6995
6996   if (count > 1)
6997     {
6998       vl_api_control_ping_t *mp_ping;
6999       f64 after;
7000
7001       /* Shut off async mode */
7002       vam->async_mode = 0;
7003
7004       MPING (CONTROL_PING, mp_ping);
7005       S (mp_ping);
7006
7007       timeout = vat_time_now (vam) + 1.0;
7008       while (vat_time_now (vam) < timeout)
7009         if (vam->result_ready == 1)
7010           goto out;
7011       vam->retval = -99;
7012
7013     out:
7014       if (vam->retval == -99)
7015         errmsg ("timeout");
7016
7017       if (vam->async_errors > 0)
7018         {
7019           errmsg ("%d asynchronous errors", vam->async_errors);
7020           vam->retval = -98;
7021         }
7022       vam->async_errors = 0;
7023       after = vat_time_now (vam);
7024
7025       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7026              count, after - before, count / (after - before));
7027     }
7028   else
7029     {
7030       int ret;
7031
7032       /* Wait for a reply... */
7033       W (ret);
7034       return ret;
7035     }
7036   /* Return the good/bad news */
7037   return (vam->retval);
7038 }
7039
7040 static int
7041 api_bridge_domain_set_mac_age (vat_main_t * vam)
7042 {
7043   unformat_input_t *i = vam->input;
7044   vl_api_bridge_domain_set_mac_age_t *mp;
7045   u32 bd_id = ~0;
7046   u32 mac_age = 0;
7047   int ret;
7048
7049   /* Parse args required to build the message */
7050   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7051     {
7052       if (unformat (i, "bd_id %d", &bd_id));
7053       else if (unformat (i, "mac-age %d", &mac_age));
7054       else
7055         break;
7056     }
7057
7058   if (bd_id == ~0)
7059     {
7060       errmsg ("missing bridge domain");
7061       return -99;
7062     }
7063
7064   if (mac_age > 255)
7065     {
7066       errmsg ("mac age must be less than 256 ");
7067       return -99;
7068     }
7069
7070   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7071
7072   mp->bd_id = htonl (bd_id);
7073   mp->mac_age = (u8) mac_age;
7074
7075   S (mp);
7076   W (ret);
7077   return ret;
7078 }
7079
7080 static int
7081 api_l2_flags (vat_main_t * vam)
7082 {
7083   unformat_input_t *i = vam->input;
7084   vl_api_l2_flags_t *mp;
7085   u32 sw_if_index;
7086   u32 flags = 0;
7087   u8 sw_if_index_set = 0;
7088   u8 is_set = 0;
7089   int ret;
7090
7091   /* Parse args required to build the message */
7092   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7093     {
7094       if (unformat (i, "sw_if_index %d", &sw_if_index))
7095         sw_if_index_set = 1;
7096       else if (unformat (i, "sw_if"))
7097         {
7098           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7099             {
7100               if (unformat
7101                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7102                 sw_if_index_set = 1;
7103             }
7104           else
7105             break;
7106         }
7107       else if (unformat (i, "learn"))
7108         flags |= L2_LEARN;
7109       else if (unformat (i, "forward"))
7110         flags |= L2_FWD;
7111       else if (unformat (i, "flood"))
7112         flags |= L2_FLOOD;
7113       else if (unformat (i, "uu-flood"))
7114         flags |= L2_UU_FLOOD;
7115       else if (unformat (i, "arp-term"))
7116         flags |= L2_ARP_TERM;
7117       else if (unformat (i, "off"))
7118         is_set = 0;
7119       else if (unformat (i, "disable"))
7120         is_set = 0;
7121       else
7122         break;
7123     }
7124
7125   if (sw_if_index_set == 0)
7126     {
7127       errmsg ("missing interface name or sw_if_index");
7128       return -99;
7129     }
7130
7131   M (L2_FLAGS, mp);
7132
7133   mp->sw_if_index = ntohl (sw_if_index);
7134   mp->feature_bitmap = ntohl (flags);
7135   mp->is_set = is_set;
7136
7137   S (mp);
7138   W (ret);
7139   return ret;
7140 }
7141
7142 static int
7143 api_bridge_flags (vat_main_t * vam)
7144 {
7145   unformat_input_t *i = vam->input;
7146   vl_api_bridge_flags_t *mp;
7147   u32 bd_id;
7148   u8 bd_id_set = 0;
7149   u8 is_set = 1;
7150   bd_flags_t flags = 0;
7151   int ret;
7152
7153   /* Parse args required to build the message */
7154   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7155     {
7156       if (unformat (i, "bd_id %d", &bd_id))
7157         bd_id_set = 1;
7158       else if (unformat (i, "learn"))
7159         flags |= BRIDGE_API_FLAG_LEARN;
7160       else if (unformat (i, "forward"))
7161         flags |= BRIDGE_API_FLAG_FWD;
7162       else if (unformat (i, "flood"))
7163         flags |= BRIDGE_API_FLAG_FLOOD;
7164       else if (unformat (i, "uu-flood"))
7165         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7166       else if (unformat (i, "arp-term"))
7167         flags |= BRIDGE_API_FLAG_ARP_TERM;
7168       else if (unformat (i, "off"))
7169         is_set = 0;
7170       else if (unformat (i, "disable"))
7171         is_set = 0;
7172       else
7173         break;
7174     }
7175
7176   if (bd_id_set == 0)
7177     {
7178       errmsg ("missing bridge domain");
7179       return -99;
7180     }
7181
7182   M (BRIDGE_FLAGS, mp);
7183
7184   mp->bd_id = ntohl (bd_id);
7185   mp->flags = ntohl (flags);
7186   mp->is_set = is_set;
7187
7188   S (mp);
7189   W (ret);
7190   return ret;
7191 }
7192
7193 static int
7194 api_bd_ip_mac_add_del (vat_main_t * vam)
7195 {
7196   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7197   vl_api_mac_address_t mac = { 0 };
7198   unformat_input_t *i = vam->input;
7199   vl_api_bd_ip_mac_add_del_t *mp;
7200   u32 bd_id;
7201   u8 is_add = 1;
7202   u8 bd_id_set = 0;
7203   u8 ip_set = 0;
7204   u8 mac_set = 0;
7205   int ret;
7206
7207
7208   /* Parse args required to build the message */
7209   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7210     {
7211       if (unformat (i, "bd_id %d", &bd_id))
7212         {
7213           bd_id_set++;
7214         }
7215       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7216         {
7217           ip_set++;
7218         }
7219       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7220         {
7221           mac_set++;
7222         }
7223       else if (unformat (i, "del"))
7224         is_add = 0;
7225       else
7226         break;
7227     }
7228
7229   if (bd_id_set == 0)
7230     {
7231       errmsg ("missing bridge domain");
7232       return -99;
7233     }
7234   else if (ip_set == 0)
7235     {
7236       errmsg ("missing IP address");
7237       return -99;
7238     }
7239   else if (mac_set == 0)
7240     {
7241       errmsg ("missing MAC address");
7242       return -99;
7243     }
7244
7245   M (BD_IP_MAC_ADD_DEL, mp);
7246
7247   mp->entry.bd_id = ntohl (bd_id);
7248   mp->is_add = is_add;
7249
7250   clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
7251   clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
7252
7253   S (mp);
7254   W (ret);
7255   return ret;
7256 }
7257
7258 static int
7259 api_bd_ip_mac_flush (vat_main_t * vam)
7260 {
7261   unformat_input_t *i = vam->input;
7262   vl_api_bd_ip_mac_flush_t *mp;
7263   u32 bd_id;
7264   u8 bd_id_set = 0;
7265   int ret;
7266
7267   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7268     {
7269       if (unformat (i, "bd_id %d", &bd_id))
7270         {
7271           bd_id_set++;
7272         }
7273       else
7274         break;
7275     }
7276
7277   if (bd_id_set == 0)
7278     {
7279       errmsg ("missing bridge domain");
7280       return -99;
7281     }
7282
7283   M (BD_IP_MAC_FLUSH, mp);
7284
7285   mp->bd_id = ntohl (bd_id);
7286
7287   S (mp);
7288   W (ret);
7289   return ret;
7290 }
7291
7292 static void vl_api_bd_ip_mac_details_t_handler
7293   (vl_api_bd_ip_mac_details_t * mp)
7294 {
7295   vat_main_t *vam = &vat_main;
7296
7297   print (vam->ofp,
7298          "\n%-5d %U %U",
7299          ntohl (mp->entry.bd_id),
7300          format_vl_api_mac_address, mp->entry.mac,
7301          format_vl_api_address, &mp->entry.ip);
7302 }
7303
7304 static void vl_api_bd_ip_mac_details_t_handler_json
7305   (vl_api_bd_ip_mac_details_t * mp)
7306 {
7307   vat_main_t *vam = &vat_main;
7308   vat_json_node_t *node = NULL;
7309
7310   if (VAT_JSON_ARRAY != vam->json_tree.type)
7311     {
7312       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7313       vat_json_init_array (&vam->json_tree);
7314     }
7315   node = vat_json_array_add (&vam->json_tree);
7316
7317   vat_json_init_object (node);
7318   vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
7319   vat_json_object_add_string_copy (node, "mac_address",
7320                                    format (0, "%U", format_vl_api_mac_address,
7321                                            &mp->entry.mac));
7322   u8 *ip = 0;
7323
7324   ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
7325   vat_json_object_add_string_copy (node, "ip_address", ip);
7326   vec_free (ip);
7327 }
7328
7329 static int
7330 api_bd_ip_mac_dump (vat_main_t * vam)
7331 {
7332   unformat_input_t *i = vam->input;
7333   vl_api_bd_ip_mac_dump_t *mp;
7334   vl_api_control_ping_t *mp_ping;
7335   int ret;
7336   u32 bd_id;
7337   u8 bd_id_set = 0;
7338
7339   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7340     {
7341       if (unformat (i, "bd_id %d", &bd_id))
7342         {
7343           bd_id_set++;
7344         }
7345       else
7346         break;
7347     }
7348
7349   print (vam->ofp,
7350          "\n%-5s %-7s %-20s %-30s",
7351          "bd_id", "is_ipv6", "mac_address", "ip_address");
7352
7353   /* Dump Bridge Domain Ip to Mac entries */
7354   M (BD_IP_MAC_DUMP, mp);
7355
7356   if (bd_id_set)
7357     mp->bd_id = htonl (bd_id);
7358   else
7359     mp->bd_id = ~0;
7360
7361   S (mp);
7362
7363   /* Use a control ping for synchronization */
7364   MPING (CONTROL_PING, mp_ping);
7365   S (mp_ping);
7366
7367   W (ret);
7368   return ret;
7369 }
7370
7371 static int
7372 api_tap_create_v2 (vat_main_t * vam)
7373 {
7374   unformat_input_t *i = vam->input;
7375   vl_api_tap_create_v2_t *mp;
7376 #define TAP_FLAG_GSO (1 << 0)
7377   u8 mac_address[6];
7378   u8 random_mac = 1;
7379   u32 id = ~0;
7380   u8 *host_if_name = 0;
7381   u8 *host_ns = 0;
7382   u8 host_mac_addr[6];
7383   u8 host_mac_addr_set = 0;
7384   u8 *host_bridge = 0;
7385   ip4_address_t host_ip4_addr;
7386   ip4_address_t host_ip4_gw;
7387   u8 host_ip4_gw_set = 0;
7388   u32 host_ip4_prefix_len = 0;
7389   ip6_address_t host_ip6_addr;
7390   ip6_address_t host_ip6_gw;
7391   u8 host_ip6_gw_set = 0;
7392   u32 host_ip6_prefix_len = 0;
7393   u8 host_mtu_set = 0;
7394   u32 host_mtu_size = 0;
7395   u32 tap_flags = 0;
7396   int ret;
7397   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7398
7399   clib_memset (mac_address, 0, sizeof (mac_address));
7400
7401   /* Parse args required to build the message */
7402   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7403     {
7404       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7405         {
7406           random_mac = 0;
7407         }
7408       else if (unformat (i, "id %u", &id))
7409         ;
7410       else if (unformat (i, "host-if-name %s", &host_if_name))
7411         ;
7412       else if (unformat (i, "host-ns %s", &host_ns))
7413         ;
7414       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7415                          host_mac_addr))
7416         host_mac_addr_set = 1;
7417       else if (unformat (i, "host-bridge %s", &host_bridge))
7418         ;
7419       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7420                          &host_ip4_addr, &host_ip4_prefix_len))
7421         ;
7422       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7423                          &host_ip6_addr, &host_ip6_prefix_len))
7424         ;
7425       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7426                          &host_ip4_gw))
7427         host_ip4_gw_set = 1;
7428       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7429                          &host_ip6_gw))
7430         host_ip6_gw_set = 1;
7431       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7432         ;
7433       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7434         ;
7435       else if (unformat (i, "host-mtu-size %d", &host_mtu_size))
7436         host_mtu_set = 1;
7437       else if (unformat (i, "no-gso"))
7438         tap_flags &= ~TAP_FLAG_GSO;
7439       else if (unformat (i, "gso"))
7440         tap_flags |= TAP_FLAG_GSO;
7441       else
7442         break;
7443     }
7444
7445   if (vec_len (host_if_name) > 63)
7446     {
7447       errmsg ("tap name too long. ");
7448       return -99;
7449     }
7450   if (vec_len (host_ns) > 63)
7451     {
7452       errmsg ("host name space too long. ");
7453       return -99;
7454     }
7455   if (vec_len (host_bridge) > 63)
7456     {
7457       errmsg ("host bridge name too long. ");
7458       return -99;
7459     }
7460   if (host_ip4_prefix_len > 32)
7461     {
7462       errmsg ("host ip4 prefix length not valid. ");
7463       return -99;
7464     }
7465   if (host_ip6_prefix_len > 128)
7466     {
7467       errmsg ("host ip6 prefix length not valid. ");
7468       return -99;
7469     }
7470   if (!is_pow2 (rx_ring_sz))
7471     {
7472       errmsg ("rx ring size must be power of 2. ");
7473       return -99;
7474     }
7475   if (rx_ring_sz > 32768)
7476     {
7477       errmsg ("rx ring size must be 32768 or lower. ");
7478       return -99;
7479     }
7480   if (!is_pow2 (tx_ring_sz))
7481     {
7482       errmsg ("tx ring size must be power of 2. ");
7483       return -99;
7484     }
7485   if (tx_ring_sz > 32768)
7486     {
7487       errmsg ("tx ring size must be 32768 or lower. ");
7488       return -99;
7489     }
7490   if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
7491     {
7492       errmsg ("host MTU size must be in between 64 and 65355. ");
7493       return -99;
7494     }
7495
7496   /* Construct the API message */
7497   M (TAP_CREATE_V2, mp);
7498
7499   mp->use_random_mac = random_mac;
7500
7501   mp->id = ntohl (id);
7502   mp->host_namespace_set = host_ns != 0;
7503   mp->host_bridge_set = host_bridge != 0;
7504   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7505   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7506   mp->rx_ring_sz = ntohs (rx_ring_sz);
7507   mp->tx_ring_sz = ntohs (tx_ring_sz);
7508   mp->host_mtu_set = host_mtu_set;
7509   mp->host_mtu_size = ntohl (host_mtu_size);
7510   mp->tap_flags = ntohl (tap_flags);
7511
7512   if (random_mac == 0)
7513     clib_memcpy (mp->mac_address, mac_address, 6);
7514   if (host_mac_addr_set)
7515     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7516   if (host_if_name)
7517     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7518   if (host_ns)
7519     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7520   if (host_bridge)
7521     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7522   if (host_ip4_prefix_len)
7523     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
7524   if (host_ip6_prefix_len)
7525     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
7526   if (host_ip4_gw_set)
7527     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7528   if (host_ip6_gw_set)
7529     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7530
7531   vec_free (host_ns);
7532   vec_free (host_if_name);
7533   vec_free (host_bridge);
7534
7535   /* send it... */
7536   S (mp);
7537
7538   /* Wait for a reply... */
7539   W (ret);
7540   return ret;
7541 }
7542
7543 static int
7544 api_tap_delete_v2 (vat_main_t * vam)
7545 {
7546   unformat_input_t *i = vam->input;
7547   vl_api_tap_delete_v2_t *mp;
7548   u32 sw_if_index = ~0;
7549   u8 sw_if_index_set = 0;
7550   int ret;
7551
7552   /* Parse args required to build the message */
7553   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7554     {
7555       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7556         sw_if_index_set = 1;
7557       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7558         sw_if_index_set = 1;
7559       else
7560         break;
7561     }
7562
7563   if (sw_if_index_set == 0)
7564     {
7565       errmsg ("missing vpp interface name. ");
7566       return -99;
7567     }
7568
7569   /* Construct the API message */
7570   M (TAP_DELETE_V2, mp);
7571
7572   mp->sw_if_index = ntohl (sw_if_index);
7573
7574   /* send it... */
7575   S (mp);
7576
7577   /* Wait for a reply... */
7578   W (ret);
7579   return ret;
7580 }
7581
7582 uword
7583 unformat_vlib_pci_addr (unformat_input_t * input, va_list * args)
7584 {
7585   vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
7586   u32 x[4];
7587
7588   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7589     return 0;
7590
7591   addr->domain = x[0];
7592   addr->bus = x[1];
7593   addr->slot = x[2];
7594   addr->function = x[3];
7595
7596   return 1;
7597 }
7598
7599 static int
7600 api_virtio_pci_create (vat_main_t * vam)
7601 {
7602   unformat_input_t *i = vam->input;
7603   vl_api_virtio_pci_create_t *mp;
7604   u8 mac_address[6];
7605   u8 random_mac = 1;
7606   u8 gso_enabled = 0;
7607   u32 pci_addr = 0;
7608   u64 features = (u64) ~ (0ULL);
7609   int ret;
7610
7611   clib_memset (mac_address, 0, sizeof (mac_address));
7612
7613   /* Parse args required to build the message */
7614   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7615     {
7616       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7617         {
7618           random_mac = 0;
7619         }
7620       else if (unformat (i, "pci-addr %U", unformat_vlib_pci_addr, &pci_addr))
7621         ;
7622       else if (unformat (i, "features 0x%llx", &features))
7623         ;
7624       else if (unformat (i, "gso-enabled"))
7625         gso_enabled = 1;
7626       else
7627         break;
7628     }
7629
7630   if (pci_addr == 0)
7631     {
7632       errmsg ("pci address must be non zero. ");
7633       return -99;
7634     }
7635
7636   /* Construct the API message */
7637   M (VIRTIO_PCI_CREATE, mp);
7638
7639   mp->use_random_mac = random_mac;
7640
7641   mp->pci_addr = htonl (pci_addr);
7642   mp->features = clib_host_to_net_u64 (features);
7643   mp->gso_enabled = gso_enabled;
7644
7645   if (random_mac == 0)
7646     clib_memcpy (mp->mac_address, mac_address, 6);
7647
7648   /* send it... */
7649   S (mp);
7650
7651   /* Wait for a reply... */
7652   W (ret);
7653   return ret;
7654 }
7655
7656 static int
7657 api_virtio_pci_delete (vat_main_t * vam)
7658 {
7659   unformat_input_t *i = vam->input;
7660   vl_api_virtio_pci_delete_t *mp;
7661   u32 sw_if_index = ~0;
7662   u8 sw_if_index_set = 0;
7663   int ret;
7664
7665   /* Parse args required to build the message */
7666   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7667     {
7668       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7669         sw_if_index_set = 1;
7670       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7671         sw_if_index_set = 1;
7672       else
7673         break;
7674     }
7675
7676   if (sw_if_index_set == 0)
7677     {
7678       errmsg ("missing vpp interface name. ");
7679       return -99;
7680     }
7681
7682   /* Construct the API message */
7683   M (VIRTIO_PCI_DELETE, mp);
7684
7685   mp->sw_if_index = htonl (sw_if_index);
7686
7687   /* send it... */
7688   S (mp);
7689
7690   /* Wait for a reply... */
7691   W (ret);
7692   return ret;
7693 }
7694
7695 static int
7696 api_bond_create (vat_main_t * vam)
7697 {
7698   unformat_input_t *i = vam->input;
7699   vl_api_bond_create_t *mp;
7700   u8 mac_address[6];
7701   u8 custom_mac = 0;
7702   int ret;
7703   u8 mode;
7704   u8 lb;
7705   u8 mode_is_set = 0;
7706   u32 id = ~0;
7707   u8 numa_only = 0;
7708
7709   clib_memset (mac_address, 0, sizeof (mac_address));
7710   lb = BOND_LB_L2;
7711
7712   /* Parse args required to build the message */
7713   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7714     {
7715       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7716         mode_is_set = 1;
7717       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7718                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7719         ;
7720       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7721                          mac_address))
7722         custom_mac = 1;
7723       else if (unformat (i, "numa-only"))
7724         numa_only = 1;
7725       else if (unformat (i, "id %u", &id))
7726         ;
7727       else
7728         break;
7729     }
7730
7731   if (mode_is_set == 0)
7732     {
7733       errmsg ("Missing bond mode. ");
7734       return -99;
7735     }
7736
7737   /* Construct the API message */
7738   M (BOND_CREATE, mp);
7739
7740   mp->use_custom_mac = custom_mac;
7741
7742   mp->mode = htonl (mode);
7743   mp->lb = htonl (lb);
7744   mp->id = htonl (id);
7745   mp->numa_only = numa_only;
7746
7747   if (custom_mac)
7748     clib_memcpy (mp->mac_address, mac_address, 6);
7749
7750   /* send it... */
7751   S (mp);
7752
7753   /* Wait for a reply... */
7754   W (ret);
7755   return ret;
7756 }
7757
7758 static int
7759 api_bond_delete (vat_main_t * vam)
7760 {
7761   unformat_input_t *i = vam->input;
7762   vl_api_bond_delete_t *mp;
7763   u32 sw_if_index = ~0;
7764   u8 sw_if_index_set = 0;
7765   int ret;
7766
7767   /* Parse args required to build the message */
7768   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7769     {
7770       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7771         sw_if_index_set = 1;
7772       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7773         sw_if_index_set = 1;
7774       else
7775         break;
7776     }
7777
7778   if (sw_if_index_set == 0)
7779     {
7780       errmsg ("missing vpp interface name. ");
7781       return -99;
7782     }
7783
7784   /* Construct the API message */
7785   M (BOND_DELETE, mp);
7786
7787   mp->sw_if_index = ntohl (sw_if_index);
7788
7789   /* send it... */
7790   S (mp);
7791
7792   /* Wait for a reply... */
7793   W (ret);
7794   return ret;
7795 }
7796
7797 static int
7798 api_bond_enslave (vat_main_t * vam)
7799 {
7800   unformat_input_t *i = vam->input;
7801   vl_api_bond_enslave_t *mp;
7802   u32 bond_sw_if_index;
7803   int ret;
7804   u8 is_passive;
7805   u8 is_long_timeout;
7806   u32 bond_sw_if_index_is_set = 0;
7807   u32 sw_if_index;
7808   u8 sw_if_index_is_set = 0;
7809
7810   /* Parse args required to build the message */
7811   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7812     {
7813       if (unformat (i, "sw_if_index %d", &sw_if_index))
7814         sw_if_index_is_set = 1;
7815       else if (unformat (i, "bond %u", &bond_sw_if_index))
7816         bond_sw_if_index_is_set = 1;
7817       else if (unformat (i, "passive %d", &is_passive))
7818         ;
7819       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7820         ;
7821       else
7822         break;
7823     }
7824
7825   if (bond_sw_if_index_is_set == 0)
7826     {
7827       errmsg ("Missing bond sw_if_index. ");
7828       return -99;
7829     }
7830   if (sw_if_index_is_set == 0)
7831     {
7832       errmsg ("Missing slave sw_if_index. ");
7833       return -99;
7834     }
7835
7836   /* Construct the API message */
7837   M (BOND_ENSLAVE, mp);
7838
7839   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7840   mp->sw_if_index = ntohl (sw_if_index);
7841   mp->is_long_timeout = is_long_timeout;
7842   mp->is_passive = is_passive;
7843
7844   /* send it... */
7845   S (mp);
7846
7847   /* Wait for a reply... */
7848   W (ret);
7849   return ret;
7850 }
7851
7852 static int
7853 api_bond_detach_slave (vat_main_t * vam)
7854 {
7855   unformat_input_t *i = vam->input;
7856   vl_api_bond_detach_slave_t *mp;
7857   u32 sw_if_index = ~0;
7858   u8 sw_if_index_set = 0;
7859   int ret;
7860
7861   /* Parse args required to build the message */
7862   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7863     {
7864       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7865         sw_if_index_set = 1;
7866       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7867         sw_if_index_set = 1;
7868       else
7869         break;
7870     }
7871
7872   if (sw_if_index_set == 0)
7873     {
7874       errmsg ("missing vpp interface name. ");
7875       return -99;
7876     }
7877
7878   /* Construct the API message */
7879   M (BOND_DETACH_SLAVE, mp);
7880
7881   mp->sw_if_index = ntohl (sw_if_index);
7882
7883   /* send it... */
7884   S (mp);
7885
7886   /* Wait for a reply... */
7887   W (ret);
7888   return ret;
7889 }
7890
7891 static int
7892 api_ip_table_add_del (vat_main_t * vam)
7893 {
7894   unformat_input_t *i = vam->input;
7895   vl_api_ip_table_add_del_t *mp;
7896   u32 table_id = ~0;
7897   u8 is_ipv6 = 0;
7898   u8 is_add = 1;
7899   int ret = 0;
7900
7901   /* Parse args required to build the message */
7902   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7903     {
7904       if (unformat (i, "ipv6"))
7905         is_ipv6 = 1;
7906       else if (unformat (i, "del"))
7907         is_add = 0;
7908       else if (unformat (i, "add"))
7909         is_add = 1;
7910       else if (unformat (i, "table %d", &table_id))
7911         ;
7912       else
7913         {
7914           clib_warning ("parse error '%U'", format_unformat_error, i);
7915           return -99;
7916         }
7917     }
7918
7919   if (~0 == table_id)
7920     {
7921       errmsg ("missing table-ID");
7922       return -99;
7923     }
7924
7925   /* Construct the API message */
7926   M (IP_TABLE_ADD_DEL, mp);
7927
7928   mp->table.table_id = ntohl (table_id);
7929   mp->table.is_ip6 = is_ipv6;
7930   mp->is_add = is_add;
7931
7932   /* send it... */
7933   S (mp);
7934
7935   /* Wait for a reply... */
7936   W (ret);
7937
7938   return ret;
7939 }
7940
7941 uword
7942 unformat_fib_path (unformat_input_t * input, va_list * args)
7943 {
7944   vat_main_t *vam = va_arg (*args, vat_main_t *);
7945   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
7946   u32 weight, preference;
7947   mpls_label_t out_label;
7948
7949   clib_memset (path, 0, sizeof (*path));
7950   path->weight = 1;
7951   path->sw_if_index = ~0;
7952   path->rpf_id = ~0;
7953   path->n_labels = 0;
7954
7955   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7956     {
7957       if (unformat (input, "%U %U",
7958                     unformat_vl_api_ip4_address,
7959                     &path->nh.address.ip4,
7960                     api_unformat_sw_if_index, vam, &path->sw_if_index))
7961         {
7962           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7963         }
7964       else if (unformat (input, "%U %U",
7965                          unformat_vl_api_ip6_address,
7966                          &path->nh.address.ip6,
7967                          api_unformat_sw_if_index, vam, &path->sw_if_index))
7968         {
7969           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7970         }
7971       else if (unformat (input, "weight %u", &weight))
7972         {
7973           path->weight = weight;
7974         }
7975       else if (unformat (input, "preference %u", &preference))
7976         {
7977           path->preference = preference;
7978         }
7979       else if (unformat (input, "%U next-hop-table %d",
7980                          unformat_vl_api_ip4_address,
7981                          &path->nh.address.ip4, &path->table_id))
7982         {
7983           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7984         }
7985       else if (unformat (input, "%U next-hop-table %d",
7986                          unformat_vl_api_ip6_address,
7987                          &path->nh.address.ip6, &path->table_id))
7988         {
7989           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7990         }
7991       else if (unformat (input, "%U",
7992                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
7993         {
7994           /*
7995            * the recursive next-hops are by default in the default table
7996            */
7997           path->table_id = 0;
7998           path->sw_if_index = ~0;
7999           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8000         }
8001       else if (unformat (input, "%U",
8002                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
8003         {
8004           /*
8005            * the recursive next-hops are by default in the default table
8006            */
8007           path->table_id = 0;
8008           path->sw_if_index = ~0;
8009           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8010         }
8011       else if (unformat (input, "resolve-via-host"))
8012         {
8013           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
8014         }
8015       else if (unformat (input, "resolve-via-attached"))
8016         {
8017           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
8018         }
8019       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
8020         {
8021           path->type = FIB_API_PATH_TYPE_LOCAL;
8022           path->sw_if_index = ~0;
8023           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8024         }
8025       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
8026         {
8027           path->type = FIB_API_PATH_TYPE_LOCAL;
8028           path->sw_if_index = ~0;
8029           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8030         }
8031       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
8032         ;
8033       else if (unformat (input, "via-label %d", &path->nh.via_label))
8034         {
8035           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
8036           path->sw_if_index = ~0;
8037         }
8038       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
8039         {
8040           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
8041           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
8042         }
8043       else if (unformat (input, "local"))
8044         {
8045           path->type = FIB_API_PATH_TYPE_LOCAL;
8046         }
8047       else if (unformat (input, "out-labels"))
8048         {
8049           while (unformat (input, "%d", &out_label))
8050             {
8051               path->label_stack[path->n_labels].label = out_label;
8052               path->label_stack[path->n_labels].is_uniform = 0;
8053               path->label_stack[path->n_labels].ttl = 64;
8054               path->n_labels++;
8055             }
8056         }
8057       else if (unformat (input, "via"))
8058         {
8059           /* new path, back up and return */
8060           unformat_put_input (input);
8061           unformat_put_input (input);
8062           unformat_put_input (input);
8063           unformat_put_input (input);
8064           break;
8065         }
8066       else
8067         {
8068           return (0);
8069         }
8070     }
8071
8072   path->proto = ntohl (path->proto);
8073   path->type = ntohl (path->type);
8074   path->flags = ntohl (path->flags);
8075   path->table_id = ntohl (path->table_id);
8076   path->sw_if_index = ntohl (path->sw_if_index);
8077
8078   return (1);
8079 }
8080
8081 static int
8082 api_ip_route_add_del (vat_main_t * vam)
8083 {
8084   unformat_input_t *i = vam->input;
8085   vl_api_ip_route_add_del_t *mp;
8086   u32 vrf_id = 0;
8087   u8 is_add = 1;
8088   u8 is_multipath = 0;
8089   u8 prefix_set = 0;
8090   u8 path_count = 0;
8091   vl_api_prefix_t pfx = { };
8092   vl_api_fib_path_t paths[8];
8093   int count = 1;
8094   int j;
8095   f64 before = 0;
8096   u32 random_add_del = 0;
8097   u32 *random_vector = 0;
8098   u32 random_seed = 0xdeaddabe;
8099
8100   /* Parse args required to build the message */
8101   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8102     {
8103       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8104         prefix_set = 1;
8105       else if (unformat (i, "del"))
8106         is_add = 0;
8107       else if (unformat (i, "add"))
8108         is_add = 1;
8109       else if (unformat (i, "vrf %d", &vrf_id))
8110         ;
8111       else if (unformat (i, "count %d", &count))
8112         ;
8113       else if (unformat (i, "random"))
8114         random_add_del = 1;
8115       else if (unformat (i, "multipath"))
8116         is_multipath = 1;
8117       else if (unformat (i, "seed %d", &random_seed))
8118         ;
8119       else
8120         if (unformat
8121             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8122         {
8123           path_count++;
8124           if (8 == path_count)
8125             {
8126               errmsg ("max 8 paths");
8127               return -99;
8128             }
8129         }
8130       else
8131         {
8132           clib_warning ("parse error '%U'", format_unformat_error, i);
8133           return -99;
8134         }
8135     }
8136
8137   if (!path_count)
8138     {
8139       errmsg ("specify a path; via ...");
8140       return -99;
8141     }
8142   if (prefix_set == 0)
8143     {
8144       errmsg ("missing prefix");
8145       return -99;
8146     }
8147
8148   /* Generate a pile of unique, random routes */
8149   if (random_add_del)
8150     {
8151       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
8152       u32 this_random_address;
8153       uword *random_hash;
8154
8155       random_hash = hash_create (count, sizeof (uword));
8156
8157       hash_set (random_hash, i->as_u32, 1);
8158       for (j = 0; j <= count; j++)
8159         {
8160           do
8161             {
8162               this_random_address = random_u32 (&random_seed);
8163               this_random_address =
8164                 clib_host_to_net_u32 (this_random_address);
8165             }
8166           while (hash_get (random_hash, this_random_address));
8167           vec_add1 (random_vector, this_random_address);
8168           hash_set (random_hash, this_random_address, 1);
8169         }
8170       hash_free (random_hash);
8171       set_ip4_address (&pfx.address, random_vector[0]);
8172     }
8173
8174   if (count > 1)
8175     {
8176       /* Turn on async mode */
8177       vam->async_mode = 1;
8178       vam->async_errors = 0;
8179       before = vat_time_now (vam);
8180     }
8181
8182   for (j = 0; j < count; j++)
8183     {
8184       /* Construct the API message */
8185       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8186
8187       mp->is_add = is_add;
8188       mp->is_multipath = is_multipath;
8189
8190       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8191       mp->route.table_id = ntohl (vrf_id);
8192       mp->route.n_paths = path_count;
8193
8194       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
8195
8196       if (random_add_del)
8197         set_ip4_address (&pfx.address, random_vector[j + 1]);
8198       else
8199         increment_address (&pfx.address);
8200       /* send it... */
8201       S (mp);
8202       /* If we receive SIGTERM, stop now... */
8203       if (vam->do_exit)
8204         break;
8205     }
8206
8207   /* When testing multiple add/del ops, use a control-ping to sync */
8208   if (count > 1)
8209     {
8210       vl_api_control_ping_t *mp_ping;
8211       f64 after;
8212       f64 timeout;
8213
8214       /* Shut off async mode */
8215       vam->async_mode = 0;
8216
8217       MPING (CONTROL_PING, mp_ping);
8218       S (mp_ping);
8219
8220       timeout = vat_time_now (vam) + 1.0;
8221       while (vat_time_now (vam) < timeout)
8222         if (vam->result_ready == 1)
8223           goto out;
8224       vam->retval = -99;
8225
8226     out:
8227       if (vam->retval == -99)
8228         errmsg ("timeout");
8229
8230       if (vam->async_errors > 0)
8231         {
8232           errmsg ("%d asynchronous errors", vam->async_errors);
8233           vam->retval = -98;
8234         }
8235       vam->async_errors = 0;
8236       after = vat_time_now (vam);
8237
8238       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8239       if (j > 0)
8240         count = j;
8241
8242       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8243              count, after - before, count / (after - before));
8244     }
8245   else
8246     {
8247       int ret;
8248
8249       /* Wait for a reply... */
8250       W (ret);
8251       return ret;
8252     }
8253
8254   /* Return the good/bad news */
8255   return (vam->retval);
8256 }
8257
8258 static int
8259 api_ip_mroute_add_del (vat_main_t * vam)
8260 {
8261   unformat_input_t *i = vam->input;
8262   u8 path_set = 0, prefix_set = 0, is_add = 1;
8263   vl_api_ip_mroute_add_del_t *mp;
8264   mfib_entry_flags_t eflags = 0;
8265   vl_api_mfib_path_t path;
8266   vl_api_mprefix_t pfx = { };
8267   u32 vrf_id = 0;
8268   int ret;
8269
8270   /* Parse args required to build the message */
8271   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8272     {
8273       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
8274         {
8275           prefix_set = 1;
8276           pfx.grp_address_length = htons (pfx.grp_address_length);
8277         }
8278       else if (unformat (i, "del"))
8279         is_add = 0;
8280       else if (unformat (i, "add"))
8281         is_add = 1;
8282       else if (unformat (i, "vrf %d", &vrf_id))
8283         ;
8284       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
8285         path.itf_flags = htonl (path.itf_flags);
8286       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8287         ;
8288       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
8289         path_set = 1;
8290       else
8291         {
8292           clib_warning ("parse error '%U'", format_unformat_error, i);
8293           return -99;
8294         }
8295     }
8296
8297   if (prefix_set == 0)
8298     {
8299       errmsg ("missing addresses\n");
8300       return -99;
8301     }
8302   if (path_set == 0)
8303     {
8304       errmsg ("missing path\n");
8305       return -99;
8306     }
8307
8308   /* Construct the API message */
8309   M (IP_MROUTE_ADD_DEL, mp);
8310
8311   mp->is_add = is_add;
8312   mp->is_multipath = 1;
8313
8314   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8315   mp->route.table_id = htonl (vrf_id);
8316   mp->route.n_paths = 1;
8317   mp->route.entry_flags = htonl (eflags);
8318
8319   clib_memcpy (&mp->route.paths, &path, sizeof (path));
8320
8321   /* send it... */
8322   S (mp);
8323   /* Wait for a reply... */
8324   W (ret);
8325   return ret;
8326 }
8327
8328 static int
8329 api_mpls_table_add_del (vat_main_t * vam)
8330 {
8331   unformat_input_t *i = vam->input;
8332   vl_api_mpls_table_add_del_t *mp;
8333   u32 table_id = ~0;
8334   u8 is_add = 1;
8335   int ret = 0;
8336
8337   /* Parse args required to build the message */
8338   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8339     {
8340       if (unformat (i, "table %d", &table_id))
8341         ;
8342       else if (unformat (i, "del"))
8343         is_add = 0;
8344       else if (unformat (i, "add"))
8345         is_add = 1;
8346       else
8347         {
8348           clib_warning ("parse error '%U'", format_unformat_error, i);
8349           return -99;
8350         }
8351     }
8352
8353   if (~0 == table_id)
8354     {
8355       errmsg ("missing table-ID");
8356       return -99;
8357     }
8358
8359   /* Construct the API message */
8360   M (MPLS_TABLE_ADD_DEL, mp);
8361
8362   mp->mt_table.mt_table_id = ntohl (table_id);
8363   mp->mt_is_add = is_add;
8364
8365   /* send it... */
8366   S (mp);
8367
8368   /* Wait for a reply... */
8369   W (ret);
8370
8371   return ret;
8372 }
8373
8374 static int
8375 api_mpls_route_add_del (vat_main_t * vam)
8376 {
8377   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
8378   mpls_label_t local_label = MPLS_LABEL_INVALID;
8379   unformat_input_t *i = vam->input;
8380   vl_api_mpls_route_add_del_t *mp;
8381   vl_api_fib_path_t paths[8];
8382   int count = 1, j;
8383   f64 before = 0;
8384
8385   /* Parse args required to build the message */
8386   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8387     {
8388       if (unformat (i, "%d", &local_label))
8389         ;
8390       else if (unformat (i, "eos"))
8391         is_eos = 1;
8392       else if (unformat (i, "non-eos"))
8393         is_eos = 0;
8394       else if (unformat (i, "del"))
8395         is_add = 0;
8396       else if (unformat (i, "add"))
8397         is_add = 1;
8398       else if (unformat (i, "multipath"))
8399         is_multipath = 1;
8400       else if (unformat (i, "count %d", &count))
8401         ;
8402       else
8403         if (unformat
8404             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8405         {
8406           path_count++;
8407           if (8 == path_count)
8408             {
8409               errmsg ("max 8 paths");
8410               return -99;
8411             }
8412         }
8413       else
8414         {
8415           clib_warning ("parse error '%U'", format_unformat_error, i);
8416           return -99;
8417         }
8418     }
8419
8420   if (!path_count)
8421     {
8422       errmsg ("specify a path; via ...");
8423       return -99;
8424     }
8425
8426   if (MPLS_LABEL_INVALID == local_label)
8427     {
8428       errmsg ("missing label");
8429       return -99;
8430     }
8431
8432   if (count > 1)
8433     {
8434       /* Turn on async mode */
8435       vam->async_mode = 1;
8436       vam->async_errors = 0;
8437       before = vat_time_now (vam);
8438     }
8439
8440   for (j = 0; j < count; j++)
8441     {
8442       /* Construct the API message */
8443       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8444
8445       mp->mr_is_add = is_add;
8446       mp->mr_is_multipath = is_multipath;
8447
8448       mp->mr_route.mr_label = local_label;
8449       mp->mr_route.mr_eos = is_eos;
8450       mp->mr_route.mr_table_id = 0;
8451       mp->mr_route.mr_n_paths = path_count;
8452
8453       clib_memcpy (&mp->mr_route.mr_paths, paths,
8454                    sizeof (paths[0]) * path_count);
8455
8456       local_label++;
8457
8458       /* send it... */
8459       S (mp);
8460       /* If we receive SIGTERM, stop now... */
8461       if (vam->do_exit)
8462         break;
8463     }
8464
8465   /* When testing multiple add/del ops, use a control-ping to sync */
8466   if (count > 1)
8467     {
8468       vl_api_control_ping_t *mp_ping;
8469       f64 after;
8470       f64 timeout;
8471
8472       /* Shut off async mode */
8473       vam->async_mode = 0;
8474
8475       MPING (CONTROL_PING, mp_ping);
8476       S (mp_ping);
8477
8478       timeout = vat_time_now (vam) + 1.0;
8479       while (vat_time_now (vam) < timeout)
8480         if (vam->result_ready == 1)
8481           goto out;
8482       vam->retval = -99;
8483
8484     out:
8485       if (vam->retval == -99)
8486         errmsg ("timeout");
8487
8488       if (vam->async_errors > 0)
8489         {
8490           errmsg ("%d asynchronous errors", vam->async_errors);
8491           vam->retval = -98;
8492         }
8493       vam->async_errors = 0;
8494       after = vat_time_now (vam);
8495
8496       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8497       if (j > 0)
8498         count = j;
8499
8500       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8501              count, after - before, count / (after - before));
8502     }
8503   else
8504     {
8505       int ret;
8506
8507       /* Wait for a reply... */
8508       W (ret);
8509       return ret;
8510     }
8511
8512   /* Return the good/bad news */
8513   return (vam->retval);
8514   return (0);
8515 }
8516
8517 static int
8518 api_mpls_ip_bind_unbind (vat_main_t * vam)
8519 {
8520   unformat_input_t *i = vam->input;
8521   vl_api_mpls_ip_bind_unbind_t *mp;
8522   u32 ip_table_id = 0;
8523   u8 is_bind = 1;
8524   vl_api_prefix_t pfx;
8525   u8 prefix_set = 0;
8526   mpls_label_t local_label = MPLS_LABEL_INVALID;
8527   int ret;
8528
8529   /* Parse args required to build the message */
8530   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8531     {
8532       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8533         prefix_set = 1;
8534       else if (unformat (i, "%d", &local_label))
8535         ;
8536       else if (unformat (i, "table-id %d", &ip_table_id))
8537         ;
8538       else if (unformat (i, "unbind"))
8539         is_bind = 0;
8540       else if (unformat (i, "bind"))
8541         is_bind = 1;
8542       else
8543         {
8544           clib_warning ("parse error '%U'", format_unformat_error, i);
8545           return -99;
8546         }
8547     }
8548
8549   if (!prefix_set)
8550     {
8551       errmsg ("IP prefix not set");
8552       return -99;
8553     }
8554
8555   if (MPLS_LABEL_INVALID == local_label)
8556     {
8557       errmsg ("missing label");
8558       return -99;
8559     }
8560
8561   /* Construct the API message */
8562   M (MPLS_IP_BIND_UNBIND, mp);
8563
8564   mp->mb_is_bind = is_bind;
8565   mp->mb_ip_table_id = ntohl (ip_table_id);
8566   mp->mb_mpls_table_id = 0;
8567   mp->mb_label = ntohl (local_label);
8568   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
8569
8570   /* send it... */
8571   S (mp);
8572
8573   /* Wait for a reply... */
8574   W (ret);
8575   return ret;
8576   return (0);
8577 }
8578
8579 static int
8580 api_sr_mpls_policy_add (vat_main_t * vam)
8581 {
8582   unformat_input_t *i = vam->input;
8583   vl_api_sr_mpls_policy_add_t *mp;
8584   u32 bsid = 0;
8585   u32 weight = 1;
8586   u8 type = 0;
8587   u8 n_segments = 0;
8588   u32 sid;
8589   u32 *segments = NULL;
8590   int ret;
8591
8592   /* Parse args required to build the message */
8593   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8594     {
8595       if (unformat (i, "bsid %d", &bsid))
8596         ;
8597       else if (unformat (i, "weight %d", &weight))
8598         ;
8599       else if (unformat (i, "spray"))
8600         type = 1;
8601       else if (unformat (i, "next %d", &sid))
8602         {
8603           n_segments += 1;
8604           vec_add1 (segments, htonl (sid));
8605         }
8606       else
8607         {
8608           clib_warning ("parse error '%U'", format_unformat_error, i);
8609           return -99;
8610         }
8611     }
8612
8613   if (bsid == 0)
8614     {
8615       errmsg ("bsid not set");
8616       return -99;
8617     }
8618
8619   if (n_segments == 0)
8620     {
8621       errmsg ("no sid in segment stack");
8622       return -99;
8623     }
8624
8625   /* Construct the API message */
8626   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8627
8628   mp->bsid = htonl (bsid);
8629   mp->weight = htonl (weight);
8630   mp->type = type;
8631   mp->n_segments = n_segments;
8632   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8633   vec_free (segments);
8634
8635   /* send it... */
8636   S (mp);
8637
8638   /* Wait for a reply... */
8639   W (ret);
8640   return ret;
8641 }
8642
8643 static int
8644 api_sr_mpls_policy_del (vat_main_t * vam)
8645 {
8646   unformat_input_t *i = vam->input;
8647   vl_api_sr_mpls_policy_del_t *mp;
8648   u32 bsid = 0;
8649   int ret;
8650
8651   /* Parse args required to build the message */
8652   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8653     {
8654       if (unformat (i, "bsid %d", &bsid))
8655         ;
8656       else
8657         {
8658           clib_warning ("parse error '%U'", format_unformat_error, i);
8659           return -99;
8660         }
8661     }
8662
8663   if (bsid == 0)
8664     {
8665       errmsg ("bsid not set");
8666       return -99;
8667     }
8668
8669   /* Construct the API message */
8670   M (SR_MPLS_POLICY_DEL, mp);
8671
8672   mp->bsid = htonl (bsid);
8673
8674   /* send it... */
8675   S (mp);
8676
8677   /* Wait for a reply... */
8678   W (ret);
8679   return ret;
8680 }
8681
8682 static int
8683 api_bier_table_add_del (vat_main_t * vam)
8684 {
8685   unformat_input_t *i = vam->input;
8686   vl_api_bier_table_add_del_t *mp;
8687   u8 is_add = 1;
8688   u32 set = 0, sub_domain = 0, hdr_len = 3;
8689   mpls_label_t local_label = MPLS_LABEL_INVALID;
8690   int ret;
8691
8692   /* Parse args required to build the message */
8693   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8694     {
8695       if (unformat (i, "sub-domain %d", &sub_domain))
8696         ;
8697       else if (unformat (i, "set %d", &set))
8698         ;
8699       else if (unformat (i, "label %d", &local_label))
8700         ;
8701       else if (unformat (i, "hdr-len %d", &hdr_len))
8702         ;
8703       else if (unformat (i, "add"))
8704         is_add = 1;
8705       else if (unformat (i, "del"))
8706         is_add = 0;
8707       else
8708         {
8709           clib_warning ("parse error '%U'", format_unformat_error, i);
8710           return -99;
8711         }
8712     }
8713
8714   if (MPLS_LABEL_INVALID == local_label)
8715     {
8716       errmsg ("missing label\n");
8717       return -99;
8718     }
8719
8720   /* Construct the API message */
8721   M (BIER_TABLE_ADD_DEL, mp);
8722
8723   mp->bt_is_add = is_add;
8724   mp->bt_label = ntohl (local_label);
8725   mp->bt_tbl_id.bt_set = set;
8726   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8727   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8728
8729   /* send it... */
8730   S (mp);
8731
8732   /* Wait for a reply... */
8733   W (ret);
8734
8735   return (ret);
8736 }
8737
8738 static int
8739 api_bier_route_add_del (vat_main_t * vam)
8740 {
8741   unformat_input_t *i = vam->input;
8742   vl_api_bier_route_add_del_t *mp;
8743   u8 is_add = 1;
8744   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8745   ip4_address_t v4_next_hop_address;
8746   ip6_address_t v6_next_hop_address;
8747   u8 next_hop_set = 0;
8748   u8 next_hop_proto_is_ip4 = 1;
8749   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8750   int ret;
8751
8752   /* Parse args required to build the message */
8753   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8754     {
8755       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8756         {
8757           next_hop_proto_is_ip4 = 1;
8758           next_hop_set = 1;
8759         }
8760       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8761         {
8762           next_hop_proto_is_ip4 = 0;
8763           next_hop_set = 1;
8764         }
8765       if (unformat (i, "sub-domain %d", &sub_domain))
8766         ;
8767       else if (unformat (i, "set %d", &set))
8768         ;
8769       else if (unformat (i, "hdr-len %d", &hdr_len))
8770         ;
8771       else if (unformat (i, "bp %d", &bp))
8772         ;
8773       else if (unformat (i, "add"))
8774         is_add = 1;
8775       else if (unformat (i, "del"))
8776         is_add = 0;
8777       else if (unformat (i, "out-label %d", &next_hop_out_label))
8778         ;
8779       else
8780         {
8781           clib_warning ("parse error '%U'", format_unformat_error, i);
8782           return -99;
8783         }
8784     }
8785
8786   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8787     {
8788       errmsg ("next hop / label set\n");
8789       return -99;
8790     }
8791   if (0 == bp)
8792     {
8793       errmsg ("bit=position not set\n");
8794       return -99;
8795     }
8796
8797   /* Construct the API message */
8798   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
8799
8800   mp->br_is_add = is_add;
8801   mp->br_route.br_tbl_id.bt_set = set;
8802   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
8803   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
8804   mp->br_route.br_bp = ntohs (bp);
8805   mp->br_route.br_n_paths = 1;
8806   mp->br_route.br_paths[0].n_labels = 1;
8807   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
8808   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
8809                                     FIB_API_PATH_NH_PROTO_IP4 :
8810                                     FIB_API_PATH_NH_PROTO_IP6);
8811
8812   if (next_hop_proto_is_ip4)
8813     {
8814       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
8815                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8816     }
8817   else
8818     {
8819       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
8820                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8821     }
8822
8823   /* send it... */
8824   S (mp);
8825
8826   /* Wait for a reply... */
8827   W (ret);
8828
8829   return (ret);
8830 }
8831
8832 static int
8833 api_proxy_arp_add_del (vat_main_t * vam)
8834 {
8835   unformat_input_t *i = vam->input;
8836   vl_api_proxy_arp_add_del_t *mp;
8837   u32 vrf_id = 0;
8838   u8 is_add = 1;
8839   vl_api_ip4_address_t lo, hi;
8840   u8 range_set = 0;
8841   int ret;
8842
8843   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8844     {
8845       if (unformat (i, "vrf %d", &vrf_id))
8846         ;
8847       else if (unformat (i, "%U - %U", unformat_vl_api_ip4_address, &lo,
8848                          unformat_vl_api_ip4_address, &hi))
8849         range_set = 1;
8850       else if (unformat (i, "del"))
8851         is_add = 0;
8852       else
8853         {
8854           clib_warning ("parse error '%U'", format_unformat_error, i);
8855           return -99;
8856         }
8857     }
8858
8859   if (range_set == 0)
8860     {
8861       errmsg ("address range not set");
8862       return -99;
8863     }
8864
8865   M (PROXY_ARP_ADD_DEL, mp);
8866
8867   mp->proxy.table_id = ntohl (vrf_id);
8868   mp->is_add = is_add;
8869   clib_memcpy (mp->proxy.low, &lo, sizeof (lo));
8870   clib_memcpy (mp->proxy.hi, &hi, sizeof (hi));
8871
8872   S (mp);
8873   W (ret);
8874   return ret;
8875 }
8876
8877 static int
8878 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8879 {
8880   unformat_input_t *i = vam->input;
8881   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8882   u32 sw_if_index;
8883   u8 enable = 1;
8884   u8 sw_if_index_set = 0;
8885   int ret;
8886
8887   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8888     {
8889       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8890         sw_if_index_set = 1;
8891       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8892         sw_if_index_set = 1;
8893       else if (unformat (i, "enable"))
8894         enable = 1;
8895       else if (unformat (i, "disable"))
8896         enable = 0;
8897       else
8898         {
8899           clib_warning ("parse error '%U'", format_unformat_error, i);
8900           return -99;
8901         }
8902     }
8903
8904   if (sw_if_index_set == 0)
8905     {
8906       errmsg ("missing interface name or sw_if_index");
8907       return -99;
8908     }
8909
8910   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8911
8912   mp->sw_if_index = ntohl (sw_if_index);
8913   mp->enable_disable = enable;
8914
8915   S (mp);
8916   W (ret);
8917   return ret;
8918 }
8919
8920 static int
8921 api_mpls_tunnel_add_del (vat_main_t * vam)
8922 {
8923   unformat_input_t *i = vam->input;
8924   vl_api_mpls_tunnel_add_del_t *mp;
8925
8926   vl_api_fib_path_t paths[8];
8927   u32 sw_if_index = ~0;
8928   u8 path_count = 0;
8929   u8 l2_only = 0;
8930   u8 is_add = 1;
8931   int ret;
8932
8933   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8934     {
8935       if (unformat (i, "add"))
8936         is_add = 1;
8937       else
8938         if (unformat
8939             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
8940         is_add = 0;
8941       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8942         is_add = 0;
8943       else if (unformat (i, "l2-only"))
8944         l2_only = 1;
8945       else
8946         if (unformat
8947             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8948         {
8949           path_count++;
8950           if (8 == path_count)
8951             {
8952               errmsg ("max 8 paths");
8953               return -99;
8954             }
8955         }
8956       else
8957         {
8958           clib_warning ("parse error '%U'", format_unformat_error, i);
8959           return -99;
8960         }
8961     }
8962
8963   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8964
8965   mp->mt_is_add = is_add;
8966   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
8967   mp->mt_tunnel.mt_l2_only = l2_only;
8968   mp->mt_tunnel.mt_is_multicast = 0;
8969   mp->mt_tunnel.mt_n_paths = path_count;
8970
8971   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
8972                sizeof (paths[0]) * path_count);
8973
8974   S (mp);
8975   W (ret);
8976   return ret;
8977 }
8978
8979 static int
8980 api_sw_interface_set_unnumbered (vat_main_t * vam)
8981 {
8982   unformat_input_t *i = vam->input;
8983   vl_api_sw_interface_set_unnumbered_t *mp;
8984   u32 sw_if_index;
8985   u32 unnum_sw_index = ~0;
8986   u8 is_add = 1;
8987   u8 sw_if_index_set = 0;
8988   int ret;
8989
8990   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8991     {
8992       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8993         sw_if_index_set = 1;
8994       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8995         sw_if_index_set = 1;
8996       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8997         ;
8998       else if (unformat (i, "del"))
8999         is_add = 0;
9000       else
9001         {
9002           clib_warning ("parse error '%U'", format_unformat_error, i);
9003           return -99;
9004         }
9005     }
9006
9007   if (sw_if_index_set == 0)
9008     {
9009       errmsg ("missing interface name or sw_if_index");
9010       return -99;
9011     }
9012
9013   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9014
9015   mp->sw_if_index = ntohl (sw_if_index);
9016   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9017   mp->is_add = is_add;
9018
9019   S (mp);
9020   W (ret);
9021   return ret;
9022 }
9023
9024 static int
9025 api_ip_neighbor_add_del (vat_main_t * vam)
9026 {
9027   vl_api_mac_address_t mac_address;
9028   unformat_input_t *i = vam->input;
9029   vl_api_ip_neighbor_add_del_t *mp;
9030   vl_api_address_t ip_address;
9031   u32 sw_if_index;
9032   u8 sw_if_index_set = 0;
9033   u8 is_add = 1;
9034   u8 mac_set = 0;
9035   u8 address_set = 0;
9036   int ret;
9037   ip_neighbor_flags_t flags;
9038
9039   flags = IP_NEIGHBOR_FLAG_NONE;
9040   clib_memset (&ip_address, 0, sizeof (ip_address));
9041   clib_memset (&mac_address, 0, sizeof (mac_address));
9042
9043   /* Parse args required to build the message */
9044   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9045     {
9046       if (unformat (i, "mac %U", unformat_vl_api_mac_address, &mac_address))
9047         {
9048           mac_set = 1;
9049         }
9050       else if (unformat (i, "del"))
9051         is_add = 0;
9052       else
9053         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9054         sw_if_index_set = 1;
9055       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9056         sw_if_index_set = 1;
9057       else if (unformat (i, "static"))
9058         flags |= IP_NEIGHBOR_FLAG_STATIC;
9059       else if (unformat (i, "no-fib-entry"))
9060         flags |= IP_NEIGHBOR_FLAG_NO_FIB_ENTRY;
9061       else if (unformat (i, "dst %U", unformat_vl_api_address, &ip_address))
9062         address_set = 1;
9063       else
9064         {
9065           clib_warning ("parse error '%U'", format_unformat_error, i);
9066           return -99;
9067         }
9068     }
9069
9070   if (sw_if_index_set == 0)
9071     {
9072       errmsg ("missing interface name or sw_if_index");
9073       return -99;
9074     }
9075   if (!address_set)
9076     {
9077       errmsg ("no address set");
9078       return -99;
9079     }
9080
9081   /* Construct the API message */
9082   M (IP_NEIGHBOR_ADD_DEL, mp);
9083
9084   mp->neighbor.sw_if_index = ntohl (sw_if_index);
9085   mp->is_add = is_add;
9086   mp->neighbor.flags = htonl (flags);
9087   if (mac_set)
9088     clib_memcpy (&mp->neighbor.mac_address, &mac_address,
9089                  sizeof (mac_address));
9090   if (address_set)
9091     clib_memcpy (&mp->neighbor.ip_address, &ip_address, sizeof (ip_address));
9092
9093   /* send it... */
9094   S (mp);
9095
9096   /* Wait for a reply, return good/bad news  */
9097   W (ret);
9098   return ret;
9099 }
9100
9101 static int
9102 api_create_vlan_subif (vat_main_t * vam)
9103 {
9104   unformat_input_t *i = vam->input;
9105   vl_api_create_vlan_subif_t *mp;
9106   u32 sw_if_index;
9107   u8 sw_if_index_set = 0;
9108   u32 vlan_id;
9109   u8 vlan_id_set = 0;
9110   int ret;
9111
9112   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9113     {
9114       if (unformat (i, "sw_if_index %d", &sw_if_index))
9115         sw_if_index_set = 1;
9116       else
9117         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9118         sw_if_index_set = 1;
9119       else if (unformat (i, "vlan %d", &vlan_id))
9120         vlan_id_set = 1;
9121       else
9122         {
9123           clib_warning ("parse error '%U'", format_unformat_error, i);
9124           return -99;
9125         }
9126     }
9127
9128   if (sw_if_index_set == 0)
9129     {
9130       errmsg ("missing interface name or sw_if_index");
9131       return -99;
9132     }
9133
9134   if (vlan_id_set == 0)
9135     {
9136       errmsg ("missing vlan_id");
9137       return -99;
9138     }
9139   M (CREATE_VLAN_SUBIF, mp);
9140
9141   mp->sw_if_index = ntohl (sw_if_index);
9142   mp->vlan_id = ntohl (vlan_id);
9143
9144   S (mp);
9145   W (ret);
9146   return ret;
9147 }
9148
9149 #define foreach_create_subif_bit                \
9150 _(no_tags)                                      \
9151 _(one_tag)                                      \
9152 _(two_tags)                                     \
9153 _(dot1ad)                                       \
9154 _(exact_match)                                  \
9155 _(default_sub)                                  \
9156 _(outer_vlan_id_any)                            \
9157 _(inner_vlan_id_any)
9158
9159 #define foreach_create_subif_flag               \
9160 _(0, "no_tags")                                 \
9161 _(1, "one_tag")                                 \
9162 _(2, "two_tags")                                \
9163 _(3, "dot1ad")                                  \
9164 _(4, "exact_match")                             \
9165 _(5, "default_sub")                             \
9166 _(6, "outer_vlan_id_any")                       \
9167 _(7, "inner_vlan_id_any")
9168
9169 static int
9170 api_create_subif (vat_main_t * vam)
9171 {
9172   unformat_input_t *i = vam->input;
9173   vl_api_create_subif_t *mp;
9174   u32 sw_if_index;
9175   u8 sw_if_index_set = 0;
9176   u32 sub_id;
9177   u8 sub_id_set = 0;
9178   u32 __attribute__ ((unused)) no_tags = 0;
9179   u32 __attribute__ ((unused)) one_tag = 0;
9180   u32 __attribute__ ((unused)) two_tags = 0;
9181   u32 __attribute__ ((unused)) dot1ad = 0;
9182   u32 __attribute__ ((unused)) exact_match = 0;
9183   u32 __attribute__ ((unused)) default_sub = 0;
9184   u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
9185   u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
9186   u32 tmp;
9187   u16 outer_vlan_id = 0;
9188   u16 inner_vlan_id = 0;
9189   int ret;
9190
9191   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9192     {
9193       if (unformat (i, "sw_if_index %d", &sw_if_index))
9194         sw_if_index_set = 1;
9195       else
9196         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9197         sw_if_index_set = 1;
9198       else if (unformat (i, "sub_id %d", &sub_id))
9199         sub_id_set = 1;
9200       else if (unformat (i, "outer_vlan_id %d", &tmp))
9201         outer_vlan_id = tmp;
9202       else if (unformat (i, "inner_vlan_id %d", &tmp))
9203         inner_vlan_id = tmp;
9204
9205 #define _(a) else if (unformat (i, #a)) a = 1 ;
9206       foreach_create_subif_bit
9207 #undef _
9208         else
9209         {
9210           clib_warning ("parse error '%U'", format_unformat_error, i);
9211           return -99;
9212         }
9213     }
9214
9215   if (sw_if_index_set == 0)
9216     {
9217       errmsg ("missing interface name or sw_if_index");
9218       return -99;
9219     }
9220
9221   if (sub_id_set == 0)
9222     {
9223       errmsg ("missing sub_id");
9224       return -99;
9225     }
9226   M (CREATE_SUBIF, mp);
9227
9228   mp->sw_if_index = ntohl (sw_if_index);
9229   mp->sub_id = ntohl (sub_id);
9230
9231 #define _(a,b) mp->sub_if_flags |= (1 << a);
9232   foreach_create_subif_flag;
9233 #undef _
9234
9235   mp->outer_vlan_id = ntohs (outer_vlan_id);
9236   mp->inner_vlan_id = ntohs (inner_vlan_id);
9237
9238   S (mp);
9239   W (ret);
9240   return ret;
9241 }
9242
9243 static int
9244 api_reset_fib (vat_main_t * vam)
9245 {
9246   unformat_input_t *i = vam->input;
9247   vl_api_reset_fib_t *mp;
9248   u32 vrf_id = 0;
9249   u8 is_ipv6 = 0;
9250   u8 vrf_id_set = 0;
9251
9252   int ret;
9253   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9254     {
9255       if (unformat (i, "vrf %d", &vrf_id))
9256         vrf_id_set = 1;
9257       else if (unformat (i, "ipv6"))
9258         is_ipv6 = 1;
9259       else
9260         {
9261           clib_warning ("parse error '%U'", format_unformat_error, i);
9262           return -99;
9263         }
9264     }
9265
9266   if (vrf_id_set == 0)
9267     {
9268       errmsg ("missing vrf id");
9269       return -99;
9270     }
9271
9272   M (RESET_FIB, mp);
9273
9274   mp->vrf_id = ntohl (vrf_id);
9275   mp->is_ipv6 = is_ipv6;
9276
9277   S (mp);
9278   W (ret);
9279   return ret;
9280 }
9281
9282 static int
9283 api_dhcp_proxy_config (vat_main_t * vam)
9284 {
9285   unformat_input_t *i = vam->input;
9286   vl_api_dhcp_proxy_config_t *mp;
9287   u32 rx_vrf_id = 0;
9288   u32 server_vrf_id = 0;
9289   u8 is_add = 1;
9290   u8 v4_address_set = 0;
9291   u8 v6_address_set = 0;
9292   ip4_address_t v4address;
9293   ip6_address_t v6address;
9294   u8 v4_src_address_set = 0;
9295   u8 v6_src_address_set = 0;
9296   ip4_address_t v4srcaddress;
9297   ip6_address_t v6srcaddress;
9298   int ret;
9299
9300   /* Parse args required to build the message */
9301   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9302     {
9303       if (unformat (i, "del"))
9304         is_add = 0;
9305       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9306         ;
9307       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9308         ;
9309       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9310         v4_address_set = 1;
9311       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9312         v6_address_set = 1;
9313       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9314         v4_src_address_set = 1;
9315       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9316         v6_src_address_set = 1;
9317       else
9318         break;
9319     }
9320
9321   if (v4_address_set && v6_address_set)
9322     {
9323       errmsg ("both v4 and v6 server addresses set");
9324       return -99;
9325     }
9326   if (!v4_address_set && !v6_address_set)
9327     {
9328       errmsg ("no server addresses set");
9329       return -99;
9330     }
9331
9332   if (v4_src_address_set && v6_src_address_set)
9333     {
9334       errmsg ("both v4 and v6  src addresses set");
9335       return -99;
9336     }
9337   if (!v4_src_address_set && !v6_src_address_set)
9338     {
9339       errmsg ("no src addresses set");
9340       return -99;
9341     }
9342
9343   if (!(v4_src_address_set && v4_address_set) &&
9344       !(v6_src_address_set && v6_address_set))
9345     {
9346       errmsg ("no matching server and src addresses set");
9347       return -99;
9348     }
9349
9350   /* Construct the API message */
9351   M (DHCP_PROXY_CONFIG, mp);
9352
9353   mp->is_add = is_add;
9354   mp->rx_vrf_id = ntohl (rx_vrf_id);
9355   mp->server_vrf_id = ntohl (server_vrf_id);
9356   if (v6_address_set)
9357     {
9358       mp->is_ipv6 = 1;
9359       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9360       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9361     }
9362   else
9363     {
9364       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9365       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, 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_bytes (node, "vss-type", &mp->vss_type,
9438                              sizeof (mp->vss_type));
9439   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9440                                    mp->vss_vpn_ascii_id);
9441   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9442   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9443
9444   if (mp->is_ipv6)
9445     {
9446       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9447       vat_json_object_add_ip6 (node, "src_address", ip6);
9448     }
9449   else
9450     {
9451       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9452       vat_json_object_add_ip4 (node, "src_address", ip4);
9453     }
9454
9455   for (i = 0; i < count; i++)
9456     {
9457       s = &mp->servers[i];
9458
9459       vat_json_object_add_uint (node, "server-table-id",
9460                                 ntohl (s->server_vrf_id));
9461
9462       if (mp->is_ipv6)
9463         {
9464           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9465           vat_json_object_add_ip4 (node, "src_address", ip4);
9466         }
9467       else
9468         {
9469           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9470           vat_json_object_add_ip6 (node, "server_address", ip6);
9471         }
9472     }
9473 }
9474
9475 static int
9476 api_dhcp_proxy_dump (vat_main_t * vam)
9477 {
9478   unformat_input_t *i = vam->input;
9479   vl_api_control_ping_t *mp_ping;
9480   vl_api_dhcp_proxy_dump_t *mp;
9481   u8 is_ipv6 = 0;
9482   int ret;
9483
9484   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9485     {
9486       if (unformat (i, "ipv6"))
9487         is_ipv6 = 1;
9488       else
9489         {
9490           clib_warning ("parse error '%U'", format_unformat_error, i);
9491           return -99;
9492         }
9493     }
9494
9495   M (DHCP_PROXY_DUMP, mp);
9496
9497   mp->is_ip6 = is_ipv6;
9498   S (mp);
9499
9500   /* Use a control ping for synchronization */
9501   MPING (CONTROL_PING, mp_ping);
9502   S (mp_ping);
9503
9504   W (ret);
9505   return ret;
9506 }
9507
9508 static int
9509 api_dhcp_proxy_set_vss (vat_main_t * vam)
9510 {
9511   unformat_input_t *i = vam->input;
9512   vl_api_dhcp_proxy_set_vss_t *mp;
9513   u8 is_ipv6 = 0;
9514   u8 is_add = 1;
9515   u32 tbl_id = ~0;
9516   u8 vss_type = VSS_TYPE_DEFAULT;
9517   u8 *vpn_ascii_id = 0;
9518   u32 oui = 0;
9519   u32 fib_id = 0;
9520   int ret;
9521
9522   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9523     {
9524       if (unformat (i, "tbl_id %d", &tbl_id))
9525         ;
9526       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
9527         vss_type = VSS_TYPE_ASCII;
9528       else if (unformat (i, "fib_id %d", &fib_id))
9529         vss_type = VSS_TYPE_VPN_ID;
9530       else if (unformat (i, "oui %d", &oui))
9531         vss_type = VSS_TYPE_VPN_ID;
9532       else if (unformat (i, "ipv6"))
9533         is_ipv6 = 1;
9534       else if (unformat (i, "del"))
9535         is_add = 0;
9536       else
9537         break;
9538     }
9539
9540   if (tbl_id == ~0)
9541     {
9542       errmsg ("missing tbl_id ");
9543       vec_free (vpn_ascii_id);
9544       return -99;
9545     }
9546
9547   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
9548     {
9549       errmsg ("vpn_ascii_id cannot be longer than 128 ");
9550       vec_free (vpn_ascii_id);
9551       return -99;
9552     }
9553
9554   M (DHCP_PROXY_SET_VSS, mp);
9555   mp->tbl_id = ntohl (tbl_id);
9556   mp->vss_type = vss_type;
9557   if (vpn_ascii_id)
9558     {
9559       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
9560       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
9561     }
9562   mp->vpn_index = ntohl (fib_id);
9563   mp->oui = ntohl (oui);
9564   mp->is_ipv6 = is_ipv6;
9565   mp->is_add = is_add;
9566
9567   S (mp);
9568   W (ret);
9569
9570   vec_free (vpn_ascii_id);
9571   return ret;
9572 }
9573
9574 static int
9575 api_dhcp_client_config (vat_main_t * vam)
9576 {
9577   unformat_input_t *i = vam->input;
9578   vl_api_dhcp_client_config_t *mp;
9579   u32 sw_if_index;
9580   u8 sw_if_index_set = 0;
9581   u8 is_add = 1;
9582   u8 *hostname = 0;
9583   u8 disable_event = 0;
9584   int ret;
9585
9586   /* Parse args required to build the message */
9587   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9588     {
9589       if (unformat (i, "del"))
9590         is_add = 0;
9591       else
9592         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9593         sw_if_index_set = 1;
9594       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9595         sw_if_index_set = 1;
9596       else if (unformat (i, "hostname %s", &hostname))
9597         ;
9598       else if (unformat (i, "disable_event"))
9599         disable_event = 1;
9600       else
9601         break;
9602     }
9603
9604   if (sw_if_index_set == 0)
9605     {
9606       errmsg ("missing interface name or sw_if_index");
9607       return -99;
9608     }
9609
9610   if (vec_len (hostname) > 63)
9611     {
9612       errmsg ("hostname too long");
9613     }
9614   vec_add1 (hostname, 0);
9615
9616   /* Construct the API message */
9617   M (DHCP_CLIENT_CONFIG, mp);
9618
9619   mp->is_add = is_add;
9620   mp->client.sw_if_index = htonl (sw_if_index);
9621   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
9622   vec_free (hostname);
9623   mp->client.want_dhcp_event = disable_event ? 0 : 1;
9624   mp->client.pid = htonl (getpid ());
9625
9626   /* send it... */
9627   S (mp);
9628
9629   /* Wait for a reply, return good/bad news  */
9630   W (ret);
9631   return ret;
9632 }
9633
9634 static int
9635 api_set_ip_flow_hash (vat_main_t * vam)
9636 {
9637   unformat_input_t *i = vam->input;
9638   vl_api_set_ip_flow_hash_t *mp;
9639   u32 vrf_id = 0;
9640   u8 is_ipv6 = 0;
9641   u8 vrf_id_set = 0;
9642   u8 src = 0;
9643   u8 dst = 0;
9644   u8 sport = 0;
9645   u8 dport = 0;
9646   u8 proto = 0;
9647   u8 reverse = 0;
9648   int ret;
9649
9650   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9651     {
9652       if (unformat (i, "vrf %d", &vrf_id))
9653         vrf_id_set = 1;
9654       else if (unformat (i, "ipv6"))
9655         is_ipv6 = 1;
9656       else if (unformat (i, "src"))
9657         src = 1;
9658       else if (unformat (i, "dst"))
9659         dst = 1;
9660       else if (unformat (i, "sport"))
9661         sport = 1;
9662       else if (unformat (i, "dport"))
9663         dport = 1;
9664       else if (unformat (i, "proto"))
9665         proto = 1;
9666       else if (unformat (i, "reverse"))
9667         reverse = 1;
9668
9669       else
9670         {
9671           clib_warning ("parse error '%U'", format_unformat_error, i);
9672           return -99;
9673         }
9674     }
9675
9676   if (vrf_id_set == 0)
9677     {
9678       errmsg ("missing vrf id");
9679       return -99;
9680     }
9681
9682   M (SET_IP_FLOW_HASH, mp);
9683   mp->src = src;
9684   mp->dst = dst;
9685   mp->sport = sport;
9686   mp->dport = dport;
9687   mp->proto = proto;
9688   mp->reverse = reverse;
9689   mp->vrf_id = ntohl (vrf_id);
9690   mp->is_ipv6 = is_ipv6;
9691
9692   S (mp);
9693   W (ret);
9694   return ret;
9695 }
9696
9697 static int
9698 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9699 {
9700   unformat_input_t *i = vam->input;
9701   vl_api_sw_interface_ip6_enable_disable_t *mp;
9702   u32 sw_if_index;
9703   u8 sw_if_index_set = 0;
9704   u8 enable = 0;
9705   int ret;
9706
9707   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9708     {
9709       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9710         sw_if_index_set = 1;
9711       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9712         sw_if_index_set = 1;
9713       else if (unformat (i, "enable"))
9714         enable = 1;
9715       else if (unformat (i, "disable"))
9716         enable = 0;
9717       else
9718         {
9719           clib_warning ("parse error '%U'", format_unformat_error, i);
9720           return -99;
9721         }
9722     }
9723
9724   if (sw_if_index_set == 0)
9725     {
9726       errmsg ("missing interface name or sw_if_index");
9727       return -99;
9728     }
9729
9730   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9731
9732   mp->sw_if_index = ntohl (sw_if_index);
9733   mp->enable = enable;
9734
9735   S (mp);
9736   W (ret);
9737   return ret;
9738 }
9739
9740 static int
9741 api_ip6nd_proxy_add_del (vat_main_t * vam)
9742 {
9743   unformat_input_t *i = vam->input;
9744   vl_api_ip6nd_proxy_add_del_t *mp;
9745   u32 sw_if_index = ~0;
9746   u8 v6_address_set = 0;
9747   vl_api_ip6_address_t v6address;
9748   u8 is_del = 0;
9749   int ret;
9750
9751   /* Parse args required to build the message */
9752   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9753     {
9754       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9755         ;
9756       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9757         ;
9758       else if (unformat (i, "%U", unformat_vl_api_ip6_address, &v6address))
9759         v6_address_set = 1;
9760       if (unformat (i, "del"))
9761         is_del = 1;
9762       else
9763         {
9764           clib_warning ("parse error '%U'", format_unformat_error, i);
9765           return -99;
9766         }
9767     }
9768
9769   if (sw_if_index == ~0)
9770     {
9771       errmsg ("missing interface name or sw_if_index");
9772       return -99;
9773     }
9774   if (!v6_address_set)
9775     {
9776       errmsg ("no address set");
9777       return -99;
9778     }
9779
9780   /* Construct the API message */
9781   M (IP6ND_PROXY_ADD_DEL, mp);
9782
9783   mp->is_del = is_del;
9784   mp->sw_if_index = ntohl (sw_if_index);
9785   clib_memcpy (mp->ip, v6address, sizeof (v6address));
9786
9787   /* send it... */
9788   S (mp);
9789
9790   /* Wait for a reply, return good/bad news  */
9791   W (ret);
9792   return ret;
9793 }
9794
9795 static int
9796 api_ip6nd_proxy_dump (vat_main_t * vam)
9797 {
9798   vl_api_ip6nd_proxy_dump_t *mp;
9799   vl_api_control_ping_t *mp_ping;
9800   int ret;
9801
9802   M (IP6ND_PROXY_DUMP, mp);
9803
9804   S (mp);
9805
9806   /* Use a control ping for synchronization */
9807   MPING (CONTROL_PING, mp_ping);
9808   S (mp_ping);
9809
9810   W (ret);
9811   return ret;
9812 }
9813
9814 static void vl_api_ip6nd_proxy_details_t_handler
9815   (vl_api_ip6nd_proxy_details_t * mp)
9816 {
9817   vat_main_t *vam = &vat_main;
9818
9819   print (vam->ofp, "host %U sw_if_index %d",
9820          format_vl_api_ip6_address, mp->ip, ntohl (mp->sw_if_index));
9821 }
9822
9823 static void vl_api_ip6nd_proxy_details_t_handler_json
9824   (vl_api_ip6nd_proxy_details_t * mp)
9825 {
9826   vat_main_t *vam = &vat_main;
9827   struct in6_addr ip6;
9828   vat_json_node_t *node = NULL;
9829
9830   if (VAT_JSON_ARRAY != vam->json_tree.type)
9831     {
9832       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9833       vat_json_init_array (&vam->json_tree);
9834     }
9835   node = vat_json_array_add (&vam->json_tree);
9836
9837   vat_json_init_object (node);
9838   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9839
9840   clib_memcpy (&ip6, mp->ip, sizeof (ip6));
9841   vat_json_object_add_ip6 (node, "host", ip6);
9842 }
9843
9844 static int
9845 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
9846 {
9847   unformat_input_t *i = vam->input;
9848   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
9849   u32 sw_if_index;
9850   u8 sw_if_index_set = 0;
9851   u8 v6_address_set = 0;
9852   vl_api_prefix_t pfx;
9853   u8 use_default = 0;
9854   u8 no_advertise = 0;
9855   u8 off_link = 0;
9856   u8 no_autoconfig = 0;
9857   u8 no_onlink = 0;
9858   u8 is_no = 0;
9859   u32 val_lifetime = 0;
9860   u32 pref_lifetime = 0;
9861   int ret;
9862
9863   /* Parse args required to build the message */
9864   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9865     {
9866       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9867         sw_if_index_set = 1;
9868       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9869         sw_if_index_set = 1;
9870       else if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
9871         v6_address_set = 1;
9872       else if (unformat (i, "val_life %d", &val_lifetime))
9873         ;
9874       else if (unformat (i, "pref_life %d", &pref_lifetime))
9875         ;
9876       else if (unformat (i, "def"))
9877         use_default = 1;
9878       else if (unformat (i, "noadv"))
9879         no_advertise = 1;
9880       else if (unformat (i, "offl"))
9881         off_link = 1;
9882       else if (unformat (i, "noauto"))
9883         no_autoconfig = 1;
9884       else if (unformat (i, "nolink"))
9885         no_onlink = 1;
9886       else if (unformat (i, "isno"))
9887         is_no = 1;
9888       else
9889         {
9890           clib_warning ("parse error '%U'", format_unformat_error, i);
9891           return -99;
9892         }
9893     }
9894
9895   if (sw_if_index_set == 0)
9896     {
9897       errmsg ("missing interface name or sw_if_index");
9898       return -99;
9899     }
9900   if (!v6_address_set)
9901     {
9902       errmsg ("no address set");
9903       return -99;
9904     }
9905
9906   /* Construct the API message */
9907   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9908
9909   mp->sw_if_index = ntohl (sw_if_index);
9910   clib_memcpy (&mp->prefix, &pfx, sizeof (pfx));
9911   mp->use_default = use_default;
9912   mp->no_advertise = no_advertise;
9913   mp->off_link = off_link;
9914   mp->no_autoconfig = no_autoconfig;
9915   mp->no_onlink = no_onlink;
9916   mp->is_no = is_no;
9917   mp->val_lifetime = ntohl (val_lifetime);
9918   mp->pref_lifetime = ntohl (pref_lifetime);
9919
9920   /* send it... */
9921   S (mp);
9922
9923   /* Wait for a reply, return good/bad news  */
9924   W (ret);
9925   return ret;
9926 }
9927
9928 static int
9929 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9930 {
9931   unformat_input_t *i = vam->input;
9932   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9933   u32 sw_if_index;
9934   u8 sw_if_index_set = 0;
9935   u8 suppress = 0;
9936   u8 managed = 0;
9937   u8 other = 0;
9938   u8 ll_option = 0;
9939   u8 send_unicast = 0;
9940   u8 cease = 0;
9941   u8 is_no = 0;
9942   u8 default_router = 0;
9943   u32 max_interval = 0;
9944   u32 min_interval = 0;
9945   u32 lifetime = 0;
9946   u32 initial_count = 0;
9947   u32 initial_interval = 0;
9948   int ret;
9949
9950
9951   /* Parse args required to build the message */
9952   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9953     {
9954       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9955         sw_if_index_set = 1;
9956       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9957         sw_if_index_set = 1;
9958       else if (unformat (i, "maxint %d", &max_interval))
9959         ;
9960       else if (unformat (i, "minint %d", &min_interval))
9961         ;
9962       else if (unformat (i, "life %d", &lifetime))
9963         ;
9964       else if (unformat (i, "count %d", &initial_count))
9965         ;
9966       else if (unformat (i, "interval %d", &initial_interval))
9967         ;
9968       else if (unformat (i, "suppress") || unformat (i, "surpress"))
9969         suppress = 1;
9970       else if (unformat (i, "managed"))
9971         managed = 1;
9972       else if (unformat (i, "other"))
9973         other = 1;
9974       else if (unformat (i, "ll"))
9975         ll_option = 1;
9976       else if (unformat (i, "send"))
9977         send_unicast = 1;
9978       else if (unformat (i, "cease"))
9979         cease = 1;
9980       else if (unformat (i, "isno"))
9981         is_no = 1;
9982       else if (unformat (i, "def"))
9983         default_router = 1;
9984       else
9985         {
9986           clib_warning ("parse error '%U'", format_unformat_error, i);
9987           return -99;
9988         }
9989     }
9990
9991   if (sw_if_index_set == 0)
9992     {
9993       errmsg ("missing interface name or sw_if_index");
9994       return -99;
9995     }
9996
9997   /* Construct the API message */
9998   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
9999
10000   mp->sw_if_index = ntohl (sw_if_index);
10001   mp->max_interval = ntohl (max_interval);
10002   mp->min_interval = ntohl (min_interval);
10003   mp->lifetime = ntohl (lifetime);
10004   mp->initial_count = ntohl (initial_count);
10005   mp->initial_interval = ntohl (initial_interval);
10006   mp->suppress = suppress;
10007   mp->managed = managed;
10008   mp->other = other;
10009   mp->ll_option = ll_option;
10010   mp->send_unicast = send_unicast;
10011   mp->cease = cease;
10012   mp->is_no = is_no;
10013   mp->default_router = default_router;
10014
10015   /* send it... */
10016   S (mp);
10017
10018   /* Wait for a reply, return good/bad news  */
10019   W (ret);
10020   return ret;
10021 }
10022
10023 static int
10024 api_set_arp_neighbor_limit (vat_main_t * vam)
10025 {
10026   unformat_input_t *i = vam->input;
10027   vl_api_set_arp_neighbor_limit_t *mp;
10028   u32 arp_nbr_limit;
10029   u8 limit_set = 0;
10030   u8 is_ipv6 = 0;
10031   int ret;
10032
10033   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10034     {
10035       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10036         limit_set = 1;
10037       else if (unformat (i, "ipv6"))
10038         is_ipv6 = 1;
10039       else
10040         {
10041           clib_warning ("parse error '%U'", format_unformat_error, i);
10042           return -99;
10043         }
10044     }
10045
10046   if (limit_set == 0)
10047     {
10048       errmsg ("missing limit value");
10049       return -99;
10050     }
10051
10052   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10053
10054   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10055   mp->is_ipv6 = is_ipv6;
10056
10057   S (mp);
10058   W (ret);
10059   return ret;
10060 }
10061
10062 static int
10063 api_l2_patch_add_del (vat_main_t * vam)
10064 {
10065   unformat_input_t *i = vam->input;
10066   vl_api_l2_patch_add_del_t *mp;
10067   u32 rx_sw_if_index;
10068   u8 rx_sw_if_index_set = 0;
10069   u32 tx_sw_if_index;
10070   u8 tx_sw_if_index_set = 0;
10071   u8 is_add = 1;
10072   int ret;
10073
10074   /* Parse args required to build the message */
10075   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10076     {
10077       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10078         rx_sw_if_index_set = 1;
10079       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10080         tx_sw_if_index_set = 1;
10081       else if (unformat (i, "rx"))
10082         {
10083           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10084             {
10085               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10086                             &rx_sw_if_index))
10087                 rx_sw_if_index_set = 1;
10088             }
10089           else
10090             break;
10091         }
10092       else if (unformat (i, "tx"))
10093         {
10094           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10095             {
10096               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10097                             &tx_sw_if_index))
10098                 tx_sw_if_index_set = 1;
10099             }
10100           else
10101             break;
10102         }
10103       else if (unformat (i, "del"))
10104         is_add = 0;
10105       else
10106         break;
10107     }
10108
10109   if (rx_sw_if_index_set == 0)
10110     {
10111       errmsg ("missing rx interface name or rx_sw_if_index");
10112       return -99;
10113     }
10114
10115   if (tx_sw_if_index_set == 0)
10116     {
10117       errmsg ("missing tx interface name or tx_sw_if_index");
10118       return -99;
10119     }
10120
10121   M (L2_PATCH_ADD_DEL, mp);
10122
10123   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10124   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10125   mp->is_add = is_add;
10126
10127   S (mp);
10128   W (ret);
10129   return ret;
10130 }
10131
10132 u8 is_del;
10133 u8 localsid_addr[16];
10134 u8 end_psp;
10135 u8 behavior;
10136 u32 sw_if_index;
10137 u32 vlan_index;
10138 u32 fib_table;
10139 u8 nh_addr[16];
10140
10141 static int
10142 api_sr_localsid_add_del (vat_main_t * vam)
10143 {
10144   unformat_input_t *i = vam->input;
10145   vl_api_sr_localsid_add_del_t *mp;
10146
10147   u8 is_del;
10148   ip6_address_t localsid;
10149   u8 end_psp = 0;
10150   u8 behavior = ~0;
10151   u32 sw_if_index;
10152   u32 fib_table = ~(u32) 0;
10153   ip6_address_t nh_addr6;
10154   ip4_address_t nh_addr4;
10155   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
10156   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
10157
10158   bool nexthop_set = 0;
10159
10160   int ret;
10161
10162   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10163     {
10164       if (unformat (i, "del"))
10165         is_del = 1;
10166       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10167       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
10168         nexthop_set = 1;
10169       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
10170         nexthop_set = 1;
10171       else if (unformat (i, "behavior %u", &behavior));
10172       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10173       else if (unformat (i, "fib-table %u", &fib_table));
10174       else if (unformat (i, "end.psp %u", &behavior));
10175       else
10176         break;
10177     }
10178
10179   M (SR_LOCALSID_ADD_DEL, mp);
10180
10181   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
10182   if (nexthop_set)
10183     {
10184       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
10185       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
10186     }
10187   mp->behavior = behavior;
10188   mp->sw_if_index = ntohl (sw_if_index);
10189   mp->fib_table = ntohl (fib_table);
10190   mp->end_psp = end_psp;
10191   mp->is_del = is_del;
10192
10193   S (mp);
10194   W (ret);
10195   return ret;
10196 }
10197
10198 static int
10199 api_ioam_enable (vat_main_t * vam)
10200 {
10201   unformat_input_t *input = vam->input;
10202   vl_api_ioam_enable_t *mp;
10203   u32 id = 0;
10204   int has_trace_option = 0;
10205   int has_pot_option = 0;
10206   int has_seqno_option = 0;
10207   int has_analyse_option = 0;
10208   int ret;
10209
10210   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10211     {
10212       if (unformat (input, "trace"))
10213         has_trace_option = 1;
10214       else if (unformat (input, "pot"))
10215         has_pot_option = 1;
10216       else if (unformat (input, "seqno"))
10217         has_seqno_option = 1;
10218       else if (unformat (input, "analyse"))
10219         has_analyse_option = 1;
10220       else
10221         break;
10222     }
10223   M (IOAM_ENABLE, mp);
10224   mp->id = htons (id);
10225   mp->seqno = has_seqno_option;
10226   mp->analyse = has_analyse_option;
10227   mp->pot_enable = has_pot_option;
10228   mp->trace_enable = has_trace_option;
10229
10230   S (mp);
10231   W (ret);
10232   return ret;
10233 }
10234
10235
10236 static int
10237 api_ioam_disable (vat_main_t * vam)
10238 {
10239   vl_api_ioam_disable_t *mp;
10240   int ret;
10241
10242   M (IOAM_DISABLE, mp);
10243   S (mp);
10244   W (ret);
10245   return ret;
10246 }
10247
10248 #define foreach_tcp_proto_field                 \
10249 _(src_port)                                     \
10250 _(dst_port)
10251
10252 #define foreach_udp_proto_field                 \
10253 _(src_port)                                     \
10254 _(dst_port)
10255
10256 #define foreach_ip4_proto_field                 \
10257 _(src_address)                                  \
10258 _(dst_address)                                  \
10259 _(tos)                                          \
10260 _(length)                                       \
10261 _(fragment_id)                                  \
10262 _(ttl)                                          \
10263 _(protocol)                                     \
10264 _(checksum)
10265
10266 typedef struct
10267 {
10268   u16 src_port, dst_port;
10269 } tcpudp_header_t;
10270
10271 #if VPP_API_TEST_BUILTIN == 0
10272 uword
10273 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10274 {
10275   u8 **maskp = va_arg (*args, u8 **);
10276   u8 *mask = 0;
10277   u8 found_something = 0;
10278   tcp_header_t *tcp;
10279
10280 #define _(a) u8 a=0;
10281   foreach_tcp_proto_field;
10282 #undef _
10283
10284   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10285     {
10286       if (0);
10287 #define _(a) else if (unformat (input, #a)) a=1;
10288       foreach_tcp_proto_field
10289 #undef _
10290         else
10291         break;
10292     }
10293
10294 #define _(a) found_something += a;
10295   foreach_tcp_proto_field;
10296 #undef _
10297
10298   if (found_something == 0)
10299     return 0;
10300
10301   vec_validate (mask, sizeof (*tcp) - 1);
10302
10303   tcp = (tcp_header_t *) mask;
10304
10305 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
10306   foreach_tcp_proto_field;
10307 #undef _
10308
10309   *maskp = mask;
10310   return 1;
10311 }
10312
10313 uword
10314 unformat_udp_mask (unformat_input_t * input, va_list * args)
10315 {
10316   u8 **maskp = va_arg (*args, u8 **);
10317   u8 *mask = 0;
10318   u8 found_something = 0;
10319   udp_header_t *udp;
10320
10321 #define _(a) u8 a=0;
10322   foreach_udp_proto_field;
10323 #undef _
10324
10325   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10326     {
10327       if (0);
10328 #define _(a) else if (unformat (input, #a)) a=1;
10329       foreach_udp_proto_field
10330 #undef _
10331         else
10332         break;
10333     }
10334
10335 #define _(a) found_something += a;
10336   foreach_udp_proto_field;
10337 #undef _
10338
10339   if (found_something == 0)
10340     return 0;
10341
10342   vec_validate (mask, sizeof (*udp) - 1);
10343
10344   udp = (udp_header_t *) mask;
10345
10346 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
10347   foreach_udp_proto_field;
10348 #undef _
10349
10350   *maskp = mask;
10351   return 1;
10352 }
10353
10354 uword
10355 unformat_l4_mask (unformat_input_t * input, va_list * args)
10356 {
10357   u8 **maskp = va_arg (*args, u8 **);
10358   u16 src_port = 0, dst_port = 0;
10359   tcpudp_header_t *tcpudp;
10360
10361   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10362     {
10363       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10364         return 1;
10365       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10366         return 1;
10367       else if (unformat (input, "src_port"))
10368         src_port = 0xFFFF;
10369       else if (unformat (input, "dst_port"))
10370         dst_port = 0xFFFF;
10371       else
10372         return 0;
10373     }
10374
10375   if (!src_port && !dst_port)
10376     return 0;
10377
10378   u8 *mask = 0;
10379   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10380
10381   tcpudp = (tcpudp_header_t *) mask;
10382   tcpudp->src_port = src_port;
10383   tcpudp->dst_port = dst_port;
10384
10385   *maskp = mask;
10386
10387   return 1;
10388 }
10389
10390 uword
10391 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10392 {
10393   u8 **maskp = va_arg (*args, u8 **);
10394   u8 *mask = 0;
10395   u8 found_something = 0;
10396   ip4_header_t *ip;
10397
10398 #define _(a) u8 a=0;
10399   foreach_ip4_proto_field;
10400 #undef _
10401   u8 version = 0;
10402   u8 hdr_length = 0;
10403
10404
10405   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10406     {
10407       if (unformat (input, "version"))
10408         version = 1;
10409       else if (unformat (input, "hdr_length"))
10410         hdr_length = 1;
10411       else if (unformat (input, "src"))
10412         src_address = 1;
10413       else if (unformat (input, "dst"))
10414         dst_address = 1;
10415       else if (unformat (input, "proto"))
10416         protocol = 1;
10417
10418 #define _(a) else if (unformat (input, #a)) a=1;
10419       foreach_ip4_proto_field
10420 #undef _
10421         else
10422         break;
10423     }
10424
10425 #define _(a) found_something += a;
10426   foreach_ip4_proto_field;
10427 #undef _
10428
10429   if (found_something == 0)
10430     return 0;
10431
10432   vec_validate (mask, sizeof (*ip) - 1);
10433
10434   ip = (ip4_header_t *) mask;
10435
10436 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10437   foreach_ip4_proto_field;
10438 #undef _
10439
10440   ip->ip_version_and_header_length = 0;
10441
10442   if (version)
10443     ip->ip_version_and_header_length |= 0xF0;
10444
10445   if (hdr_length)
10446     ip->ip_version_and_header_length |= 0x0F;
10447
10448   *maskp = mask;
10449   return 1;
10450 }
10451
10452 #define foreach_ip6_proto_field                 \
10453 _(src_address)                                  \
10454 _(dst_address)                                  \
10455 _(payload_length)                               \
10456 _(hop_limit)                                    \
10457 _(protocol)
10458
10459 uword
10460 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10461 {
10462   u8 **maskp = va_arg (*args, u8 **);
10463   u8 *mask = 0;
10464   u8 found_something = 0;
10465   ip6_header_t *ip;
10466   u32 ip_version_traffic_class_and_flow_label;
10467
10468 #define _(a) u8 a=0;
10469   foreach_ip6_proto_field;
10470 #undef _
10471   u8 version = 0;
10472   u8 traffic_class = 0;
10473   u8 flow_label = 0;
10474
10475   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10476     {
10477       if (unformat (input, "version"))
10478         version = 1;
10479       else if (unformat (input, "traffic-class"))
10480         traffic_class = 1;
10481       else if (unformat (input, "flow-label"))
10482         flow_label = 1;
10483       else if (unformat (input, "src"))
10484         src_address = 1;
10485       else if (unformat (input, "dst"))
10486         dst_address = 1;
10487       else if (unformat (input, "proto"))
10488         protocol = 1;
10489
10490 #define _(a) else if (unformat (input, #a)) a=1;
10491       foreach_ip6_proto_field
10492 #undef _
10493         else
10494         break;
10495     }
10496
10497 #define _(a) found_something += a;
10498   foreach_ip6_proto_field;
10499 #undef _
10500
10501   if (found_something == 0)
10502     return 0;
10503
10504   vec_validate (mask, sizeof (*ip) - 1);
10505
10506   ip = (ip6_header_t *) mask;
10507
10508 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10509   foreach_ip6_proto_field;
10510 #undef _
10511
10512   ip_version_traffic_class_and_flow_label = 0;
10513
10514   if (version)
10515     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10516
10517   if (traffic_class)
10518     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10519
10520   if (flow_label)
10521     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10522
10523   ip->ip_version_traffic_class_and_flow_label =
10524     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10525
10526   *maskp = mask;
10527   return 1;
10528 }
10529
10530 uword
10531 unformat_l3_mask (unformat_input_t * input, va_list * args)
10532 {
10533   u8 **maskp = va_arg (*args, u8 **);
10534
10535   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10536     {
10537       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10538         return 1;
10539       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10540         return 1;
10541       else
10542         break;
10543     }
10544   return 0;
10545 }
10546
10547 uword
10548 unformat_l2_mask (unformat_input_t * input, va_list * args)
10549 {
10550   u8 **maskp = va_arg (*args, u8 **);
10551   u8 *mask = 0;
10552   u8 src = 0;
10553   u8 dst = 0;
10554   u8 proto = 0;
10555   u8 tag1 = 0;
10556   u8 tag2 = 0;
10557   u8 ignore_tag1 = 0;
10558   u8 ignore_tag2 = 0;
10559   u8 cos1 = 0;
10560   u8 cos2 = 0;
10561   u8 dot1q = 0;
10562   u8 dot1ad = 0;
10563   int len = 14;
10564
10565   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10566     {
10567       if (unformat (input, "src"))
10568         src = 1;
10569       else if (unformat (input, "dst"))
10570         dst = 1;
10571       else if (unformat (input, "proto"))
10572         proto = 1;
10573       else if (unformat (input, "tag1"))
10574         tag1 = 1;
10575       else if (unformat (input, "tag2"))
10576         tag2 = 1;
10577       else if (unformat (input, "ignore-tag1"))
10578         ignore_tag1 = 1;
10579       else if (unformat (input, "ignore-tag2"))
10580         ignore_tag2 = 1;
10581       else if (unformat (input, "cos1"))
10582         cos1 = 1;
10583       else if (unformat (input, "cos2"))
10584         cos2 = 1;
10585       else if (unformat (input, "dot1q"))
10586         dot1q = 1;
10587       else if (unformat (input, "dot1ad"))
10588         dot1ad = 1;
10589       else
10590         break;
10591     }
10592   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10593        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10594     return 0;
10595
10596   if (tag1 || ignore_tag1 || cos1 || dot1q)
10597     len = 18;
10598   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10599     len = 22;
10600
10601   vec_validate (mask, len - 1);
10602
10603   if (dst)
10604     clib_memset (mask, 0xff, 6);
10605
10606   if (src)
10607     clib_memset (mask + 6, 0xff, 6);
10608
10609   if (tag2 || dot1ad)
10610     {
10611       /* inner vlan tag */
10612       if (tag2)
10613         {
10614           mask[19] = 0xff;
10615           mask[18] = 0x0f;
10616         }
10617       if (cos2)
10618         mask[18] |= 0xe0;
10619       if (proto)
10620         mask[21] = mask[20] = 0xff;
10621       if (tag1)
10622         {
10623           mask[15] = 0xff;
10624           mask[14] = 0x0f;
10625         }
10626       if (cos1)
10627         mask[14] |= 0xe0;
10628       *maskp = mask;
10629       return 1;
10630     }
10631   if (tag1 | dot1q)
10632     {
10633       if (tag1)
10634         {
10635           mask[15] = 0xff;
10636           mask[14] = 0x0f;
10637         }
10638       if (cos1)
10639         mask[14] |= 0xe0;
10640       if (proto)
10641         mask[16] = mask[17] = 0xff;
10642
10643       *maskp = mask;
10644       return 1;
10645     }
10646   if (cos2)
10647     mask[18] |= 0xe0;
10648   if (cos1)
10649     mask[14] |= 0xe0;
10650   if (proto)
10651     mask[12] = mask[13] = 0xff;
10652
10653   *maskp = mask;
10654   return 1;
10655 }
10656
10657 uword
10658 unformat_classify_mask (unformat_input_t * input, va_list * args)
10659 {
10660   u8 **maskp = va_arg (*args, u8 **);
10661   u32 *skipp = va_arg (*args, u32 *);
10662   u32 *matchp = va_arg (*args, u32 *);
10663   u32 match;
10664   u8 *mask = 0;
10665   u8 *l2 = 0;
10666   u8 *l3 = 0;
10667   u8 *l4 = 0;
10668   int i;
10669
10670   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10671     {
10672       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10673         ;
10674       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10675         ;
10676       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10677         ;
10678       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10679         ;
10680       else
10681         break;
10682     }
10683
10684   if (l4 && !l3)
10685     {
10686       vec_free (mask);
10687       vec_free (l2);
10688       vec_free (l4);
10689       return 0;
10690     }
10691
10692   if (mask || l2 || l3 || l4)
10693     {
10694       if (l2 || l3 || l4)
10695         {
10696           /* "With a free Ethernet header in every package" */
10697           if (l2 == 0)
10698             vec_validate (l2, 13);
10699           mask = l2;
10700           if (vec_len (l3))
10701             {
10702               vec_append (mask, l3);
10703               vec_free (l3);
10704             }
10705           if (vec_len (l4))
10706             {
10707               vec_append (mask, l4);
10708               vec_free (l4);
10709             }
10710         }
10711
10712       /* Scan forward looking for the first significant mask octet */
10713       for (i = 0; i < vec_len (mask); i++)
10714         if (mask[i])
10715           break;
10716
10717       /* compute (skip, match) params */
10718       *skipp = i / sizeof (u32x4);
10719       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10720
10721       /* Pad mask to an even multiple of the vector size */
10722       while (vec_len (mask) % sizeof (u32x4))
10723         vec_add1 (mask, 0);
10724
10725       match = vec_len (mask) / sizeof (u32x4);
10726
10727       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10728         {
10729           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10730           if (*tmp || *(tmp + 1))
10731             break;
10732           match--;
10733         }
10734       if (match == 0)
10735         clib_warning ("BUG: match 0");
10736
10737       _vec_len (mask) = match * sizeof (u32x4);
10738
10739       *matchp = match;
10740       *maskp = mask;
10741
10742       return 1;
10743     }
10744
10745   return 0;
10746 }
10747 #endif /* VPP_API_TEST_BUILTIN */
10748
10749 #define foreach_l2_next                         \
10750 _(drop, DROP)                                   \
10751 _(ethernet, ETHERNET_INPUT)                     \
10752 _(ip4, IP4_INPUT)                               \
10753 _(ip6, IP6_INPUT)
10754
10755 uword
10756 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10757 {
10758   u32 *miss_next_indexp = va_arg (*args, u32 *);
10759   u32 next_index = 0;
10760   u32 tmp;
10761
10762 #define _(n,N) \
10763   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10764   foreach_l2_next;
10765 #undef _
10766
10767   if (unformat (input, "%d", &tmp))
10768     {
10769       next_index = tmp;
10770       goto out;
10771     }
10772
10773   return 0;
10774
10775 out:
10776   *miss_next_indexp = next_index;
10777   return 1;
10778 }
10779
10780 #define foreach_ip_next                         \
10781 _(drop, DROP)                                   \
10782 _(local, LOCAL)                                 \
10783 _(rewrite, REWRITE)
10784
10785 uword
10786 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10787 {
10788   u32 *miss_next_indexp = va_arg (*args, u32 *);
10789   u32 next_index = 0;
10790   u32 tmp;
10791
10792 #define _(n,N) \
10793   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10794   foreach_ip_next;
10795 #undef _
10796
10797   if (unformat (input, "%d", &tmp))
10798     {
10799       next_index = tmp;
10800       goto out;
10801     }
10802
10803   return 0;
10804
10805 out:
10806   *miss_next_indexp = next_index;
10807   return 1;
10808 }
10809
10810 #define foreach_acl_next                        \
10811 _(deny, DENY)
10812
10813 uword
10814 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10815 {
10816   u32 *miss_next_indexp = va_arg (*args, u32 *);
10817   u32 next_index = 0;
10818   u32 tmp;
10819
10820 #define _(n,N) \
10821   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10822   foreach_acl_next;
10823 #undef _
10824
10825   if (unformat (input, "permit"))
10826     {
10827       next_index = ~0;
10828       goto out;
10829     }
10830   else if (unformat (input, "%d", &tmp))
10831     {
10832       next_index = tmp;
10833       goto out;
10834     }
10835
10836   return 0;
10837
10838 out:
10839   *miss_next_indexp = next_index;
10840   return 1;
10841 }
10842
10843 uword
10844 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10845 {
10846   u32 *r = va_arg (*args, u32 *);
10847
10848   if (unformat (input, "conform-color"))
10849     *r = POLICE_CONFORM;
10850   else if (unformat (input, "exceed-color"))
10851     *r = POLICE_EXCEED;
10852   else
10853     return 0;
10854
10855   return 1;
10856 }
10857
10858 static int
10859 api_classify_add_del_table (vat_main_t * vam)
10860 {
10861   unformat_input_t *i = vam->input;
10862   vl_api_classify_add_del_table_t *mp;
10863
10864   u32 nbuckets = 2;
10865   u32 skip = ~0;
10866   u32 match = ~0;
10867   int is_add = 1;
10868   int del_chain = 0;
10869   u32 table_index = ~0;
10870   u32 next_table_index = ~0;
10871   u32 miss_next_index = ~0;
10872   u32 memory_size = 32 << 20;
10873   u8 *mask = 0;
10874   u32 current_data_flag = 0;
10875   int current_data_offset = 0;
10876   int ret;
10877
10878   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10879     {
10880       if (unformat (i, "del"))
10881         is_add = 0;
10882       else if (unformat (i, "del-chain"))
10883         {
10884           is_add = 0;
10885           del_chain = 1;
10886         }
10887       else if (unformat (i, "buckets %d", &nbuckets))
10888         ;
10889       else if (unformat (i, "memory_size %d", &memory_size))
10890         ;
10891       else if (unformat (i, "skip %d", &skip))
10892         ;
10893       else if (unformat (i, "match %d", &match))
10894         ;
10895       else if (unformat (i, "table %d", &table_index))
10896         ;
10897       else if (unformat (i, "mask %U", unformat_classify_mask,
10898                          &mask, &skip, &match))
10899         ;
10900       else if (unformat (i, "next-table %d", &next_table_index))
10901         ;
10902       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10903                          &miss_next_index))
10904         ;
10905       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10906                          &miss_next_index))
10907         ;
10908       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10909                          &miss_next_index))
10910         ;
10911       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10912         ;
10913       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10914         ;
10915       else
10916         break;
10917     }
10918
10919   if (is_add && mask == 0)
10920     {
10921       errmsg ("Mask required");
10922       return -99;
10923     }
10924
10925   if (is_add && skip == ~0)
10926     {
10927       errmsg ("skip count required");
10928       return -99;
10929     }
10930
10931   if (is_add && match == ~0)
10932     {
10933       errmsg ("match count required");
10934       return -99;
10935     }
10936
10937   if (!is_add && table_index == ~0)
10938     {
10939       errmsg ("table index required for delete");
10940       return -99;
10941     }
10942
10943   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10944
10945   mp->is_add = is_add;
10946   mp->del_chain = del_chain;
10947   mp->table_index = ntohl (table_index);
10948   mp->nbuckets = ntohl (nbuckets);
10949   mp->memory_size = ntohl (memory_size);
10950   mp->skip_n_vectors = ntohl (skip);
10951   mp->match_n_vectors = ntohl (match);
10952   mp->next_table_index = ntohl (next_table_index);
10953   mp->miss_next_index = ntohl (miss_next_index);
10954   mp->current_data_flag = ntohl (current_data_flag);
10955   mp->current_data_offset = ntohl (current_data_offset);
10956   mp->mask_len = ntohl (vec_len (mask));
10957   clib_memcpy (mp->mask, mask, vec_len (mask));
10958
10959   vec_free (mask);
10960
10961   S (mp);
10962   W (ret);
10963   return ret;
10964 }
10965
10966 #if VPP_API_TEST_BUILTIN == 0
10967 uword
10968 unformat_l4_match (unformat_input_t * input, va_list * args)
10969 {
10970   u8 **matchp = va_arg (*args, u8 **);
10971
10972   u8 *proto_header = 0;
10973   int src_port = 0;
10974   int dst_port = 0;
10975
10976   tcpudp_header_t h;
10977
10978   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10979     {
10980       if (unformat (input, "src_port %d", &src_port))
10981         ;
10982       else if (unformat (input, "dst_port %d", &dst_port))
10983         ;
10984       else
10985         return 0;
10986     }
10987
10988   h.src_port = clib_host_to_net_u16 (src_port);
10989   h.dst_port = clib_host_to_net_u16 (dst_port);
10990   vec_validate (proto_header, sizeof (h) - 1);
10991   memcpy (proto_header, &h, sizeof (h));
10992
10993   *matchp = proto_header;
10994
10995   return 1;
10996 }
10997
10998 uword
10999 unformat_ip4_match (unformat_input_t * input, va_list * args)
11000 {
11001   u8 **matchp = va_arg (*args, u8 **);
11002   u8 *match = 0;
11003   ip4_header_t *ip;
11004   int version = 0;
11005   u32 version_val;
11006   int hdr_length = 0;
11007   u32 hdr_length_val;
11008   int src = 0, dst = 0;
11009   ip4_address_t src_val, dst_val;
11010   int proto = 0;
11011   u32 proto_val;
11012   int tos = 0;
11013   u32 tos_val;
11014   int length = 0;
11015   u32 length_val;
11016   int fragment_id = 0;
11017   u32 fragment_id_val;
11018   int ttl = 0;
11019   int ttl_val;
11020   int checksum = 0;
11021   u32 checksum_val;
11022
11023   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11024     {
11025       if (unformat (input, "version %d", &version_val))
11026         version = 1;
11027       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11028         hdr_length = 1;
11029       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11030         src = 1;
11031       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11032         dst = 1;
11033       else if (unformat (input, "proto %d", &proto_val))
11034         proto = 1;
11035       else if (unformat (input, "tos %d", &tos_val))
11036         tos = 1;
11037       else if (unformat (input, "length %d", &length_val))
11038         length = 1;
11039       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11040         fragment_id = 1;
11041       else if (unformat (input, "ttl %d", &ttl_val))
11042         ttl = 1;
11043       else if (unformat (input, "checksum %d", &checksum_val))
11044         checksum = 1;
11045       else
11046         break;
11047     }
11048
11049   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11050       + ttl + checksum == 0)
11051     return 0;
11052
11053   /*
11054    * Aligned because we use the real comparison functions
11055    */
11056   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11057
11058   ip = (ip4_header_t *) match;
11059
11060   /* These are realistically matched in practice */
11061   if (src)
11062     ip->src_address.as_u32 = src_val.as_u32;
11063
11064   if (dst)
11065     ip->dst_address.as_u32 = dst_val.as_u32;
11066
11067   if (proto)
11068     ip->protocol = proto_val;
11069
11070
11071   /* These are not, but they're included for completeness */
11072   if (version)
11073     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11074
11075   if (hdr_length)
11076     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11077
11078   if (tos)
11079     ip->tos = tos_val;
11080
11081   if (length)
11082     ip->length = clib_host_to_net_u16 (length_val);
11083
11084   if (ttl)
11085     ip->ttl = ttl_val;
11086
11087   if (checksum)
11088     ip->checksum = clib_host_to_net_u16 (checksum_val);
11089
11090   *matchp = match;
11091   return 1;
11092 }
11093
11094 uword
11095 unformat_ip6_match (unformat_input_t * input, va_list * args)
11096 {
11097   u8 **matchp = va_arg (*args, u8 **);
11098   u8 *match = 0;
11099   ip6_header_t *ip;
11100   int version = 0;
11101   u32 version_val;
11102   u8 traffic_class = 0;
11103   u32 traffic_class_val = 0;
11104   u8 flow_label = 0;
11105   u8 flow_label_val;
11106   int src = 0, dst = 0;
11107   ip6_address_t src_val, dst_val;
11108   int proto = 0;
11109   u32 proto_val;
11110   int payload_length = 0;
11111   u32 payload_length_val;
11112   int hop_limit = 0;
11113   int hop_limit_val;
11114   u32 ip_version_traffic_class_and_flow_label;
11115
11116   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11117     {
11118       if (unformat (input, "version %d", &version_val))
11119         version = 1;
11120       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11121         traffic_class = 1;
11122       else if (unformat (input, "flow_label %d", &flow_label_val))
11123         flow_label = 1;
11124       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11125         src = 1;
11126       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11127         dst = 1;
11128       else if (unformat (input, "proto %d", &proto_val))
11129         proto = 1;
11130       else if (unformat (input, "payload_length %d", &payload_length_val))
11131         payload_length = 1;
11132       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11133         hop_limit = 1;
11134       else
11135         break;
11136     }
11137
11138   if (version + traffic_class + flow_label + src + dst + proto +
11139       payload_length + hop_limit == 0)
11140     return 0;
11141
11142   /*
11143    * Aligned because we use the real comparison functions
11144    */
11145   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11146
11147   ip = (ip6_header_t *) match;
11148
11149   if (src)
11150     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11151
11152   if (dst)
11153     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11154
11155   if (proto)
11156     ip->protocol = proto_val;
11157
11158   ip_version_traffic_class_and_flow_label = 0;
11159
11160   if (version)
11161     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11162
11163   if (traffic_class)
11164     ip_version_traffic_class_and_flow_label |=
11165       (traffic_class_val & 0xFF) << 20;
11166
11167   if (flow_label)
11168     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11169
11170   ip->ip_version_traffic_class_and_flow_label =
11171     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11172
11173   if (payload_length)
11174     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11175
11176   if (hop_limit)
11177     ip->hop_limit = hop_limit_val;
11178
11179   *matchp = match;
11180   return 1;
11181 }
11182
11183 uword
11184 unformat_l3_match (unformat_input_t * input, va_list * args)
11185 {
11186   u8 **matchp = va_arg (*args, u8 **);
11187
11188   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11189     {
11190       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11191         return 1;
11192       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11193         return 1;
11194       else
11195         break;
11196     }
11197   return 0;
11198 }
11199
11200 uword
11201 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11202 {
11203   u8 *tagp = va_arg (*args, u8 *);
11204   u32 tag;
11205
11206   if (unformat (input, "%d", &tag))
11207     {
11208       tagp[0] = (tag >> 8) & 0x0F;
11209       tagp[1] = tag & 0xFF;
11210       return 1;
11211     }
11212
11213   return 0;
11214 }
11215
11216 uword
11217 unformat_l2_match (unformat_input_t * input, va_list * args)
11218 {
11219   u8 **matchp = va_arg (*args, u8 **);
11220   u8 *match = 0;
11221   u8 src = 0;
11222   u8 src_val[6];
11223   u8 dst = 0;
11224   u8 dst_val[6];
11225   u8 proto = 0;
11226   u16 proto_val;
11227   u8 tag1 = 0;
11228   u8 tag1_val[2];
11229   u8 tag2 = 0;
11230   u8 tag2_val[2];
11231   int len = 14;
11232   u8 ignore_tag1 = 0;
11233   u8 ignore_tag2 = 0;
11234   u8 cos1 = 0;
11235   u8 cos2 = 0;
11236   u32 cos1_val = 0;
11237   u32 cos2_val = 0;
11238
11239   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11240     {
11241       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11242         src = 1;
11243       else
11244         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11245         dst = 1;
11246       else if (unformat (input, "proto %U",
11247                          unformat_ethernet_type_host_byte_order, &proto_val))
11248         proto = 1;
11249       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11250         tag1 = 1;
11251       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11252         tag2 = 1;
11253       else if (unformat (input, "ignore-tag1"))
11254         ignore_tag1 = 1;
11255       else if (unformat (input, "ignore-tag2"))
11256         ignore_tag2 = 1;
11257       else if (unformat (input, "cos1 %d", &cos1_val))
11258         cos1 = 1;
11259       else if (unformat (input, "cos2 %d", &cos2_val))
11260         cos2 = 1;
11261       else
11262         break;
11263     }
11264   if ((src + dst + proto + tag1 + tag2 +
11265        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11266     return 0;
11267
11268   if (tag1 || ignore_tag1 || cos1)
11269     len = 18;
11270   if (tag2 || ignore_tag2 || cos2)
11271     len = 22;
11272
11273   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11274
11275   if (dst)
11276     clib_memcpy (match, dst_val, 6);
11277
11278   if (src)
11279     clib_memcpy (match + 6, src_val, 6);
11280
11281   if (tag2)
11282     {
11283       /* inner vlan tag */
11284       match[19] = tag2_val[1];
11285       match[18] = tag2_val[0];
11286       if (cos2)
11287         match[18] |= (cos2_val & 0x7) << 5;
11288       if (proto)
11289         {
11290           match[21] = proto_val & 0xff;
11291           match[20] = proto_val >> 8;
11292         }
11293       if (tag1)
11294         {
11295           match[15] = tag1_val[1];
11296           match[14] = tag1_val[0];
11297         }
11298       if (cos1)
11299         match[14] |= (cos1_val & 0x7) << 5;
11300       *matchp = match;
11301       return 1;
11302     }
11303   if (tag1)
11304     {
11305       match[15] = tag1_val[1];
11306       match[14] = tag1_val[0];
11307       if (proto)
11308         {
11309           match[17] = proto_val & 0xff;
11310           match[16] = proto_val >> 8;
11311         }
11312       if (cos1)
11313         match[14] |= (cos1_val & 0x7) << 5;
11314
11315       *matchp = match;
11316       return 1;
11317     }
11318   if (cos2)
11319     match[18] |= (cos2_val & 0x7) << 5;
11320   if (cos1)
11321     match[14] |= (cos1_val & 0x7) << 5;
11322   if (proto)
11323     {
11324       match[13] = proto_val & 0xff;
11325       match[12] = proto_val >> 8;
11326     }
11327
11328   *matchp = match;
11329   return 1;
11330 }
11331
11332 uword
11333 unformat_qos_source (unformat_input_t * input, va_list * args)
11334 {
11335   int *qs = va_arg (*args, int *);
11336
11337   if (unformat (input, "ip"))
11338     *qs = QOS_SOURCE_IP;
11339   else if (unformat (input, "mpls"))
11340     *qs = QOS_SOURCE_MPLS;
11341   else if (unformat (input, "ext"))
11342     *qs = QOS_SOURCE_EXT;
11343   else if (unformat (input, "vlan"))
11344     *qs = QOS_SOURCE_VLAN;
11345   else
11346     return 0;
11347
11348   return 1;
11349 }
11350 #endif
11351
11352 uword
11353 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11354 {
11355   u8 **matchp = va_arg (*args, u8 **);
11356   u32 skip_n_vectors = va_arg (*args, u32);
11357   u32 match_n_vectors = va_arg (*args, u32);
11358
11359   u8 *match = 0;
11360   u8 *l2 = 0;
11361   u8 *l3 = 0;
11362   u8 *l4 = 0;
11363
11364   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11365     {
11366       if (unformat (input, "hex %U", unformat_hex_string, &match))
11367         ;
11368       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11369         ;
11370       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11371         ;
11372       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11373         ;
11374       else
11375         break;
11376     }
11377
11378   if (l4 && !l3)
11379     {
11380       vec_free (match);
11381       vec_free (l2);
11382       vec_free (l4);
11383       return 0;
11384     }
11385
11386   if (match || l2 || l3 || l4)
11387     {
11388       if (l2 || l3 || l4)
11389         {
11390           /* "Win a free Ethernet header in every packet" */
11391           if (l2 == 0)
11392             vec_validate_aligned (l2, 13, sizeof (u32x4));
11393           match = l2;
11394           if (vec_len (l3))
11395             {
11396               vec_append_aligned (match, l3, sizeof (u32x4));
11397               vec_free (l3);
11398             }
11399           if (vec_len (l4))
11400             {
11401               vec_append_aligned (match, l4, sizeof (u32x4));
11402               vec_free (l4);
11403             }
11404         }
11405
11406       /* Make sure the vector is big enough even if key is all 0's */
11407       vec_validate_aligned
11408         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11409          sizeof (u32x4));
11410
11411       /* Set size, include skipped vectors */
11412       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11413
11414       *matchp = match;
11415
11416       return 1;
11417     }
11418
11419   return 0;
11420 }
11421
11422 static int
11423 api_classify_add_del_session (vat_main_t * vam)
11424 {
11425   unformat_input_t *i = vam->input;
11426   vl_api_classify_add_del_session_t *mp;
11427   int is_add = 1;
11428   u32 table_index = ~0;
11429   u32 hit_next_index = ~0;
11430   u32 opaque_index = ~0;
11431   u8 *match = 0;
11432   i32 advance = 0;
11433   u32 skip_n_vectors = 0;
11434   u32 match_n_vectors = 0;
11435   u32 action = 0;
11436   u32 metadata = 0;
11437   int ret;
11438
11439   /*
11440    * Warning: you have to supply skip_n and match_n
11441    * because the API client cant simply look at the classify
11442    * table object.
11443    */
11444
11445   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11446     {
11447       if (unformat (i, "del"))
11448         is_add = 0;
11449       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11450                          &hit_next_index))
11451         ;
11452       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11453                          &hit_next_index))
11454         ;
11455       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11456                          &hit_next_index))
11457         ;
11458       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11459         ;
11460       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11461         ;
11462       else if (unformat (i, "opaque-index %d", &opaque_index))
11463         ;
11464       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11465         ;
11466       else if (unformat (i, "match_n %d", &match_n_vectors))
11467         ;
11468       else if (unformat (i, "match %U", api_unformat_classify_match,
11469                          &match, skip_n_vectors, match_n_vectors))
11470         ;
11471       else if (unformat (i, "advance %d", &advance))
11472         ;
11473       else if (unformat (i, "table-index %d", &table_index))
11474         ;
11475       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11476         action = 1;
11477       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11478         action = 2;
11479       else if (unformat (i, "action %d", &action))
11480         ;
11481       else if (unformat (i, "metadata %d", &metadata))
11482         ;
11483       else
11484         break;
11485     }
11486
11487   if (table_index == ~0)
11488     {
11489       errmsg ("Table index required");
11490       return -99;
11491     }
11492
11493   if (is_add && match == 0)
11494     {
11495       errmsg ("Match value required");
11496       return -99;
11497     }
11498
11499   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11500
11501   mp->is_add = is_add;
11502   mp->table_index = ntohl (table_index);
11503   mp->hit_next_index = ntohl (hit_next_index);
11504   mp->opaque_index = ntohl (opaque_index);
11505   mp->advance = ntohl (advance);
11506   mp->action = action;
11507   mp->metadata = ntohl (metadata);
11508   mp->match_len = ntohl (vec_len (match));
11509   clib_memcpy (mp->match, match, vec_len (match));
11510   vec_free (match);
11511
11512   S (mp);
11513   W (ret);
11514   return ret;
11515 }
11516
11517 static int
11518 api_classify_set_interface_ip_table (vat_main_t * vam)
11519 {
11520   unformat_input_t *i = vam->input;
11521   vl_api_classify_set_interface_ip_table_t *mp;
11522   u32 sw_if_index;
11523   int sw_if_index_set;
11524   u32 table_index = ~0;
11525   u8 is_ipv6 = 0;
11526   int ret;
11527
11528   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11529     {
11530       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11531         sw_if_index_set = 1;
11532       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11533         sw_if_index_set = 1;
11534       else if (unformat (i, "table %d", &table_index))
11535         ;
11536       else
11537         {
11538           clib_warning ("parse error '%U'", format_unformat_error, i);
11539           return -99;
11540         }
11541     }
11542
11543   if (sw_if_index_set == 0)
11544     {
11545       errmsg ("missing interface name or sw_if_index");
11546       return -99;
11547     }
11548
11549
11550   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11551
11552   mp->sw_if_index = ntohl (sw_if_index);
11553   mp->table_index = ntohl (table_index);
11554   mp->is_ipv6 = is_ipv6;
11555
11556   S (mp);
11557   W (ret);
11558   return ret;
11559 }
11560
11561 static int
11562 api_classify_set_interface_l2_tables (vat_main_t * vam)
11563 {
11564   unformat_input_t *i = vam->input;
11565   vl_api_classify_set_interface_l2_tables_t *mp;
11566   u32 sw_if_index;
11567   int sw_if_index_set;
11568   u32 ip4_table_index = ~0;
11569   u32 ip6_table_index = ~0;
11570   u32 other_table_index = ~0;
11571   u32 is_input = 1;
11572   int ret;
11573
11574   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11575     {
11576       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11577         sw_if_index_set = 1;
11578       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11579         sw_if_index_set = 1;
11580       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11581         ;
11582       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11583         ;
11584       else if (unformat (i, "other-table %d", &other_table_index))
11585         ;
11586       else if (unformat (i, "is-input %d", &is_input))
11587         ;
11588       else
11589         {
11590           clib_warning ("parse error '%U'", format_unformat_error, i);
11591           return -99;
11592         }
11593     }
11594
11595   if (sw_if_index_set == 0)
11596     {
11597       errmsg ("missing interface name or sw_if_index");
11598       return -99;
11599     }
11600
11601
11602   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11603
11604   mp->sw_if_index = ntohl (sw_if_index);
11605   mp->ip4_table_index = ntohl (ip4_table_index);
11606   mp->ip6_table_index = ntohl (ip6_table_index);
11607   mp->other_table_index = ntohl (other_table_index);
11608   mp->is_input = (u8) is_input;
11609
11610   S (mp);
11611   W (ret);
11612   return ret;
11613 }
11614
11615 static int
11616 api_set_ipfix_exporter (vat_main_t * vam)
11617 {
11618   unformat_input_t *i = vam->input;
11619   vl_api_set_ipfix_exporter_t *mp;
11620   ip4_address_t collector_address;
11621   u8 collector_address_set = 0;
11622   u32 collector_port = ~0;
11623   ip4_address_t src_address;
11624   u8 src_address_set = 0;
11625   u32 vrf_id = ~0;
11626   u32 path_mtu = ~0;
11627   u32 template_interval = ~0;
11628   u8 udp_checksum = 0;
11629   int ret;
11630
11631   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11632     {
11633       if (unformat (i, "collector_address %U", unformat_ip4_address,
11634                     &collector_address))
11635         collector_address_set = 1;
11636       else if (unformat (i, "collector_port %d", &collector_port))
11637         ;
11638       else if (unformat (i, "src_address %U", unformat_ip4_address,
11639                          &src_address))
11640         src_address_set = 1;
11641       else if (unformat (i, "vrf_id %d", &vrf_id))
11642         ;
11643       else if (unformat (i, "path_mtu %d", &path_mtu))
11644         ;
11645       else if (unformat (i, "template_interval %d", &template_interval))
11646         ;
11647       else if (unformat (i, "udp_checksum"))
11648         udp_checksum = 1;
11649       else
11650         break;
11651     }
11652
11653   if (collector_address_set == 0)
11654     {
11655       errmsg ("collector_address required");
11656       return -99;
11657     }
11658
11659   if (src_address_set == 0)
11660     {
11661       errmsg ("src_address required");
11662       return -99;
11663     }
11664
11665   M (SET_IPFIX_EXPORTER, mp);
11666
11667   memcpy (mp->collector_address, collector_address.data,
11668           sizeof (collector_address.data));
11669   mp->collector_port = htons ((u16) collector_port);
11670   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11671   mp->vrf_id = htonl (vrf_id);
11672   mp->path_mtu = htonl (path_mtu);
11673   mp->template_interval = htonl (template_interval);
11674   mp->udp_checksum = udp_checksum;
11675
11676   S (mp);
11677   W (ret);
11678   return ret;
11679 }
11680
11681 static int
11682 api_set_ipfix_classify_stream (vat_main_t * vam)
11683 {
11684   unformat_input_t *i = vam->input;
11685   vl_api_set_ipfix_classify_stream_t *mp;
11686   u32 domain_id = 0;
11687   u32 src_port = UDP_DST_PORT_ipfix;
11688   int ret;
11689
11690   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11691     {
11692       if (unformat (i, "domain %d", &domain_id))
11693         ;
11694       else if (unformat (i, "src_port %d", &src_port))
11695         ;
11696       else
11697         {
11698           errmsg ("unknown input `%U'", format_unformat_error, i);
11699           return -99;
11700         }
11701     }
11702
11703   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11704
11705   mp->domain_id = htonl (domain_id);
11706   mp->src_port = htons ((u16) src_port);
11707
11708   S (mp);
11709   W (ret);
11710   return ret;
11711 }
11712
11713 static int
11714 api_ipfix_classify_table_add_del (vat_main_t * vam)
11715 {
11716   unformat_input_t *i = vam->input;
11717   vl_api_ipfix_classify_table_add_del_t *mp;
11718   int is_add = -1;
11719   u32 classify_table_index = ~0;
11720   u8 ip_version = 0;
11721   u8 transport_protocol = 255;
11722   int ret;
11723
11724   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11725     {
11726       if (unformat (i, "add"))
11727         is_add = 1;
11728       else if (unformat (i, "del"))
11729         is_add = 0;
11730       else if (unformat (i, "table %d", &classify_table_index))
11731         ;
11732       else if (unformat (i, "ip4"))
11733         ip_version = 4;
11734       else if (unformat (i, "ip6"))
11735         ip_version = 6;
11736       else if (unformat (i, "tcp"))
11737         transport_protocol = 6;
11738       else if (unformat (i, "udp"))
11739         transport_protocol = 17;
11740       else
11741         {
11742           errmsg ("unknown input `%U'", format_unformat_error, i);
11743           return -99;
11744         }
11745     }
11746
11747   if (is_add == -1)
11748     {
11749       errmsg ("expecting: add|del");
11750       return -99;
11751     }
11752   if (classify_table_index == ~0)
11753     {
11754       errmsg ("classifier table not specified");
11755       return -99;
11756     }
11757   if (ip_version == 0)
11758     {
11759       errmsg ("IP version not specified");
11760       return -99;
11761     }
11762
11763   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11764
11765   mp->is_add = is_add;
11766   mp->table_id = htonl (classify_table_index);
11767   mp->ip_version = ip_version;
11768   mp->transport_protocol = transport_protocol;
11769
11770   S (mp);
11771   W (ret);
11772   return ret;
11773 }
11774
11775 static int
11776 api_get_node_index (vat_main_t * vam)
11777 {
11778   unformat_input_t *i = vam->input;
11779   vl_api_get_node_index_t *mp;
11780   u8 *name = 0;
11781   int ret;
11782
11783   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11784     {
11785       if (unformat (i, "node %s", &name))
11786         ;
11787       else
11788         break;
11789     }
11790   if (name == 0)
11791     {
11792       errmsg ("node name required");
11793       return -99;
11794     }
11795   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11796     {
11797       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11798       return -99;
11799     }
11800
11801   M (GET_NODE_INDEX, mp);
11802   clib_memcpy (mp->node_name, name, vec_len (name));
11803   vec_free (name);
11804
11805   S (mp);
11806   W (ret);
11807   return ret;
11808 }
11809
11810 static int
11811 api_get_next_index (vat_main_t * vam)
11812 {
11813   unformat_input_t *i = vam->input;
11814   vl_api_get_next_index_t *mp;
11815   u8 *node_name = 0, *next_node_name = 0;
11816   int ret;
11817
11818   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11819     {
11820       if (unformat (i, "node-name %s", &node_name))
11821         ;
11822       else if (unformat (i, "next-node-name %s", &next_node_name))
11823         break;
11824     }
11825
11826   if (node_name == 0)
11827     {
11828       errmsg ("node name required");
11829       return -99;
11830     }
11831   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11832     {
11833       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11834       return -99;
11835     }
11836
11837   if (next_node_name == 0)
11838     {
11839       errmsg ("next node name required");
11840       return -99;
11841     }
11842   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11843     {
11844       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11845       return -99;
11846     }
11847
11848   M (GET_NEXT_INDEX, mp);
11849   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11850   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11851   vec_free (node_name);
11852   vec_free (next_node_name);
11853
11854   S (mp);
11855   W (ret);
11856   return ret;
11857 }
11858
11859 static int
11860 api_add_node_next (vat_main_t * vam)
11861 {
11862   unformat_input_t *i = vam->input;
11863   vl_api_add_node_next_t *mp;
11864   u8 *name = 0;
11865   u8 *next = 0;
11866   int ret;
11867
11868   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11869     {
11870       if (unformat (i, "node %s", &name))
11871         ;
11872       else if (unformat (i, "next %s", &next))
11873         ;
11874       else
11875         break;
11876     }
11877   if (name == 0)
11878     {
11879       errmsg ("node name required");
11880       return -99;
11881     }
11882   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11883     {
11884       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11885       return -99;
11886     }
11887   if (next == 0)
11888     {
11889       errmsg ("next node required");
11890       return -99;
11891     }
11892   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11893     {
11894       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11895       return -99;
11896     }
11897
11898   M (ADD_NODE_NEXT, mp);
11899   clib_memcpy (mp->node_name, name, vec_len (name));
11900   clib_memcpy (mp->next_name, next, vec_len (next));
11901   vec_free (name);
11902   vec_free (next);
11903
11904   S (mp);
11905   W (ret);
11906   return ret;
11907 }
11908
11909 static int
11910 api_l2tpv3_create_tunnel (vat_main_t * vam)
11911 {
11912   unformat_input_t *i = vam->input;
11913   ip6_address_t client_address, our_address;
11914   int client_address_set = 0;
11915   int our_address_set = 0;
11916   u32 local_session_id = 0;
11917   u32 remote_session_id = 0;
11918   u64 local_cookie = 0;
11919   u64 remote_cookie = 0;
11920   u8 l2_sublayer_present = 0;
11921   vl_api_l2tpv3_create_tunnel_t *mp;
11922   int ret;
11923
11924   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11925     {
11926       if (unformat (i, "client_address %U", unformat_ip6_address,
11927                     &client_address))
11928         client_address_set = 1;
11929       else if (unformat (i, "our_address %U", unformat_ip6_address,
11930                          &our_address))
11931         our_address_set = 1;
11932       else if (unformat (i, "local_session_id %d", &local_session_id))
11933         ;
11934       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11935         ;
11936       else if (unformat (i, "local_cookie %lld", &local_cookie))
11937         ;
11938       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11939         ;
11940       else if (unformat (i, "l2-sublayer-present"))
11941         l2_sublayer_present = 1;
11942       else
11943         break;
11944     }
11945
11946   if (client_address_set == 0)
11947     {
11948       errmsg ("client_address required");
11949       return -99;
11950     }
11951
11952   if (our_address_set == 0)
11953     {
11954       errmsg ("our_address required");
11955       return -99;
11956     }
11957
11958   M (L2TPV3_CREATE_TUNNEL, mp);
11959
11960   clib_memcpy (mp->client_address, client_address.as_u8,
11961                sizeof (mp->client_address));
11962
11963   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
11964
11965   mp->local_session_id = ntohl (local_session_id);
11966   mp->remote_session_id = ntohl (remote_session_id);
11967   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11968   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11969   mp->l2_sublayer_present = l2_sublayer_present;
11970   mp->is_ipv6 = 1;
11971
11972   S (mp);
11973   W (ret);
11974   return ret;
11975 }
11976
11977 static int
11978 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11979 {
11980   unformat_input_t *i = vam->input;
11981   u32 sw_if_index;
11982   u8 sw_if_index_set = 0;
11983   u64 new_local_cookie = 0;
11984   u64 new_remote_cookie = 0;
11985   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11986   int ret;
11987
11988   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11989     {
11990       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11991         sw_if_index_set = 1;
11992       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11993         sw_if_index_set = 1;
11994       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11995         ;
11996       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11997         ;
11998       else
11999         break;
12000     }
12001
12002   if (sw_if_index_set == 0)
12003     {
12004       errmsg ("missing interface name or sw_if_index");
12005       return -99;
12006     }
12007
12008   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12009
12010   mp->sw_if_index = ntohl (sw_if_index);
12011   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12012   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12013
12014   S (mp);
12015   W (ret);
12016   return ret;
12017 }
12018
12019 static int
12020 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12021 {
12022   unformat_input_t *i = vam->input;
12023   vl_api_l2tpv3_interface_enable_disable_t *mp;
12024   u32 sw_if_index;
12025   u8 sw_if_index_set = 0;
12026   u8 enable_disable = 1;
12027   int ret;
12028
12029   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12030     {
12031       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12032         sw_if_index_set = 1;
12033       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12034         sw_if_index_set = 1;
12035       else if (unformat (i, "enable"))
12036         enable_disable = 1;
12037       else if (unformat (i, "disable"))
12038         enable_disable = 0;
12039       else
12040         break;
12041     }
12042
12043   if (sw_if_index_set == 0)
12044     {
12045       errmsg ("missing interface name or sw_if_index");
12046       return -99;
12047     }
12048
12049   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12050
12051   mp->sw_if_index = ntohl (sw_if_index);
12052   mp->enable_disable = enable_disable;
12053
12054   S (mp);
12055   W (ret);
12056   return ret;
12057 }
12058
12059 static int
12060 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12061 {
12062   unformat_input_t *i = vam->input;
12063   vl_api_l2tpv3_set_lookup_key_t *mp;
12064   u8 key = ~0;
12065   int ret;
12066
12067   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12068     {
12069       if (unformat (i, "lookup_v6_src"))
12070         key = L2T_LOOKUP_SRC_ADDRESS;
12071       else if (unformat (i, "lookup_v6_dst"))
12072         key = L2T_LOOKUP_DST_ADDRESS;
12073       else if (unformat (i, "lookup_session_id"))
12074         key = L2T_LOOKUP_SESSION_ID;
12075       else
12076         break;
12077     }
12078
12079   if (key == (u8) ~ 0)
12080     {
12081       errmsg ("l2tp session lookup key unset");
12082       return -99;
12083     }
12084
12085   M (L2TPV3_SET_LOOKUP_KEY, mp);
12086
12087   mp->key = key;
12088
12089   S (mp);
12090   W (ret);
12091   return ret;
12092 }
12093
12094 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12095   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12096 {
12097   vat_main_t *vam = &vat_main;
12098
12099   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12100          format_ip6_address, mp->our_address,
12101          format_ip6_address, mp->client_address,
12102          clib_net_to_host_u32 (mp->sw_if_index));
12103
12104   print (vam->ofp,
12105          "   local cookies %016llx %016llx remote cookie %016llx",
12106          clib_net_to_host_u64 (mp->local_cookie[0]),
12107          clib_net_to_host_u64 (mp->local_cookie[1]),
12108          clib_net_to_host_u64 (mp->remote_cookie));
12109
12110   print (vam->ofp, "   local session-id %d remote session-id %d",
12111          clib_net_to_host_u32 (mp->local_session_id),
12112          clib_net_to_host_u32 (mp->remote_session_id));
12113
12114   print (vam->ofp, "   l2 specific sublayer %s\n",
12115          mp->l2_sublayer_present ? "preset" : "absent");
12116
12117 }
12118
12119 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12120   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12121 {
12122   vat_main_t *vam = &vat_main;
12123   vat_json_node_t *node = NULL;
12124   struct in6_addr addr;
12125
12126   if (VAT_JSON_ARRAY != vam->json_tree.type)
12127     {
12128       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12129       vat_json_init_array (&vam->json_tree);
12130     }
12131   node = vat_json_array_add (&vam->json_tree);
12132
12133   vat_json_init_object (node);
12134
12135   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12136   vat_json_object_add_ip6 (node, "our_address", addr);
12137   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12138   vat_json_object_add_ip6 (node, "client_address", addr);
12139
12140   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12141   vat_json_init_array (lc);
12142   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12143   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12144   vat_json_object_add_uint (node, "remote_cookie",
12145                             clib_net_to_host_u64 (mp->remote_cookie));
12146
12147   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12148   vat_json_object_add_uint (node, "local_session_id",
12149                             clib_net_to_host_u32 (mp->local_session_id));
12150   vat_json_object_add_uint (node, "remote_session_id",
12151                             clib_net_to_host_u32 (mp->remote_session_id));
12152   vat_json_object_add_string_copy (node, "l2_sublayer",
12153                                    mp->l2_sublayer_present ? (u8 *) "present"
12154                                    : (u8 *) "absent");
12155 }
12156
12157 static int
12158 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12159 {
12160   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12161   vl_api_control_ping_t *mp_ping;
12162   int ret;
12163
12164   /* Get list of l2tpv3-tunnel interfaces */
12165   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12166   S (mp);
12167
12168   /* Use a control ping for synchronization */
12169   MPING (CONTROL_PING, mp_ping);
12170   S (mp_ping);
12171
12172   W (ret);
12173   return ret;
12174 }
12175
12176
12177 static void vl_api_sw_interface_tap_v2_details_t_handler
12178   (vl_api_sw_interface_tap_v2_details_t * mp)
12179 {
12180   vat_main_t *vam = &vat_main;
12181
12182   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12183                     mp->host_ip4_prefix_len);
12184   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12185                     mp->host_ip6_prefix_len);
12186
12187   print (vam->ofp,
12188          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
12189          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12190          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12191          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12192          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
12193
12194   vec_free (ip4);
12195   vec_free (ip6);
12196 }
12197
12198 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12199   (vl_api_sw_interface_tap_v2_details_t * mp)
12200 {
12201   vat_main_t *vam = &vat_main;
12202   vat_json_node_t *node = NULL;
12203
12204   if (VAT_JSON_ARRAY != vam->json_tree.type)
12205     {
12206       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12207       vat_json_init_array (&vam->json_tree);
12208     }
12209   node = vat_json_array_add (&vam->json_tree);
12210
12211   vat_json_init_object (node);
12212   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12213   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12214   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
12215   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12216   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12217   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12218   vat_json_object_add_string_copy (node, "host_mac_addr",
12219                                    format (0, "%U", format_ethernet_address,
12220                                            &mp->host_mac_addr));
12221   vat_json_object_add_string_copy (node, "host_namespace",
12222                                    mp->host_namespace);
12223   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12224   vat_json_object_add_string_copy (node, "host_ip4_addr",
12225                                    format (0, "%U/%d", format_ip4_address,
12226                                            mp->host_ip4_addr,
12227                                            mp->host_ip4_prefix_len));
12228   vat_json_object_add_string_copy (node, "host_ip6_addr",
12229                                    format (0, "%U/%d", format_ip6_address,
12230                                            mp->host_ip6_addr,
12231                                            mp->host_ip6_prefix_len));
12232
12233 }
12234
12235 static int
12236 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12237 {
12238   vl_api_sw_interface_tap_v2_dump_t *mp;
12239   vl_api_control_ping_t *mp_ping;
12240   int ret;
12241
12242   print (vam->ofp,
12243          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12244          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12245          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12246          "host_ip6_addr");
12247
12248   /* Get list of tap interfaces */
12249   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12250   S (mp);
12251
12252   /* Use a control ping for synchronization */
12253   MPING (CONTROL_PING, mp_ping);
12254   S (mp_ping);
12255
12256   W (ret);
12257   return ret;
12258 }
12259
12260 static void vl_api_sw_interface_virtio_pci_details_t_handler
12261   (vl_api_sw_interface_virtio_pci_details_t * mp)
12262 {
12263   vat_main_t *vam = &vat_main;
12264
12265   typedef union
12266   {
12267     struct
12268     {
12269       u16 domain;
12270       u8 bus;
12271       u8 slot:5;
12272       u8 function:3;
12273     };
12274     u32 as_u32;
12275   } pci_addr_t;
12276   pci_addr_t addr;
12277   addr.as_u32 = ntohl (mp->pci_addr);
12278   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
12279                          addr.slot, addr.function);
12280
12281   print (vam->ofp,
12282          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
12283          pci_addr, ntohl (mp->sw_if_index),
12284          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12285          format_ethernet_address, mp->mac_addr,
12286          clib_net_to_host_u64 (mp->features));
12287   vec_free (pci_addr);
12288 }
12289
12290 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
12291   (vl_api_sw_interface_virtio_pci_details_t * mp)
12292 {
12293   vat_main_t *vam = &vat_main;
12294   vat_json_node_t *node = NULL;
12295
12296   if (VAT_JSON_ARRAY != vam->json_tree.type)
12297     {
12298       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12299       vat_json_init_array (&vam->json_tree);
12300     }
12301   node = vat_json_array_add (&vam->json_tree);
12302
12303   vat_json_init_object (node);
12304   vat_json_object_add_uint (node, "pci-addr", ntohl (mp->pci_addr));
12305   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12306   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12307   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12308   vat_json_object_add_uint (node, "features",
12309                             clib_net_to_host_u64 (mp->features));
12310   vat_json_object_add_string_copy (node, "mac_addr",
12311                                    format (0, "%U", format_ethernet_address,
12312                                            &mp->mac_addr));
12313 }
12314
12315 static int
12316 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
12317 {
12318   vl_api_sw_interface_virtio_pci_dump_t *mp;
12319   vl_api_control_ping_t *mp_ping;
12320   int ret;
12321
12322   print (vam->ofp,
12323          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
12324          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
12325          "mac_addr", "features");
12326
12327   /* Get list of tap interfaces */
12328   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
12329   S (mp);
12330
12331   /* Use a control ping for synchronization */
12332   MPING (CONTROL_PING, mp_ping);
12333   S (mp_ping);
12334
12335   W (ret);
12336   return ret;
12337 }
12338
12339 static int
12340 api_vxlan_offload_rx (vat_main_t * vam)
12341 {
12342   unformat_input_t *line_input = vam->input;
12343   vl_api_vxlan_offload_rx_t *mp;
12344   u32 hw_if_index = ~0, rx_if_index = ~0;
12345   u8 is_add = 1;
12346   int ret;
12347
12348   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12349     {
12350       if (unformat (line_input, "del"))
12351         is_add = 0;
12352       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
12353                          &hw_if_index))
12354         ;
12355       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
12356         ;
12357       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
12358                          &rx_if_index))
12359         ;
12360       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
12361         ;
12362       else
12363         {
12364           errmsg ("parse error '%U'", format_unformat_error, line_input);
12365           return -99;
12366         }
12367     }
12368
12369   if (hw_if_index == ~0)
12370     {
12371       errmsg ("no hw interface");
12372       return -99;
12373     }
12374
12375   if (rx_if_index == ~0)
12376     {
12377       errmsg ("no rx tunnel");
12378       return -99;
12379     }
12380
12381   M (VXLAN_OFFLOAD_RX, mp);
12382
12383   mp->hw_if_index = ntohl (hw_if_index);
12384   mp->sw_if_index = ntohl (rx_if_index);
12385   mp->enable = is_add;
12386
12387   S (mp);
12388   W (ret);
12389   return ret;
12390 }
12391
12392 static uword unformat_vxlan_decap_next
12393   (unformat_input_t * input, va_list * args)
12394 {
12395   u32 *result = va_arg (*args, u32 *);
12396   u32 tmp;
12397
12398   if (unformat (input, "l2"))
12399     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12400   else if (unformat (input, "%d", &tmp))
12401     *result = tmp;
12402   else
12403     return 0;
12404   return 1;
12405 }
12406
12407 static int
12408 api_vxlan_add_del_tunnel (vat_main_t * vam)
12409 {
12410   unformat_input_t *line_input = vam->input;
12411   vl_api_vxlan_add_del_tunnel_t *mp;
12412   ip46_address_t src, dst;
12413   u8 is_add = 1;
12414   u8 ipv4_set = 0, ipv6_set = 0;
12415   u8 src_set = 0;
12416   u8 dst_set = 0;
12417   u8 grp_set = 0;
12418   u32 instance = ~0;
12419   u32 mcast_sw_if_index = ~0;
12420   u32 encap_vrf_id = 0;
12421   u32 decap_next_index = ~0;
12422   u32 vni = 0;
12423   int ret;
12424
12425   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12426   clib_memset (&src, 0, sizeof src);
12427   clib_memset (&dst, 0, sizeof dst);
12428
12429   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12430     {
12431       if (unformat (line_input, "del"))
12432         is_add = 0;
12433       else if (unformat (line_input, "instance %d", &instance))
12434         ;
12435       else
12436         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12437         {
12438           ipv4_set = 1;
12439           src_set = 1;
12440         }
12441       else
12442         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12443         {
12444           ipv4_set = 1;
12445           dst_set = 1;
12446         }
12447       else
12448         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12449         {
12450           ipv6_set = 1;
12451           src_set = 1;
12452         }
12453       else
12454         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12455         {
12456           ipv6_set = 1;
12457           dst_set = 1;
12458         }
12459       else if (unformat (line_input, "group %U %U",
12460                          unformat_ip4_address, &dst.ip4,
12461                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12462         {
12463           grp_set = dst_set = 1;
12464           ipv4_set = 1;
12465         }
12466       else if (unformat (line_input, "group %U",
12467                          unformat_ip4_address, &dst.ip4))
12468         {
12469           grp_set = dst_set = 1;
12470           ipv4_set = 1;
12471         }
12472       else if (unformat (line_input, "group %U %U",
12473                          unformat_ip6_address, &dst.ip6,
12474                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12475         {
12476           grp_set = dst_set = 1;
12477           ipv6_set = 1;
12478         }
12479       else if (unformat (line_input, "group %U",
12480                          unformat_ip6_address, &dst.ip6))
12481         {
12482           grp_set = dst_set = 1;
12483           ipv6_set = 1;
12484         }
12485       else
12486         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12487         ;
12488       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12489         ;
12490       else if (unformat (line_input, "decap-next %U",
12491                          unformat_vxlan_decap_next, &decap_next_index))
12492         ;
12493       else if (unformat (line_input, "vni %d", &vni))
12494         ;
12495       else
12496         {
12497           errmsg ("parse error '%U'", format_unformat_error, line_input);
12498           return -99;
12499         }
12500     }
12501
12502   if (src_set == 0)
12503     {
12504       errmsg ("tunnel src address not specified");
12505       return -99;
12506     }
12507   if (dst_set == 0)
12508     {
12509       errmsg ("tunnel dst address not specified");
12510       return -99;
12511     }
12512
12513   if (grp_set && !ip46_address_is_multicast (&dst))
12514     {
12515       errmsg ("tunnel group address not multicast");
12516       return -99;
12517     }
12518   if (grp_set && mcast_sw_if_index == ~0)
12519     {
12520       errmsg ("tunnel nonexistent multicast device");
12521       return -99;
12522     }
12523   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12524     {
12525       errmsg ("tunnel dst address must be unicast");
12526       return -99;
12527     }
12528
12529
12530   if (ipv4_set && ipv6_set)
12531     {
12532       errmsg ("both IPv4 and IPv6 addresses specified");
12533       return -99;
12534     }
12535
12536   if ((vni == 0) || (vni >> 24))
12537     {
12538       errmsg ("vni not specified or out of range");
12539       return -99;
12540     }
12541
12542   M (VXLAN_ADD_DEL_TUNNEL, mp);
12543
12544   if (ipv6_set)
12545     {
12546       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12547       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12548     }
12549   else
12550     {
12551       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12552       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12553     }
12554
12555   mp->instance = htonl (instance);
12556   mp->encap_vrf_id = ntohl (encap_vrf_id);
12557   mp->decap_next_index = ntohl (decap_next_index);
12558   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12559   mp->vni = ntohl (vni);
12560   mp->is_add = is_add;
12561   mp->is_ipv6 = ipv6_set;
12562
12563   S (mp);
12564   W (ret);
12565   return ret;
12566 }
12567
12568 static void vl_api_vxlan_tunnel_details_t_handler
12569   (vl_api_vxlan_tunnel_details_t * mp)
12570 {
12571   vat_main_t *vam = &vat_main;
12572   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12573   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12574
12575   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
12576          ntohl (mp->sw_if_index),
12577          ntohl (mp->instance),
12578          format_ip46_address, &src, IP46_TYPE_ANY,
12579          format_ip46_address, &dst, IP46_TYPE_ANY,
12580          ntohl (mp->encap_vrf_id),
12581          ntohl (mp->decap_next_index), ntohl (mp->vni),
12582          ntohl (mp->mcast_sw_if_index));
12583 }
12584
12585 static void vl_api_vxlan_tunnel_details_t_handler_json
12586   (vl_api_vxlan_tunnel_details_t * mp)
12587 {
12588   vat_main_t *vam = &vat_main;
12589   vat_json_node_t *node = NULL;
12590
12591   if (VAT_JSON_ARRAY != vam->json_tree.type)
12592     {
12593       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12594       vat_json_init_array (&vam->json_tree);
12595     }
12596   node = vat_json_array_add (&vam->json_tree);
12597
12598   vat_json_init_object (node);
12599   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12600
12601   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
12602
12603   if (mp->is_ipv6)
12604     {
12605       struct in6_addr ip6;
12606
12607       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12608       vat_json_object_add_ip6 (node, "src_address", ip6);
12609       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12610       vat_json_object_add_ip6 (node, "dst_address", ip6);
12611     }
12612   else
12613     {
12614       struct in_addr ip4;
12615
12616       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12617       vat_json_object_add_ip4 (node, "src_address", ip4);
12618       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12619       vat_json_object_add_ip4 (node, "dst_address", ip4);
12620     }
12621   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12622   vat_json_object_add_uint (node, "decap_next_index",
12623                             ntohl (mp->decap_next_index));
12624   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12625   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12626   vat_json_object_add_uint (node, "mcast_sw_if_index",
12627                             ntohl (mp->mcast_sw_if_index));
12628 }
12629
12630 static int
12631 api_vxlan_tunnel_dump (vat_main_t * vam)
12632 {
12633   unformat_input_t *i = vam->input;
12634   vl_api_vxlan_tunnel_dump_t *mp;
12635   vl_api_control_ping_t *mp_ping;
12636   u32 sw_if_index;
12637   u8 sw_if_index_set = 0;
12638   int ret;
12639
12640   /* Parse args required to build the message */
12641   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12642     {
12643       if (unformat (i, "sw_if_index %d", &sw_if_index))
12644         sw_if_index_set = 1;
12645       else
12646         break;
12647     }
12648
12649   if (sw_if_index_set == 0)
12650     {
12651       sw_if_index = ~0;
12652     }
12653
12654   if (!vam->json_output)
12655     {
12656       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
12657              "sw_if_index", "instance", "src_address", "dst_address",
12658              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12659     }
12660
12661   /* Get list of vxlan-tunnel interfaces */
12662   M (VXLAN_TUNNEL_DUMP, mp);
12663
12664   mp->sw_if_index = htonl (sw_if_index);
12665
12666   S (mp);
12667
12668   /* Use a control ping for synchronization */
12669   MPING (CONTROL_PING, mp_ping);
12670   S (mp_ping);
12671
12672   W (ret);
12673   return ret;
12674 }
12675
12676 static uword unformat_geneve_decap_next
12677   (unformat_input_t * input, va_list * args)
12678 {
12679   u32 *result = va_arg (*args, u32 *);
12680   u32 tmp;
12681
12682   if (unformat (input, "l2"))
12683     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12684   else if (unformat (input, "%d", &tmp))
12685     *result = tmp;
12686   else
12687     return 0;
12688   return 1;
12689 }
12690
12691 static int
12692 api_geneve_add_del_tunnel (vat_main_t * vam)
12693 {
12694   unformat_input_t *line_input = vam->input;
12695   vl_api_geneve_add_del_tunnel_t *mp;
12696   ip46_address_t src, dst;
12697   u8 is_add = 1;
12698   u8 ipv4_set = 0, ipv6_set = 0;
12699   u8 src_set = 0;
12700   u8 dst_set = 0;
12701   u8 grp_set = 0;
12702   u32 mcast_sw_if_index = ~0;
12703   u32 encap_vrf_id = 0;
12704   u32 decap_next_index = ~0;
12705   u32 vni = 0;
12706   int ret;
12707
12708   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12709   clib_memset (&src, 0, sizeof src);
12710   clib_memset (&dst, 0, sizeof dst);
12711
12712   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12713     {
12714       if (unformat (line_input, "del"))
12715         is_add = 0;
12716       else
12717         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12718         {
12719           ipv4_set = 1;
12720           src_set = 1;
12721         }
12722       else
12723         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12724         {
12725           ipv4_set = 1;
12726           dst_set = 1;
12727         }
12728       else
12729         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12730         {
12731           ipv6_set = 1;
12732           src_set = 1;
12733         }
12734       else
12735         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12736         {
12737           ipv6_set = 1;
12738           dst_set = 1;
12739         }
12740       else if (unformat (line_input, "group %U %U",
12741                          unformat_ip4_address, &dst.ip4,
12742                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12743         {
12744           grp_set = dst_set = 1;
12745           ipv4_set = 1;
12746         }
12747       else if (unformat (line_input, "group %U",
12748                          unformat_ip4_address, &dst.ip4))
12749         {
12750           grp_set = dst_set = 1;
12751           ipv4_set = 1;
12752         }
12753       else if (unformat (line_input, "group %U %U",
12754                          unformat_ip6_address, &dst.ip6,
12755                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12756         {
12757           grp_set = dst_set = 1;
12758           ipv6_set = 1;
12759         }
12760       else if (unformat (line_input, "group %U",
12761                          unformat_ip6_address, &dst.ip6))
12762         {
12763           grp_set = dst_set = 1;
12764           ipv6_set = 1;
12765         }
12766       else
12767         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12768         ;
12769       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12770         ;
12771       else if (unformat (line_input, "decap-next %U",
12772                          unformat_geneve_decap_next, &decap_next_index))
12773         ;
12774       else if (unformat (line_input, "vni %d", &vni))
12775         ;
12776       else
12777         {
12778           errmsg ("parse error '%U'", format_unformat_error, line_input);
12779           return -99;
12780         }
12781     }
12782
12783   if (src_set == 0)
12784     {
12785       errmsg ("tunnel src address not specified");
12786       return -99;
12787     }
12788   if (dst_set == 0)
12789     {
12790       errmsg ("tunnel dst address not specified");
12791       return -99;
12792     }
12793
12794   if (grp_set && !ip46_address_is_multicast (&dst))
12795     {
12796       errmsg ("tunnel group address not multicast");
12797       return -99;
12798     }
12799   if (grp_set && mcast_sw_if_index == ~0)
12800     {
12801       errmsg ("tunnel nonexistent multicast device");
12802       return -99;
12803     }
12804   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12805     {
12806       errmsg ("tunnel dst address must be unicast");
12807       return -99;
12808     }
12809
12810
12811   if (ipv4_set && ipv6_set)
12812     {
12813       errmsg ("both IPv4 and IPv6 addresses specified");
12814       return -99;
12815     }
12816
12817   if ((vni == 0) || (vni >> 24))
12818     {
12819       errmsg ("vni not specified or out of range");
12820       return -99;
12821     }
12822
12823   M (GENEVE_ADD_DEL_TUNNEL, mp);
12824
12825   if (ipv6_set)
12826     {
12827       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12828       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12829     }
12830   else
12831     {
12832       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12833       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12834     }
12835   mp->encap_vrf_id = ntohl (encap_vrf_id);
12836   mp->decap_next_index = ntohl (decap_next_index);
12837   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12838   mp->vni = ntohl (vni);
12839   mp->is_add = is_add;
12840   mp->is_ipv6 = ipv6_set;
12841
12842   S (mp);
12843   W (ret);
12844   return ret;
12845 }
12846
12847 static void vl_api_geneve_tunnel_details_t_handler
12848   (vl_api_geneve_tunnel_details_t * mp)
12849 {
12850   vat_main_t *vam = &vat_main;
12851   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12852   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12853
12854   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12855          ntohl (mp->sw_if_index),
12856          format_ip46_address, &src, IP46_TYPE_ANY,
12857          format_ip46_address, &dst, IP46_TYPE_ANY,
12858          ntohl (mp->encap_vrf_id),
12859          ntohl (mp->decap_next_index), ntohl (mp->vni),
12860          ntohl (mp->mcast_sw_if_index));
12861 }
12862
12863 static void vl_api_geneve_tunnel_details_t_handler_json
12864   (vl_api_geneve_tunnel_details_t * mp)
12865 {
12866   vat_main_t *vam = &vat_main;
12867   vat_json_node_t *node = NULL;
12868
12869   if (VAT_JSON_ARRAY != vam->json_tree.type)
12870     {
12871       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12872       vat_json_init_array (&vam->json_tree);
12873     }
12874   node = vat_json_array_add (&vam->json_tree);
12875
12876   vat_json_init_object (node);
12877   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12878   if (mp->is_ipv6)
12879     {
12880       struct in6_addr ip6;
12881
12882       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12883       vat_json_object_add_ip6 (node, "src_address", ip6);
12884       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12885       vat_json_object_add_ip6 (node, "dst_address", ip6);
12886     }
12887   else
12888     {
12889       struct in_addr ip4;
12890
12891       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12892       vat_json_object_add_ip4 (node, "src_address", ip4);
12893       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12894       vat_json_object_add_ip4 (node, "dst_address", ip4);
12895     }
12896   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12897   vat_json_object_add_uint (node, "decap_next_index",
12898                             ntohl (mp->decap_next_index));
12899   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12900   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12901   vat_json_object_add_uint (node, "mcast_sw_if_index",
12902                             ntohl (mp->mcast_sw_if_index));
12903 }
12904
12905 static int
12906 api_geneve_tunnel_dump (vat_main_t * vam)
12907 {
12908   unformat_input_t *i = vam->input;
12909   vl_api_geneve_tunnel_dump_t *mp;
12910   vl_api_control_ping_t *mp_ping;
12911   u32 sw_if_index;
12912   u8 sw_if_index_set = 0;
12913   int ret;
12914
12915   /* Parse args required to build the message */
12916   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12917     {
12918       if (unformat (i, "sw_if_index %d", &sw_if_index))
12919         sw_if_index_set = 1;
12920       else
12921         break;
12922     }
12923
12924   if (sw_if_index_set == 0)
12925     {
12926       sw_if_index = ~0;
12927     }
12928
12929   if (!vam->json_output)
12930     {
12931       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12932              "sw_if_index", "local_address", "remote_address",
12933              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12934     }
12935
12936   /* Get list of geneve-tunnel interfaces */
12937   M (GENEVE_TUNNEL_DUMP, mp);
12938
12939   mp->sw_if_index = htonl (sw_if_index);
12940
12941   S (mp);
12942
12943   /* Use a control ping for synchronization */
12944   M (CONTROL_PING, mp_ping);
12945   S (mp_ping);
12946
12947   W (ret);
12948   return ret;
12949 }
12950
12951 static int
12952 api_gre_tunnel_add_del (vat_main_t * vam)
12953 {
12954   unformat_input_t *line_input = vam->input;
12955   vl_api_address_t src = { }, dst =
12956   {
12957   };
12958   vl_api_gre_tunnel_add_del_t *mp;
12959   vl_api_gre_tunnel_type_t t_type;
12960   u8 is_add = 1;
12961   u8 src_set = 0;
12962   u8 dst_set = 0;
12963   u32 outer_fib_id = 0;
12964   u32 session_id = 0;
12965   u32 instance = ~0;
12966   int ret;
12967
12968   t_type = GRE_API_TUNNEL_TYPE_L3;
12969
12970   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12971     {
12972       if (unformat (line_input, "del"))
12973         is_add = 0;
12974       else if (unformat (line_input, "instance %d", &instance))
12975         ;
12976       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
12977         {
12978           src_set = 1;
12979         }
12980       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
12981         {
12982           dst_set = 1;
12983         }
12984       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
12985         ;
12986       else if (unformat (line_input, "teb"))
12987         t_type = GRE_API_TUNNEL_TYPE_TEB;
12988       else if (unformat (line_input, "erspan %d", &session_id))
12989         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
12990       else
12991         {
12992           errmsg ("parse error '%U'", format_unformat_error, line_input);
12993           return -99;
12994         }
12995     }
12996
12997   if (src_set == 0)
12998     {
12999       errmsg ("tunnel src address not specified");
13000       return -99;
13001     }
13002   if (dst_set == 0)
13003     {
13004       errmsg ("tunnel dst address not specified");
13005       return -99;
13006     }
13007
13008   M (GRE_TUNNEL_ADD_DEL, mp);
13009
13010   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
13011   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
13012
13013   mp->tunnel.instance = htonl (instance);
13014   mp->tunnel.outer_fib_id = htonl (outer_fib_id);
13015   mp->is_add = is_add;
13016   mp->tunnel.session_id = htons ((u16) session_id);
13017   mp->tunnel.type = htonl (t_type);
13018
13019   S (mp);
13020   W (ret);
13021   return ret;
13022 }
13023
13024 static void vl_api_gre_tunnel_details_t_handler
13025   (vl_api_gre_tunnel_details_t * mp)
13026 {
13027   vat_main_t *vam = &vat_main;
13028
13029   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13030          ntohl (mp->tunnel.sw_if_index),
13031          ntohl (mp->tunnel.instance),
13032          format_vl_api_address, &mp->tunnel.src,
13033          format_vl_api_address, &mp->tunnel.dst,
13034          mp->tunnel.type, ntohl (mp->tunnel.outer_fib_id),
13035          ntohl (mp->tunnel.session_id));
13036 }
13037
13038 static void vl_api_gre_tunnel_details_t_handler_json
13039   (vl_api_gre_tunnel_details_t * mp)
13040 {
13041   vat_main_t *vam = &vat_main;
13042   vat_json_node_t *node = NULL;
13043
13044   if (VAT_JSON_ARRAY != vam->json_tree.type)
13045     {
13046       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13047       vat_json_init_array (&vam->json_tree);
13048     }
13049   node = vat_json_array_add (&vam->json_tree);
13050
13051   vat_json_init_object (node);
13052   vat_json_object_add_uint (node, "sw_if_index",
13053                             ntohl (mp->tunnel.sw_if_index));
13054   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
13055
13056   vat_json_object_add_address (node, "src", &mp->tunnel.src);
13057   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
13058   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
13059   vat_json_object_add_uint (node, "outer_fib_id",
13060                             ntohl (mp->tunnel.outer_fib_id));
13061   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
13062 }
13063
13064 static int
13065 api_gre_tunnel_dump (vat_main_t * vam)
13066 {
13067   unformat_input_t *i = vam->input;
13068   vl_api_gre_tunnel_dump_t *mp;
13069   vl_api_control_ping_t *mp_ping;
13070   u32 sw_if_index;
13071   u8 sw_if_index_set = 0;
13072   int ret;
13073
13074   /* Parse args required to build the message */
13075   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13076     {
13077       if (unformat (i, "sw_if_index %d", &sw_if_index))
13078         sw_if_index_set = 1;
13079       else
13080         break;
13081     }
13082
13083   if (sw_if_index_set == 0)
13084     {
13085       sw_if_index = ~0;
13086     }
13087
13088   if (!vam->json_output)
13089     {
13090       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13091              "sw_if_index", "instance", "src_address", "dst_address",
13092              "tunnel_type", "outer_fib_id", "session_id");
13093     }
13094
13095   /* Get list of gre-tunnel interfaces */
13096   M (GRE_TUNNEL_DUMP, mp);
13097
13098   mp->sw_if_index = htonl (sw_if_index);
13099
13100   S (mp);
13101
13102   /* Use a control ping for synchronization */
13103   MPING (CONTROL_PING, mp_ping);
13104   S (mp_ping);
13105
13106   W (ret);
13107   return ret;
13108 }
13109
13110 static int
13111 api_l2_fib_clear_table (vat_main_t * vam)
13112 {
13113 //  unformat_input_t * i = vam->input;
13114   vl_api_l2_fib_clear_table_t *mp;
13115   int ret;
13116
13117   M (L2_FIB_CLEAR_TABLE, mp);
13118
13119   S (mp);
13120   W (ret);
13121   return ret;
13122 }
13123
13124 static int
13125 api_l2_interface_efp_filter (vat_main_t * vam)
13126 {
13127   unformat_input_t *i = vam->input;
13128   vl_api_l2_interface_efp_filter_t *mp;
13129   u32 sw_if_index;
13130   u8 enable = 1;
13131   u8 sw_if_index_set = 0;
13132   int ret;
13133
13134   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13135     {
13136       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13137         sw_if_index_set = 1;
13138       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13139         sw_if_index_set = 1;
13140       else if (unformat (i, "enable"))
13141         enable = 1;
13142       else if (unformat (i, "disable"))
13143         enable = 0;
13144       else
13145         {
13146           clib_warning ("parse error '%U'", format_unformat_error, i);
13147           return -99;
13148         }
13149     }
13150
13151   if (sw_if_index_set == 0)
13152     {
13153       errmsg ("missing sw_if_index");
13154       return -99;
13155     }
13156
13157   M (L2_INTERFACE_EFP_FILTER, mp);
13158
13159   mp->sw_if_index = ntohl (sw_if_index);
13160   mp->enable_disable = enable;
13161
13162   S (mp);
13163   W (ret);
13164   return ret;
13165 }
13166
13167 #define foreach_vtr_op                          \
13168 _("disable",  L2_VTR_DISABLED)                  \
13169 _("push-1",  L2_VTR_PUSH_1)                     \
13170 _("push-2",  L2_VTR_PUSH_2)                     \
13171 _("pop-1",  L2_VTR_POP_1)                       \
13172 _("pop-2",  L2_VTR_POP_2)                       \
13173 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13174 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13175 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13176 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13177
13178 static int
13179 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13180 {
13181   unformat_input_t *i = vam->input;
13182   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13183   u32 sw_if_index;
13184   u8 sw_if_index_set = 0;
13185   u8 vtr_op_set = 0;
13186   u32 vtr_op = 0;
13187   u32 push_dot1q = 1;
13188   u32 tag1 = ~0;
13189   u32 tag2 = ~0;
13190   int ret;
13191
13192   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13193     {
13194       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13195         sw_if_index_set = 1;
13196       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13197         sw_if_index_set = 1;
13198       else if (unformat (i, "vtr_op %d", &vtr_op))
13199         vtr_op_set = 1;
13200 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13201       foreach_vtr_op
13202 #undef _
13203         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13204         ;
13205       else if (unformat (i, "tag1 %d", &tag1))
13206         ;
13207       else if (unformat (i, "tag2 %d", &tag2))
13208         ;
13209       else
13210         {
13211           clib_warning ("parse error '%U'", format_unformat_error, i);
13212           return -99;
13213         }
13214     }
13215
13216   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13217     {
13218       errmsg ("missing vtr operation or sw_if_index");
13219       return -99;
13220     }
13221
13222   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13223   mp->sw_if_index = ntohl (sw_if_index);
13224   mp->vtr_op = ntohl (vtr_op);
13225   mp->push_dot1q = ntohl (push_dot1q);
13226   mp->tag1 = ntohl (tag1);
13227   mp->tag2 = ntohl (tag2);
13228
13229   S (mp);
13230   W (ret);
13231   return ret;
13232 }
13233
13234 static int
13235 api_create_vhost_user_if (vat_main_t * vam)
13236 {
13237   unformat_input_t *i = vam->input;
13238   vl_api_create_vhost_user_if_t *mp;
13239   u8 *file_name;
13240   u8 is_server = 0;
13241   u8 file_name_set = 0;
13242   u32 custom_dev_instance = ~0;
13243   u8 hwaddr[6];
13244   u8 use_custom_mac = 0;
13245   u8 disable_mrg_rxbuf = 0;
13246   u8 disable_indirect_desc = 0;
13247   u8 *tag = 0;
13248   u8 enable_gso = 0;
13249   int ret;
13250
13251   /* Shut up coverity */
13252   clib_memset (hwaddr, 0, sizeof (hwaddr));
13253
13254   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13255     {
13256       if (unformat (i, "socket %s", &file_name))
13257         {
13258           file_name_set = 1;
13259         }
13260       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13261         ;
13262       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13263         use_custom_mac = 1;
13264       else if (unformat (i, "server"))
13265         is_server = 1;
13266       else if (unformat (i, "disable_mrg_rxbuf"))
13267         disable_mrg_rxbuf = 1;
13268       else if (unformat (i, "disable_indirect_desc"))
13269         disable_indirect_desc = 1;
13270       else if (unformat (i, "gso"))
13271         enable_gso = 1;
13272       else if (unformat (i, "tag %s", &tag))
13273         ;
13274       else
13275         break;
13276     }
13277
13278   if (file_name_set == 0)
13279     {
13280       errmsg ("missing socket file name");
13281       return -99;
13282     }
13283
13284   if (vec_len (file_name) > 255)
13285     {
13286       errmsg ("socket file name too long");
13287       return -99;
13288     }
13289   vec_add1 (file_name, 0);
13290
13291   M (CREATE_VHOST_USER_IF, mp);
13292
13293   mp->is_server = is_server;
13294   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
13295   mp->disable_indirect_desc = disable_indirect_desc;
13296   mp->enable_gso = enable_gso;
13297   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13298   vec_free (file_name);
13299   if (custom_dev_instance != ~0)
13300     {
13301       mp->renumber = 1;
13302       mp->custom_dev_instance = ntohl (custom_dev_instance);
13303     }
13304
13305   mp->use_custom_mac = use_custom_mac;
13306   clib_memcpy (mp->mac_address, hwaddr, 6);
13307   if (tag)
13308     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13309   vec_free (tag);
13310
13311   S (mp);
13312   W (ret);
13313   return ret;
13314 }
13315
13316 static int
13317 api_modify_vhost_user_if (vat_main_t * vam)
13318 {
13319   unformat_input_t *i = vam->input;
13320   vl_api_modify_vhost_user_if_t *mp;
13321   u8 *file_name;
13322   u8 is_server = 0;
13323   u8 file_name_set = 0;
13324   u32 custom_dev_instance = ~0;
13325   u8 sw_if_index_set = 0;
13326   u32 sw_if_index = (u32) ~ 0;
13327   u8 enable_gso = 0;
13328   int ret;
13329
13330   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13331     {
13332       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13333         sw_if_index_set = 1;
13334       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13335         sw_if_index_set = 1;
13336       else if (unformat (i, "socket %s", &file_name))
13337         {
13338           file_name_set = 1;
13339         }
13340       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13341         ;
13342       else if (unformat (i, "server"))
13343         is_server = 1;
13344       else if (unformat (i, "gso"))
13345         enable_gso = 1;
13346       else
13347         break;
13348     }
13349
13350   if (sw_if_index_set == 0)
13351     {
13352       errmsg ("missing sw_if_index or interface name");
13353       return -99;
13354     }
13355
13356   if (file_name_set == 0)
13357     {
13358       errmsg ("missing socket file name");
13359       return -99;
13360     }
13361
13362   if (vec_len (file_name) > 255)
13363     {
13364       errmsg ("socket file name too long");
13365       return -99;
13366     }
13367   vec_add1 (file_name, 0);
13368
13369   M (MODIFY_VHOST_USER_IF, mp);
13370
13371   mp->sw_if_index = ntohl (sw_if_index);
13372   mp->is_server = is_server;
13373   mp->enable_gso = enable_gso;
13374   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13375   vec_free (file_name);
13376   if (custom_dev_instance != ~0)
13377     {
13378       mp->renumber = 1;
13379       mp->custom_dev_instance = ntohl (custom_dev_instance);
13380     }
13381
13382   S (mp);
13383   W (ret);
13384   return ret;
13385 }
13386
13387 static int
13388 api_delete_vhost_user_if (vat_main_t * vam)
13389 {
13390   unformat_input_t *i = vam->input;
13391   vl_api_delete_vhost_user_if_t *mp;
13392   u32 sw_if_index = ~0;
13393   u8 sw_if_index_set = 0;
13394   int ret;
13395
13396   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13397     {
13398       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13399         sw_if_index_set = 1;
13400       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13401         sw_if_index_set = 1;
13402       else
13403         break;
13404     }
13405
13406   if (sw_if_index_set == 0)
13407     {
13408       errmsg ("missing sw_if_index or interface name");
13409       return -99;
13410     }
13411
13412
13413   M (DELETE_VHOST_USER_IF, mp);
13414
13415   mp->sw_if_index = ntohl (sw_if_index);
13416
13417   S (mp);
13418   W (ret);
13419   return ret;
13420 }
13421
13422 static void vl_api_sw_interface_vhost_user_details_t_handler
13423   (vl_api_sw_interface_vhost_user_details_t * mp)
13424 {
13425   vat_main_t *vam = &vat_main;
13426
13427   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13428          (char *) mp->interface_name,
13429          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13430          clib_net_to_host_u64 (mp->features), mp->is_server,
13431          ntohl (mp->num_regions), (char *) mp->sock_filename);
13432   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13433 }
13434
13435 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13436   (vl_api_sw_interface_vhost_user_details_t * mp)
13437 {
13438   vat_main_t *vam = &vat_main;
13439   vat_json_node_t *node = NULL;
13440
13441   if (VAT_JSON_ARRAY != vam->json_tree.type)
13442     {
13443       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13444       vat_json_init_array (&vam->json_tree);
13445     }
13446   node = vat_json_array_add (&vam->json_tree);
13447
13448   vat_json_init_object (node);
13449   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13450   vat_json_object_add_string_copy (node, "interface_name",
13451                                    mp->interface_name);
13452   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13453                             ntohl (mp->virtio_net_hdr_sz));
13454   vat_json_object_add_uint (node, "features",
13455                             clib_net_to_host_u64 (mp->features));
13456   vat_json_object_add_uint (node, "is_server", mp->is_server);
13457   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13458   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13459   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13460 }
13461
13462 static int
13463 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13464 {
13465   vl_api_sw_interface_vhost_user_dump_t *mp;
13466   vl_api_control_ping_t *mp_ping;
13467   int ret;
13468   print (vam->ofp,
13469          "Interface name            idx hdr_sz features server regions filename");
13470
13471   /* Get list of vhost-user interfaces */
13472   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13473   S (mp);
13474
13475   /* Use a control ping for synchronization */
13476   MPING (CONTROL_PING, mp_ping);
13477   S (mp_ping);
13478
13479   W (ret);
13480   return ret;
13481 }
13482
13483 static int
13484 api_show_version (vat_main_t * vam)
13485 {
13486   vl_api_show_version_t *mp;
13487   int ret;
13488
13489   M (SHOW_VERSION, mp);
13490
13491   S (mp);
13492   W (ret);
13493   return ret;
13494 }
13495
13496
13497 static int
13498 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13499 {
13500   unformat_input_t *line_input = vam->input;
13501   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13502   ip4_address_t local4, remote4;
13503   ip6_address_t local6, remote6;
13504   u8 is_add = 1;
13505   u8 ipv4_set = 0, ipv6_set = 0;
13506   u8 local_set = 0;
13507   u8 remote_set = 0;
13508   u8 grp_set = 0;
13509   u32 mcast_sw_if_index = ~0;
13510   u32 encap_vrf_id = 0;
13511   u32 decap_vrf_id = 0;
13512   u8 protocol = ~0;
13513   u32 vni;
13514   u8 vni_set = 0;
13515   int ret;
13516
13517   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13518   clib_memset (&local4, 0, sizeof local4);
13519   clib_memset (&remote4, 0, sizeof remote4);
13520   clib_memset (&local6, 0, sizeof local6);
13521   clib_memset (&remote6, 0, sizeof remote6);
13522
13523   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13524     {
13525       if (unformat (line_input, "del"))
13526         is_add = 0;
13527       else if (unformat (line_input, "local %U",
13528                          unformat_ip4_address, &local4))
13529         {
13530           local_set = 1;
13531           ipv4_set = 1;
13532         }
13533       else if (unformat (line_input, "remote %U",
13534                          unformat_ip4_address, &remote4))
13535         {
13536           remote_set = 1;
13537           ipv4_set = 1;
13538         }
13539       else if (unformat (line_input, "local %U",
13540                          unformat_ip6_address, &local6))
13541         {
13542           local_set = 1;
13543           ipv6_set = 1;
13544         }
13545       else if (unformat (line_input, "remote %U",
13546                          unformat_ip6_address, &remote6))
13547         {
13548           remote_set = 1;
13549           ipv6_set = 1;
13550         }
13551       else if (unformat (line_input, "group %U %U",
13552                          unformat_ip4_address, &remote4,
13553                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13554         {
13555           grp_set = remote_set = 1;
13556           ipv4_set = 1;
13557         }
13558       else if (unformat (line_input, "group %U",
13559                          unformat_ip4_address, &remote4))
13560         {
13561           grp_set = remote_set = 1;
13562           ipv4_set = 1;
13563         }
13564       else if (unformat (line_input, "group %U %U",
13565                          unformat_ip6_address, &remote6,
13566                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13567         {
13568           grp_set = remote_set = 1;
13569           ipv6_set = 1;
13570         }
13571       else if (unformat (line_input, "group %U",
13572                          unformat_ip6_address, &remote6))
13573         {
13574           grp_set = remote_set = 1;
13575           ipv6_set = 1;
13576         }
13577       else
13578         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13579         ;
13580       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13581         ;
13582       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13583         ;
13584       else if (unformat (line_input, "vni %d", &vni))
13585         vni_set = 1;
13586       else if (unformat (line_input, "next-ip4"))
13587         protocol = 1;
13588       else if (unformat (line_input, "next-ip6"))
13589         protocol = 2;
13590       else if (unformat (line_input, "next-ethernet"))
13591         protocol = 3;
13592       else if (unformat (line_input, "next-nsh"))
13593         protocol = 4;
13594       else
13595         {
13596           errmsg ("parse error '%U'", format_unformat_error, line_input);
13597           return -99;
13598         }
13599     }
13600
13601   if (local_set == 0)
13602     {
13603       errmsg ("tunnel local address not specified");
13604       return -99;
13605     }
13606   if (remote_set == 0)
13607     {
13608       errmsg ("tunnel remote address not specified");
13609       return -99;
13610     }
13611   if (grp_set && mcast_sw_if_index == ~0)
13612     {
13613       errmsg ("tunnel nonexistent multicast device");
13614       return -99;
13615     }
13616   if (ipv4_set && ipv6_set)
13617     {
13618       errmsg ("both IPv4 and IPv6 addresses specified");
13619       return -99;
13620     }
13621
13622   if (vni_set == 0)
13623     {
13624       errmsg ("vni not specified");
13625       return -99;
13626     }
13627
13628   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13629
13630
13631   if (ipv6_set)
13632     {
13633       clib_memcpy (&mp->local, &local6, sizeof (local6));
13634       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13635     }
13636   else
13637     {
13638       clib_memcpy (&mp->local, &local4, sizeof (local4));
13639       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13640     }
13641
13642   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13643   mp->encap_vrf_id = ntohl (encap_vrf_id);
13644   mp->decap_vrf_id = ntohl (decap_vrf_id);
13645   mp->protocol = protocol;
13646   mp->vni = ntohl (vni);
13647   mp->is_add = is_add;
13648   mp->is_ipv6 = ipv6_set;
13649
13650   S (mp);
13651   W (ret);
13652   return ret;
13653 }
13654
13655 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13656   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13657 {
13658   vat_main_t *vam = &vat_main;
13659   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13660   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13661
13662   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13663          ntohl (mp->sw_if_index),
13664          format_ip46_address, &local, IP46_TYPE_ANY,
13665          format_ip46_address, &remote, IP46_TYPE_ANY,
13666          ntohl (mp->vni), mp->protocol,
13667          ntohl (mp->mcast_sw_if_index),
13668          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13669 }
13670
13671
13672 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13673   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13674 {
13675   vat_main_t *vam = &vat_main;
13676   vat_json_node_t *node = NULL;
13677   struct in_addr ip4;
13678   struct in6_addr ip6;
13679
13680   if (VAT_JSON_ARRAY != vam->json_tree.type)
13681     {
13682       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13683       vat_json_init_array (&vam->json_tree);
13684     }
13685   node = vat_json_array_add (&vam->json_tree);
13686
13687   vat_json_init_object (node);
13688   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13689   if (mp->is_ipv6)
13690     {
13691       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13692       vat_json_object_add_ip6 (node, "local", ip6);
13693       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13694       vat_json_object_add_ip6 (node, "remote", ip6);
13695     }
13696   else
13697     {
13698       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13699       vat_json_object_add_ip4 (node, "local", ip4);
13700       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13701       vat_json_object_add_ip4 (node, "remote", ip4);
13702     }
13703   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13704   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13705   vat_json_object_add_uint (node, "mcast_sw_if_index",
13706                             ntohl (mp->mcast_sw_if_index));
13707   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13708   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13709   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13710 }
13711
13712 static int
13713 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13714 {
13715   unformat_input_t *i = vam->input;
13716   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13717   vl_api_control_ping_t *mp_ping;
13718   u32 sw_if_index;
13719   u8 sw_if_index_set = 0;
13720   int ret;
13721
13722   /* Parse args required to build the message */
13723   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13724     {
13725       if (unformat (i, "sw_if_index %d", &sw_if_index))
13726         sw_if_index_set = 1;
13727       else
13728         break;
13729     }
13730
13731   if (sw_if_index_set == 0)
13732     {
13733       sw_if_index = ~0;
13734     }
13735
13736   if (!vam->json_output)
13737     {
13738       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13739              "sw_if_index", "local", "remote", "vni",
13740              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13741     }
13742
13743   /* Get list of vxlan-tunnel interfaces */
13744   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13745
13746   mp->sw_if_index = htonl (sw_if_index);
13747
13748   S (mp);
13749
13750   /* Use a control ping for synchronization */
13751   MPING (CONTROL_PING, mp_ping);
13752   S (mp_ping);
13753
13754   W (ret);
13755   return ret;
13756 }
13757
13758 static void vl_api_l2_fib_table_details_t_handler
13759   (vl_api_l2_fib_table_details_t * mp)
13760 {
13761   vat_main_t *vam = &vat_main;
13762
13763   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13764          "       %d       %d     %d",
13765          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
13766          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13767          mp->bvi_mac);
13768 }
13769
13770 static void vl_api_l2_fib_table_details_t_handler_json
13771   (vl_api_l2_fib_table_details_t * mp)
13772 {
13773   vat_main_t *vam = &vat_main;
13774   vat_json_node_t *node = NULL;
13775
13776   if (VAT_JSON_ARRAY != vam->json_tree.type)
13777     {
13778       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13779       vat_json_init_array (&vam->json_tree);
13780     }
13781   node = vat_json_array_add (&vam->json_tree);
13782
13783   vat_json_init_object (node);
13784   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13785   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
13786   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13787   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13788   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13789   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13790 }
13791
13792 static int
13793 api_l2_fib_table_dump (vat_main_t * vam)
13794 {
13795   unformat_input_t *i = vam->input;
13796   vl_api_l2_fib_table_dump_t *mp;
13797   vl_api_control_ping_t *mp_ping;
13798   u32 bd_id;
13799   u8 bd_id_set = 0;
13800   int ret;
13801
13802   /* Parse args required to build the message */
13803   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13804     {
13805       if (unformat (i, "bd_id %d", &bd_id))
13806         bd_id_set = 1;
13807       else
13808         break;
13809     }
13810
13811   if (bd_id_set == 0)
13812     {
13813       errmsg ("missing bridge domain");
13814       return -99;
13815     }
13816
13817   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13818
13819   /* Get list of l2 fib entries */
13820   M (L2_FIB_TABLE_DUMP, mp);
13821
13822   mp->bd_id = ntohl (bd_id);
13823   S (mp);
13824
13825   /* Use a control ping for synchronization */
13826   MPING (CONTROL_PING, mp_ping);
13827   S (mp_ping);
13828
13829   W (ret);
13830   return ret;
13831 }
13832
13833
13834 static int
13835 api_interface_name_renumber (vat_main_t * vam)
13836 {
13837   unformat_input_t *line_input = vam->input;
13838   vl_api_interface_name_renumber_t *mp;
13839   u32 sw_if_index = ~0;
13840   u32 new_show_dev_instance = ~0;
13841   int ret;
13842
13843   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13844     {
13845       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13846                     &sw_if_index))
13847         ;
13848       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13849         ;
13850       else if (unformat (line_input, "new_show_dev_instance %d",
13851                          &new_show_dev_instance))
13852         ;
13853       else
13854         break;
13855     }
13856
13857   if (sw_if_index == ~0)
13858     {
13859       errmsg ("missing interface name or sw_if_index");
13860       return -99;
13861     }
13862
13863   if (new_show_dev_instance == ~0)
13864     {
13865       errmsg ("missing new_show_dev_instance");
13866       return -99;
13867     }
13868
13869   M (INTERFACE_NAME_RENUMBER, mp);
13870
13871   mp->sw_if_index = ntohl (sw_if_index);
13872   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13873
13874   S (mp);
13875   W (ret);
13876   return ret;
13877 }
13878
13879 static int
13880 api_ip_probe_neighbor (vat_main_t * vam)
13881 {
13882   unformat_input_t *i = vam->input;
13883   vl_api_ip_probe_neighbor_t *mp;
13884   vl_api_address_t dst_adr = { };
13885   u8 int_set = 0;
13886   u8 adr_set = 0;
13887   u32 sw_if_index;
13888   int ret;
13889
13890   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13891     {
13892       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13893         int_set = 1;
13894       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13895         int_set = 1;
13896       else if (unformat (i, "address %U", unformat_vl_api_address, &dst_adr))
13897         adr_set = 1;
13898       else
13899         break;
13900     }
13901
13902   if (int_set == 0)
13903     {
13904       errmsg ("missing interface");
13905       return -99;
13906     }
13907
13908   if (adr_set == 0)
13909     {
13910       errmsg ("missing addresses");
13911       return -99;
13912     }
13913
13914   M (IP_PROBE_NEIGHBOR, mp);
13915
13916   mp->sw_if_index = ntohl (sw_if_index);
13917   clib_memcpy (&mp->dst, &dst_adr, sizeof (dst_adr));
13918
13919   S (mp);
13920   W (ret);
13921   return ret;
13922 }
13923
13924 static int
13925 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
13926 {
13927   unformat_input_t *i = vam->input;
13928   vl_api_ip_scan_neighbor_enable_disable_t *mp;
13929   u8 mode = IP_SCAN_V46_NEIGHBORS;
13930   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
13931   int ret;
13932
13933   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13934     {
13935       if (unformat (i, "ip4"))
13936         mode = IP_SCAN_V4_NEIGHBORS;
13937       else if (unformat (i, "ip6"))
13938         mode = IP_SCAN_V6_NEIGHBORS;
13939       if (unformat (i, "both"))
13940         mode = IP_SCAN_V46_NEIGHBORS;
13941       else if (unformat (i, "disable"))
13942         mode = IP_SCAN_DISABLED;
13943       else if (unformat (i, "interval %d", &interval))
13944         ;
13945       else if (unformat (i, "max-time %d", &time))
13946         ;
13947       else if (unformat (i, "max-update %d", &update))
13948         ;
13949       else if (unformat (i, "delay %d", &delay))
13950         ;
13951       else if (unformat (i, "stale %d", &stale))
13952         ;
13953       else
13954         break;
13955     }
13956
13957   if (interval > 255)
13958     {
13959       errmsg ("interval cannot exceed 255 minutes.");
13960       return -99;
13961     }
13962   if (time > 255)
13963     {
13964       errmsg ("max-time cannot exceed 255 usec.");
13965       return -99;
13966     }
13967   if (update > 255)
13968     {
13969       errmsg ("max-update cannot exceed 255.");
13970       return -99;
13971     }
13972   if (delay > 255)
13973     {
13974       errmsg ("delay cannot exceed 255 msec.");
13975       return -99;
13976     }
13977   if (stale > 255)
13978     {
13979       errmsg ("stale cannot exceed 255 minutes.");
13980       return -99;
13981     }
13982
13983   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
13984   mp->mode = mode;
13985   mp->scan_interval = interval;
13986   mp->max_proc_time = time;
13987   mp->max_update = update;
13988   mp->scan_int_delay = delay;
13989   mp->stale_threshold = stale;
13990
13991   S (mp);
13992   W (ret);
13993   return ret;
13994 }
13995
13996 static int
13997 api_want_ip4_arp_events (vat_main_t * vam)
13998 {
13999   unformat_input_t *line_input = vam->input;
14000   vl_api_want_ip4_arp_events_t *mp;
14001   ip4_address_t address;
14002   int address_set = 0;
14003   u32 enable_disable = 1;
14004   int ret;
14005
14006   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14007     {
14008       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14009         address_set = 1;
14010       else if (unformat (line_input, "del"))
14011         enable_disable = 0;
14012       else
14013         break;
14014     }
14015
14016   if (address_set == 0)
14017     {
14018       errmsg ("missing addresses");
14019       return -99;
14020     }
14021
14022   M (WANT_IP4_ARP_EVENTS, mp);
14023   mp->enable_disable = enable_disable;
14024   mp->pid = htonl (getpid ());
14025   clib_memcpy (mp->ip, &address, sizeof (address));
14026
14027   S (mp);
14028   W (ret);
14029   return ret;
14030 }
14031
14032 static int
14033 api_want_ip6_nd_events (vat_main_t * vam)
14034 {
14035   unformat_input_t *line_input = vam->input;
14036   vl_api_want_ip6_nd_events_t *mp;
14037   vl_api_ip6_address_t address;
14038   int address_set = 0;
14039   u32 enable_disable = 1;
14040   int ret;
14041
14042   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14043     {
14044       if (unformat
14045           (line_input, "address %U", unformat_vl_api_ip6_address, &address))
14046         address_set = 1;
14047       else if (unformat (line_input, "del"))
14048         enable_disable = 0;
14049       else
14050         break;
14051     }
14052
14053   if (address_set == 0)
14054     {
14055       errmsg ("missing addresses");
14056       return -99;
14057     }
14058
14059   M (WANT_IP6_ND_EVENTS, mp);
14060   mp->enable_disable = enable_disable;
14061   mp->pid = htonl (getpid ());
14062   clib_memcpy (&mp->ip, &address, sizeof (address));
14063
14064   S (mp);
14065   W (ret);
14066   return ret;
14067 }
14068
14069 static int
14070 api_want_l2_macs_events (vat_main_t * vam)
14071 {
14072   unformat_input_t *line_input = vam->input;
14073   vl_api_want_l2_macs_events_t *mp;
14074   u8 enable_disable = 1;
14075   u32 scan_delay = 0;
14076   u32 max_macs_in_event = 0;
14077   u32 learn_limit = 0;
14078   int ret;
14079
14080   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14081     {
14082       if (unformat (line_input, "learn-limit %d", &learn_limit))
14083         ;
14084       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14085         ;
14086       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14087         ;
14088       else if (unformat (line_input, "disable"))
14089         enable_disable = 0;
14090       else
14091         break;
14092     }
14093
14094   M (WANT_L2_MACS_EVENTS, mp);
14095   mp->enable_disable = enable_disable;
14096   mp->pid = htonl (getpid ());
14097   mp->learn_limit = htonl (learn_limit);
14098   mp->scan_delay = (u8) scan_delay;
14099   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14100   S (mp);
14101   W (ret);
14102   return ret;
14103 }
14104
14105 static int
14106 api_input_acl_set_interface (vat_main_t * vam)
14107 {
14108   unformat_input_t *i = vam->input;
14109   vl_api_input_acl_set_interface_t *mp;
14110   u32 sw_if_index;
14111   int sw_if_index_set;
14112   u32 ip4_table_index = ~0;
14113   u32 ip6_table_index = ~0;
14114   u32 l2_table_index = ~0;
14115   u8 is_add = 1;
14116   int ret;
14117
14118   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14119     {
14120       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14121         sw_if_index_set = 1;
14122       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14123         sw_if_index_set = 1;
14124       else if (unformat (i, "del"))
14125         is_add = 0;
14126       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14127         ;
14128       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14129         ;
14130       else if (unformat (i, "l2-table %d", &l2_table_index))
14131         ;
14132       else
14133         {
14134           clib_warning ("parse error '%U'", format_unformat_error, i);
14135           return -99;
14136         }
14137     }
14138
14139   if (sw_if_index_set == 0)
14140     {
14141       errmsg ("missing interface name or sw_if_index");
14142       return -99;
14143     }
14144
14145   M (INPUT_ACL_SET_INTERFACE, mp);
14146
14147   mp->sw_if_index = ntohl (sw_if_index);
14148   mp->ip4_table_index = ntohl (ip4_table_index);
14149   mp->ip6_table_index = ntohl (ip6_table_index);
14150   mp->l2_table_index = ntohl (l2_table_index);
14151   mp->is_add = is_add;
14152
14153   S (mp);
14154   W (ret);
14155   return ret;
14156 }
14157
14158 static int
14159 api_output_acl_set_interface (vat_main_t * vam)
14160 {
14161   unformat_input_t *i = vam->input;
14162   vl_api_output_acl_set_interface_t *mp;
14163   u32 sw_if_index;
14164   int sw_if_index_set;
14165   u32 ip4_table_index = ~0;
14166   u32 ip6_table_index = ~0;
14167   u32 l2_table_index = ~0;
14168   u8 is_add = 1;
14169   int ret;
14170
14171   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14172     {
14173       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14174         sw_if_index_set = 1;
14175       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14176         sw_if_index_set = 1;
14177       else if (unformat (i, "del"))
14178         is_add = 0;
14179       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14180         ;
14181       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14182         ;
14183       else if (unformat (i, "l2-table %d", &l2_table_index))
14184         ;
14185       else
14186         {
14187           clib_warning ("parse error '%U'", format_unformat_error, i);
14188           return -99;
14189         }
14190     }
14191
14192   if (sw_if_index_set == 0)
14193     {
14194       errmsg ("missing interface name or sw_if_index");
14195       return -99;
14196     }
14197
14198   M (OUTPUT_ACL_SET_INTERFACE, mp);
14199
14200   mp->sw_if_index = ntohl (sw_if_index);
14201   mp->ip4_table_index = ntohl (ip4_table_index);
14202   mp->ip6_table_index = ntohl (ip6_table_index);
14203   mp->l2_table_index = ntohl (l2_table_index);
14204   mp->is_add = is_add;
14205
14206   S (mp);
14207   W (ret);
14208   return ret;
14209 }
14210
14211 static int
14212 api_ip_address_dump (vat_main_t * vam)
14213 {
14214   unformat_input_t *i = vam->input;
14215   vl_api_ip_address_dump_t *mp;
14216   vl_api_control_ping_t *mp_ping;
14217   u32 sw_if_index = ~0;
14218   u8 sw_if_index_set = 0;
14219   u8 ipv4_set = 0;
14220   u8 ipv6_set = 0;
14221   int ret;
14222
14223   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14224     {
14225       if (unformat (i, "sw_if_index %d", &sw_if_index))
14226         sw_if_index_set = 1;
14227       else
14228         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14229         sw_if_index_set = 1;
14230       else if (unformat (i, "ipv4"))
14231         ipv4_set = 1;
14232       else if (unformat (i, "ipv6"))
14233         ipv6_set = 1;
14234       else
14235         break;
14236     }
14237
14238   if (ipv4_set && ipv6_set)
14239     {
14240       errmsg ("ipv4 and ipv6 flags cannot be both set");
14241       return -99;
14242     }
14243
14244   if ((!ipv4_set) && (!ipv6_set))
14245     {
14246       errmsg ("no ipv4 nor ipv6 flag set");
14247       return -99;
14248     }
14249
14250   if (sw_if_index_set == 0)
14251     {
14252       errmsg ("missing interface name or sw_if_index");
14253       return -99;
14254     }
14255
14256   vam->current_sw_if_index = sw_if_index;
14257   vam->is_ipv6 = ipv6_set;
14258
14259   M (IP_ADDRESS_DUMP, mp);
14260   mp->sw_if_index = ntohl (sw_if_index);
14261   mp->is_ipv6 = ipv6_set;
14262   S (mp);
14263
14264   /* Use a control ping for synchronization */
14265   MPING (CONTROL_PING, mp_ping);
14266   S (mp_ping);
14267
14268   W (ret);
14269   return ret;
14270 }
14271
14272 static int
14273 api_ip_dump (vat_main_t * vam)
14274 {
14275   vl_api_ip_dump_t *mp;
14276   vl_api_control_ping_t *mp_ping;
14277   unformat_input_t *in = vam->input;
14278   int ipv4_set = 0;
14279   int ipv6_set = 0;
14280   int is_ipv6;
14281   int i;
14282   int ret;
14283
14284   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14285     {
14286       if (unformat (in, "ipv4"))
14287         ipv4_set = 1;
14288       else if (unformat (in, "ipv6"))
14289         ipv6_set = 1;
14290       else
14291         break;
14292     }
14293
14294   if (ipv4_set && ipv6_set)
14295     {
14296       errmsg ("ipv4 and ipv6 flags cannot be both set");
14297       return -99;
14298     }
14299
14300   if ((!ipv4_set) && (!ipv6_set))
14301     {
14302       errmsg ("no ipv4 nor ipv6 flag set");
14303       return -99;
14304     }
14305
14306   is_ipv6 = ipv6_set;
14307   vam->is_ipv6 = is_ipv6;
14308
14309   /* free old data */
14310   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14311     {
14312       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14313     }
14314   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14315
14316   M (IP_DUMP, mp);
14317   mp->is_ipv6 = ipv6_set;
14318   S (mp);
14319
14320   /* Use a control ping for synchronization */
14321   MPING (CONTROL_PING, mp_ping);
14322   S (mp_ping);
14323
14324   W (ret);
14325   return ret;
14326 }
14327
14328 static int
14329 api_ipsec_spd_add_del (vat_main_t * vam)
14330 {
14331   unformat_input_t *i = vam->input;
14332   vl_api_ipsec_spd_add_del_t *mp;
14333   u32 spd_id = ~0;
14334   u8 is_add = 1;
14335   int ret;
14336
14337   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14338     {
14339       if (unformat (i, "spd_id %d", &spd_id))
14340         ;
14341       else if (unformat (i, "del"))
14342         is_add = 0;
14343       else
14344         {
14345           clib_warning ("parse error '%U'", format_unformat_error, i);
14346           return -99;
14347         }
14348     }
14349   if (spd_id == ~0)
14350     {
14351       errmsg ("spd_id must be set");
14352       return -99;
14353     }
14354
14355   M (IPSEC_SPD_ADD_DEL, mp);
14356
14357   mp->spd_id = ntohl (spd_id);
14358   mp->is_add = is_add;
14359
14360   S (mp);
14361   W (ret);
14362   return ret;
14363 }
14364
14365 static int
14366 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14367 {
14368   unformat_input_t *i = vam->input;
14369   vl_api_ipsec_interface_add_del_spd_t *mp;
14370   u32 sw_if_index;
14371   u8 sw_if_index_set = 0;
14372   u32 spd_id = (u32) ~ 0;
14373   u8 is_add = 1;
14374   int ret;
14375
14376   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14377     {
14378       if (unformat (i, "del"))
14379         is_add = 0;
14380       else if (unformat (i, "spd_id %d", &spd_id))
14381         ;
14382       else
14383         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14384         sw_if_index_set = 1;
14385       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14386         sw_if_index_set = 1;
14387       else
14388         {
14389           clib_warning ("parse error '%U'", format_unformat_error, i);
14390           return -99;
14391         }
14392
14393     }
14394
14395   if (spd_id == (u32) ~ 0)
14396     {
14397       errmsg ("spd_id must be set");
14398       return -99;
14399     }
14400
14401   if (sw_if_index_set == 0)
14402     {
14403       errmsg ("missing interface name or sw_if_index");
14404       return -99;
14405     }
14406
14407   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14408
14409   mp->spd_id = ntohl (spd_id);
14410   mp->sw_if_index = ntohl (sw_if_index);
14411   mp->is_add = is_add;
14412
14413   S (mp);
14414   W (ret);
14415   return ret;
14416 }
14417
14418 static int
14419 api_ipsec_spd_entry_add_del (vat_main_t * vam)
14420 {
14421   unformat_input_t *i = vam->input;
14422   vl_api_ipsec_spd_entry_add_del_t *mp;
14423   u8 is_add = 1, is_outbound = 0;
14424   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14425   i32 priority = 0;
14426   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14427   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14428   vl_api_address_t laddr_start = { }, laddr_stop =
14429   {
14430   }, raddr_start =
14431   {
14432   }, raddr_stop =
14433   {
14434   };
14435   int ret;
14436
14437   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14438     {
14439       if (unformat (i, "del"))
14440         is_add = 0;
14441       if (unformat (i, "outbound"))
14442         is_outbound = 1;
14443       if (unformat (i, "inbound"))
14444         is_outbound = 0;
14445       else if (unformat (i, "spd_id %d", &spd_id))
14446         ;
14447       else if (unformat (i, "sa_id %d", &sa_id))
14448         ;
14449       else if (unformat (i, "priority %d", &priority))
14450         ;
14451       else if (unformat (i, "protocol %d", &protocol))
14452         ;
14453       else if (unformat (i, "lport_start %d", &lport_start))
14454         ;
14455       else if (unformat (i, "lport_stop %d", &lport_stop))
14456         ;
14457       else if (unformat (i, "rport_start %d", &rport_start))
14458         ;
14459       else if (unformat (i, "rport_stop %d", &rport_stop))
14460         ;
14461       else if (unformat (i, "laddr_start %U",
14462                          unformat_vl_api_address, &laddr_start))
14463         ;
14464       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
14465                          &laddr_stop))
14466         ;
14467       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
14468                          &raddr_start))
14469         ;
14470       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
14471                          &raddr_stop))
14472         ;
14473       else
14474         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14475         {
14476           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14477             {
14478               clib_warning ("unsupported action: 'resolve'");
14479               return -99;
14480             }
14481         }
14482       else
14483         {
14484           clib_warning ("parse error '%U'", format_unformat_error, i);
14485           return -99;
14486         }
14487
14488     }
14489
14490   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
14491
14492   mp->is_add = is_add;
14493
14494   mp->entry.spd_id = ntohl (spd_id);
14495   mp->entry.priority = ntohl (priority);
14496   mp->entry.is_outbound = is_outbound;
14497
14498   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
14499                sizeof (vl_api_address_t));
14500   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
14501                sizeof (vl_api_address_t));
14502   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
14503                sizeof (vl_api_address_t));
14504   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
14505                sizeof (vl_api_address_t));
14506
14507   mp->entry.protocol = (u8) protocol;
14508   mp->entry.local_port_start = ntohs ((u16) lport_start);
14509   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
14510   mp->entry.remote_port_start = ntohs ((u16) rport_start);
14511   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
14512   mp->entry.policy = (u8) policy;
14513   mp->entry.sa_id = ntohl (sa_id);
14514
14515   S (mp);
14516   W (ret);
14517   return ret;
14518 }
14519
14520 static int
14521 api_ipsec_sad_entry_add_del (vat_main_t * vam)
14522 {
14523   unformat_input_t *i = vam->input;
14524   vl_api_ipsec_sad_entry_add_del_t *mp;
14525   u32 sad_id = 0, spi = 0;
14526   u8 *ck = 0, *ik = 0;
14527   u8 is_add = 1;
14528
14529   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
14530   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
14531   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
14532   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
14533   vl_api_address_t tun_src, tun_dst;
14534   int ret;
14535
14536   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14537     {
14538       if (unformat (i, "del"))
14539         is_add = 0;
14540       else if (unformat (i, "sad_id %d", &sad_id))
14541         ;
14542       else if (unformat (i, "spi %d", &spi))
14543         ;
14544       else if (unformat (i, "esp"))
14545         protocol = IPSEC_API_PROTO_ESP;
14546       else
14547         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
14548         {
14549           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14550           if (ADDRESS_IP6 == tun_src.af)
14551             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14552         }
14553       else
14554         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
14555         {
14556           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14557           if (ADDRESS_IP6 == tun_src.af)
14558             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14559         }
14560       else
14561         if (unformat (i, "crypto_alg %U",
14562                       unformat_ipsec_api_crypto_alg, &crypto_alg))
14563         ;
14564       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14565         ;
14566       else if (unformat (i, "integ_alg %U",
14567                          unformat_ipsec_api_integ_alg, &integ_alg))
14568         ;
14569       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14570         ;
14571       else
14572         {
14573           clib_warning ("parse error '%U'", format_unformat_error, i);
14574           return -99;
14575         }
14576
14577     }
14578
14579   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
14580
14581   mp->is_add = is_add;
14582   mp->entry.sad_id = ntohl (sad_id);
14583   mp->entry.protocol = protocol;
14584   mp->entry.spi = ntohl (spi);
14585   mp->entry.flags = flags;
14586
14587   mp->entry.crypto_algorithm = crypto_alg;
14588   mp->entry.integrity_algorithm = integ_alg;
14589   mp->entry.crypto_key.length = vec_len (ck);
14590   mp->entry.integrity_key.length = vec_len (ik);
14591
14592   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
14593     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
14594
14595   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
14596     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
14597
14598   if (ck)
14599     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
14600   if (ik)
14601     clib_memcpy (mp->entry.integrity_key.data, ik,
14602                  mp->entry.integrity_key.length);
14603
14604   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
14605     {
14606       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
14607                    sizeof (mp->entry.tunnel_src));
14608       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
14609                    sizeof (mp->entry.tunnel_dst));
14610     }
14611
14612   S (mp);
14613   W (ret);
14614   return ret;
14615 }
14616
14617 static int
14618 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14619 {
14620   unformat_input_t *i = vam->input;
14621   vl_api_ipsec_tunnel_if_add_del_t *mp;
14622   u32 local_spi = 0, remote_spi = 0;
14623   u32 crypto_alg = 0, integ_alg = 0;
14624   u8 *lck = NULL, *rck = NULL;
14625   u8 *lik = NULL, *rik = NULL;
14626   vl_api_address_t local_ip = { 0 };
14627   vl_api_address_t remote_ip = { 0 };
14628   f64 before = 0;
14629   u8 is_add = 1;
14630   u8 esn = 0;
14631   u8 anti_replay = 0;
14632   u8 renumber = 0;
14633   u32 instance = ~0;
14634   u32 count = 1, jj;
14635   int ret = -1;
14636
14637   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14638     {
14639       if (unformat (i, "del"))
14640         is_add = 0;
14641       else if (unformat (i, "esn"))
14642         esn = 1;
14643       else if (unformat (i, "anti-replay"))
14644         anti_replay = 1;
14645       else if (unformat (i, "count %d", &count))
14646         ;
14647       else if (unformat (i, "local_spi %d", &local_spi))
14648         ;
14649       else if (unformat (i, "remote_spi %d", &remote_spi))
14650         ;
14651       else
14652         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
14653         ;
14654       else
14655         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
14656         ;
14657       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14658         ;
14659       else
14660         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14661         ;
14662       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14663         ;
14664       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14665         ;
14666       else
14667         if (unformat
14668             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
14669         {
14670           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
14671             {
14672               errmsg ("unsupported crypto-alg: '%U'\n",
14673                       format_ipsec_crypto_alg, crypto_alg);
14674               return -99;
14675             }
14676         }
14677       else
14678         if (unformat
14679             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
14680         {
14681           if (integ_alg >= IPSEC_INTEG_N_ALG)
14682             {
14683               errmsg ("unsupported integ-alg: '%U'\n",
14684                       format_ipsec_integ_alg, integ_alg);
14685               return -99;
14686             }
14687         }
14688       else if (unformat (i, "instance %u", &instance))
14689         renumber = 1;
14690       else
14691         {
14692           errmsg ("parse error '%U'\n", format_unformat_error, i);
14693           return -99;
14694         }
14695     }
14696
14697   if (count > 1)
14698     {
14699       /* Turn on async mode */
14700       vam->async_mode = 1;
14701       vam->async_errors = 0;
14702       before = vat_time_now (vam);
14703     }
14704
14705   for (jj = 0; jj < count; jj++)
14706     {
14707       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14708
14709       mp->is_add = is_add;
14710       mp->esn = esn;
14711       mp->anti_replay = anti_replay;
14712
14713       if (jj > 0)
14714         increment_address (&remote_ip);
14715
14716       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
14717       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
14718
14719       mp->local_spi = htonl (local_spi + jj);
14720       mp->remote_spi = htonl (remote_spi + jj);
14721       mp->crypto_alg = (u8) crypto_alg;
14722
14723       mp->local_crypto_key_len = 0;
14724       if (lck)
14725         {
14726           mp->local_crypto_key_len = vec_len (lck);
14727           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14728             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14729           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14730         }
14731
14732       mp->remote_crypto_key_len = 0;
14733       if (rck)
14734         {
14735           mp->remote_crypto_key_len = vec_len (rck);
14736           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14737             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14738           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14739         }
14740
14741       mp->integ_alg = (u8) integ_alg;
14742
14743       mp->local_integ_key_len = 0;
14744       if (lik)
14745         {
14746           mp->local_integ_key_len = vec_len (lik);
14747           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14748             mp->local_integ_key_len = sizeof (mp->local_integ_key);
14749           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14750         }
14751
14752       mp->remote_integ_key_len = 0;
14753       if (rik)
14754         {
14755           mp->remote_integ_key_len = vec_len (rik);
14756           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14757             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14758           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14759         }
14760
14761       if (renumber)
14762         {
14763           mp->renumber = renumber;
14764           mp->show_instance = ntohl (instance);
14765         }
14766       S (mp);
14767     }
14768
14769   /* When testing multiple add/del ops, use a control-ping to sync */
14770   if (count > 1)
14771     {
14772       vl_api_control_ping_t *mp_ping;
14773       f64 after;
14774       f64 timeout;
14775
14776       /* Shut off async mode */
14777       vam->async_mode = 0;
14778
14779       MPING (CONTROL_PING, mp_ping);
14780       S (mp_ping);
14781
14782       timeout = vat_time_now (vam) + 1.0;
14783       while (vat_time_now (vam) < timeout)
14784         if (vam->result_ready == 1)
14785           goto out;
14786       vam->retval = -99;
14787
14788     out:
14789       if (vam->retval == -99)
14790         errmsg ("timeout");
14791
14792       if (vam->async_errors > 0)
14793         {
14794           errmsg ("%d asynchronous errors", vam->async_errors);
14795           vam->retval = -98;
14796         }
14797       vam->async_errors = 0;
14798       after = vat_time_now (vam);
14799
14800       /* slim chance, but we might have eaten SIGTERM on the first iteration */
14801       if (jj > 0)
14802         count = jj;
14803
14804       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
14805              count, after - before, count / (after - before));
14806     }
14807   else
14808     {
14809       /* Wait for a reply... */
14810       W (ret);
14811       return ret;
14812     }
14813
14814   return ret;
14815 }
14816
14817 static void
14818 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14819 {
14820   vat_main_t *vam = &vat_main;
14821
14822   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14823          "crypto_key %U integ_alg %u integ_key %U flags %x "
14824          "tunnel_src_addr %U tunnel_dst_addr %U "
14825          "salt %u seq_outbound %lu last_seq_inbound %lu "
14826          "replay_window %lu\n",
14827          ntohl (mp->entry.sad_id),
14828          ntohl (mp->sw_if_index),
14829          ntohl (mp->entry.spi),
14830          ntohl (mp->entry.protocol),
14831          ntohl (mp->entry.crypto_algorithm),
14832          format_hex_bytes, mp->entry.crypto_key.data,
14833          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
14834          format_hex_bytes, mp->entry.integrity_key.data,
14835          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
14836          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
14837          &mp->entry.tunnel_dst, ntohl (mp->salt),
14838          clib_net_to_host_u64 (mp->seq_outbound),
14839          clib_net_to_host_u64 (mp->last_seq_inbound),
14840          clib_net_to_host_u64 (mp->replay_window));
14841 }
14842
14843 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14844 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14845
14846 static void vl_api_ipsec_sa_details_t_handler_json
14847   (vl_api_ipsec_sa_details_t * mp)
14848 {
14849   vat_main_t *vam = &vat_main;
14850   vat_json_node_t *node = NULL;
14851   vl_api_ipsec_sad_flags_t flags;
14852
14853   if (VAT_JSON_ARRAY != vam->json_tree.type)
14854     {
14855       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14856       vat_json_init_array (&vam->json_tree);
14857     }
14858   node = vat_json_array_add (&vam->json_tree);
14859
14860   vat_json_init_object (node);
14861   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
14862   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14863   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
14864   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
14865   vat_json_object_add_uint (node, "crypto_alg",
14866                             ntohl (mp->entry.crypto_algorithm));
14867   vat_json_object_add_uint (node, "integ_alg",
14868                             ntohl (mp->entry.integrity_algorithm));
14869   flags = ntohl (mp->entry.flags);
14870   vat_json_object_add_uint (node, "use_esn",
14871                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
14872   vat_json_object_add_uint (node, "use_anti_replay",
14873                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
14874   vat_json_object_add_uint (node, "is_tunnel",
14875                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
14876   vat_json_object_add_uint (node, "is_tunnel_ip6",
14877                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
14878   vat_json_object_add_uint (node, "udp_encap",
14879                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
14880   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
14881                              mp->entry.crypto_key.length);
14882   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
14883                              mp->entry.integrity_key.length);
14884   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
14885   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
14886   vat_json_object_add_uint (node, "replay_window",
14887                             clib_net_to_host_u64 (mp->replay_window));
14888 }
14889
14890 static int
14891 api_ipsec_sa_dump (vat_main_t * vam)
14892 {
14893   unformat_input_t *i = vam->input;
14894   vl_api_ipsec_sa_dump_t *mp;
14895   vl_api_control_ping_t *mp_ping;
14896   u32 sa_id = ~0;
14897   int ret;
14898
14899   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14900     {
14901       if (unformat (i, "sa_id %d", &sa_id))
14902         ;
14903       else
14904         {
14905           clib_warning ("parse error '%U'", format_unformat_error, i);
14906           return -99;
14907         }
14908     }
14909
14910   M (IPSEC_SA_DUMP, mp);
14911
14912   mp->sa_id = ntohl (sa_id);
14913
14914   S (mp);
14915
14916   /* Use a control ping for synchronization */
14917   M (CONTROL_PING, mp_ping);
14918   S (mp_ping);
14919
14920   W (ret);
14921   return ret;
14922 }
14923
14924 static int
14925 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
14926 {
14927   unformat_input_t *i = vam->input;
14928   vl_api_ipsec_tunnel_if_set_sa_t *mp;
14929   u32 sw_if_index = ~0;
14930   u32 sa_id = ~0;
14931   u8 is_outbound = (u8) ~ 0;
14932   int ret;
14933
14934   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14935     {
14936       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14937         ;
14938       else if (unformat (i, "sa_id %d", &sa_id))
14939         ;
14940       else if (unformat (i, "outbound"))
14941         is_outbound = 1;
14942       else if (unformat (i, "inbound"))
14943         is_outbound = 0;
14944       else
14945         {
14946           clib_warning ("parse error '%U'", format_unformat_error, i);
14947           return -99;
14948         }
14949     }
14950
14951   if (sw_if_index == ~0)
14952     {
14953       errmsg ("interface must be specified");
14954       return -99;
14955     }
14956
14957   if (sa_id == ~0)
14958     {
14959       errmsg ("SA ID must be specified");
14960       return -99;
14961     }
14962
14963   M (IPSEC_TUNNEL_IF_SET_SA, mp);
14964
14965   mp->sw_if_index = htonl (sw_if_index);
14966   mp->sa_id = htonl (sa_id);
14967   mp->is_outbound = is_outbound;
14968
14969   S (mp);
14970   W (ret);
14971
14972   return ret;
14973 }
14974
14975 static int
14976 api_get_first_msg_id (vat_main_t * vam)
14977 {
14978   vl_api_get_first_msg_id_t *mp;
14979   unformat_input_t *i = vam->input;
14980   u8 *name;
14981   u8 name_set = 0;
14982   int ret;
14983
14984   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14985     {
14986       if (unformat (i, "client %s", &name))
14987         name_set = 1;
14988       else
14989         break;
14990     }
14991
14992   if (name_set == 0)
14993     {
14994       errmsg ("missing client name");
14995       return -99;
14996     }
14997   vec_add1 (name, 0);
14998
14999   if (vec_len (name) > 63)
15000     {
15001       errmsg ("client name too long");
15002       return -99;
15003     }
15004
15005   M (GET_FIRST_MSG_ID, mp);
15006   clib_memcpy (mp->name, name, vec_len (name));
15007   S (mp);
15008   W (ret);
15009   return ret;
15010 }
15011
15012 static int
15013 api_cop_interface_enable_disable (vat_main_t * vam)
15014 {
15015   unformat_input_t *line_input = vam->input;
15016   vl_api_cop_interface_enable_disable_t *mp;
15017   u32 sw_if_index = ~0;
15018   u8 enable_disable = 1;
15019   int ret;
15020
15021   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15022     {
15023       if (unformat (line_input, "disable"))
15024         enable_disable = 0;
15025       if (unformat (line_input, "enable"))
15026         enable_disable = 1;
15027       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15028                          vam, &sw_if_index))
15029         ;
15030       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15031         ;
15032       else
15033         break;
15034     }
15035
15036   if (sw_if_index == ~0)
15037     {
15038       errmsg ("missing interface name or sw_if_index");
15039       return -99;
15040     }
15041
15042   /* Construct the API message */
15043   M (COP_INTERFACE_ENABLE_DISABLE, mp);
15044   mp->sw_if_index = ntohl (sw_if_index);
15045   mp->enable_disable = enable_disable;
15046
15047   /* send it... */
15048   S (mp);
15049   /* Wait for the reply */
15050   W (ret);
15051   return ret;
15052 }
15053
15054 static int
15055 api_cop_whitelist_enable_disable (vat_main_t * vam)
15056 {
15057   unformat_input_t *line_input = vam->input;
15058   vl_api_cop_whitelist_enable_disable_t *mp;
15059   u32 sw_if_index = ~0;
15060   u8 ip4 = 0, ip6 = 0, default_cop = 0;
15061   u32 fib_id = 0;
15062   int ret;
15063
15064   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15065     {
15066       if (unformat (line_input, "ip4"))
15067         ip4 = 1;
15068       else if (unformat (line_input, "ip6"))
15069         ip6 = 1;
15070       else if (unformat (line_input, "default"))
15071         default_cop = 1;
15072       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15073                          vam, &sw_if_index))
15074         ;
15075       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15076         ;
15077       else if (unformat (line_input, "fib-id %d", &fib_id))
15078         ;
15079       else
15080         break;
15081     }
15082
15083   if (sw_if_index == ~0)
15084     {
15085       errmsg ("missing interface name or sw_if_index");
15086       return -99;
15087     }
15088
15089   /* Construct the API message */
15090   M (COP_WHITELIST_ENABLE_DISABLE, mp);
15091   mp->sw_if_index = ntohl (sw_if_index);
15092   mp->fib_id = ntohl (fib_id);
15093   mp->ip4 = ip4;
15094   mp->ip6 = ip6;
15095   mp->default_cop = default_cop;
15096
15097   /* send it... */
15098   S (mp);
15099   /* Wait for the reply */
15100   W (ret);
15101   return ret;
15102 }
15103
15104 static int
15105 api_get_node_graph (vat_main_t * vam)
15106 {
15107   vl_api_get_node_graph_t *mp;
15108   int ret;
15109
15110   M (GET_NODE_GRAPH, mp);
15111
15112   /* send it... */
15113   S (mp);
15114   /* Wait for the reply */
15115   W (ret);
15116   return ret;
15117 }
15118
15119 /* *INDENT-OFF* */
15120 /** Used for parsing LISP eids */
15121 typedef CLIB_PACKED(struct{
15122   u8 addr[16];   /**< eid address */
15123   u32 len;       /**< prefix length if IP */
15124   u8 type;      /**< type of eid */
15125 }) lisp_eid_vat_t;
15126 /* *INDENT-ON* */
15127
15128 static uword
15129 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
15130 {
15131   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
15132
15133   clib_memset (a, 0, sizeof (a[0]));
15134
15135   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
15136     {
15137       a->type = 0;              /* ipv4 type */
15138     }
15139   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
15140     {
15141       a->type = 1;              /* ipv6 type */
15142     }
15143   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
15144     {
15145       a->type = 2;              /* mac type */
15146     }
15147   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
15148     {
15149       a->type = 3;              /* NSH type */
15150       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
15151       nsh->spi = clib_host_to_net_u32 (nsh->spi);
15152     }
15153   else
15154     {
15155       return 0;
15156     }
15157
15158   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
15159     {
15160       return 0;
15161     }
15162
15163   return 1;
15164 }
15165
15166 static int
15167 lisp_eid_size_vat (u8 type)
15168 {
15169   switch (type)
15170     {
15171     case 0:
15172       return 4;
15173     case 1:
15174       return 16;
15175     case 2:
15176       return 6;
15177     case 3:
15178       return 5;
15179     }
15180   return 0;
15181 }
15182
15183 static void
15184 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
15185 {
15186   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
15187 }
15188
15189 static int
15190 api_one_add_del_locator_set (vat_main_t * vam)
15191 {
15192   unformat_input_t *input = vam->input;
15193   vl_api_one_add_del_locator_set_t *mp;
15194   u8 is_add = 1;
15195   u8 *locator_set_name = NULL;
15196   u8 locator_set_name_set = 0;
15197   vl_api_local_locator_t locator, *locators = 0;
15198   u32 sw_if_index, priority, weight;
15199   u32 data_len = 0;
15200
15201   int ret;
15202   /* Parse args required to build the message */
15203   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15204     {
15205       if (unformat (input, "del"))
15206         {
15207           is_add = 0;
15208         }
15209       else if (unformat (input, "locator-set %s", &locator_set_name))
15210         {
15211           locator_set_name_set = 1;
15212         }
15213       else if (unformat (input, "sw_if_index %u p %u w %u",
15214                          &sw_if_index, &priority, &weight))
15215         {
15216           locator.sw_if_index = htonl (sw_if_index);
15217           locator.priority = priority;
15218           locator.weight = weight;
15219           vec_add1 (locators, locator);
15220         }
15221       else
15222         if (unformat
15223             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
15224              &sw_if_index, &priority, &weight))
15225         {
15226           locator.sw_if_index = htonl (sw_if_index);
15227           locator.priority = priority;
15228           locator.weight = weight;
15229           vec_add1 (locators, locator);
15230         }
15231       else
15232         break;
15233     }
15234
15235   if (locator_set_name_set == 0)
15236     {
15237       errmsg ("missing locator-set name");
15238       vec_free (locators);
15239       return -99;
15240     }
15241
15242   if (vec_len (locator_set_name) > 64)
15243     {
15244       errmsg ("locator-set name too long");
15245       vec_free (locator_set_name);
15246       vec_free (locators);
15247       return -99;
15248     }
15249   vec_add1 (locator_set_name, 0);
15250
15251   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
15252
15253   /* Construct the API message */
15254   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
15255
15256   mp->is_add = is_add;
15257   clib_memcpy (mp->locator_set_name, locator_set_name,
15258                vec_len (locator_set_name));
15259   vec_free (locator_set_name);
15260
15261   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
15262   if (locators)
15263     clib_memcpy (mp->locators, locators, data_len);
15264   vec_free (locators);
15265
15266   /* send it... */
15267   S (mp);
15268
15269   /* Wait for a reply... */
15270   W (ret);
15271   return ret;
15272 }
15273
15274 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
15275
15276 static int
15277 api_one_add_del_locator (vat_main_t * vam)
15278 {
15279   unformat_input_t *input = vam->input;
15280   vl_api_one_add_del_locator_t *mp;
15281   u32 tmp_if_index = ~0;
15282   u32 sw_if_index = ~0;
15283   u8 sw_if_index_set = 0;
15284   u8 sw_if_index_if_name_set = 0;
15285   u32 priority = ~0;
15286   u8 priority_set = 0;
15287   u32 weight = ~0;
15288   u8 weight_set = 0;
15289   u8 is_add = 1;
15290   u8 *locator_set_name = NULL;
15291   u8 locator_set_name_set = 0;
15292   int ret;
15293
15294   /* Parse args required to build the message */
15295   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15296     {
15297       if (unformat (input, "del"))
15298         {
15299           is_add = 0;
15300         }
15301       else if (unformat (input, "locator-set %s", &locator_set_name))
15302         {
15303           locator_set_name_set = 1;
15304         }
15305       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
15306                          &tmp_if_index))
15307         {
15308           sw_if_index_if_name_set = 1;
15309           sw_if_index = tmp_if_index;
15310         }
15311       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
15312         {
15313           sw_if_index_set = 1;
15314           sw_if_index = tmp_if_index;
15315         }
15316       else if (unformat (input, "p %d", &priority))
15317         {
15318           priority_set = 1;
15319         }
15320       else if (unformat (input, "w %d", &weight))
15321         {
15322           weight_set = 1;
15323         }
15324       else
15325         break;
15326     }
15327
15328   if (locator_set_name_set == 0)
15329     {
15330       errmsg ("missing locator-set name");
15331       return -99;
15332     }
15333
15334   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
15335     {
15336       errmsg ("missing sw_if_index");
15337       vec_free (locator_set_name);
15338       return -99;
15339     }
15340
15341   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
15342     {
15343       errmsg ("cannot use both params interface name and sw_if_index");
15344       vec_free (locator_set_name);
15345       return -99;
15346     }
15347
15348   if (priority_set == 0)
15349     {
15350       errmsg ("missing locator-set priority");
15351       vec_free (locator_set_name);
15352       return -99;
15353     }
15354
15355   if (weight_set == 0)
15356     {
15357       errmsg ("missing locator-set weight");
15358       vec_free (locator_set_name);
15359       return -99;
15360     }
15361
15362   if (vec_len (locator_set_name) > 64)
15363     {
15364       errmsg ("locator-set name too long");
15365       vec_free (locator_set_name);
15366       return -99;
15367     }
15368   vec_add1 (locator_set_name, 0);
15369
15370   /* Construct the API message */
15371   M (ONE_ADD_DEL_LOCATOR, mp);
15372
15373   mp->is_add = is_add;
15374   mp->sw_if_index = ntohl (sw_if_index);
15375   mp->priority = priority;
15376   mp->weight = weight;
15377   clib_memcpy (mp->locator_set_name, locator_set_name,
15378                vec_len (locator_set_name));
15379   vec_free (locator_set_name);
15380
15381   /* send it... */
15382   S (mp);
15383
15384   /* Wait for a reply... */
15385   W (ret);
15386   return ret;
15387 }
15388
15389 #define api_lisp_add_del_locator api_one_add_del_locator
15390
15391 uword
15392 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15393 {
15394   u32 *key_id = va_arg (*args, u32 *);
15395   u8 *s = 0;
15396
15397   if (unformat (input, "%s", &s))
15398     {
15399       if (!strcmp ((char *) s, "sha1"))
15400         key_id[0] = HMAC_SHA_1_96;
15401       else if (!strcmp ((char *) s, "sha256"))
15402         key_id[0] = HMAC_SHA_256_128;
15403       else
15404         {
15405           clib_warning ("invalid key_id: '%s'", s);
15406           key_id[0] = HMAC_NO_KEY;
15407         }
15408     }
15409   else
15410     return 0;
15411
15412   vec_free (s);
15413   return 1;
15414 }
15415
15416 static int
15417 api_one_add_del_local_eid (vat_main_t * vam)
15418 {
15419   unformat_input_t *input = vam->input;
15420   vl_api_one_add_del_local_eid_t *mp;
15421   u8 is_add = 1;
15422   u8 eid_set = 0;
15423   lisp_eid_vat_t _eid, *eid = &_eid;
15424   u8 *locator_set_name = 0;
15425   u8 locator_set_name_set = 0;
15426   u32 vni = 0;
15427   u16 key_id = 0;
15428   u8 *key = 0;
15429   int ret;
15430
15431   /* Parse args required to build the message */
15432   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15433     {
15434       if (unformat (input, "del"))
15435         {
15436           is_add = 0;
15437         }
15438       else if (unformat (input, "vni %d", &vni))
15439         {
15440           ;
15441         }
15442       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15443         {
15444           eid_set = 1;
15445         }
15446       else if (unformat (input, "locator-set %s", &locator_set_name))
15447         {
15448           locator_set_name_set = 1;
15449         }
15450       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15451         ;
15452       else if (unformat (input, "secret-key %_%v%_", &key))
15453         ;
15454       else
15455         break;
15456     }
15457
15458   if (locator_set_name_set == 0)
15459     {
15460       errmsg ("missing locator-set name");
15461       return -99;
15462     }
15463
15464   if (0 == eid_set)
15465     {
15466       errmsg ("EID address not set!");
15467       vec_free (locator_set_name);
15468       return -99;
15469     }
15470
15471   if (key && (0 == key_id))
15472     {
15473       errmsg ("invalid key_id!");
15474       return -99;
15475     }
15476
15477   if (vec_len (key) > 64)
15478     {
15479       errmsg ("key too long");
15480       vec_free (key);
15481       return -99;
15482     }
15483
15484   if (vec_len (locator_set_name) > 64)
15485     {
15486       errmsg ("locator-set name too long");
15487       vec_free (locator_set_name);
15488       return -99;
15489     }
15490   vec_add1 (locator_set_name, 0);
15491
15492   /* Construct the API message */
15493   M (ONE_ADD_DEL_LOCAL_EID, mp);
15494
15495   mp->is_add = is_add;
15496   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15497   mp->eid_type = eid->type;
15498   mp->prefix_len = eid->len;
15499   mp->vni = clib_host_to_net_u32 (vni);
15500   mp->key_id = clib_host_to_net_u16 (key_id);
15501   clib_memcpy (mp->locator_set_name, locator_set_name,
15502                vec_len (locator_set_name));
15503   clib_memcpy (mp->key, key, vec_len (key));
15504
15505   vec_free (locator_set_name);
15506   vec_free (key);
15507
15508   /* send it... */
15509   S (mp);
15510
15511   /* Wait for a reply... */
15512   W (ret);
15513   return ret;
15514 }
15515
15516 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15517
15518 static int
15519 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
15520 {
15521   u32 dp_table = 0, vni = 0;;
15522   unformat_input_t *input = vam->input;
15523   vl_api_gpe_add_del_fwd_entry_t *mp;
15524   u8 is_add = 1;
15525   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
15526   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
15527   u8 rmt_eid_set = 0, lcl_eid_set = 0;
15528   u32 action = ~0, w;
15529   ip4_address_t rmt_rloc4, lcl_rloc4;
15530   ip6_address_t rmt_rloc6, lcl_rloc6;
15531   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
15532   int ret;
15533
15534   clib_memset (&rloc, 0, sizeof (rloc));
15535
15536   /* Parse args required to build the message */
15537   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15538     {
15539       if (unformat (input, "del"))
15540         is_add = 0;
15541       else if (unformat (input, "add"))
15542         is_add = 1;
15543       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
15544         {
15545           rmt_eid_set = 1;
15546         }
15547       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
15548         {
15549           lcl_eid_set = 1;
15550         }
15551       else if (unformat (input, "vrf %d", &dp_table))
15552         ;
15553       else if (unformat (input, "bd %d", &dp_table))
15554         ;
15555       else if (unformat (input, "vni %d", &vni))
15556         ;
15557       else if (unformat (input, "w %d", &w))
15558         {
15559           if (!curr_rloc)
15560             {
15561               errmsg ("No RLOC configured for setting priority/weight!");
15562               return -99;
15563             }
15564           curr_rloc->weight = w;
15565         }
15566       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
15567                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
15568         {
15569           rloc.is_ip4 = 1;
15570
15571           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
15572           rloc.weight = 0;
15573           vec_add1 (lcl_locs, rloc);
15574
15575           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
15576           vec_add1 (rmt_locs, rloc);
15577           /* weight saved in rmt loc */
15578           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15579         }
15580       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
15581                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
15582         {
15583           rloc.is_ip4 = 0;
15584           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
15585           rloc.weight = 0;
15586           vec_add1 (lcl_locs, rloc);
15587
15588           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
15589           vec_add1 (rmt_locs, rloc);
15590           /* weight saved in rmt loc */
15591           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15592         }
15593       else if (unformat (input, "action %d", &action))
15594         {
15595           ;
15596         }
15597       else
15598         {
15599           clib_warning ("parse error '%U'", format_unformat_error, input);
15600           return -99;
15601         }
15602     }
15603
15604   if (!rmt_eid_set)
15605     {
15606       errmsg ("remote eid addresses not set");
15607       return -99;
15608     }
15609
15610   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
15611     {
15612       errmsg ("eid types don't match");
15613       return -99;
15614     }
15615
15616   if (0 == rmt_locs && (u32) ~ 0 == action)
15617     {
15618       errmsg ("action not set for negative mapping");
15619       return -99;
15620     }
15621
15622   /* Construct the API message */
15623   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
15624       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
15625
15626   mp->is_add = is_add;
15627   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
15628   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
15629   mp->eid_type = rmt_eid->type;
15630   mp->dp_table = clib_host_to_net_u32 (dp_table);
15631   mp->vni = clib_host_to_net_u32 (vni);
15632   mp->rmt_len = rmt_eid->len;
15633   mp->lcl_len = lcl_eid->len;
15634   mp->action = action;
15635
15636   if (0 != rmt_locs && 0 != lcl_locs)
15637     {
15638       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
15639       clib_memcpy (mp->locs, lcl_locs,
15640                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
15641
15642       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
15643       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
15644                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
15645     }
15646   vec_free (lcl_locs);
15647   vec_free (rmt_locs);
15648
15649   /* send it... */
15650   S (mp);
15651
15652   /* Wait for a reply... */
15653   W (ret);
15654   return ret;
15655 }
15656
15657 static int
15658 api_one_add_del_map_server (vat_main_t * vam)
15659 {
15660   unformat_input_t *input = vam->input;
15661   vl_api_one_add_del_map_server_t *mp;
15662   u8 is_add = 1;
15663   u8 ipv4_set = 0;
15664   u8 ipv6_set = 0;
15665   ip4_address_t ipv4;
15666   ip6_address_t ipv6;
15667   int ret;
15668
15669   /* Parse args required to build the message */
15670   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15671     {
15672       if (unformat (input, "del"))
15673         {
15674           is_add = 0;
15675         }
15676       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15677         {
15678           ipv4_set = 1;
15679         }
15680       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15681         {
15682           ipv6_set = 1;
15683         }
15684       else
15685         break;
15686     }
15687
15688   if (ipv4_set && ipv6_set)
15689     {
15690       errmsg ("both eid v4 and v6 addresses set");
15691       return -99;
15692     }
15693
15694   if (!ipv4_set && !ipv6_set)
15695     {
15696       errmsg ("eid addresses not set");
15697       return -99;
15698     }
15699
15700   /* Construct the API message */
15701   M (ONE_ADD_DEL_MAP_SERVER, mp);
15702
15703   mp->is_add = is_add;
15704   if (ipv6_set)
15705     {
15706       mp->is_ipv6 = 1;
15707       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15708     }
15709   else
15710     {
15711       mp->is_ipv6 = 0;
15712       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15713     }
15714
15715   /* send it... */
15716   S (mp);
15717
15718   /* Wait for a reply... */
15719   W (ret);
15720   return ret;
15721 }
15722
15723 #define api_lisp_add_del_map_server api_one_add_del_map_server
15724
15725 static int
15726 api_one_add_del_map_resolver (vat_main_t * vam)
15727 {
15728   unformat_input_t *input = vam->input;
15729   vl_api_one_add_del_map_resolver_t *mp;
15730   u8 is_add = 1;
15731   u8 ipv4_set = 0;
15732   u8 ipv6_set = 0;
15733   ip4_address_t ipv4;
15734   ip6_address_t ipv6;
15735   int ret;
15736
15737   /* Parse args required to build the message */
15738   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15739     {
15740       if (unformat (input, "del"))
15741         {
15742           is_add = 0;
15743         }
15744       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15745         {
15746           ipv4_set = 1;
15747         }
15748       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15749         {
15750           ipv6_set = 1;
15751         }
15752       else
15753         break;
15754     }
15755
15756   if (ipv4_set && ipv6_set)
15757     {
15758       errmsg ("both eid v4 and v6 addresses set");
15759       return -99;
15760     }
15761
15762   if (!ipv4_set && !ipv6_set)
15763     {
15764       errmsg ("eid addresses not set");
15765       return -99;
15766     }
15767
15768   /* Construct the API message */
15769   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
15770
15771   mp->is_add = is_add;
15772   if (ipv6_set)
15773     {
15774       mp->is_ipv6 = 1;
15775       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15776     }
15777   else
15778     {
15779       mp->is_ipv6 = 0;
15780       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15781     }
15782
15783   /* send it... */
15784   S (mp);
15785
15786   /* Wait for a reply... */
15787   W (ret);
15788   return ret;
15789 }
15790
15791 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
15792
15793 static int
15794 api_lisp_gpe_enable_disable (vat_main_t * vam)
15795 {
15796   unformat_input_t *input = vam->input;
15797   vl_api_gpe_enable_disable_t *mp;
15798   u8 is_set = 0;
15799   u8 is_en = 1;
15800   int ret;
15801
15802   /* Parse args required to build the message */
15803   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15804     {
15805       if (unformat (input, "enable"))
15806         {
15807           is_set = 1;
15808           is_en = 1;
15809         }
15810       else if (unformat (input, "disable"))
15811         {
15812           is_set = 1;
15813           is_en = 0;
15814         }
15815       else
15816         break;
15817     }
15818
15819   if (is_set == 0)
15820     {
15821       errmsg ("Value not set");
15822       return -99;
15823     }
15824
15825   /* Construct the API message */
15826   M (GPE_ENABLE_DISABLE, mp);
15827
15828   mp->is_en = is_en;
15829
15830   /* send it... */
15831   S (mp);
15832
15833   /* Wait for a reply... */
15834   W (ret);
15835   return ret;
15836 }
15837
15838 static int
15839 api_one_rloc_probe_enable_disable (vat_main_t * vam)
15840 {
15841   unformat_input_t *input = vam->input;
15842   vl_api_one_rloc_probe_enable_disable_t *mp;
15843   u8 is_set = 0;
15844   u8 is_en = 0;
15845   int ret;
15846
15847   /* Parse args required to build the message */
15848   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15849     {
15850       if (unformat (input, "enable"))
15851         {
15852           is_set = 1;
15853           is_en = 1;
15854         }
15855       else if (unformat (input, "disable"))
15856         is_set = 1;
15857       else
15858         break;
15859     }
15860
15861   if (!is_set)
15862     {
15863       errmsg ("Value not set");
15864       return -99;
15865     }
15866
15867   /* Construct the API message */
15868   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
15869
15870   mp->is_enabled = is_en;
15871
15872   /* send it... */
15873   S (mp);
15874
15875   /* Wait for a reply... */
15876   W (ret);
15877   return ret;
15878 }
15879
15880 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
15881
15882 static int
15883 api_one_map_register_enable_disable (vat_main_t * vam)
15884 {
15885   unformat_input_t *input = vam->input;
15886   vl_api_one_map_register_enable_disable_t *mp;
15887   u8 is_set = 0;
15888   u8 is_en = 0;
15889   int ret;
15890
15891   /* Parse args required to build the message */
15892   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15893     {
15894       if (unformat (input, "enable"))
15895         {
15896           is_set = 1;
15897           is_en = 1;
15898         }
15899       else if (unformat (input, "disable"))
15900         is_set = 1;
15901       else
15902         break;
15903     }
15904
15905   if (!is_set)
15906     {
15907       errmsg ("Value not set");
15908       return -99;
15909     }
15910
15911   /* Construct the API message */
15912   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
15913
15914   mp->is_enabled = is_en;
15915
15916   /* send it... */
15917   S (mp);
15918
15919   /* Wait for a reply... */
15920   W (ret);
15921   return ret;
15922 }
15923
15924 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
15925
15926 static int
15927 api_one_enable_disable (vat_main_t * vam)
15928 {
15929   unformat_input_t *input = vam->input;
15930   vl_api_one_enable_disable_t *mp;
15931   u8 is_set = 0;
15932   u8 is_en = 0;
15933   int ret;
15934
15935   /* Parse args required to build the message */
15936   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15937     {
15938       if (unformat (input, "enable"))
15939         {
15940           is_set = 1;
15941           is_en = 1;
15942         }
15943       else if (unformat (input, "disable"))
15944         {
15945           is_set = 1;
15946         }
15947       else
15948         break;
15949     }
15950
15951   if (!is_set)
15952     {
15953       errmsg ("Value not set");
15954       return -99;
15955     }
15956
15957   /* Construct the API message */
15958   M (ONE_ENABLE_DISABLE, mp);
15959
15960   mp->is_en = is_en;
15961
15962   /* send it... */
15963   S (mp);
15964
15965   /* Wait for a reply... */
15966   W (ret);
15967   return ret;
15968 }
15969
15970 #define api_lisp_enable_disable api_one_enable_disable
15971
15972 static int
15973 api_one_enable_disable_xtr_mode (vat_main_t * vam)
15974 {
15975   unformat_input_t *input = vam->input;
15976   vl_api_one_enable_disable_xtr_mode_t *mp;
15977   u8 is_set = 0;
15978   u8 is_en = 0;
15979   int ret;
15980
15981   /* Parse args required to build the message */
15982   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15983     {
15984       if (unformat (input, "enable"))
15985         {
15986           is_set = 1;
15987           is_en = 1;
15988         }
15989       else if (unformat (input, "disable"))
15990         {
15991           is_set = 1;
15992         }
15993       else
15994         break;
15995     }
15996
15997   if (!is_set)
15998     {
15999       errmsg ("Value not set");
16000       return -99;
16001     }
16002
16003   /* Construct the API message */
16004   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
16005
16006   mp->is_en = is_en;
16007
16008   /* send it... */
16009   S (mp);
16010
16011   /* Wait for a reply... */
16012   W (ret);
16013   return ret;
16014 }
16015
16016 static int
16017 api_one_show_xtr_mode (vat_main_t * vam)
16018 {
16019   vl_api_one_show_xtr_mode_t *mp;
16020   int ret;
16021
16022   /* Construct the API message */
16023   M (ONE_SHOW_XTR_MODE, mp);
16024
16025   /* send it... */
16026   S (mp);
16027
16028   /* Wait for a reply... */
16029   W (ret);
16030   return ret;
16031 }
16032
16033 static int
16034 api_one_enable_disable_pitr_mode (vat_main_t * vam)
16035 {
16036   unformat_input_t *input = vam->input;
16037   vl_api_one_enable_disable_pitr_mode_t *mp;
16038   u8 is_set = 0;
16039   u8 is_en = 0;
16040   int ret;
16041
16042   /* Parse args required to build the message */
16043   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16044     {
16045       if (unformat (input, "enable"))
16046         {
16047           is_set = 1;
16048           is_en = 1;
16049         }
16050       else if (unformat (input, "disable"))
16051         {
16052           is_set = 1;
16053         }
16054       else
16055         break;
16056     }
16057
16058   if (!is_set)
16059     {
16060       errmsg ("Value not set");
16061       return -99;
16062     }
16063
16064   /* Construct the API message */
16065   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
16066
16067   mp->is_en = is_en;
16068
16069   /* send it... */
16070   S (mp);
16071
16072   /* Wait for a reply... */
16073   W (ret);
16074   return ret;
16075 }
16076
16077 static int
16078 api_one_show_pitr_mode (vat_main_t * vam)
16079 {
16080   vl_api_one_show_pitr_mode_t *mp;
16081   int ret;
16082
16083   /* Construct the API message */
16084   M (ONE_SHOW_PITR_MODE, mp);
16085
16086   /* send it... */
16087   S (mp);
16088
16089   /* Wait for a reply... */
16090   W (ret);
16091   return ret;
16092 }
16093
16094 static int
16095 api_one_enable_disable_petr_mode (vat_main_t * vam)
16096 {
16097   unformat_input_t *input = vam->input;
16098   vl_api_one_enable_disable_petr_mode_t *mp;
16099   u8 is_set = 0;
16100   u8 is_en = 0;
16101   int ret;
16102
16103   /* Parse args required to build the message */
16104   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16105     {
16106       if (unformat (input, "enable"))
16107         {
16108           is_set = 1;
16109           is_en = 1;
16110         }
16111       else if (unformat (input, "disable"))
16112         {
16113           is_set = 1;
16114         }
16115       else
16116         break;
16117     }
16118
16119   if (!is_set)
16120     {
16121       errmsg ("Value not set");
16122       return -99;
16123     }
16124
16125   /* Construct the API message */
16126   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
16127
16128   mp->is_en = is_en;
16129
16130   /* send it... */
16131   S (mp);
16132
16133   /* Wait for a reply... */
16134   W (ret);
16135   return ret;
16136 }
16137
16138 static int
16139 api_one_show_petr_mode (vat_main_t * vam)
16140 {
16141   vl_api_one_show_petr_mode_t *mp;
16142   int ret;
16143
16144   /* Construct the API message */
16145   M (ONE_SHOW_PETR_MODE, mp);
16146
16147   /* send it... */
16148   S (mp);
16149
16150   /* Wait for a reply... */
16151   W (ret);
16152   return ret;
16153 }
16154
16155 static int
16156 api_show_one_map_register_state (vat_main_t * vam)
16157 {
16158   vl_api_show_one_map_register_state_t *mp;
16159   int ret;
16160
16161   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
16162
16163   /* send */
16164   S (mp);
16165
16166   /* wait for reply */
16167   W (ret);
16168   return ret;
16169 }
16170
16171 #define api_show_lisp_map_register_state api_show_one_map_register_state
16172
16173 static int
16174 api_show_one_rloc_probe_state (vat_main_t * vam)
16175 {
16176   vl_api_show_one_rloc_probe_state_t *mp;
16177   int ret;
16178
16179   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
16180
16181   /* send */
16182   S (mp);
16183
16184   /* wait for reply */
16185   W (ret);
16186   return ret;
16187 }
16188
16189 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
16190
16191 static int
16192 api_one_add_del_ndp_entry (vat_main_t * vam)
16193 {
16194   vl_api_one_add_del_ndp_entry_t *mp;
16195   unformat_input_t *input = vam->input;
16196   u8 is_add = 1;
16197   u8 mac_set = 0;
16198   u8 bd_set = 0;
16199   u8 ip_set = 0;
16200   u8 mac[6] = { 0, };
16201   u8 ip6[16] = { 0, };
16202   u32 bd = ~0;
16203   int ret;
16204
16205   /* Parse args required to build the message */
16206   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16207     {
16208       if (unformat (input, "del"))
16209         is_add = 0;
16210       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16211         mac_set = 1;
16212       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
16213         ip_set = 1;
16214       else if (unformat (input, "bd %d", &bd))
16215         bd_set = 1;
16216       else
16217         {
16218           errmsg ("parse error '%U'", format_unformat_error, input);
16219           return -99;
16220         }
16221     }
16222
16223   if (!bd_set || !ip_set || (!mac_set && is_add))
16224     {
16225       errmsg ("Missing BD, IP or MAC!");
16226       return -99;
16227     }
16228
16229   M (ONE_ADD_DEL_NDP_ENTRY, mp);
16230   mp->is_add = is_add;
16231   clib_memcpy (mp->mac, mac, 6);
16232   mp->bd = clib_host_to_net_u32 (bd);
16233   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
16234
16235   /* send */
16236   S (mp);
16237
16238   /* wait for reply */
16239   W (ret);
16240   return ret;
16241 }
16242
16243 static int
16244 api_one_add_del_l2_arp_entry (vat_main_t * vam)
16245 {
16246   vl_api_one_add_del_l2_arp_entry_t *mp;
16247   unformat_input_t *input = vam->input;
16248   u8 is_add = 1;
16249   u8 mac_set = 0;
16250   u8 bd_set = 0;
16251   u8 ip_set = 0;
16252   u8 mac[6] = { 0, };
16253   u32 ip4 = 0, bd = ~0;
16254   int ret;
16255
16256   /* Parse args required to build the message */
16257   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16258     {
16259       if (unformat (input, "del"))
16260         is_add = 0;
16261       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16262         mac_set = 1;
16263       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
16264         ip_set = 1;
16265       else if (unformat (input, "bd %d", &bd))
16266         bd_set = 1;
16267       else
16268         {
16269           errmsg ("parse error '%U'", format_unformat_error, input);
16270           return -99;
16271         }
16272     }
16273
16274   if (!bd_set || !ip_set || (!mac_set && is_add))
16275     {
16276       errmsg ("Missing BD, IP or MAC!");
16277       return -99;
16278     }
16279
16280   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
16281   mp->is_add = is_add;
16282   clib_memcpy (mp->mac, mac, 6);
16283   mp->bd = clib_host_to_net_u32 (bd);
16284   mp->ip4 = ip4;
16285
16286   /* send */
16287   S (mp);
16288
16289   /* wait for reply */
16290   W (ret);
16291   return ret;
16292 }
16293
16294 static int
16295 api_one_ndp_bd_get (vat_main_t * vam)
16296 {
16297   vl_api_one_ndp_bd_get_t *mp;
16298   int ret;
16299
16300   M (ONE_NDP_BD_GET, mp);
16301
16302   /* send */
16303   S (mp);
16304
16305   /* wait for reply */
16306   W (ret);
16307   return ret;
16308 }
16309
16310 static int
16311 api_one_ndp_entries_get (vat_main_t * vam)
16312 {
16313   vl_api_one_ndp_entries_get_t *mp;
16314   unformat_input_t *input = vam->input;
16315   u8 bd_set = 0;
16316   u32 bd = ~0;
16317   int ret;
16318
16319   /* Parse args required to build the message */
16320   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16321     {
16322       if (unformat (input, "bd %d", &bd))
16323         bd_set = 1;
16324       else
16325         {
16326           errmsg ("parse error '%U'", format_unformat_error, input);
16327           return -99;
16328         }
16329     }
16330
16331   if (!bd_set)
16332     {
16333       errmsg ("Expected bridge domain!");
16334       return -99;
16335     }
16336
16337   M (ONE_NDP_ENTRIES_GET, mp);
16338   mp->bd = clib_host_to_net_u32 (bd);
16339
16340   /* send */
16341   S (mp);
16342
16343   /* wait for reply */
16344   W (ret);
16345   return ret;
16346 }
16347
16348 static int
16349 api_one_l2_arp_bd_get (vat_main_t * vam)
16350 {
16351   vl_api_one_l2_arp_bd_get_t *mp;
16352   int ret;
16353
16354   M (ONE_L2_ARP_BD_GET, mp);
16355
16356   /* send */
16357   S (mp);
16358
16359   /* wait for reply */
16360   W (ret);
16361   return ret;
16362 }
16363
16364 static int
16365 api_one_l2_arp_entries_get (vat_main_t * vam)
16366 {
16367   vl_api_one_l2_arp_entries_get_t *mp;
16368   unformat_input_t *input = vam->input;
16369   u8 bd_set = 0;
16370   u32 bd = ~0;
16371   int ret;
16372
16373   /* Parse args required to build the message */
16374   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16375     {
16376       if (unformat (input, "bd %d", &bd))
16377         bd_set = 1;
16378       else
16379         {
16380           errmsg ("parse error '%U'", format_unformat_error, input);
16381           return -99;
16382         }
16383     }
16384
16385   if (!bd_set)
16386     {
16387       errmsg ("Expected bridge domain!");
16388       return -99;
16389     }
16390
16391   M (ONE_L2_ARP_ENTRIES_GET, mp);
16392   mp->bd = clib_host_to_net_u32 (bd);
16393
16394   /* send */
16395   S (mp);
16396
16397   /* wait for reply */
16398   W (ret);
16399   return ret;
16400 }
16401
16402 static int
16403 api_one_stats_enable_disable (vat_main_t * vam)
16404 {
16405   vl_api_one_stats_enable_disable_t *mp;
16406   unformat_input_t *input = vam->input;
16407   u8 is_set = 0;
16408   u8 is_en = 0;
16409   int ret;
16410
16411   /* Parse args required to build the message */
16412   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16413     {
16414       if (unformat (input, "enable"))
16415         {
16416           is_set = 1;
16417           is_en = 1;
16418         }
16419       else if (unformat (input, "disable"))
16420         {
16421           is_set = 1;
16422         }
16423       else
16424         break;
16425     }
16426
16427   if (!is_set)
16428     {
16429       errmsg ("Value not set");
16430       return -99;
16431     }
16432
16433   M (ONE_STATS_ENABLE_DISABLE, mp);
16434   mp->is_en = is_en;
16435
16436   /* send */
16437   S (mp);
16438
16439   /* wait for reply */
16440   W (ret);
16441   return ret;
16442 }
16443
16444 static int
16445 api_show_one_stats_enable_disable (vat_main_t * vam)
16446 {
16447   vl_api_show_one_stats_enable_disable_t *mp;
16448   int ret;
16449
16450   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16451
16452   /* send */
16453   S (mp);
16454
16455   /* wait for reply */
16456   W (ret);
16457   return ret;
16458 }
16459
16460 static int
16461 api_show_one_map_request_mode (vat_main_t * vam)
16462 {
16463   vl_api_show_one_map_request_mode_t *mp;
16464   int ret;
16465
16466   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16467
16468   /* send */
16469   S (mp);
16470
16471   /* wait for reply */
16472   W (ret);
16473   return ret;
16474 }
16475
16476 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16477
16478 static int
16479 api_one_map_request_mode (vat_main_t * vam)
16480 {
16481   unformat_input_t *input = vam->input;
16482   vl_api_one_map_request_mode_t *mp;
16483   u8 mode = 0;
16484   int ret;
16485
16486   /* Parse args required to build the message */
16487   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16488     {
16489       if (unformat (input, "dst-only"))
16490         mode = 0;
16491       else if (unformat (input, "src-dst"))
16492         mode = 1;
16493       else
16494         {
16495           errmsg ("parse error '%U'", format_unformat_error, input);
16496           return -99;
16497         }
16498     }
16499
16500   M (ONE_MAP_REQUEST_MODE, mp);
16501
16502   mp->mode = mode;
16503
16504   /* send */
16505   S (mp);
16506
16507   /* wait for reply */
16508   W (ret);
16509   return ret;
16510 }
16511
16512 #define api_lisp_map_request_mode api_one_map_request_mode
16513
16514 /**
16515  * Enable/disable ONE proxy ITR.
16516  *
16517  * @param vam vpp API test context
16518  * @return return code
16519  */
16520 static int
16521 api_one_pitr_set_locator_set (vat_main_t * vam)
16522 {
16523   u8 ls_name_set = 0;
16524   unformat_input_t *input = vam->input;
16525   vl_api_one_pitr_set_locator_set_t *mp;
16526   u8 is_add = 1;
16527   u8 *ls_name = 0;
16528   int ret;
16529
16530   /* Parse args required to build the message */
16531   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16532     {
16533       if (unformat (input, "del"))
16534         is_add = 0;
16535       else if (unformat (input, "locator-set %s", &ls_name))
16536         ls_name_set = 1;
16537       else
16538         {
16539           errmsg ("parse error '%U'", format_unformat_error, input);
16540           return -99;
16541         }
16542     }
16543
16544   if (!ls_name_set)
16545     {
16546       errmsg ("locator-set name not set!");
16547       return -99;
16548     }
16549
16550   M (ONE_PITR_SET_LOCATOR_SET, mp);
16551
16552   mp->is_add = is_add;
16553   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16554   vec_free (ls_name);
16555
16556   /* send */
16557   S (mp);
16558
16559   /* wait for reply */
16560   W (ret);
16561   return ret;
16562 }
16563
16564 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
16565
16566 static int
16567 api_one_nsh_set_locator_set (vat_main_t * vam)
16568 {
16569   u8 ls_name_set = 0;
16570   unformat_input_t *input = vam->input;
16571   vl_api_one_nsh_set_locator_set_t *mp;
16572   u8 is_add = 1;
16573   u8 *ls_name = 0;
16574   int ret;
16575
16576   /* Parse args required to build the message */
16577   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16578     {
16579       if (unformat (input, "del"))
16580         is_add = 0;
16581       else if (unformat (input, "ls %s", &ls_name))
16582         ls_name_set = 1;
16583       else
16584         {
16585           errmsg ("parse error '%U'", format_unformat_error, input);
16586           return -99;
16587         }
16588     }
16589
16590   if (!ls_name_set && is_add)
16591     {
16592       errmsg ("locator-set name not set!");
16593       return -99;
16594     }
16595
16596   M (ONE_NSH_SET_LOCATOR_SET, mp);
16597
16598   mp->is_add = is_add;
16599   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16600   vec_free (ls_name);
16601
16602   /* send */
16603   S (mp);
16604
16605   /* wait for reply */
16606   W (ret);
16607   return ret;
16608 }
16609
16610 static int
16611 api_show_one_pitr (vat_main_t * vam)
16612 {
16613   vl_api_show_one_pitr_t *mp;
16614   int ret;
16615
16616   if (!vam->json_output)
16617     {
16618       print (vam->ofp, "%=20s", "lisp status:");
16619     }
16620
16621   M (SHOW_ONE_PITR, mp);
16622   /* send it... */
16623   S (mp);
16624
16625   /* Wait for a reply... */
16626   W (ret);
16627   return ret;
16628 }
16629
16630 #define api_show_lisp_pitr api_show_one_pitr
16631
16632 static int
16633 api_one_use_petr (vat_main_t * vam)
16634 {
16635   unformat_input_t *input = vam->input;
16636   vl_api_one_use_petr_t *mp;
16637   u8 is_add = 0;
16638   ip_address_t ip;
16639   int ret;
16640
16641   clib_memset (&ip, 0, sizeof (ip));
16642
16643   /* Parse args required to build the message */
16644   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16645     {
16646       if (unformat (input, "disable"))
16647         is_add = 0;
16648       else
16649         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
16650         {
16651           is_add = 1;
16652           ip_addr_version (&ip) = IP4;
16653         }
16654       else
16655         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
16656         {
16657           is_add = 1;
16658           ip_addr_version (&ip) = IP6;
16659         }
16660       else
16661         {
16662           errmsg ("parse error '%U'", format_unformat_error, input);
16663           return -99;
16664         }
16665     }
16666
16667   M (ONE_USE_PETR, mp);
16668
16669   mp->is_add = is_add;
16670   if (is_add)
16671     {
16672       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
16673       if (mp->is_ip4)
16674         clib_memcpy (mp->address, &ip, 4);
16675       else
16676         clib_memcpy (mp->address, &ip, 16);
16677     }
16678
16679   /* send */
16680   S (mp);
16681
16682   /* wait for reply */
16683   W (ret);
16684   return ret;
16685 }
16686
16687 #define api_lisp_use_petr api_one_use_petr
16688
16689 static int
16690 api_show_one_nsh_mapping (vat_main_t * vam)
16691 {
16692   vl_api_show_one_use_petr_t *mp;
16693   int ret;
16694
16695   if (!vam->json_output)
16696     {
16697       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
16698     }
16699
16700   M (SHOW_ONE_NSH_MAPPING, mp);
16701   /* send it... */
16702   S (mp);
16703
16704   /* Wait for a reply... */
16705   W (ret);
16706   return ret;
16707 }
16708
16709 static int
16710 api_show_one_use_petr (vat_main_t * vam)
16711 {
16712   vl_api_show_one_use_petr_t *mp;
16713   int ret;
16714
16715   if (!vam->json_output)
16716     {
16717       print (vam->ofp, "%=20s", "Proxy-ETR status:");
16718     }
16719
16720   M (SHOW_ONE_USE_PETR, mp);
16721   /* send it... */
16722   S (mp);
16723
16724   /* Wait for a reply... */
16725   W (ret);
16726   return ret;
16727 }
16728
16729 #define api_show_lisp_use_petr api_show_one_use_petr
16730
16731 /**
16732  * Add/delete mapping between vni and vrf
16733  */
16734 static int
16735 api_one_eid_table_add_del_map (vat_main_t * vam)
16736 {
16737   unformat_input_t *input = vam->input;
16738   vl_api_one_eid_table_add_del_map_t *mp;
16739   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
16740   u32 vni, vrf, bd_index;
16741   int ret;
16742
16743   /* Parse args required to build the message */
16744   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16745     {
16746       if (unformat (input, "del"))
16747         is_add = 0;
16748       else if (unformat (input, "vrf %d", &vrf))
16749         vrf_set = 1;
16750       else if (unformat (input, "bd_index %d", &bd_index))
16751         bd_index_set = 1;
16752       else if (unformat (input, "vni %d", &vni))
16753         vni_set = 1;
16754       else
16755         break;
16756     }
16757
16758   if (!vni_set || (!vrf_set && !bd_index_set))
16759     {
16760       errmsg ("missing arguments!");
16761       return -99;
16762     }
16763
16764   if (vrf_set && bd_index_set)
16765     {
16766       errmsg ("error: both vrf and bd entered!");
16767       return -99;
16768     }
16769
16770   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
16771
16772   mp->is_add = is_add;
16773   mp->vni = htonl (vni);
16774   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
16775   mp->is_l2 = bd_index_set;
16776
16777   /* send */
16778   S (mp);
16779
16780   /* wait for reply */
16781   W (ret);
16782   return ret;
16783 }
16784
16785 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
16786
16787 uword
16788 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
16789 {
16790   u32 *action = va_arg (*args, u32 *);
16791   u8 *s = 0;
16792
16793   if (unformat (input, "%s", &s))
16794     {
16795       if (!strcmp ((char *) s, "no-action"))
16796         action[0] = 0;
16797       else if (!strcmp ((char *) s, "natively-forward"))
16798         action[0] = 1;
16799       else if (!strcmp ((char *) s, "send-map-request"))
16800         action[0] = 2;
16801       else if (!strcmp ((char *) s, "drop"))
16802         action[0] = 3;
16803       else
16804         {
16805           clib_warning ("invalid action: '%s'", s);
16806           action[0] = 3;
16807         }
16808     }
16809   else
16810     return 0;
16811
16812   vec_free (s);
16813   return 1;
16814 }
16815
16816 /**
16817  * Add/del remote mapping to/from ONE control plane
16818  *
16819  * @param vam vpp API test context
16820  * @return return code
16821  */
16822 static int
16823 api_one_add_del_remote_mapping (vat_main_t * vam)
16824 {
16825   unformat_input_t *input = vam->input;
16826   vl_api_one_add_del_remote_mapping_t *mp;
16827   u32 vni = 0;
16828   lisp_eid_vat_t _eid, *eid = &_eid;
16829   lisp_eid_vat_t _seid, *seid = &_seid;
16830   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
16831   u32 action = ~0, p, w, data_len;
16832   ip4_address_t rloc4;
16833   ip6_address_t rloc6;
16834   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
16835   int ret;
16836
16837   clib_memset (&rloc, 0, sizeof (rloc));
16838
16839   /* Parse args required to build the message */
16840   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16841     {
16842       if (unformat (input, "del-all"))
16843         {
16844           del_all = 1;
16845         }
16846       else if (unformat (input, "del"))
16847         {
16848           is_add = 0;
16849         }
16850       else if (unformat (input, "add"))
16851         {
16852           is_add = 1;
16853         }
16854       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16855         {
16856           eid_set = 1;
16857         }
16858       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
16859         {
16860           seid_set = 1;
16861         }
16862       else if (unformat (input, "vni %d", &vni))
16863         {
16864           ;
16865         }
16866       else if (unformat (input, "p %d w %d", &p, &w))
16867         {
16868           if (!curr_rloc)
16869             {
16870               errmsg ("No RLOC configured for setting priority/weight!");
16871               return -99;
16872             }
16873           curr_rloc->priority = p;
16874           curr_rloc->weight = w;
16875         }
16876       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
16877         {
16878           rloc.is_ip4 = 1;
16879           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
16880           vec_add1 (rlocs, rloc);
16881           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16882         }
16883       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
16884         {
16885           rloc.is_ip4 = 0;
16886           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
16887           vec_add1 (rlocs, rloc);
16888           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16889         }
16890       else if (unformat (input, "action %U",
16891                          unformat_negative_mapping_action, &action))
16892         {
16893           ;
16894         }
16895       else
16896         {
16897           clib_warning ("parse error '%U'", format_unformat_error, input);
16898           return -99;
16899         }
16900     }
16901
16902   if (0 == eid_set)
16903     {
16904       errmsg ("missing params!");
16905       return -99;
16906     }
16907
16908   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
16909     {
16910       errmsg ("no action set for negative map-reply!");
16911       return -99;
16912     }
16913
16914   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
16915
16916   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
16917   mp->is_add = is_add;
16918   mp->vni = htonl (vni);
16919   mp->action = (u8) action;
16920   mp->is_src_dst = seid_set;
16921   mp->eid_len = eid->len;
16922   mp->seid_len = seid->len;
16923   mp->del_all = del_all;
16924   mp->eid_type = eid->type;
16925   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16926   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
16927
16928   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
16929   clib_memcpy (mp->rlocs, rlocs, data_len);
16930   vec_free (rlocs);
16931
16932   /* send it... */
16933   S (mp);
16934
16935   /* Wait for a reply... */
16936   W (ret);
16937   return ret;
16938 }
16939
16940 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
16941
16942 /**
16943  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
16944  * forwarding entries in data-plane accordingly.
16945  *
16946  * @param vam vpp API test context
16947  * @return return code
16948  */
16949 static int
16950 api_one_add_del_adjacency (vat_main_t * vam)
16951 {
16952   unformat_input_t *input = vam->input;
16953   vl_api_one_add_del_adjacency_t *mp;
16954   u32 vni = 0;
16955   ip4_address_t leid4, reid4;
16956   ip6_address_t leid6, reid6;
16957   u8 reid_mac[6] = { 0 };
16958   u8 leid_mac[6] = { 0 };
16959   u8 reid_type, leid_type;
16960   u32 leid_len = 0, reid_len = 0, len;
16961   u8 is_add = 1;
16962   int ret;
16963
16964   leid_type = reid_type = (u8) ~ 0;
16965
16966   /* Parse args required to build the message */
16967   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16968     {
16969       if (unformat (input, "del"))
16970         {
16971           is_add = 0;
16972         }
16973       else if (unformat (input, "add"))
16974         {
16975           is_add = 1;
16976         }
16977       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
16978                          &reid4, &len))
16979         {
16980           reid_type = 0;        /* ipv4 */
16981           reid_len = len;
16982         }
16983       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
16984                          &reid6, &len))
16985         {
16986           reid_type = 1;        /* ipv6 */
16987           reid_len = len;
16988         }
16989       else if (unformat (input, "reid %U", unformat_ethernet_address,
16990                          reid_mac))
16991         {
16992           reid_type = 2;        /* mac */
16993         }
16994       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
16995                          &leid4, &len))
16996         {
16997           leid_type = 0;        /* ipv4 */
16998           leid_len = len;
16999         }
17000       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17001                          &leid6, &len))
17002         {
17003           leid_type = 1;        /* ipv6 */
17004           leid_len = len;
17005         }
17006       else if (unformat (input, "leid %U", unformat_ethernet_address,
17007                          leid_mac))
17008         {
17009           leid_type = 2;        /* mac */
17010         }
17011       else if (unformat (input, "vni %d", &vni))
17012         {
17013           ;
17014         }
17015       else
17016         {
17017           errmsg ("parse error '%U'", format_unformat_error, input);
17018           return -99;
17019         }
17020     }
17021
17022   if ((u8) ~ 0 == reid_type)
17023     {
17024       errmsg ("missing params!");
17025       return -99;
17026     }
17027
17028   if (leid_type != reid_type)
17029     {
17030       errmsg ("remote and local EIDs are of different types!");
17031       return -99;
17032     }
17033
17034   M (ONE_ADD_DEL_ADJACENCY, mp);
17035   mp->is_add = is_add;
17036   mp->vni = htonl (vni);
17037   mp->leid_len = leid_len;
17038   mp->reid_len = reid_len;
17039   mp->eid_type = reid_type;
17040
17041   switch (mp->eid_type)
17042     {
17043     case 0:
17044       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
17045       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
17046       break;
17047     case 1:
17048       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
17049       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
17050       break;
17051     case 2:
17052       clib_memcpy (mp->leid, leid_mac, 6);
17053       clib_memcpy (mp->reid, reid_mac, 6);
17054       break;
17055     default:
17056       errmsg ("unknown EID type %d!", mp->eid_type);
17057       return 0;
17058     }
17059
17060   /* send it... */
17061   S (mp);
17062
17063   /* Wait for a reply... */
17064   W (ret);
17065   return ret;
17066 }
17067
17068 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
17069
17070 uword
17071 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
17072 {
17073   u32 *mode = va_arg (*args, u32 *);
17074
17075   if (unformat (input, "lisp"))
17076     *mode = 0;
17077   else if (unformat (input, "vxlan"))
17078     *mode = 1;
17079   else
17080     return 0;
17081
17082   return 1;
17083 }
17084
17085 static int
17086 api_gpe_get_encap_mode (vat_main_t * vam)
17087 {
17088   vl_api_gpe_get_encap_mode_t *mp;
17089   int ret;
17090
17091   /* Construct the API message */
17092   M (GPE_GET_ENCAP_MODE, mp);
17093
17094   /* send it... */
17095   S (mp);
17096
17097   /* Wait for a reply... */
17098   W (ret);
17099   return ret;
17100 }
17101
17102 static int
17103 api_gpe_set_encap_mode (vat_main_t * vam)
17104 {
17105   unformat_input_t *input = vam->input;
17106   vl_api_gpe_set_encap_mode_t *mp;
17107   int ret;
17108   u32 mode = 0;
17109
17110   /* Parse args required to build the message */
17111   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17112     {
17113       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
17114         ;
17115       else
17116         break;
17117     }
17118
17119   /* Construct the API message */
17120   M (GPE_SET_ENCAP_MODE, mp);
17121
17122   mp->mode = mode;
17123
17124   /* send it... */
17125   S (mp);
17126
17127   /* Wait for a reply... */
17128   W (ret);
17129   return ret;
17130 }
17131
17132 static int
17133 api_lisp_gpe_add_del_iface (vat_main_t * vam)
17134 {
17135   unformat_input_t *input = vam->input;
17136   vl_api_gpe_add_del_iface_t *mp;
17137   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
17138   u32 dp_table = 0, vni = 0;
17139   int ret;
17140
17141   /* Parse args required to build the message */
17142   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17143     {
17144       if (unformat (input, "up"))
17145         {
17146           action_set = 1;
17147           is_add = 1;
17148         }
17149       else if (unformat (input, "down"))
17150         {
17151           action_set = 1;
17152           is_add = 0;
17153         }
17154       else if (unformat (input, "table_id %d", &dp_table))
17155         {
17156           dp_table_set = 1;
17157         }
17158       else if (unformat (input, "bd_id %d", &dp_table))
17159         {
17160           dp_table_set = 1;
17161           is_l2 = 1;
17162         }
17163       else if (unformat (input, "vni %d", &vni))
17164         {
17165           vni_set = 1;
17166         }
17167       else
17168         break;
17169     }
17170
17171   if (action_set == 0)
17172     {
17173       errmsg ("Action not set");
17174       return -99;
17175     }
17176   if (dp_table_set == 0 || vni_set == 0)
17177     {
17178       errmsg ("vni and dp_table must be set");
17179       return -99;
17180     }
17181
17182   /* Construct the API message */
17183   M (GPE_ADD_DEL_IFACE, mp);
17184
17185   mp->is_add = is_add;
17186   mp->dp_table = clib_host_to_net_u32 (dp_table);
17187   mp->is_l2 = is_l2;
17188   mp->vni = clib_host_to_net_u32 (vni);
17189
17190   /* send it... */
17191   S (mp);
17192
17193   /* Wait for a reply... */
17194   W (ret);
17195   return ret;
17196 }
17197
17198 static int
17199 api_one_map_register_fallback_threshold (vat_main_t * vam)
17200 {
17201   unformat_input_t *input = vam->input;
17202   vl_api_one_map_register_fallback_threshold_t *mp;
17203   u32 value = 0;
17204   u8 is_set = 0;
17205   int ret;
17206
17207   /* Parse args required to build the message */
17208   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17209     {
17210       if (unformat (input, "%u", &value))
17211         is_set = 1;
17212       else
17213         {
17214           clib_warning ("parse error '%U'", format_unformat_error, input);
17215           return -99;
17216         }
17217     }
17218
17219   if (!is_set)
17220     {
17221       errmsg ("fallback threshold value is missing!");
17222       return -99;
17223     }
17224
17225   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17226   mp->value = clib_host_to_net_u32 (value);
17227
17228   /* send it... */
17229   S (mp);
17230
17231   /* Wait for a reply... */
17232   W (ret);
17233   return ret;
17234 }
17235
17236 static int
17237 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
17238 {
17239   vl_api_show_one_map_register_fallback_threshold_t *mp;
17240   int ret;
17241
17242   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17243
17244   /* send it... */
17245   S (mp);
17246
17247   /* Wait for a reply... */
17248   W (ret);
17249   return ret;
17250 }
17251
17252 uword
17253 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
17254 {
17255   u32 *proto = va_arg (*args, u32 *);
17256
17257   if (unformat (input, "udp"))
17258     *proto = 1;
17259   else if (unformat (input, "api"))
17260     *proto = 2;
17261   else
17262     return 0;
17263
17264   return 1;
17265 }
17266
17267 static int
17268 api_one_set_transport_protocol (vat_main_t * vam)
17269 {
17270   unformat_input_t *input = vam->input;
17271   vl_api_one_set_transport_protocol_t *mp;
17272   u8 is_set = 0;
17273   u32 protocol = 0;
17274   int ret;
17275
17276   /* Parse args required to build the message */
17277   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17278     {
17279       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
17280         is_set = 1;
17281       else
17282         {
17283           clib_warning ("parse error '%U'", format_unformat_error, input);
17284           return -99;
17285         }
17286     }
17287
17288   if (!is_set)
17289     {
17290       errmsg ("Transport protocol missing!");
17291       return -99;
17292     }
17293
17294   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
17295   mp->protocol = (u8) protocol;
17296
17297   /* send it... */
17298   S (mp);
17299
17300   /* Wait for a reply... */
17301   W (ret);
17302   return ret;
17303 }
17304
17305 static int
17306 api_one_get_transport_protocol (vat_main_t * vam)
17307 {
17308   vl_api_one_get_transport_protocol_t *mp;
17309   int ret;
17310
17311   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
17312
17313   /* send it... */
17314   S (mp);
17315
17316   /* Wait for a reply... */
17317   W (ret);
17318   return ret;
17319 }
17320
17321 static int
17322 api_one_map_register_set_ttl (vat_main_t * vam)
17323 {
17324   unformat_input_t *input = vam->input;
17325   vl_api_one_map_register_set_ttl_t *mp;
17326   u32 ttl = 0;
17327   u8 is_set = 0;
17328   int ret;
17329
17330   /* Parse args required to build the message */
17331   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17332     {
17333       if (unformat (input, "%u", &ttl))
17334         is_set = 1;
17335       else
17336         {
17337           clib_warning ("parse error '%U'", format_unformat_error, input);
17338           return -99;
17339         }
17340     }
17341
17342   if (!is_set)
17343     {
17344       errmsg ("TTL value missing!");
17345       return -99;
17346     }
17347
17348   M (ONE_MAP_REGISTER_SET_TTL, mp);
17349   mp->ttl = clib_host_to_net_u32 (ttl);
17350
17351   /* send it... */
17352   S (mp);
17353
17354   /* Wait for a reply... */
17355   W (ret);
17356   return ret;
17357 }
17358
17359 static int
17360 api_show_one_map_register_ttl (vat_main_t * vam)
17361 {
17362   vl_api_show_one_map_register_ttl_t *mp;
17363   int ret;
17364
17365   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
17366
17367   /* send it... */
17368   S (mp);
17369
17370   /* Wait for a reply... */
17371   W (ret);
17372   return ret;
17373 }
17374
17375 /**
17376  * Add/del map request itr rlocs from ONE control plane and updates
17377  *
17378  * @param vam vpp API test context
17379  * @return return code
17380  */
17381 static int
17382 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17383 {
17384   unformat_input_t *input = vam->input;
17385   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17386   u8 *locator_set_name = 0;
17387   u8 locator_set_name_set = 0;
17388   u8 is_add = 1;
17389   int ret;
17390
17391   /* Parse args required to build the message */
17392   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17393     {
17394       if (unformat (input, "del"))
17395         {
17396           is_add = 0;
17397         }
17398       else if (unformat (input, "%_%v%_", &locator_set_name))
17399         {
17400           locator_set_name_set = 1;
17401         }
17402       else
17403         {
17404           clib_warning ("parse error '%U'", format_unformat_error, input);
17405           return -99;
17406         }
17407     }
17408
17409   if (is_add && !locator_set_name_set)
17410     {
17411       errmsg ("itr-rloc is not set!");
17412       return -99;
17413     }
17414
17415   if (is_add && vec_len (locator_set_name) > 64)
17416     {
17417       errmsg ("itr-rloc locator-set name too long");
17418       vec_free (locator_set_name);
17419       return -99;
17420     }
17421
17422   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17423   mp->is_add = is_add;
17424   if (is_add)
17425     {
17426       clib_memcpy (mp->locator_set_name, locator_set_name,
17427                    vec_len (locator_set_name));
17428     }
17429   else
17430     {
17431       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17432     }
17433   vec_free (locator_set_name);
17434
17435   /* send it... */
17436   S (mp);
17437
17438   /* Wait for a reply... */
17439   W (ret);
17440   return ret;
17441 }
17442
17443 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17444
17445 static int
17446 api_one_locator_dump (vat_main_t * vam)
17447 {
17448   unformat_input_t *input = vam->input;
17449   vl_api_one_locator_dump_t *mp;
17450   vl_api_control_ping_t *mp_ping;
17451   u8 is_index_set = 0, is_name_set = 0;
17452   u8 *ls_name = 0;
17453   u32 ls_index = ~0;
17454   int ret;
17455
17456   /* Parse args required to build the message */
17457   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17458     {
17459       if (unformat (input, "ls_name %_%v%_", &ls_name))
17460         {
17461           is_name_set = 1;
17462         }
17463       else if (unformat (input, "ls_index %d", &ls_index))
17464         {
17465           is_index_set = 1;
17466         }
17467       else
17468         {
17469           errmsg ("parse error '%U'", format_unformat_error, input);
17470           return -99;
17471         }
17472     }
17473
17474   if (!is_index_set && !is_name_set)
17475     {
17476       errmsg ("error: expected one of index or name!");
17477       return -99;
17478     }
17479
17480   if (is_index_set && is_name_set)
17481     {
17482       errmsg ("error: only one param expected!");
17483       return -99;
17484     }
17485
17486   if (vec_len (ls_name) > 62)
17487     {
17488       errmsg ("error: locator set name too long!");
17489       return -99;
17490     }
17491
17492   if (!vam->json_output)
17493     {
17494       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17495     }
17496
17497   M (ONE_LOCATOR_DUMP, mp);
17498   mp->is_index_set = is_index_set;
17499
17500   if (is_index_set)
17501     mp->ls_index = clib_host_to_net_u32 (ls_index);
17502   else
17503     {
17504       vec_add1 (ls_name, 0);
17505       strncpy ((char *) mp->ls_name, (char *) ls_name,
17506                sizeof (mp->ls_name) - 1);
17507     }
17508
17509   /* send it... */
17510   S (mp);
17511
17512   /* Use a control ping for synchronization */
17513   MPING (CONTROL_PING, mp_ping);
17514   S (mp_ping);
17515
17516   /* Wait for a reply... */
17517   W (ret);
17518   return ret;
17519 }
17520
17521 #define api_lisp_locator_dump api_one_locator_dump
17522
17523 static int
17524 api_one_locator_set_dump (vat_main_t * vam)
17525 {
17526   vl_api_one_locator_set_dump_t *mp;
17527   vl_api_control_ping_t *mp_ping;
17528   unformat_input_t *input = vam->input;
17529   u8 filter = 0;
17530   int ret;
17531
17532   /* Parse args required to build the message */
17533   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17534     {
17535       if (unformat (input, "local"))
17536         {
17537           filter = 1;
17538         }
17539       else if (unformat (input, "remote"))
17540         {
17541           filter = 2;
17542         }
17543       else
17544         {
17545           errmsg ("parse error '%U'", format_unformat_error, input);
17546           return -99;
17547         }
17548     }
17549
17550   if (!vam->json_output)
17551     {
17552       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
17553     }
17554
17555   M (ONE_LOCATOR_SET_DUMP, mp);
17556
17557   mp->filter = filter;
17558
17559   /* send it... */
17560   S (mp);
17561
17562   /* Use a control ping for synchronization */
17563   MPING (CONTROL_PING, mp_ping);
17564   S (mp_ping);
17565
17566   /* Wait for a reply... */
17567   W (ret);
17568   return ret;
17569 }
17570
17571 #define api_lisp_locator_set_dump api_one_locator_set_dump
17572
17573 static int
17574 api_one_eid_table_map_dump (vat_main_t * vam)
17575 {
17576   u8 is_l2 = 0;
17577   u8 mode_set = 0;
17578   unformat_input_t *input = vam->input;
17579   vl_api_one_eid_table_map_dump_t *mp;
17580   vl_api_control_ping_t *mp_ping;
17581   int ret;
17582
17583   /* Parse args required to build the message */
17584   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17585     {
17586       if (unformat (input, "l2"))
17587         {
17588           is_l2 = 1;
17589           mode_set = 1;
17590         }
17591       else if (unformat (input, "l3"))
17592         {
17593           is_l2 = 0;
17594           mode_set = 1;
17595         }
17596       else
17597         {
17598           errmsg ("parse error '%U'", format_unformat_error, input);
17599           return -99;
17600         }
17601     }
17602
17603   if (!mode_set)
17604     {
17605       errmsg ("expected one of 'l2' or 'l3' parameter!");
17606       return -99;
17607     }
17608
17609   if (!vam->json_output)
17610     {
17611       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
17612     }
17613
17614   M (ONE_EID_TABLE_MAP_DUMP, mp);
17615   mp->is_l2 = is_l2;
17616
17617   /* send it... */
17618   S (mp);
17619
17620   /* Use a control ping for synchronization */
17621   MPING (CONTROL_PING, mp_ping);
17622   S (mp_ping);
17623
17624   /* Wait for a reply... */
17625   W (ret);
17626   return ret;
17627 }
17628
17629 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
17630
17631 static int
17632 api_one_eid_table_vni_dump (vat_main_t * vam)
17633 {
17634   vl_api_one_eid_table_vni_dump_t *mp;
17635   vl_api_control_ping_t *mp_ping;
17636   int ret;
17637
17638   if (!vam->json_output)
17639     {
17640       print (vam->ofp, "VNI");
17641     }
17642
17643   M (ONE_EID_TABLE_VNI_DUMP, mp);
17644
17645   /* send it... */
17646   S (mp);
17647
17648   /* Use a control ping for synchronization */
17649   MPING (CONTROL_PING, mp_ping);
17650   S (mp_ping);
17651
17652   /* Wait for a reply... */
17653   W (ret);
17654   return ret;
17655 }
17656
17657 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
17658
17659 static int
17660 api_one_eid_table_dump (vat_main_t * vam)
17661 {
17662   unformat_input_t *i = vam->input;
17663   vl_api_one_eid_table_dump_t *mp;
17664   vl_api_control_ping_t *mp_ping;
17665   struct in_addr ip4;
17666   struct in6_addr ip6;
17667   u8 mac[6];
17668   u8 eid_type = ~0, eid_set = 0;
17669   u32 prefix_length = ~0, t, vni = 0;
17670   u8 filter = 0;
17671   int ret;
17672   lisp_nsh_api_t nsh;
17673
17674   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17675     {
17676       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
17677         {
17678           eid_set = 1;
17679           eid_type = 0;
17680           prefix_length = t;
17681         }
17682       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
17683         {
17684           eid_set = 1;
17685           eid_type = 1;
17686           prefix_length = t;
17687         }
17688       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
17689         {
17690           eid_set = 1;
17691           eid_type = 2;
17692         }
17693       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
17694         {
17695           eid_set = 1;
17696           eid_type = 3;
17697         }
17698       else if (unformat (i, "vni %d", &t))
17699         {
17700           vni = t;
17701         }
17702       else if (unformat (i, "local"))
17703         {
17704           filter = 1;
17705         }
17706       else if (unformat (i, "remote"))
17707         {
17708           filter = 2;
17709         }
17710       else
17711         {
17712           errmsg ("parse error '%U'", format_unformat_error, i);
17713           return -99;
17714         }
17715     }
17716
17717   if (!vam->json_output)
17718     {
17719       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
17720              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
17721     }
17722
17723   M (ONE_EID_TABLE_DUMP, mp);
17724
17725   mp->filter = filter;
17726   if (eid_set)
17727     {
17728       mp->eid_set = 1;
17729       mp->vni = htonl (vni);
17730       mp->eid_type = eid_type;
17731       switch (eid_type)
17732         {
17733         case 0:
17734           mp->prefix_length = prefix_length;
17735           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
17736           break;
17737         case 1:
17738           mp->prefix_length = prefix_length;
17739           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
17740           break;
17741         case 2:
17742           clib_memcpy (mp->eid, mac, sizeof (mac));
17743           break;
17744         case 3:
17745           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
17746           break;
17747         default:
17748           errmsg ("unknown EID type %d!", eid_type);
17749           return -99;
17750         }
17751     }
17752
17753   /* send it... */
17754   S (mp);
17755
17756   /* Use a control ping for synchronization */
17757   MPING (CONTROL_PING, mp_ping);
17758   S (mp_ping);
17759
17760   /* Wait for a reply... */
17761   W (ret);
17762   return ret;
17763 }
17764
17765 #define api_lisp_eid_table_dump api_one_eid_table_dump
17766
17767 static int
17768 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
17769 {
17770   unformat_input_t *i = vam->input;
17771   vl_api_gpe_fwd_entries_get_t *mp;
17772   u8 vni_set = 0;
17773   u32 vni = ~0;
17774   int ret;
17775
17776   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17777     {
17778       if (unformat (i, "vni %d", &vni))
17779         {
17780           vni_set = 1;
17781         }
17782       else
17783         {
17784           errmsg ("parse error '%U'", format_unformat_error, i);
17785           return -99;
17786         }
17787     }
17788
17789   if (!vni_set)
17790     {
17791       errmsg ("vni not set!");
17792       return -99;
17793     }
17794
17795   if (!vam->json_output)
17796     {
17797       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
17798              "leid", "reid");
17799     }
17800
17801   M (GPE_FWD_ENTRIES_GET, mp);
17802   mp->vni = clib_host_to_net_u32 (vni);
17803
17804   /* send it... */
17805   S (mp);
17806
17807   /* Wait for a reply... */
17808   W (ret);
17809   return ret;
17810 }
17811
17812 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
17813 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
17814 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
17815 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
17816 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
17817 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
17818 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
17819 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
17820
17821 static int
17822 api_one_adjacencies_get (vat_main_t * vam)
17823 {
17824   unformat_input_t *i = vam->input;
17825   vl_api_one_adjacencies_get_t *mp;
17826   u8 vni_set = 0;
17827   u32 vni = ~0;
17828   int ret;
17829
17830   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17831     {
17832       if (unformat (i, "vni %d", &vni))
17833         {
17834           vni_set = 1;
17835         }
17836       else
17837         {
17838           errmsg ("parse error '%U'", format_unformat_error, i);
17839           return -99;
17840         }
17841     }
17842
17843   if (!vni_set)
17844     {
17845       errmsg ("vni not set!");
17846       return -99;
17847     }
17848
17849   if (!vam->json_output)
17850     {
17851       print (vam->ofp, "%s %40s", "leid", "reid");
17852     }
17853
17854   M (ONE_ADJACENCIES_GET, mp);
17855   mp->vni = clib_host_to_net_u32 (vni);
17856
17857   /* send it... */
17858   S (mp);
17859
17860   /* Wait for a reply... */
17861   W (ret);
17862   return ret;
17863 }
17864
17865 #define api_lisp_adjacencies_get api_one_adjacencies_get
17866
17867 static int
17868 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
17869 {
17870   unformat_input_t *i = vam->input;
17871   vl_api_gpe_native_fwd_rpaths_get_t *mp;
17872   int ret;
17873   u8 ip_family_set = 0, is_ip4 = 1;
17874
17875   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17876     {
17877       if (unformat (i, "ip4"))
17878         {
17879           ip_family_set = 1;
17880           is_ip4 = 1;
17881         }
17882       else if (unformat (i, "ip6"))
17883         {
17884           ip_family_set = 1;
17885           is_ip4 = 0;
17886         }
17887       else
17888         {
17889           errmsg ("parse error '%U'", format_unformat_error, i);
17890           return -99;
17891         }
17892     }
17893
17894   if (!ip_family_set)
17895     {
17896       errmsg ("ip family not set!");
17897       return -99;
17898     }
17899
17900   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
17901   mp->is_ip4 = is_ip4;
17902
17903   /* send it... */
17904   S (mp);
17905
17906   /* Wait for a reply... */
17907   W (ret);
17908   return ret;
17909 }
17910
17911 static int
17912 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
17913 {
17914   vl_api_gpe_fwd_entry_vnis_get_t *mp;
17915   int ret;
17916
17917   if (!vam->json_output)
17918     {
17919       print (vam->ofp, "VNIs");
17920     }
17921
17922   M (GPE_FWD_ENTRY_VNIS_GET, mp);
17923
17924   /* send it... */
17925   S (mp);
17926
17927   /* Wait for a reply... */
17928   W (ret);
17929   return ret;
17930 }
17931
17932 static int
17933 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
17934 {
17935   unformat_input_t *i = vam->input;
17936   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
17937   int ret = 0;
17938   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
17939   struct in_addr ip4;
17940   struct in6_addr ip6;
17941   u32 table_id = 0, nh_sw_if_index = ~0;
17942
17943   clib_memset (&ip4, 0, sizeof (ip4));
17944   clib_memset (&ip6, 0, sizeof (ip6));
17945
17946   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17947     {
17948       if (unformat (i, "del"))
17949         is_add = 0;
17950       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
17951                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17952         {
17953           ip_set = 1;
17954           is_ip4 = 1;
17955         }
17956       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
17957                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17958         {
17959           ip_set = 1;
17960           is_ip4 = 0;
17961         }
17962       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
17963         {
17964           ip_set = 1;
17965           is_ip4 = 1;
17966           nh_sw_if_index = ~0;
17967         }
17968       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
17969         {
17970           ip_set = 1;
17971           is_ip4 = 0;
17972           nh_sw_if_index = ~0;
17973         }
17974       else if (unformat (i, "table %d", &table_id))
17975         ;
17976       else
17977         {
17978           errmsg ("parse error '%U'", format_unformat_error, i);
17979           return -99;
17980         }
17981     }
17982
17983   if (!ip_set)
17984     {
17985       errmsg ("nh addr not set!");
17986       return -99;
17987     }
17988
17989   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
17990   mp->is_add = is_add;
17991   mp->table_id = clib_host_to_net_u32 (table_id);
17992   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
17993   mp->is_ip4 = is_ip4;
17994   if (is_ip4)
17995     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
17996   else
17997     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
17998
17999   /* send it... */
18000   S (mp);
18001
18002   /* Wait for a reply... */
18003   W (ret);
18004   return ret;
18005 }
18006
18007 static int
18008 api_one_map_server_dump (vat_main_t * vam)
18009 {
18010   vl_api_one_map_server_dump_t *mp;
18011   vl_api_control_ping_t *mp_ping;
18012   int ret;
18013
18014   if (!vam->json_output)
18015     {
18016       print (vam->ofp, "%=20s", "Map server");
18017     }
18018
18019   M (ONE_MAP_SERVER_DUMP, mp);
18020   /* send it... */
18021   S (mp);
18022
18023   /* Use a control ping for synchronization */
18024   MPING (CONTROL_PING, mp_ping);
18025   S (mp_ping);
18026
18027   /* Wait for a reply... */
18028   W (ret);
18029   return ret;
18030 }
18031
18032 #define api_lisp_map_server_dump api_one_map_server_dump
18033
18034 static int
18035 api_one_map_resolver_dump (vat_main_t * vam)
18036 {
18037   vl_api_one_map_resolver_dump_t *mp;
18038   vl_api_control_ping_t *mp_ping;
18039   int ret;
18040
18041   if (!vam->json_output)
18042     {
18043       print (vam->ofp, "%=20s", "Map resolver");
18044     }
18045
18046   M (ONE_MAP_RESOLVER_DUMP, mp);
18047   /* send it... */
18048   S (mp);
18049
18050   /* Use a control ping for synchronization */
18051   MPING (CONTROL_PING, mp_ping);
18052   S (mp_ping);
18053
18054   /* Wait for a reply... */
18055   W (ret);
18056   return ret;
18057 }
18058
18059 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
18060
18061 static int
18062 api_one_stats_flush (vat_main_t * vam)
18063 {
18064   vl_api_one_stats_flush_t *mp;
18065   int ret = 0;
18066
18067   M (ONE_STATS_FLUSH, mp);
18068   S (mp);
18069   W (ret);
18070   return ret;
18071 }
18072
18073 static int
18074 api_one_stats_dump (vat_main_t * vam)
18075 {
18076   vl_api_one_stats_dump_t *mp;
18077   vl_api_control_ping_t *mp_ping;
18078   int ret;
18079
18080   M (ONE_STATS_DUMP, mp);
18081   /* send it... */
18082   S (mp);
18083
18084   /* Use a control ping for synchronization */
18085   MPING (CONTROL_PING, mp_ping);
18086   S (mp_ping);
18087
18088   /* Wait for a reply... */
18089   W (ret);
18090   return ret;
18091 }
18092
18093 static int
18094 api_show_one_status (vat_main_t * vam)
18095 {
18096   vl_api_show_one_status_t *mp;
18097   int ret;
18098
18099   if (!vam->json_output)
18100     {
18101       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
18102     }
18103
18104   M (SHOW_ONE_STATUS, mp);
18105   /* send it... */
18106   S (mp);
18107   /* Wait for a reply... */
18108   W (ret);
18109   return ret;
18110 }
18111
18112 #define api_show_lisp_status api_show_one_status
18113
18114 static int
18115 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
18116 {
18117   vl_api_gpe_fwd_entry_path_dump_t *mp;
18118   vl_api_control_ping_t *mp_ping;
18119   unformat_input_t *i = vam->input;
18120   u32 fwd_entry_index = ~0;
18121   int ret;
18122
18123   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18124     {
18125       if (unformat (i, "index %d", &fwd_entry_index))
18126         ;
18127       else
18128         break;
18129     }
18130
18131   if (~0 == fwd_entry_index)
18132     {
18133       errmsg ("no index specified!");
18134       return -99;
18135     }
18136
18137   if (!vam->json_output)
18138     {
18139       print (vam->ofp, "first line");
18140     }
18141
18142   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
18143
18144   /* send it... */
18145   S (mp);
18146   /* Use a control ping for synchronization */
18147   MPING (CONTROL_PING, mp_ping);
18148   S (mp_ping);
18149
18150   /* Wait for a reply... */
18151   W (ret);
18152   return ret;
18153 }
18154
18155 static int
18156 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
18157 {
18158   vl_api_one_get_map_request_itr_rlocs_t *mp;
18159   int ret;
18160
18161   if (!vam->json_output)
18162     {
18163       print (vam->ofp, "%=20s", "itr-rlocs:");
18164     }
18165
18166   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
18167   /* send it... */
18168   S (mp);
18169   /* Wait for a reply... */
18170   W (ret);
18171   return ret;
18172 }
18173
18174 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
18175
18176 static int
18177 api_af_packet_create (vat_main_t * vam)
18178 {
18179   unformat_input_t *i = vam->input;
18180   vl_api_af_packet_create_t *mp;
18181   u8 *host_if_name = 0;
18182   u8 hw_addr[6];
18183   u8 random_hw_addr = 1;
18184   int ret;
18185
18186   clib_memset (hw_addr, 0, sizeof (hw_addr));
18187
18188   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18189     {
18190       if (unformat (i, "name %s", &host_if_name))
18191         vec_add1 (host_if_name, 0);
18192       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18193         random_hw_addr = 0;
18194       else
18195         break;
18196     }
18197
18198   if (!vec_len (host_if_name))
18199     {
18200       errmsg ("host-interface name must be specified");
18201       return -99;
18202     }
18203
18204   if (vec_len (host_if_name) > 64)
18205     {
18206       errmsg ("host-interface name too long");
18207       return -99;
18208     }
18209
18210   M (AF_PACKET_CREATE, mp);
18211
18212   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18213   clib_memcpy (mp->hw_addr, hw_addr, 6);
18214   mp->use_random_hw_addr = random_hw_addr;
18215   vec_free (host_if_name);
18216
18217   S (mp);
18218
18219   /* *INDENT-OFF* */
18220   W2 (ret,
18221       ({
18222         if (ret == 0)
18223           fprintf (vam->ofp ? vam->ofp : stderr,
18224                    " new sw_if_index = %d\n", vam->sw_if_index);
18225       }));
18226   /* *INDENT-ON* */
18227   return ret;
18228 }
18229
18230 static int
18231 api_af_packet_delete (vat_main_t * vam)
18232 {
18233   unformat_input_t *i = vam->input;
18234   vl_api_af_packet_delete_t *mp;
18235   u8 *host_if_name = 0;
18236   int ret;
18237
18238   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18239     {
18240       if (unformat (i, "name %s", &host_if_name))
18241         vec_add1 (host_if_name, 0);
18242       else
18243         break;
18244     }
18245
18246   if (!vec_len (host_if_name))
18247     {
18248       errmsg ("host-interface name must be specified");
18249       return -99;
18250     }
18251
18252   if (vec_len (host_if_name) > 64)
18253     {
18254       errmsg ("host-interface name too long");
18255       return -99;
18256     }
18257
18258   M (AF_PACKET_DELETE, mp);
18259
18260   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18261   vec_free (host_if_name);
18262
18263   S (mp);
18264   W (ret);
18265   return ret;
18266 }
18267
18268 static void vl_api_af_packet_details_t_handler
18269   (vl_api_af_packet_details_t * mp)
18270 {
18271   vat_main_t *vam = &vat_main;
18272
18273   print (vam->ofp, "%-16s %d",
18274          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
18275 }
18276
18277 static void vl_api_af_packet_details_t_handler_json
18278   (vl_api_af_packet_details_t * mp)
18279 {
18280   vat_main_t *vam = &vat_main;
18281   vat_json_node_t *node = NULL;
18282
18283   if (VAT_JSON_ARRAY != vam->json_tree.type)
18284     {
18285       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18286       vat_json_init_array (&vam->json_tree);
18287     }
18288   node = vat_json_array_add (&vam->json_tree);
18289
18290   vat_json_init_object (node);
18291   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
18292   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
18293 }
18294
18295 static int
18296 api_af_packet_dump (vat_main_t * vam)
18297 {
18298   vl_api_af_packet_dump_t *mp;
18299   vl_api_control_ping_t *mp_ping;
18300   int ret;
18301
18302   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
18303   /* Get list of tap interfaces */
18304   M (AF_PACKET_DUMP, mp);
18305   S (mp);
18306
18307   /* Use a control ping for synchronization */
18308   MPING (CONTROL_PING, mp_ping);
18309   S (mp_ping);
18310
18311   W (ret);
18312   return ret;
18313 }
18314
18315 static int
18316 api_policer_add_del (vat_main_t * vam)
18317 {
18318   unformat_input_t *i = vam->input;
18319   vl_api_policer_add_del_t *mp;
18320   u8 is_add = 1;
18321   u8 *name = 0;
18322   u32 cir = 0;
18323   u32 eir = 0;
18324   u64 cb = 0;
18325   u64 eb = 0;
18326   u8 rate_type = 0;
18327   u8 round_type = 0;
18328   u8 type = 0;
18329   u8 color_aware = 0;
18330   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
18331   int ret;
18332
18333   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
18334   conform_action.dscp = 0;
18335   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
18336   exceed_action.dscp = 0;
18337   violate_action.action_type = SSE2_QOS_ACTION_DROP;
18338   violate_action.dscp = 0;
18339
18340   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18341     {
18342       if (unformat (i, "del"))
18343         is_add = 0;
18344       else if (unformat (i, "name %s", &name))
18345         vec_add1 (name, 0);
18346       else if (unformat (i, "cir %u", &cir))
18347         ;
18348       else if (unformat (i, "eir %u", &eir))
18349         ;
18350       else if (unformat (i, "cb %u", &cb))
18351         ;
18352       else if (unformat (i, "eb %u", &eb))
18353         ;
18354       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
18355                          &rate_type))
18356         ;
18357       else if (unformat (i, "round_type %U", unformat_policer_round_type,
18358                          &round_type))
18359         ;
18360       else if (unformat (i, "type %U", unformat_policer_type, &type))
18361         ;
18362       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
18363                          &conform_action))
18364         ;
18365       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
18366                          &exceed_action))
18367         ;
18368       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
18369                          &violate_action))
18370         ;
18371       else if (unformat (i, "color-aware"))
18372         color_aware = 1;
18373       else
18374         break;
18375     }
18376
18377   if (!vec_len (name))
18378     {
18379       errmsg ("policer name must be specified");
18380       return -99;
18381     }
18382
18383   if (vec_len (name) > 64)
18384     {
18385       errmsg ("policer name too long");
18386       return -99;
18387     }
18388
18389   M (POLICER_ADD_DEL, mp);
18390
18391   clib_memcpy (mp->name, name, vec_len (name));
18392   vec_free (name);
18393   mp->is_add = is_add;
18394   mp->cir = ntohl (cir);
18395   mp->eir = ntohl (eir);
18396   mp->cb = clib_net_to_host_u64 (cb);
18397   mp->eb = clib_net_to_host_u64 (eb);
18398   mp->rate_type = rate_type;
18399   mp->round_type = round_type;
18400   mp->type = type;
18401   mp->conform_action_type = conform_action.action_type;
18402   mp->conform_dscp = conform_action.dscp;
18403   mp->exceed_action_type = exceed_action.action_type;
18404   mp->exceed_dscp = exceed_action.dscp;
18405   mp->violate_action_type = violate_action.action_type;
18406   mp->violate_dscp = violate_action.dscp;
18407   mp->color_aware = color_aware;
18408
18409   S (mp);
18410   W (ret);
18411   return ret;
18412 }
18413
18414 static int
18415 api_policer_dump (vat_main_t * vam)
18416 {
18417   unformat_input_t *i = vam->input;
18418   vl_api_policer_dump_t *mp;
18419   vl_api_control_ping_t *mp_ping;
18420   u8 *match_name = 0;
18421   u8 match_name_valid = 0;
18422   int ret;
18423
18424   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18425     {
18426       if (unformat (i, "name %s", &match_name))
18427         {
18428           vec_add1 (match_name, 0);
18429           match_name_valid = 1;
18430         }
18431       else
18432         break;
18433     }
18434
18435   M (POLICER_DUMP, mp);
18436   mp->match_name_valid = match_name_valid;
18437   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18438   vec_free (match_name);
18439   /* send it... */
18440   S (mp);
18441
18442   /* Use a control ping for synchronization */
18443   MPING (CONTROL_PING, mp_ping);
18444   S (mp_ping);
18445
18446   /* Wait for a reply... */
18447   W (ret);
18448   return ret;
18449 }
18450
18451 static int
18452 api_policer_classify_set_interface (vat_main_t * vam)
18453 {
18454   unformat_input_t *i = vam->input;
18455   vl_api_policer_classify_set_interface_t *mp;
18456   u32 sw_if_index;
18457   int sw_if_index_set;
18458   u32 ip4_table_index = ~0;
18459   u32 ip6_table_index = ~0;
18460   u32 l2_table_index = ~0;
18461   u8 is_add = 1;
18462   int ret;
18463
18464   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18465     {
18466       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18467         sw_if_index_set = 1;
18468       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18469         sw_if_index_set = 1;
18470       else if (unformat (i, "del"))
18471         is_add = 0;
18472       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18473         ;
18474       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18475         ;
18476       else if (unformat (i, "l2-table %d", &l2_table_index))
18477         ;
18478       else
18479         {
18480           clib_warning ("parse error '%U'", format_unformat_error, i);
18481           return -99;
18482         }
18483     }
18484
18485   if (sw_if_index_set == 0)
18486     {
18487       errmsg ("missing interface name or sw_if_index");
18488       return -99;
18489     }
18490
18491   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18492
18493   mp->sw_if_index = ntohl (sw_if_index);
18494   mp->ip4_table_index = ntohl (ip4_table_index);
18495   mp->ip6_table_index = ntohl (ip6_table_index);
18496   mp->l2_table_index = ntohl (l2_table_index);
18497   mp->is_add = is_add;
18498
18499   S (mp);
18500   W (ret);
18501   return ret;
18502 }
18503
18504 static int
18505 api_policer_classify_dump (vat_main_t * vam)
18506 {
18507   unformat_input_t *i = vam->input;
18508   vl_api_policer_classify_dump_t *mp;
18509   vl_api_control_ping_t *mp_ping;
18510   u8 type = POLICER_CLASSIFY_N_TABLES;
18511   int ret;
18512
18513   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
18514     ;
18515   else
18516     {
18517       errmsg ("classify table type must be specified");
18518       return -99;
18519     }
18520
18521   if (!vam->json_output)
18522     {
18523       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18524     }
18525
18526   M (POLICER_CLASSIFY_DUMP, mp);
18527   mp->type = type;
18528   /* send it... */
18529   S (mp);
18530
18531   /* Use a control ping for synchronization */
18532   MPING (CONTROL_PING, mp_ping);
18533   S (mp_ping);
18534
18535   /* Wait for a reply... */
18536   W (ret);
18537   return ret;
18538 }
18539
18540 static int
18541 api_netmap_create (vat_main_t * vam)
18542 {
18543   unformat_input_t *i = vam->input;
18544   vl_api_netmap_create_t *mp;
18545   u8 *if_name = 0;
18546   u8 hw_addr[6];
18547   u8 random_hw_addr = 1;
18548   u8 is_pipe = 0;
18549   u8 is_master = 0;
18550   int ret;
18551
18552   clib_memset (hw_addr, 0, sizeof (hw_addr));
18553
18554   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18555     {
18556       if (unformat (i, "name %s", &if_name))
18557         vec_add1 (if_name, 0);
18558       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18559         random_hw_addr = 0;
18560       else if (unformat (i, "pipe"))
18561         is_pipe = 1;
18562       else if (unformat (i, "master"))
18563         is_master = 1;
18564       else if (unformat (i, "slave"))
18565         is_master = 0;
18566       else
18567         break;
18568     }
18569
18570   if (!vec_len (if_name))
18571     {
18572       errmsg ("interface name must be specified");
18573       return -99;
18574     }
18575
18576   if (vec_len (if_name) > 64)
18577     {
18578       errmsg ("interface name too long");
18579       return -99;
18580     }
18581
18582   M (NETMAP_CREATE, mp);
18583
18584   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18585   clib_memcpy (mp->hw_addr, hw_addr, 6);
18586   mp->use_random_hw_addr = random_hw_addr;
18587   mp->is_pipe = is_pipe;
18588   mp->is_master = is_master;
18589   vec_free (if_name);
18590
18591   S (mp);
18592   W (ret);
18593   return ret;
18594 }
18595
18596 static int
18597 api_netmap_delete (vat_main_t * vam)
18598 {
18599   unformat_input_t *i = vam->input;
18600   vl_api_netmap_delete_t *mp;
18601   u8 *if_name = 0;
18602   int ret;
18603
18604   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18605     {
18606       if (unformat (i, "name %s", &if_name))
18607         vec_add1 (if_name, 0);
18608       else
18609         break;
18610     }
18611
18612   if (!vec_len (if_name))
18613     {
18614       errmsg ("interface name must be specified");
18615       return -99;
18616     }
18617
18618   if (vec_len (if_name) > 64)
18619     {
18620       errmsg ("interface name too long");
18621       return -99;
18622     }
18623
18624   M (NETMAP_DELETE, mp);
18625
18626   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18627   vec_free (if_name);
18628
18629   S (mp);
18630   W (ret);
18631   return ret;
18632 }
18633
18634 static u8 *
18635 format_fib_api_path_nh_proto (u8 * s, va_list * args)
18636 {
18637   vl_api_fib_path_nh_proto_t proto =
18638     va_arg (*args, vl_api_fib_path_nh_proto_t);
18639
18640   switch (proto)
18641     {
18642     case FIB_API_PATH_NH_PROTO_IP4:
18643       s = format (s, "ip4");
18644       break;
18645     case FIB_API_PATH_NH_PROTO_IP6:
18646       s = format (s, "ip6");
18647       break;
18648     case FIB_API_PATH_NH_PROTO_MPLS:
18649       s = format (s, "mpls");
18650       break;
18651     case FIB_API_PATH_NH_PROTO_BIER:
18652       s = format (s, "bier");
18653       break;
18654     case FIB_API_PATH_NH_PROTO_ETHERNET:
18655       s = format (s, "ethernet");
18656       break;
18657     }
18658
18659   return (s);
18660 }
18661
18662 static u8 *
18663 format_vl_api_ip_address_union (u8 * s, va_list * args)
18664 {
18665   vl_api_address_family_t af = va_arg (*args, vl_api_address_family_t);
18666   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
18667
18668   switch (af)
18669     {
18670     case ADDRESS_IP4:
18671       s = format (s, "%U", format_ip4_address, u->ip4);
18672       break;
18673     case ADDRESS_IP6:
18674       s = format (s, "%U", format_ip6_address, u->ip6);
18675       break;
18676     }
18677   return (s);
18678 }
18679
18680 static u8 *
18681 format_vl_api_fib_path_type (u8 * s, va_list * args)
18682 {
18683   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
18684
18685   switch (t)
18686     {
18687     case FIB_API_PATH_TYPE_NORMAL:
18688       s = format (s, "normal");
18689       break;
18690     case FIB_API_PATH_TYPE_LOCAL:
18691       s = format (s, "local");
18692       break;
18693     case FIB_API_PATH_TYPE_DROP:
18694       s = format (s, "drop");
18695       break;
18696     case FIB_API_PATH_TYPE_UDP_ENCAP:
18697       s = format (s, "udp-encap");
18698       break;
18699     case FIB_API_PATH_TYPE_BIER_IMP:
18700       s = format (s, "bier-imp");
18701       break;
18702     case FIB_API_PATH_TYPE_ICMP_UNREACH:
18703       s = format (s, "unreach");
18704       break;
18705     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
18706       s = format (s, "prohibit");
18707       break;
18708     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
18709       s = format (s, "src-lookup");
18710       break;
18711     case FIB_API_PATH_TYPE_DVR:
18712       s = format (s, "dvr");
18713       break;
18714     case FIB_API_PATH_TYPE_INTERFACE_RX:
18715       s = format (s, "interface-rx");
18716       break;
18717     case FIB_API_PATH_TYPE_CLASSIFY:
18718       s = format (s, "classify");
18719       break;
18720     }
18721
18722   return (s);
18723 }
18724
18725 static void
18726 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
18727 {
18728   print (vam->ofp,
18729          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
18730          ntohl (fp->weight), ntohl (fp->sw_if_index),
18731          format_vl_api_fib_path_type, fp->type,
18732          format_fib_api_path_nh_proto, fp->proto,
18733          format_vl_api_ip_address_union, &fp->nh.address);
18734 }
18735
18736 static void
18737 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
18738                                  vl_api_fib_path_t * fp)
18739 {
18740   struct in_addr ip4;
18741   struct in6_addr ip6;
18742
18743   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18744   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18745   vat_json_object_add_uint (node, "type", fp->type);
18746   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
18747   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18748     {
18749       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
18750       vat_json_object_add_ip4 (node, "next_hop", ip4);
18751     }
18752   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18753     {
18754       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
18755       vat_json_object_add_ip6 (node, "next_hop", ip6);
18756     }
18757 }
18758
18759 static void
18760 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
18761 {
18762   vat_main_t *vam = &vat_main;
18763   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18764   vl_api_fib_path_t *fp;
18765   i32 i;
18766
18767   print (vam->ofp, "sw_if_index %d via:",
18768          ntohl (mp->mt_tunnel.mt_sw_if_index));
18769   fp = mp->mt_tunnel.mt_paths;
18770   for (i = 0; i < count; i++)
18771     {
18772       vl_api_fib_path_print (vam, fp);
18773       fp++;
18774     }
18775
18776   print (vam->ofp, "");
18777 }
18778
18779 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
18780 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
18781
18782 static void
18783 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
18784 {
18785   vat_main_t *vam = &vat_main;
18786   vat_json_node_t *node = NULL;
18787   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18788   vl_api_fib_path_t *fp;
18789   i32 i;
18790
18791   if (VAT_JSON_ARRAY != vam->json_tree.type)
18792     {
18793       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18794       vat_json_init_array (&vam->json_tree);
18795     }
18796   node = vat_json_array_add (&vam->json_tree);
18797
18798   vat_json_init_object (node);
18799   vat_json_object_add_uint (node, "sw_if_index",
18800                             ntohl (mp->mt_tunnel.mt_sw_if_index));
18801
18802   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
18803
18804   fp = mp->mt_tunnel.mt_paths;
18805   for (i = 0; i < count; i++)
18806     {
18807       vl_api_mpls_fib_path_json_print (node, fp);
18808       fp++;
18809     }
18810 }
18811
18812 static int
18813 api_mpls_tunnel_dump (vat_main_t * vam)
18814 {
18815   vl_api_mpls_tunnel_dump_t *mp;
18816   vl_api_control_ping_t *mp_ping;
18817   int ret;
18818
18819   M (MPLS_TUNNEL_DUMP, mp);
18820
18821   S (mp);
18822
18823   /* Use a control ping for synchronization */
18824   MPING (CONTROL_PING, mp_ping);
18825   S (mp_ping);
18826
18827   W (ret);
18828   return ret;
18829 }
18830
18831 #define vl_api_mpls_table_details_t_endian vl_noop_handler
18832 #define vl_api_mpls_table_details_t_print vl_noop_handler
18833
18834
18835 static void
18836 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
18837 {
18838   vat_main_t *vam = &vat_main;
18839
18840   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
18841 }
18842
18843 static void vl_api_mpls_table_details_t_handler_json
18844   (vl_api_mpls_table_details_t * mp)
18845 {
18846   vat_main_t *vam = &vat_main;
18847   vat_json_node_t *node = NULL;
18848
18849   if (VAT_JSON_ARRAY != vam->json_tree.type)
18850     {
18851       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18852       vat_json_init_array (&vam->json_tree);
18853     }
18854   node = vat_json_array_add (&vam->json_tree);
18855
18856   vat_json_init_object (node);
18857   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
18858 }
18859
18860 static int
18861 api_mpls_table_dump (vat_main_t * vam)
18862 {
18863   vl_api_mpls_table_dump_t *mp;
18864   vl_api_control_ping_t *mp_ping;
18865   int ret;
18866
18867   M (MPLS_TABLE_DUMP, mp);
18868   S (mp);
18869
18870   /* Use a control ping for synchronization */
18871   MPING (CONTROL_PING, mp_ping);
18872   S (mp_ping);
18873
18874   W (ret);
18875   return ret;
18876 }
18877
18878 #define vl_api_mpls_route_details_t_endian vl_noop_handler
18879 #define vl_api_mpls_route_details_t_print vl_noop_handler
18880
18881 static void
18882 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
18883 {
18884   vat_main_t *vam = &vat_main;
18885   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
18886   vl_api_fib_path_t *fp;
18887   int i;
18888
18889   print (vam->ofp,
18890          "table-id %d, label %u, ess_bit %u",
18891          ntohl (mp->mr_route.mr_table_id),
18892          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
18893   fp = mp->mr_route.mr_paths;
18894   for (i = 0; i < count; i++)
18895     {
18896       vl_api_fib_path_print (vam, fp);
18897       fp++;
18898     }
18899 }
18900
18901 static void vl_api_mpls_route_details_t_handler_json
18902   (vl_api_mpls_route_details_t * mp)
18903 {
18904   vat_main_t *vam = &vat_main;
18905   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
18906   vat_json_node_t *node = NULL;
18907   vl_api_fib_path_t *fp;
18908   int i;
18909
18910   if (VAT_JSON_ARRAY != vam->json_tree.type)
18911     {
18912       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18913       vat_json_init_array (&vam->json_tree);
18914     }
18915   node = vat_json_array_add (&vam->json_tree);
18916
18917   vat_json_init_object (node);
18918   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
18919   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
18920   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
18921   vat_json_object_add_uint (node, "path_count", count);
18922   fp = mp->mr_route.mr_paths;
18923   for (i = 0; i < count; i++)
18924     {
18925       vl_api_mpls_fib_path_json_print (node, fp);
18926       fp++;
18927     }
18928 }
18929
18930 static int
18931 api_mpls_route_dump (vat_main_t * vam)
18932 {
18933   unformat_input_t *input = vam->input;
18934   vl_api_mpls_route_dump_t *mp;
18935   vl_api_control_ping_t *mp_ping;
18936   u32 table_id;
18937   int ret;
18938
18939   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18940     {
18941       if (unformat (input, "table_id %d", &table_id))
18942         ;
18943       else
18944         break;
18945     }
18946   if (table_id == ~0)
18947     {
18948       errmsg ("missing table id");
18949       return -99;
18950     }
18951
18952   M (MPLS_ROUTE_DUMP, mp);
18953
18954   mp->table.mt_table_id = ntohl (table_id);
18955   S (mp);
18956
18957   /* Use a control ping for synchronization */
18958   MPING (CONTROL_PING, mp_ping);
18959   S (mp_ping);
18960
18961   W (ret);
18962   return ret;
18963 }
18964
18965 #define vl_api_ip_table_details_t_endian vl_noop_handler
18966 #define vl_api_ip_table_details_t_print vl_noop_handler
18967
18968 static void
18969 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
18970 {
18971   vat_main_t *vam = &vat_main;
18972
18973   print (vam->ofp,
18974          "%s; table-id %d, prefix %U/%d",
18975          mp->table.name, ntohl (mp->table.table_id));
18976 }
18977
18978
18979 static void vl_api_ip_table_details_t_handler_json
18980   (vl_api_ip_table_details_t * mp)
18981 {
18982   vat_main_t *vam = &vat_main;
18983   vat_json_node_t *node = NULL;
18984
18985   if (VAT_JSON_ARRAY != vam->json_tree.type)
18986     {
18987       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18988       vat_json_init_array (&vam->json_tree);
18989     }
18990   node = vat_json_array_add (&vam->json_tree);
18991
18992   vat_json_init_object (node);
18993   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
18994 }
18995
18996 static int
18997 api_ip_table_dump (vat_main_t * vam)
18998 {
18999   vl_api_ip_table_dump_t *mp;
19000   vl_api_control_ping_t *mp_ping;
19001   int ret;
19002
19003   M (IP_TABLE_DUMP, mp);
19004   S (mp);
19005
19006   /* Use a control ping for synchronization */
19007   MPING (CONTROL_PING, mp_ping);
19008   S (mp_ping);
19009
19010   W (ret);
19011   return ret;
19012 }
19013
19014 static int
19015 api_ip_mtable_dump (vat_main_t * vam)
19016 {
19017   vl_api_ip_mtable_dump_t *mp;
19018   vl_api_control_ping_t *mp_ping;
19019   int ret;
19020
19021   M (IP_MTABLE_DUMP, mp);
19022   S (mp);
19023
19024   /* Use a control ping for synchronization */
19025   MPING (CONTROL_PING, mp_ping);
19026   S (mp_ping);
19027
19028   W (ret);
19029   return ret;
19030 }
19031
19032 static int
19033 api_ip_mroute_dump (vat_main_t * vam)
19034 {
19035   unformat_input_t *input = vam->input;
19036   vl_api_control_ping_t *mp_ping;
19037   vl_api_ip_mroute_dump_t *mp;
19038   int ret, is_ip6;
19039   u32 table_id;
19040
19041   is_ip6 = 0;
19042   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19043     {
19044       if (unformat (input, "table_id %d", &table_id))
19045         ;
19046       else if (unformat (input, "ip6"))
19047         is_ip6 = 1;
19048       else if (unformat (input, "ip4"))
19049         is_ip6 = 0;
19050       else
19051         break;
19052     }
19053   if (table_id == ~0)
19054     {
19055       errmsg ("missing table id");
19056       return -99;
19057     }
19058
19059   M (IP_MROUTE_DUMP, mp);
19060   mp->table.table_id = table_id;
19061   mp->table.is_ip6 = is_ip6;
19062   S (mp);
19063
19064   /* Use a control ping for synchronization */
19065   MPING (CONTROL_PING, mp_ping);
19066   S (mp_ping);
19067
19068   W (ret);
19069   return ret;
19070 }
19071
19072 static void vl_api_ip_neighbor_details_t_handler
19073   (vl_api_ip_neighbor_details_t * mp)
19074 {
19075   vat_main_t *vam = &vat_main;
19076
19077   print (vam->ofp, "%c %U %U",
19078          (ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ? 'S' : 'D',
19079          format_vl_api_mac_address, &mp->neighbor.mac_address,
19080          format_vl_api_address, &mp->neighbor.ip_address);
19081 }
19082
19083 static void vl_api_ip_neighbor_details_t_handler_json
19084   (vl_api_ip_neighbor_details_t * mp)
19085 {
19086
19087   vat_main_t *vam = &vat_main;
19088   vat_json_node_t *node;
19089
19090   if (VAT_JSON_ARRAY != vam->json_tree.type)
19091     {
19092       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19093       vat_json_init_array (&vam->json_tree);
19094     }
19095   node = vat_json_array_add (&vam->json_tree);
19096
19097   vat_json_init_object (node);
19098   vat_json_object_add_string_copy
19099     (node, "flag",
19100      ((ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ?
19101       (u8 *) "static" : (u8 *) "dynamic"));
19102
19103   vat_json_object_add_string_copy (node, "link_layer",
19104                                    format (0, "%U", format_vl_api_mac_address,
19105                                            &mp->neighbor.mac_address));
19106   vat_json_object_add_address (node, "ip", &mp->neighbor.ip_address);
19107 }
19108
19109 static int
19110 api_ip_neighbor_dump (vat_main_t * vam)
19111 {
19112   unformat_input_t *i = vam->input;
19113   vl_api_ip_neighbor_dump_t *mp;
19114   vl_api_control_ping_t *mp_ping;
19115   u8 is_ipv6 = 0;
19116   u32 sw_if_index = ~0;
19117   int ret;
19118
19119   /* Parse args required to build the message */
19120   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19121     {
19122       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19123         ;
19124       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19125         ;
19126       else if (unformat (i, "ip6"))
19127         is_ipv6 = 1;
19128       else
19129         break;
19130     }
19131
19132   if (sw_if_index == ~0)
19133     {
19134       errmsg ("missing interface name or sw_if_index");
19135       return -99;
19136     }
19137
19138   M (IP_NEIGHBOR_DUMP, mp);
19139   mp->is_ipv6 = (u8) is_ipv6;
19140   mp->sw_if_index = ntohl (sw_if_index);
19141   S (mp);
19142
19143   /* Use a control ping for synchronization */
19144   MPING (CONTROL_PING, mp_ping);
19145   S (mp_ping);
19146
19147   W (ret);
19148   return ret;
19149 }
19150
19151 #define vl_api_ip_route_details_t_endian vl_noop_handler
19152 #define vl_api_ip_route_details_t_print vl_noop_handler
19153
19154 static void
19155 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
19156 {
19157   vat_main_t *vam = &vat_main;
19158   u8 count = mp->route.n_paths;
19159   vl_api_fib_path_t *fp;
19160   int i;
19161
19162   print (vam->ofp,
19163          "table-id %d, prefix %U/%d",
19164          ntohl (mp->route.table_id),
19165          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
19166   for (i = 0; i < count; i++)
19167     {
19168       fp = &mp->route.paths[i];
19169
19170       vl_api_fib_path_print (vam, fp);
19171       fp++;
19172     }
19173 }
19174
19175 static void vl_api_ip_route_details_t_handler_json
19176   (vl_api_ip_route_details_t * mp)
19177 {
19178   vat_main_t *vam = &vat_main;
19179   u8 count = mp->route.n_paths;
19180   vat_json_node_t *node = NULL;
19181   struct in_addr ip4;
19182   struct in6_addr ip6;
19183   vl_api_fib_path_t *fp;
19184   int i;
19185
19186   if (VAT_JSON_ARRAY != vam->json_tree.type)
19187     {
19188       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19189       vat_json_init_array (&vam->json_tree);
19190     }
19191   node = vat_json_array_add (&vam->json_tree);
19192
19193   vat_json_init_object (node);
19194   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
19195   if (ADDRESS_IP6 == mp->route.prefix.address.af)
19196     {
19197       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
19198       vat_json_object_add_ip6 (node, "prefix", ip6);
19199     }
19200   else
19201     {
19202       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
19203       vat_json_object_add_ip4 (node, "prefix", ip4);
19204     }
19205   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
19206   vat_json_object_add_uint (node, "path_count", count);
19207   for (i = 0; i < count; i++)
19208     {
19209       fp = &mp->route.paths[i];
19210       vl_api_mpls_fib_path_json_print (node, fp);
19211     }
19212 }
19213
19214 static int
19215 api_ip_route_dump (vat_main_t * vam)
19216 {
19217   unformat_input_t *input = vam->input;
19218   vl_api_ip_route_dump_t *mp;
19219   vl_api_control_ping_t *mp_ping;
19220   u32 table_id;
19221   u8 is_ip6;
19222   int ret;
19223
19224   is_ip6 = 0;
19225   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19226     {
19227       if (unformat (input, "table_id %d", &table_id))
19228         ;
19229       else if (unformat (input, "ip6"))
19230         is_ip6 = 1;
19231       else if (unformat (input, "ip4"))
19232         is_ip6 = 0;
19233       else
19234         break;
19235     }
19236   if (table_id == ~0)
19237     {
19238       errmsg ("missing table id");
19239       return -99;
19240     }
19241
19242   M (IP_ROUTE_DUMP, mp);
19243
19244   mp->table.table_id = table_id;
19245   mp->table.is_ip6 = is_ip6;
19246
19247   S (mp);
19248
19249   /* Use a control ping for synchronization */
19250   MPING (CONTROL_PING, mp_ping);
19251   S (mp_ping);
19252
19253   W (ret);
19254   return ret;
19255 }
19256
19257 int
19258 api_classify_table_ids (vat_main_t * vam)
19259 {
19260   vl_api_classify_table_ids_t *mp;
19261   int ret;
19262
19263   /* Construct the API message */
19264   M (CLASSIFY_TABLE_IDS, mp);
19265   mp->context = 0;
19266
19267   S (mp);
19268   W (ret);
19269   return ret;
19270 }
19271
19272 int
19273 api_classify_table_by_interface (vat_main_t * vam)
19274 {
19275   unformat_input_t *input = vam->input;
19276   vl_api_classify_table_by_interface_t *mp;
19277
19278   u32 sw_if_index = ~0;
19279   int ret;
19280   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19281     {
19282       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19283         ;
19284       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19285         ;
19286       else
19287         break;
19288     }
19289   if (sw_if_index == ~0)
19290     {
19291       errmsg ("missing interface name or sw_if_index");
19292       return -99;
19293     }
19294
19295   /* Construct the API message */
19296   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
19297   mp->context = 0;
19298   mp->sw_if_index = ntohl (sw_if_index);
19299
19300   S (mp);
19301   W (ret);
19302   return ret;
19303 }
19304
19305 int
19306 api_classify_table_info (vat_main_t * vam)
19307 {
19308   unformat_input_t *input = vam->input;
19309   vl_api_classify_table_info_t *mp;
19310
19311   u32 table_id = ~0;
19312   int ret;
19313   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19314     {
19315       if (unformat (input, "table_id %d", &table_id))
19316         ;
19317       else
19318         break;
19319     }
19320   if (table_id == ~0)
19321     {
19322       errmsg ("missing table id");
19323       return -99;
19324     }
19325
19326   /* Construct the API message */
19327   M (CLASSIFY_TABLE_INFO, mp);
19328   mp->context = 0;
19329   mp->table_id = ntohl (table_id);
19330
19331   S (mp);
19332   W (ret);
19333   return ret;
19334 }
19335
19336 int
19337 api_classify_session_dump (vat_main_t * vam)
19338 {
19339   unformat_input_t *input = vam->input;
19340   vl_api_classify_session_dump_t *mp;
19341   vl_api_control_ping_t *mp_ping;
19342
19343   u32 table_id = ~0;
19344   int ret;
19345   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19346     {
19347       if (unformat (input, "table_id %d", &table_id))
19348         ;
19349       else
19350         break;
19351     }
19352   if (table_id == ~0)
19353     {
19354       errmsg ("missing table id");
19355       return -99;
19356     }
19357
19358   /* Construct the API message */
19359   M (CLASSIFY_SESSION_DUMP, mp);
19360   mp->context = 0;
19361   mp->table_id = ntohl (table_id);
19362   S (mp);
19363
19364   /* Use a control ping for synchronization */
19365   MPING (CONTROL_PING, mp_ping);
19366   S (mp_ping);
19367
19368   W (ret);
19369   return ret;
19370 }
19371
19372 static void
19373 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19374 {
19375   vat_main_t *vam = &vat_main;
19376
19377   print (vam->ofp, "collector_address %U, collector_port %d, "
19378          "src_address %U, vrf_id %d, path_mtu %u, "
19379          "template_interval %u, udp_checksum %d",
19380          format_ip4_address, mp->collector_address,
19381          ntohs (mp->collector_port),
19382          format_ip4_address, mp->src_address,
19383          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19384          ntohl (mp->template_interval), mp->udp_checksum);
19385
19386   vam->retval = 0;
19387   vam->result_ready = 1;
19388 }
19389
19390 static void
19391   vl_api_ipfix_exporter_details_t_handler_json
19392   (vl_api_ipfix_exporter_details_t * mp)
19393 {
19394   vat_main_t *vam = &vat_main;
19395   vat_json_node_t node;
19396   struct in_addr collector_address;
19397   struct in_addr src_address;
19398
19399   vat_json_init_object (&node);
19400   clib_memcpy (&collector_address, &mp->collector_address,
19401                sizeof (collector_address));
19402   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19403   vat_json_object_add_uint (&node, "collector_port",
19404                             ntohs (mp->collector_port));
19405   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19406   vat_json_object_add_ip4 (&node, "src_address", src_address);
19407   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19408   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19409   vat_json_object_add_uint (&node, "template_interval",
19410                             ntohl (mp->template_interval));
19411   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19412
19413   vat_json_print (vam->ofp, &node);
19414   vat_json_free (&node);
19415   vam->retval = 0;
19416   vam->result_ready = 1;
19417 }
19418
19419 int
19420 api_ipfix_exporter_dump (vat_main_t * vam)
19421 {
19422   vl_api_ipfix_exporter_dump_t *mp;
19423   int ret;
19424
19425   /* Construct the API message */
19426   M (IPFIX_EXPORTER_DUMP, mp);
19427   mp->context = 0;
19428
19429   S (mp);
19430   W (ret);
19431   return ret;
19432 }
19433
19434 static int
19435 api_ipfix_classify_stream_dump (vat_main_t * vam)
19436 {
19437   vl_api_ipfix_classify_stream_dump_t *mp;
19438   int ret;
19439
19440   /* Construct the API message */
19441   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19442   mp->context = 0;
19443
19444   S (mp);
19445   W (ret);
19446   return ret;
19447   /* NOTREACHED */
19448   return 0;
19449 }
19450
19451 static void
19452   vl_api_ipfix_classify_stream_details_t_handler
19453   (vl_api_ipfix_classify_stream_details_t * mp)
19454 {
19455   vat_main_t *vam = &vat_main;
19456   print (vam->ofp, "domain_id %d, src_port %d",
19457          ntohl (mp->domain_id), ntohs (mp->src_port));
19458   vam->retval = 0;
19459   vam->result_ready = 1;
19460 }
19461
19462 static void
19463   vl_api_ipfix_classify_stream_details_t_handler_json
19464   (vl_api_ipfix_classify_stream_details_t * mp)
19465 {
19466   vat_main_t *vam = &vat_main;
19467   vat_json_node_t node;
19468
19469   vat_json_init_object (&node);
19470   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19471   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19472
19473   vat_json_print (vam->ofp, &node);
19474   vat_json_free (&node);
19475   vam->retval = 0;
19476   vam->result_ready = 1;
19477 }
19478
19479 static int
19480 api_ipfix_classify_table_dump (vat_main_t * vam)
19481 {
19482   vl_api_ipfix_classify_table_dump_t *mp;
19483   vl_api_control_ping_t *mp_ping;
19484   int ret;
19485
19486   if (!vam->json_output)
19487     {
19488       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19489              "transport_protocol");
19490     }
19491
19492   /* Construct the API message */
19493   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19494
19495   /* send it... */
19496   S (mp);
19497
19498   /* Use a control ping for synchronization */
19499   MPING (CONTROL_PING, mp_ping);
19500   S (mp_ping);
19501
19502   W (ret);
19503   return ret;
19504 }
19505
19506 static void
19507   vl_api_ipfix_classify_table_details_t_handler
19508   (vl_api_ipfix_classify_table_details_t * mp)
19509 {
19510   vat_main_t *vam = &vat_main;
19511   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19512          mp->transport_protocol);
19513 }
19514
19515 static void
19516   vl_api_ipfix_classify_table_details_t_handler_json
19517   (vl_api_ipfix_classify_table_details_t * mp)
19518 {
19519   vat_json_node_t *node = NULL;
19520   vat_main_t *vam = &vat_main;
19521
19522   if (VAT_JSON_ARRAY != vam->json_tree.type)
19523     {
19524       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19525       vat_json_init_array (&vam->json_tree);
19526     }
19527
19528   node = vat_json_array_add (&vam->json_tree);
19529   vat_json_init_object (node);
19530
19531   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19532   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19533   vat_json_object_add_uint (node, "transport_protocol",
19534                             mp->transport_protocol);
19535 }
19536
19537 static int
19538 api_sw_interface_span_enable_disable (vat_main_t * vam)
19539 {
19540   unformat_input_t *i = vam->input;
19541   vl_api_sw_interface_span_enable_disable_t *mp;
19542   u32 src_sw_if_index = ~0;
19543   u32 dst_sw_if_index = ~0;
19544   u8 state = 3;
19545   int ret;
19546   u8 is_l2 = 0;
19547
19548   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19549     {
19550       if (unformat
19551           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19552         ;
19553       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19554         ;
19555       else
19556         if (unformat
19557             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19558         ;
19559       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19560         ;
19561       else if (unformat (i, "disable"))
19562         state = 0;
19563       else if (unformat (i, "rx"))
19564         state = 1;
19565       else if (unformat (i, "tx"))
19566         state = 2;
19567       else if (unformat (i, "both"))
19568         state = 3;
19569       else if (unformat (i, "l2"))
19570         is_l2 = 1;
19571       else
19572         break;
19573     }
19574
19575   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19576
19577   mp->sw_if_index_from = htonl (src_sw_if_index);
19578   mp->sw_if_index_to = htonl (dst_sw_if_index);
19579   mp->state = state;
19580   mp->is_l2 = is_l2;
19581
19582   S (mp);
19583   W (ret);
19584   return ret;
19585 }
19586
19587 static void
19588 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19589                                             * mp)
19590 {
19591   vat_main_t *vam = &vat_main;
19592   u8 *sw_if_from_name = 0;
19593   u8 *sw_if_to_name = 0;
19594   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19595   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19596   char *states[] = { "none", "rx", "tx", "both" };
19597   hash_pair_t *p;
19598
19599   /* *INDENT-OFF* */
19600   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19601   ({
19602     if ((u32) p->value[0] == sw_if_index_from)
19603       {
19604         sw_if_from_name = (u8 *)(p->key);
19605         if (sw_if_to_name)
19606           break;
19607       }
19608     if ((u32) p->value[0] == sw_if_index_to)
19609       {
19610         sw_if_to_name = (u8 *)(p->key);
19611         if (sw_if_from_name)
19612           break;
19613       }
19614   }));
19615   /* *INDENT-ON* */
19616   print (vam->ofp, "%20s => %20s (%s) %s",
19617          sw_if_from_name, sw_if_to_name, states[mp->state],
19618          mp->is_l2 ? "l2" : "device");
19619 }
19620
19621 static void
19622   vl_api_sw_interface_span_details_t_handler_json
19623   (vl_api_sw_interface_span_details_t * mp)
19624 {
19625   vat_main_t *vam = &vat_main;
19626   vat_json_node_t *node = NULL;
19627   u8 *sw_if_from_name = 0;
19628   u8 *sw_if_to_name = 0;
19629   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19630   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19631   hash_pair_t *p;
19632
19633   /* *INDENT-OFF* */
19634   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19635   ({
19636     if ((u32) p->value[0] == sw_if_index_from)
19637       {
19638         sw_if_from_name = (u8 *)(p->key);
19639         if (sw_if_to_name)
19640           break;
19641       }
19642     if ((u32) p->value[0] == sw_if_index_to)
19643       {
19644         sw_if_to_name = (u8 *)(p->key);
19645         if (sw_if_from_name)
19646           break;
19647       }
19648   }));
19649   /* *INDENT-ON* */
19650
19651   if (VAT_JSON_ARRAY != vam->json_tree.type)
19652     {
19653       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19654       vat_json_init_array (&vam->json_tree);
19655     }
19656   node = vat_json_array_add (&vam->json_tree);
19657
19658   vat_json_init_object (node);
19659   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
19660   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
19661   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
19662   if (0 != sw_if_to_name)
19663     {
19664       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
19665     }
19666   vat_json_object_add_uint (node, "state", mp->state);
19667   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
19668 }
19669
19670 static int
19671 api_sw_interface_span_dump (vat_main_t * vam)
19672 {
19673   unformat_input_t *input = vam->input;
19674   vl_api_sw_interface_span_dump_t *mp;
19675   vl_api_control_ping_t *mp_ping;
19676   u8 is_l2 = 0;
19677   int ret;
19678
19679   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19680     {
19681       if (unformat (input, "l2"))
19682         is_l2 = 1;
19683       else
19684         break;
19685     }
19686
19687   M (SW_INTERFACE_SPAN_DUMP, mp);
19688   mp->is_l2 = is_l2;
19689   S (mp);
19690
19691   /* Use a control ping for synchronization */
19692   MPING (CONTROL_PING, mp_ping);
19693   S (mp_ping);
19694
19695   W (ret);
19696   return ret;
19697 }
19698
19699 int
19700 api_pg_create_interface (vat_main_t * vam)
19701 {
19702   unformat_input_t *input = vam->input;
19703   vl_api_pg_create_interface_t *mp;
19704
19705   u32 if_id = ~0, gso_size = 0;
19706   u8 gso_enabled = 0;
19707   int ret;
19708   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19709     {
19710       if (unformat (input, "if_id %d", &if_id))
19711         ;
19712       else if (unformat (input, "gso-enabled"))
19713         {
19714           gso_enabled = 1;
19715           if (unformat (input, "gso-size %u", &gso_size))
19716             ;
19717           else
19718             {
19719               errmsg ("missing gso-size");
19720               return -99;
19721             }
19722         }
19723       else
19724         break;
19725     }
19726   if (if_id == ~0)
19727     {
19728       errmsg ("missing pg interface index");
19729       return -99;
19730     }
19731
19732   /* Construct the API message */
19733   M (PG_CREATE_INTERFACE, mp);
19734   mp->context = 0;
19735   mp->interface_id = ntohl (if_id);
19736   mp->gso_enabled = gso_enabled;
19737
19738   S (mp);
19739   W (ret);
19740   return ret;
19741 }
19742
19743 int
19744 api_pg_capture (vat_main_t * vam)
19745 {
19746   unformat_input_t *input = vam->input;
19747   vl_api_pg_capture_t *mp;
19748
19749   u32 if_id = ~0;
19750   u8 enable = 1;
19751   u32 count = 1;
19752   u8 pcap_file_set = 0;
19753   u8 *pcap_file = 0;
19754   int ret;
19755   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19756     {
19757       if (unformat (input, "if_id %d", &if_id))
19758         ;
19759       else if (unformat (input, "pcap %s", &pcap_file))
19760         pcap_file_set = 1;
19761       else if (unformat (input, "count %d", &count))
19762         ;
19763       else if (unformat (input, "disable"))
19764         enable = 0;
19765       else
19766         break;
19767     }
19768   if (if_id == ~0)
19769     {
19770       errmsg ("missing pg interface index");
19771       return -99;
19772     }
19773   if (pcap_file_set > 0)
19774     {
19775       if (vec_len (pcap_file) > 255)
19776         {
19777           errmsg ("pcap file name is too long");
19778           return -99;
19779         }
19780     }
19781
19782   u32 name_len = vec_len (pcap_file);
19783   /* Construct the API message */
19784   M (PG_CAPTURE, mp);
19785   mp->context = 0;
19786   mp->interface_id = ntohl (if_id);
19787   mp->is_enabled = enable;
19788   mp->count = ntohl (count);
19789   mp->pcap_name_length = ntohl (name_len);
19790   if (pcap_file_set != 0)
19791     {
19792       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
19793     }
19794   vec_free (pcap_file);
19795
19796   S (mp);
19797   W (ret);
19798   return ret;
19799 }
19800
19801 int
19802 api_pg_enable_disable (vat_main_t * vam)
19803 {
19804   unformat_input_t *input = vam->input;
19805   vl_api_pg_enable_disable_t *mp;
19806
19807   u8 enable = 1;
19808   u8 stream_name_set = 0;
19809   u8 *stream_name = 0;
19810   int ret;
19811   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19812     {
19813       if (unformat (input, "stream %s", &stream_name))
19814         stream_name_set = 1;
19815       else if (unformat (input, "disable"))
19816         enable = 0;
19817       else
19818         break;
19819     }
19820
19821   if (stream_name_set > 0)
19822     {
19823       if (vec_len (stream_name) > 255)
19824         {
19825           errmsg ("stream name too long");
19826           return -99;
19827         }
19828     }
19829
19830   u32 name_len = vec_len (stream_name);
19831   /* Construct the API message */
19832   M (PG_ENABLE_DISABLE, mp);
19833   mp->context = 0;
19834   mp->is_enabled = enable;
19835   if (stream_name_set != 0)
19836     {
19837       mp->stream_name_length = ntohl (name_len);
19838       clib_memcpy (mp->stream_name, stream_name, name_len);
19839     }
19840   vec_free (stream_name);
19841
19842   S (mp);
19843   W (ret);
19844   return ret;
19845 }
19846
19847 int
19848 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
19849 {
19850   unformat_input_t *input = vam->input;
19851   vl_api_ip_source_and_port_range_check_add_del_t *mp;
19852
19853   u16 *low_ports = 0;
19854   u16 *high_ports = 0;
19855   u16 this_low;
19856   u16 this_hi;
19857   vl_api_prefix_t prefix;
19858   u32 tmp, tmp2;
19859   u8 prefix_set = 0;
19860   u32 vrf_id = ~0;
19861   u8 is_add = 1;
19862   int ret;
19863
19864   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19865     {
19866       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
19867         prefix_set = 1;
19868       else if (unformat (input, "vrf %d", &vrf_id))
19869         ;
19870       else if (unformat (input, "del"))
19871         is_add = 0;
19872       else if (unformat (input, "port %d", &tmp))
19873         {
19874           if (tmp == 0 || tmp > 65535)
19875             {
19876               errmsg ("port %d out of range", tmp);
19877               return -99;
19878             }
19879           this_low = tmp;
19880           this_hi = this_low + 1;
19881           vec_add1 (low_ports, this_low);
19882           vec_add1 (high_ports, this_hi);
19883         }
19884       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
19885         {
19886           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
19887             {
19888               errmsg ("incorrect range parameters");
19889               return -99;
19890             }
19891           this_low = tmp;
19892           /* Note: in debug CLI +1 is added to high before
19893              passing to real fn that does "the work"
19894              (ip_source_and_port_range_check_add_del).
19895              This fn is a wrapper around the binary API fn a
19896              control plane will call, which expects this increment
19897              to have occurred. Hence letting the binary API control
19898              plane fn do the increment for consistency between VAT
19899              and other control planes.
19900            */
19901           this_hi = tmp2;
19902           vec_add1 (low_ports, this_low);
19903           vec_add1 (high_ports, this_hi);
19904         }
19905       else
19906         break;
19907     }
19908
19909   if (prefix_set == 0)
19910     {
19911       errmsg ("<address>/<mask> not specified");
19912       return -99;
19913     }
19914
19915   if (vrf_id == ~0)
19916     {
19917       errmsg ("VRF ID required, not specified");
19918       return -99;
19919     }
19920
19921   if (vrf_id == 0)
19922     {
19923       errmsg
19924         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19925       return -99;
19926     }
19927
19928   if (vec_len (low_ports) == 0)
19929     {
19930       errmsg ("At least one port or port range required");
19931       return -99;
19932     }
19933
19934   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
19935
19936   mp->is_add = is_add;
19937
19938   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
19939
19940   mp->number_of_ranges = vec_len (low_ports);
19941
19942   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
19943   vec_free (low_ports);
19944
19945   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
19946   vec_free (high_ports);
19947
19948   mp->vrf_id = ntohl (vrf_id);
19949
19950   S (mp);
19951   W (ret);
19952   return ret;
19953 }
19954
19955 int
19956 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
19957 {
19958   unformat_input_t *input = vam->input;
19959   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
19960   u32 sw_if_index = ~0;
19961   int vrf_set = 0;
19962   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
19963   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
19964   u8 is_add = 1;
19965   int ret;
19966
19967   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19968     {
19969       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19970         ;
19971       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19972         ;
19973       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
19974         vrf_set = 1;
19975       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
19976         vrf_set = 1;
19977       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
19978         vrf_set = 1;
19979       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
19980         vrf_set = 1;
19981       else if (unformat (input, "del"))
19982         is_add = 0;
19983       else
19984         break;
19985     }
19986
19987   if (sw_if_index == ~0)
19988     {
19989       errmsg ("Interface required but not specified");
19990       return -99;
19991     }
19992
19993   if (vrf_set == 0)
19994     {
19995       errmsg ("VRF ID required but not specified");
19996       return -99;
19997     }
19998
19999   if (tcp_out_vrf_id == 0
20000       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
20001     {
20002       errmsg
20003         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20004       return -99;
20005     }
20006
20007   /* Construct the API message */
20008   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20009
20010   mp->sw_if_index = ntohl (sw_if_index);
20011   mp->is_add = is_add;
20012   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20013   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20014   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20015   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20016
20017   /* send it... */
20018   S (mp);
20019
20020   /* Wait for a reply... */
20021   W (ret);
20022   return ret;
20023 }
20024
20025 static int
20026 api_set_punt (vat_main_t * vam)
20027 {
20028   unformat_input_t *i = vam->input;
20029   vl_api_address_family_t af;
20030   vl_api_set_punt_t *mp;
20031   u32 protocol = ~0;
20032   u32 port = ~0;
20033   int is_add = 1;
20034   int ret;
20035
20036   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20037     {
20038       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
20039         ;
20040       else if (unformat (i, "protocol %d", &protocol))
20041         ;
20042       else if (unformat (i, "port %d", &port))
20043         ;
20044       else if (unformat (i, "del"))
20045         is_add = 0;
20046       else
20047         {
20048           clib_warning ("parse error '%U'", format_unformat_error, i);
20049           return -99;
20050         }
20051     }
20052
20053   M (SET_PUNT, mp);
20054
20055   mp->is_add = (u8) is_add;
20056   mp->punt.type = PUNT_API_TYPE_L4;
20057   mp->punt.punt.l4.af = af;
20058   mp->punt.punt.l4.protocol = (u8) protocol;
20059   mp->punt.punt.l4.port = htons ((u16) port);
20060
20061   S (mp);
20062   W (ret);
20063   return ret;
20064 }
20065
20066 static int
20067 api_delete_subif (vat_main_t * vam)
20068 {
20069   unformat_input_t *i = vam->input;
20070   vl_api_delete_subif_t *mp;
20071   u32 sw_if_index = ~0;
20072   int ret;
20073
20074   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20075     {
20076       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20077         ;
20078       if (unformat (i, "sw_if_index %d", &sw_if_index))
20079         ;
20080       else
20081         break;
20082     }
20083
20084   if (sw_if_index == ~0)
20085     {
20086       errmsg ("missing sw_if_index");
20087       return -99;
20088     }
20089
20090   /* Construct the API message */
20091   M (DELETE_SUBIF, mp);
20092   mp->sw_if_index = ntohl (sw_if_index);
20093
20094   S (mp);
20095   W (ret);
20096   return ret;
20097 }
20098
20099 #define foreach_pbb_vtr_op      \
20100 _("disable",  L2_VTR_DISABLED)  \
20101 _("pop",  L2_VTR_POP_2)         \
20102 _("push",  L2_VTR_PUSH_2)
20103
20104 static int
20105 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
20106 {
20107   unformat_input_t *i = vam->input;
20108   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
20109   u32 sw_if_index = ~0, vtr_op = ~0;
20110   u16 outer_tag = ~0;
20111   u8 dmac[6], smac[6];
20112   u8 dmac_set = 0, smac_set = 0;
20113   u16 vlanid = 0;
20114   u32 sid = ~0;
20115   u32 tmp;
20116   int ret;
20117
20118   /* Shut up coverity */
20119   clib_memset (dmac, 0, sizeof (dmac));
20120   clib_memset (smac, 0, sizeof (smac));
20121
20122   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20123     {
20124       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20125         ;
20126       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20127         ;
20128       else if (unformat (i, "vtr_op %d", &vtr_op))
20129         ;
20130 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
20131       foreach_pbb_vtr_op
20132 #undef _
20133         else if (unformat (i, "translate_pbb_stag"))
20134         {
20135           if (unformat (i, "%d", &tmp))
20136             {
20137               vtr_op = L2_VTR_TRANSLATE_2_1;
20138               outer_tag = tmp;
20139             }
20140           else
20141             {
20142               errmsg
20143                 ("translate_pbb_stag operation requires outer tag definition");
20144               return -99;
20145             }
20146         }
20147       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
20148         dmac_set++;
20149       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
20150         smac_set++;
20151       else if (unformat (i, "sid %d", &sid))
20152         ;
20153       else if (unformat (i, "vlanid %d", &tmp))
20154         vlanid = tmp;
20155       else
20156         {
20157           clib_warning ("parse error '%U'", format_unformat_error, i);
20158           return -99;
20159         }
20160     }
20161
20162   if ((sw_if_index == ~0) || (vtr_op == ~0))
20163     {
20164       errmsg ("missing sw_if_index or vtr operation");
20165       return -99;
20166     }
20167   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
20168       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
20169     {
20170       errmsg
20171         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
20172       return -99;
20173     }
20174
20175   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
20176   mp->sw_if_index = ntohl (sw_if_index);
20177   mp->vtr_op = ntohl (vtr_op);
20178   mp->outer_tag = ntohs (outer_tag);
20179   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
20180   clib_memcpy (mp->b_smac, smac, sizeof (smac));
20181   mp->b_vlanid = ntohs (vlanid);
20182   mp->i_sid = ntohl (sid);
20183
20184   S (mp);
20185   W (ret);
20186   return ret;
20187 }
20188
20189 static int
20190 api_flow_classify_set_interface (vat_main_t * vam)
20191 {
20192   unformat_input_t *i = vam->input;
20193   vl_api_flow_classify_set_interface_t *mp;
20194   u32 sw_if_index;
20195   int sw_if_index_set;
20196   u32 ip4_table_index = ~0;
20197   u32 ip6_table_index = ~0;
20198   u8 is_add = 1;
20199   int ret;
20200
20201   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20202     {
20203       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20204         sw_if_index_set = 1;
20205       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20206         sw_if_index_set = 1;
20207       else if (unformat (i, "del"))
20208         is_add = 0;
20209       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20210         ;
20211       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20212         ;
20213       else
20214         {
20215           clib_warning ("parse error '%U'", format_unformat_error, i);
20216           return -99;
20217         }
20218     }
20219
20220   if (sw_if_index_set == 0)
20221     {
20222       errmsg ("missing interface name or sw_if_index");
20223       return -99;
20224     }
20225
20226   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
20227
20228   mp->sw_if_index = ntohl (sw_if_index);
20229   mp->ip4_table_index = ntohl (ip4_table_index);
20230   mp->ip6_table_index = ntohl (ip6_table_index);
20231   mp->is_add = is_add;
20232
20233   S (mp);
20234   W (ret);
20235   return ret;
20236 }
20237
20238 static int
20239 api_flow_classify_dump (vat_main_t * vam)
20240 {
20241   unformat_input_t *i = vam->input;
20242   vl_api_flow_classify_dump_t *mp;
20243   vl_api_control_ping_t *mp_ping;
20244   u8 type = FLOW_CLASSIFY_N_TABLES;
20245   int ret;
20246
20247   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
20248     ;
20249   else
20250     {
20251       errmsg ("classify table type must be specified");
20252       return -99;
20253     }
20254
20255   if (!vam->json_output)
20256     {
20257       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20258     }
20259
20260   M (FLOW_CLASSIFY_DUMP, mp);
20261   mp->type = type;
20262   /* send it... */
20263   S (mp);
20264
20265   /* Use a control ping for synchronization */
20266   MPING (CONTROL_PING, mp_ping);
20267   S (mp_ping);
20268
20269   /* Wait for a reply... */
20270   W (ret);
20271   return ret;
20272 }
20273
20274 static int
20275 api_feature_enable_disable (vat_main_t * vam)
20276 {
20277   unformat_input_t *i = vam->input;
20278   vl_api_feature_enable_disable_t *mp;
20279   u8 *arc_name = 0;
20280   u8 *feature_name = 0;
20281   u32 sw_if_index = ~0;
20282   u8 enable = 1;
20283   int ret;
20284
20285   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20286     {
20287       if (unformat (i, "arc_name %s", &arc_name))
20288         ;
20289       else if (unformat (i, "feature_name %s", &feature_name))
20290         ;
20291       else
20292         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20293         ;
20294       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20295         ;
20296       else if (unformat (i, "disable"))
20297         enable = 0;
20298       else
20299         break;
20300     }
20301
20302   if (arc_name == 0)
20303     {
20304       errmsg ("missing arc name");
20305       return -99;
20306     }
20307   if (vec_len (arc_name) > 63)
20308     {
20309       errmsg ("arc name too long");
20310     }
20311
20312   if (feature_name == 0)
20313     {
20314       errmsg ("missing feature name");
20315       return -99;
20316     }
20317   if (vec_len (feature_name) > 63)
20318     {
20319       errmsg ("feature name too long");
20320     }
20321
20322   if (sw_if_index == ~0)
20323     {
20324       errmsg ("missing interface name or sw_if_index");
20325       return -99;
20326     }
20327
20328   /* Construct the API message */
20329   M (FEATURE_ENABLE_DISABLE, mp);
20330   mp->sw_if_index = ntohl (sw_if_index);
20331   mp->enable = enable;
20332   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
20333   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
20334   vec_free (arc_name);
20335   vec_free (feature_name);
20336
20337   S (mp);
20338   W (ret);
20339   return ret;
20340 }
20341
20342 static int
20343 api_sw_interface_tag_add_del (vat_main_t * vam)
20344 {
20345   unformat_input_t *i = vam->input;
20346   vl_api_sw_interface_tag_add_del_t *mp;
20347   u32 sw_if_index = ~0;
20348   u8 *tag = 0;
20349   u8 enable = 1;
20350   int ret;
20351
20352   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20353     {
20354       if (unformat (i, "tag %s", &tag))
20355         ;
20356       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20357         ;
20358       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20359         ;
20360       else if (unformat (i, "del"))
20361         enable = 0;
20362       else
20363         break;
20364     }
20365
20366   if (sw_if_index == ~0)
20367     {
20368       errmsg ("missing interface name or sw_if_index");
20369       return -99;
20370     }
20371
20372   if (enable && (tag == 0))
20373     {
20374       errmsg ("no tag specified");
20375       return -99;
20376     }
20377
20378   /* Construct the API message */
20379   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20380   mp->sw_if_index = ntohl (sw_if_index);
20381   mp->is_add = enable;
20382   if (enable)
20383     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
20384   vec_free (tag);
20385
20386   S (mp);
20387   W (ret);
20388   return ret;
20389 }
20390
20391 static void vl_api_l2_xconnect_details_t_handler
20392   (vl_api_l2_xconnect_details_t * mp)
20393 {
20394   vat_main_t *vam = &vat_main;
20395
20396   print (vam->ofp, "%15d%15d",
20397          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20398 }
20399
20400 static void vl_api_l2_xconnect_details_t_handler_json
20401   (vl_api_l2_xconnect_details_t * mp)
20402 {
20403   vat_main_t *vam = &vat_main;
20404   vat_json_node_t *node = NULL;
20405
20406   if (VAT_JSON_ARRAY != vam->json_tree.type)
20407     {
20408       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20409       vat_json_init_array (&vam->json_tree);
20410     }
20411   node = vat_json_array_add (&vam->json_tree);
20412
20413   vat_json_init_object (node);
20414   vat_json_object_add_uint (node, "rx_sw_if_index",
20415                             ntohl (mp->rx_sw_if_index));
20416   vat_json_object_add_uint (node, "tx_sw_if_index",
20417                             ntohl (mp->tx_sw_if_index));
20418 }
20419
20420 static int
20421 api_l2_xconnect_dump (vat_main_t * vam)
20422 {
20423   vl_api_l2_xconnect_dump_t *mp;
20424   vl_api_control_ping_t *mp_ping;
20425   int ret;
20426
20427   if (!vam->json_output)
20428     {
20429       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20430     }
20431
20432   M (L2_XCONNECT_DUMP, mp);
20433
20434   S (mp);
20435
20436   /* Use a control ping for synchronization */
20437   MPING (CONTROL_PING, mp_ping);
20438   S (mp_ping);
20439
20440   W (ret);
20441   return ret;
20442 }
20443
20444 static int
20445 api_hw_interface_set_mtu (vat_main_t * vam)
20446 {
20447   unformat_input_t *i = vam->input;
20448   vl_api_hw_interface_set_mtu_t *mp;
20449   u32 sw_if_index = ~0;
20450   u32 mtu = 0;
20451   int ret;
20452
20453   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20454     {
20455       if (unformat (i, "mtu %d", &mtu))
20456         ;
20457       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20458         ;
20459       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20460         ;
20461       else
20462         break;
20463     }
20464
20465   if (sw_if_index == ~0)
20466     {
20467       errmsg ("missing interface name or sw_if_index");
20468       return -99;
20469     }
20470
20471   if (mtu == 0)
20472     {
20473       errmsg ("no mtu specified");
20474       return -99;
20475     }
20476
20477   /* Construct the API message */
20478   M (HW_INTERFACE_SET_MTU, mp);
20479   mp->sw_if_index = ntohl (sw_if_index);
20480   mp->mtu = ntohs ((u16) mtu);
20481
20482   S (mp);
20483   W (ret);
20484   return ret;
20485 }
20486
20487 static int
20488 api_p2p_ethernet_add (vat_main_t * vam)
20489 {
20490   unformat_input_t *i = vam->input;
20491   vl_api_p2p_ethernet_add_t *mp;
20492   u32 parent_if_index = ~0;
20493   u32 sub_id = ~0;
20494   u8 remote_mac[6];
20495   u8 mac_set = 0;
20496   int ret;
20497
20498   clib_memset (remote_mac, 0, sizeof (remote_mac));
20499   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20500     {
20501       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20502         ;
20503       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20504         ;
20505       else
20506         if (unformat
20507             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20508         mac_set++;
20509       else if (unformat (i, "sub_id %d", &sub_id))
20510         ;
20511       else
20512         {
20513           clib_warning ("parse error '%U'", format_unformat_error, i);
20514           return -99;
20515         }
20516     }
20517
20518   if (parent_if_index == ~0)
20519     {
20520       errmsg ("missing interface name or sw_if_index");
20521       return -99;
20522     }
20523   if (mac_set == 0)
20524     {
20525       errmsg ("missing remote mac address");
20526       return -99;
20527     }
20528   if (sub_id == ~0)
20529     {
20530       errmsg ("missing sub-interface id");
20531       return -99;
20532     }
20533
20534   M (P2P_ETHERNET_ADD, mp);
20535   mp->parent_if_index = ntohl (parent_if_index);
20536   mp->subif_id = ntohl (sub_id);
20537   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20538
20539   S (mp);
20540   W (ret);
20541   return ret;
20542 }
20543
20544 static int
20545 api_p2p_ethernet_del (vat_main_t * vam)
20546 {
20547   unformat_input_t *i = vam->input;
20548   vl_api_p2p_ethernet_del_t *mp;
20549   u32 parent_if_index = ~0;
20550   u8 remote_mac[6];
20551   u8 mac_set = 0;
20552   int ret;
20553
20554   clib_memset (remote_mac, 0, sizeof (remote_mac));
20555   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20556     {
20557       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20558         ;
20559       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20560         ;
20561       else
20562         if (unformat
20563             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20564         mac_set++;
20565       else
20566         {
20567           clib_warning ("parse error '%U'", format_unformat_error, i);
20568           return -99;
20569         }
20570     }
20571
20572   if (parent_if_index == ~0)
20573     {
20574       errmsg ("missing interface name or sw_if_index");
20575       return -99;
20576     }
20577   if (mac_set == 0)
20578     {
20579       errmsg ("missing remote mac address");
20580       return -99;
20581     }
20582
20583   M (P2P_ETHERNET_DEL, mp);
20584   mp->parent_if_index = ntohl (parent_if_index);
20585   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20586
20587   S (mp);
20588   W (ret);
20589   return ret;
20590 }
20591
20592 static int
20593 api_lldp_config (vat_main_t * vam)
20594 {
20595   unformat_input_t *i = vam->input;
20596   vl_api_lldp_config_t *mp;
20597   int tx_hold = 0;
20598   int tx_interval = 0;
20599   u8 *sys_name = NULL;
20600   int ret;
20601
20602   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20603     {
20604       if (unformat (i, "system-name %s", &sys_name))
20605         ;
20606       else if (unformat (i, "tx-hold %d", &tx_hold))
20607         ;
20608       else if (unformat (i, "tx-interval %d", &tx_interval))
20609         ;
20610       else
20611         {
20612           clib_warning ("parse error '%U'", format_unformat_error, i);
20613           return -99;
20614         }
20615     }
20616
20617   vec_add1 (sys_name, 0);
20618
20619   M (LLDP_CONFIG, mp);
20620   mp->tx_hold = htonl (tx_hold);
20621   mp->tx_interval = htonl (tx_interval);
20622   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
20623   vec_free (sys_name);
20624
20625   S (mp);
20626   W (ret);
20627   return ret;
20628 }
20629
20630 static int
20631 api_sw_interface_set_lldp (vat_main_t * vam)
20632 {
20633   unformat_input_t *i = vam->input;
20634   vl_api_sw_interface_set_lldp_t *mp;
20635   u32 sw_if_index = ~0;
20636   u32 enable = 1;
20637   u8 *port_desc = NULL, *mgmt_oid = NULL;
20638   ip4_address_t ip4_addr;
20639   ip6_address_t ip6_addr;
20640   int ret;
20641
20642   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
20643   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
20644
20645   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20646     {
20647       if (unformat (i, "disable"))
20648         enable = 0;
20649       else
20650         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20651         ;
20652       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20653         ;
20654       else if (unformat (i, "port-desc %s", &port_desc))
20655         ;
20656       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
20657         ;
20658       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
20659         ;
20660       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
20661         ;
20662       else
20663         break;
20664     }
20665
20666   if (sw_if_index == ~0)
20667     {
20668       errmsg ("missing interface name or sw_if_index");
20669       return -99;
20670     }
20671
20672   /* Construct the API message */
20673   vec_add1 (port_desc, 0);
20674   vec_add1 (mgmt_oid, 0);
20675   M (SW_INTERFACE_SET_LLDP, mp);
20676   mp->sw_if_index = ntohl (sw_if_index);
20677   mp->enable = enable;
20678   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
20679   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
20680   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
20681   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
20682   vec_free (port_desc);
20683   vec_free (mgmt_oid);
20684
20685   S (mp);
20686   W (ret);
20687   return ret;
20688 }
20689
20690 static int
20691 api_tcp_configure_src_addresses (vat_main_t * vam)
20692 {
20693   vl_api_tcp_configure_src_addresses_t *mp;
20694   unformat_input_t *i = vam->input;
20695   ip4_address_t v4first, v4last;
20696   ip6_address_t v6first, v6last;
20697   u8 range_set = 0;
20698   u32 vrf_id = 0;
20699   int ret;
20700
20701   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20702     {
20703       if (unformat (i, "%U - %U",
20704                     unformat_ip4_address, &v4first,
20705                     unformat_ip4_address, &v4last))
20706         {
20707           if (range_set)
20708             {
20709               errmsg ("one range per message (range already set)");
20710               return -99;
20711             }
20712           range_set = 1;
20713         }
20714       else if (unformat (i, "%U - %U",
20715                          unformat_ip6_address, &v6first,
20716                          unformat_ip6_address, &v6last))
20717         {
20718           if (range_set)
20719             {
20720               errmsg ("one range per message (range already set)");
20721               return -99;
20722             }
20723           range_set = 2;
20724         }
20725       else if (unformat (i, "vrf %d", &vrf_id))
20726         ;
20727       else
20728         break;
20729     }
20730
20731   if (range_set == 0)
20732     {
20733       errmsg ("address range not set");
20734       return -99;
20735     }
20736
20737   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
20738   mp->vrf_id = ntohl (vrf_id);
20739   /* ipv6? */
20740   if (range_set == 2)
20741     {
20742       mp->is_ipv6 = 1;
20743       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
20744       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
20745     }
20746   else
20747     {
20748       mp->is_ipv6 = 0;
20749       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
20750       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
20751     }
20752   S (mp);
20753   W (ret);
20754   return ret;
20755 }
20756
20757 static void vl_api_app_namespace_add_del_reply_t_handler
20758   (vl_api_app_namespace_add_del_reply_t * mp)
20759 {
20760   vat_main_t *vam = &vat_main;
20761   i32 retval = ntohl (mp->retval);
20762   if (vam->async_mode)
20763     {
20764       vam->async_errors += (retval < 0);
20765     }
20766   else
20767     {
20768       vam->retval = retval;
20769       if (retval == 0)
20770         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
20771       vam->result_ready = 1;
20772     }
20773 }
20774
20775 static void vl_api_app_namespace_add_del_reply_t_handler_json
20776   (vl_api_app_namespace_add_del_reply_t * mp)
20777 {
20778   vat_main_t *vam = &vat_main;
20779   vat_json_node_t node;
20780
20781   vat_json_init_object (&node);
20782   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
20783   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
20784
20785   vat_json_print (vam->ofp, &node);
20786   vat_json_free (&node);
20787
20788   vam->retval = ntohl (mp->retval);
20789   vam->result_ready = 1;
20790 }
20791
20792 static int
20793 api_app_namespace_add_del (vat_main_t * vam)
20794 {
20795   vl_api_app_namespace_add_del_t *mp;
20796   unformat_input_t *i = vam->input;
20797   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
20798   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
20799   u64 secret;
20800   int ret;
20801
20802   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20803     {
20804       if (unformat (i, "id %_%v%_", &ns_id))
20805         ;
20806       else if (unformat (i, "secret %lu", &secret))
20807         secret_set = 1;
20808       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20809         sw_if_index_set = 1;
20810       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
20811         ;
20812       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
20813         ;
20814       else
20815         break;
20816     }
20817   if (!ns_id || !secret_set || !sw_if_index_set)
20818     {
20819       errmsg ("namespace id, secret and sw_if_index must be set");
20820       return -99;
20821     }
20822   if (vec_len (ns_id) > 64)
20823     {
20824       errmsg ("namespace id too long");
20825       return -99;
20826     }
20827   M (APP_NAMESPACE_ADD_DEL, mp);
20828
20829   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
20830   mp->namespace_id_len = vec_len (ns_id);
20831   mp->secret = clib_host_to_net_u64 (secret);
20832   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20833   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
20834   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
20835   vec_free (ns_id);
20836   S (mp);
20837   W (ret);
20838   return ret;
20839 }
20840
20841 static int
20842 api_sock_init_shm (vat_main_t * vam)
20843 {
20844 #if VPP_API_TEST_BUILTIN == 0
20845   unformat_input_t *i = vam->input;
20846   vl_api_shm_elem_config_t *config = 0;
20847   u64 size = 64 << 20;
20848   int rv;
20849
20850   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20851     {
20852       if (unformat (i, "size %U", unformat_memory_size, &size))
20853         ;
20854       else
20855         break;
20856     }
20857
20858   /*
20859    * Canned custom ring allocator config.
20860    * Should probably parse all of this
20861    */
20862   vec_validate (config, 6);
20863   config[0].type = VL_API_VLIB_RING;
20864   config[0].size = 256;
20865   config[0].count = 32;
20866
20867   config[1].type = VL_API_VLIB_RING;
20868   config[1].size = 1024;
20869   config[1].count = 16;
20870
20871   config[2].type = VL_API_VLIB_RING;
20872   config[2].size = 4096;
20873   config[2].count = 2;
20874
20875   config[3].type = VL_API_CLIENT_RING;
20876   config[3].size = 256;
20877   config[3].count = 32;
20878
20879   config[4].type = VL_API_CLIENT_RING;
20880   config[4].size = 1024;
20881   config[4].count = 16;
20882
20883   config[5].type = VL_API_CLIENT_RING;
20884   config[5].size = 4096;
20885   config[5].count = 2;
20886
20887   config[6].type = VL_API_QUEUE;
20888   config[6].count = 128;
20889   config[6].size = sizeof (uword);
20890
20891   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
20892   if (!rv)
20893     vam->client_index_invalid = 1;
20894   return rv;
20895 #else
20896   return -99;
20897 #endif
20898 }
20899
20900 static void
20901 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
20902 {
20903   vat_main_t *vam = &vat_main;
20904
20905   if (mp->is_ip4)
20906     {
20907       print (vam->ofp,
20908              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
20909              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
20910              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
20911              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
20912              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
20913              clib_net_to_host_u32 (mp->action_index), mp->tag);
20914     }
20915   else
20916     {
20917       print (vam->ofp,
20918              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
20919              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
20920              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
20921              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
20922              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
20923              clib_net_to_host_u32 (mp->action_index), mp->tag);
20924     }
20925 }
20926
20927 static void
20928 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
20929                                              mp)
20930 {
20931   vat_main_t *vam = &vat_main;
20932   vat_json_node_t *node = NULL;
20933   struct in6_addr ip6;
20934   struct in_addr ip4;
20935
20936   if (VAT_JSON_ARRAY != vam->json_tree.type)
20937     {
20938       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20939       vat_json_init_array (&vam->json_tree);
20940     }
20941   node = vat_json_array_add (&vam->json_tree);
20942   vat_json_init_object (node);
20943
20944   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
20945   vat_json_object_add_uint (node, "appns_index",
20946                             clib_net_to_host_u32 (mp->appns_index));
20947   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
20948   vat_json_object_add_uint (node, "scope", mp->scope);
20949   vat_json_object_add_uint (node, "action_index",
20950                             clib_net_to_host_u32 (mp->action_index));
20951   vat_json_object_add_uint (node, "lcl_port",
20952                             clib_net_to_host_u16 (mp->lcl_port));
20953   vat_json_object_add_uint (node, "rmt_port",
20954                             clib_net_to_host_u16 (mp->rmt_port));
20955   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
20956   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
20957   vat_json_object_add_string_copy (node, "tag", mp->tag);
20958   if (mp->is_ip4)
20959     {
20960       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
20961       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
20962       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
20963       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
20964     }
20965   else
20966     {
20967       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
20968       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
20969       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
20970       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
20971     }
20972 }
20973
20974 static int
20975 api_session_rule_add_del (vat_main_t * vam)
20976 {
20977   vl_api_session_rule_add_del_t *mp;
20978   unformat_input_t *i = vam->input;
20979   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
20980   u32 appns_index = 0, scope = 0;
20981   ip4_address_t lcl_ip4, rmt_ip4;
20982   ip6_address_t lcl_ip6, rmt_ip6;
20983   u8 is_ip4 = 1, conn_set = 0;
20984   u8 is_add = 1, *tag = 0;
20985   int ret;
20986
20987   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20988     {
20989       if (unformat (i, "del"))
20990         is_add = 0;
20991       else if (unformat (i, "add"))
20992         ;
20993       else if (unformat (i, "proto tcp"))
20994         proto = 0;
20995       else if (unformat (i, "proto udp"))
20996         proto = 1;
20997       else if (unformat (i, "appns %d", &appns_index))
20998         ;
20999       else if (unformat (i, "scope %d", &scope))
21000         ;
21001       else if (unformat (i, "tag %_%v%_", &tag))
21002         ;
21003       else
21004         if (unformat
21005             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
21006              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
21007              &rmt_port))
21008         {
21009           is_ip4 = 1;
21010           conn_set = 1;
21011         }
21012       else
21013         if (unformat
21014             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
21015              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
21016              &rmt_port))
21017         {
21018           is_ip4 = 0;
21019           conn_set = 1;
21020         }
21021       else if (unformat (i, "action %d", &action))
21022         ;
21023       else
21024         break;
21025     }
21026   if (proto == ~0 || !conn_set || action == ~0)
21027     {
21028       errmsg ("transport proto, connection and action must be set");
21029       return -99;
21030     }
21031
21032   if (scope > 3)
21033     {
21034       errmsg ("scope should be 0-3");
21035       return -99;
21036     }
21037
21038   M (SESSION_RULE_ADD_DEL, mp);
21039
21040   mp->is_ip4 = is_ip4;
21041   mp->transport_proto = proto;
21042   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
21043   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
21044   mp->lcl_plen = lcl_plen;
21045   mp->rmt_plen = rmt_plen;
21046   mp->action_index = clib_host_to_net_u32 (action);
21047   mp->appns_index = clib_host_to_net_u32 (appns_index);
21048   mp->scope = scope;
21049   mp->is_add = is_add;
21050   if (is_ip4)
21051     {
21052       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
21053       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
21054     }
21055   else
21056     {
21057       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
21058       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
21059     }
21060   if (tag)
21061     {
21062       clib_memcpy (mp->tag, tag, vec_len (tag));
21063       vec_free (tag);
21064     }
21065
21066   S (mp);
21067   W (ret);
21068   return ret;
21069 }
21070
21071 static int
21072 api_session_rules_dump (vat_main_t * vam)
21073 {
21074   vl_api_session_rules_dump_t *mp;
21075   vl_api_control_ping_t *mp_ping;
21076   int ret;
21077
21078   if (!vam->json_output)
21079     {
21080       print (vam->ofp, "%=20s", "Session Rules");
21081     }
21082
21083   M (SESSION_RULES_DUMP, mp);
21084   /* send it... */
21085   S (mp);
21086
21087   /* Use a control ping for synchronization */
21088   MPING (CONTROL_PING, mp_ping);
21089   S (mp_ping);
21090
21091   /* Wait for a reply... */
21092   W (ret);
21093   return ret;
21094 }
21095
21096 static int
21097 api_ip_container_proxy_add_del (vat_main_t * vam)
21098 {
21099   vl_api_ip_container_proxy_add_del_t *mp;
21100   unformat_input_t *i = vam->input;
21101   u32 sw_if_index = ~0;
21102   vl_api_prefix_t pfx = { };
21103   u8 is_add = 1;
21104   int ret;
21105
21106   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21107     {
21108       if (unformat (i, "del"))
21109         is_add = 0;
21110       else if (unformat (i, "add"))
21111         ;
21112       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
21113         ;
21114       else if (unformat (i, "sw_if_index %u", &sw_if_index))
21115         ;
21116       else
21117         break;
21118     }
21119   if (sw_if_index == ~0 || pfx.len == 0)
21120     {
21121       errmsg ("address and sw_if_index must be set");
21122       return -99;
21123     }
21124
21125   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
21126
21127   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21128   mp->is_add = is_add;
21129   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
21130
21131   S (mp);
21132   W (ret);
21133   return ret;
21134 }
21135
21136 static int
21137 api_qos_record_enable_disable (vat_main_t * vam)
21138 {
21139   unformat_input_t *i = vam->input;
21140   vl_api_qos_record_enable_disable_t *mp;
21141   u32 sw_if_index, qs = 0xff;
21142   u8 sw_if_index_set = 0;
21143   u8 enable = 1;
21144   int ret;
21145
21146   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21147     {
21148       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21149         sw_if_index_set = 1;
21150       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21151         sw_if_index_set = 1;
21152       else if (unformat (i, "%U", unformat_qos_source, &qs))
21153         ;
21154       else if (unformat (i, "disable"))
21155         enable = 0;
21156       else
21157         {
21158           clib_warning ("parse error '%U'", format_unformat_error, i);
21159           return -99;
21160         }
21161     }
21162
21163   if (sw_if_index_set == 0)
21164     {
21165       errmsg ("missing interface name or sw_if_index");
21166       return -99;
21167     }
21168   if (qs == 0xff)
21169     {
21170       errmsg ("input location must be specified");
21171       return -99;
21172     }
21173
21174   M (QOS_RECORD_ENABLE_DISABLE, mp);
21175
21176   mp->record.sw_if_index = ntohl (sw_if_index);
21177   mp->record.input_source = qs;
21178   mp->enable = enable;
21179
21180   S (mp);
21181   W (ret);
21182   return ret;
21183 }
21184
21185
21186 static int
21187 q_or_quit (vat_main_t * vam)
21188 {
21189 #if VPP_API_TEST_BUILTIN == 0
21190   longjmp (vam->jump_buf, 1);
21191 #endif
21192   return 0;                     /* not so much */
21193 }
21194
21195 static int
21196 q (vat_main_t * vam)
21197 {
21198   return q_or_quit (vam);
21199 }
21200
21201 static int
21202 quit (vat_main_t * vam)
21203 {
21204   return q_or_quit (vam);
21205 }
21206
21207 static int
21208 comment (vat_main_t * vam)
21209 {
21210   return 0;
21211 }
21212
21213 static int
21214 elog_save (vat_main_t * vam)
21215 {
21216 #if VPP_API_TEST_BUILTIN == 0
21217   elog_main_t *em = &vam->elog_main;
21218   unformat_input_t *i = vam->input;
21219   char *file, *chroot_file;
21220   clib_error_t *error;
21221
21222   if (!unformat (i, "%s", &file))
21223     {
21224       errmsg ("expected file name, got `%U'", format_unformat_error, i);
21225       return 0;
21226     }
21227
21228   /* It's fairly hard to get "../oopsie" through unformat; just in case */
21229   if (strstr (file, "..") || index (file, '/'))
21230     {
21231       errmsg ("illegal characters in filename '%s'", file);
21232       return 0;
21233     }
21234
21235   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
21236
21237   vec_free (file);
21238
21239   errmsg ("Saving %wd of %wd events to %s",
21240           elog_n_events_in_buffer (em),
21241           elog_buffer_capacity (em), chroot_file);
21242
21243   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
21244   vec_free (chroot_file);
21245
21246   if (error)
21247     clib_error_report (error);
21248 #else
21249   errmsg ("Use the vpp event loger...");
21250 #endif
21251
21252   return 0;
21253 }
21254
21255 static int
21256 elog_setup (vat_main_t * vam)
21257 {
21258 #if VPP_API_TEST_BUILTIN == 0
21259   elog_main_t *em = &vam->elog_main;
21260   unformat_input_t *i = vam->input;
21261   u32 nevents = 128 << 10;
21262
21263   (void) unformat (i, "nevents %d", &nevents);
21264
21265   elog_init (em, nevents);
21266   vl_api_set_elog_main (em);
21267   vl_api_set_elog_trace_api_messages (1);
21268   errmsg ("Event logger initialized with %u events", nevents);
21269 #else
21270   errmsg ("Use the vpp event loger...");
21271 #endif
21272   return 0;
21273 }
21274
21275 static int
21276 elog_enable (vat_main_t * vam)
21277 {
21278 #if VPP_API_TEST_BUILTIN == 0
21279   elog_main_t *em = &vam->elog_main;
21280
21281   elog_enable_disable (em, 1 /* enable */ );
21282   vl_api_set_elog_trace_api_messages (1);
21283   errmsg ("Event logger enabled...");
21284 #else
21285   errmsg ("Use the vpp event loger...");
21286 #endif
21287   return 0;
21288 }
21289
21290 static int
21291 elog_disable (vat_main_t * vam)
21292 {
21293 #if VPP_API_TEST_BUILTIN == 0
21294   elog_main_t *em = &vam->elog_main;
21295
21296   elog_enable_disable (em, 0 /* enable */ );
21297   vl_api_set_elog_trace_api_messages (1);
21298   errmsg ("Event logger disabled...");
21299 #else
21300   errmsg ("Use the vpp event loger...");
21301 #endif
21302   return 0;
21303 }
21304
21305 static int
21306 statseg (vat_main_t * vam)
21307 {
21308   ssvm_private_t *ssvmp = &vam->stat_segment;
21309   ssvm_shared_header_t *shared_header = ssvmp->sh;
21310   vlib_counter_t **counters;
21311   u64 thread0_index1_packets;
21312   u64 thread0_index1_bytes;
21313   f64 vector_rate, input_rate;
21314   uword *p;
21315
21316   uword *counter_vector_by_name;
21317   if (vam->stat_segment_lockp == 0)
21318     {
21319       errmsg ("Stat segment not mapped...");
21320       return -99;
21321     }
21322
21323   /* look up "/if/rx for sw_if_index 1 as a test */
21324
21325   clib_spinlock_lock (vam->stat_segment_lockp);
21326
21327   counter_vector_by_name = (uword *) shared_header->opaque[1];
21328
21329   p = hash_get_mem (counter_vector_by_name, "/if/rx");
21330   if (p == 0)
21331     {
21332       clib_spinlock_unlock (vam->stat_segment_lockp);
21333       errmsg ("/if/tx not found?");
21334       return -99;
21335     }
21336
21337   /* Fish per-thread vector of combined counters from shared memory */
21338   counters = (vlib_counter_t **) p[0];
21339
21340   if (vec_len (counters[0]) < 2)
21341     {
21342       clib_spinlock_unlock (vam->stat_segment_lockp);
21343       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
21344       return -99;
21345     }
21346
21347   /* Read thread 0 sw_if_index 1 counter */
21348   thread0_index1_packets = counters[0][1].packets;
21349   thread0_index1_bytes = counters[0][1].bytes;
21350
21351   p = hash_get_mem (counter_vector_by_name, "vector_rate");
21352   if (p == 0)
21353     {
21354       clib_spinlock_unlock (vam->stat_segment_lockp);
21355       errmsg ("vector_rate not found?");
21356       return -99;
21357     }
21358
21359   vector_rate = *(f64 *) (p[0]);
21360   p = hash_get_mem (counter_vector_by_name, "input_rate");
21361   if (p == 0)
21362     {
21363       clib_spinlock_unlock (vam->stat_segment_lockp);
21364       errmsg ("input_rate not found?");
21365       return -99;
21366     }
21367   input_rate = *(f64 *) (p[0]);
21368
21369   clib_spinlock_unlock (vam->stat_segment_lockp);
21370
21371   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
21372          vector_rate, input_rate);
21373   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
21374          thread0_index1_packets, thread0_index1_bytes);
21375
21376   return 0;
21377 }
21378
21379 static int
21380 cmd_cmp (void *a1, void *a2)
21381 {
21382   u8 **c1 = a1;
21383   u8 **c2 = a2;
21384
21385   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21386 }
21387
21388 static int
21389 help (vat_main_t * vam)
21390 {
21391   u8 **cmds = 0;
21392   u8 *name = 0;
21393   hash_pair_t *p;
21394   unformat_input_t *i = vam->input;
21395   int j;
21396
21397   if (unformat (i, "%s", &name))
21398     {
21399       uword *hs;
21400
21401       vec_add1 (name, 0);
21402
21403       hs = hash_get_mem (vam->help_by_name, name);
21404       if (hs)
21405         print (vam->ofp, "usage: %s %s", name, hs[0]);
21406       else
21407         print (vam->ofp, "No such msg / command '%s'", name);
21408       vec_free (name);
21409       return 0;
21410     }
21411
21412   print (vam->ofp, "Help is available for the following:");
21413
21414     /* *INDENT-OFF* */
21415     hash_foreach_pair (p, vam->function_by_name,
21416     ({
21417       vec_add1 (cmds, (u8 *)(p->key));
21418     }));
21419     /* *INDENT-ON* */
21420
21421   vec_sort_with_function (cmds, cmd_cmp);
21422
21423   for (j = 0; j < vec_len (cmds); j++)
21424     print (vam->ofp, "%s", cmds[j]);
21425
21426   vec_free (cmds);
21427   return 0;
21428 }
21429
21430 static int
21431 set (vat_main_t * vam)
21432 {
21433   u8 *name = 0, *value = 0;
21434   unformat_input_t *i = vam->input;
21435
21436   if (unformat (i, "%s", &name))
21437     {
21438       /* The input buffer is a vector, not a string. */
21439       value = vec_dup (i->buffer);
21440       vec_delete (value, i->index, 0);
21441       /* Almost certainly has a trailing newline */
21442       if (value[vec_len (value) - 1] == '\n')
21443         value[vec_len (value) - 1] = 0;
21444       /* Make sure it's a proper string, one way or the other */
21445       vec_add1 (value, 0);
21446       (void) clib_macro_set_value (&vam->macro_main,
21447                                    (char *) name, (char *) value);
21448     }
21449   else
21450     errmsg ("usage: set <name> <value>");
21451
21452   vec_free (name);
21453   vec_free (value);
21454   return 0;
21455 }
21456
21457 static int
21458 unset (vat_main_t * vam)
21459 {
21460   u8 *name = 0;
21461
21462   if (unformat (vam->input, "%s", &name))
21463     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
21464       errmsg ("unset: %s wasn't set", name);
21465   vec_free (name);
21466   return 0;
21467 }
21468
21469 typedef struct
21470 {
21471   u8 *name;
21472   u8 *value;
21473 } macro_sort_t;
21474
21475
21476 static int
21477 macro_sort_cmp (void *a1, void *a2)
21478 {
21479   macro_sort_t *s1 = a1;
21480   macro_sort_t *s2 = a2;
21481
21482   return strcmp ((char *) (s1->name), (char *) (s2->name));
21483 }
21484
21485 static int
21486 dump_macro_table (vat_main_t * vam)
21487 {
21488   macro_sort_t *sort_me = 0, *sm;
21489   int i;
21490   hash_pair_t *p;
21491
21492     /* *INDENT-OFF* */
21493     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
21494     ({
21495       vec_add2 (sort_me, sm, 1);
21496       sm->name = (u8 *)(p->key);
21497       sm->value = (u8 *) (p->value[0]);
21498     }));
21499     /* *INDENT-ON* */
21500
21501   vec_sort_with_function (sort_me, macro_sort_cmp);
21502
21503   if (vec_len (sort_me))
21504     print (vam->ofp, "%-15s%s", "Name", "Value");
21505   else
21506     print (vam->ofp, "The macro table is empty...");
21507
21508   for (i = 0; i < vec_len (sort_me); i++)
21509     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
21510   return 0;
21511 }
21512
21513 static int
21514 dump_node_table (vat_main_t * vam)
21515 {
21516   int i, j;
21517   vlib_node_t *node, *next_node;
21518
21519   if (vec_len (vam->graph_nodes) == 0)
21520     {
21521       print (vam->ofp, "Node table empty, issue get_node_graph...");
21522       return 0;
21523     }
21524
21525   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
21526     {
21527       node = vam->graph_nodes[0][i];
21528       print (vam->ofp, "[%d] %s", i, node->name);
21529       for (j = 0; j < vec_len (node->next_nodes); j++)
21530         {
21531           if (node->next_nodes[j] != ~0)
21532             {
21533               next_node = vam->graph_nodes[0][node->next_nodes[j]];
21534               print (vam->ofp, "  [%d] %s", j, next_node->name);
21535             }
21536         }
21537     }
21538   return 0;
21539 }
21540
21541 static int
21542 value_sort_cmp (void *a1, void *a2)
21543 {
21544   name_sort_t *n1 = a1;
21545   name_sort_t *n2 = a2;
21546
21547   if (n1->value < n2->value)
21548     return -1;
21549   if (n1->value > n2->value)
21550     return 1;
21551   return 0;
21552 }
21553
21554
21555 static int
21556 dump_msg_api_table (vat_main_t * vam)
21557 {
21558   api_main_t *am = &api_main;
21559   name_sort_t *nses = 0, *ns;
21560   hash_pair_t *hp;
21561   int i;
21562
21563   /* *INDENT-OFF* */
21564   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
21565   ({
21566     vec_add2 (nses, ns, 1);
21567     ns->name = (u8 *)(hp->key);
21568     ns->value = (u32) hp->value[0];
21569   }));
21570   /* *INDENT-ON* */
21571
21572   vec_sort_with_function (nses, value_sort_cmp);
21573
21574   for (i = 0; i < vec_len (nses); i++)
21575     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
21576   vec_free (nses);
21577   return 0;
21578 }
21579
21580 static int
21581 get_msg_id (vat_main_t * vam)
21582 {
21583   u8 *name_and_crc;
21584   u32 message_index;
21585
21586   if (unformat (vam->input, "%s", &name_and_crc))
21587     {
21588       message_index = vl_msg_api_get_msg_index (name_and_crc);
21589       if (message_index == ~0)
21590         {
21591           print (vam->ofp, " '%s' not found", name_and_crc);
21592           return 0;
21593         }
21594       print (vam->ofp, " '%s' has message index %d",
21595              name_and_crc, message_index);
21596       return 0;
21597     }
21598   errmsg ("name_and_crc required...");
21599   return 0;
21600 }
21601
21602 static int
21603 search_node_table (vat_main_t * vam)
21604 {
21605   unformat_input_t *line_input = vam->input;
21606   u8 *node_to_find;
21607   int j;
21608   vlib_node_t *node, *next_node;
21609   uword *p;
21610
21611   if (vam->graph_node_index_by_name == 0)
21612     {
21613       print (vam->ofp, "Node table empty, issue get_node_graph...");
21614       return 0;
21615     }
21616
21617   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21618     {
21619       if (unformat (line_input, "%s", &node_to_find))
21620         {
21621           vec_add1 (node_to_find, 0);
21622           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
21623           if (p == 0)
21624             {
21625               print (vam->ofp, "%s not found...", node_to_find);
21626               goto out;
21627             }
21628           node = vam->graph_nodes[0][p[0]];
21629           print (vam->ofp, "[%d] %s", p[0], node->name);
21630           for (j = 0; j < vec_len (node->next_nodes); j++)
21631             {
21632               if (node->next_nodes[j] != ~0)
21633                 {
21634                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
21635                   print (vam->ofp, "  [%d] %s", j, next_node->name);
21636                 }
21637             }
21638         }
21639
21640       else
21641         {
21642           clib_warning ("parse error '%U'", format_unformat_error,
21643                         line_input);
21644           return -99;
21645         }
21646
21647     out:
21648       vec_free (node_to_find);
21649
21650     }
21651
21652   return 0;
21653 }
21654
21655
21656 static int
21657 script (vat_main_t * vam)
21658 {
21659 #if (VPP_API_TEST_BUILTIN==0)
21660   u8 *s = 0;
21661   char *save_current_file;
21662   unformat_input_t save_input;
21663   jmp_buf save_jump_buf;
21664   u32 save_line_number;
21665
21666   FILE *new_fp, *save_ifp;
21667
21668   if (unformat (vam->input, "%s", &s))
21669     {
21670       new_fp = fopen ((char *) s, "r");
21671       if (new_fp == 0)
21672         {
21673           errmsg ("Couldn't open script file %s", s);
21674           vec_free (s);
21675           return -99;
21676         }
21677     }
21678   else
21679     {
21680       errmsg ("Missing script name");
21681       return -99;
21682     }
21683
21684   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
21685   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
21686   save_ifp = vam->ifp;
21687   save_line_number = vam->input_line_number;
21688   save_current_file = (char *) vam->current_file;
21689
21690   vam->input_line_number = 0;
21691   vam->ifp = new_fp;
21692   vam->current_file = s;
21693   do_one_file (vam);
21694
21695   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
21696   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
21697   vam->ifp = save_ifp;
21698   vam->input_line_number = save_line_number;
21699   vam->current_file = (u8 *) save_current_file;
21700   vec_free (s);
21701
21702   return 0;
21703 #else
21704   clib_warning ("use the exec command...");
21705   return -99;
21706 #endif
21707 }
21708
21709 static int
21710 echo (vat_main_t * vam)
21711 {
21712   print (vam->ofp, "%v", vam->input->buffer);
21713   return 0;
21714 }
21715
21716 /* List of API message constructors, CLI names map to api_xxx */
21717 #define foreach_vpe_api_msg                                             \
21718 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
21719 _(sw_interface_dump,"")                                                 \
21720 _(sw_interface_set_flags,                                               \
21721   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
21722 _(sw_interface_add_del_address,                                         \
21723   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
21724 _(sw_interface_set_rx_mode,                                             \
21725   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
21726 _(sw_interface_set_rx_placement,                                        \
21727   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
21728 _(sw_interface_rx_placement_dump,                                       \
21729   "[<intfc> | sw_if_index <id>]")                                         \
21730 _(sw_interface_set_table,                                               \
21731   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
21732 _(sw_interface_set_mpls_enable,                                         \
21733   "<intfc> | sw_if_index [disable | dis]")                              \
21734 _(sw_interface_set_vpath,                                               \
21735   "<intfc> | sw_if_index <id> enable | disable")                        \
21736 _(sw_interface_set_vxlan_bypass,                                        \
21737   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21738 _(sw_interface_set_geneve_bypass,                                       \
21739   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21740 _(sw_interface_set_l2_xconnect,                                         \
21741   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21742   "enable | disable")                                                   \
21743 _(sw_interface_set_l2_bridge,                                           \
21744   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
21745   "[shg <split-horizon-group>] [bvi]\n"                                 \
21746   "enable | disable")                                                   \
21747 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
21748 _(bridge_domain_add_del,                                                \
21749   "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") \
21750 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
21751 _(l2fib_add_del,                                                        \
21752   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
21753 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
21754 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
21755 _(l2_flags,                                                             \
21756   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21757 _(bridge_flags,                                                         \
21758   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21759 _(tap_create_v2,                                                        \
21760   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>] [host-mtu-size <mtu>] [gso | no-gso]") \
21761 _(tap_delete_v2,                                                        \
21762   "<vpp-if-name> | sw_if_index <id>")                                   \
21763 _(sw_interface_tap_v2_dump, "")                                         \
21764 _(virtio_pci_create,                                                    \
21765   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled]") \
21766 _(virtio_pci_delete,                                                    \
21767   "<vpp-if-name> | sw_if_index <id>")                                   \
21768 _(sw_interface_virtio_pci_dump, "")                                     \
21769 _(bond_create,                                                          \
21770   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
21771   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
21772   "[id <if-id>]")                                                       \
21773 _(bond_delete,                                                          \
21774   "<vpp-if-name> | sw_if_index <id>")                                   \
21775 _(bond_enslave,                                                         \
21776   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
21777 _(bond_detach_slave,                                                    \
21778   "sw_if_index <n>")                                                    \
21779  _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
21780 _(sw_interface_bond_dump, "")                                           \
21781 _(sw_interface_slave_dump,                                              \
21782   "<vpp-if-name> | sw_if_index <id>")                                   \
21783 _(ip_table_add_del,                                                     \
21784   "table <n> [ipv6] [add | del]\n")                                     \
21785 _(ip_route_add_del,                                                     \
21786   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
21787   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
21788   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
21789   "[multipath] [count <n>] [del]")                                      \
21790 _(ip_mroute_add_del,                                                    \
21791   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
21792   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
21793 _(mpls_table_add_del,                                                   \
21794   "table <n> [add | del]\n")                                            \
21795 _(mpls_route_add_del,                                                   \
21796   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
21797   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
21798   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
21799   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
21800   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
21801   "[count <n>] [del]")                                                  \
21802 _(mpls_ip_bind_unbind,                                                  \
21803   "<label> <addr/len>")                                                 \
21804 _(mpls_tunnel_add_del,                                                  \
21805   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
21806   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
21807   "[l2-only]  [out-label <n>]")                                         \
21808 _(sr_mpls_policy_add,                                                   \
21809   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
21810 _(sr_mpls_policy_del,                                                   \
21811   "bsid <id>")                                                          \
21812 _(bier_table_add_del,                                                   \
21813   "<label> <sub-domain> <set> <bsl> [del]")                             \
21814 _(bier_route_add_del,                                                   \
21815   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
21816   "[<intfc> | sw_if_index <id>]"                                        \
21817   "[weight <n>] [del] [multipath]")                                     \
21818 _(proxy_arp_add_del,                                                    \
21819   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
21820 _(proxy_arp_intfc_enable_disable,                                       \
21821   "<intfc> | sw_if_index <id> enable | disable")                        \
21822 _(sw_interface_set_unnumbered,                                          \
21823   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
21824 _(ip_neighbor_add_del,                                                  \
21825   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
21826   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
21827 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
21828 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
21829   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
21830   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
21831   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
21832 _(reset_fib, "vrf <n> [ipv6]")                                          \
21833 _(dhcp_proxy_config,                                                    \
21834   "svr <v46-address> src <v46-address>\n"                               \
21835    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
21836 _(dhcp_proxy_set_vss,                                                   \
21837   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
21838 _(dhcp_proxy_dump, "ip6")                                               \
21839 _(dhcp_client_config,                                                   \
21840   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
21841 _(set_ip_flow_hash,                                                     \
21842   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
21843 _(sw_interface_ip6_enable_disable,                                      \
21844   "<intfc> | sw_if_index <id> enable | disable")                        \
21845 _(ip6nd_proxy_add_del,                                                  \
21846   "<intfc> | sw_if_index <id> <ip6-address>")                           \
21847 _(ip6nd_proxy_dump, "")                                                 \
21848 _(sw_interface_ip6nd_ra_prefix,                                         \
21849   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
21850   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
21851   "[nolink] [isno]")                                                    \
21852 _(sw_interface_ip6nd_ra_config,                                         \
21853   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
21854   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
21855   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
21856 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
21857 _(l2_patch_add_del,                                                     \
21858   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21859   "enable | disable")                                                   \
21860 _(sr_localsid_add_del,                                                  \
21861   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
21862   "fib-table <num> (end.psp) sw_if_index <num>")                        \
21863 _(classify_add_del_table,                                               \
21864   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
21865   " [del] [del-chain] mask <mask-value>\n"                              \
21866   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
21867   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
21868 _(classify_add_del_session,                                             \
21869   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
21870   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
21871   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
21872   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
21873 _(classify_set_interface_ip_table,                                      \
21874   "<intfc> | sw_if_index <nn> table <nn>")                              \
21875 _(classify_set_interface_l2_tables,                                     \
21876   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21877   "  [other-table <nn>]")                                               \
21878 _(get_node_index, "node <node-name")                                    \
21879 _(add_node_next, "node <node-name> next <next-node-name>")              \
21880 _(l2tpv3_create_tunnel,                                                 \
21881   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
21882   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
21883   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
21884 _(l2tpv3_set_tunnel_cookies,                                            \
21885   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
21886   "[new_remote_cookie <nn>]\n")                                         \
21887 _(l2tpv3_interface_enable_disable,                                      \
21888   "<intfc> | sw_if_index <nn> enable | disable")                        \
21889 _(l2tpv3_set_lookup_key,                                                \
21890   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
21891 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
21892 _(vxlan_offload_rx,                                                     \
21893   "hw { <interface name> | hw_if_index <nn>} "                          \
21894   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
21895 _(vxlan_add_del_tunnel,                                                 \
21896   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21897   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
21898   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21899 _(geneve_add_del_tunnel,                                                \
21900   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21901   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21902   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21903 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
21904 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
21905 _(gre_tunnel_add_del,                                                   \
21906   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
21907   "[teb | erspan <session-id>] [del]")                                  \
21908 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
21909 _(l2_fib_clear_table, "")                                               \
21910 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
21911 _(l2_interface_vlan_tag_rewrite,                                        \
21912   "<intfc> | sw_if_index <nn> \n"                                       \
21913   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
21914   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
21915 _(create_vhost_user_if,                                                 \
21916         "socket <filename> [server] [renumber <dev_instance>] "         \
21917         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
21918         "[mac <mac_address>]")                                          \
21919 _(modify_vhost_user_if,                                                 \
21920         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
21921         "[server] [renumber <dev_instance>] [gso]")                     \
21922 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
21923 _(sw_interface_vhost_user_dump, "")                                     \
21924 _(show_version, "")                                                     \
21925 _(show_threads, "")                                                     \
21926 _(vxlan_gpe_add_del_tunnel,                                             \
21927   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
21928   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21929   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
21930   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
21931 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
21932 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
21933 _(interface_name_renumber,                                              \
21934   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
21935 _(input_acl_set_interface,                                              \
21936   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21937   "  [l2-table <nn>] [del]")                                            \
21938 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
21939 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
21940   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
21941 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
21942 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
21943 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
21944 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
21945 _(ip_dump, "ipv4 | ipv6")                                               \
21946 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
21947 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
21948   "  spid_id <n> ")                                                     \
21949 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
21950   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
21951   "  integ_alg <alg> integ_key <hex>")                                  \
21952 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
21953   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
21954   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
21955   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
21956 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
21957   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
21958   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
21959   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
21960   "  [instance <n>]")     \
21961 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
21962 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
21963 _(delete_loopback,"sw_if_index <nn>")                                   \
21964 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
21965 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
21966 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
21967 _(want_interface_events,  "enable|disable")                             \
21968 _(get_first_msg_id, "client <name>")                                    \
21969 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
21970 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
21971   "fib-id <nn> [ip4][ip6][default]")                                    \
21972 _(get_node_graph, " ")                                                  \
21973 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
21974 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
21975 _(ioam_disable, "")                                                     \
21976 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
21977                             " sw_if_index <sw_if_index> p <priority> "  \
21978                             "w <weight>] [del]")                        \
21979 _(one_add_del_locator, "locator-set <locator_name> "                    \
21980                         "iface <intf> | sw_if_index <sw_if_index> "     \
21981                         "p <priority> w <weight> [del]")                \
21982 _(one_add_del_local_eid,"vni <vni> eid "                                \
21983                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21984                          "locator-set <locator_name> [del]"             \
21985                          "[key-id sha1|sha256 secret-key <secret-key>]")\
21986 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
21987 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
21988 _(one_enable_disable, "enable|disable")                                 \
21989 _(one_map_register_enable_disable, "enable|disable")                    \
21990 _(one_map_register_fallback_threshold, "<value>")                       \
21991 _(one_rloc_probe_enable_disable, "enable|disable")                      \
21992 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
21993                                "[seid <seid>] "                         \
21994                                "rloc <locator> p <prio> "               \
21995                                "w <weight> [rloc <loc> ... ] "          \
21996                                "action <action> [del-all]")             \
21997 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
21998                           "<local-eid>")                                \
21999 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
22000 _(one_use_petr, "ip-address> | disable")                                \
22001 _(one_map_request_mode, "src-dst|dst-only")                             \
22002 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
22003 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
22004 _(one_locator_set_dump, "[local | remote]")                             \
22005 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
22006 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
22007                        "[local] | [remote]")                            \
22008 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
22009 _(one_ndp_bd_get, "")                                                   \
22010 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
22011 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
22012 _(one_l2_arp_bd_get, "")                                                \
22013 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
22014 _(one_stats_enable_disable, "enable|disable")                           \
22015 _(show_one_stats_enable_disable, "")                                    \
22016 _(one_eid_table_vni_dump, "")                                           \
22017 _(one_eid_table_map_dump, "l2|l3")                                      \
22018 _(one_map_resolver_dump, "")                                            \
22019 _(one_map_server_dump, "")                                              \
22020 _(one_adjacencies_get, "vni <vni>")                                     \
22021 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
22022 _(show_one_rloc_probe_state, "")                                        \
22023 _(show_one_map_register_state, "")                                      \
22024 _(show_one_status, "")                                                  \
22025 _(one_stats_dump, "")                                                   \
22026 _(one_stats_flush, "")                                                  \
22027 _(one_get_map_request_itr_rlocs, "")                                    \
22028 _(one_map_register_set_ttl, "<ttl>")                                    \
22029 _(one_set_transport_protocol, "udp|api")                                \
22030 _(one_get_transport_protocol, "")                                       \
22031 _(one_enable_disable_xtr_mode, "enable|disable")                        \
22032 _(one_show_xtr_mode, "")                                                \
22033 _(one_enable_disable_pitr_mode, "enable|disable")                       \
22034 _(one_show_pitr_mode, "")                                               \
22035 _(one_enable_disable_petr_mode, "enable|disable")                       \
22036 _(one_show_petr_mode, "")                                               \
22037 _(show_one_nsh_mapping, "")                                             \
22038 _(show_one_pitr, "")                                                    \
22039 _(show_one_use_petr, "")                                                \
22040 _(show_one_map_request_mode, "")                                        \
22041 _(show_one_map_register_ttl, "")                                        \
22042 _(show_one_map_register_fallback_threshold, "")                         \
22043 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
22044                             " sw_if_index <sw_if_index> p <priority> "  \
22045                             "w <weight>] [del]")                        \
22046 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
22047                         "iface <intf> | sw_if_index <sw_if_index> "     \
22048                         "p <priority> w <weight> [del]")                \
22049 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
22050                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22051                          "locator-set <locator_name> [del]"             \
22052                          "[key-id sha1|sha256 secret-key <secret-key>]") \
22053 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
22054 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
22055 _(lisp_enable_disable, "enable|disable")                                \
22056 _(lisp_map_register_enable_disable, "enable|disable")                   \
22057 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
22058 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
22059                                "[seid <seid>] "                         \
22060                                "rloc <locator> p <prio> "               \
22061                                "w <weight> [rloc <loc> ... ] "          \
22062                                "action <action> [del-all]")             \
22063 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
22064                           "<local-eid>")                                \
22065 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
22066 _(lisp_use_petr, "<ip-address> | disable")                              \
22067 _(lisp_map_request_mode, "src-dst|dst-only")                            \
22068 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
22069 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
22070 _(lisp_locator_set_dump, "[local | remote]")                            \
22071 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
22072 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
22073                        "[local] | [remote]")                            \
22074 _(lisp_eid_table_vni_dump, "")                                          \
22075 _(lisp_eid_table_map_dump, "l2|l3")                                     \
22076 _(lisp_map_resolver_dump, "")                                           \
22077 _(lisp_map_server_dump, "")                                             \
22078 _(lisp_adjacencies_get, "vni <vni>")                                    \
22079 _(gpe_fwd_entry_vnis_get, "")                                           \
22080 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
22081 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
22082                                 "[table <table-id>]")                   \
22083 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
22084 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
22085 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
22086 _(gpe_get_encap_mode, "")                                               \
22087 _(lisp_gpe_add_del_iface, "up|down")                                    \
22088 _(lisp_gpe_enable_disable, "enable|disable")                            \
22089 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
22090   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
22091 _(show_lisp_rloc_probe_state, "")                                       \
22092 _(show_lisp_map_register_state, "")                                     \
22093 _(show_lisp_status, "")                                                 \
22094 _(lisp_get_map_request_itr_rlocs, "")                                   \
22095 _(show_lisp_pitr, "")                                                   \
22096 _(show_lisp_use_petr, "")                                               \
22097 _(show_lisp_map_request_mode, "")                                       \
22098 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
22099 _(af_packet_delete, "name <host interface name>")                       \
22100 _(af_packet_dump, "")                                                   \
22101 _(policer_add_del, "name <policer name> <params> [del]")                \
22102 _(policer_dump, "[name <policer name>]")                                \
22103 _(policer_classify_set_interface,                                       \
22104   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22105   "  [l2-table <nn>] [del]")                                            \
22106 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
22107 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
22108     "[master|slave]")                                                   \
22109 _(netmap_delete, "name <interface name>")                               \
22110 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
22111 _(mpls_table_dump, "")                                                  \
22112 _(mpls_route_dump, "table-id <ID>")                                     \
22113 _(classify_table_ids, "")                                               \
22114 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
22115 _(classify_table_info, "table_id <nn>")                                 \
22116 _(classify_session_dump, "table_id <nn>")                               \
22117 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
22118     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
22119     "[template_interval <nn>] [udp_checksum]")                          \
22120 _(ipfix_exporter_dump, "")                                              \
22121 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
22122 _(ipfix_classify_stream_dump, "")                                       \
22123 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
22124 _(ipfix_classify_table_dump, "")                                        \
22125 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
22126 _(sw_interface_span_dump, "[l2]")                                           \
22127 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
22128 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
22129 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
22130 _(pg_enable_disable, "[stream <id>] disable")                           \
22131 _(ip_source_and_port_range_check_add_del,                               \
22132   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
22133 _(ip_source_and_port_range_check_interface_add_del,                     \
22134   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
22135   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
22136 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
22137 _(l2_interface_pbb_tag_rewrite,                                         \
22138   "<intfc> | sw_if_index <nn> \n"                                       \
22139   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
22140   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
22141 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
22142 _(flow_classify_set_interface,                                          \
22143   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
22144 _(flow_classify_dump, "type [ip4|ip6]")                                 \
22145 _(ip_table_dump, "")                                                    \
22146 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
22147 _(ip_mtable_dump, "")                                                   \
22148 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
22149 _(feature_enable_disable, "arc_name <arc_name> "                        \
22150   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
22151 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
22152 "[disable]")                                                            \
22153 _(l2_xconnect_dump, "")                                                 \
22154 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
22155 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
22156 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
22157 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
22158 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
22159 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
22160 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
22161   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
22162 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
22163 _(sock_init_shm, "size <nnn>")                                          \
22164 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
22165 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
22166   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
22167 _(session_rules_dump, "")                                               \
22168 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
22169 _(output_acl_set_interface,                                             \
22170   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22171   "  [l2-table <nn>] [del]")                                            \
22172 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
22173
22174 /* List of command functions, CLI names map directly to functions */
22175 #define foreach_cli_function                                    \
22176 _(comment, "usage: comment <ignore-rest-of-line>")              \
22177 _(dump_interface_table, "usage: dump_interface_table")          \
22178 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
22179 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
22180 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
22181 _(dump_macro_table, "usage: dump_macro_table ")                 \
22182 _(dump_node_table, "usage: dump_node_table")                    \
22183 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
22184 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
22185 _(elog_disable, "usage: elog_disable")                          \
22186 _(elog_enable, "usage: elog_enable")                            \
22187 _(elog_save, "usage: elog_save <filename>")                     \
22188 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
22189 _(echo, "usage: echo <message>")                                \
22190 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
22191 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
22192 _(help, "usage: help")                                          \
22193 _(q, "usage: quit")                                             \
22194 _(quit, "usage: quit")                                          \
22195 _(search_node_table, "usage: search_node_table <name>...")      \
22196 _(set, "usage: set <variable-name> <value>")                    \
22197 _(script, "usage: script <file-name>")                          \
22198 _(statseg, "usage: statseg")                                    \
22199 _(unset, "usage: unset <variable-name>")
22200
22201 #define _(N,n)                                  \
22202     static void vl_api_##n##_t_handler_uni      \
22203     (vl_api_##n##_t * mp)                       \
22204     {                                           \
22205         vat_main_t * vam = &vat_main;           \
22206         if (vam->json_output) {                 \
22207             vl_api_##n##_t_handler_json(mp);    \
22208         } else {                                \
22209             vl_api_##n##_t_handler(mp);         \
22210         }                                       \
22211     }
22212 foreach_vpe_api_reply_msg;
22213 #if VPP_API_TEST_BUILTIN == 0
22214 foreach_standalone_reply_msg;
22215 #endif
22216 #undef _
22217
22218 void
22219 vat_api_hookup (vat_main_t * vam)
22220 {
22221 #define _(N,n)                                                  \
22222     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
22223                            vl_api_##n##_t_handler_uni,          \
22224                            vl_noop_handler,                     \
22225                            vl_api_##n##_t_endian,               \
22226                            vl_api_##n##_t_print,                \
22227                            sizeof(vl_api_##n##_t), 1);
22228   foreach_vpe_api_reply_msg;
22229 #if VPP_API_TEST_BUILTIN == 0
22230   foreach_standalone_reply_msg;
22231 #endif
22232 #undef _
22233
22234 #if (VPP_API_TEST_BUILTIN==0)
22235   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
22236
22237   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
22238
22239   vam->function_by_name = hash_create_string (0, sizeof (uword));
22240
22241   vam->help_by_name = hash_create_string (0, sizeof (uword));
22242 #endif
22243
22244   /* API messages we can send */
22245 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
22246   foreach_vpe_api_msg;
22247 #undef _
22248
22249   /* Help strings */
22250 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22251   foreach_vpe_api_msg;
22252 #undef _
22253
22254   /* CLI functions */
22255 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
22256   foreach_cli_function;
22257 #undef _
22258
22259   /* Help strings */
22260 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22261   foreach_cli_function;
22262 #undef _
22263 }
22264
22265 #if VPP_API_TEST_BUILTIN
22266 static clib_error_t *
22267 vat_api_hookup_shim (vlib_main_t * vm)
22268 {
22269   vat_api_hookup (&vat_main);
22270   return 0;
22271 }
22272
22273 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
22274 #endif
22275
22276 /*
22277  * fd.io coding-style-patch-verification: ON
22278  *
22279  * Local Variables:
22280  * eval: (c-set-style "gnu")
22281  * End:
22282  */