flow: add vnet/flow formal API
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2020 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlib/pci/pci.h>
22 #include <vpp/api/types.h>
23 #include <vppinfra/socket.h>
24 #include <vlibapi/api.h>
25 #include <vlibmemory/api.h>
26 #include <vnet/ip/ip.h>
27 #include <vnet/ip-neighbor/ip_neighbor.h>
28 #include <vnet/ip/ip_types_api.h>
29 #include <vnet/l2/l2_input.h>
30 #include <vnet/l2tp/l2tp.h>
31 #include <vnet/vxlan/vxlan.h>
32 #include <vnet/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/ip/ip6_hop_by_hop.h>
47 #include <vnet/ip/ip_source_and_port_range_check.h>
48 #include <vnet/policer/xlate.h>
49 #include <vnet/span/span.h>
50 #include <vnet/policer/policer.h>
51 #include <vnet/policer/police.h>
52 #include <vnet/mfib/mfib_types.h>
53 #include <vnet/bonding/node.h>
54 #include <vnet/qos/qos_types.h>
55 #include <vnet/ethernet/ethernet_types_api.h>
56 #include <vnet/ip/ip_types_api.h>
57 #include "vat/json_format.h"
58 #include <vnet/ip/ip_types_api.h>
59 #include <vnet/ethernet/ethernet_types_api.h>
60
61 #include <inttypes.h>
62 #include <sys/stat.h>
63
64 #define vl_typedefs             /* define message structures */
65 #include <vpp/api/vpe_all_api_h.h>
66 #undef vl_typedefs
67
68 /* declare message handlers for each api */
69
70 #define vl_endianfun            /* define message structures */
71 #include <vpp/api/vpe_all_api_h.h>
72 #undef vl_endianfun
73
74 /* instantiate all the print functions we know about */
75 #if VPP_API_TEST_BUILTIN == 0
76 #define vl_print(handle, ...)
77 #else
78 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
79 #endif
80 #define vl_printfun
81 #include <vpp/api/vpe_all_api_h.h>
82 #undef vl_printfun
83
84 #define __plugin_msg_base 0
85 #include <vlibapi/vat_helper_macros.h>
86
87 #include <vnet/format_fns.h>
88
89 void vl_api_set_elog_main (elog_main_t * m);
90 int vl_api_set_elog_trace_api_messages (int enable);
91
92 #if VPP_API_TEST_BUILTIN == 0
93 #include <netdb.h>
94
95 u32
96 vl (void *p)
97 {
98   return vec_len (p);
99 }
100
101 int
102 vat_socket_connect (vat_main_t * vam)
103 {
104   int rv;
105   api_main_t *am = vlibapi_get_main ();
106   vam->socket_client_main = &socket_client_main;
107   if ((rv = vl_socket_client_connect ((char *) vam->socket_name,
108                                       "vpp_api_test",
109                                       0 /* default socket rx, tx buffer */ )))
110     return rv;
111
112   /* vpp expects the client index in network order */
113   vam->my_client_index = htonl (socket_client_main.client_index);
114   am->my_client_index = vam->my_client_index;
115   return 0;
116 }
117 #else /* vpp built-in case, we don't do sockets... */
118 int
119 vat_socket_connect (vat_main_t * vam)
120 {
121   return 0;
122 }
123
124 int
125 vl_socket_client_read (int wait)
126 {
127   return -1;
128 };
129
130 int
131 vl_socket_client_write ()
132 {
133   return -1;
134 };
135
136 void *
137 vl_socket_client_msg_alloc (int nbytes)
138 {
139   return 0;
140 }
141 #endif
142
143
144 f64
145 vat_time_now (vat_main_t * vam)
146 {
147 #if VPP_API_TEST_BUILTIN
148   return vlib_time_now (vam->vlib_main);
149 #else
150   return clib_time_now (&vam->clib_time);
151 #endif
152 }
153
154 void
155 errmsg (char *fmt, ...)
156 {
157   vat_main_t *vam = &vat_main;
158   va_list va;
159   u8 *s;
160
161   va_start (va, fmt);
162   s = va_format (0, fmt, &va);
163   va_end (va);
164
165   vec_add1 (s, 0);
166
167 #if VPP_API_TEST_BUILTIN
168   vlib_cli_output (vam->vlib_main, (char *) s);
169 #else
170   {
171     if (vam->ifp != stdin)
172       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
173                vam->input_line_number);
174     else
175       fformat (vam->ofp, "%s\n", (char *) s);
176     fflush (vam->ofp);
177   }
178 #endif
179
180   vec_free (s);
181 }
182
183 #if VPP_API_TEST_BUILTIN == 0
184 static uword
185 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
186 {
187   vat_main_t *vam = va_arg (*args, vat_main_t *);
188   u32 *result = va_arg (*args, u32 *);
189   u8 *if_name;
190   uword *p;
191
192   if (!unformat (input, "%s", &if_name))
193     return 0;
194
195   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
196   if (p == 0)
197     return 0;
198   *result = p[0];
199   return 1;
200 }
201
202 static uword
203 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
204 {
205   return 0;
206 }
207
208 /* Parse an IP4 address %d.%d.%d.%d. */
209 uword
210 unformat_ip4_address (unformat_input_t * input, va_list * args)
211 {
212   u8 *result = va_arg (*args, u8 *);
213   unsigned a[4];
214
215   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
216     return 0;
217
218   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
219     return 0;
220
221   result[0] = a[0];
222   result[1] = a[1];
223   result[2] = a[2];
224   result[3] = a[3];
225
226   return 1;
227 }
228
229 uword
230 unformat_ethernet_address (unformat_input_t * input, va_list * args)
231 {
232   u8 *result = va_arg (*args, u8 *);
233   u32 i, a[6];
234
235   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
236                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
237     return 0;
238
239   /* Check range. */
240   for (i = 0; i < 6; i++)
241     if (a[i] >= (1 << 8))
242       return 0;
243
244   for (i = 0; i < 6; i++)
245     result[i] = a[i];
246
247   return 1;
248 }
249
250 /* Returns ethernet type as an int in host byte order. */
251 uword
252 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
253                                         va_list * args)
254 {
255   u16 *result = va_arg (*args, u16 *);
256   int type;
257
258   /* Numeric type. */
259   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
260     {
261       if (type >= (1 << 16))
262         return 0;
263       *result = type;
264       return 1;
265     }
266   return 0;
267 }
268
269 /* Parse an IP46 address. */
270 uword
271 unformat_ip46_address (unformat_input_t * input, va_list * args)
272 {
273   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
274   ip46_type_t type = va_arg (*args, ip46_type_t);
275   if ((type != IP46_TYPE_IP6) &&
276       unformat (input, "%U", unformat_ip4_address, &ip46->ip4))
277     {
278       ip46_address_mask_ip4 (ip46);
279       return 1;
280     }
281   else if ((type != IP46_TYPE_IP4) &&
282            unformat (input, "%U", unformat_ip6_address, &ip46->ip6))
283     {
284       return 1;
285     }
286   return 0;
287 }
288
289 /* Parse an IP6 address. */
290 uword
291 unformat_ip6_address (unformat_input_t * input, va_list * args)
292 {
293   ip6_address_t *result = va_arg (*args, ip6_address_t *);
294   u16 hex_quads[8];
295   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
296   uword c, n_colon, double_colon_index;
297
298   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
299   double_colon_index = ARRAY_LEN (hex_quads);
300   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
301     {
302       hex_digit = 16;
303       if (c >= '0' && c <= '9')
304         hex_digit = c - '0';
305       else if (c >= 'a' && c <= 'f')
306         hex_digit = c + 10 - 'a';
307       else if (c >= 'A' && c <= 'F')
308         hex_digit = c + 10 - 'A';
309       else if (c == ':' && n_colon < 2)
310         n_colon++;
311       else
312         {
313           unformat_put_input (input);
314           break;
315         }
316
317       /* Too many hex quads. */
318       if (n_hex_quads >= ARRAY_LEN (hex_quads))
319         return 0;
320
321       if (hex_digit < 16)
322         {
323           hex_quad = (hex_quad << 4) | hex_digit;
324
325           /* Hex quad must fit in 16 bits. */
326           if (n_hex_digits >= 4)
327             return 0;
328
329           n_colon = 0;
330           n_hex_digits++;
331         }
332
333       /* Save position of :: */
334       if (n_colon == 2)
335         {
336           /* More than one :: ? */
337           if (double_colon_index < ARRAY_LEN (hex_quads))
338             return 0;
339           double_colon_index = n_hex_quads;
340         }
341
342       if (n_colon > 0 && n_hex_digits > 0)
343         {
344           hex_quads[n_hex_quads++] = hex_quad;
345           hex_quad = 0;
346           n_hex_digits = 0;
347         }
348     }
349
350   if (n_hex_digits > 0)
351     hex_quads[n_hex_quads++] = hex_quad;
352
353   {
354     word i;
355
356     /* Expand :: to appropriate number of zero hex quads. */
357     if (double_colon_index < ARRAY_LEN (hex_quads))
358       {
359         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
360
361         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
362           hex_quads[n_zero + i] = hex_quads[i];
363
364         for (i = 0; i < n_zero; i++)
365           hex_quads[double_colon_index + i] = 0;
366
367         n_hex_quads = ARRAY_LEN (hex_quads);
368       }
369
370     /* Too few hex quads given. */
371     if (n_hex_quads < ARRAY_LEN (hex_quads))
372       return 0;
373
374     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
375       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
376
377     return 1;
378   }
379 }
380
381 uword
382 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
383 {
384   u32 *r = va_arg (*args, u32 *);
385
386   if (0);
387 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
388   foreach_ipsec_policy_action
389 #undef _
390     else
391     return 0;
392   return 1;
393 }
394
395 u8 *
396 format_ipsec_crypto_alg (u8 * s, va_list * args)
397 {
398   u32 i = va_arg (*args, u32);
399   u8 *t = 0;
400
401   switch (i)
402     {
403 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
404       foreach_ipsec_crypto_alg
405 #undef _
406     default:
407       return format (s, "unknown");
408     }
409   return format (s, "%s", t);
410 }
411
412 u8 *
413 format_ipsec_integ_alg (u8 * s, va_list * args)
414 {
415   u32 i = va_arg (*args, u32);
416   u8 *t = 0;
417
418   switch (i)
419     {
420 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
421       foreach_ipsec_integ_alg
422 #undef _
423     default:
424       return format (s, "unknown");
425     }
426   return format (s, "%s", t);
427 }
428
429 #else /* VPP_API_TEST_BUILTIN == 1 */
430 static uword
431 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
432 {
433   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
434   vnet_main_t *vnm = vnet_get_main ();
435   u32 *result = va_arg (*args, u32 *);
436
437   return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
438 }
439
440 static uword
441 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
442 {
443   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
444   vnet_main_t *vnm = vnet_get_main ();
445   u32 *result = va_arg (*args, u32 *);
446
447   return unformat (input, "%U", unformat_vnet_hw_interface, vnm, result);
448 }
449
450 #endif /* VPP_API_TEST_BUILTIN */
451
452 uword
453 unformat_ipsec_api_crypto_alg (unformat_input_t * input, va_list * args)
454 {
455   u32 *r = va_arg (*args, u32 *);
456
457   if (0);
458 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_CRYPTO_ALG_##f;
459   foreach_ipsec_crypto_alg
460 #undef _
461     else
462     return 0;
463   return 1;
464 }
465
466 uword
467 unformat_ipsec_api_integ_alg (unformat_input_t * input, va_list * args)
468 {
469   u32 *r = va_arg (*args, u32 *);
470
471   if (0);
472 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_INTEG_ALG_##f;
473   foreach_ipsec_integ_alg
474 #undef _
475     else
476     return 0;
477   return 1;
478 }
479
480 static uword
481 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
482 {
483   u8 *r = va_arg (*args, u8 *);
484
485   if (unformat (input, "kbps"))
486     *r = SSE2_QOS_RATE_KBPS;
487   else if (unformat (input, "pps"))
488     *r = SSE2_QOS_RATE_PPS;
489   else
490     return 0;
491   return 1;
492 }
493
494 static uword
495 unformat_policer_round_type (unformat_input_t * input, va_list * args)
496 {
497   u8 *r = va_arg (*args, u8 *);
498
499   if (unformat (input, "closest"))
500     *r = SSE2_QOS_ROUND_TO_CLOSEST;
501   else if (unformat (input, "up"))
502     *r = SSE2_QOS_ROUND_TO_UP;
503   else if (unformat (input, "down"))
504     *r = SSE2_QOS_ROUND_TO_DOWN;
505   else
506     return 0;
507   return 1;
508 }
509
510 static uword
511 unformat_policer_type (unformat_input_t * input, va_list * args)
512 {
513   u8 *r = va_arg (*args, u8 *);
514
515   if (unformat (input, "1r2c"))
516     *r = SSE2_QOS_POLICER_TYPE_1R2C;
517   else if (unformat (input, "1r3c"))
518     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
519   else if (unformat (input, "2r3c-2698"))
520     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
521   else if (unformat (input, "2r3c-4115"))
522     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
523   else if (unformat (input, "2r3c-mef5cf1"))
524     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
525   else
526     return 0;
527   return 1;
528 }
529
530 static uword
531 unformat_dscp (unformat_input_t * input, va_list * va)
532 {
533   u8 *r = va_arg (*va, u8 *);
534
535   if (0);
536 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
537   foreach_vnet_dscp
538 #undef _
539     else
540     return 0;
541   return 1;
542 }
543
544 static uword
545 unformat_policer_action_type (unformat_input_t * input, va_list * va)
546 {
547   sse2_qos_pol_action_params_st *a
548     = va_arg (*va, sse2_qos_pol_action_params_st *);
549
550   if (unformat (input, "drop"))
551     a->action_type = SSE2_QOS_ACTION_DROP;
552   else if (unformat (input, "transmit"))
553     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
554   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
555     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
556   else
557     return 0;
558   return 1;
559 }
560
561 static uword
562 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
563 {
564   u32 *r = va_arg (*va, u32 *);
565   u32 tid;
566
567   if (unformat (input, "ip4"))
568     tid = POLICER_CLASSIFY_TABLE_IP4;
569   else if (unformat (input, "ip6"))
570     tid = POLICER_CLASSIFY_TABLE_IP6;
571   else if (unformat (input, "l2"))
572     tid = POLICER_CLASSIFY_TABLE_L2;
573   else
574     return 0;
575
576   *r = tid;
577   return 1;
578 }
579
580 static uword
581 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
582 {
583   u32 *r = va_arg (*va, u32 *);
584   u32 tid;
585
586   if (unformat (input, "ip4"))
587     tid = FLOW_CLASSIFY_TABLE_IP4;
588   else if (unformat (input, "ip6"))
589     tid = FLOW_CLASSIFY_TABLE_IP6;
590   else
591     return 0;
592
593   *r = tid;
594   return 1;
595 }
596
597 #if (VPP_API_TEST_BUILTIN==0)
598
599 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
600 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
601 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
602 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
603
604 uword
605 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
606 {
607   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
608   mfib_itf_attribute_t attr;
609
610   old = *iflags;
611   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
612   {
613     if (unformat (input, mfib_itf_flag_long_names[attr]))
614       *iflags |= (1 << attr);
615   }
616   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
617   {
618     if (unformat (input, mfib_itf_flag_names[attr]))
619       *iflags |= (1 << attr);
620   }
621
622   return (old == *iflags ? 0 : 1);
623 }
624
625 uword
626 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
627 {
628   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
629   mfib_entry_attribute_t attr;
630
631   old = *eflags;
632   FOR_EACH_MFIB_ATTRIBUTE (attr)
633   {
634     if (unformat (input, mfib_flag_long_names[attr]))
635       *eflags |= (1 << attr);
636   }
637   FOR_EACH_MFIB_ATTRIBUTE (attr)
638   {
639     if (unformat (input, mfib_flag_names[attr]))
640       *eflags |= (1 << attr);
641   }
642
643   return (old == *eflags ? 0 : 1);
644 }
645
646 u8 *
647 format_ip4_address (u8 * s, va_list * args)
648 {
649   u8 *a = va_arg (*args, u8 *);
650   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
651 }
652
653 u8 *
654 format_ip6_address (u8 * s, va_list * args)
655 {
656   ip6_address_t *a = va_arg (*args, ip6_address_t *);
657   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
658
659   i_max_n_zero = ARRAY_LEN (a->as_u16);
660   max_n_zeros = 0;
661   i_first_zero = i_max_n_zero;
662   n_zeros = 0;
663   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
664     {
665       u32 is_zero = a->as_u16[i] == 0;
666       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
667         {
668           i_first_zero = i;
669           n_zeros = 0;
670         }
671       n_zeros += is_zero;
672       if ((!is_zero && n_zeros > max_n_zeros)
673           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
674         {
675           i_max_n_zero = i_first_zero;
676           max_n_zeros = n_zeros;
677           i_first_zero = ARRAY_LEN (a->as_u16);
678           n_zeros = 0;
679         }
680     }
681
682   last_double_colon = 0;
683   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
684     {
685       if (i == i_max_n_zero && max_n_zeros > 1)
686         {
687           s = format (s, "::");
688           i += max_n_zeros - 1;
689           last_double_colon = 1;
690         }
691       else
692         {
693           s = format (s, "%s%x",
694                       (last_double_colon || i == 0) ? "" : ":",
695                       clib_net_to_host_u16 (a->as_u16[i]));
696           last_double_colon = 0;
697         }
698     }
699
700   return s;
701 }
702
703 /* Format an IP46 address. */
704 u8 *
705 format_ip46_address (u8 * s, va_list * args)
706 {
707   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
708   ip46_type_t type = va_arg (*args, ip46_type_t);
709   int is_ip4 = 1;
710
711   switch (type)
712     {
713     case IP46_TYPE_ANY:
714       is_ip4 = ip46_address_is_ip4 (ip46);
715       break;
716     case IP46_TYPE_IP4:
717       is_ip4 = 1;
718       break;
719     case IP46_TYPE_IP6:
720       is_ip4 = 0;
721       break;
722     }
723
724   return is_ip4 ?
725     format (s, "%U", format_ip4_address, &ip46->ip4) :
726     format (s, "%U", format_ip6_address, &ip46->ip6);
727 }
728
729 u8 *
730 format_ethernet_address (u8 * s, va_list * args)
731 {
732   u8 *a = va_arg (*args, u8 *);
733
734   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
735                  a[0], a[1], a[2], a[3], a[4], a[5]);
736 }
737 #endif
738
739 static void
740 increment_v4_address (vl_api_ip4_address_t * i)
741 {
742   ip4_address_t *a = (ip4_address_t *) i;
743   u32 v;
744
745   v = ntohl (a->as_u32) + 1;
746   a->as_u32 = ntohl (v);
747 }
748
749 static void
750 increment_v6_address (vl_api_ip6_address_t * i)
751 {
752   ip6_address_t *a = (ip6_address_t *) i;
753   u64 v0, v1;
754
755   v0 = clib_net_to_host_u64 (a->as_u64[0]);
756   v1 = clib_net_to_host_u64 (a->as_u64[1]);
757
758   v1 += 1;
759   if (v1 == 0)
760     v0 += 1;
761   a->as_u64[0] = clib_net_to_host_u64 (v0);
762   a->as_u64[1] = clib_net_to_host_u64 (v1);
763 }
764
765 static void
766 increment_address (vl_api_address_t * a)
767 {
768   if (a->af == ADDRESS_IP4)
769     increment_v4_address (&a->un.ip4);
770   else if (a->af == ADDRESS_IP6)
771     increment_v6_address (&a->un.ip6);
772 }
773
774 static void
775 set_ip4_address (vl_api_address_t * a, u32 v)
776 {
777   if (a->af == ADDRESS_IP4)
778     {
779       ip4_address_t *i = (ip4_address_t *) & a->un.ip4;
780       i->as_u32 = v;
781     }
782 }
783
784 void
785 ip_set (ip46_address_t * dst, void *src, u8 is_ip4)
786 {
787   if (is_ip4)
788     dst->ip4.as_u32 = ((ip4_address_t *) src)->as_u32;
789   else
790     clib_memcpy_fast (&dst->ip6, (ip6_address_t *) src,
791                       sizeof (ip6_address_t));
792 }
793
794 static void
795 increment_mac_address (u8 * mac)
796 {
797   u64 tmp = *((u64 *) mac);
798   tmp = clib_net_to_host_u64 (tmp);
799   tmp += 1 << 16;               /* skip unused (least significant) octets */
800   tmp = clib_host_to_net_u64 (tmp);
801
802   clib_memcpy (mac, &tmp, 6);
803 }
804
805 static void
806 vat_json_object_add_address (vat_json_node_t * node,
807                              const char *str, const vl_api_address_t * addr)
808 {
809   if (ADDRESS_IP6 == addr->af)
810     {
811       struct in6_addr ip6;
812
813       clib_memcpy (&ip6, &addr->un.ip6, sizeof (ip6));
814       vat_json_object_add_ip6 (node, str, ip6);
815     }
816   else
817     {
818       struct in_addr ip4;
819
820       clib_memcpy (&ip4, &addr->un.ip4, sizeof (ip4));
821       vat_json_object_add_ip4 (node, str, ip4);
822     }
823 }
824
825 static void
826 vat_json_object_add_prefix (vat_json_node_t * node,
827                             const vl_api_prefix_t * prefix)
828 {
829   vat_json_object_add_uint (node, "len", prefix->len);
830   vat_json_object_add_address (node, "address", &prefix->address);
831 }
832
833 static void vl_api_create_loopback_reply_t_handler
834   (vl_api_create_loopback_reply_t * mp)
835 {
836   vat_main_t *vam = &vat_main;
837   i32 retval = ntohl (mp->retval);
838
839   vam->retval = retval;
840   vam->regenerate_interface_table = 1;
841   vam->sw_if_index = ntohl (mp->sw_if_index);
842   vam->result_ready = 1;
843 }
844
845 static void vl_api_create_loopback_reply_t_handler_json
846   (vl_api_create_loopback_reply_t * mp)
847 {
848   vat_main_t *vam = &vat_main;
849   vat_json_node_t node;
850
851   vat_json_init_object (&node);
852   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
853   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
854
855   vat_json_print (vam->ofp, &node);
856   vat_json_free (&node);
857   vam->retval = ntohl (mp->retval);
858   vam->result_ready = 1;
859 }
860
861 static void vl_api_create_loopback_instance_reply_t_handler
862   (vl_api_create_loopback_instance_reply_t * mp)
863 {
864   vat_main_t *vam = &vat_main;
865   i32 retval = ntohl (mp->retval);
866
867   vam->retval = retval;
868   vam->regenerate_interface_table = 1;
869   vam->sw_if_index = ntohl (mp->sw_if_index);
870   vam->result_ready = 1;
871 }
872
873 static void vl_api_create_loopback_instance_reply_t_handler_json
874   (vl_api_create_loopback_instance_reply_t * mp)
875 {
876   vat_main_t *vam = &vat_main;
877   vat_json_node_t node;
878
879   vat_json_init_object (&node);
880   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
881   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
882
883   vat_json_print (vam->ofp, &node);
884   vat_json_free (&node);
885   vam->retval = ntohl (mp->retval);
886   vam->result_ready = 1;
887 }
888
889 static void vl_api_af_packet_create_reply_t_handler
890   (vl_api_af_packet_create_reply_t * mp)
891 {
892   vat_main_t *vam = &vat_main;
893   i32 retval = ntohl (mp->retval);
894
895   vam->retval = retval;
896   vam->regenerate_interface_table = 1;
897   vam->sw_if_index = ntohl (mp->sw_if_index);
898   vam->result_ready = 1;
899 }
900
901 static void vl_api_af_packet_create_reply_t_handler_json
902   (vl_api_af_packet_create_reply_t * mp)
903 {
904   vat_main_t *vam = &vat_main;
905   vat_json_node_t node;
906
907   vat_json_init_object (&node);
908   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
909   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
910
911   vat_json_print (vam->ofp, &node);
912   vat_json_free (&node);
913
914   vam->retval = ntohl (mp->retval);
915   vam->result_ready = 1;
916 }
917
918 static void vl_api_create_vlan_subif_reply_t_handler
919   (vl_api_create_vlan_subif_reply_t * mp)
920 {
921   vat_main_t *vam = &vat_main;
922   i32 retval = ntohl (mp->retval);
923
924   vam->retval = retval;
925   vam->regenerate_interface_table = 1;
926   vam->sw_if_index = ntohl (mp->sw_if_index);
927   vam->result_ready = 1;
928 }
929
930 static void vl_api_create_vlan_subif_reply_t_handler_json
931   (vl_api_create_vlan_subif_reply_t * mp)
932 {
933   vat_main_t *vam = &vat_main;
934   vat_json_node_t node;
935
936   vat_json_init_object (&node);
937   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
938   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
939
940   vat_json_print (vam->ofp, &node);
941   vat_json_free (&node);
942
943   vam->retval = ntohl (mp->retval);
944   vam->result_ready = 1;
945 }
946
947 static void vl_api_create_subif_reply_t_handler
948   (vl_api_create_subif_reply_t * mp)
949 {
950   vat_main_t *vam = &vat_main;
951   i32 retval = ntohl (mp->retval);
952
953   vam->retval = retval;
954   vam->regenerate_interface_table = 1;
955   vam->sw_if_index = ntohl (mp->sw_if_index);
956   vam->result_ready = 1;
957 }
958
959 static void vl_api_create_subif_reply_t_handler_json
960   (vl_api_create_subif_reply_t * mp)
961 {
962   vat_main_t *vam = &vat_main;
963   vat_json_node_t node;
964
965   vat_json_init_object (&node);
966   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
967   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
968
969   vat_json_print (vam->ofp, &node);
970   vat_json_free (&node);
971
972   vam->retval = ntohl (mp->retval);
973   vam->result_ready = 1;
974 }
975
976 static void vl_api_interface_name_renumber_reply_t_handler
977   (vl_api_interface_name_renumber_reply_t * mp)
978 {
979   vat_main_t *vam = &vat_main;
980   i32 retval = ntohl (mp->retval);
981
982   vam->retval = retval;
983   vam->regenerate_interface_table = 1;
984   vam->result_ready = 1;
985 }
986
987 static void vl_api_interface_name_renumber_reply_t_handler_json
988   (vl_api_interface_name_renumber_reply_t * mp)
989 {
990   vat_main_t *vam = &vat_main;
991   vat_json_node_t node;
992
993   vat_json_init_object (&node);
994   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
995
996   vat_json_print (vam->ofp, &node);
997   vat_json_free (&node);
998
999   vam->retval = ntohl (mp->retval);
1000   vam->result_ready = 1;
1001 }
1002
1003 /*
1004  * Special-case: build the interface table, maintain
1005  * the next loopback sw_if_index vbl.
1006  */
1007 static void vl_api_sw_interface_details_t_handler
1008   (vl_api_sw_interface_details_t * mp)
1009 {
1010   vat_main_t *vam = &vat_main;
1011   u8 *s = format (0, "%s%c", mp->interface_name, 0);
1012
1013   hash_set_mem (vam->sw_if_index_by_interface_name, s,
1014                 ntohl (mp->sw_if_index));
1015
1016   /* In sub interface case, fill the sub interface table entry */
1017   if (mp->sw_if_index != mp->sup_sw_if_index)
1018     {
1019       sw_interface_subif_t *sub = NULL;
1020
1021       vec_add2 (vam->sw_if_subif_table, sub, 1);
1022
1023       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
1024       strncpy ((char *) sub->interface_name, (char *) s,
1025                vec_len (sub->interface_name));
1026       sub->sw_if_index = ntohl (mp->sw_if_index);
1027       sub->sub_id = ntohl (mp->sub_id);
1028
1029       sub->raw_flags = ntohl (mp->sub_if_flags & SUB_IF_API_FLAG_MASK_VNET);
1030
1031       sub->sub_number_of_tags = mp->sub_number_of_tags;
1032       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
1033       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
1034
1035       /* vlan tag rewrite */
1036       sub->vtr_op = ntohl (mp->vtr_op);
1037       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
1038       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
1039       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
1040     }
1041 }
1042
1043 static void vl_api_sw_interface_details_t_handler_json
1044   (vl_api_sw_interface_details_t * mp)
1045 {
1046   vat_main_t *vam = &vat_main;
1047   vat_json_node_t *node = NULL;
1048
1049   if (VAT_JSON_ARRAY != vam->json_tree.type)
1050     {
1051       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1052       vat_json_init_array (&vam->json_tree);
1053     }
1054   node = vat_json_array_add (&vam->json_tree);
1055
1056   vat_json_init_object (node);
1057   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1058   vat_json_object_add_uint (node, "sup_sw_if_index",
1059                             ntohl (mp->sup_sw_if_index));
1060   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
1061                              sizeof (mp->l2_address));
1062   vat_json_object_add_string_copy (node, "interface_name",
1063                                    mp->interface_name);
1064   vat_json_object_add_string_copy (node, "interface_dev_type",
1065                                    mp->interface_dev_type);
1066   vat_json_object_add_uint (node, "flags", mp->flags);
1067   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
1068   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
1069   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
1070   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
1071   vat_json_object_add_uint (node, "sub_number_of_tags",
1072                             mp->sub_number_of_tags);
1073   vat_json_object_add_uint (node, "sub_outer_vlan_id",
1074                             ntohs (mp->sub_outer_vlan_id));
1075   vat_json_object_add_uint (node, "sub_inner_vlan_id",
1076                             ntohs (mp->sub_inner_vlan_id));
1077   vat_json_object_add_uint (node, "sub_if_flags", ntohl (mp->sub_if_flags));
1078   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1079   vat_json_object_add_uint (node, "vtr_push_dot1q",
1080                             ntohl (mp->vtr_push_dot1q));
1081   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1082   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1083   if (ntohl (mp->sub_if_flags) & SUB_IF_API_FLAG_DOT1AH)
1084     {
1085       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1086                                        format (0, "%U",
1087                                                format_ethernet_address,
1088                                                &mp->b_dmac));
1089       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1090                                        format (0, "%U",
1091                                                format_ethernet_address,
1092                                                &mp->b_smac));
1093       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1094       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1095     }
1096 }
1097
1098 #if VPP_API_TEST_BUILTIN == 0
1099 static void vl_api_sw_interface_event_t_handler
1100   (vl_api_sw_interface_event_t * mp)
1101 {
1102   vat_main_t *vam = &vat_main;
1103   if (vam->interface_event_display)
1104     errmsg ("interface flags: sw_if_index %d %s %s",
1105             ntohl (mp->sw_if_index),
1106             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_ADMIN_UP) ?
1107             "admin-up" : "admin-down",
1108             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_LINK_UP) ?
1109             "link-up" : "link-down");
1110 }
1111 #endif
1112
1113 __clib_unused static void
1114 vl_api_sw_interface_event_t_handler_json (vl_api_sw_interface_event_t * mp)
1115 {
1116   /* JSON output not supported */
1117 }
1118
1119 static void
1120 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1121 {
1122   vat_main_t *vam = &vat_main;
1123   i32 retval = ntohl (mp->retval);
1124
1125   vam->retval = retval;
1126   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1127   vam->result_ready = 1;
1128 }
1129
1130 static void
1131 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1132 {
1133   vat_main_t *vam = &vat_main;
1134   vat_json_node_t node;
1135   void *oldheap;
1136   u8 *reply;
1137
1138   vat_json_init_object (&node);
1139   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1140   vat_json_object_add_uint (&node, "reply_in_shmem",
1141                             ntohl (mp->reply_in_shmem));
1142   /* Toss the shared-memory original... */
1143   oldheap = vl_msg_push_heap ();
1144
1145   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1146   vec_free (reply);
1147
1148   vl_msg_pop_heap (oldheap);
1149
1150   vat_json_print (vam->ofp, &node);
1151   vat_json_free (&node);
1152
1153   vam->retval = ntohl (mp->retval);
1154   vam->result_ready = 1;
1155 }
1156
1157 static void
1158 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1159 {
1160   vat_main_t *vam = &vat_main;
1161   i32 retval = ntohl (mp->retval);
1162
1163   vec_reset_length (vam->cmd_reply);
1164
1165   vam->retval = retval;
1166   if (retval == 0)
1167     vam->cmd_reply = vl_api_from_api_to_new_vec (mp, &mp->reply);
1168   vam->result_ready = 1;
1169 }
1170
1171 static void
1172 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1173 {
1174   vat_main_t *vam = &vat_main;
1175   vat_json_node_t node;
1176   u8 *reply = 0;                /* reply vector */
1177
1178   reply = vl_api_from_api_to_new_vec (mp, &mp->reply);
1179   vec_reset_length (vam->cmd_reply);
1180
1181   vat_json_init_object (&node);
1182   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1183   vat_json_object_add_string_copy (&node, "reply", reply);
1184
1185   vat_json_print (vam->ofp, &node);
1186   vat_json_free (&node);
1187   vec_free (reply);
1188
1189   vam->retval = ntohl (mp->retval);
1190   vam->result_ready = 1;
1191 }
1192
1193 static void vl_api_classify_add_del_table_reply_t_handler
1194   (vl_api_classify_add_del_table_reply_t * mp)
1195 {
1196   vat_main_t *vam = &vat_main;
1197   i32 retval = ntohl (mp->retval);
1198   if (vam->async_mode)
1199     {
1200       vam->async_errors += (retval < 0);
1201     }
1202   else
1203     {
1204       vam->retval = retval;
1205       if (retval == 0 &&
1206           ((mp->new_table_index != 0xFFFFFFFF) ||
1207            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1208            (mp->match_n_vectors != 0xFFFFFFFF)))
1209         /*
1210          * Note: this is just barely thread-safe, depends on
1211          * the main thread spinning waiting for an answer...
1212          */
1213         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1214                 ntohl (mp->new_table_index),
1215                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1216       vam->result_ready = 1;
1217     }
1218 }
1219
1220 static void vl_api_classify_add_del_table_reply_t_handler_json
1221   (vl_api_classify_add_del_table_reply_t * mp)
1222 {
1223   vat_main_t *vam = &vat_main;
1224   vat_json_node_t node;
1225
1226   vat_json_init_object (&node);
1227   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1228   vat_json_object_add_uint (&node, "new_table_index",
1229                             ntohl (mp->new_table_index));
1230   vat_json_object_add_uint (&node, "skip_n_vectors",
1231                             ntohl (mp->skip_n_vectors));
1232   vat_json_object_add_uint (&node, "match_n_vectors",
1233                             ntohl (mp->match_n_vectors));
1234
1235   vat_json_print (vam->ofp, &node);
1236   vat_json_free (&node);
1237
1238   vam->retval = ntohl (mp->retval);
1239   vam->result_ready = 1;
1240 }
1241
1242 static void vl_api_get_node_index_reply_t_handler
1243   (vl_api_get_node_index_reply_t * mp)
1244 {
1245   vat_main_t *vam = &vat_main;
1246   i32 retval = ntohl (mp->retval);
1247   if (vam->async_mode)
1248     {
1249       vam->async_errors += (retval < 0);
1250     }
1251   else
1252     {
1253       vam->retval = retval;
1254       if (retval == 0)
1255         errmsg ("node index %d", ntohl (mp->node_index));
1256       vam->result_ready = 1;
1257     }
1258 }
1259
1260 static void vl_api_get_node_index_reply_t_handler_json
1261   (vl_api_get_node_index_reply_t * mp)
1262 {
1263   vat_main_t *vam = &vat_main;
1264   vat_json_node_t node;
1265
1266   vat_json_init_object (&node);
1267   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1268   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1269
1270   vat_json_print (vam->ofp, &node);
1271   vat_json_free (&node);
1272
1273   vam->retval = ntohl (mp->retval);
1274   vam->result_ready = 1;
1275 }
1276
1277 static void vl_api_get_next_index_reply_t_handler
1278   (vl_api_get_next_index_reply_t * mp)
1279 {
1280   vat_main_t *vam = &vat_main;
1281   i32 retval = ntohl (mp->retval);
1282   if (vam->async_mode)
1283     {
1284       vam->async_errors += (retval < 0);
1285     }
1286   else
1287     {
1288       vam->retval = retval;
1289       if (retval == 0)
1290         errmsg ("next node index %d", ntohl (mp->next_index));
1291       vam->result_ready = 1;
1292     }
1293 }
1294
1295 static void vl_api_get_next_index_reply_t_handler_json
1296   (vl_api_get_next_index_reply_t * mp)
1297 {
1298   vat_main_t *vam = &vat_main;
1299   vat_json_node_t node;
1300
1301   vat_json_init_object (&node);
1302   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1303   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1304
1305   vat_json_print (vam->ofp, &node);
1306   vat_json_free (&node);
1307
1308   vam->retval = ntohl (mp->retval);
1309   vam->result_ready = 1;
1310 }
1311
1312 static void vl_api_add_node_next_reply_t_handler
1313   (vl_api_add_node_next_reply_t * mp)
1314 {
1315   vat_main_t *vam = &vat_main;
1316   i32 retval = ntohl (mp->retval);
1317   if (vam->async_mode)
1318     {
1319       vam->async_errors += (retval < 0);
1320     }
1321   else
1322     {
1323       vam->retval = retval;
1324       if (retval == 0)
1325         errmsg ("next index %d", ntohl (mp->next_index));
1326       vam->result_ready = 1;
1327     }
1328 }
1329
1330 static void vl_api_add_node_next_reply_t_handler_json
1331   (vl_api_add_node_next_reply_t * mp)
1332 {
1333   vat_main_t *vam = &vat_main;
1334   vat_json_node_t node;
1335
1336   vat_json_init_object (&node);
1337   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1338   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1339
1340   vat_json_print (vam->ofp, &node);
1341   vat_json_free (&node);
1342
1343   vam->retval = ntohl (mp->retval);
1344   vam->result_ready = 1;
1345 }
1346
1347 static void vl_api_show_version_reply_t_handler
1348   (vl_api_show_version_reply_t * mp)
1349 {
1350   vat_main_t *vam = &vat_main;
1351   i32 retval = ntohl (mp->retval);
1352
1353   if (retval >= 0)
1354     {
1355       errmsg ("        program: %s", mp->program);
1356       errmsg ("        version: %s", mp->version);
1357       errmsg ("     build date: %s", mp->build_date);
1358       errmsg ("build directory: %s", mp->build_directory);
1359     }
1360   vam->retval = retval;
1361   vam->result_ready = 1;
1362 }
1363
1364 static void vl_api_show_version_reply_t_handler_json
1365   (vl_api_show_version_reply_t * mp)
1366 {
1367   vat_main_t *vam = &vat_main;
1368   vat_json_node_t node;
1369
1370   vat_json_init_object (&node);
1371   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1372   vat_json_object_add_string_copy (&node, "program", mp->program);
1373   vat_json_object_add_string_copy (&node, "version", mp->version);
1374   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1375   vat_json_object_add_string_copy (&node, "build_directory",
1376                                    mp->build_directory);
1377
1378   vat_json_print (vam->ofp, &node);
1379   vat_json_free (&node);
1380
1381   vam->retval = ntohl (mp->retval);
1382   vam->result_ready = 1;
1383 }
1384
1385 static void vl_api_show_threads_reply_t_handler
1386   (vl_api_show_threads_reply_t * mp)
1387 {
1388   vat_main_t *vam = &vat_main;
1389   i32 retval = ntohl (mp->retval);
1390   int i, count = 0;
1391
1392   if (retval >= 0)
1393     count = ntohl (mp->count);
1394
1395   for (i = 0; i < count; i++)
1396     print (vam->ofp,
1397            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1398            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1399            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1400            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1401            ntohl (mp->thread_data[i].cpu_socket));
1402
1403   vam->retval = retval;
1404   vam->result_ready = 1;
1405 }
1406
1407 static void vl_api_show_threads_reply_t_handler_json
1408   (vl_api_show_threads_reply_t * mp)
1409 {
1410   vat_main_t *vam = &vat_main;
1411   vat_json_node_t node;
1412   vl_api_thread_data_t *td;
1413   i32 retval = ntohl (mp->retval);
1414   int i, count = 0;
1415
1416   if (retval >= 0)
1417     count = ntohl (mp->count);
1418
1419   vat_json_init_object (&node);
1420   vat_json_object_add_int (&node, "retval", retval);
1421   vat_json_object_add_uint (&node, "count", count);
1422
1423   for (i = 0; i < count; i++)
1424     {
1425       td = &mp->thread_data[i];
1426       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1427       vat_json_object_add_string_copy (&node, "name", td->name);
1428       vat_json_object_add_string_copy (&node, "type", td->type);
1429       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1430       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1431       vat_json_object_add_int (&node, "core", ntohl (td->id));
1432       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1433     }
1434
1435   vat_json_print (vam->ofp, &node);
1436   vat_json_free (&node);
1437
1438   vam->retval = retval;
1439   vam->result_ready = 1;
1440 }
1441
1442 static int
1443 api_show_threads (vat_main_t * vam)
1444 {
1445   vl_api_show_threads_t *mp;
1446   int ret;
1447
1448   print (vam->ofp,
1449          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1450          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1451
1452   M (SHOW_THREADS, mp);
1453
1454   S (mp);
1455   W (ret);
1456   return ret;
1457 }
1458
1459 static void
1460 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1461 {
1462   u32 n_macs = ntohl (mp->n_macs);
1463   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1464           ntohl (mp->pid), mp->client_index, n_macs);
1465   int i;
1466   for (i = 0; i < n_macs; i++)
1467     {
1468       vl_api_mac_entry_t *mac = &mp->mac[i];
1469       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1470               i + 1, ntohl (mac->sw_if_index),
1471               format_ethernet_address, mac->mac_addr, mac->action);
1472       if (i == 1000)
1473         break;
1474     }
1475 }
1476
1477 static void
1478 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1479 {
1480   /* JSON output not supported */
1481 }
1482
1483 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1484 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1485
1486 /*
1487  * Special-case: build the bridge domain table, maintain
1488  * the next bd id vbl.
1489  */
1490 static void vl_api_bridge_domain_details_t_handler
1491   (vl_api_bridge_domain_details_t * mp)
1492 {
1493   vat_main_t *vam = &vat_main;
1494   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1495   int i;
1496
1497   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1498          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1499
1500   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1501          ntohl (mp->bd_id), mp->learn, mp->forward,
1502          mp->flood, ntohl (mp->bvi_sw_if_index),
1503          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1504
1505   if (n_sw_ifs)
1506     {
1507       vl_api_bridge_domain_sw_if_t *sw_ifs;
1508       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1509              "Interface Name");
1510
1511       sw_ifs = mp->sw_if_details;
1512       for (i = 0; i < n_sw_ifs; i++)
1513         {
1514           u8 *sw_if_name = 0;
1515           u32 sw_if_index;
1516           hash_pair_t *p;
1517
1518           sw_if_index = ntohl (sw_ifs->sw_if_index);
1519
1520           /* *INDENT-OFF* */
1521           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1522                              ({
1523                                if ((u32) p->value[0] == sw_if_index)
1524                                  {
1525                                    sw_if_name = (u8 *)(p->key);
1526                                    break;
1527                                  }
1528                              }));
1529           /* *INDENT-ON* */
1530           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1531                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1532                  "sw_if_index not found!");
1533
1534           sw_ifs++;
1535         }
1536     }
1537 }
1538
1539 static void vl_api_bridge_domain_details_t_handler_json
1540   (vl_api_bridge_domain_details_t * mp)
1541 {
1542   vat_main_t *vam = &vat_main;
1543   vat_json_node_t *node, *array = NULL;
1544   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1545
1546   if (VAT_JSON_ARRAY != vam->json_tree.type)
1547     {
1548       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1549       vat_json_init_array (&vam->json_tree);
1550     }
1551   node = vat_json_array_add (&vam->json_tree);
1552
1553   vat_json_init_object (node);
1554   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1555   vat_json_object_add_uint (node, "flood", mp->flood);
1556   vat_json_object_add_uint (node, "forward", mp->forward);
1557   vat_json_object_add_uint (node, "learn", mp->learn);
1558   vat_json_object_add_uint (node, "bvi_sw_if_index",
1559                             ntohl (mp->bvi_sw_if_index));
1560   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1561   array = vat_json_object_add (node, "sw_if");
1562   vat_json_init_array (array);
1563
1564
1565
1566   if (n_sw_ifs)
1567     {
1568       vl_api_bridge_domain_sw_if_t *sw_ifs;
1569       int i;
1570
1571       sw_ifs = mp->sw_if_details;
1572       for (i = 0; i < n_sw_ifs; i++)
1573         {
1574           node = vat_json_array_add (array);
1575           vat_json_init_object (node);
1576           vat_json_object_add_uint (node, "sw_if_index",
1577                                     ntohl (sw_ifs->sw_if_index));
1578           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1579           sw_ifs++;
1580         }
1581     }
1582 }
1583
1584 static void vl_api_control_ping_reply_t_handler
1585   (vl_api_control_ping_reply_t * mp)
1586 {
1587   vat_main_t *vam = &vat_main;
1588   i32 retval = ntohl (mp->retval);
1589   if (vam->async_mode)
1590     {
1591       vam->async_errors += (retval < 0);
1592     }
1593   else
1594     {
1595       vam->retval = retval;
1596       vam->result_ready = 1;
1597     }
1598   if (vam->socket_client_main)
1599     vam->socket_client_main->control_pings_outstanding--;
1600 }
1601
1602 static void vl_api_control_ping_reply_t_handler_json
1603   (vl_api_control_ping_reply_t * mp)
1604 {
1605   vat_main_t *vam = &vat_main;
1606   i32 retval = ntohl (mp->retval);
1607
1608   if (VAT_JSON_NONE != vam->json_tree.type)
1609     {
1610       vat_json_print (vam->ofp, &vam->json_tree);
1611       vat_json_free (&vam->json_tree);
1612       vam->json_tree.type = VAT_JSON_NONE;
1613     }
1614   else
1615     {
1616       /* just print [] */
1617       vat_json_init_array (&vam->json_tree);
1618       vat_json_print (vam->ofp, &vam->json_tree);
1619       vam->json_tree.type = VAT_JSON_NONE;
1620     }
1621
1622   vam->retval = retval;
1623   vam->result_ready = 1;
1624 }
1625
1626 static void
1627   vl_api_bridge_domain_set_mac_age_reply_t_handler
1628   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1629 {
1630   vat_main_t *vam = &vat_main;
1631   i32 retval = ntohl (mp->retval);
1632   if (vam->async_mode)
1633     {
1634       vam->async_errors += (retval < 0);
1635     }
1636   else
1637     {
1638       vam->retval = retval;
1639       vam->result_ready = 1;
1640     }
1641 }
1642
1643 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1644   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1645 {
1646   vat_main_t *vam = &vat_main;
1647   vat_json_node_t node;
1648
1649   vat_json_init_object (&node);
1650   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1651
1652   vat_json_print (vam->ofp, &node);
1653   vat_json_free (&node);
1654
1655   vam->retval = ntohl (mp->retval);
1656   vam->result_ready = 1;
1657 }
1658
1659 static void
1660 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1661 {
1662   vat_main_t *vam = &vat_main;
1663   i32 retval = ntohl (mp->retval);
1664   if (vam->async_mode)
1665     {
1666       vam->async_errors += (retval < 0);
1667     }
1668   else
1669     {
1670       vam->retval = retval;
1671       vam->result_ready = 1;
1672     }
1673 }
1674
1675 static void vl_api_l2_flags_reply_t_handler_json
1676   (vl_api_l2_flags_reply_t * mp)
1677 {
1678   vat_main_t *vam = &vat_main;
1679   vat_json_node_t node;
1680
1681   vat_json_init_object (&node);
1682   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1683   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1684                             ntohl (mp->resulting_feature_bitmap));
1685
1686   vat_json_print (vam->ofp, &node);
1687   vat_json_free (&node);
1688
1689   vam->retval = ntohl (mp->retval);
1690   vam->result_ready = 1;
1691 }
1692
1693 static void vl_api_bridge_flags_reply_t_handler
1694   (vl_api_bridge_flags_reply_t * mp)
1695 {
1696   vat_main_t *vam = &vat_main;
1697   i32 retval = ntohl (mp->retval);
1698   if (vam->async_mode)
1699     {
1700       vam->async_errors += (retval < 0);
1701     }
1702   else
1703     {
1704       vam->retval = retval;
1705       vam->result_ready = 1;
1706     }
1707 }
1708
1709 static void vl_api_bridge_flags_reply_t_handler_json
1710   (vl_api_bridge_flags_reply_t * mp)
1711 {
1712   vat_main_t *vam = &vat_main;
1713   vat_json_node_t node;
1714
1715   vat_json_init_object (&node);
1716   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1717   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1718                             ntohl (mp->resulting_feature_bitmap));
1719
1720   vat_json_print (vam->ofp, &node);
1721   vat_json_free (&node);
1722
1723   vam->retval = ntohl (mp->retval);
1724   vam->result_ready = 1;
1725 }
1726
1727 static void
1728 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1729 {
1730   vat_main_t *vam = &vat_main;
1731   i32 retval = ntohl (mp->retval);
1732   if (vam->async_mode)
1733     {
1734       vam->async_errors += (retval < 0);
1735     }
1736   else
1737     {
1738       vam->retval = retval;
1739       vam->sw_if_index = ntohl (mp->sw_if_index);
1740       vam->result_ready = 1;
1741     }
1742
1743 }
1744
1745 static void vl_api_tap_create_v2_reply_t_handler_json
1746   (vl_api_tap_create_v2_reply_t * mp)
1747 {
1748   vat_main_t *vam = &vat_main;
1749   vat_json_node_t node;
1750
1751   vat_json_init_object (&node);
1752   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1753   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1754
1755   vat_json_print (vam->ofp, &node);
1756   vat_json_free (&node);
1757
1758   vam->retval = ntohl (mp->retval);
1759   vam->result_ready = 1;
1760
1761 }
1762
1763 static void
1764 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1765 {
1766   vat_main_t *vam = &vat_main;
1767   i32 retval = ntohl (mp->retval);
1768   if (vam->async_mode)
1769     {
1770       vam->async_errors += (retval < 0);
1771     }
1772   else
1773     {
1774       vam->retval = retval;
1775       vam->result_ready = 1;
1776     }
1777 }
1778
1779 static void vl_api_tap_delete_v2_reply_t_handler_json
1780   (vl_api_tap_delete_v2_reply_t * mp)
1781 {
1782   vat_main_t *vam = &vat_main;
1783   vat_json_node_t node;
1784
1785   vat_json_init_object (&node);
1786   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1787
1788   vat_json_print (vam->ofp, &node);
1789   vat_json_free (&node);
1790
1791   vam->retval = ntohl (mp->retval);
1792   vam->result_ready = 1;
1793 }
1794
1795 static void
1796 vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1797                                           mp)
1798 {
1799   vat_main_t *vam = &vat_main;
1800   i32 retval = ntohl (mp->retval);
1801   if (vam->async_mode)
1802     {
1803       vam->async_errors += (retval < 0);
1804     }
1805   else
1806     {
1807       vam->retval = retval;
1808       vam->sw_if_index = ntohl (mp->sw_if_index);
1809       vam->result_ready = 1;
1810     }
1811 }
1812
1813 static void vl_api_virtio_pci_create_reply_t_handler_json
1814   (vl_api_virtio_pci_create_reply_t * mp)
1815 {
1816   vat_main_t *vam = &vat_main;
1817   vat_json_node_t node;
1818
1819   vat_json_init_object (&node);
1820   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1821   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1822
1823   vat_json_print (vam->ofp, &node);
1824   vat_json_free (&node);
1825
1826   vam->retval = ntohl (mp->retval);
1827   vam->result_ready = 1;
1828
1829 }
1830
1831 static void
1832 vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1833                                           mp)
1834 {
1835   vat_main_t *vam = &vat_main;
1836   i32 retval = ntohl (mp->retval);
1837   if (vam->async_mode)
1838     {
1839       vam->async_errors += (retval < 0);
1840     }
1841   else
1842     {
1843       vam->retval = retval;
1844       vam->result_ready = 1;
1845     }
1846 }
1847
1848 static void vl_api_virtio_pci_delete_reply_t_handler_json
1849   (vl_api_virtio_pci_delete_reply_t * mp)
1850 {
1851   vat_main_t *vam = &vat_main;
1852   vat_json_node_t node;
1853
1854   vat_json_init_object (&node);
1855   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1856
1857   vat_json_print (vam->ofp, &node);
1858   vat_json_free (&node);
1859
1860   vam->retval = ntohl (mp->retval);
1861   vam->result_ready = 1;
1862 }
1863
1864 static void
1865 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1866 {
1867   vat_main_t *vam = &vat_main;
1868   i32 retval = ntohl (mp->retval);
1869
1870   if (vam->async_mode)
1871     {
1872       vam->async_errors += (retval < 0);
1873     }
1874   else
1875     {
1876       vam->retval = retval;
1877       vam->sw_if_index = ntohl (mp->sw_if_index);
1878       vam->result_ready = 1;
1879     }
1880 }
1881
1882 static void vl_api_bond_create_reply_t_handler_json
1883   (vl_api_bond_create_reply_t * mp)
1884 {
1885   vat_main_t *vam = &vat_main;
1886   vat_json_node_t node;
1887
1888   vat_json_init_object (&node);
1889   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1890   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1891
1892   vat_json_print (vam->ofp, &node);
1893   vat_json_free (&node);
1894
1895   vam->retval = ntohl (mp->retval);
1896   vam->result_ready = 1;
1897 }
1898
1899 static void
1900 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1901 {
1902   vat_main_t *vam = &vat_main;
1903   i32 retval = ntohl (mp->retval);
1904
1905   if (vam->async_mode)
1906     {
1907       vam->async_errors += (retval < 0);
1908     }
1909   else
1910     {
1911       vam->retval = retval;
1912       vam->result_ready = 1;
1913     }
1914 }
1915
1916 static void vl_api_bond_delete_reply_t_handler_json
1917   (vl_api_bond_delete_reply_t * mp)
1918 {
1919   vat_main_t *vam = &vat_main;
1920   vat_json_node_t node;
1921
1922   vat_json_init_object (&node);
1923   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1924
1925   vat_json_print (vam->ofp, &node);
1926   vat_json_free (&node);
1927
1928   vam->retval = ntohl (mp->retval);
1929   vam->result_ready = 1;
1930 }
1931
1932 static void
1933 vl_api_bond_add_member_reply_t_handler (vl_api_bond_add_member_reply_t * mp)
1934 {
1935   vat_main_t *vam = &vat_main;
1936   i32 retval = ntohl (mp->retval);
1937
1938   if (vam->async_mode)
1939     {
1940       vam->async_errors += (retval < 0);
1941     }
1942   else
1943     {
1944       vam->retval = retval;
1945       vam->result_ready = 1;
1946     }
1947 }
1948
1949 static void vl_api_bond_add_member_reply_t_handler_json
1950   (vl_api_bond_add_member_reply_t * mp)
1951 {
1952   vat_main_t *vam = &vat_main;
1953   vat_json_node_t node;
1954
1955   vat_json_init_object (&node);
1956   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1957
1958   vat_json_print (vam->ofp, &node);
1959   vat_json_free (&node);
1960
1961   vam->retval = ntohl (mp->retval);
1962   vam->result_ready = 1;
1963 }
1964
1965 static void
1966 vl_api_bond_detach_member_reply_t_handler (vl_api_bond_detach_member_reply_t *
1967                                            mp)
1968 {
1969   vat_main_t *vam = &vat_main;
1970   i32 retval = ntohl (mp->retval);
1971
1972   if (vam->async_mode)
1973     {
1974       vam->async_errors += (retval < 0);
1975     }
1976   else
1977     {
1978       vam->retval = retval;
1979       vam->result_ready = 1;
1980     }
1981 }
1982
1983 static void vl_api_bond_detach_member_reply_t_handler_json
1984   (vl_api_bond_detach_member_reply_t * mp)
1985 {
1986   vat_main_t *vam = &vat_main;
1987   vat_json_node_t node;
1988
1989   vat_json_init_object (&node);
1990   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1991
1992   vat_json_print (vam->ofp, &node);
1993   vat_json_free (&node);
1994
1995   vam->retval = ntohl (mp->retval);
1996   vam->result_ready = 1;
1997 }
1998
1999 static int
2000 api_sw_interface_set_bond_weight (vat_main_t * vam)
2001 {
2002   unformat_input_t *i = vam->input;
2003   vl_api_sw_interface_set_bond_weight_t *mp;
2004   u32 sw_if_index = ~0;
2005   u32 weight = 0;
2006   u8 weight_enter = 0;
2007   int ret;
2008
2009   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2010     {
2011       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2012         ;
2013       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2014         ;
2015       else if (unformat (i, "weight %u", &weight))
2016         weight_enter = 1;
2017       else
2018         break;
2019     }
2020
2021   if (sw_if_index == ~0)
2022     {
2023       errmsg ("missing interface name or sw_if_index");
2024       return -99;
2025     }
2026   if (weight_enter == 0)
2027     {
2028       errmsg ("missing valid weight");
2029       return -99;
2030     }
2031
2032   /* Construct the API message */
2033   M (SW_INTERFACE_SET_BOND_WEIGHT, mp);
2034   mp->sw_if_index = ntohl (sw_if_index);
2035   mp->weight = ntohl (weight);
2036
2037   S (mp);
2038   W (ret);
2039   return ret;
2040 }
2041
2042 static void vl_api_sw_bond_interface_details_t_handler
2043   (vl_api_sw_bond_interface_details_t * mp)
2044 {
2045   vat_main_t *vam = &vat_main;
2046
2047   print (vam->ofp,
2048          "%-16s %-12d %-12U %-13U %-14u %-14u",
2049          mp->interface_name, ntohl (mp->sw_if_index),
2050          format_bond_mode, ntohl (mp->mode), format_bond_load_balance,
2051          ntohl (mp->lb), ntohl (mp->active_members), ntohl (mp->members));
2052 }
2053
2054 static void vl_api_sw_bond_interface_details_t_handler_json
2055   (vl_api_sw_bond_interface_details_t * mp)
2056 {
2057   vat_main_t *vam = &vat_main;
2058   vat_json_node_t *node = NULL;
2059
2060   if (VAT_JSON_ARRAY != vam->json_tree.type)
2061     {
2062       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2063       vat_json_init_array (&vam->json_tree);
2064     }
2065   node = vat_json_array_add (&vam->json_tree);
2066
2067   vat_json_init_object (node);
2068   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2069   vat_json_object_add_string_copy (node, "interface_name",
2070                                    mp->interface_name);
2071   vat_json_object_add_uint (node, "mode", ntohl (mp->mode));
2072   vat_json_object_add_uint (node, "load_balance", ntohl (mp->lb));
2073   vat_json_object_add_uint (node, "active_members",
2074                             ntohl (mp->active_members));
2075   vat_json_object_add_uint (node, "members", ntohl (mp->members));
2076 }
2077
2078 static int
2079 api_sw_bond_interface_dump (vat_main_t * vam)
2080 {
2081   unformat_input_t *i = vam->input;
2082   vl_api_sw_bond_interface_dump_t *mp;
2083   vl_api_control_ping_t *mp_ping;
2084   int ret;
2085   u32 sw_if_index = ~0;
2086
2087   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2088     {
2089       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2090         ;
2091       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2092         ;
2093       else
2094         break;
2095     }
2096
2097   print (vam->ofp,
2098          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2099          "interface name", "sw_if_index", "mode", "load balance",
2100          "active members", "members");
2101
2102   /* Get list of bond interfaces */
2103   M (SW_BOND_INTERFACE_DUMP, mp);
2104   mp->sw_if_index = ntohl (sw_if_index);
2105   S (mp);
2106
2107   /* Use a control ping for synchronization */
2108   MPING (CONTROL_PING, mp_ping);
2109   S (mp_ping);
2110
2111   W (ret);
2112   return ret;
2113 }
2114
2115 static void vl_api_sw_member_interface_details_t_handler
2116   (vl_api_sw_member_interface_details_t * mp)
2117 {
2118   vat_main_t *vam = &vat_main;
2119
2120   print (vam->ofp,
2121          "%-25s %-12d %-7d %-12d %-10d %-10d", mp->interface_name,
2122          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout,
2123          ntohl (mp->weight), mp->is_local_numa);
2124 }
2125
2126 static void vl_api_sw_member_interface_details_t_handler_json
2127   (vl_api_sw_member_interface_details_t * mp)
2128 {
2129   vat_main_t *vam = &vat_main;
2130   vat_json_node_t *node = NULL;
2131
2132   if (VAT_JSON_ARRAY != vam->json_tree.type)
2133     {
2134       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2135       vat_json_init_array (&vam->json_tree);
2136     }
2137   node = vat_json_array_add (&vam->json_tree);
2138
2139   vat_json_init_object (node);
2140   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2141   vat_json_object_add_string_copy (node, "interface_name",
2142                                    mp->interface_name);
2143   vat_json_object_add_uint (node, "passive", mp->is_passive);
2144   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2145   vat_json_object_add_uint (node, "weight", ntohl (mp->weight));
2146   vat_json_object_add_uint (node, "is_local_numa", mp->is_local_numa);
2147 }
2148
2149 static int
2150 api_sw_member_interface_dump (vat_main_t * vam)
2151 {
2152   unformat_input_t *i = vam->input;
2153   vl_api_sw_member_interface_dump_t *mp;
2154   vl_api_control_ping_t *mp_ping;
2155   u32 sw_if_index = ~0;
2156   u8 sw_if_index_set = 0;
2157   int ret;
2158
2159   /* Parse args required to build the message */
2160   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2161     {
2162       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2163         sw_if_index_set = 1;
2164       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2165         sw_if_index_set = 1;
2166       else
2167         break;
2168     }
2169
2170   if (sw_if_index_set == 0)
2171     {
2172       errmsg ("missing vpp interface name. ");
2173       return -99;
2174     }
2175
2176   print (vam->ofp,
2177          "\n%-25s %-12s %-7s %-12s %-10s %-10s",
2178          "member interface name", "sw_if_index", "passive", "long_timeout",
2179          "weight", "local numa");
2180
2181   /* Get list of bond interfaces */
2182   M (SW_MEMBER_INTERFACE_DUMP, mp);
2183   mp->sw_if_index = ntohl (sw_if_index);
2184   S (mp);
2185
2186   /* Use a control ping for synchronization */
2187   MPING (CONTROL_PING, mp_ping);
2188   S (mp_ping);
2189
2190   W (ret);
2191   return ret;
2192 }
2193
2194 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2195   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2196 {
2197   vat_main_t *vam = &vat_main;
2198   i32 retval = ntohl (mp->retval);
2199   if (vam->async_mode)
2200     {
2201       vam->async_errors += (retval < 0);
2202     }
2203   else
2204     {
2205       vam->retval = retval;
2206       vam->sw_if_index = ntohl (mp->sw_if_index);
2207       vam->result_ready = 1;
2208     }
2209   vam->regenerate_interface_table = 1;
2210 }
2211
2212 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2213   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2214 {
2215   vat_main_t *vam = &vat_main;
2216   vat_json_node_t node;
2217
2218   vat_json_init_object (&node);
2219   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2220   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2221                             ntohl (mp->sw_if_index));
2222
2223   vat_json_print (vam->ofp, &node);
2224   vat_json_free (&node);
2225
2226   vam->retval = ntohl (mp->retval);
2227   vam->result_ready = 1;
2228 }
2229
2230 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2231   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2232 {
2233   vat_main_t *vam = &vat_main;
2234   i32 retval = ntohl (mp->retval);
2235   if (vam->async_mode)
2236     {
2237       vam->async_errors += (retval < 0);
2238     }
2239   else
2240     {
2241       vam->retval = retval;
2242       vam->sw_if_index = ntohl (mp->sw_if_index);
2243       vam->result_ready = 1;
2244     }
2245 }
2246
2247 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2248   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2249 {
2250   vat_main_t *vam = &vat_main;
2251   vat_json_node_t node;
2252
2253   vat_json_init_object (&node);
2254   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2255   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2256
2257   vat_json_print (vam->ofp, &node);
2258   vat_json_free (&node);
2259
2260   vam->retval = ntohl (mp->retval);
2261   vam->result_ready = 1;
2262 }
2263
2264 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2265   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2266 {
2267   vat_main_t *vam = &vat_main;
2268   i32 retval = ntohl (mp->retval);
2269   if (vam->async_mode)
2270     {
2271       vam->async_errors += (retval < 0);
2272     }
2273   else
2274     {
2275       vam->retval = retval;
2276       vam->result_ready = 1;
2277     }
2278 }
2279
2280 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2281   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2282 {
2283   vat_main_t *vam = &vat_main;
2284   vat_json_node_t node;
2285
2286   vat_json_init_object (&node);
2287   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2288   vat_json_object_add_uint (&node, "fwd_entry_index",
2289                             clib_net_to_host_u32 (mp->fwd_entry_index));
2290
2291   vat_json_print (vam->ofp, &node);
2292   vat_json_free (&node);
2293
2294   vam->retval = ntohl (mp->retval);
2295   vam->result_ready = 1;
2296 }
2297
2298 u8 *
2299 format_lisp_transport_protocol (u8 * s, va_list * args)
2300 {
2301   u32 proto = va_arg (*args, u32);
2302
2303   switch (proto)
2304     {
2305     case 1:
2306       return format (s, "udp");
2307     case 2:
2308       return format (s, "api");
2309     default:
2310       return 0;
2311     }
2312   return 0;
2313 }
2314
2315 static void vl_api_one_get_transport_protocol_reply_t_handler
2316   (vl_api_one_get_transport_protocol_reply_t * mp)
2317 {
2318   vat_main_t *vam = &vat_main;
2319   i32 retval = ntohl (mp->retval);
2320   if (vam->async_mode)
2321     {
2322       vam->async_errors += (retval < 0);
2323     }
2324   else
2325     {
2326       u32 proto = mp->protocol;
2327       print (vam->ofp, "Transport protocol: %U",
2328              format_lisp_transport_protocol, proto);
2329       vam->retval = retval;
2330       vam->result_ready = 1;
2331     }
2332 }
2333
2334 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2335   (vl_api_one_get_transport_protocol_reply_t * mp)
2336 {
2337   vat_main_t *vam = &vat_main;
2338   vat_json_node_t node;
2339   u8 *s;
2340
2341   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2342   vec_add1 (s, 0);
2343
2344   vat_json_init_object (&node);
2345   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2346   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2347
2348   vec_free (s);
2349   vat_json_print (vam->ofp, &node);
2350   vat_json_free (&node);
2351
2352   vam->retval = ntohl (mp->retval);
2353   vam->result_ready = 1;
2354 }
2355
2356 static void vl_api_one_add_del_locator_set_reply_t_handler
2357   (vl_api_one_add_del_locator_set_reply_t * mp)
2358 {
2359   vat_main_t *vam = &vat_main;
2360   i32 retval = ntohl (mp->retval);
2361   if (vam->async_mode)
2362     {
2363       vam->async_errors += (retval < 0);
2364     }
2365   else
2366     {
2367       vam->retval = retval;
2368       vam->result_ready = 1;
2369     }
2370 }
2371
2372 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2373   (vl_api_one_add_del_locator_set_reply_t * mp)
2374 {
2375   vat_main_t *vam = &vat_main;
2376   vat_json_node_t node;
2377
2378   vat_json_init_object (&node);
2379   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2380   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2381
2382   vat_json_print (vam->ofp, &node);
2383   vat_json_free (&node);
2384
2385   vam->retval = ntohl (mp->retval);
2386   vam->result_ready = 1;
2387 }
2388
2389 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2390   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2391 {
2392   vat_main_t *vam = &vat_main;
2393   i32 retval = ntohl (mp->retval);
2394   if (vam->async_mode)
2395     {
2396       vam->async_errors += (retval < 0);
2397     }
2398   else
2399     {
2400       vam->retval = retval;
2401       vam->sw_if_index = ntohl (mp->sw_if_index);
2402       vam->result_ready = 1;
2403     }
2404   vam->regenerate_interface_table = 1;
2405 }
2406
2407 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2408   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2409 {
2410   vat_main_t *vam = &vat_main;
2411   vat_json_node_t node;
2412
2413   vat_json_init_object (&node);
2414   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2415   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2416
2417   vat_json_print (vam->ofp, &node);
2418   vat_json_free (&node);
2419
2420   vam->retval = ntohl (mp->retval);
2421   vam->result_ready = 1;
2422 }
2423
2424 static void vl_api_vxlan_offload_rx_reply_t_handler
2425   (vl_api_vxlan_offload_rx_reply_t * mp)
2426 {
2427   vat_main_t *vam = &vat_main;
2428   i32 retval = ntohl (mp->retval);
2429   if (vam->async_mode)
2430     {
2431       vam->async_errors += (retval < 0);
2432     }
2433   else
2434     {
2435       vam->retval = retval;
2436       vam->result_ready = 1;
2437     }
2438 }
2439
2440 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2441   (vl_api_vxlan_offload_rx_reply_t * mp)
2442 {
2443   vat_main_t *vam = &vat_main;
2444   vat_json_node_t node;
2445
2446   vat_json_init_object (&node);
2447   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2448
2449   vat_json_print (vam->ofp, &node);
2450   vat_json_free (&node);
2451
2452   vam->retval = ntohl (mp->retval);
2453   vam->result_ready = 1;
2454 }
2455
2456 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2457   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2458 {
2459   vat_main_t *vam = &vat_main;
2460   i32 retval = ntohl (mp->retval);
2461   if (vam->async_mode)
2462     {
2463       vam->async_errors += (retval < 0);
2464     }
2465   else
2466     {
2467       vam->retval = retval;
2468       vam->sw_if_index = ntohl (mp->sw_if_index);
2469       vam->result_ready = 1;
2470     }
2471 }
2472
2473 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2474   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2475 {
2476   vat_main_t *vam = &vat_main;
2477   vat_json_node_t node;
2478
2479   vat_json_init_object (&node);
2480   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2481   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2482
2483   vat_json_print (vam->ofp, &node);
2484   vat_json_free (&node);
2485
2486   vam->retval = ntohl (mp->retval);
2487   vam->result_ready = 1;
2488 }
2489
2490 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2491   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2492 {
2493   vat_main_t *vam = &vat_main;
2494   i32 retval = ntohl (mp->retval);
2495   if (vam->async_mode)
2496     {
2497       vam->async_errors += (retval < 0);
2498     }
2499   else
2500     {
2501       vam->retval = retval;
2502       vam->sw_if_index = ntohl (mp->sw_if_index);
2503       vam->result_ready = 1;
2504     }
2505   vam->regenerate_interface_table = 1;
2506 }
2507
2508 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2509   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2510 {
2511   vat_main_t *vam = &vat_main;
2512   vat_json_node_t node;
2513
2514   vat_json_init_object (&node);
2515   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2516   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2517
2518   vat_json_print (vam->ofp, &node);
2519   vat_json_free (&node);
2520
2521   vam->retval = ntohl (mp->retval);
2522   vam->result_ready = 1;
2523 }
2524
2525 static void vl_api_gre_tunnel_add_del_reply_t_handler
2526   (vl_api_gre_tunnel_add_del_reply_t * mp)
2527 {
2528   vat_main_t *vam = &vat_main;
2529   i32 retval = ntohl (mp->retval);
2530   if (vam->async_mode)
2531     {
2532       vam->async_errors += (retval < 0);
2533     }
2534   else
2535     {
2536       vam->retval = retval;
2537       vam->sw_if_index = ntohl (mp->sw_if_index);
2538       vam->result_ready = 1;
2539     }
2540 }
2541
2542 static void vl_api_gre_tunnel_add_del_reply_t_handler_json
2543   (vl_api_gre_tunnel_add_del_reply_t * mp)
2544 {
2545   vat_main_t *vam = &vat_main;
2546   vat_json_node_t node;
2547
2548   vat_json_init_object (&node);
2549   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2550   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2551
2552   vat_json_print (vam->ofp, &node);
2553   vat_json_free (&node);
2554
2555   vam->retval = ntohl (mp->retval);
2556   vam->result_ready = 1;
2557 }
2558
2559 static void vl_api_create_vhost_user_if_reply_t_handler
2560   (vl_api_create_vhost_user_if_reply_t * mp)
2561 {
2562   vat_main_t *vam = &vat_main;
2563   i32 retval = ntohl (mp->retval);
2564   if (vam->async_mode)
2565     {
2566       vam->async_errors += (retval < 0);
2567     }
2568   else
2569     {
2570       vam->retval = retval;
2571       vam->sw_if_index = ntohl (mp->sw_if_index);
2572       vam->result_ready = 1;
2573     }
2574   vam->regenerate_interface_table = 1;
2575 }
2576
2577 static void vl_api_create_vhost_user_if_reply_t_handler_json
2578   (vl_api_create_vhost_user_if_reply_t * mp)
2579 {
2580   vat_main_t *vam = &vat_main;
2581   vat_json_node_t node;
2582
2583   vat_json_init_object (&node);
2584   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2585   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2586
2587   vat_json_print (vam->ofp, &node);
2588   vat_json_free (&node);
2589
2590   vam->retval = ntohl (mp->retval);
2591   vam->result_ready = 1;
2592 }
2593
2594 static void vl_api_ip_address_details_t_handler
2595   (vl_api_ip_address_details_t * mp)
2596 {
2597   vat_main_t *vam = &vat_main;
2598   static ip_address_details_t empty_ip_address_details = { {0} };
2599   ip_address_details_t *address = NULL;
2600   ip_details_t *current_ip_details = NULL;
2601   ip_details_t *details = NULL;
2602
2603   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2604
2605   if (!details || vam->current_sw_if_index >= vec_len (details)
2606       || !details[vam->current_sw_if_index].present)
2607     {
2608       errmsg ("ip address details arrived but not stored");
2609       errmsg ("ip_dump should be called first");
2610       return;
2611     }
2612
2613   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2614
2615 #define addresses (current_ip_details->addr)
2616
2617   vec_validate_init_empty (addresses, vec_len (addresses),
2618                            empty_ip_address_details);
2619
2620   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2621
2622   clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
2623   address->prefix_length = mp->prefix.len;
2624 #undef addresses
2625 }
2626
2627 static void vl_api_ip_address_details_t_handler_json
2628   (vl_api_ip_address_details_t * mp)
2629 {
2630   vat_main_t *vam = &vat_main;
2631   vat_json_node_t *node = NULL;
2632
2633   if (VAT_JSON_ARRAY != vam->json_tree.type)
2634     {
2635       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2636       vat_json_init_array (&vam->json_tree);
2637     }
2638   node = vat_json_array_add (&vam->json_tree);
2639
2640   vat_json_init_object (node);
2641   vat_json_object_add_prefix (node, &mp->prefix);
2642 }
2643
2644 static void
2645 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2646 {
2647   vat_main_t *vam = &vat_main;
2648   static ip_details_t empty_ip_details = { 0 };
2649   ip_details_t *ip = NULL;
2650   u32 sw_if_index = ~0;
2651
2652   sw_if_index = ntohl (mp->sw_if_index);
2653
2654   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2655                            sw_if_index, empty_ip_details);
2656
2657   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2658                          sw_if_index);
2659
2660   ip->present = 1;
2661 }
2662
2663 static void
2664 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2665 {
2666   vat_main_t *vam = &vat_main;
2667
2668   if (VAT_JSON_ARRAY != vam->json_tree.type)
2669     {
2670       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2671       vat_json_init_array (&vam->json_tree);
2672     }
2673   vat_json_array_add_uint (&vam->json_tree,
2674                            clib_net_to_host_u32 (mp->sw_if_index));
2675 }
2676
2677 static void vl_api_get_first_msg_id_reply_t_handler
2678   (vl_api_get_first_msg_id_reply_t * mp)
2679 {
2680   vat_main_t *vam = &vat_main;
2681   i32 retval = ntohl (mp->retval);
2682
2683   if (vam->async_mode)
2684     {
2685       vam->async_errors += (retval < 0);
2686     }
2687   else
2688     {
2689       vam->retval = retval;
2690       vam->result_ready = 1;
2691     }
2692   if (retval >= 0)
2693     {
2694       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2695     }
2696 }
2697
2698 static void vl_api_get_first_msg_id_reply_t_handler_json
2699   (vl_api_get_first_msg_id_reply_t * mp)
2700 {
2701   vat_main_t *vam = &vat_main;
2702   vat_json_node_t node;
2703
2704   vat_json_init_object (&node);
2705   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2706   vat_json_object_add_uint (&node, "first_msg_id",
2707                             (uint) ntohs (mp->first_msg_id));
2708
2709   vat_json_print (vam->ofp, &node);
2710   vat_json_free (&node);
2711
2712   vam->retval = ntohl (mp->retval);
2713   vam->result_ready = 1;
2714 }
2715
2716 static void vl_api_get_node_graph_reply_t_handler
2717   (vl_api_get_node_graph_reply_t * mp)
2718 {
2719   vat_main_t *vam = &vat_main;
2720   i32 retval = ntohl (mp->retval);
2721   u8 *pvt_copy, *reply;
2722   void *oldheap;
2723   vlib_node_t *node;
2724   int i;
2725
2726   if (vam->async_mode)
2727     {
2728       vam->async_errors += (retval < 0);
2729     }
2730   else
2731     {
2732       vam->retval = retval;
2733       vam->result_ready = 1;
2734     }
2735
2736   /* "Should never happen..." */
2737   if (retval != 0)
2738     return;
2739
2740   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2741   pvt_copy = vec_dup (reply);
2742
2743   /* Toss the shared-memory original... */
2744   oldheap = vl_msg_push_heap ();
2745
2746   vec_free (reply);
2747
2748   vl_msg_pop_heap (oldheap);
2749
2750   if (vam->graph_nodes)
2751     {
2752       hash_free (vam->graph_node_index_by_name);
2753
2754       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2755         {
2756           node = vam->graph_nodes[0][i];
2757           vec_free (node->name);
2758           vec_free (node->next_nodes);
2759           vec_free (node);
2760         }
2761       vec_free (vam->graph_nodes[0]);
2762       vec_free (vam->graph_nodes);
2763     }
2764
2765   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2766   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2767   vec_free (pvt_copy);
2768
2769   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2770     {
2771       node = vam->graph_nodes[0][i];
2772       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2773     }
2774 }
2775
2776 static void vl_api_get_node_graph_reply_t_handler_json
2777   (vl_api_get_node_graph_reply_t * mp)
2778 {
2779   vat_main_t *vam = &vat_main;
2780   void *oldheap;
2781   vat_json_node_t node;
2782   u8 *reply;
2783
2784   /* $$$$ make this real? */
2785   vat_json_init_object (&node);
2786   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2787   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2788
2789   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2790
2791   /* Toss the shared-memory original... */
2792   oldheap = vl_msg_push_heap ();
2793
2794   vec_free (reply);
2795
2796   vl_msg_pop_heap (oldheap);
2797
2798   vat_json_print (vam->ofp, &node);
2799   vat_json_free (&node);
2800
2801   vam->retval = ntohl (mp->retval);
2802   vam->result_ready = 1;
2803 }
2804
2805 static void
2806 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2807 {
2808   vat_main_t *vam = &vat_main;
2809   u8 *s = 0;
2810
2811   if (mp->local)
2812     {
2813       s = format (s, "%=16d%=16d%=16d",
2814                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2815     }
2816   else
2817     {
2818       s = format (s, "%=16U%=16d%=16d",
2819                   format_ip46_address,
2820                   mp->ip_address, mp->priority, mp->weight);
2821     }
2822
2823   print (vam->ofp, "%v", s);
2824   vec_free (s);
2825 }
2826
2827 static void
2828 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2829 {
2830   vat_main_t *vam = &vat_main;
2831   vat_json_node_t *node = NULL;
2832   struct in6_addr ip6;
2833   struct in_addr ip4;
2834
2835   if (VAT_JSON_ARRAY != vam->json_tree.type)
2836     {
2837       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2838       vat_json_init_array (&vam->json_tree);
2839     }
2840   node = vat_json_array_add (&vam->json_tree);
2841   vat_json_init_object (node);
2842
2843   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2844   vat_json_object_add_uint (node, "priority", mp->priority);
2845   vat_json_object_add_uint (node, "weight", mp->weight);
2846
2847   if (mp->local)
2848     vat_json_object_add_uint (node, "sw_if_index",
2849                               clib_net_to_host_u32 (mp->sw_if_index));
2850   else
2851     {
2852       if (mp->ip_address.af)
2853         {
2854           clib_memcpy (&ip6, mp->ip_address.un.ip6, sizeof (ip6));
2855           vat_json_object_add_ip6 (node, "address", ip6);
2856         }
2857       else
2858         {
2859           clib_memcpy (&ip4, mp->ip_address.un.ip4, sizeof (ip4));
2860           vat_json_object_add_ip4 (node, "address", ip4);
2861         }
2862     }
2863 }
2864
2865 static void
2866 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2867                                           mp)
2868 {
2869   vat_main_t *vam = &vat_main;
2870   u8 *ls_name = 0;
2871
2872   ls_name = format (0, "%s", mp->ls_name);
2873
2874   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2875          ls_name);
2876   vec_free (ls_name);
2877 }
2878
2879 static void
2880   vl_api_one_locator_set_details_t_handler_json
2881   (vl_api_one_locator_set_details_t * mp)
2882 {
2883   vat_main_t *vam = &vat_main;
2884   vat_json_node_t *node = 0;
2885   u8 *ls_name = 0;
2886
2887   ls_name = format (0, "%s", mp->ls_name);
2888   vec_add1 (ls_name, 0);
2889
2890   if (VAT_JSON_ARRAY != vam->json_tree.type)
2891     {
2892       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2893       vat_json_init_array (&vam->json_tree);
2894     }
2895   node = vat_json_array_add (&vam->json_tree);
2896
2897   vat_json_init_object (node);
2898   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2899   vat_json_object_add_uint (node, "ls_index",
2900                             clib_net_to_host_u32 (mp->ls_index));
2901   vec_free (ls_name);
2902 }
2903
2904 typedef struct
2905 {
2906   u32 spi;
2907   u8 si;
2908 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2909
2910 uword
2911 unformat_nsh_address (unformat_input_t * input, va_list * args)
2912 {
2913   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2914   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2915 }
2916
2917 static u8 *
2918 format_nsh_address_vat (u8 * s, va_list * args)
2919 {
2920   nsh_t *a = va_arg (*args, nsh_t *);
2921   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2922 }
2923
2924 static u8 *
2925 format_lisp_flat_eid (u8 * s, va_list * args)
2926 {
2927   vl_api_eid_t *eid = va_arg (*args, vl_api_eid_t *);
2928
2929   switch (eid->type)
2930     {
2931     case EID_TYPE_API_PREFIX:
2932       if (eid->address.prefix.address.af)
2933         return format (s, "%U/%d", format_ip6_address,
2934                        eid->address.prefix.address.un.ip6,
2935                        eid->address.prefix.len);
2936       return format (s, "%U/%d", format_ip4_address,
2937                      eid->address.prefix.address.un.ip4,
2938                      eid->address.prefix.len);
2939     case EID_TYPE_API_MAC:
2940       return format (s, "%U", format_ethernet_address, eid->address.mac);
2941     case EID_TYPE_API_NSH:
2942       return format (s, "%U", format_nsh_address_vat, eid->address.nsh);
2943     }
2944   return 0;
2945 }
2946
2947 static u8 *
2948 format_lisp_eid_vat (u8 * s, va_list * args)
2949 {
2950   vl_api_eid_t *deid = va_arg (*args, vl_api_eid_t *);
2951   vl_api_eid_t *seid = va_arg (*args, vl_api_eid_t *);
2952   u8 is_src_dst = (u8) va_arg (*args, int);
2953
2954   if (is_src_dst)
2955     s = format (s, "%U|", format_lisp_flat_eid, seid);
2956
2957   s = format (s, "%U", format_lisp_flat_eid, deid);
2958
2959   return s;
2960 }
2961
2962 static void
2963 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2964 {
2965   vat_main_t *vam = &vat_main;
2966   u8 *s = 0, *eid = 0;
2967
2968   if (~0 == mp->locator_set_index)
2969     s = format (0, "action: %d", mp->action);
2970   else
2971     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2972
2973   eid = format (0, "%U", format_lisp_eid_vat,
2974                 &mp->deid, &mp->seid, mp->is_src_dst);
2975   vec_add1 (eid, 0);
2976
2977   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2978          clib_net_to_host_u32 (mp->vni),
2979          eid,
2980          mp->is_local ? "local" : "remote",
2981          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2982          clib_net_to_host_u16 (mp->key.id), mp->key.key);
2983
2984   vec_free (s);
2985   vec_free (eid);
2986 }
2987
2988 static void
2989 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2990                                              * mp)
2991 {
2992   vat_main_t *vam = &vat_main;
2993   vat_json_node_t *node = 0;
2994   u8 *eid = 0;
2995
2996   if (VAT_JSON_ARRAY != vam->json_tree.type)
2997     {
2998       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2999       vat_json_init_array (&vam->json_tree);
3000     }
3001   node = vat_json_array_add (&vam->json_tree);
3002
3003   vat_json_init_object (node);
3004   if (~0 == mp->locator_set_index)
3005     vat_json_object_add_uint (node, "action", mp->action);
3006   else
3007     vat_json_object_add_uint (node, "locator_set_index",
3008                               clib_net_to_host_u32 (mp->locator_set_index));
3009
3010   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3011   if (mp->deid.type == 3)
3012     {
3013       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3014       vat_json_init_object (nsh_json);
3015       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) & mp->deid.address.nsh;
3016       vat_json_object_add_uint (nsh_json, "spi",
3017                                 clib_net_to_host_u32 (nsh->spi));
3018       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3019     }
3020   else
3021     {
3022       eid = format (0, "%U", format_lisp_eid_vat,
3023                     &mp->deid, &mp->seid, mp->is_src_dst);
3024       vec_add1 (eid, 0);
3025       vat_json_object_add_string_copy (node, "eid", eid);
3026       vec_free (eid);
3027     }
3028   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3029   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3030   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3031
3032   if (mp->key.id)
3033     {
3034       vat_json_object_add_uint (node, "key_id",
3035                                 clib_net_to_host_u16 (mp->key.id));
3036       vat_json_object_add_string_copy (node, "key", mp->key.key);
3037     }
3038 }
3039
3040 static void
3041 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3042 {
3043   vat_main_t *vam = &vat_main;
3044   u8 *seid = 0, *deid = 0;
3045   ip46_address_t lloc, rloc;
3046
3047   deid = format (0, "%U", format_lisp_eid_vat, &mp->deid, 0, 0);
3048
3049   seid = format (0, "%U", format_lisp_eid_vat, &mp->seid, 0, 0);
3050
3051   vec_add1 (deid, 0);
3052   vec_add1 (seid, 0);
3053
3054   if (mp->lloc.af)
3055     {
3056       clib_memcpy (&lloc.ip6, mp->lloc.un.ip6, 16);
3057       clib_memcpy (&rloc.ip6, mp->rloc.un.ip6, 16);
3058     }
3059   else
3060     {
3061       clib_memcpy (&lloc.ip4, mp->lloc.un.ip4, 4);
3062       clib_memcpy (&rloc.ip4, mp->rloc.un.ip4, 4);
3063     }
3064
3065
3066   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3067          clib_net_to_host_u32 (mp->vni),
3068          seid, deid,
3069          format_ip46_address, lloc,
3070          format_ip46_address, rloc,
3071          clib_net_to_host_u32 (mp->pkt_count),
3072          clib_net_to_host_u32 (mp->bytes));
3073
3074   vec_free (deid);
3075   vec_free (seid);
3076 }
3077
3078 static void
3079 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3080 {
3081   struct in6_addr ip6;
3082   struct in_addr ip4;
3083   vat_main_t *vam = &vat_main;
3084   vat_json_node_t *node = 0;
3085   u8 *deid = 0, *seid = 0;
3086
3087   if (VAT_JSON_ARRAY != vam->json_tree.type)
3088     {
3089       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3090       vat_json_init_array (&vam->json_tree);
3091     }
3092   node = vat_json_array_add (&vam->json_tree);
3093
3094   vat_json_init_object (node);
3095   deid = format (0, "%U", format_lisp_eid_vat, &mp->deid, 0, 0);
3096
3097   seid = format (0, "%U", format_lisp_eid_vat, &mp->seid, 0, 0);
3098
3099   vec_add1 (deid, 0);
3100   vec_add1 (seid, 0);
3101
3102   vat_json_object_add_string_copy (node, "seid", seid);
3103   vat_json_object_add_string_copy (node, "deid", deid);
3104   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3105
3106   if (mp->lloc.af)
3107     {
3108       clib_memcpy (&ip6, mp->lloc.un.ip6, sizeof (ip6));
3109       vat_json_object_add_ip6 (node, "lloc", ip6);
3110       clib_memcpy (&ip6, mp->rloc.un.ip6, sizeof (ip6));
3111       vat_json_object_add_ip6 (node, "rloc", ip6);
3112
3113     }
3114   else
3115     {
3116       clib_memcpy (&ip4, mp->lloc.un.ip4, sizeof (ip4));
3117       vat_json_object_add_ip4 (node, "lloc", ip4);
3118       clib_memcpy (&ip4, mp->rloc.un.ip4, sizeof (ip4));
3119       vat_json_object_add_ip4 (node, "rloc", ip4);
3120     }
3121   vat_json_object_add_uint (node, "pkt_count",
3122                             clib_net_to_host_u32 (mp->pkt_count));
3123   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3124
3125   vec_free (deid);
3126   vec_free (seid);
3127 }
3128
3129 static void
3130   vl_api_one_eid_table_map_details_t_handler
3131   (vl_api_one_eid_table_map_details_t * mp)
3132 {
3133   vat_main_t *vam = &vat_main;
3134
3135   u8 *line = format (0, "%=10d%=10d",
3136                      clib_net_to_host_u32 (mp->vni),
3137                      clib_net_to_host_u32 (mp->dp_table));
3138   print (vam->ofp, "%v", line);
3139   vec_free (line);
3140 }
3141
3142 static void
3143   vl_api_one_eid_table_map_details_t_handler_json
3144   (vl_api_one_eid_table_map_details_t * mp)
3145 {
3146   vat_main_t *vam = &vat_main;
3147   vat_json_node_t *node = NULL;
3148
3149   if (VAT_JSON_ARRAY != vam->json_tree.type)
3150     {
3151       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3152       vat_json_init_array (&vam->json_tree);
3153     }
3154   node = vat_json_array_add (&vam->json_tree);
3155   vat_json_init_object (node);
3156   vat_json_object_add_uint (node, "dp_table",
3157                             clib_net_to_host_u32 (mp->dp_table));
3158   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3159 }
3160
3161 static void
3162   vl_api_one_eid_table_vni_details_t_handler
3163   (vl_api_one_eid_table_vni_details_t * mp)
3164 {
3165   vat_main_t *vam = &vat_main;
3166
3167   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3168   print (vam->ofp, "%v", line);
3169   vec_free (line);
3170 }
3171
3172 static void
3173   vl_api_one_eid_table_vni_details_t_handler_json
3174   (vl_api_one_eid_table_vni_details_t * mp)
3175 {
3176   vat_main_t *vam = &vat_main;
3177   vat_json_node_t *node = NULL;
3178
3179   if (VAT_JSON_ARRAY != vam->json_tree.type)
3180     {
3181       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3182       vat_json_init_array (&vam->json_tree);
3183     }
3184   node = vat_json_array_add (&vam->json_tree);
3185   vat_json_init_object (node);
3186   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3187 }
3188
3189 static void
3190   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3191   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3192 {
3193   vat_main_t *vam = &vat_main;
3194   int retval = clib_net_to_host_u32 (mp->retval);
3195
3196   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3197   print (vam->ofp, "fallback threshold value: %d", mp->value);
3198
3199   vam->retval = retval;
3200   vam->result_ready = 1;
3201 }
3202
3203 static void
3204   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3205   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3206 {
3207   vat_main_t *vam = &vat_main;
3208   vat_json_node_t _node, *node = &_node;
3209   int retval = clib_net_to_host_u32 (mp->retval);
3210
3211   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3212   vat_json_init_object (node);
3213   vat_json_object_add_uint (node, "value", mp->value);
3214
3215   vat_json_print (vam->ofp, node);
3216   vat_json_free (node);
3217
3218   vam->retval = retval;
3219   vam->result_ready = 1;
3220 }
3221
3222 static void
3223   vl_api_show_one_map_register_state_reply_t_handler
3224   (vl_api_show_one_map_register_state_reply_t * mp)
3225 {
3226   vat_main_t *vam = &vat_main;
3227   int retval = clib_net_to_host_u32 (mp->retval);
3228
3229   print (vam->ofp, "%s", mp->is_enable ? "enabled" : "disabled");
3230
3231   vam->retval = retval;
3232   vam->result_ready = 1;
3233 }
3234
3235 static void
3236   vl_api_show_one_map_register_state_reply_t_handler_json
3237   (vl_api_show_one_map_register_state_reply_t * mp)
3238 {
3239   vat_main_t *vam = &vat_main;
3240   vat_json_node_t _node, *node = &_node;
3241   int retval = clib_net_to_host_u32 (mp->retval);
3242
3243   u8 *s = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
3244
3245   vat_json_init_object (node);
3246   vat_json_object_add_string_copy (node, "state", s);
3247
3248   vat_json_print (vam->ofp, node);
3249   vat_json_free (node);
3250
3251   vam->retval = retval;
3252   vam->result_ready = 1;
3253   vec_free (s);
3254 }
3255
3256 static void
3257   vl_api_show_one_rloc_probe_state_reply_t_handler
3258   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3259 {
3260   vat_main_t *vam = &vat_main;
3261   int retval = clib_net_to_host_u32 (mp->retval);
3262
3263   if (retval)
3264     goto end;
3265
3266   print (vam->ofp, "%s", mp->is_enable ? "enabled" : "disabled");
3267 end:
3268   vam->retval = retval;
3269   vam->result_ready = 1;
3270 }
3271
3272 static void
3273   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3274   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3275 {
3276   vat_main_t *vam = &vat_main;
3277   vat_json_node_t _node, *node = &_node;
3278   int retval = clib_net_to_host_u32 (mp->retval);
3279
3280   u8 *s = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
3281   vat_json_init_object (node);
3282   vat_json_object_add_string_copy (node, "state", s);
3283
3284   vat_json_print (vam->ofp, node);
3285   vat_json_free (node);
3286
3287   vam->retval = retval;
3288   vam->result_ready = 1;
3289   vec_free (s);
3290 }
3291
3292 static void
3293   vl_api_show_one_stats_enable_disable_reply_t_handler
3294   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3295 {
3296   vat_main_t *vam = &vat_main;
3297   int retval = clib_net_to_host_u32 (mp->retval);
3298
3299   if (retval)
3300     goto end;
3301
3302   print (vam->ofp, "%s", mp->is_enable ? "enabled" : "disabled");
3303 end:
3304   vam->retval = retval;
3305   vam->result_ready = 1;
3306 }
3307
3308 static void
3309   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3310   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3311 {
3312   vat_main_t *vam = &vat_main;
3313   vat_json_node_t _node, *node = &_node;
3314   int retval = clib_net_to_host_u32 (mp->retval);
3315
3316   u8 *s = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
3317   vat_json_init_object (node);
3318   vat_json_object_add_string_copy (node, "state", s);
3319
3320   vat_json_print (vam->ofp, node);
3321   vat_json_free (node);
3322
3323   vam->retval = retval;
3324   vam->result_ready = 1;
3325   vec_free (s);
3326 }
3327
3328 static void
3329 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3330 {
3331   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3332   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3333   e->vni = clib_net_to_host_u32 (e->vni);
3334 }
3335
3336 static void
3337   gpe_fwd_entries_get_reply_t_net_to_host
3338   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3339 {
3340   u32 i;
3341
3342   mp->count = clib_net_to_host_u32 (mp->count);
3343   for (i = 0; i < mp->count; i++)
3344     {
3345       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3346     }
3347 }
3348
3349 static u8 *
3350 format_gpe_encap_mode (u8 * s, va_list * args)
3351 {
3352   u32 mode = va_arg (*args, u32);
3353
3354   switch (mode)
3355     {
3356     case 0:
3357       return format (s, "lisp");
3358     case 1:
3359       return format (s, "vxlan");
3360     }
3361   return 0;
3362 }
3363
3364 static void
3365   vl_api_gpe_get_encap_mode_reply_t_handler
3366   (vl_api_gpe_get_encap_mode_reply_t * mp)
3367 {
3368   vat_main_t *vam = &vat_main;
3369
3370   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3371   vam->retval = ntohl (mp->retval);
3372   vam->result_ready = 1;
3373 }
3374
3375 static void
3376   vl_api_gpe_get_encap_mode_reply_t_handler_json
3377   (vl_api_gpe_get_encap_mode_reply_t * mp)
3378 {
3379   vat_main_t *vam = &vat_main;
3380   vat_json_node_t node;
3381
3382   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3383   vec_add1 (encap_mode, 0);
3384
3385   vat_json_init_object (&node);
3386   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3387
3388   vec_free (encap_mode);
3389   vat_json_print (vam->ofp, &node);
3390   vat_json_free (&node);
3391
3392   vam->retval = ntohl (mp->retval);
3393   vam->result_ready = 1;
3394 }
3395
3396 static void
3397   vl_api_gpe_fwd_entry_path_details_t_handler
3398   (vl_api_gpe_fwd_entry_path_details_t * mp)
3399 {
3400   vat_main_t *vam = &vat_main;
3401   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3402
3403   if (mp->lcl_loc.addr.af)
3404     format_ip_address_fcn = format_ip6_address;
3405   else
3406     format_ip_address_fcn = format_ip4_address;
3407
3408   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3409          format_ip_address_fcn, &mp->lcl_loc.addr.un,
3410          format_ip_address_fcn, &mp->rmt_loc.addr.un);
3411 }
3412
3413 static void
3414 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3415 {
3416   struct in6_addr ip6;
3417   struct in_addr ip4;
3418
3419   if (loc->addr.af)
3420     {
3421       clib_memcpy (&ip6, loc->addr.un.ip6, sizeof (ip6));
3422       vat_json_object_add_ip6 (n, "address", ip6);
3423     }
3424   else
3425     {
3426       clib_memcpy (&ip4, loc->addr.un.ip4, sizeof (ip4));
3427       vat_json_object_add_ip4 (n, "address", ip4);
3428     }
3429   vat_json_object_add_uint (n, "weight", loc->weight);
3430 }
3431
3432 static void
3433   vl_api_gpe_fwd_entry_path_details_t_handler_json
3434   (vl_api_gpe_fwd_entry_path_details_t * mp)
3435 {
3436   vat_main_t *vam = &vat_main;
3437   vat_json_node_t *node = NULL;
3438   vat_json_node_t *loc_node;
3439
3440   if (VAT_JSON_ARRAY != vam->json_tree.type)
3441     {
3442       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3443       vat_json_init_array (&vam->json_tree);
3444     }
3445   node = vat_json_array_add (&vam->json_tree);
3446   vat_json_init_object (node);
3447
3448   loc_node = vat_json_object_add (node, "local_locator");
3449   vat_json_init_object (loc_node);
3450   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3451
3452   loc_node = vat_json_object_add (node, "remote_locator");
3453   vat_json_init_object (loc_node);
3454   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3455 }
3456
3457 static void
3458   vl_api_gpe_fwd_entries_get_reply_t_handler
3459   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3460 {
3461   vat_main_t *vam = &vat_main;
3462   u32 i;
3463   int retval = clib_net_to_host_u32 (mp->retval);
3464   vl_api_gpe_fwd_entry_t *e;
3465
3466   if (retval)
3467     goto end;
3468
3469   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3470
3471   for (i = 0; i < mp->count; i++)
3472     {
3473       e = &mp->entries[i];
3474       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3475              format_lisp_flat_eid, e->leid, format_lisp_flat_eid, e->reid);
3476     }
3477
3478 end:
3479   vam->retval = retval;
3480   vam->result_ready = 1;
3481 }
3482
3483 static void
3484   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3485   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3486 {
3487   u8 *s = 0;
3488   vat_main_t *vam = &vat_main;
3489   vat_json_node_t *e = 0, root;
3490   u32 i;
3491   int retval = clib_net_to_host_u32 (mp->retval);
3492   vl_api_gpe_fwd_entry_t *fwd;
3493
3494   if (retval)
3495     goto end;
3496
3497   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3498   vat_json_init_array (&root);
3499
3500   for (i = 0; i < mp->count; i++)
3501     {
3502       e = vat_json_array_add (&root);
3503       fwd = &mp->entries[i];
3504
3505       vat_json_init_object (e);
3506       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3507       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3508       vat_json_object_add_int (e, "vni", fwd->vni);
3509       vat_json_object_add_int (e, "action", fwd->action);
3510
3511       s = format (0, "%U", format_lisp_flat_eid, fwd->leid);
3512       vec_add1 (s, 0);
3513       vat_json_object_add_string_copy (e, "leid", s);
3514       vec_free (s);
3515
3516       s = format (0, "%U", format_lisp_flat_eid, fwd->reid);
3517       vec_add1 (s, 0);
3518       vat_json_object_add_string_copy (e, "reid", s);
3519       vec_free (s);
3520     }
3521
3522   vat_json_print (vam->ofp, &root);
3523   vat_json_free (&root);
3524
3525 end:
3526   vam->retval = retval;
3527   vam->result_ready = 1;
3528 }
3529
3530 static void
3531   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3532   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3533 {
3534   vat_main_t *vam = &vat_main;
3535   u32 i, n;
3536   int retval = clib_net_to_host_u32 (mp->retval);
3537   vl_api_gpe_native_fwd_rpath_t *r;
3538
3539   if (retval)
3540     goto end;
3541
3542   n = clib_net_to_host_u32 (mp->count);
3543
3544   for (i = 0; i < n; i++)
3545     {
3546       r = &mp->entries[i];
3547       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3548              clib_net_to_host_u32 (r->fib_index),
3549              clib_net_to_host_u32 (r->nh_sw_if_index),
3550              r->nh_addr.af ? format_ip6_address : format_ip4_address,
3551              r->nh_addr.un);
3552     }
3553
3554 end:
3555   vam->retval = retval;
3556   vam->result_ready = 1;
3557 }
3558
3559 static void
3560   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3561   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3562 {
3563   vat_main_t *vam = &vat_main;
3564   vat_json_node_t root, *e;
3565   u32 i, n;
3566   int retval = clib_net_to_host_u32 (mp->retval);
3567   vl_api_gpe_native_fwd_rpath_t *r;
3568   u8 *s;
3569
3570   if (retval)
3571     goto end;
3572
3573   n = clib_net_to_host_u32 (mp->count);
3574   vat_json_init_array (&root);
3575
3576   for (i = 0; i < n; i++)
3577     {
3578       e = vat_json_array_add (&root);
3579       vat_json_init_object (e);
3580       r = &mp->entries[i];
3581       s =
3582         format (0, "%U",
3583                 r->nh_addr.af ? format_ip6_address : format_ip4_address,
3584                 r->nh_addr.un);
3585       vec_add1 (s, 0);
3586       vat_json_object_add_string_copy (e, "ip4", s);
3587       vec_free (s);
3588
3589       vat_json_object_add_uint (e, "fib_index",
3590                                 clib_net_to_host_u32 (r->fib_index));
3591       vat_json_object_add_uint (e, "nh_sw_if_index",
3592                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3593     }
3594
3595   vat_json_print (vam->ofp, &root);
3596   vat_json_free (&root);
3597
3598 end:
3599   vam->retval = retval;
3600   vam->result_ready = 1;
3601 }
3602
3603 static void
3604   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3605   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3606 {
3607   vat_main_t *vam = &vat_main;
3608   u32 i, n;
3609   int retval = clib_net_to_host_u32 (mp->retval);
3610
3611   if (retval)
3612     goto end;
3613
3614   n = clib_net_to_host_u32 (mp->count);
3615
3616   for (i = 0; i < n; i++)
3617     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3618
3619 end:
3620   vam->retval = retval;
3621   vam->result_ready = 1;
3622 }
3623
3624 static void
3625   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3626   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3627 {
3628   vat_main_t *vam = &vat_main;
3629   vat_json_node_t root;
3630   u32 i, n;
3631   int retval = clib_net_to_host_u32 (mp->retval);
3632
3633   if (retval)
3634     goto end;
3635
3636   n = clib_net_to_host_u32 (mp->count);
3637   vat_json_init_array (&root);
3638
3639   for (i = 0; i < n; i++)
3640     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3641
3642   vat_json_print (vam->ofp, &root);
3643   vat_json_free (&root);
3644
3645 end:
3646   vam->retval = retval;
3647   vam->result_ready = 1;
3648 }
3649
3650 static void
3651   vl_api_one_ndp_entries_get_reply_t_handler
3652   (vl_api_one_ndp_entries_get_reply_t * mp)
3653 {
3654   vat_main_t *vam = &vat_main;
3655   u32 i, n;
3656   int retval = clib_net_to_host_u32 (mp->retval);
3657
3658   if (retval)
3659     goto end;
3660
3661   n = clib_net_to_host_u32 (mp->count);
3662
3663   for (i = 0; i < n; i++)
3664     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3665            format_ethernet_address, mp->entries[i].mac);
3666
3667 end:
3668   vam->retval = retval;
3669   vam->result_ready = 1;
3670 }
3671
3672 static void
3673   vl_api_one_ndp_entries_get_reply_t_handler_json
3674   (vl_api_one_ndp_entries_get_reply_t * mp)
3675 {
3676   u8 *s = 0;
3677   vat_main_t *vam = &vat_main;
3678   vat_json_node_t *e = 0, root;
3679   u32 i, n;
3680   int retval = clib_net_to_host_u32 (mp->retval);
3681   vl_api_one_ndp_entry_t *arp_entry;
3682
3683   if (retval)
3684     goto end;
3685
3686   n = clib_net_to_host_u32 (mp->count);
3687   vat_json_init_array (&root);
3688
3689   for (i = 0; i < n; i++)
3690     {
3691       e = vat_json_array_add (&root);
3692       arp_entry = &mp->entries[i];
3693
3694       vat_json_init_object (e);
3695       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3696       vec_add1 (s, 0);
3697
3698       vat_json_object_add_string_copy (e, "mac", s);
3699       vec_free (s);
3700
3701       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3702       vec_add1 (s, 0);
3703       vat_json_object_add_string_copy (e, "ip6", s);
3704       vec_free (s);
3705     }
3706
3707   vat_json_print (vam->ofp, &root);
3708   vat_json_free (&root);
3709
3710 end:
3711   vam->retval = retval;
3712   vam->result_ready = 1;
3713 }
3714
3715 static void
3716   vl_api_one_l2_arp_entries_get_reply_t_handler
3717   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3718 {
3719   vat_main_t *vam = &vat_main;
3720   u32 i, n;
3721   int retval = clib_net_to_host_u32 (mp->retval);
3722
3723   if (retval)
3724     goto end;
3725
3726   n = clib_net_to_host_u32 (mp->count);
3727
3728   for (i = 0; i < n; i++)
3729     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3730            format_ethernet_address, mp->entries[i].mac);
3731
3732 end:
3733   vam->retval = retval;
3734   vam->result_ready = 1;
3735 }
3736
3737 static void
3738   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3739   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3740 {
3741   u8 *s = 0;
3742   vat_main_t *vam = &vat_main;
3743   vat_json_node_t *e = 0, root;
3744   u32 i, n;
3745   int retval = clib_net_to_host_u32 (mp->retval);
3746   vl_api_one_l2_arp_entry_t *arp_entry;
3747
3748   if (retval)
3749     goto end;
3750
3751   n = clib_net_to_host_u32 (mp->count);
3752   vat_json_init_array (&root);
3753
3754   for (i = 0; i < n; i++)
3755     {
3756       e = vat_json_array_add (&root);
3757       arp_entry = &mp->entries[i];
3758
3759       vat_json_init_object (e);
3760       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3761       vec_add1 (s, 0);
3762
3763       vat_json_object_add_string_copy (e, "mac", s);
3764       vec_free (s);
3765
3766       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3767       vec_add1 (s, 0);
3768       vat_json_object_add_string_copy (e, "ip4", s);
3769       vec_free (s);
3770     }
3771
3772   vat_json_print (vam->ofp, &root);
3773   vat_json_free (&root);
3774
3775 end:
3776   vam->retval = retval;
3777   vam->result_ready = 1;
3778 }
3779
3780 static void
3781 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3782 {
3783   vat_main_t *vam = &vat_main;
3784   u32 i, n;
3785   int retval = clib_net_to_host_u32 (mp->retval);
3786
3787   if (retval)
3788     goto end;
3789
3790   n = clib_net_to_host_u32 (mp->count);
3791
3792   for (i = 0; i < n; i++)
3793     {
3794       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3795     }
3796
3797 end:
3798   vam->retval = retval;
3799   vam->result_ready = 1;
3800 }
3801
3802 static void
3803   vl_api_one_ndp_bd_get_reply_t_handler_json
3804   (vl_api_one_ndp_bd_get_reply_t * mp)
3805 {
3806   vat_main_t *vam = &vat_main;
3807   vat_json_node_t root;
3808   u32 i, n;
3809   int retval = clib_net_to_host_u32 (mp->retval);
3810
3811   if (retval)
3812     goto end;
3813
3814   n = clib_net_to_host_u32 (mp->count);
3815   vat_json_init_array (&root);
3816
3817   for (i = 0; i < n; i++)
3818     {
3819       vat_json_array_add_uint (&root,
3820                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3821     }
3822
3823   vat_json_print (vam->ofp, &root);
3824   vat_json_free (&root);
3825
3826 end:
3827   vam->retval = retval;
3828   vam->result_ready = 1;
3829 }
3830
3831 static void
3832   vl_api_one_l2_arp_bd_get_reply_t_handler
3833   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3834 {
3835   vat_main_t *vam = &vat_main;
3836   u32 i, n;
3837   int retval = clib_net_to_host_u32 (mp->retval);
3838
3839   if (retval)
3840     goto end;
3841
3842   n = clib_net_to_host_u32 (mp->count);
3843
3844   for (i = 0; i < n; i++)
3845     {
3846       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3847     }
3848
3849 end:
3850   vam->retval = retval;
3851   vam->result_ready = 1;
3852 }
3853
3854 static void
3855   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3856   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3857 {
3858   vat_main_t *vam = &vat_main;
3859   vat_json_node_t root;
3860   u32 i, n;
3861   int retval = clib_net_to_host_u32 (mp->retval);
3862
3863   if (retval)
3864     goto end;
3865
3866   n = clib_net_to_host_u32 (mp->count);
3867   vat_json_init_array (&root);
3868
3869   for (i = 0; i < n; i++)
3870     {
3871       vat_json_array_add_uint (&root,
3872                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3873     }
3874
3875   vat_json_print (vam->ofp, &root);
3876   vat_json_free (&root);
3877
3878 end:
3879   vam->retval = retval;
3880   vam->result_ready = 1;
3881 }
3882
3883 static void
3884   vl_api_one_adjacencies_get_reply_t_handler
3885   (vl_api_one_adjacencies_get_reply_t * mp)
3886 {
3887   vat_main_t *vam = &vat_main;
3888   u32 i, n;
3889   int retval = clib_net_to_host_u32 (mp->retval);
3890   vl_api_one_adjacency_t *a;
3891
3892   if (retval)
3893     goto end;
3894
3895   n = clib_net_to_host_u32 (mp->count);
3896
3897   for (i = 0; i < n; i++)
3898     {
3899       a = &mp->adjacencies[i];
3900       print (vam->ofp, "%U %40U",
3901              format_lisp_flat_eid, a->leid, format_lisp_flat_eid, a->reid);
3902     }
3903
3904 end:
3905   vam->retval = retval;
3906   vam->result_ready = 1;
3907 }
3908
3909 static void
3910   vl_api_one_adjacencies_get_reply_t_handler_json
3911   (vl_api_one_adjacencies_get_reply_t * mp)
3912 {
3913   u8 *s = 0;
3914   vat_main_t *vam = &vat_main;
3915   vat_json_node_t *e = 0, root;
3916   u32 i, n;
3917   int retval = clib_net_to_host_u32 (mp->retval);
3918   vl_api_one_adjacency_t *a;
3919
3920   if (retval)
3921     goto end;
3922
3923   n = clib_net_to_host_u32 (mp->count);
3924   vat_json_init_array (&root);
3925
3926   for (i = 0; i < n; i++)
3927     {
3928       e = vat_json_array_add (&root);
3929       a = &mp->adjacencies[i];
3930
3931       vat_json_init_object (e);
3932       s = format (0, "%U", format_lisp_flat_eid, a->leid);
3933       vec_add1 (s, 0);
3934       vat_json_object_add_string_copy (e, "leid", s);
3935       vec_free (s);
3936
3937       s = format (0, "%U", format_lisp_flat_eid, a->reid);
3938       vec_add1 (s, 0);
3939       vat_json_object_add_string_copy (e, "reid", s);
3940       vec_free (s);
3941     }
3942
3943   vat_json_print (vam->ofp, &root);
3944   vat_json_free (&root);
3945
3946 end:
3947   vam->retval = retval;
3948   vam->result_ready = 1;
3949 }
3950
3951 static void
3952 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3953 {
3954   vat_main_t *vam = &vat_main;
3955
3956   print (vam->ofp, "%=20U",
3957          mp->ip_address.af ? format_ip6_address : format_ip4_address,
3958          mp->ip_address.un);
3959 }
3960
3961 static void
3962   vl_api_one_map_server_details_t_handler_json
3963   (vl_api_one_map_server_details_t * mp)
3964 {
3965   vat_main_t *vam = &vat_main;
3966   vat_json_node_t *node = NULL;
3967   struct in6_addr ip6;
3968   struct in_addr ip4;
3969
3970   if (VAT_JSON_ARRAY != vam->json_tree.type)
3971     {
3972       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3973       vat_json_init_array (&vam->json_tree);
3974     }
3975   node = vat_json_array_add (&vam->json_tree);
3976
3977   vat_json_init_object (node);
3978   if (mp->ip_address.af)
3979     {
3980       clib_memcpy (&ip6, mp->ip_address.un.ip6, sizeof (ip6));
3981       vat_json_object_add_ip6 (node, "map-server", ip6);
3982     }
3983   else
3984     {
3985       clib_memcpy (&ip4, mp->ip_address.un.ip4, sizeof (ip4));
3986       vat_json_object_add_ip4 (node, "map-server", ip4);
3987     }
3988 }
3989
3990 static void
3991 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3992                                            * mp)
3993 {
3994   vat_main_t *vam = &vat_main;
3995
3996   print (vam->ofp, "%=20U",
3997          mp->ip_address.af ? format_ip6_address : format_ip4_address,
3998          mp->ip_address.un);
3999 }
4000
4001 static void
4002   vl_api_one_map_resolver_details_t_handler_json
4003   (vl_api_one_map_resolver_details_t * mp)
4004 {
4005   vat_main_t *vam = &vat_main;
4006   vat_json_node_t *node = NULL;
4007   struct in6_addr ip6;
4008   struct in_addr ip4;
4009
4010   if (VAT_JSON_ARRAY != vam->json_tree.type)
4011     {
4012       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4013       vat_json_init_array (&vam->json_tree);
4014     }
4015   node = vat_json_array_add (&vam->json_tree);
4016
4017   vat_json_init_object (node);
4018   if (mp->ip_address.af)
4019     {
4020       clib_memcpy (&ip6, mp->ip_address.un.ip6, sizeof (ip6));
4021       vat_json_object_add_ip6 (node, "map resolver", ip6);
4022     }
4023   else
4024     {
4025       clib_memcpy (&ip4, mp->ip_address.un.ip4, sizeof (ip4));
4026       vat_json_object_add_ip4 (node, "map resolver", ip4);
4027     }
4028 }
4029
4030 static void
4031 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4032 {
4033   vat_main_t *vam = &vat_main;
4034   i32 retval = ntohl (mp->retval);
4035
4036   if (0 <= retval)
4037     {
4038       print (vam->ofp, "feature: %s\ngpe: %s",
4039              mp->feature_status ? "enabled" : "disabled",
4040              mp->gpe_status ? "enabled" : "disabled");
4041     }
4042
4043   vam->retval = retval;
4044   vam->result_ready = 1;
4045 }
4046
4047 static void
4048   vl_api_show_one_status_reply_t_handler_json
4049   (vl_api_show_one_status_reply_t * mp)
4050 {
4051   vat_main_t *vam = &vat_main;
4052   vat_json_node_t node;
4053   u8 *gpe_status = NULL;
4054   u8 *feature_status = NULL;
4055
4056   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4057   feature_status = format (0, "%s",
4058                            mp->feature_status ? "enabled" : "disabled");
4059   vec_add1 (gpe_status, 0);
4060   vec_add1 (feature_status, 0);
4061
4062   vat_json_init_object (&node);
4063   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4064   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4065
4066   vec_free (gpe_status);
4067   vec_free (feature_status);
4068
4069   vat_json_print (vam->ofp, &node);
4070   vat_json_free (&node);
4071
4072   vam->retval = ntohl (mp->retval);
4073   vam->result_ready = 1;
4074 }
4075
4076 static void
4077   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4078   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4079 {
4080   vat_main_t *vam = &vat_main;
4081   i32 retval = ntohl (mp->retval);
4082
4083   if (retval >= 0)
4084     {
4085       print (vam->ofp, "%=20s", mp->locator_set_name);
4086     }
4087
4088   vam->retval = retval;
4089   vam->result_ready = 1;
4090 }
4091
4092 static void
4093   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4094   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4095 {
4096   vat_main_t *vam = &vat_main;
4097   vat_json_node_t *node = NULL;
4098
4099   if (VAT_JSON_ARRAY != vam->json_tree.type)
4100     {
4101       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4102       vat_json_init_array (&vam->json_tree);
4103     }
4104   node = vat_json_array_add (&vam->json_tree);
4105
4106   vat_json_init_object (node);
4107   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4108
4109   vat_json_print (vam->ofp, node);
4110   vat_json_free (node);
4111
4112   vam->retval = ntohl (mp->retval);
4113   vam->result_ready = 1;
4114 }
4115
4116 static u8 *
4117 format_lisp_map_request_mode (u8 * s, va_list * args)
4118 {
4119   u32 mode = va_arg (*args, u32);
4120
4121   switch (mode)
4122     {
4123     case 0:
4124       return format (0, "dst-only");
4125     case 1:
4126       return format (0, "src-dst");
4127     }
4128   return 0;
4129 }
4130
4131 static void
4132   vl_api_show_one_map_request_mode_reply_t_handler
4133   (vl_api_show_one_map_request_mode_reply_t * mp)
4134 {
4135   vat_main_t *vam = &vat_main;
4136   i32 retval = ntohl (mp->retval);
4137
4138   if (0 <= retval)
4139     {
4140       u32 mode = mp->mode;
4141       print (vam->ofp, "map_request_mode: %U",
4142              format_lisp_map_request_mode, mode);
4143     }
4144
4145   vam->retval = retval;
4146   vam->result_ready = 1;
4147 }
4148
4149 static void
4150   vl_api_show_one_map_request_mode_reply_t_handler_json
4151   (vl_api_show_one_map_request_mode_reply_t * mp)
4152 {
4153   vat_main_t *vam = &vat_main;
4154   vat_json_node_t node;
4155   u8 *s = 0;
4156   u32 mode;
4157
4158   mode = mp->mode;
4159   s = format (0, "%U", format_lisp_map_request_mode, mode);
4160   vec_add1 (s, 0);
4161
4162   vat_json_init_object (&node);
4163   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4164   vat_json_print (vam->ofp, &node);
4165   vat_json_free (&node);
4166
4167   vec_free (s);
4168   vam->retval = ntohl (mp->retval);
4169   vam->result_ready = 1;
4170 }
4171
4172 static void
4173   vl_api_one_show_xtr_mode_reply_t_handler
4174   (vl_api_one_show_xtr_mode_reply_t * mp)
4175 {
4176   vat_main_t *vam = &vat_main;
4177   i32 retval = ntohl (mp->retval);
4178
4179   if (0 <= retval)
4180     {
4181       print (vam->ofp, "%s\n", mp->is_enable ? "enabled" : "disabled");
4182     }
4183
4184   vam->retval = retval;
4185   vam->result_ready = 1;
4186 }
4187
4188 static void
4189   vl_api_one_show_xtr_mode_reply_t_handler_json
4190   (vl_api_one_show_xtr_mode_reply_t * mp)
4191 {
4192   vat_main_t *vam = &vat_main;
4193   vat_json_node_t node;
4194   u8 *status = 0;
4195
4196   status = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
4197   vec_add1 (status, 0);
4198
4199   vat_json_init_object (&node);
4200   vat_json_object_add_string_copy (&node, "status", status);
4201
4202   vec_free (status);
4203
4204   vat_json_print (vam->ofp, &node);
4205   vat_json_free (&node);
4206
4207   vam->retval = ntohl (mp->retval);
4208   vam->result_ready = 1;
4209 }
4210
4211 static void
4212   vl_api_one_show_pitr_mode_reply_t_handler
4213   (vl_api_one_show_pitr_mode_reply_t * mp)
4214 {
4215   vat_main_t *vam = &vat_main;
4216   i32 retval = ntohl (mp->retval);
4217
4218   if (0 <= retval)
4219     {
4220       print (vam->ofp, "%s\n", mp->is_enable ? "enabled" : "disabled");
4221     }
4222
4223   vam->retval = retval;
4224   vam->result_ready = 1;
4225 }
4226
4227 static void
4228   vl_api_one_show_pitr_mode_reply_t_handler_json
4229   (vl_api_one_show_pitr_mode_reply_t * mp)
4230 {
4231   vat_main_t *vam = &vat_main;
4232   vat_json_node_t node;
4233   u8 *status = 0;
4234
4235   status = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
4236   vec_add1 (status, 0);
4237
4238   vat_json_init_object (&node);
4239   vat_json_object_add_string_copy (&node, "status", status);
4240
4241   vec_free (status);
4242
4243   vat_json_print (vam->ofp, &node);
4244   vat_json_free (&node);
4245
4246   vam->retval = ntohl (mp->retval);
4247   vam->result_ready = 1;
4248 }
4249
4250 static void
4251   vl_api_one_show_petr_mode_reply_t_handler
4252   (vl_api_one_show_petr_mode_reply_t * mp)
4253 {
4254   vat_main_t *vam = &vat_main;
4255   i32 retval = ntohl (mp->retval);
4256
4257   if (0 <= retval)
4258     {
4259       print (vam->ofp, "%s\n", mp->is_enable ? "enabled" : "disabled");
4260     }
4261
4262   vam->retval = retval;
4263   vam->result_ready = 1;
4264 }
4265
4266 static void
4267   vl_api_one_show_petr_mode_reply_t_handler_json
4268   (vl_api_one_show_petr_mode_reply_t * mp)
4269 {
4270   vat_main_t *vam = &vat_main;
4271   vat_json_node_t node;
4272   u8 *status = 0;
4273
4274   status = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
4275   vec_add1 (status, 0);
4276
4277   vat_json_init_object (&node);
4278   vat_json_object_add_string_copy (&node, "status", status);
4279
4280   vec_free (status);
4281
4282   vat_json_print (vam->ofp, &node);
4283   vat_json_free (&node);
4284
4285   vam->retval = ntohl (mp->retval);
4286   vam->result_ready = 1;
4287 }
4288
4289 static void
4290   vl_api_show_one_use_petr_reply_t_handler
4291   (vl_api_show_one_use_petr_reply_t * mp)
4292 {
4293   vat_main_t *vam = &vat_main;
4294   i32 retval = ntohl (mp->retval);
4295
4296   if (0 <= retval)
4297     {
4298       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4299       if (mp->status)
4300         {
4301           print (vam->ofp, "Proxy-ETR address; %U",
4302                  mp->ip_address.af ? format_ip6_address : format_ip4_address,
4303                  mp->ip_address.un);
4304         }
4305     }
4306
4307   vam->retval = retval;
4308   vam->result_ready = 1;
4309 }
4310
4311 static void
4312   vl_api_show_one_use_petr_reply_t_handler_json
4313   (vl_api_show_one_use_petr_reply_t * mp)
4314 {
4315   vat_main_t *vam = &vat_main;
4316   vat_json_node_t node;
4317   u8 *status = 0;
4318   struct in_addr ip4;
4319   struct in6_addr ip6;
4320
4321   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4322   vec_add1 (status, 0);
4323
4324   vat_json_init_object (&node);
4325   vat_json_object_add_string_copy (&node, "status", status);
4326   if (mp->status)
4327     {
4328       if (mp->ip_address.af)
4329         {
4330           clib_memcpy (&ip6, mp->ip_address.un.ip6, sizeof (ip6));
4331           vat_json_object_add_ip6 (&node, "address", ip6);
4332         }
4333       else
4334         {
4335           clib_memcpy (&ip4, mp->ip_address.un.ip4, sizeof (ip4));
4336           vat_json_object_add_ip4 (&node, "address", ip4);
4337         }
4338     }
4339
4340   vec_free (status);
4341
4342   vat_json_print (vam->ofp, &node);
4343   vat_json_free (&node);
4344
4345   vam->retval = ntohl (mp->retval);
4346   vam->result_ready = 1;
4347 }
4348
4349 static void
4350   vl_api_show_one_nsh_mapping_reply_t_handler
4351   (vl_api_show_one_nsh_mapping_reply_t * mp)
4352 {
4353   vat_main_t *vam = &vat_main;
4354   i32 retval = ntohl (mp->retval);
4355
4356   if (0 <= retval)
4357     {
4358       print (vam->ofp, "%-20s%-16s",
4359              mp->is_set ? "set" : "not-set",
4360              mp->is_set ? (char *) mp->locator_set_name : "");
4361     }
4362
4363   vam->retval = retval;
4364   vam->result_ready = 1;
4365 }
4366
4367 static void
4368   vl_api_show_one_nsh_mapping_reply_t_handler_json
4369   (vl_api_show_one_nsh_mapping_reply_t * mp)
4370 {
4371   vat_main_t *vam = &vat_main;
4372   vat_json_node_t node;
4373   u8 *status = 0;
4374
4375   status = format (0, "%s", mp->is_set ? "yes" : "no");
4376   vec_add1 (status, 0);
4377
4378   vat_json_init_object (&node);
4379   vat_json_object_add_string_copy (&node, "is_set", status);
4380   if (mp->is_set)
4381     {
4382       vat_json_object_add_string_copy (&node, "locator_set",
4383                                        mp->locator_set_name);
4384     }
4385
4386   vec_free (status);
4387
4388   vat_json_print (vam->ofp, &node);
4389   vat_json_free (&node);
4390
4391   vam->retval = ntohl (mp->retval);
4392   vam->result_ready = 1;
4393 }
4394
4395 static void
4396   vl_api_show_one_map_register_ttl_reply_t_handler
4397   (vl_api_show_one_map_register_ttl_reply_t * mp)
4398 {
4399   vat_main_t *vam = &vat_main;
4400   i32 retval = ntohl (mp->retval);
4401
4402   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4403
4404   if (0 <= retval)
4405     {
4406       print (vam->ofp, "ttl: %u", mp->ttl);
4407     }
4408
4409   vam->retval = retval;
4410   vam->result_ready = 1;
4411 }
4412
4413 static void
4414   vl_api_show_one_map_register_ttl_reply_t_handler_json
4415   (vl_api_show_one_map_register_ttl_reply_t * mp)
4416 {
4417   vat_main_t *vam = &vat_main;
4418   vat_json_node_t node;
4419
4420   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4421   vat_json_init_object (&node);
4422   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4423
4424   vat_json_print (vam->ofp, &node);
4425   vat_json_free (&node);
4426
4427   vam->retval = ntohl (mp->retval);
4428   vam->result_ready = 1;
4429 }
4430
4431 static void
4432 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4433 {
4434   vat_main_t *vam = &vat_main;
4435   i32 retval = ntohl (mp->retval);
4436
4437   if (0 <= retval)
4438     {
4439       print (vam->ofp, "%-20s%-16s",
4440              mp->status ? "enabled" : "disabled",
4441              mp->status ? (char *) mp->locator_set_name : "");
4442     }
4443
4444   vam->retval = retval;
4445   vam->result_ready = 1;
4446 }
4447
4448 static void
4449 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4450 {
4451   vat_main_t *vam = &vat_main;
4452   vat_json_node_t node;
4453   u8 *status = 0;
4454
4455   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4456   vec_add1 (status, 0);
4457
4458   vat_json_init_object (&node);
4459   vat_json_object_add_string_copy (&node, "status", status);
4460   if (mp->status)
4461     {
4462       vat_json_object_add_string_copy (&node, "locator_set",
4463                                        mp->locator_set_name);
4464     }
4465
4466   vec_free (status);
4467
4468   vat_json_print (vam->ofp, &node);
4469   vat_json_free (&node);
4470
4471   vam->retval = ntohl (mp->retval);
4472   vam->result_ready = 1;
4473 }
4474
4475 static u8 *
4476 format_policer_type (u8 * s, va_list * va)
4477 {
4478   u32 i = va_arg (*va, u32);
4479
4480   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4481     s = format (s, "1r2c");
4482   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4483     s = format (s, "1r3c");
4484   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4485     s = format (s, "2r3c-2698");
4486   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4487     s = format (s, "2r3c-4115");
4488   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4489     s = format (s, "2r3c-mef5cf1");
4490   else
4491     s = format (s, "ILLEGAL");
4492   return s;
4493 }
4494
4495 static u8 *
4496 format_policer_rate_type (u8 * s, va_list * va)
4497 {
4498   u32 i = va_arg (*va, u32);
4499
4500   if (i == SSE2_QOS_RATE_KBPS)
4501     s = format (s, "kbps");
4502   else if (i == SSE2_QOS_RATE_PPS)
4503     s = format (s, "pps");
4504   else
4505     s = format (s, "ILLEGAL");
4506   return s;
4507 }
4508
4509 static u8 *
4510 format_policer_round_type (u8 * s, va_list * va)
4511 {
4512   u32 i = va_arg (*va, u32);
4513
4514   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4515     s = format (s, "closest");
4516   else if (i == SSE2_QOS_ROUND_TO_UP)
4517     s = format (s, "up");
4518   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4519     s = format (s, "down");
4520   else
4521     s = format (s, "ILLEGAL");
4522   return s;
4523 }
4524
4525 static u8 *
4526 format_policer_action_type (u8 * s, va_list * va)
4527 {
4528   u32 i = va_arg (*va, u32);
4529
4530   if (i == SSE2_QOS_ACTION_DROP)
4531     s = format (s, "drop");
4532   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4533     s = format (s, "transmit");
4534   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4535     s = format (s, "mark-and-transmit");
4536   else
4537     s = format (s, "ILLEGAL");
4538   return s;
4539 }
4540
4541 static u8 *
4542 format_dscp (u8 * s, va_list * va)
4543 {
4544   u32 i = va_arg (*va, u32);
4545   char *t = 0;
4546
4547   switch (i)
4548     {
4549 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4550       foreach_vnet_dscp
4551 #undef _
4552     default:
4553       return format (s, "ILLEGAL");
4554     }
4555   s = format (s, "%s", t);
4556   return s;
4557 }
4558
4559 static void
4560 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4561 {
4562   vat_main_t *vam = &vat_main;
4563   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4564
4565   if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4566     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp);
4567   else
4568     conform_dscp_str = format (0, "");
4569
4570   if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4571     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp);
4572   else
4573     exceed_dscp_str = format (0, "");
4574
4575   if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4576     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp);
4577   else
4578     violate_dscp_str = format (0, "");
4579
4580   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4581          "rate type %U, round type %U, %s rate, %s color-aware, "
4582          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4583          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4584          "conform action %U%s, exceed action %U%s, violate action %U%s",
4585          mp->name,
4586          format_policer_type, mp->type,
4587          ntohl (mp->cir),
4588          ntohl (mp->eir),
4589          clib_net_to_host_u64 (mp->cb),
4590          clib_net_to_host_u64 (mp->eb),
4591          format_policer_rate_type, mp->rate_type,
4592          format_policer_round_type, mp->round_type,
4593          mp->single_rate ? "single" : "dual",
4594          mp->color_aware ? "is" : "not",
4595          ntohl (mp->cir_tokens_per_period),
4596          ntohl (mp->pir_tokens_per_period),
4597          ntohl (mp->scale),
4598          ntohl (mp->current_limit),
4599          ntohl (mp->current_bucket),
4600          ntohl (mp->extended_limit),
4601          ntohl (mp->extended_bucket),
4602          clib_net_to_host_u64 (mp->last_update_time),
4603          format_policer_action_type, mp->conform_action.type,
4604          conform_dscp_str,
4605          format_policer_action_type, mp->exceed_action.type,
4606          exceed_dscp_str,
4607          format_policer_action_type, mp->violate_action.type,
4608          violate_dscp_str);
4609
4610   vec_free (conform_dscp_str);
4611   vec_free (exceed_dscp_str);
4612   vec_free (violate_dscp_str);
4613 }
4614
4615 static void vl_api_policer_details_t_handler_json
4616   (vl_api_policer_details_t * mp)
4617 {
4618   vat_main_t *vam = &vat_main;
4619   vat_json_node_t *node;
4620   u8 *rate_type_str, *round_type_str, *type_str;
4621   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4622
4623   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4624   round_type_str =
4625     format (0, "%U", format_policer_round_type, mp->round_type);
4626   type_str = format (0, "%U", format_policer_type, mp->type);
4627   conform_action_str = format (0, "%U", format_policer_action_type,
4628                                mp->conform_action.type);
4629   exceed_action_str = format (0, "%U", format_policer_action_type,
4630                               mp->exceed_action.type);
4631   violate_action_str = format (0, "%U", format_policer_action_type,
4632                                mp->violate_action.type);
4633
4634   if (VAT_JSON_ARRAY != vam->json_tree.type)
4635     {
4636       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4637       vat_json_init_array (&vam->json_tree);
4638     }
4639   node = vat_json_array_add (&vam->json_tree);
4640
4641   vat_json_init_object (node);
4642   vat_json_object_add_string_copy (node, "name", mp->name);
4643   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4644   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4645   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4646   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4647   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4648   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4649   vat_json_object_add_string_copy (node, "type", type_str);
4650   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4651   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4652   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4653   vat_json_object_add_uint (node, "cir_tokens_per_period",
4654                             ntohl (mp->cir_tokens_per_period));
4655   vat_json_object_add_uint (node, "eir_tokens_per_period",
4656                             ntohl (mp->pir_tokens_per_period));
4657   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4658   vat_json_object_add_uint (node, "current_bucket",
4659                             ntohl (mp->current_bucket));
4660   vat_json_object_add_uint (node, "extended_limit",
4661                             ntohl (mp->extended_limit));
4662   vat_json_object_add_uint (node, "extended_bucket",
4663                             ntohl (mp->extended_bucket));
4664   vat_json_object_add_uint (node, "last_update_time",
4665                             ntohl (mp->last_update_time));
4666   vat_json_object_add_string_copy (node, "conform_action",
4667                                    conform_action_str);
4668   if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4669     {
4670       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp);
4671       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4672       vec_free (dscp_str);
4673     }
4674   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4675   if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4676     {
4677       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp);
4678       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4679       vec_free (dscp_str);
4680     }
4681   vat_json_object_add_string_copy (node, "violate_action",
4682                                    violate_action_str);
4683   if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4684     {
4685       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp);
4686       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4687       vec_free (dscp_str);
4688     }
4689
4690   vec_free (rate_type_str);
4691   vec_free (round_type_str);
4692   vec_free (type_str);
4693   vec_free (conform_action_str);
4694   vec_free (exceed_action_str);
4695   vec_free (violate_action_str);
4696 }
4697
4698 static void
4699 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4700                                            mp)
4701 {
4702   vat_main_t *vam = &vat_main;
4703   int i, count = ntohl (mp->count);
4704
4705   if (count > 0)
4706     print (vam->ofp, "classify table ids (%d) : ", count);
4707   for (i = 0; i < count; i++)
4708     {
4709       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4710       print (vam->ofp, (i < count - 1) ? "," : "");
4711     }
4712   vam->retval = ntohl (mp->retval);
4713   vam->result_ready = 1;
4714 }
4715
4716 static void
4717   vl_api_classify_table_ids_reply_t_handler_json
4718   (vl_api_classify_table_ids_reply_t * mp)
4719 {
4720   vat_main_t *vam = &vat_main;
4721   int i, count = ntohl (mp->count);
4722
4723   if (count > 0)
4724     {
4725       vat_json_node_t node;
4726
4727       vat_json_init_object (&node);
4728       for (i = 0; i < count; i++)
4729         {
4730           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4731         }
4732       vat_json_print (vam->ofp, &node);
4733       vat_json_free (&node);
4734     }
4735   vam->retval = ntohl (mp->retval);
4736   vam->result_ready = 1;
4737 }
4738
4739 static void
4740   vl_api_classify_table_by_interface_reply_t_handler
4741   (vl_api_classify_table_by_interface_reply_t * mp)
4742 {
4743   vat_main_t *vam = &vat_main;
4744   u32 table_id;
4745
4746   table_id = ntohl (mp->l2_table_id);
4747   if (table_id != ~0)
4748     print (vam->ofp, "l2 table id : %d", table_id);
4749   else
4750     print (vam->ofp, "l2 table id : No input ACL tables configured");
4751   table_id = ntohl (mp->ip4_table_id);
4752   if (table_id != ~0)
4753     print (vam->ofp, "ip4 table id : %d", table_id);
4754   else
4755     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4756   table_id = ntohl (mp->ip6_table_id);
4757   if (table_id != ~0)
4758     print (vam->ofp, "ip6 table id : %d", table_id);
4759   else
4760     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4761   vam->retval = ntohl (mp->retval);
4762   vam->result_ready = 1;
4763 }
4764
4765 static void
4766   vl_api_classify_table_by_interface_reply_t_handler_json
4767   (vl_api_classify_table_by_interface_reply_t * mp)
4768 {
4769   vat_main_t *vam = &vat_main;
4770   vat_json_node_t node;
4771
4772   vat_json_init_object (&node);
4773
4774   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4775   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4776   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4777
4778   vat_json_print (vam->ofp, &node);
4779   vat_json_free (&node);
4780
4781   vam->retval = ntohl (mp->retval);
4782   vam->result_ready = 1;
4783 }
4784
4785 static void vl_api_policer_add_del_reply_t_handler
4786   (vl_api_policer_add_del_reply_t * mp)
4787 {
4788   vat_main_t *vam = &vat_main;
4789   i32 retval = ntohl (mp->retval);
4790   if (vam->async_mode)
4791     {
4792       vam->async_errors += (retval < 0);
4793     }
4794   else
4795     {
4796       vam->retval = retval;
4797       vam->result_ready = 1;
4798       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4799         /*
4800          * Note: this is just barely thread-safe, depends on
4801          * the main thread spinning waiting for an answer...
4802          */
4803         errmsg ("policer index %d", ntohl (mp->policer_index));
4804     }
4805 }
4806
4807 static void vl_api_policer_add_del_reply_t_handler_json
4808   (vl_api_policer_add_del_reply_t * mp)
4809 {
4810   vat_main_t *vam = &vat_main;
4811   vat_json_node_t node;
4812
4813   vat_json_init_object (&node);
4814   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4815   vat_json_object_add_uint (&node, "policer_index",
4816                             ntohl (mp->policer_index));
4817
4818   vat_json_print (vam->ofp, &node);
4819   vat_json_free (&node);
4820
4821   vam->retval = ntohl (mp->retval);
4822   vam->result_ready = 1;
4823 }
4824
4825 /* Format hex dump. */
4826 u8 *
4827 format_hex_bytes (u8 * s, va_list * va)
4828 {
4829   u8 *bytes = va_arg (*va, u8 *);
4830   int n_bytes = va_arg (*va, int);
4831   uword i;
4832
4833   /* Print short or long form depending on byte count. */
4834   uword short_form = n_bytes <= 32;
4835   u32 indent = format_get_indent (s);
4836
4837   if (n_bytes == 0)
4838     return s;
4839
4840   for (i = 0; i < n_bytes; i++)
4841     {
4842       if (!short_form && (i % 32) == 0)
4843         s = format (s, "%08x: ", i);
4844       s = format (s, "%02x", bytes[i]);
4845       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4846         s = format (s, "\n%U", format_white_space, indent);
4847     }
4848
4849   return s;
4850 }
4851
4852 static void
4853 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4854                                             * mp)
4855 {
4856   vat_main_t *vam = &vat_main;
4857   i32 retval = ntohl (mp->retval);
4858   if (retval == 0)
4859     {
4860       print (vam->ofp, "classify table info :");
4861       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4862              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4863              ntohl (mp->miss_next_index));
4864       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4865              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4866              ntohl (mp->match_n_vectors));
4867       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4868              ntohl (mp->mask_length));
4869     }
4870   vam->retval = retval;
4871   vam->result_ready = 1;
4872 }
4873
4874 static void
4875   vl_api_classify_table_info_reply_t_handler_json
4876   (vl_api_classify_table_info_reply_t * mp)
4877 {
4878   vat_main_t *vam = &vat_main;
4879   vat_json_node_t node;
4880
4881   i32 retval = ntohl (mp->retval);
4882   if (retval == 0)
4883     {
4884       vat_json_init_object (&node);
4885
4886       vat_json_object_add_int (&node, "sessions",
4887                                ntohl (mp->active_sessions));
4888       vat_json_object_add_int (&node, "nexttbl",
4889                                ntohl (mp->next_table_index));
4890       vat_json_object_add_int (&node, "nextnode",
4891                                ntohl (mp->miss_next_index));
4892       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4893       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4894       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4895       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4896                       ntohl (mp->mask_length), 0);
4897       vat_json_object_add_string_copy (&node, "mask", s);
4898
4899       vat_json_print (vam->ofp, &node);
4900       vat_json_free (&node);
4901     }
4902   vam->retval = ntohl (mp->retval);
4903   vam->result_ready = 1;
4904 }
4905
4906 static void
4907 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4908                                            mp)
4909 {
4910   vat_main_t *vam = &vat_main;
4911
4912   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4913          ntohl (mp->hit_next_index), ntohl (mp->advance),
4914          ntohl (mp->opaque_index));
4915   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4916          ntohl (mp->match_length));
4917 }
4918
4919 static void
4920   vl_api_classify_session_details_t_handler_json
4921   (vl_api_classify_session_details_t * mp)
4922 {
4923   vat_main_t *vam = &vat_main;
4924   vat_json_node_t *node = NULL;
4925
4926   if (VAT_JSON_ARRAY != vam->json_tree.type)
4927     {
4928       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4929       vat_json_init_array (&vam->json_tree);
4930     }
4931   node = vat_json_array_add (&vam->json_tree);
4932
4933   vat_json_init_object (node);
4934   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4935   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4936   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4937   u8 *s =
4938     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4939             0);
4940   vat_json_object_add_string_copy (node, "match", s);
4941 }
4942
4943 static void vl_api_pg_create_interface_reply_t_handler
4944   (vl_api_pg_create_interface_reply_t * mp)
4945 {
4946   vat_main_t *vam = &vat_main;
4947
4948   vam->retval = ntohl (mp->retval);
4949   vam->result_ready = 1;
4950 }
4951
4952 static void vl_api_pg_create_interface_reply_t_handler_json
4953   (vl_api_pg_create_interface_reply_t * mp)
4954 {
4955   vat_main_t *vam = &vat_main;
4956   vat_json_node_t node;
4957
4958   i32 retval = ntohl (mp->retval);
4959   if (retval == 0)
4960     {
4961       vat_json_init_object (&node);
4962
4963       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4964
4965       vat_json_print (vam->ofp, &node);
4966       vat_json_free (&node);
4967     }
4968   vam->retval = ntohl (mp->retval);
4969   vam->result_ready = 1;
4970 }
4971
4972 static void vl_api_policer_classify_details_t_handler
4973   (vl_api_policer_classify_details_t * mp)
4974 {
4975   vat_main_t *vam = &vat_main;
4976
4977   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4978          ntohl (mp->table_index));
4979 }
4980
4981 static void vl_api_policer_classify_details_t_handler_json
4982   (vl_api_policer_classify_details_t * mp)
4983 {
4984   vat_main_t *vam = &vat_main;
4985   vat_json_node_t *node;
4986
4987   if (VAT_JSON_ARRAY != vam->json_tree.type)
4988     {
4989       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4990       vat_json_init_array (&vam->json_tree);
4991     }
4992   node = vat_json_array_add (&vam->json_tree);
4993
4994   vat_json_init_object (node);
4995   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4996   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4997 }
4998
4999 static void vl_api_flow_classify_details_t_handler
5000   (vl_api_flow_classify_details_t * mp)
5001 {
5002   vat_main_t *vam = &vat_main;
5003
5004   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5005          ntohl (mp->table_index));
5006 }
5007
5008 static void vl_api_flow_classify_details_t_handler_json
5009   (vl_api_flow_classify_details_t * mp)
5010 {
5011   vat_main_t *vam = &vat_main;
5012   vat_json_node_t *node;
5013
5014   if (VAT_JSON_ARRAY != vam->json_tree.type)
5015     {
5016       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5017       vat_json_init_array (&vam->json_tree);
5018     }
5019   node = vat_json_array_add (&vam->json_tree);
5020
5021   vat_json_init_object (node);
5022   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5023   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5024 }
5025
5026 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5027 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5028 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5029 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5030 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5031 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5032 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5033 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5034 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5035 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5036
5037 /*
5038  * Generate boilerplate reply handlers, which
5039  * dig the return value out of the xxx_reply_t API message,
5040  * stick it into vam->retval, and set vam->result_ready
5041  *
5042  * Could also do this by pointing N message decode slots at
5043  * a single function, but that could break in subtle ways.
5044  */
5045
5046 #define foreach_standard_reply_retval_handler           \
5047 _(sw_interface_set_flags_reply)                         \
5048 _(sw_interface_add_del_address_reply)                   \
5049 _(sw_interface_set_rx_mode_reply)                       \
5050 _(sw_interface_set_rx_placement_reply)                  \
5051 _(sw_interface_set_table_reply)                         \
5052 _(sw_interface_set_mpls_enable_reply)                   \
5053 _(sw_interface_set_vpath_reply)                         \
5054 _(sw_interface_set_vxlan_bypass_reply)                  \
5055 _(sw_interface_set_geneve_bypass_reply)                 \
5056 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5057 _(sw_interface_set_l2_bridge_reply)                     \
5058 _(sw_interface_set_bond_weight_reply)                   \
5059 _(bridge_domain_add_del_reply)                          \
5060 _(sw_interface_set_l2_xconnect_reply)                   \
5061 _(l2fib_add_del_reply)                                  \
5062 _(l2fib_flush_int_reply)                                \
5063 _(l2fib_flush_bd_reply)                                 \
5064 _(ip_route_add_del_reply)                               \
5065 _(ip_table_add_del_reply)                               \
5066 _(ip_table_replace_begin_reply)                         \
5067 _(ip_table_flush_reply)                                 \
5068 _(ip_table_replace_end_reply)                           \
5069 _(ip_mroute_add_del_reply)                              \
5070 _(mpls_route_add_del_reply)                             \
5071 _(mpls_table_add_del_reply)                             \
5072 _(mpls_ip_bind_unbind_reply)                            \
5073 _(bier_route_add_del_reply)                             \
5074 _(bier_table_add_del_reply)                             \
5075 _(sw_interface_set_unnumbered_reply)                    \
5076 _(set_ip_flow_hash_reply)                               \
5077 _(sw_interface_ip6_enable_disable_reply)                \
5078 _(l2_patch_add_del_reply)                               \
5079 _(sr_mpls_policy_add_reply)                             \
5080 _(sr_mpls_policy_mod_reply)                             \
5081 _(sr_mpls_policy_del_reply)                             \
5082 _(sr_policy_add_reply)                                  \
5083 _(sr_policy_mod_reply)                                  \
5084 _(sr_policy_del_reply)                                  \
5085 _(sr_localsid_add_del_reply)                            \
5086 _(sr_steering_add_del_reply)                            \
5087 _(classify_add_del_session_reply)                       \
5088 _(classify_set_interface_ip_table_reply)                \
5089 _(classify_set_interface_l2_tables_reply)               \
5090 _(l2tpv3_set_tunnel_cookies_reply)                      \
5091 _(l2tpv3_interface_enable_disable_reply)                \
5092 _(l2tpv3_set_lookup_key_reply)                          \
5093 _(l2_fib_clear_table_reply)                             \
5094 _(l2_interface_efp_filter_reply)                        \
5095 _(l2_interface_vlan_tag_rewrite_reply)                  \
5096 _(modify_vhost_user_if_reply)                           \
5097 _(delete_vhost_user_if_reply)                           \
5098 _(want_l2_macs_events_reply)                            \
5099 _(input_acl_set_interface_reply)                        \
5100 _(ipsec_spd_add_del_reply)                              \
5101 _(ipsec_interface_add_del_spd_reply)                    \
5102 _(ipsec_spd_entry_add_del_reply)                        \
5103 _(ipsec_sad_entry_add_del_reply)                        \
5104 _(ipsec_tunnel_if_add_del_reply)                        \
5105 _(ipsec_tunnel_if_set_sa_reply)                         \
5106 _(delete_loopback_reply)                                \
5107 _(bd_ip_mac_add_del_reply)                              \
5108 _(bd_ip_mac_flush_reply)                                \
5109 _(want_interface_events_reply)                          \
5110 _(cop_interface_enable_disable_reply)                   \
5111 _(cop_whitelist_enable_disable_reply)                   \
5112 _(sw_interface_clear_stats_reply)                       \
5113 _(ioam_enable_reply)                                    \
5114 _(ioam_disable_reply)                                   \
5115 _(one_add_del_locator_reply)                            \
5116 _(one_add_del_local_eid_reply)                          \
5117 _(one_add_del_remote_mapping_reply)                     \
5118 _(one_add_del_adjacency_reply)                          \
5119 _(one_add_del_map_resolver_reply)                       \
5120 _(one_add_del_map_server_reply)                         \
5121 _(one_enable_disable_reply)                             \
5122 _(one_rloc_probe_enable_disable_reply)                  \
5123 _(one_map_register_enable_disable_reply)                \
5124 _(one_map_register_set_ttl_reply)                       \
5125 _(one_set_transport_protocol_reply)                     \
5126 _(one_map_register_fallback_threshold_reply)            \
5127 _(one_pitr_set_locator_set_reply)                       \
5128 _(one_map_request_mode_reply)                           \
5129 _(one_add_del_map_request_itr_rlocs_reply)              \
5130 _(one_eid_table_add_del_map_reply)                      \
5131 _(one_use_petr_reply)                                   \
5132 _(one_stats_enable_disable_reply)                       \
5133 _(one_add_del_l2_arp_entry_reply)                       \
5134 _(one_add_del_ndp_entry_reply)                          \
5135 _(one_stats_flush_reply)                                \
5136 _(one_enable_disable_xtr_mode_reply)                    \
5137 _(one_enable_disable_pitr_mode_reply)                   \
5138 _(one_enable_disable_petr_mode_reply)                   \
5139 _(gpe_enable_disable_reply)                             \
5140 _(gpe_set_encap_mode_reply)                             \
5141 _(gpe_add_del_iface_reply)                              \
5142 _(gpe_add_del_native_fwd_rpath_reply)                   \
5143 _(af_packet_delete_reply)                               \
5144 _(policer_classify_set_interface_reply)                 \
5145 _(set_ipfix_exporter_reply)                             \
5146 _(set_ipfix_classify_stream_reply)                      \
5147 _(ipfix_classify_table_add_del_reply)                   \
5148 _(flow_classify_set_interface_reply)                    \
5149 _(sw_interface_span_enable_disable_reply)               \
5150 _(pg_capture_reply)                                     \
5151 _(pg_enable_disable_reply)                              \
5152 _(pg_interface_enable_disable_coalesce_reply)           \
5153 _(ip_source_and_port_range_check_add_del_reply)         \
5154 _(ip_source_and_port_range_check_interface_add_del_reply)\
5155 _(delete_subif_reply)                                   \
5156 _(l2_interface_pbb_tag_rewrite_reply)                   \
5157 _(set_punt_reply)                                       \
5158 _(feature_enable_disable_reply)                         \
5159 _(feature_gso_enable_disable_reply)                     \
5160 _(sw_interface_tag_add_del_reply)                       \
5161 _(sw_interface_add_del_mac_address_reply)               \
5162 _(hw_interface_set_mtu_reply)                           \
5163 _(p2p_ethernet_add_reply)                               \
5164 _(p2p_ethernet_del_reply)                               \
5165 _(lldp_config_reply)                                    \
5166 _(sw_interface_set_lldp_reply)                          \
5167 _(tcp_configure_src_addresses_reply)                    \
5168 _(session_rule_add_del_reply)                           \
5169 _(ip_container_proxy_add_del_reply)                     \
5170 _(output_acl_set_interface_reply)                       \
5171 _(qos_record_enable_disable_reply)                      \
5172 _(flow_add_reply)
5173
5174 #define _(n)                                    \
5175     static void vl_api_##n##_t_handler          \
5176     (vl_api_##n##_t * mp)                       \
5177     {                                           \
5178         vat_main_t * vam = &vat_main;           \
5179         i32 retval = ntohl(mp->retval);         \
5180         if (vam->async_mode) {                  \
5181             vam->async_errors += (retval < 0);  \
5182         } else {                                \
5183             vam->retval = retval;               \
5184             vam->result_ready = 1;              \
5185         }                                       \
5186     }
5187 foreach_standard_reply_retval_handler;
5188 #undef _
5189
5190 #define _(n)                                    \
5191     static void vl_api_##n##_t_handler_json     \
5192     (vl_api_##n##_t * mp)                       \
5193     {                                           \
5194         vat_main_t * vam = &vat_main;           \
5195         vat_json_node_t node;                   \
5196         vat_json_init_object(&node);            \
5197         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5198         vat_json_print(vam->ofp, &node);        \
5199         vam->retval = ntohl(mp->retval);        \
5200         vam->result_ready = 1;                  \
5201     }
5202 foreach_standard_reply_retval_handler;
5203 #undef _
5204
5205 /*
5206  * Table of message reply handlers, must include boilerplate handlers
5207  * we just generated
5208  */
5209
5210 #define foreach_vpe_api_reply_msg                                       \
5211 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5212 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5213 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5214 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5215 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5216 _(CLI_REPLY, cli_reply)                                                 \
5217 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5218 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5219   sw_interface_add_del_address_reply)                                   \
5220 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5221 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5222 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5223 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5224 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5225 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5226 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5227 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5228 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5229 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5230   sw_interface_set_l2_xconnect_reply)                                   \
5231 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5232   sw_interface_set_l2_bridge_reply)                                     \
5233 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5234 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5235 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5236 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5237 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5238 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5239 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5240 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5241 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5242 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5243 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5244 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5245 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5246 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5247 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5248 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5249 _(BOND_ADD_MEMBER_REPLY, bond_add_member_reply)                         \
5250 _(BOND_DETACH_MEMBER_REPLY, bond_detach_member_reply)                   \
5251 _(SW_INTERFACE_SET_BOND_WEIGHT_REPLY, sw_interface_set_bond_weight_reply) \
5252 _(SW_BOND_INTERFACE_DETAILS, sw_bond_interface_details)                 \
5253 _(SW_MEMBER_INTERFACE_DETAILS, sw_member_interface_details)               \
5254 _(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply)                       \
5255 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5256 _(IP_TABLE_REPLACE_BEGIN_REPLY, ip_table_replace_begin_reply)           \
5257 _(IP_TABLE_FLUSH_REPLY, ip_table_flush_reply)                           \
5258 _(IP_TABLE_REPLACE_END_REPLY, ip_table_replace_end_reply)               \
5259 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5260 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5261 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5262 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5263 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5264 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5265 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5266 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5267   sw_interface_set_unnumbered_reply)                                    \
5268 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5269 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5270 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5271 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5272   sw_interface_ip6_enable_disable_reply)                                \
5273 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5274 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5275 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5276 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5277 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5278 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5279 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5280 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5281 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5282 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5283 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5284 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5285 classify_set_interface_ip_table_reply)                                  \
5286 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5287   classify_set_interface_l2_tables_reply)                               \
5288 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5289 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5290 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5291 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5292 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5293   l2tpv3_interface_enable_disable_reply)                                \
5294 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5295 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5296 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5297 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5298 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5299 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5300 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5301 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5302 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5303 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5304 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5305 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5306 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5307 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5308 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5309 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5310 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5311 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5312 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5313 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5314 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5315 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5316 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5317 _(L2_MACS_EVENT, l2_macs_event)                                         \
5318 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5319 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5320 _(IP_DETAILS, ip_details)                                               \
5321 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5322 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5323 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5324 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5325 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5326 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5327 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5328 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5329 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5330 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5331 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5332 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5333 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5334 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5335 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5336 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5337 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5338 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5339 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5340 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5341 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5342 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5343 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5344 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5345 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5346 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5347 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5348 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5349   one_map_register_enable_disable_reply)                                \
5350 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5351 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5352 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5353 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5354   one_map_register_fallback_threshold_reply)                            \
5355 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5356   one_rloc_probe_enable_disable_reply)                                  \
5357 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5358 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5359 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5360 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5361 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5362 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5363 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5364 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5365 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5366 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5367 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5368 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5369 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5370 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5371 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5372 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5373   show_one_stats_enable_disable_reply)                                  \
5374 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5375 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5376 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5377 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5378 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5379 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5380 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5381 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5382   one_enable_disable_pitr_mode_reply)                                   \
5383 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5384   one_enable_disable_petr_mode_reply)                                   \
5385 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5386 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5387 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5388 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5389 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5390 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5391 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5392 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5393 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5394 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5395 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5396 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5397   gpe_add_del_native_fwd_rpath_reply)                                   \
5398 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5399   gpe_fwd_entry_path_details)                                           \
5400 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5401 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5402   one_add_del_map_request_itr_rlocs_reply)                              \
5403 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5404   one_get_map_request_itr_rlocs_reply)                                  \
5405 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5406 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5407 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5408 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5409 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5410 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5411   show_one_map_register_state_reply)                                    \
5412 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5413 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5414   show_one_map_register_fallback_threshold_reply)                       \
5415 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5416 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5417 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5418 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5419 _(POLICER_DETAILS, policer_details)                                     \
5420 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5421 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5422 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5423 _(MPLS_TABLE_DETAILS, mpls_table_details)                               \
5424 _(MPLS_ROUTE_DETAILS, mpls_route_details)                               \
5425 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5426 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5427 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5428 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5429 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5430 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5431 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5432 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5433 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5434 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5435 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5436 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5437 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5438 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5439 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5440 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5441 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5442 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5443 _(PG_INTERFACE_ENABLE_DISABLE_COALESCE_REPLY, pg_interface_enable_disable_coalesce_reply) \
5444 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5445  ip_source_and_port_range_check_add_del_reply)                          \
5446 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5447  ip_source_and_port_range_check_interface_add_del_reply)                \
5448 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5449 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5450 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5451 _(IP_TABLE_DETAILS, ip_table_details)                                   \
5452 _(IP_ROUTE_DETAILS, ip_route_details)                                   \
5453 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5454 _(FEATURE_GSO_ENABLE_DISABLE_REPLY, feature_gso_enable_disable_reply)   \
5455 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5456 _(SW_INTERFACE_ADD_DEL_MAC_ADDRESS_REPLY, sw_interface_add_del_mac_address_reply) \
5457 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5458 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5459 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5460 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5461 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5462 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5463 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5464 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5465 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5466 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5467 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5468 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5469 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5470 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)             \
5471 _(FLOW_ADD_REPLY, flow_add_reply)   \
5472
5473 #define foreach_standalone_reply_msg                                    \
5474 _(SW_INTERFACE_EVENT, sw_interface_event)
5475
5476 typedef struct
5477 {
5478   u8 *name;
5479   u32 value;
5480 } name_sort_t;
5481
5482 #define STR_VTR_OP_CASE(op)     \
5483     case L2_VTR_ ## op:         \
5484         return "" # op;
5485
5486 static const char *
5487 str_vtr_op (u32 vtr_op)
5488 {
5489   switch (vtr_op)
5490     {
5491       STR_VTR_OP_CASE (DISABLED);
5492       STR_VTR_OP_CASE (PUSH_1);
5493       STR_VTR_OP_CASE (PUSH_2);
5494       STR_VTR_OP_CASE (POP_1);
5495       STR_VTR_OP_CASE (POP_2);
5496       STR_VTR_OP_CASE (TRANSLATE_1_1);
5497       STR_VTR_OP_CASE (TRANSLATE_1_2);
5498       STR_VTR_OP_CASE (TRANSLATE_2_1);
5499       STR_VTR_OP_CASE (TRANSLATE_2_2);
5500     }
5501
5502   return "UNKNOWN";
5503 }
5504
5505 static int
5506 dump_sub_interface_table (vat_main_t * vam)
5507 {
5508   const sw_interface_subif_t *sub = NULL;
5509
5510   if (vam->json_output)
5511     {
5512       clib_warning
5513         ("JSON output supported only for VPE API calls and dump_stats_table");
5514       return -99;
5515     }
5516
5517   print (vam->ofp,
5518          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5519          "Interface", "sw_if_index",
5520          "sub id", "dot1ad", "tags", "outer id",
5521          "inner id", "exact", "default", "outer any", "inner any");
5522
5523   vec_foreach (sub, vam->sw_if_subif_table)
5524   {
5525     print (vam->ofp,
5526            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5527            sub->interface_name,
5528            sub->sw_if_index,
5529            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5530            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5531            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5532            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5533     if (sub->vtr_op != L2_VTR_DISABLED)
5534       {
5535         print (vam->ofp,
5536                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5537                "tag1: %d tag2: %d ]",
5538                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5539                sub->vtr_tag1, sub->vtr_tag2);
5540       }
5541   }
5542
5543   return 0;
5544 }
5545
5546 static int
5547 name_sort_cmp (void *a1, void *a2)
5548 {
5549   name_sort_t *n1 = a1;
5550   name_sort_t *n2 = a2;
5551
5552   return strcmp ((char *) n1->name, (char *) n2->name);
5553 }
5554
5555 static int
5556 dump_interface_table (vat_main_t * vam)
5557 {
5558   hash_pair_t *p;
5559   name_sort_t *nses = 0, *ns;
5560
5561   if (vam->json_output)
5562     {
5563       clib_warning
5564         ("JSON output supported only for VPE API calls and dump_stats_table");
5565       return -99;
5566     }
5567
5568   /* *INDENT-OFF* */
5569   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5570   ({
5571     vec_add2 (nses, ns, 1);
5572     ns->name = (u8 *)(p->key);
5573     ns->value = (u32) p->value[0];
5574   }));
5575   /* *INDENT-ON* */
5576
5577   vec_sort_with_function (nses, name_sort_cmp);
5578
5579   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5580   vec_foreach (ns, nses)
5581   {
5582     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5583   }
5584   vec_free (nses);
5585   return 0;
5586 }
5587
5588 static int
5589 dump_ip_table (vat_main_t * vam, int is_ipv6)
5590 {
5591   const ip_details_t *det = NULL;
5592   const ip_address_details_t *address = NULL;
5593   u32 i = ~0;
5594
5595   print (vam->ofp, "%-12s", "sw_if_index");
5596
5597   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5598   {
5599     i++;
5600     if (!det->present)
5601       {
5602         continue;
5603       }
5604     print (vam->ofp, "%-12d", i);
5605     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5606     if (!det->addr)
5607       {
5608         continue;
5609       }
5610     vec_foreach (address, det->addr)
5611     {
5612       print (vam->ofp,
5613              "            %-30U%-13d",
5614              is_ipv6 ? format_ip6_address : format_ip4_address,
5615              address->ip, address->prefix_length);
5616     }
5617   }
5618
5619   return 0;
5620 }
5621
5622 static int
5623 dump_ipv4_table (vat_main_t * vam)
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   return dump_ip_table (vam, 0);
5633 }
5634
5635 static int
5636 dump_ipv6_table (vat_main_t * vam)
5637 {
5638   if (vam->json_output)
5639     {
5640       clib_warning
5641         ("JSON output supported only for VPE API calls and dump_stats_table");
5642       return -99;
5643     }
5644
5645   return dump_ip_table (vam, 1);
5646 }
5647
5648 /*
5649  * Pass CLI buffers directly in the CLI_INBAND API message,
5650  * instead of an additional shared memory area.
5651  */
5652 static int
5653 exec_inband (vat_main_t * vam)
5654 {
5655   vl_api_cli_inband_t *mp;
5656   unformat_input_t *i = vam->input;
5657   int ret;
5658
5659   if (vec_len (i->buffer) == 0)
5660     return -1;
5661
5662   if (vam->exec_mode == 0 && unformat (i, "mode"))
5663     {
5664       vam->exec_mode = 1;
5665       return 0;
5666     }
5667   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5668     {
5669       vam->exec_mode = 0;
5670       return 0;
5671     }
5672
5673   /*
5674    * In order for the CLI command to work, it
5675    * must be a vector ending in \n, not a C-string ending
5676    * in \n\0.
5677    */
5678   M2 (CLI_INBAND, mp, vec_len (vam->input->buffer));
5679   vl_api_vec_to_api_string (vam->input->buffer, &mp->cmd);
5680
5681   S (mp);
5682   W (ret);
5683   /* json responses may or may not include a useful reply... */
5684   if (vec_len (vam->cmd_reply))
5685     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5686   return ret;
5687 }
5688
5689 int
5690 exec (vat_main_t * vam)
5691 {
5692   return exec_inband (vam);
5693 }
5694
5695 static int
5696 api_create_loopback (vat_main_t * vam)
5697 {
5698   unformat_input_t *i = vam->input;
5699   vl_api_create_loopback_t *mp;
5700   vl_api_create_loopback_instance_t *mp_lbi;
5701   u8 mac_address[6];
5702   u8 mac_set = 0;
5703   u8 is_specified = 0;
5704   u32 user_instance = 0;
5705   int ret;
5706
5707   clib_memset (mac_address, 0, sizeof (mac_address));
5708
5709   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5710     {
5711       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5712         mac_set = 1;
5713       if (unformat (i, "instance %d", &user_instance))
5714         is_specified = 1;
5715       else
5716         break;
5717     }
5718
5719   if (is_specified)
5720     {
5721       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5722       mp_lbi->is_specified = is_specified;
5723       if (is_specified)
5724         mp_lbi->user_instance = htonl (user_instance);
5725       if (mac_set)
5726         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5727       S (mp_lbi);
5728     }
5729   else
5730     {
5731       /* Construct the API message */
5732       M (CREATE_LOOPBACK, mp);
5733       if (mac_set)
5734         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5735       S (mp);
5736     }
5737
5738   W (ret);
5739   return ret;
5740 }
5741
5742 static int
5743 api_delete_loopback (vat_main_t * vam)
5744 {
5745   unformat_input_t *i = vam->input;
5746   vl_api_delete_loopback_t *mp;
5747   u32 sw_if_index = ~0;
5748   int ret;
5749
5750   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5751     {
5752       if (unformat (i, "sw_if_index %d", &sw_if_index))
5753         ;
5754       else
5755         break;
5756     }
5757
5758   if (sw_if_index == ~0)
5759     {
5760       errmsg ("missing sw_if_index");
5761       return -99;
5762     }
5763
5764   /* Construct the API message */
5765   M (DELETE_LOOPBACK, mp);
5766   mp->sw_if_index = ntohl (sw_if_index);
5767
5768   S (mp);
5769   W (ret);
5770   return ret;
5771 }
5772
5773 static int
5774 api_want_interface_events (vat_main_t * vam)
5775 {
5776   unformat_input_t *i = vam->input;
5777   vl_api_want_interface_events_t *mp;
5778   int enable = -1;
5779   int ret;
5780
5781   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5782     {
5783       if (unformat (i, "enable"))
5784         enable = 1;
5785       else if (unformat (i, "disable"))
5786         enable = 0;
5787       else
5788         break;
5789     }
5790
5791   if (enable == -1)
5792     {
5793       errmsg ("missing enable|disable");
5794       return -99;
5795     }
5796
5797   M (WANT_INTERFACE_EVENTS, mp);
5798   mp->enable_disable = enable;
5799
5800   vam->interface_event_display = enable;
5801
5802   S (mp);
5803   W (ret);
5804   return ret;
5805 }
5806
5807
5808 /* Note: non-static, called once to set up the initial intfc table */
5809 int
5810 api_sw_interface_dump (vat_main_t * vam)
5811 {
5812   vl_api_sw_interface_dump_t *mp;
5813   vl_api_control_ping_t *mp_ping;
5814   hash_pair_t *p;
5815   name_sort_t *nses = 0, *ns;
5816   sw_interface_subif_t *sub = NULL;
5817   int ret;
5818
5819   /* Toss the old name table */
5820   /* *INDENT-OFF* */
5821   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5822   ({
5823     vec_add2 (nses, ns, 1);
5824     ns->name = (u8 *)(p->key);
5825     ns->value = (u32) p->value[0];
5826   }));
5827   /* *INDENT-ON* */
5828
5829   hash_free (vam->sw_if_index_by_interface_name);
5830
5831   vec_foreach (ns, nses) vec_free (ns->name);
5832
5833   vec_free (nses);
5834
5835   vec_foreach (sub, vam->sw_if_subif_table)
5836   {
5837     vec_free (sub->interface_name);
5838   }
5839   vec_free (vam->sw_if_subif_table);
5840
5841   /* recreate the interface name hash table */
5842   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5843
5844   /*
5845    * Ask for all interface names. Otherwise, the epic catalog of
5846    * name filters becomes ridiculously long, and vat ends up needing
5847    * to be taught about new interface types.
5848    */
5849   M (SW_INTERFACE_DUMP, mp);
5850   S (mp);
5851
5852   /* Use a control ping for synchronization */
5853   MPING (CONTROL_PING, mp_ping);
5854   S (mp_ping);
5855
5856   W (ret);
5857   return ret;
5858 }
5859
5860 static int
5861 api_sw_interface_set_flags (vat_main_t * vam)
5862 {
5863   unformat_input_t *i = vam->input;
5864   vl_api_sw_interface_set_flags_t *mp;
5865   u32 sw_if_index;
5866   u8 sw_if_index_set = 0;
5867   u8 admin_up = 0;
5868   int ret;
5869
5870   /* Parse args required to build the message */
5871   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5872     {
5873       if (unformat (i, "admin-up"))
5874         admin_up = 1;
5875       else if (unformat (i, "admin-down"))
5876         admin_up = 0;
5877       else
5878         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5879         sw_if_index_set = 1;
5880       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5881         sw_if_index_set = 1;
5882       else
5883         break;
5884     }
5885
5886   if (sw_if_index_set == 0)
5887     {
5888       errmsg ("missing interface name or sw_if_index");
5889       return -99;
5890     }
5891
5892   /* Construct the API message */
5893   M (SW_INTERFACE_SET_FLAGS, mp);
5894   mp->sw_if_index = ntohl (sw_if_index);
5895   mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
5896
5897   /* send it... */
5898   S (mp);
5899
5900   /* Wait for a reply, return the good/bad news... */
5901   W (ret);
5902   return ret;
5903 }
5904
5905 static int
5906 api_sw_interface_set_rx_mode (vat_main_t * vam)
5907 {
5908   unformat_input_t *i = vam->input;
5909   vl_api_sw_interface_set_rx_mode_t *mp;
5910   u32 sw_if_index;
5911   u8 sw_if_index_set = 0;
5912   int ret;
5913   u8 queue_id_valid = 0;
5914   u32 queue_id;
5915   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
5916
5917   /* Parse args required to build the message */
5918   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5919     {
5920       if (unformat (i, "queue %d", &queue_id))
5921         queue_id_valid = 1;
5922       else if (unformat (i, "polling"))
5923         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
5924       else if (unformat (i, "interrupt"))
5925         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
5926       else if (unformat (i, "adaptive"))
5927         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
5928       else
5929         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5930         sw_if_index_set = 1;
5931       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5932         sw_if_index_set = 1;
5933       else
5934         break;
5935     }
5936
5937   if (sw_if_index_set == 0)
5938     {
5939       errmsg ("missing interface name or sw_if_index");
5940       return -99;
5941     }
5942   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
5943     {
5944       errmsg ("missing rx-mode");
5945       return -99;
5946     }
5947
5948   /* Construct the API message */
5949   M (SW_INTERFACE_SET_RX_MODE, mp);
5950   mp->sw_if_index = ntohl (sw_if_index);
5951   mp->mode = (vl_api_rx_mode_t) mode;
5952   mp->queue_id_valid = queue_id_valid;
5953   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
5954
5955   /* send it... */
5956   S (mp);
5957
5958   /* Wait for a reply, return the good/bad news... */
5959   W (ret);
5960   return ret;
5961 }
5962
5963 static int
5964 api_sw_interface_set_rx_placement (vat_main_t * vam)
5965 {
5966   unformat_input_t *i = vam->input;
5967   vl_api_sw_interface_set_rx_placement_t *mp;
5968   u32 sw_if_index;
5969   u8 sw_if_index_set = 0;
5970   int ret;
5971   u8 is_main = 0;
5972   u32 queue_id, thread_index;
5973
5974   /* Parse args required to build the message */
5975   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5976     {
5977       if (unformat (i, "queue %d", &queue_id))
5978         ;
5979       else if (unformat (i, "main"))
5980         is_main = 1;
5981       else if (unformat (i, "worker %d", &thread_index))
5982         ;
5983       else
5984         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5985         sw_if_index_set = 1;
5986       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5987         sw_if_index_set = 1;
5988       else
5989         break;
5990     }
5991
5992   if (sw_if_index_set == 0)
5993     {
5994       errmsg ("missing interface name or sw_if_index");
5995       return -99;
5996     }
5997
5998   if (is_main)
5999     thread_index = 0;
6000   /* Construct the API message */
6001   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6002   mp->sw_if_index = ntohl (sw_if_index);
6003   mp->worker_id = ntohl (thread_index);
6004   mp->queue_id = ntohl (queue_id);
6005   mp->is_main = is_main;
6006
6007   /* send it... */
6008   S (mp);
6009   /* Wait for a reply, return the good/bad news... */
6010   W (ret);
6011   return ret;
6012 }
6013
6014 static void vl_api_sw_interface_rx_placement_details_t_handler
6015   (vl_api_sw_interface_rx_placement_details_t * mp)
6016 {
6017   vat_main_t *vam = &vat_main;
6018   u32 worker_id = ntohl (mp->worker_id);
6019
6020   print (vam->ofp,
6021          "\n%-11d %-11s %-6d %-5d %-9s",
6022          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6023          worker_id, ntohl (mp->queue_id),
6024          (mp->mode ==
6025           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6026 }
6027
6028 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6029   (vl_api_sw_interface_rx_placement_details_t * mp)
6030 {
6031   vat_main_t *vam = &vat_main;
6032   vat_json_node_t *node = NULL;
6033
6034   if (VAT_JSON_ARRAY != vam->json_tree.type)
6035     {
6036       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6037       vat_json_init_array (&vam->json_tree);
6038     }
6039   node = vat_json_array_add (&vam->json_tree);
6040
6041   vat_json_init_object (node);
6042   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6043   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6044   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6045   vat_json_object_add_uint (node, "mode", mp->mode);
6046 }
6047
6048 static int
6049 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6050 {
6051   unformat_input_t *i = vam->input;
6052   vl_api_sw_interface_rx_placement_dump_t *mp;
6053   vl_api_control_ping_t *mp_ping;
6054   int ret;
6055   u32 sw_if_index;
6056   u8 sw_if_index_set = 0;
6057
6058   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6059     {
6060       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6061         sw_if_index_set++;
6062       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6063         sw_if_index_set++;
6064       else
6065         break;
6066     }
6067
6068   print (vam->ofp,
6069          "\n%-11s %-11s %-6s %-5s %-4s",
6070          "sw_if_index", "main/worker", "thread", "queue", "mode");
6071
6072   /* Dump Interface rx placement */
6073   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6074
6075   if (sw_if_index_set)
6076     mp->sw_if_index = htonl (sw_if_index);
6077   else
6078     mp->sw_if_index = ~0;
6079
6080   S (mp);
6081
6082   /* Use a control ping for synchronization */
6083   MPING (CONTROL_PING, mp_ping);
6084   S (mp_ping);
6085
6086   W (ret);
6087   return ret;
6088 }
6089
6090 static int
6091 api_sw_interface_clear_stats (vat_main_t * vam)
6092 {
6093   unformat_input_t *i = vam->input;
6094   vl_api_sw_interface_clear_stats_t *mp;
6095   u32 sw_if_index;
6096   u8 sw_if_index_set = 0;
6097   int ret;
6098
6099   /* Parse args required to build the message */
6100   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6101     {
6102       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6103         sw_if_index_set = 1;
6104       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6105         sw_if_index_set = 1;
6106       else
6107         break;
6108     }
6109
6110   /* Construct the API message */
6111   M (SW_INTERFACE_CLEAR_STATS, mp);
6112
6113   if (sw_if_index_set == 1)
6114     mp->sw_if_index = ntohl (sw_if_index);
6115   else
6116     mp->sw_if_index = ~0;
6117
6118   /* send it... */
6119   S (mp);
6120
6121   /* Wait for a reply, return the good/bad news... */
6122   W (ret);
6123   return ret;
6124 }
6125
6126 static int
6127 api_sw_interface_add_del_address (vat_main_t * vam)
6128 {
6129   unformat_input_t *i = vam->input;
6130   vl_api_sw_interface_add_del_address_t *mp;
6131   u32 sw_if_index;
6132   u8 sw_if_index_set = 0;
6133   u8 is_add = 1, del_all = 0;
6134   u32 address_length = 0;
6135   u8 v4_address_set = 0;
6136   u8 v6_address_set = 0;
6137   ip4_address_t v4address;
6138   ip6_address_t v6address;
6139   int ret;
6140
6141   /* Parse args required to build the message */
6142   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6143     {
6144       if (unformat (i, "del-all"))
6145         del_all = 1;
6146       else if (unformat (i, "del"))
6147         is_add = 0;
6148       else
6149         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6150         sw_if_index_set = 1;
6151       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6152         sw_if_index_set = 1;
6153       else if (unformat (i, "%U/%d",
6154                          unformat_ip4_address, &v4address, &address_length))
6155         v4_address_set = 1;
6156       else if (unformat (i, "%U/%d",
6157                          unformat_ip6_address, &v6address, &address_length))
6158         v6_address_set = 1;
6159       else
6160         break;
6161     }
6162
6163   if (sw_if_index_set == 0)
6164     {
6165       errmsg ("missing interface name or sw_if_index");
6166       return -99;
6167     }
6168   if (v4_address_set && v6_address_set)
6169     {
6170       errmsg ("both v4 and v6 addresses set");
6171       return -99;
6172     }
6173   if (!v4_address_set && !v6_address_set && !del_all)
6174     {
6175       errmsg ("no addresses set");
6176       return -99;
6177     }
6178
6179   /* Construct the API message */
6180   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6181
6182   mp->sw_if_index = ntohl (sw_if_index);
6183   mp->is_add = is_add;
6184   mp->del_all = del_all;
6185   if (v6_address_set)
6186     {
6187       mp->prefix.address.af = ADDRESS_IP6;
6188       clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
6189     }
6190   else
6191     {
6192       mp->prefix.address.af = ADDRESS_IP4;
6193       clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
6194     }
6195   mp->prefix.len = address_length;
6196
6197   /* send it... */
6198   S (mp);
6199
6200   /* Wait for a reply, return good/bad news  */
6201   W (ret);
6202   return ret;
6203 }
6204
6205 static int
6206 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6207 {
6208   unformat_input_t *i = vam->input;
6209   vl_api_sw_interface_set_mpls_enable_t *mp;
6210   u32 sw_if_index;
6211   u8 sw_if_index_set = 0;
6212   u8 enable = 1;
6213   int ret;
6214
6215   /* Parse args required to build the message */
6216   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6217     {
6218       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6219         sw_if_index_set = 1;
6220       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6221         sw_if_index_set = 1;
6222       else if (unformat (i, "disable"))
6223         enable = 0;
6224       else if (unformat (i, "dis"))
6225         enable = 0;
6226       else
6227         break;
6228     }
6229
6230   if (sw_if_index_set == 0)
6231     {
6232       errmsg ("missing interface name or sw_if_index");
6233       return -99;
6234     }
6235
6236   /* Construct the API message */
6237   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6238
6239   mp->sw_if_index = ntohl (sw_if_index);
6240   mp->enable = enable;
6241
6242   /* send it... */
6243   S (mp);
6244
6245   /* Wait for a reply... */
6246   W (ret);
6247   return ret;
6248 }
6249
6250 static int
6251 api_sw_interface_set_table (vat_main_t * vam)
6252 {
6253   unformat_input_t *i = vam->input;
6254   vl_api_sw_interface_set_table_t *mp;
6255   u32 sw_if_index, vrf_id = 0;
6256   u8 sw_if_index_set = 0;
6257   u8 is_ipv6 = 0;
6258   int ret;
6259
6260   /* Parse args required to build the message */
6261   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6262     {
6263       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6264         sw_if_index_set = 1;
6265       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6266         sw_if_index_set = 1;
6267       else if (unformat (i, "vrf %d", &vrf_id))
6268         ;
6269       else if (unformat (i, "ipv6"))
6270         is_ipv6 = 1;
6271       else
6272         break;
6273     }
6274
6275   if (sw_if_index_set == 0)
6276     {
6277       errmsg ("missing interface name or sw_if_index");
6278       return -99;
6279     }
6280
6281   /* Construct the API message */
6282   M (SW_INTERFACE_SET_TABLE, mp);
6283
6284   mp->sw_if_index = ntohl (sw_if_index);
6285   mp->is_ipv6 = is_ipv6;
6286   mp->vrf_id = ntohl (vrf_id);
6287
6288   /* send it... */
6289   S (mp);
6290
6291   /* Wait for a reply... */
6292   W (ret);
6293   return ret;
6294 }
6295
6296 static void vl_api_sw_interface_get_table_reply_t_handler
6297   (vl_api_sw_interface_get_table_reply_t * mp)
6298 {
6299   vat_main_t *vam = &vat_main;
6300
6301   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6302
6303   vam->retval = ntohl (mp->retval);
6304   vam->result_ready = 1;
6305
6306 }
6307
6308 static void vl_api_sw_interface_get_table_reply_t_handler_json
6309   (vl_api_sw_interface_get_table_reply_t * mp)
6310 {
6311   vat_main_t *vam = &vat_main;
6312   vat_json_node_t node;
6313
6314   vat_json_init_object (&node);
6315   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6316   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6317
6318   vat_json_print (vam->ofp, &node);
6319   vat_json_free (&node);
6320
6321   vam->retval = ntohl (mp->retval);
6322   vam->result_ready = 1;
6323 }
6324
6325 static int
6326 api_sw_interface_get_table (vat_main_t * vam)
6327 {
6328   unformat_input_t *i = vam->input;
6329   vl_api_sw_interface_get_table_t *mp;
6330   u32 sw_if_index;
6331   u8 sw_if_index_set = 0;
6332   u8 is_ipv6 = 0;
6333   int ret;
6334
6335   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6336     {
6337       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6338         sw_if_index_set = 1;
6339       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6340         sw_if_index_set = 1;
6341       else if (unformat (i, "ipv6"))
6342         is_ipv6 = 1;
6343       else
6344         break;
6345     }
6346
6347   if (sw_if_index_set == 0)
6348     {
6349       errmsg ("missing interface name or sw_if_index");
6350       return -99;
6351     }
6352
6353   M (SW_INTERFACE_GET_TABLE, mp);
6354   mp->sw_if_index = htonl (sw_if_index);
6355   mp->is_ipv6 = is_ipv6;
6356
6357   S (mp);
6358   W (ret);
6359   return ret;
6360 }
6361
6362 static int
6363 api_sw_interface_set_vpath (vat_main_t * vam)
6364 {
6365   unformat_input_t *i = vam->input;
6366   vl_api_sw_interface_set_vpath_t *mp;
6367   u32 sw_if_index = 0;
6368   u8 sw_if_index_set = 0;
6369   u8 is_enable = 0;
6370   int ret;
6371
6372   /* Parse args required to build the message */
6373   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6374     {
6375       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6376         sw_if_index_set = 1;
6377       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6378         sw_if_index_set = 1;
6379       else if (unformat (i, "enable"))
6380         is_enable = 1;
6381       else if (unformat (i, "disable"))
6382         is_enable = 0;
6383       else
6384         break;
6385     }
6386
6387   if (sw_if_index_set == 0)
6388     {
6389       errmsg ("missing interface name or sw_if_index");
6390       return -99;
6391     }
6392
6393   /* Construct the API message */
6394   M (SW_INTERFACE_SET_VPATH, mp);
6395
6396   mp->sw_if_index = ntohl (sw_if_index);
6397   mp->enable = is_enable;
6398
6399   /* send it... */
6400   S (mp);
6401
6402   /* Wait for a reply... */
6403   W (ret);
6404   return ret;
6405 }
6406
6407 static int
6408 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6409 {
6410   unformat_input_t *i = vam->input;
6411   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6412   u32 sw_if_index = 0;
6413   u8 sw_if_index_set = 0;
6414   u8 is_enable = 1;
6415   u8 is_ipv6 = 0;
6416   int ret;
6417
6418   /* Parse args required to build the message */
6419   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6420     {
6421       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6422         sw_if_index_set = 1;
6423       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6424         sw_if_index_set = 1;
6425       else if (unformat (i, "enable"))
6426         is_enable = 1;
6427       else if (unformat (i, "disable"))
6428         is_enable = 0;
6429       else if (unformat (i, "ip4"))
6430         is_ipv6 = 0;
6431       else if (unformat (i, "ip6"))
6432         is_ipv6 = 1;
6433       else
6434         break;
6435     }
6436
6437   if (sw_if_index_set == 0)
6438     {
6439       errmsg ("missing interface name or sw_if_index");
6440       return -99;
6441     }
6442
6443   /* Construct the API message */
6444   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6445
6446   mp->sw_if_index = ntohl (sw_if_index);
6447   mp->enable = is_enable;
6448   mp->is_ipv6 = is_ipv6;
6449
6450   /* send it... */
6451   S (mp);
6452
6453   /* Wait for a reply... */
6454   W (ret);
6455   return ret;
6456 }
6457
6458 static int
6459 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6460 {
6461   unformat_input_t *i = vam->input;
6462   vl_api_sw_interface_set_geneve_bypass_t *mp;
6463   u32 sw_if_index = 0;
6464   u8 sw_if_index_set = 0;
6465   u8 is_enable = 1;
6466   u8 is_ipv6 = 0;
6467   int ret;
6468
6469   /* Parse args required to build the message */
6470   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6471     {
6472       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6473         sw_if_index_set = 1;
6474       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6475         sw_if_index_set = 1;
6476       else if (unformat (i, "enable"))
6477         is_enable = 1;
6478       else if (unformat (i, "disable"))
6479         is_enable = 0;
6480       else if (unformat (i, "ip4"))
6481         is_ipv6 = 0;
6482       else if (unformat (i, "ip6"))
6483         is_ipv6 = 1;
6484       else
6485         break;
6486     }
6487
6488   if (sw_if_index_set == 0)
6489     {
6490       errmsg ("missing interface name or sw_if_index");
6491       return -99;
6492     }
6493
6494   /* Construct the API message */
6495   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6496
6497   mp->sw_if_index = ntohl (sw_if_index);
6498   mp->enable = is_enable;
6499   mp->is_ipv6 = is_ipv6;
6500
6501   /* send it... */
6502   S (mp);
6503
6504   /* Wait for a reply... */
6505   W (ret);
6506   return ret;
6507 }
6508
6509 static int
6510 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6511 {
6512   unformat_input_t *i = vam->input;
6513   vl_api_sw_interface_set_l2_xconnect_t *mp;
6514   u32 rx_sw_if_index;
6515   u8 rx_sw_if_index_set = 0;
6516   u32 tx_sw_if_index;
6517   u8 tx_sw_if_index_set = 0;
6518   u8 enable = 1;
6519   int ret;
6520
6521   /* Parse args required to build the message */
6522   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6523     {
6524       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6525         rx_sw_if_index_set = 1;
6526       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6527         tx_sw_if_index_set = 1;
6528       else if (unformat (i, "rx"))
6529         {
6530           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6531             {
6532               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6533                             &rx_sw_if_index))
6534                 rx_sw_if_index_set = 1;
6535             }
6536           else
6537             break;
6538         }
6539       else if (unformat (i, "tx"))
6540         {
6541           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6542             {
6543               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6544                             &tx_sw_if_index))
6545                 tx_sw_if_index_set = 1;
6546             }
6547           else
6548             break;
6549         }
6550       else if (unformat (i, "enable"))
6551         enable = 1;
6552       else if (unformat (i, "disable"))
6553         enable = 0;
6554       else
6555         break;
6556     }
6557
6558   if (rx_sw_if_index_set == 0)
6559     {
6560       errmsg ("missing rx interface name or rx_sw_if_index");
6561       return -99;
6562     }
6563
6564   if (enable && (tx_sw_if_index_set == 0))
6565     {
6566       errmsg ("missing tx interface name or tx_sw_if_index");
6567       return -99;
6568     }
6569
6570   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6571
6572   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6573   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6574   mp->enable = enable;
6575
6576   S (mp);
6577   W (ret);
6578   return ret;
6579 }
6580
6581 static int
6582 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6583 {
6584   unformat_input_t *i = vam->input;
6585   vl_api_sw_interface_set_l2_bridge_t *mp;
6586   vl_api_l2_port_type_t port_type;
6587   u32 rx_sw_if_index;
6588   u8 rx_sw_if_index_set = 0;
6589   u32 bd_id;
6590   u8 bd_id_set = 0;
6591   u32 shg = 0;
6592   u8 enable = 1;
6593   int ret;
6594
6595   port_type = L2_API_PORT_TYPE_NORMAL;
6596
6597   /* Parse args required to build the message */
6598   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6599     {
6600       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6601         rx_sw_if_index_set = 1;
6602       else if (unformat (i, "bd_id %d", &bd_id))
6603         bd_id_set = 1;
6604       else
6605         if (unformat
6606             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6607         rx_sw_if_index_set = 1;
6608       else if (unformat (i, "shg %d", &shg))
6609         ;
6610       else if (unformat (i, "bvi"))
6611         port_type = L2_API_PORT_TYPE_BVI;
6612       else if (unformat (i, "uu-fwd"))
6613         port_type = L2_API_PORT_TYPE_UU_FWD;
6614       else if (unformat (i, "enable"))
6615         enable = 1;
6616       else if (unformat (i, "disable"))
6617         enable = 0;
6618       else
6619         break;
6620     }
6621
6622   if (rx_sw_if_index_set == 0)
6623     {
6624       errmsg ("missing rx interface name or sw_if_index");
6625       return -99;
6626     }
6627
6628   if (enable && (bd_id_set == 0))
6629     {
6630       errmsg ("missing bridge domain");
6631       return -99;
6632     }
6633
6634   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6635
6636   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6637   mp->bd_id = ntohl (bd_id);
6638   mp->shg = (u8) shg;
6639   mp->port_type = ntohl (port_type);
6640   mp->enable = enable;
6641
6642   S (mp);
6643   W (ret);
6644   return ret;
6645 }
6646
6647 static int
6648 api_bridge_domain_dump (vat_main_t * vam)
6649 {
6650   unformat_input_t *i = vam->input;
6651   vl_api_bridge_domain_dump_t *mp;
6652   vl_api_control_ping_t *mp_ping;
6653   u32 bd_id = ~0;
6654   int ret;
6655
6656   /* Parse args required to build the message */
6657   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6658     {
6659       if (unformat (i, "bd_id %d", &bd_id))
6660         ;
6661       else
6662         break;
6663     }
6664
6665   M (BRIDGE_DOMAIN_DUMP, mp);
6666   mp->bd_id = ntohl (bd_id);
6667   S (mp);
6668
6669   /* Use a control ping for synchronization */
6670   MPING (CONTROL_PING, mp_ping);
6671   S (mp_ping);
6672
6673   W (ret);
6674   return ret;
6675 }
6676
6677 static int
6678 api_bridge_domain_add_del (vat_main_t * vam)
6679 {
6680   unformat_input_t *i = vam->input;
6681   vl_api_bridge_domain_add_del_t *mp;
6682   u32 bd_id = ~0;
6683   u8 is_add = 1;
6684   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6685   u8 *bd_tag = NULL;
6686   u32 mac_age = 0;
6687   int ret;
6688
6689   /* Parse args required to build the message */
6690   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6691     {
6692       if (unformat (i, "bd_id %d", &bd_id))
6693         ;
6694       else if (unformat (i, "flood %d", &flood))
6695         ;
6696       else if (unformat (i, "uu-flood %d", &uu_flood))
6697         ;
6698       else if (unformat (i, "forward %d", &forward))
6699         ;
6700       else if (unformat (i, "learn %d", &learn))
6701         ;
6702       else if (unformat (i, "arp-term %d", &arp_term))
6703         ;
6704       else if (unformat (i, "mac-age %d", &mac_age))
6705         ;
6706       else if (unformat (i, "bd-tag %s", &bd_tag))
6707         ;
6708       else if (unformat (i, "del"))
6709         {
6710           is_add = 0;
6711           flood = uu_flood = forward = learn = 0;
6712         }
6713       else
6714         break;
6715     }
6716
6717   if (bd_id == ~0)
6718     {
6719       errmsg ("missing bridge domain");
6720       ret = -99;
6721       goto done;
6722     }
6723
6724   if (mac_age > 255)
6725     {
6726       errmsg ("mac age must be less than 256 ");
6727       ret = -99;
6728       goto done;
6729     }
6730
6731   if ((bd_tag) && (vec_len (bd_tag) > 63))
6732     {
6733       errmsg ("bd-tag cannot be longer than 63");
6734       ret = -99;
6735       goto done;
6736     }
6737
6738   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6739
6740   mp->bd_id = ntohl (bd_id);
6741   mp->flood = flood;
6742   mp->uu_flood = uu_flood;
6743   mp->forward = forward;
6744   mp->learn = learn;
6745   mp->arp_term = arp_term;
6746   mp->is_add = is_add;
6747   mp->mac_age = (u8) mac_age;
6748   if (bd_tag)
6749     {
6750       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6751       mp->bd_tag[vec_len (bd_tag)] = 0;
6752     }
6753   S (mp);
6754   W (ret);
6755
6756 done:
6757   vec_free (bd_tag);
6758   return ret;
6759 }
6760
6761 static int
6762 api_l2fib_flush_bd (vat_main_t * vam)
6763 {
6764   unformat_input_t *i = vam->input;
6765   vl_api_l2fib_flush_bd_t *mp;
6766   u32 bd_id = ~0;
6767   int ret;
6768
6769   /* Parse args required to build the message */
6770   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6771     {
6772       if (unformat (i, "bd_id %d", &bd_id));
6773       else
6774         break;
6775     }
6776
6777   if (bd_id == ~0)
6778     {
6779       errmsg ("missing bridge domain");
6780       return -99;
6781     }
6782
6783   M (L2FIB_FLUSH_BD, mp);
6784
6785   mp->bd_id = htonl (bd_id);
6786
6787   S (mp);
6788   W (ret);
6789   return ret;
6790 }
6791
6792 static int
6793 api_l2fib_flush_int (vat_main_t * vam)
6794 {
6795   unformat_input_t *i = vam->input;
6796   vl_api_l2fib_flush_int_t *mp;
6797   u32 sw_if_index = ~0;
6798   int ret;
6799
6800   /* Parse args required to build the message */
6801   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6802     {
6803       if (unformat (i, "sw_if_index %d", &sw_if_index));
6804       else
6805         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6806       else
6807         break;
6808     }
6809
6810   if (sw_if_index == ~0)
6811     {
6812       errmsg ("missing interface name or sw_if_index");
6813       return -99;
6814     }
6815
6816   M (L2FIB_FLUSH_INT, mp);
6817
6818   mp->sw_if_index = ntohl (sw_if_index);
6819
6820   S (mp);
6821   W (ret);
6822   return ret;
6823 }
6824
6825 static int
6826 api_l2fib_add_del (vat_main_t * vam)
6827 {
6828   unformat_input_t *i = vam->input;
6829   vl_api_l2fib_add_del_t *mp;
6830   f64 timeout;
6831   u8 mac[6] = { 0 };
6832   u8 mac_set = 0;
6833   u32 bd_id;
6834   u8 bd_id_set = 0;
6835   u32 sw_if_index = 0;
6836   u8 sw_if_index_set = 0;
6837   u8 is_add = 1;
6838   u8 static_mac = 0;
6839   u8 filter_mac = 0;
6840   u8 bvi_mac = 0;
6841   int count = 1;
6842   f64 before = 0;
6843   int j;
6844
6845   /* Parse args required to build the message */
6846   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6847     {
6848       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6849         mac_set = 1;
6850       else if (unformat (i, "bd_id %d", &bd_id))
6851         bd_id_set = 1;
6852       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6853         sw_if_index_set = 1;
6854       else if (unformat (i, "sw_if"))
6855         {
6856           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6857             {
6858               if (unformat
6859                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6860                 sw_if_index_set = 1;
6861             }
6862           else
6863             break;
6864         }
6865       else if (unformat (i, "static"))
6866         static_mac = 1;
6867       else if (unformat (i, "filter"))
6868         {
6869           filter_mac = 1;
6870           static_mac = 1;
6871         }
6872       else if (unformat (i, "bvi"))
6873         {
6874           bvi_mac = 1;
6875           static_mac = 1;
6876         }
6877       else if (unformat (i, "del"))
6878         is_add = 0;
6879       else if (unformat (i, "count %d", &count))
6880         ;
6881       else
6882         break;
6883     }
6884
6885   if (mac_set == 0)
6886     {
6887       errmsg ("missing mac address");
6888       return -99;
6889     }
6890
6891   if (bd_id_set == 0)
6892     {
6893       errmsg ("missing bridge domain");
6894       return -99;
6895     }
6896
6897   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6898     {
6899       errmsg ("missing interface name or sw_if_index");
6900       return -99;
6901     }
6902
6903   if (count > 1)
6904     {
6905       /* Turn on async mode */
6906       vam->async_mode = 1;
6907       vam->async_errors = 0;
6908       before = vat_time_now (vam);
6909     }
6910
6911   for (j = 0; j < count; j++)
6912     {
6913       M (L2FIB_ADD_DEL, mp);
6914
6915       clib_memcpy (mp->mac, mac, 6);
6916       mp->bd_id = ntohl (bd_id);
6917       mp->is_add = is_add;
6918       mp->sw_if_index = ntohl (sw_if_index);
6919
6920       if (is_add)
6921         {
6922           mp->static_mac = static_mac;
6923           mp->filter_mac = filter_mac;
6924           mp->bvi_mac = bvi_mac;
6925         }
6926       increment_mac_address (mac);
6927       /* send it... */
6928       S (mp);
6929     }
6930
6931   if (count > 1)
6932     {
6933       vl_api_control_ping_t *mp_ping;
6934       f64 after;
6935
6936       /* Shut off async mode */
6937       vam->async_mode = 0;
6938
6939       MPING (CONTROL_PING, mp_ping);
6940       S (mp_ping);
6941
6942       timeout = vat_time_now (vam) + 1.0;
6943       while (vat_time_now (vam) < timeout)
6944         if (vam->result_ready == 1)
6945           goto out;
6946       vam->retval = -99;
6947
6948     out:
6949       if (vam->retval == -99)
6950         errmsg ("timeout");
6951
6952       if (vam->async_errors > 0)
6953         {
6954           errmsg ("%d asynchronous errors", vam->async_errors);
6955           vam->retval = -98;
6956         }
6957       vam->async_errors = 0;
6958       after = vat_time_now (vam);
6959
6960       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6961              count, after - before, count / (after - before));
6962     }
6963   else
6964     {
6965       int ret;
6966
6967       /* Wait for a reply... */
6968       W (ret);
6969       return ret;
6970     }
6971   /* Return the good/bad news */
6972   return (vam->retval);
6973 }
6974
6975 static int
6976 api_bridge_domain_set_mac_age (vat_main_t * vam)
6977 {
6978   unformat_input_t *i = vam->input;
6979   vl_api_bridge_domain_set_mac_age_t *mp;
6980   u32 bd_id = ~0;
6981   u32 mac_age = 0;
6982   int ret;
6983
6984   /* Parse args required to build the message */
6985   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6986     {
6987       if (unformat (i, "bd_id %d", &bd_id));
6988       else if (unformat (i, "mac-age %d", &mac_age));
6989       else
6990         break;
6991     }
6992
6993   if (bd_id == ~0)
6994     {
6995       errmsg ("missing bridge domain");
6996       return -99;
6997     }
6998
6999   if (mac_age > 255)
7000     {
7001       errmsg ("mac age must be less than 256 ");
7002       return -99;
7003     }
7004
7005   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7006
7007   mp->bd_id = htonl (bd_id);
7008   mp->mac_age = (u8) mac_age;
7009
7010   S (mp);
7011   W (ret);
7012   return ret;
7013 }
7014
7015 static int
7016 api_l2_flags (vat_main_t * vam)
7017 {
7018   unformat_input_t *i = vam->input;
7019   vl_api_l2_flags_t *mp;
7020   u32 sw_if_index;
7021   u32 flags = 0;
7022   u8 sw_if_index_set = 0;
7023   u8 is_set = 0;
7024   int ret;
7025
7026   /* Parse args required to build the message */
7027   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7028     {
7029       if (unformat (i, "sw_if_index %d", &sw_if_index))
7030         sw_if_index_set = 1;
7031       else if (unformat (i, "sw_if"))
7032         {
7033           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7034             {
7035               if (unformat
7036                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7037                 sw_if_index_set = 1;
7038             }
7039           else
7040             break;
7041         }
7042       else if (unformat (i, "learn"))
7043         flags |= L2_LEARN;
7044       else if (unformat (i, "forward"))
7045         flags |= L2_FWD;
7046       else if (unformat (i, "flood"))
7047         flags |= L2_FLOOD;
7048       else if (unformat (i, "uu-flood"))
7049         flags |= L2_UU_FLOOD;
7050       else if (unformat (i, "arp-term"))
7051         flags |= L2_ARP_TERM;
7052       else if (unformat (i, "off"))
7053         is_set = 0;
7054       else if (unformat (i, "disable"))
7055         is_set = 0;
7056       else
7057         break;
7058     }
7059
7060   if (sw_if_index_set == 0)
7061     {
7062       errmsg ("missing interface name or sw_if_index");
7063       return -99;
7064     }
7065
7066   M (L2_FLAGS, mp);
7067
7068   mp->sw_if_index = ntohl (sw_if_index);
7069   mp->feature_bitmap = ntohl (flags);
7070   mp->is_set = is_set;
7071
7072   S (mp);
7073   W (ret);
7074   return ret;
7075 }
7076
7077 static int
7078 api_bridge_flags (vat_main_t * vam)
7079 {
7080   unformat_input_t *i = vam->input;
7081   vl_api_bridge_flags_t *mp;
7082   u32 bd_id;
7083   u8 bd_id_set = 0;
7084   u8 is_set = 1;
7085   bd_flags_t flags = 0;
7086   int ret;
7087
7088   /* Parse args required to build the message */
7089   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7090     {
7091       if (unformat (i, "bd_id %d", &bd_id))
7092         bd_id_set = 1;
7093       else if (unformat (i, "learn"))
7094         flags |= BRIDGE_API_FLAG_LEARN;
7095       else if (unformat (i, "forward"))
7096         flags |= BRIDGE_API_FLAG_FWD;
7097       else if (unformat (i, "flood"))
7098         flags |= BRIDGE_API_FLAG_FLOOD;
7099       else if (unformat (i, "uu-flood"))
7100         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7101       else if (unformat (i, "arp-term"))
7102         flags |= BRIDGE_API_FLAG_ARP_TERM;
7103       else if (unformat (i, "off"))
7104         is_set = 0;
7105       else if (unformat (i, "disable"))
7106         is_set = 0;
7107       else
7108         break;
7109     }
7110
7111   if (bd_id_set == 0)
7112     {
7113       errmsg ("missing bridge domain");
7114       return -99;
7115     }
7116
7117   M (BRIDGE_FLAGS, mp);
7118
7119   mp->bd_id = ntohl (bd_id);
7120   mp->flags = ntohl (flags);
7121   mp->is_set = is_set;
7122
7123   S (mp);
7124   W (ret);
7125   return ret;
7126 }
7127
7128 static int
7129 api_bd_ip_mac_add_del (vat_main_t * vam)
7130 {
7131   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7132   vl_api_mac_address_t mac = { 0 };
7133   unformat_input_t *i = vam->input;
7134   vl_api_bd_ip_mac_add_del_t *mp;
7135   u32 bd_id;
7136   u8 is_add = 1;
7137   u8 bd_id_set = 0;
7138   u8 ip_set = 0;
7139   u8 mac_set = 0;
7140   int ret;
7141
7142
7143   /* Parse args required to build the message */
7144   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7145     {
7146       if (unformat (i, "bd_id %d", &bd_id))
7147         {
7148           bd_id_set++;
7149         }
7150       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7151         {
7152           ip_set++;
7153         }
7154       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7155         {
7156           mac_set++;
7157         }
7158       else if (unformat (i, "del"))
7159         is_add = 0;
7160       else
7161         break;
7162     }
7163
7164   if (bd_id_set == 0)
7165     {
7166       errmsg ("missing bridge domain");
7167       return -99;
7168     }
7169   else if (ip_set == 0)
7170     {
7171       errmsg ("missing IP address");
7172       return -99;
7173     }
7174   else if (mac_set == 0)
7175     {
7176       errmsg ("missing MAC address");
7177       return -99;
7178     }
7179
7180   M (BD_IP_MAC_ADD_DEL, mp);
7181
7182   mp->entry.bd_id = ntohl (bd_id);
7183   mp->is_add = is_add;
7184
7185   clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
7186   clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
7187
7188   S (mp);
7189   W (ret);
7190   return ret;
7191 }
7192
7193 static int
7194 api_bd_ip_mac_flush (vat_main_t * vam)
7195 {
7196   unformat_input_t *i = vam->input;
7197   vl_api_bd_ip_mac_flush_t *mp;
7198   u32 bd_id;
7199   u8 bd_id_set = 0;
7200   int ret;
7201
7202   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7203     {
7204       if (unformat (i, "bd_id %d", &bd_id))
7205         {
7206           bd_id_set++;
7207         }
7208       else
7209         break;
7210     }
7211
7212   if (bd_id_set == 0)
7213     {
7214       errmsg ("missing bridge domain");
7215       return -99;
7216     }
7217
7218   M (BD_IP_MAC_FLUSH, mp);
7219
7220   mp->bd_id = ntohl (bd_id);
7221
7222   S (mp);
7223   W (ret);
7224   return ret;
7225 }
7226
7227 static void vl_api_bd_ip_mac_details_t_handler
7228   (vl_api_bd_ip_mac_details_t * mp)
7229 {
7230   vat_main_t *vam = &vat_main;
7231
7232   print (vam->ofp,
7233          "\n%-5d %U %U",
7234          ntohl (mp->entry.bd_id),
7235          format_vl_api_mac_address, mp->entry.mac,
7236          format_vl_api_address, &mp->entry.ip);
7237 }
7238
7239 static void vl_api_bd_ip_mac_details_t_handler_json
7240   (vl_api_bd_ip_mac_details_t * mp)
7241 {
7242   vat_main_t *vam = &vat_main;
7243   vat_json_node_t *node = NULL;
7244
7245   if (VAT_JSON_ARRAY != vam->json_tree.type)
7246     {
7247       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7248       vat_json_init_array (&vam->json_tree);
7249     }
7250   node = vat_json_array_add (&vam->json_tree);
7251
7252   vat_json_init_object (node);
7253   vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
7254   vat_json_object_add_string_copy (node, "mac_address",
7255                                    format (0, "%U", format_vl_api_mac_address,
7256                                            &mp->entry.mac));
7257   u8 *ip = 0;
7258
7259   ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
7260   vat_json_object_add_string_copy (node, "ip_address", ip);
7261   vec_free (ip);
7262 }
7263
7264 static int
7265 api_bd_ip_mac_dump (vat_main_t * vam)
7266 {
7267   unformat_input_t *i = vam->input;
7268   vl_api_bd_ip_mac_dump_t *mp;
7269   vl_api_control_ping_t *mp_ping;
7270   int ret;
7271   u32 bd_id;
7272   u8 bd_id_set = 0;
7273
7274   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7275     {
7276       if (unformat (i, "bd_id %d", &bd_id))
7277         {
7278           bd_id_set++;
7279         }
7280       else
7281         break;
7282     }
7283
7284   print (vam->ofp,
7285          "\n%-5s %-7s %-20s %-30s",
7286          "bd_id", "is_ipv6", "mac_address", "ip_address");
7287
7288   /* Dump Bridge Domain Ip to Mac entries */
7289   M (BD_IP_MAC_DUMP, mp);
7290
7291   if (bd_id_set)
7292     mp->bd_id = htonl (bd_id);
7293   else
7294     mp->bd_id = ~0;
7295
7296   S (mp);
7297
7298   /* Use a control ping for synchronization */
7299   MPING (CONTROL_PING, mp_ping);
7300   S (mp_ping);
7301
7302   W (ret);
7303   return ret;
7304 }
7305
7306 static int
7307 api_tap_create_v2 (vat_main_t * vam)
7308 {
7309   unformat_input_t *i = vam->input;
7310   vl_api_tap_create_v2_t *mp;
7311   u8 mac_address[6];
7312   u8 random_mac = 1;
7313   u32 id = ~0;
7314   u32 num_rx_queues = 0;
7315   u8 *host_if_name = 0;
7316   u8 host_if_name_set = 0;
7317   u8 *host_ns = 0;
7318   u8 host_ns_set = 0;
7319   u8 host_mac_addr[6];
7320   u8 host_mac_addr_set = 0;
7321   u8 *host_bridge = 0;
7322   u8 host_bridge_set = 0;
7323   u8 host_ip4_prefix_set = 0;
7324   u8 host_ip6_prefix_set = 0;
7325   ip4_address_t host_ip4_addr;
7326   ip4_address_t host_ip4_gw;
7327   u8 host_ip4_gw_set = 0;
7328   u32 host_ip4_prefix_len = 0;
7329   ip6_address_t host_ip6_addr;
7330   ip6_address_t host_ip6_gw;
7331   u8 host_ip6_gw_set = 0;
7332   u32 host_ip6_prefix_len = 0;
7333   u32 host_mtu_size = 0;
7334   u8 host_mtu_set = 0;
7335   u32 tap_flags = 0;
7336   int ret;
7337   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7338
7339   clib_memset (mac_address, 0, sizeof (mac_address));
7340
7341   /* Parse args required to build the message */
7342   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7343     {
7344       if (unformat (i, "id %u", &id))
7345         ;
7346       else
7347         if (unformat
7348             (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7349         random_mac = 0;
7350       else if (unformat (i, "host-if-name %s", &host_if_name))
7351         host_if_name_set = 1;
7352       else if (unformat (i, "num-rx-queues %u", &num_rx_queues))
7353         ;
7354       else if (unformat (i, "host-ns %s", &host_ns))
7355         host_ns_set = 1;
7356       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7357                          host_mac_addr))
7358         host_mac_addr_set = 1;
7359       else if (unformat (i, "host-bridge %s", &host_bridge))
7360         host_bridge_set = 1;
7361       else if (unformat (i, "host-ip4-addr %U/%u", unformat_ip4_address,
7362                          &host_ip4_addr, &host_ip4_prefix_len))
7363         host_ip4_prefix_set = 1;
7364       else if (unformat (i, "host-ip6-addr %U/%u", unformat_ip6_address,
7365                          &host_ip6_addr, &host_ip6_prefix_len))
7366         host_ip6_prefix_set = 1;
7367       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7368                          &host_ip4_gw))
7369         host_ip4_gw_set = 1;
7370       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7371                          &host_ip6_gw))
7372         host_ip6_gw_set = 1;
7373       else if (unformat (i, "rx-ring-size %u", &rx_ring_sz))
7374         ;
7375       else if (unformat (i, "tx-ring-size %u", &tx_ring_sz))
7376         ;
7377       else if (unformat (i, "host-mtu-size %u", &host_mtu_size))
7378         host_mtu_set = 1;
7379       else if (unformat (i, "no-gso"))
7380         tap_flags &= ~TAP_API_FLAG_GSO;
7381       else if (unformat (i, "gso"))
7382         tap_flags |= TAP_API_FLAG_GSO;
7383       else if (unformat (i, "csum-offload"))
7384         tap_flags |= TAP_API_FLAG_CSUM_OFFLOAD;
7385       else if (unformat (i, "persist"))
7386         tap_flags |= TAP_API_FLAG_PERSIST;
7387       else if (unformat (i, "attach"))
7388         tap_flags |= TAP_API_FLAG_ATTACH;
7389       else if (unformat (i, "tun"))
7390         tap_flags |= TAP_API_FLAG_TUN;
7391       else if (unformat (i, "gro-coalesce"))
7392         tap_flags |= TAP_API_FLAG_GRO_COALESCE;
7393       else
7394         break;
7395     }
7396
7397   if (vec_len (host_if_name) > 63)
7398     {
7399       errmsg ("tap name too long. ");
7400       return -99;
7401     }
7402   if (vec_len (host_ns) > 63)
7403     {
7404       errmsg ("host name space too long. ");
7405       return -99;
7406     }
7407   if (vec_len (host_bridge) > 63)
7408     {
7409       errmsg ("host bridge name too long. ");
7410       return -99;
7411     }
7412   if (host_ip4_prefix_len > 32)
7413     {
7414       errmsg ("host ip4 prefix length not valid. ");
7415       return -99;
7416     }
7417   if (host_ip6_prefix_len > 128)
7418     {
7419       errmsg ("host ip6 prefix length not valid. ");
7420       return -99;
7421     }
7422   if (!is_pow2 (rx_ring_sz))
7423     {
7424       errmsg ("rx ring size must be power of 2. ");
7425       return -99;
7426     }
7427   if (rx_ring_sz > 32768)
7428     {
7429       errmsg ("rx ring size must be 32768 or lower. ");
7430       return -99;
7431     }
7432   if (!is_pow2 (tx_ring_sz))
7433     {
7434       errmsg ("tx ring size must be power of 2. ");
7435       return -99;
7436     }
7437   if (tx_ring_sz > 32768)
7438     {
7439       errmsg ("tx ring size must be 32768 or lower. ");
7440       return -99;
7441     }
7442   if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
7443     {
7444       errmsg ("host MTU size must be in between 64 and 65355. ");
7445       return -99;
7446     }
7447
7448   /* Construct the API message */
7449   M (TAP_CREATE_V2, mp);
7450
7451   mp->id = ntohl (id);
7452   mp->use_random_mac = random_mac;
7453   mp->num_rx_queues = (u8) num_rx_queues;
7454   mp->tx_ring_sz = ntohs (tx_ring_sz);
7455   mp->rx_ring_sz = ntohs (rx_ring_sz);
7456   mp->host_mtu_set = host_mtu_set;
7457   mp->host_mtu_size = ntohl (host_mtu_size);
7458   mp->host_mac_addr_set = host_mac_addr_set;
7459   mp->host_ip4_prefix_set = host_ip4_prefix_set;
7460   mp->host_ip6_prefix_set = host_ip6_prefix_set;
7461   mp->host_ip4_gw_set = host_ip4_gw_set;
7462   mp->host_ip6_gw_set = host_ip6_gw_set;
7463   mp->tap_flags = ntohl (tap_flags);
7464   mp->host_namespace_set = host_ns_set;
7465   mp->host_if_name_set = host_if_name_set;
7466   mp->host_bridge_set = host_bridge_set;
7467
7468   if (random_mac == 0)
7469     clib_memcpy (mp->mac_address, mac_address, 6);
7470   if (host_mac_addr_set)
7471     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7472   if (host_if_name_set)
7473     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7474   if (host_ns_set)
7475     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7476   if (host_bridge_set)
7477     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7478   if (host_ip4_prefix_set)
7479     {
7480       clib_memcpy (mp->host_ip4_prefix.address, &host_ip4_addr, 4);
7481       mp->host_ip4_prefix.len = (u8) host_ip4_prefix_len;
7482     }
7483   if (host_ip6_prefix_set)
7484     {
7485       clib_memcpy (mp->host_ip6_prefix.address, &host_ip6_addr, 16);
7486       mp->host_ip6_prefix.len = (u8) host_ip6_prefix_len;
7487     }
7488   if (host_ip4_gw_set)
7489     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7490   if (host_ip6_gw_set)
7491     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7492
7493   vec_free (host_ns);
7494   vec_free (host_if_name);
7495   vec_free (host_bridge);
7496
7497   /* send it... */
7498   S (mp);
7499
7500   /* Wait for a reply... */
7501   W (ret);
7502   return ret;
7503 }
7504
7505 static int
7506 api_tap_delete_v2 (vat_main_t * vam)
7507 {
7508   unformat_input_t *i = vam->input;
7509   vl_api_tap_delete_v2_t *mp;
7510   u32 sw_if_index = ~0;
7511   u8 sw_if_index_set = 0;
7512   int ret;
7513
7514   /* Parse args required to build the message */
7515   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7516     {
7517       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7518         sw_if_index_set = 1;
7519       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7520         sw_if_index_set = 1;
7521       else
7522         break;
7523     }
7524
7525   if (sw_if_index_set == 0)
7526     {
7527       errmsg ("missing vpp interface name. ");
7528       return -99;
7529     }
7530
7531   /* Construct the API message */
7532   M (TAP_DELETE_V2, mp);
7533
7534   mp->sw_if_index = ntohl (sw_if_index);
7535
7536   /* send it... */
7537   S (mp);
7538
7539   /* Wait for a reply... */
7540   W (ret);
7541   return ret;
7542 }
7543
7544 uword
7545 unformat_vlib_pci_addr (unformat_input_t * input, va_list * args)
7546 {
7547   vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
7548   u32 x[4];
7549
7550   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7551     return 0;
7552
7553   addr->domain = x[0];
7554   addr->bus = x[1];
7555   addr->slot = x[2];
7556   addr->function = x[3];
7557
7558   return 1;
7559 }
7560
7561 static int
7562 api_virtio_pci_create (vat_main_t * vam)
7563 {
7564   unformat_input_t *i = vam->input;
7565   vl_api_virtio_pci_create_t *mp;
7566   u8 mac_address[6];
7567   u8 random_mac = 1;
7568   u8 gso_enabled = 0;
7569   u8 checksum_offload_enabled = 0;
7570   u32 pci_addr = 0;
7571   u64 features = (u64) ~ (0ULL);
7572   int ret;
7573
7574   clib_memset (mac_address, 0, sizeof (mac_address));
7575
7576   /* Parse args required to build the message */
7577   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7578     {
7579       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7580         {
7581           random_mac = 0;
7582         }
7583       else if (unformat (i, "pci-addr %U", unformat_vlib_pci_addr, &pci_addr))
7584         ;
7585       else if (unformat (i, "features 0x%llx", &features))
7586         ;
7587       else if (unformat (i, "gso-enabled"))
7588         gso_enabled = 1;
7589       else if (unformat (i, "csum-offload-enabled"))
7590         checksum_offload_enabled = 1;
7591       else
7592         break;
7593     }
7594
7595   if (pci_addr == 0)
7596     {
7597       errmsg ("pci address must be non zero. ");
7598       return -99;
7599     }
7600
7601   /* Construct the API message */
7602   M (VIRTIO_PCI_CREATE, mp);
7603
7604   mp->use_random_mac = random_mac;
7605
7606   mp->pci_addr.domain = htons (((vlib_pci_addr_t) pci_addr).domain);
7607   mp->pci_addr.bus = ((vlib_pci_addr_t) pci_addr).bus;
7608   mp->pci_addr.slot = ((vlib_pci_addr_t) pci_addr).slot;
7609   mp->pci_addr.function = ((vlib_pci_addr_t) pci_addr).function;
7610
7611   mp->features = clib_host_to_net_u64 (features);
7612   mp->gso_enabled = gso_enabled;
7613   mp->checksum_offload_enabled = checksum_offload_enabled;
7614
7615   if (random_mac == 0)
7616     clib_memcpy (mp->mac_address, mac_address, 6);
7617
7618   /* send it... */
7619   S (mp);
7620
7621   /* Wait for a reply... */
7622   W (ret);
7623   return ret;
7624 }
7625
7626 static int
7627 api_virtio_pci_delete (vat_main_t * vam)
7628 {
7629   unformat_input_t *i = vam->input;
7630   vl_api_virtio_pci_delete_t *mp;
7631   u32 sw_if_index = ~0;
7632   u8 sw_if_index_set = 0;
7633   int ret;
7634
7635   /* Parse args required to build the message */
7636   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7637     {
7638       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7639         sw_if_index_set = 1;
7640       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7641         sw_if_index_set = 1;
7642       else
7643         break;
7644     }
7645
7646   if (sw_if_index_set == 0)
7647     {
7648       errmsg ("missing vpp interface name. ");
7649       return -99;
7650     }
7651
7652   /* Construct the API message */
7653   M (VIRTIO_PCI_DELETE, mp);
7654
7655   mp->sw_if_index = htonl (sw_if_index);
7656
7657   /* send it... */
7658   S (mp);
7659
7660   /* Wait for a reply... */
7661   W (ret);
7662   return ret;
7663 }
7664
7665 static int
7666 api_bond_create (vat_main_t * vam)
7667 {
7668   unformat_input_t *i = vam->input;
7669   vl_api_bond_create_t *mp;
7670   u8 mac_address[6];
7671   u8 custom_mac = 0;
7672   int ret;
7673   u8 mode;
7674   u8 lb;
7675   u8 mode_is_set = 0;
7676   u32 id = ~0;
7677   u8 numa_only = 0;
7678
7679   clib_memset (mac_address, 0, sizeof (mac_address));
7680   lb = BOND_LB_L2;
7681
7682   /* Parse args required to build the message */
7683   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7684     {
7685       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7686         mode_is_set = 1;
7687       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7688                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7689         ;
7690       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7691                          mac_address))
7692         custom_mac = 1;
7693       else if (unformat (i, "numa-only"))
7694         numa_only = 1;
7695       else if (unformat (i, "id %u", &id))
7696         ;
7697       else
7698         break;
7699     }
7700
7701   if (mode_is_set == 0)
7702     {
7703       errmsg ("Missing bond mode. ");
7704       return -99;
7705     }
7706
7707   /* Construct the API message */
7708   M (BOND_CREATE, mp);
7709
7710   mp->use_custom_mac = custom_mac;
7711
7712   mp->mode = htonl (mode);
7713   mp->lb = htonl (lb);
7714   mp->id = htonl (id);
7715   mp->numa_only = numa_only;
7716
7717   if (custom_mac)
7718     clib_memcpy (mp->mac_address, mac_address, 6);
7719
7720   /* send it... */
7721   S (mp);
7722
7723   /* Wait for a reply... */
7724   W (ret);
7725   return ret;
7726 }
7727
7728 static int
7729 api_bond_delete (vat_main_t * vam)
7730 {
7731   unformat_input_t *i = vam->input;
7732   vl_api_bond_delete_t *mp;
7733   u32 sw_if_index = ~0;
7734   u8 sw_if_index_set = 0;
7735   int ret;
7736
7737   /* Parse args required to build the message */
7738   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7739     {
7740       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7741         sw_if_index_set = 1;
7742       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7743         sw_if_index_set = 1;
7744       else
7745         break;
7746     }
7747
7748   if (sw_if_index_set == 0)
7749     {
7750       errmsg ("missing vpp interface name. ");
7751       return -99;
7752     }
7753
7754   /* Construct the API message */
7755   M (BOND_DELETE, mp);
7756
7757   mp->sw_if_index = ntohl (sw_if_index);
7758
7759   /* send it... */
7760   S (mp);
7761
7762   /* Wait for a reply... */
7763   W (ret);
7764   return ret;
7765 }
7766
7767 static int
7768 api_bond_add_member (vat_main_t * vam)
7769 {
7770   unformat_input_t *i = vam->input;
7771   vl_api_bond_add_member_t *mp;
7772   u32 bond_sw_if_index;
7773   int ret;
7774   u8 is_passive;
7775   u8 is_long_timeout;
7776   u32 bond_sw_if_index_is_set = 0;
7777   u32 sw_if_index;
7778   u8 sw_if_index_is_set = 0;
7779
7780   /* Parse args required to build the message */
7781   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7782     {
7783       if (unformat (i, "sw_if_index %d", &sw_if_index))
7784         sw_if_index_is_set = 1;
7785       else if (unformat (i, "bond %u", &bond_sw_if_index))
7786         bond_sw_if_index_is_set = 1;
7787       else if (unformat (i, "passive %d", &is_passive))
7788         ;
7789       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7790         ;
7791       else
7792         break;
7793     }
7794
7795   if (bond_sw_if_index_is_set == 0)
7796     {
7797       errmsg ("Missing bond sw_if_index. ");
7798       return -99;
7799     }
7800   if (sw_if_index_is_set == 0)
7801     {
7802       errmsg ("Missing member sw_if_index. ");
7803       return -99;
7804     }
7805
7806   /* Construct the API message */
7807   M (BOND_ADD_MEMBER, mp);
7808
7809   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7810   mp->sw_if_index = ntohl (sw_if_index);
7811   mp->is_long_timeout = is_long_timeout;
7812   mp->is_passive = is_passive;
7813
7814   /* send it... */
7815   S (mp);
7816
7817   /* Wait for a reply... */
7818   W (ret);
7819   return ret;
7820 }
7821
7822 static int
7823 api_bond_detach_member (vat_main_t * vam)
7824 {
7825   unformat_input_t *i = vam->input;
7826   vl_api_bond_detach_member_t *mp;
7827   u32 sw_if_index = ~0;
7828   u8 sw_if_index_set = 0;
7829   int ret;
7830
7831   /* Parse args required to build the message */
7832   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7833     {
7834       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7835         sw_if_index_set = 1;
7836       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7837         sw_if_index_set = 1;
7838       else
7839         break;
7840     }
7841
7842   if (sw_if_index_set == 0)
7843     {
7844       errmsg ("missing vpp interface name. ");
7845       return -99;
7846     }
7847
7848   /* Construct the API message */
7849   M (BOND_DETACH_MEMBER, mp);
7850
7851   mp->sw_if_index = ntohl (sw_if_index);
7852
7853   /* send it... */
7854   S (mp);
7855
7856   /* Wait for a reply... */
7857   W (ret);
7858   return ret;
7859 }
7860
7861 static int
7862 api_ip_table_add_del (vat_main_t * vam)
7863 {
7864   unformat_input_t *i = vam->input;
7865   vl_api_ip_table_add_del_t *mp;
7866   u32 table_id = ~0;
7867   u8 is_ipv6 = 0;
7868   u8 is_add = 1;
7869   int ret = 0;
7870
7871   /* Parse args required to build the message */
7872   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7873     {
7874       if (unformat (i, "ipv6"))
7875         is_ipv6 = 1;
7876       else if (unformat (i, "del"))
7877         is_add = 0;
7878       else if (unformat (i, "add"))
7879         is_add = 1;
7880       else if (unformat (i, "table %d", &table_id))
7881         ;
7882       else
7883         {
7884           clib_warning ("parse error '%U'", format_unformat_error, i);
7885           return -99;
7886         }
7887     }
7888
7889   if (~0 == table_id)
7890     {
7891       errmsg ("missing table-ID");
7892       return -99;
7893     }
7894
7895   /* Construct the API message */
7896   M (IP_TABLE_ADD_DEL, mp);
7897
7898   mp->table.table_id = ntohl (table_id);
7899   mp->table.is_ip6 = is_ipv6;
7900   mp->is_add = is_add;
7901
7902   /* send it... */
7903   S (mp);
7904
7905   /* Wait for a reply... */
7906   W (ret);
7907
7908   return ret;
7909 }
7910
7911 uword
7912 unformat_fib_path (unformat_input_t * input, va_list * args)
7913 {
7914   vat_main_t *vam = va_arg (*args, vat_main_t *);
7915   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
7916   u32 weight, preference;
7917   mpls_label_t out_label;
7918
7919   clib_memset (path, 0, sizeof (*path));
7920   path->weight = 1;
7921   path->sw_if_index = ~0;
7922   path->rpf_id = ~0;
7923   path->n_labels = 0;
7924
7925   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7926     {
7927       if (unformat (input, "%U %U",
7928                     unformat_vl_api_ip4_address,
7929                     &path->nh.address.ip4,
7930                     api_unformat_sw_if_index, vam, &path->sw_if_index))
7931         {
7932           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7933         }
7934       else if (unformat (input, "%U %U",
7935                          unformat_vl_api_ip6_address,
7936                          &path->nh.address.ip6,
7937                          api_unformat_sw_if_index, vam, &path->sw_if_index))
7938         {
7939           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7940         }
7941       else if (unformat (input, "weight %u", &weight))
7942         {
7943           path->weight = weight;
7944         }
7945       else if (unformat (input, "preference %u", &preference))
7946         {
7947           path->preference = preference;
7948         }
7949       else if (unformat (input, "%U next-hop-table %d",
7950                          unformat_vl_api_ip4_address,
7951                          &path->nh.address.ip4, &path->table_id))
7952         {
7953           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7954         }
7955       else if (unformat (input, "%U next-hop-table %d",
7956                          unformat_vl_api_ip6_address,
7957                          &path->nh.address.ip6, &path->table_id))
7958         {
7959           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7960         }
7961       else if (unformat (input, "%U",
7962                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
7963         {
7964           /*
7965            * the recursive next-hops are by default in the default table
7966            */
7967           path->table_id = 0;
7968           path->sw_if_index = ~0;
7969           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7970         }
7971       else if (unformat (input, "%U",
7972                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
7973         {
7974           /*
7975            * the recursive next-hops are by default in the default table
7976            */
7977           path->table_id = 0;
7978           path->sw_if_index = ~0;
7979           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7980         }
7981       else if (unformat (input, "resolve-via-host"))
7982         {
7983           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
7984         }
7985       else if (unformat (input, "resolve-via-attached"))
7986         {
7987           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
7988         }
7989       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
7990         {
7991           path->type = FIB_API_PATH_TYPE_LOCAL;
7992           path->sw_if_index = ~0;
7993           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7994         }
7995       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
7996         {
7997           path->type = FIB_API_PATH_TYPE_LOCAL;
7998           path->sw_if_index = ~0;
7999           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8000         }
8001       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
8002         ;
8003       else if (unformat (input, "via-label %d", &path->nh.via_label))
8004         {
8005           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
8006           path->sw_if_index = ~0;
8007         }
8008       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
8009         {
8010           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
8011           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
8012         }
8013       else if (unformat (input, "local"))
8014         {
8015           path->type = FIB_API_PATH_TYPE_LOCAL;
8016         }
8017       else if (unformat (input, "out-labels"))
8018         {
8019           while (unformat (input, "%d", &out_label))
8020             {
8021               path->label_stack[path->n_labels].label = out_label;
8022               path->label_stack[path->n_labels].is_uniform = 0;
8023               path->label_stack[path->n_labels].ttl = 64;
8024               path->n_labels++;
8025             }
8026         }
8027       else if (unformat (input, "via"))
8028         {
8029           /* new path, back up and return */
8030           unformat_put_input (input);
8031           unformat_put_input (input);
8032           unformat_put_input (input);
8033           unformat_put_input (input);
8034           break;
8035         }
8036       else
8037         {
8038           return (0);
8039         }
8040     }
8041
8042   path->proto = ntohl (path->proto);
8043   path->type = ntohl (path->type);
8044   path->flags = ntohl (path->flags);
8045   path->table_id = ntohl (path->table_id);
8046   path->sw_if_index = ntohl (path->sw_if_index);
8047
8048   return (1);
8049 }
8050
8051 static int
8052 api_ip_route_add_del (vat_main_t * vam)
8053 {
8054   unformat_input_t *i = vam->input;
8055   vl_api_ip_route_add_del_t *mp;
8056   u32 vrf_id = 0;
8057   u8 is_add = 1;
8058   u8 is_multipath = 0;
8059   u8 prefix_set = 0;
8060   u8 path_count = 0;
8061   vl_api_prefix_t pfx = { };
8062   vl_api_fib_path_t paths[8];
8063   int count = 1;
8064   int j;
8065   f64 before = 0;
8066   u32 random_add_del = 0;
8067   u32 *random_vector = 0;
8068   u32 random_seed = 0xdeaddabe;
8069
8070   /* Parse args required to build the message */
8071   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8072     {
8073       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8074         prefix_set = 1;
8075       else if (unformat (i, "del"))
8076         is_add = 0;
8077       else if (unformat (i, "add"))
8078         is_add = 1;
8079       else if (unformat (i, "vrf %d", &vrf_id))
8080         ;
8081       else if (unformat (i, "count %d", &count))
8082         ;
8083       else if (unformat (i, "random"))
8084         random_add_del = 1;
8085       else if (unformat (i, "multipath"))
8086         is_multipath = 1;
8087       else if (unformat (i, "seed %d", &random_seed))
8088         ;
8089       else
8090         if (unformat
8091             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8092         {
8093           path_count++;
8094           if (8 == path_count)
8095             {
8096               errmsg ("max 8 paths");
8097               return -99;
8098             }
8099         }
8100       else
8101         {
8102           clib_warning ("parse error '%U'", format_unformat_error, i);
8103           return -99;
8104         }
8105     }
8106
8107   if (!path_count)
8108     {
8109       errmsg ("specify a path; via ...");
8110       return -99;
8111     }
8112   if (prefix_set == 0)
8113     {
8114       errmsg ("missing prefix");
8115       return -99;
8116     }
8117
8118   /* Generate a pile of unique, random routes */
8119   if (random_add_del)
8120     {
8121       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
8122       u32 this_random_address;
8123       uword *random_hash;
8124
8125       random_hash = hash_create (count, sizeof (uword));
8126
8127       hash_set (random_hash, i->as_u32, 1);
8128       for (j = 0; j <= count; j++)
8129         {
8130           do
8131             {
8132               this_random_address = random_u32 (&random_seed);
8133               this_random_address =
8134                 clib_host_to_net_u32 (this_random_address);
8135             }
8136           while (hash_get (random_hash, this_random_address));
8137           vec_add1 (random_vector, this_random_address);
8138           hash_set (random_hash, this_random_address, 1);
8139         }
8140       hash_free (random_hash);
8141       set_ip4_address (&pfx.address, random_vector[0]);
8142     }
8143
8144   if (count > 1)
8145     {
8146       /* Turn on async mode */
8147       vam->async_mode = 1;
8148       vam->async_errors = 0;
8149       before = vat_time_now (vam);
8150     }
8151
8152   for (j = 0; j < count; j++)
8153     {
8154       /* Construct the API message */
8155       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8156
8157       mp->is_add = is_add;
8158       mp->is_multipath = is_multipath;
8159
8160       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8161       mp->route.table_id = ntohl (vrf_id);
8162       mp->route.n_paths = path_count;
8163
8164       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
8165
8166       if (random_add_del)
8167         set_ip4_address (&pfx.address, random_vector[j + 1]);
8168       else
8169         increment_address (&pfx.address);
8170       /* send it... */
8171       S (mp);
8172       /* If we receive SIGTERM, stop now... */
8173       if (vam->do_exit)
8174         break;
8175     }
8176
8177   /* When testing multiple add/del ops, use a control-ping to sync */
8178   if (count > 1)
8179     {
8180       vl_api_control_ping_t *mp_ping;
8181       f64 after;
8182       f64 timeout;
8183
8184       /* Shut off async mode */
8185       vam->async_mode = 0;
8186
8187       MPING (CONTROL_PING, mp_ping);
8188       S (mp_ping);
8189
8190       timeout = vat_time_now (vam) + 1.0;
8191       while (vat_time_now (vam) < timeout)
8192         if (vam->result_ready == 1)
8193           goto out;
8194       vam->retval = -99;
8195
8196     out:
8197       if (vam->retval == -99)
8198         errmsg ("timeout");
8199
8200       if (vam->async_errors > 0)
8201         {
8202           errmsg ("%d asynchronous errors", vam->async_errors);
8203           vam->retval = -98;
8204         }
8205       vam->async_errors = 0;
8206       after = vat_time_now (vam);
8207
8208       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8209       if (j > 0)
8210         count = j;
8211
8212       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8213              count, after - before, count / (after - before));
8214     }
8215   else
8216     {
8217       int ret;
8218
8219       /* Wait for a reply... */
8220       W (ret);
8221       return ret;
8222     }
8223
8224   /* Return the good/bad news */
8225   return (vam->retval);
8226 }
8227
8228 static int
8229 api_ip_mroute_add_del (vat_main_t * vam)
8230 {
8231   unformat_input_t *i = vam->input;
8232   u8 path_set = 0, prefix_set = 0, is_add = 1;
8233   vl_api_ip_mroute_add_del_t *mp;
8234   mfib_entry_flags_t eflags = 0;
8235   vl_api_mfib_path_t path;
8236   vl_api_mprefix_t pfx = { };
8237   u32 vrf_id = 0;
8238   int ret;
8239
8240   /* Parse args required to build the message */
8241   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8242     {
8243       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
8244         {
8245           prefix_set = 1;
8246           pfx.grp_address_length = htons (pfx.grp_address_length);
8247         }
8248       else if (unformat (i, "del"))
8249         is_add = 0;
8250       else if (unformat (i, "add"))
8251         is_add = 1;
8252       else if (unformat (i, "vrf %d", &vrf_id))
8253         ;
8254       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
8255         path.itf_flags = htonl (path.itf_flags);
8256       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8257         ;
8258       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
8259         path_set = 1;
8260       else
8261         {
8262           clib_warning ("parse error '%U'", format_unformat_error, i);
8263           return -99;
8264         }
8265     }
8266
8267   if (prefix_set == 0)
8268     {
8269       errmsg ("missing addresses\n");
8270       return -99;
8271     }
8272   if (path_set == 0)
8273     {
8274       errmsg ("missing path\n");
8275       return -99;
8276     }
8277
8278   /* Construct the API message */
8279   M (IP_MROUTE_ADD_DEL, mp);
8280
8281   mp->is_add = is_add;
8282   mp->is_multipath = 1;
8283
8284   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8285   mp->route.table_id = htonl (vrf_id);
8286   mp->route.n_paths = 1;
8287   mp->route.entry_flags = htonl (eflags);
8288
8289   clib_memcpy (&mp->route.paths, &path, sizeof (path));
8290
8291   /* send it... */
8292   S (mp);
8293   /* Wait for a reply... */
8294   W (ret);
8295   return ret;
8296 }
8297
8298 static int
8299 api_mpls_table_add_del (vat_main_t * vam)
8300 {
8301   unformat_input_t *i = vam->input;
8302   vl_api_mpls_table_add_del_t *mp;
8303   u32 table_id = ~0;
8304   u8 is_add = 1;
8305   int ret = 0;
8306
8307   /* Parse args required to build the message */
8308   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8309     {
8310       if (unformat (i, "table %d", &table_id))
8311         ;
8312       else if (unformat (i, "del"))
8313         is_add = 0;
8314       else if (unformat (i, "add"))
8315         is_add = 1;
8316       else
8317         {
8318           clib_warning ("parse error '%U'", format_unformat_error, i);
8319           return -99;
8320         }
8321     }
8322
8323   if (~0 == table_id)
8324     {
8325       errmsg ("missing table-ID");
8326       return -99;
8327     }
8328
8329   /* Construct the API message */
8330   M (MPLS_TABLE_ADD_DEL, mp);
8331
8332   mp->mt_table.mt_table_id = ntohl (table_id);
8333   mp->mt_is_add = is_add;
8334
8335   /* send it... */
8336   S (mp);
8337
8338   /* Wait for a reply... */
8339   W (ret);
8340
8341   return ret;
8342 }
8343
8344 static int
8345 api_mpls_route_add_del (vat_main_t * vam)
8346 {
8347   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
8348   mpls_label_t local_label = MPLS_LABEL_INVALID;
8349   unformat_input_t *i = vam->input;
8350   vl_api_mpls_route_add_del_t *mp;
8351   vl_api_fib_path_t paths[8];
8352   int count = 1, j;
8353   f64 before = 0;
8354
8355   /* Parse args required to build the message */
8356   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8357     {
8358       if (unformat (i, "%d", &local_label))
8359         ;
8360       else if (unformat (i, "eos"))
8361         is_eos = 1;
8362       else if (unformat (i, "non-eos"))
8363         is_eos = 0;
8364       else if (unformat (i, "del"))
8365         is_add = 0;
8366       else if (unformat (i, "add"))
8367         is_add = 1;
8368       else if (unformat (i, "multipath"))
8369         is_multipath = 1;
8370       else if (unformat (i, "count %d", &count))
8371         ;
8372       else
8373         if (unformat
8374             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8375         {
8376           path_count++;
8377           if (8 == path_count)
8378             {
8379               errmsg ("max 8 paths");
8380               return -99;
8381             }
8382         }
8383       else
8384         {
8385           clib_warning ("parse error '%U'", format_unformat_error, i);
8386           return -99;
8387         }
8388     }
8389
8390   if (!path_count)
8391     {
8392       errmsg ("specify a path; via ...");
8393       return -99;
8394     }
8395
8396   if (MPLS_LABEL_INVALID == local_label)
8397     {
8398       errmsg ("missing label");
8399       return -99;
8400     }
8401
8402   if (count > 1)
8403     {
8404       /* Turn on async mode */
8405       vam->async_mode = 1;
8406       vam->async_errors = 0;
8407       before = vat_time_now (vam);
8408     }
8409
8410   for (j = 0; j < count; j++)
8411     {
8412       /* Construct the API message */
8413       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8414
8415       mp->mr_is_add = is_add;
8416       mp->mr_is_multipath = is_multipath;
8417
8418       mp->mr_route.mr_label = local_label;
8419       mp->mr_route.mr_eos = is_eos;
8420       mp->mr_route.mr_table_id = 0;
8421       mp->mr_route.mr_n_paths = path_count;
8422
8423       clib_memcpy (&mp->mr_route.mr_paths, paths,
8424                    sizeof (paths[0]) * path_count);
8425
8426       local_label++;
8427
8428       /* send it... */
8429       S (mp);
8430       /* If we receive SIGTERM, stop now... */
8431       if (vam->do_exit)
8432         break;
8433     }
8434
8435   /* When testing multiple add/del ops, use a control-ping to sync */
8436   if (count > 1)
8437     {
8438       vl_api_control_ping_t *mp_ping;
8439       f64 after;
8440       f64 timeout;
8441
8442       /* Shut off async mode */
8443       vam->async_mode = 0;
8444
8445       MPING (CONTROL_PING, mp_ping);
8446       S (mp_ping);
8447
8448       timeout = vat_time_now (vam) + 1.0;
8449       while (vat_time_now (vam) < timeout)
8450         if (vam->result_ready == 1)
8451           goto out;
8452       vam->retval = -99;
8453
8454     out:
8455       if (vam->retval == -99)
8456         errmsg ("timeout");
8457
8458       if (vam->async_errors > 0)
8459         {
8460           errmsg ("%d asynchronous errors", vam->async_errors);
8461           vam->retval = -98;
8462         }
8463       vam->async_errors = 0;
8464       after = vat_time_now (vam);
8465
8466       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8467       if (j > 0)
8468         count = j;
8469
8470       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8471              count, after - before, count / (after - before));
8472     }
8473   else
8474     {
8475       int ret;
8476
8477       /* Wait for a reply... */
8478       W (ret);
8479       return ret;
8480     }
8481
8482   /* Return the good/bad news */
8483   return (vam->retval);
8484   return (0);
8485 }
8486
8487 static int
8488 api_mpls_ip_bind_unbind (vat_main_t * vam)
8489 {
8490   unformat_input_t *i = vam->input;
8491   vl_api_mpls_ip_bind_unbind_t *mp;
8492   u32 ip_table_id = 0;
8493   u8 is_bind = 1;
8494   vl_api_prefix_t pfx;
8495   u8 prefix_set = 0;
8496   mpls_label_t local_label = MPLS_LABEL_INVALID;
8497   int ret;
8498
8499   /* Parse args required to build the message */
8500   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8501     {
8502       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8503         prefix_set = 1;
8504       else if (unformat (i, "%d", &local_label))
8505         ;
8506       else if (unformat (i, "table-id %d", &ip_table_id))
8507         ;
8508       else if (unformat (i, "unbind"))
8509         is_bind = 0;
8510       else if (unformat (i, "bind"))
8511         is_bind = 1;
8512       else
8513         {
8514           clib_warning ("parse error '%U'", format_unformat_error, i);
8515           return -99;
8516         }
8517     }
8518
8519   if (!prefix_set)
8520     {
8521       errmsg ("IP prefix not set");
8522       return -99;
8523     }
8524
8525   if (MPLS_LABEL_INVALID == local_label)
8526     {
8527       errmsg ("missing label");
8528       return -99;
8529     }
8530
8531   /* Construct the API message */
8532   M (MPLS_IP_BIND_UNBIND, mp);
8533
8534   mp->mb_is_bind = is_bind;
8535   mp->mb_ip_table_id = ntohl (ip_table_id);
8536   mp->mb_mpls_table_id = 0;
8537   mp->mb_label = ntohl (local_label);
8538   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
8539
8540   /* send it... */
8541   S (mp);
8542
8543   /* Wait for a reply... */
8544   W (ret);
8545   return ret;
8546   return (0);
8547 }
8548
8549 static int
8550 api_sr_mpls_policy_add (vat_main_t * vam)
8551 {
8552   unformat_input_t *i = vam->input;
8553   vl_api_sr_mpls_policy_add_t *mp;
8554   u32 bsid = 0;
8555   u32 weight = 1;
8556   u8 type = 0;
8557   u8 n_segments = 0;
8558   u32 sid;
8559   u32 *segments = NULL;
8560   int ret;
8561
8562   /* Parse args required to build the message */
8563   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8564     {
8565       if (unformat (i, "bsid %d", &bsid))
8566         ;
8567       else if (unformat (i, "weight %d", &weight))
8568         ;
8569       else if (unformat (i, "spray"))
8570         type = 1;
8571       else if (unformat (i, "next %d", &sid))
8572         {
8573           n_segments += 1;
8574           vec_add1 (segments, htonl (sid));
8575         }
8576       else
8577         {
8578           clib_warning ("parse error '%U'", format_unformat_error, i);
8579           return -99;
8580         }
8581     }
8582
8583   if (bsid == 0)
8584     {
8585       errmsg ("bsid not set");
8586       return -99;
8587     }
8588
8589   if (n_segments == 0)
8590     {
8591       errmsg ("no sid in segment stack");
8592       return -99;
8593     }
8594
8595   /* Construct the API message */
8596   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8597
8598   mp->bsid = htonl (bsid);
8599   mp->weight = htonl (weight);
8600   mp->is_spray = type;
8601   mp->n_segments = n_segments;
8602   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8603   vec_free (segments);
8604
8605   /* send it... */
8606   S (mp);
8607
8608   /* Wait for a reply... */
8609   W (ret);
8610   return ret;
8611 }
8612
8613 static int
8614 api_sr_mpls_policy_del (vat_main_t * vam)
8615 {
8616   unformat_input_t *i = vam->input;
8617   vl_api_sr_mpls_policy_del_t *mp;
8618   u32 bsid = 0;
8619   int ret;
8620
8621   /* Parse args required to build the message */
8622   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8623     {
8624       if (unformat (i, "bsid %d", &bsid))
8625         ;
8626       else
8627         {
8628           clib_warning ("parse error '%U'", format_unformat_error, i);
8629           return -99;
8630         }
8631     }
8632
8633   if (bsid == 0)
8634     {
8635       errmsg ("bsid not set");
8636       return -99;
8637     }
8638
8639   /* Construct the API message */
8640   M (SR_MPLS_POLICY_DEL, mp);
8641
8642   mp->bsid = htonl (bsid);
8643
8644   /* send it... */
8645   S (mp);
8646
8647   /* Wait for a reply... */
8648   W (ret);
8649   return ret;
8650 }
8651
8652 static int
8653 api_bier_table_add_del (vat_main_t * vam)
8654 {
8655   unformat_input_t *i = vam->input;
8656   vl_api_bier_table_add_del_t *mp;
8657   u8 is_add = 1;
8658   u32 set = 0, sub_domain = 0, hdr_len = 3;
8659   mpls_label_t local_label = MPLS_LABEL_INVALID;
8660   int ret;
8661
8662   /* Parse args required to build the message */
8663   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8664     {
8665       if (unformat (i, "sub-domain %d", &sub_domain))
8666         ;
8667       else if (unformat (i, "set %d", &set))
8668         ;
8669       else if (unformat (i, "label %d", &local_label))
8670         ;
8671       else if (unformat (i, "hdr-len %d", &hdr_len))
8672         ;
8673       else if (unformat (i, "add"))
8674         is_add = 1;
8675       else if (unformat (i, "del"))
8676         is_add = 0;
8677       else
8678         {
8679           clib_warning ("parse error '%U'", format_unformat_error, i);
8680           return -99;
8681         }
8682     }
8683
8684   if (MPLS_LABEL_INVALID == local_label)
8685     {
8686       errmsg ("missing label\n");
8687       return -99;
8688     }
8689
8690   /* Construct the API message */
8691   M (BIER_TABLE_ADD_DEL, mp);
8692
8693   mp->bt_is_add = is_add;
8694   mp->bt_label = ntohl (local_label);
8695   mp->bt_tbl_id.bt_set = set;
8696   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8697   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8698
8699   /* send it... */
8700   S (mp);
8701
8702   /* Wait for a reply... */
8703   W (ret);
8704
8705   return (ret);
8706 }
8707
8708 static int
8709 api_bier_route_add_del (vat_main_t * vam)
8710 {
8711   unformat_input_t *i = vam->input;
8712   vl_api_bier_route_add_del_t *mp;
8713   u8 is_add = 1;
8714   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8715   ip4_address_t v4_next_hop_address;
8716   ip6_address_t v6_next_hop_address;
8717   u8 next_hop_set = 0;
8718   u8 next_hop_proto_is_ip4 = 1;
8719   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8720   int ret;
8721
8722   /* Parse args required to build the message */
8723   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8724     {
8725       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8726         {
8727           next_hop_proto_is_ip4 = 1;
8728           next_hop_set = 1;
8729         }
8730       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8731         {
8732           next_hop_proto_is_ip4 = 0;
8733           next_hop_set = 1;
8734         }
8735       if (unformat (i, "sub-domain %d", &sub_domain))
8736         ;
8737       else if (unformat (i, "set %d", &set))
8738         ;
8739       else if (unformat (i, "hdr-len %d", &hdr_len))
8740         ;
8741       else if (unformat (i, "bp %d", &bp))
8742         ;
8743       else if (unformat (i, "add"))
8744         is_add = 1;
8745       else if (unformat (i, "del"))
8746         is_add = 0;
8747       else if (unformat (i, "out-label %d", &next_hop_out_label))
8748         ;
8749       else
8750         {
8751           clib_warning ("parse error '%U'", format_unformat_error, i);
8752           return -99;
8753         }
8754     }
8755
8756   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8757     {
8758       errmsg ("next hop / label set\n");
8759       return -99;
8760     }
8761   if (0 == bp)
8762     {
8763       errmsg ("bit=position not set\n");
8764       return -99;
8765     }
8766
8767   /* Construct the API message */
8768   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
8769
8770   mp->br_is_add = is_add;
8771   mp->br_route.br_tbl_id.bt_set = set;
8772   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
8773   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
8774   mp->br_route.br_bp = ntohs (bp);
8775   mp->br_route.br_n_paths = 1;
8776   mp->br_route.br_paths[0].n_labels = 1;
8777   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
8778   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
8779                                     FIB_API_PATH_NH_PROTO_IP4 :
8780                                     FIB_API_PATH_NH_PROTO_IP6);
8781
8782   if (next_hop_proto_is_ip4)
8783     {
8784       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
8785                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8786     }
8787   else
8788     {
8789       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
8790                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8791     }
8792
8793   /* send it... */
8794   S (mp);
8795
8796   /* Wait for a reply... */
8797   W (ret);
8798
8799   return (ret);
8800 }
8801
8802 static int
8803 api_mpls_tunnel_add_del (vat_main_t * vam)
8804 {
8805   unformat_input_t *i = vam->input;
8806   vl_api_mpls_tunnel_add_del_t *mp;
8807
8808   vl_api_fib_path_t paths[8];
8809   u32 sw_if_index = ~0;
8810   u8 path_count = 0;
8811   u8 l2_only = 0;
8812   u8 is_add = 1;
8813   int ret;
8814
8815   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8816     {
8817       if (unformat (i, "add"))
8818         is_add = 1;
8819       else
8820         if (unformat
8821             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
8822         is_add = 0;
8823       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8824         is_add = 0;
8825       else if (unformat (i, "l2-only"))
8826         l2_only = 1;
8827       else
8828         if (unformat
8829             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8830         {
8831           path_count++;
8832           if (8 == path_count)
8833             {
8834               errmsg ("max 8 paths");
8835               return -99;
8836             }
8837         }
8838       else
8839         {
8840           clib_warning ("parse error '%U'", format_unformat_error, i);
8841           return -99;
8842         }
8843     }
8844
8845   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8846
8847   mp->mt_is_add = is_add;
8848   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
8849   mp->mt_tunnel.mt_l2_only = l2_only;
8850   mp->mt_tunnel.mt_is_multicast = 0;
8851   mp->mt_tunnel.mt_n_paths = path_count;
8852
8853   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
8854                sizeof (paths[0]) * path_count);
8855
8856   S (mp);
8857   W (ret);
8858   return ret;
8859 }
8860
8861 static int
8862 api_sw_interface_set_unnumbered (vat_main_t * vam)
8863 {
8864   unformat_input_t *i = vam->input;
8865   vl_api_sw_interface_set_unnumbered_t *mp;
8866   u32 sw_if_index;
8867   u32 unnum_sw_index = ~0;
8868   u8 is_add = 1;
8869   u8 sw_if_index_set = 0;
8870   int ret;
8871
8872   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8873     {
8874       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8875         sw_if_index_set = 1;
8876       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8877         sw_if_index_set = 1;
8878       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8879         ;
8880       else if (unformat (i, "del"))
8881         is_add = 0;
8882       else
8883         {
8884           clib_warning ("parse error '%U'", format_unformat_error, i);
8885           return -99;
8886         }
8887     }
8888
8889   if (sw_if_index_set == 0)
8890     {
8891       errmsg ("missing interface name or sw_if_index");
8892       return -99;
8893     }
8894
8895   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8896
8897   mp->sw_if_index = ntohl (sw_if_index);
8898   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8899   mp->is_add = is_add;
8900
8901   S (mp);
8902   W (ret);
8903   return ret;
8904 }
8905
8906
8907 static int
8908 api_create_vlan_subif (vat_main_t * vam)
8909 {
8910   unformat_input_t *i = vam->input;
8911   vl_api_create_vlan_subif_t *mp;
8912   u32 sw_if_index;
8913   u8 sw_if_index_set = 0;
8914   u32 vlan_id;
8915   u8 vlan_id_set = 0;
8916   int ret;
8917
8918   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8919     {
8920       if (unformat (i, "sw_if_index %d", &sw_if_index))
8921         sw_if_index_set = 1;
8922       else
8923         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8924         sw_if_index_set = 1;
8925       else if (unformat (i, "vlan %d", &vlan_id))
8926         vlan_id_set = 1;
8927       else
8928         {
8929           clib_warning ("parse error '%U'", format_unformat_error, i);
8930           return -99;
8931         }
8932     }
8933
8934   if (sw_if_index_set == 0)
8935     {
8936       errmsg ("missing interface name or sw_if_index");
8937       return -99;
8938     }
8939
8940   if (vlan_id_set == 0)
8941     {
8942       errmsg ("missing vlan_id");
8943       return -99;
8944     }
8945   M (CREATE_VLAN_SUBIF, mp);
8946
8947   mp->sw_if_index = ntohl (sw_if_index);
8948   mp->vlan_id = ntohl (vlan_id);
8949
8950   S (mp);
8951   W (ret);
8952   return ret;
8953 }
8954
8955 #define foreach_create_subif_bit                \
8956 _(no_tags)                                      \
8957 _(one_tag)                                      \
8958 _(two_tags)                                     \
8959 _(dot1ad)                                       \
8960 _(exact_match)                                  \
8961 _(default_sub)                                  \
8962 _(outer_vlan_id_any)                            \
8963 _(inner_vlan_id_any)
8964
8965 #define foreach_create_subif_flag               \
8966 _(0, "no_tags")                                 \
8967 _(1, "one_tag")                                 \
8968 _(2, "two_tags")                                \
8969 _(3, "dot1ad")                                  \
8970 _(4, "exact_match")                             \
8971 _(5, "default_sub")                             \
8972 _(6, "outer_vlan_id_any")                       \
8973 _(7, "inner_vlan_id_any")
8974
8975 static int
8976 api_create_subif (vat_main_t * vam)
8977 {
8978   unformat_input_t *i = vam->input;
8979   vl_api_create_subif_t *mp;
8980   u32 sw_if_index;
8981   u8 sw_if_index_set = 0;
8982   u32 sub_id;
8983   u8 sub_id_set = 0;
8984   u32 __attribute__ ((unused)) no_tags = 0;
8985   u32 __attribute__ ((unused)) one_tag = 0;
8986   u32 __attribute__ ((unused)) two_tags = 0;
8987   u32 __attribute__ ((unused)) dot1ad = 0;
8988   u32 __attribute__ ((unused)) exact_match = 0;
8989   u32 __attribute__ ((unused)) default_sub = 0;
8990   u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
8991   u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
8992   u32 tmp;
8993   u16 outer_vlan_id = 0;
8994   u16 inner_vlan_id = 0;
8995   int ret;
8996
8997   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8998     {
8999       if (unformat (i, "sw_if_index %d", &sw_if_index))
9000         sw_if_index_set = 1;
9001       else
9002         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9003         sw_if_index_set = 1;
9004       else if (unformat (i, "sub_id %d", &sub_id))
9005         sub_id_set = 1;
9006       else if (unformat (i, "outer_vlan_id %d", &tmp))
9007         outer_vlan_id = tmp;
9008       else if (unformat (i, "inner_vlan_id %d", &tmp))
9009         inner_vlan_id = tmp;
9010
9011 #define _(a) else if (unformat (i, #a)) a = 1 ;
9012       foreach_create_subif_bit
9013 #undef _
9014         else
9015         {
9016           clib_warning ("parse error '%U'", format_unformat_error, i);
9017           return -99;
9018         }
9019     }
9020
9021   if (sw_if_index_set == 0)
9022     {
9023       errmsg ("missing interface name or sw_if_index");
9024       return -99;
9025     }
9026
9027   if (sub_id_set == 0)
9028     {
9029       errmsg ("missing sub_id");
9030       return -99;
9031     }
9032   M (CREATE_SUBIF, mp);
9033
9034   mp->sw_if_index = ntohl (sw_if_index);
9035   mp->sub_id = ntohl (sub_id);
9036
9037 #define _(a,b) mp->sub_if_flags |= (1 << a);
9038   foreach_create_subif_flag;
9039 #undef _
9040
9041   mp->outer_vlan_id = ntohs (outer_vlan_id);
9042   mp->inner_vlan_id = ntohs (inner_vlan_id);
9043
9044   S (mp);
9045   W (ret);
9046   return ret;
9047 }
9048
9049 static int
9050 api_ip_table_replace_begin (vat_main_t * vam)
9051 {
9052   unformat_input_t *i = vam->input;
9053   vl_api_ip_table_replace_begin_t *mp;
9054   u32 table_id = 0;
9055   u8 is_ipv6 = 0;
9056
9057   int ret;
9058   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9059     {
9060       if (unformat (i, "table %d", &table_id))
9061         ;
9062       else if (unformat (i, "ipv6"))
9063         is_ipv6 = 1;
9064       else
9065         {
9066           clib_warning ("parse error '%U'", format_unformat_error, i);
9067           return -99;
9068         }
9069     }
9070
9071   M (IP_TABLE_REPLACE_BEGIN, mp);
9072
9073   mp->table.table_id = ntohl (table_id);
9074   mp->table.is_ip6 = is_ipv6;
9075
9076   S (mp);
9077   W (ret);
9078   return ret;
9079 }
9080
9081 static int
9082 api_ip_table_flush (vat_main_t * vam)
9083 {
9084   unformat_input_t *i = vam->input;
9085   vl_api_ip_table_flush_t *mp;
9086   u32 table_id = 0;
9087   u8 is_ipv6 = 0;
9088
9089   int ret;
9090   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9091     {
9092       if (unformat (i, "table %d", &table_id))
9093         ;
9094       else if (unformat (i, "ipv6"))
9095         is_ipv6 = 1;
9096       else
9097         {
9098           clib_warning ("parse error '%U'", format_unformat_error, i);
9099           return -99;
9100         }
9101     }
9102
9103   M (IP_TABLE_FLUSH, mp);
9104
9105   mp->table.table_id = ntohl (table_id);
9106   mp->table.is_ip6 = is_ipv6;
9107
9108   S (mp);
9109   W (ret);
9110   return ret;
9111 }
9112
9113 static int
9114 api_ip_table_replace_end (vat_main_t * vam)
9115 {
9116   unformat_input_t *i = vam->input;
9117   vl_api_ip_table_replace_end_t *mp;
9118   u32 table_id = 0;
9119   u8 is_ipv6 = 0;
9120
9121   int ret;
9122   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9123     {
9124       if (unformat (i, "table %d", &table_id))
9125         ;
9126       else if (unformat (i, "ipv6"))
9127         is_ipv6 = 1;
9128       else
9129         {
9130           clib_warning ("parse error '%U'", format_unformat_error, i);
9131           return -99;
9132         }
9133     }
9134
9135   M (IP_TABLE_REPLACE_END, mp);
9136
9137   mp->table.table_id = ntohl (table_id);
9138   mp->table.is_ip6 = is_ipv6;
9139
9140   S (mp);
9141   W (ret);
9142   return ret;
9143 }
9144
9145 static int
9146 api_set_ip_flow_hash (vat_main_t * vam)
9147 {
9148   unformat_input_t *i = vam->input;
9149   vl_api_set_ip_flow_hash_t *mp;
9150   u32 vrf_id = 0;
9151   u8 is_ipv6 = 0;
9152   u8 vrf_id_set = 0;
9153   u8 src = 0;
9154   u8 dst = 0;
9155   u8 sport = 0;
9156   u8 dport = 0;
9157   u8 proto = 0;
9158   u8 reverse = 0;
9159   int ret;
9160
9161   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9162     {
9163       if (unformat (i, "vrf %d", &vrf_id))
9164         vrf_id_set = 1;
9165       else if (unformat (i, "ipv6"))
9166         is_ipv6 = 1;
9167       else if (unformat (i, "src"))
9168         src = 1;
9169       else if (unformat (i, "dst"))
9170         dst = 1;
9171       else if (unformat (i, "sport"))
9172         sport = 1;
9173       else if (unformat (i, "dport"))
9174         dport = 1;
9175       else if (unformat (i, "proto"))
9176         proto = 1;
9177       else if (unformat (i, "reverse"))
9178         reverse = 1;
9179
9180       else
9181         {
9182           clib_warning ("parse error '%U'", format_unformat_error, i);
9183           return -99;
9184         }
9185     }
9186
9187   if (vrf_id_set == 0)
9188     {
9189       errmsg ("missing vrf id");
9190       return -99;
9191     }
9192
9193   M (SET_IP_FLOW_HASH, mp);
9194   mp->src = src;
9195   mp->dst = dst;
9196   mp->sport = sport;
9197   mp->dport = dport;
9198   mp->proto = proto;
9199   mp->reverse = reverse;
9200   mp->vrf_id = ntohl (vrf_id);
9201   mp->is_ipv6 = is_ipv6;
9202
9203   S (mp);
9204   W (ret);
9205   return ret;
9206 }
9207
9208 static int
9209 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9210 {
9211   unformat_input_t *i = vam->input;
9212   vl_api_sw_interface_ip6_enable_disable_t *mp;
9213   u32 sw_if_index;
9214   u8 sw_if_index_set = 0;
9215   u8 enable = 0;
9216   int ret;
9217
9218   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9219     {
9220       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9221         sw_if_index_set = 1;
9222       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9223         sw_if_index_set = 1;
9224       else if (unformat (i, "enable"))
9225         enable = 1;
9226       else if (unformat (i, "disable"))
9227         enable = 0;
9228       else
9229         {
9230           clib_warning ("parse error '%U'", format_unformat_error, i);
9231           return -99;
9232         }
9233     }
9234
9235   if (sw_if_index_set == 0)
9236     {
9237       errmsg ("missing interface name or sw_if_index");
9238       return -99;
9239     }
9240
9241   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9242
9243   mp->sw_if_index = ntohl (sw_if_index);
9244   mp->enable = enable;
9245
9246   S (mp);
9247   W (ret);
9248   return ret;
9249 }
9250
9251
9252 static int
9253 api_l2_patch_add_del (vat_main_t * vam)
9254 {
9255   unformat_input_t *i = vam->input;
9256   vl_api_l2_patch_add_del_t *mp;
9257   u32 rx_sw_if_index;
9258   u8 rx_sw_if_index_set = 0;
9259   u32 tx_sw_if_index;
9260   u8 tx_sw_if_index_set = 0;
9261   u8 is_add = 1;
9262   int ret;
9263
9264   /* Parse args required to build the message */
9265   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9266     {
9267       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9268         rx_sw_if_index_set = 1;
9269       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9270         tx_sw_if_index_set = 1;
9271       else if (unformat (i, "rx"))
9272         {
9273           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9274             {
9275               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9276                             &rx_sw_if_index))
9277                 rx_sw_if_index_set = 1;
9278             }
9279           else
9280             break;
9281         }
9282       else if (unformat (i, "tx"))
9283         {
9284           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9285             {
9286               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9287                             &tx_sw_if_index))
9288                 tx_sw_if_index_set = 1;
9289             }
9290           else
9291             break;
9292         }
9293       else if (unformat (i, "del"))
9294         is_add = 0;
9295       else
9296         break;
9297     }
9298
9299   if (rx_sw_if_index_set == 0)
9300     {
9301       errmsg ("missing rx interface name or rx_sw_if_index");
9302       return -99;
9303     }
9304
9305   if (tx_sw_if_index_set == 0)
9306     {
9307       errmsg ("missing tx interface name or tx_sw_if_index");
9308       return -99;
9309     }
9310
9311   M (L2_PATCH_ADD_DEL, mp);
9312
9313   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9314   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9315   mp->is_add = is_add;
9316
9317   S (mp);
9318   W (ret);
9319   return ret;
9320 }
9321
9322 u8 is_del;
9323 u8 localsid_addr[16];
9324 u8 end_psp;
9325 u8 behavior;
9326 u32 sw_if_index;
9327 u32 vlan_index;
9328 u32 fib_table;
9329 u8 nh_addr[16];
9330
9331 static int
9332 api_sr_localsid_add_del (vat_main_t * vam)
9333 {
9334   unformat_input_t *i = vam->input;
9335   vl_api_sr_localsid_add_del_t *mp;
9336
9337   u8 is_del;
9338   ip6_address_t localsid;
9339   u8 end_psp = 0;
9340   u8 behavior = ~0;
9341   u32 sw_if_index;
9342   u32 fib_table = ~(u32) 0;
9343   ip46_address_t nh_addr;
9344   clib_memset (&nh_addr, 0, sizeof (ip46_address_t));
9345
9346   bool nexthop_set = 0;
9347
9348   int ret;
9349
9350   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9351     {
9352       if (unformat (i, "del"))
9353         is_del = 1;
9354       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9355       else if (unformat (i, "next-hop %U", unformat_ip46_address, &nh_addr))
9356         nexthop_set = 1;
9357       else if (unformat (i, "behavior %u", &behavior));
9358       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9359       else if (unformat (i, "fib-table %u", &fib_table));
9360       else if (unformat (i, "end.psp %u", &behavior));
9361       else
9362         break;
9363     }
9364
9365   M (SR_LOCALSID_ADD_DEL, mp);
9366
9367   clib_memcpy (mp->localsid, &localsid, sizeof (mp->localsid));
9368
9369   if (nexthop_set)
9370     {
9371       clib_memcpy (&mp->nh_addr.un, &nh_addr, sizeof (mp->nh_addr.un));
9372     }
9373   mp->behavior = behavior;
9374   mp->sw_if_index = ntohl (sw_if_index);
9375   mp->fib_table = ntohl (fib_table);
9376   mp->end_psp = end_psp;
9377   mp->is_del = is_del;
9378
9379   S (mp);
9380   W (ret);
9381   return ret;
9382 }
9383
9384 static int
9385 api_ioam_enable (vat_main_t * vam)
9386 {
9387   unformat_input_t *input = vam->input;
9388   vl_api_ioam_enable_t *mp;
9389   u32 id = 0;
9390   int has_trace_option = 0;
9391   int has_pot_option = 0;
9392   int has_seqno_option = 0;
9393   int has_analyse_option = 0;
9394   int ret;
9395
9396   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9397     {
9398       if (unformat (input, "trace"))
9399         has_trace_option = 1;
9400       else if (unformat (input, "pot"))
9401         has_pot_option = 1;
9402       else if (unformat (input, "seqno"))
9403         has_seqno_option = 1;
9404       else if (unformat (input, "analyse"))
9405         has_analyse_option = 1;
9406       else
9407         break;
9408     }
9409   M (IOAM_ENABLE, mp);
9410   mp->id = htons (id);
9411   mp->seqno = has_seqno_option;
9412   mp->analyse = has_analyse_option;
9413   mp->pot_enable = has_pot_option;
9414   mp->trace_enable = has_trace_option;
9415
9416   S (mp);
9417   W (ret);
9418   return ret;
9419 }
9420
9421
9422 static int
9423 api_ioam_disable (vat_main_t * vam)
9424 {
9425   vl_api_ioam_disable_t *mp;
9426   int ret;
9427
9428   M (IOAM_DISABLE, mp);
9429   S (mp);
9430   W (ret);
9431   return ret;
9432 }
9433
9434 #define foreach_tcp_proto_field                 \
9435 _(src_port)                                     \
9436 _(dst_port)
9437
9438 #define foreach_udp_proto_field                 \
9439 _(src_port)                                     \
9440 _(dst_port)
9441
9442 #define foreach_ip4_proto_field                 \
9443 _(src_address)                                  \
9444 _(dst_address)                                  \
9445 _(tos)                                          \
9446 _(length)                                       \
9447 _(fragment_id)                                  \
9448 _(ttl)                                          \
9449 _(protocol)                                     \
9450 _(checksum)
9451
9452 typedef struct
9453 {
9454   u16 src_port, dst_port;
9455 } tcpudp_header_t;
9456
9457 #if VPP_API_TEST_BUILTIN == 0
9458 uword
9459 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9460 {
9461   u8 **maskp = va_arg (*args, u8 **);
9462   u8 *mask = 0;
9463   u8 found_something = 0;
9464   tcp_header_t *tcp;
9465
9466 #define _(a) u8 a=0;
9467   foreach_tcp_proto_field;
9468 #undef _
9469
9470   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9471     {
9472       if (0);
9473 #define _(a) else if (unformat (input, #a)) a=1;
9474       foreach_tcp_proto_field
9475 #undef _
9476         else
9477         break;
9478     }
9479
9480 #define _(a) found_something += a;
9481   foreach_tcp_proto_field;
9482 #undef _
9483
9484   if (found_something == 0)
9485     return 0;
9486
9487   vec_validate (mask, sizeof (*tcp) - 1);
9488
9489   tcp = (tcp_header_t *) mask;
9490
9491 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
9492   foreach_tcp_proto_field;
9493 #undef _
9494
9495   *maskp = mask;
9496   return 1;
9497 }
9498
9499 uword
9500 unformat_udp_mask (unformat_input_t * input, va_list * args)
9501 {
9502   u8 **maskp = va_arg (*args, u8 **);
9503   u8 *mask = 0;
9504   u8 found_something = 0;
9505   udp_header_t *udp;
9506
9507 #define _(a) u8 a=0;
9508   foreach_udp_proto_field;
9509 #undef _
9510
9511   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9512     {
9513       if (0);
9514 #define _(a) else if (unformat (input, #a)) a=1;
9515       foreach_udp_proto_field
9516 #undef _
9517         else
9518         break;
9519     }
9520
9521 #define _(a) found_something += a;
9522   foreach_udp_proto_field;
9523 #undef _
9524
9525   if (found_something == 0)
9526     return 0;
9527
9528   vec_validate (mask, sizeof (*udp) - 1);
9529
9530   udp = (udp_header_t *) mask;
9531
9532 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
9533   foreach_udp_proto_field;
9534 #undef _
9535
9536   *maskp = mask;
9537   return 1;
9538 }
9539
9540 uword
9541 unformat_l4_mask (unformat_input_t * input, va_list * args)
9542 {
9543   u8 **maskp = va_arg (*args, u8 **);
9544   u16 src_port = 0, dst_port = 0;
9545   tcpudp_header_t *tcpudp;
9546
9547   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9548     {
9549       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9550         return 1;
9551       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9552         return 1;
9553       else if (unformat (input, "src_port"))
9554         src_port = 0xFFFF;
9555       else if (unformat (input, "dst_port"))
9556         dst_port = 0xFFFF;
9557       else
9558         return 0;
9559     }
9560
9561   if (!src_port && !dst_port)
9562     return 0;
9563
9564   u8 *mask = 0;
9565   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9566
9567   tcpudp = (tcpudp_header_t *) mask;
9568   tcpudp->src_port = src_port;
9569   tcpudp->dst_port = dst_port;
9570
9571   *maskp = mask;
9572
9573   return 1;
9574 }
9575
9576 uword
9577 unformat_ip4_mask (unformat_input_t * input, va_list * args)
9578 {
9579   u8 **maskp = va_arg (*args, u8 **);
9580   u8 *mask = 0;
9581   u8 found_something = 0;
9582   ip4_header_t *ip;
9583
9584 #define _(a) u8 a=0;
9585   foreach_ip4_proto_field;
9586 #undef _
9587   u8 version = 0;
9588   u8 hdr_length = 0;
9589
9590
9591   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9592     {
9593       if (unformat (input, "version"))
9594         version = 1;
9595       else if (unformat (input, "hdr_length"))
9596         hdr_length = 1;
9597       else if (unformat (input, "src"))
9598         src_address = 1;
9599       else if (unformat (input, "dst"))
9600         dst_address = 1;
9601       else if (unformat (input, "proto"))
9602         protocol = 1;
9603
9604 #define _(a) else if (unformat (input, #a)) a=1;
9605       foreach_ip4_proto_field
9606 #undef _
9607         else
9608         break;
9609     }
9610
9611 #define _(a) found_something += a;
9612   foreach_ip4_proto_field;
9613 #undef _
9614
9615   if (found_something == 0)
9616     return 0;
9617
9618   vec_validate (mask, sizeof (*ip) - 1);
9619
9620   ip = (ip4_header_t *) mask;
9621
9622 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
9623   foreach_ip4_proto_field;
9624 #undef _
9625
9626   ip->ip_version_and_header_length = 0;
9627
9628   if (version)
9629     ip->ip_version_and_header_length |= 0xF0;
9630
9631   if (hdr_length)
9632     ip->ip_version_and_header_length |= 0x0F;
9633
9634   *maskp = mask;
9635   return 1;
9636 }
9637
9638 #define foreach_ip6_proto_field                 \
9639 _(src_address)                                  \
9640 _(dst_address)                                  \
9641 _(payload_length)                               \
9642 _(hop_limit)                                    \
9643 _(protocol)
9644
9645 uword
9646 unformat_ip6_mask (unformat_input_t * input, va_list * args)
9647 {
9648   u8 **maskp = va_arg (*args, u8 **);
9649   u8 *mask = 0;
9650   u8 found_something = 0;
9651   ip6_header_t *ip;
9652   u32 ip_version_traffic_class_and_flow_label;
9653
9654 #define _(a) u8 a=0;
9655   foreach_ip6_proto_field;
9656 #undef _
9657   u8 version = 0;
9658   u8 traffic_class = 0;
9659   u8 flow_label = 0;
9660
9661   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9662     {
9663       if (unformat (input, "version"))
9664         version = 1;
9665       else if (unformat (input, "traffic-class"))
9666         traffic_class = 1;
9667       else if (unformat (input, "flow-label"))
9668         flow_label = 1;
9669       else if (unformat (input, "src"))
9670         src_address = 1;
9671       else if (unformat (input, "dst"))
9672         dst_address = 1;
9673       else if (unformat (input, "proto"))
9674         protocol = 1;
9675
9676 #define _(a) else if (unformat (input, #a)) a=1;
9677       foreach_ip6_proto_field
9678 #undef _
9679         else
9680         break;
9681     }
9682
9683 #define _(a) found_something += a;
9684   foreach_ip6_proto_field;
9685 #undef _
9686
9687   if (found_something == 0)
9688     return 0;
9689
9690   vec_validate (mask, sizeof (*ip) - 1);
9691
9692   ip = (ip6_header_t *) mask;
9693
9694 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
9695   foreach_ip6_proto_field;
9696 #undef _
9697
9698   ip_version_traffic_class_and_flow_label = 0;
9699
9700   if (version)
9701     ip_version_traffic_class_and_flow_label |= 0xF0000000;
9702
9703   if (traffic_class)
9704     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9705
9706   if (flow_label)
9707     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9708
9709   ip->ip_version_traffic_class_and_flow_label =
9710     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9711
9712   *maskp = mask;
9713   return 1;
9714 }
9715
9716 uword
9717 unformat_l3_mask (unformat_input_t * input, va_list * args)
9718 {
9719   u8 **maskp = va_arg (*args, u8 **);
9720
9721   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9722     {
9723       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9724         return 1;
9725       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9726         return 1;
9727       else
9728         break;
9729     }
9730   return 0;
9731 }
9732
9733 uword
9734 unformat_l2_mask (unformat_input_t * input, va_list * args)
9735 {
9736   u8 **maskp = va_arg (*args, u8 **);
9737   u8 *mask = 0;
9738   u8 src = 0;
9739   u8 dst = 0;
9740   u8 proto = 0;
9741   u8 tag1 = 0;
9742   u8 tag2 = 0;
9743   u8 ignore_tag1 = 0;
9744   u8 ignore_tag2 = 0;
9745   u8 cos1 = 0;
9746   u8 cos2 = 0;
9747   u8 dot1q = 0;
9748   u8 dot1ad = 0;
9749   int len = 14;
9750
9751   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9752     {
9753       if (unformat (input, "src"))
9754         src = 1;
9755       else if (unformat (input, "dst"))
9756         dst = 1;
9757       else if (unformat (input, "proto"))
9758         proto = 1;
9759       else if (unformat (input, "tag1"))
9760         tag1 = 1;
9761       else if (unformat (input, "tag2"))
9762         tag2 = 1;
9763       else if (unformat (input, "ignore-tag1"))
9764         ignore_tag1 = 1;
9765       else if (unformat (input, "ignore-tag2"))
9766         ignore_tag2 = 1;
9767       else if (unformat (input, "cos1"))
9768         cos1 = 1;
9769       else if (unformat (input, "cos2"))
9770         cos2 = 1;
9771       else if (unformat (input, "dot1q"))
9772         dot1q = 1;
9773       else if (unformat (input, "dot1ad"))
9774         dot1ad = 1;
9775       else
9776         break;
9777     }
9778   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9779        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9780     return 0;
9781
9782   if (tag1 || ignore_tag1 || cos1 || dot1q)
9783     len = 18;
9784   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9785     len = 22;
9786
9787   vec_validate (mask, len - 1);
9788
9789   if (dst)
9790     clib_memset (mask, 0xff, 6);
9791
9792   if (src)
9793     clib_memset (mask + 6, 0xff, 6);
9794
9795   if (tag2 || dot1ad)
9796     {
9797       /* inner vlan tag */
9798       if (tag2)
9799         {
9800           mask[19] = 0xff;
9801           mask[18] = 0x0f;
9802         }
9803       if (cos2)
9804         mask[18] |= 0xe0;
9805       if (proto)
9806         mask[21] = mask[20] = 0xff;
9807       if (tag1)
9808         {
9809           mask[15] = 0xff;
9810           mask[14] = 0x0f;
9811         }
9812       if (cos1)
9813         mask[14] |= 0xe0;
9814       *maskp = mask;
9815       return 1;
9816     }
9817   if (tag1 | dot1q)
9818     {
9819       if (tag1)
9820         {
9821           mask[15] = 0xff;
9822           mask[14] = 0x0f;
9823         }
9824       if (cos1)
9825         mask[14] |= 0xe0;
9826       if (proto)
9827         mask[16] = mask[17] = 0xff;
9828
9829       *maskp = mask;
9830       return 1;
9831     }
9832   if (cos2)
9833     mask[18] |= 0xe0;
9834   if (cos1)
9835     mask[14] |= 0xe0;
9836   if (proto)
9837     mask[12] = mask[13] = 0xff;
9838
9839   *maskp = mask;
9840   return 1;
9841 }
9842
9843 uword
9844 unformat_classify_mask (unformat_input_t * input, va_list * args)
9845 {
9846   u8 **maskp = va_arg (*args, u8 **);
9847   u32 *skipp = va_arg (*args, u32 *);
9848   u32 *matchp = va_arg (*args, u32 *);
9849   u32 match;
9850   u8 *mask = 0;
9851   u8 *l2 = 0;
9852   u8 *l3 = 0;
9853   u8 *l4 = 0;
9854   int i;
9855
9856   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9857     {
9858       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9859         ;
9860       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9861         ;
9862       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9863         ;
9864       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9865         ;
9866       else
9867         break;
9868     }
9869
9870   if (l4 && !l3)
9871     {
9872       vec_free (mask);
9873       vec_free (l2);
9874       vec_free (l4);
9875       return 0;
9876     }
9877
9878   if (mask || l2 || l3 || l4)
9879     {
9880       if (l2 || l3 || l4)
9881         {
9882           /* "With a free Ethernet header in every package" */
9883           if (l2 == 0)
9884             vec_validate (l2, 13);
9885           mask = l2;
9886           if (vec_len (l3))
9887             {
9888               vec_append (mask, l3);
9889               vec_free (l3);
9890             }
9891           if (vec_len (l4))
9892             {
9893               vec_append (mask, l4);
9894               vec_free (l4);
9895             }
9896         }
9897
9898       /* Scan forward looking for the first significant mask octet */
9899       for (i = 0; i < vec_len (mask); i++)
9900         if (mask[i])
9901           break;
9902
9903       /* compute (skip, match) params */
9904       *skipp = i / sizeof (u32x4);
9905       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9906
9907       /* Pad mask to an even multiple of the vector size */
9908       while (vec_len (mask) % sizeof (u32x4))
9909         vec_add1 (mask, 0);
9910
9911       match = vec_len (mask) / sizeof (u32x4);
9912
9913       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9914         {
9915           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9916           if (*tmp || *(tmp + 1))
9917             break;
9918           match--;
9919         }
9920       if (match == 0)
9921         clib_warning ("BUG: match 0");
9922
9923       _vec_len (mask) = match * sizeof (u32x4);
9924
9925       *matchp = match;
9926       *maskp = mask;
9927
9928       return 1;
9929     }
9930
9931   return 0;
9932 }
9933 #endif /* VPP_API_TEST_BUILTIN */
9934
9935 #define foreach_l2_next                         \
9936 _(drop, DROP)                                   \
9937 _(ethernet, ETHERNET_INPUT)                     \
9938 _(ip4, IP4_INPUT)                               \
9939 _(ip6, IP6_INPUT)
9940
9941 uword
9942 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9943 {
9944   u32 *miss_next_indexp = va_arg (*args, u32 *);
9945   u32 next_index = 0;
9946   u32 tmp;
9947
9948 #define _(n,N) \
9949   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9950   foreach_l2_next;
9951 #undef _
9952
9953   if (unformat (input, "%d", &tmp))
9954     {
9955       next_index = tmp;
9956       goto out;
9957     }
9958
9959   return 0;
9960
9961 out:
9962   *miss_next_indexp = next_index;
9963   return 1;
9964 }
9965
9966 #define foreach_ip_next                         \
9967 _(drop, DROP)                                   \
9968 _(local, LOCAL)                                 \
9969 _(rewrite, REWRITE)
9970
9971 uword
9972 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9973 {
9974   u32 *miss_next_indexp = va_arg (*args, u32 *);
9975   u32 next_index = 0;
9976   u32 tmp;
9977
9978 #define _(n,N) \
9979   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9980   foreach_ip_next;
9981 #undef _
9982
9983   if (unformat (input, "%d", &tmp))
9984     {
9985       next_index = tmp;
9986       goto out;
9987     }
9988
9989   return 0;
9990
9991 out:
9992   *miss_next_indexp = next_index;
9993   return 1;
9994 }
9995
9996 #define foreach_acl_next                        \
9997 _(deny, DENY)
9998
9999 uword
10000 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10001 {
10002   u32 *miss_next_indexp = va_arg (*args, u32 *);
10003   u32 next_index = 0;
10004   u32 tmp;
10005
10006 #define _(n,N) \
10007   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10008   foreach_acl_next;
10009 #undef _
10010
10011   if (unformat (input, "permit"))
10012     {
10013       next_index = ~0;
10014       goto out;
10015     }
10016   else if (unformat (input, "%d", &tmp))
10017     {
10018       next_index = tmp;
10019       goto out;
10020     }
10021
10022   return 0;
10023
10024 out:
10025   *miss_next_indexp = next_index;
10026   return 1;
10027 }
10028
10029 uword
10030 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10031 {
10032   u32 *r = va_arg (*args, u32 *);
10033
10034   if (unformat (input, "conform-color"))
10035     *r = POLICE_CONFORM;
10036   else if (unformat (input, "exceed-color"))
10037     *r = POLICE_EXCEED;
10038   else
10039     return 0;
10040
10041   return 1;
10042 }
10043
10044 static int
10045 api_classify_add_del_table (vat_main_t * vam)
10046 {
10047   unformat_input_t *i = vam->input;
10048   vl_api_classify_add_del_table_t *mp;
10049
10050   u32 nbuckets = 2;
10051   u32 skip = ~0;
10052   u32 match = ~0;
10053   int is_add = 1;
10054   int del_chain = 0;
10055   u32 table_index = ~0;
10056   u32 next_table_index = ~0;
10057   u32 miss_next_index = ~0;
10058   u32 memory_size = 32 << 20;
10059   u8 *mask = 0;
10060   u32 current_data_flag = 0;
10061   int current_data_offset = 0;
10062   int ret;
10063
10064   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10065     {
10066       if (unformat (i, "del"))
10067         is_add = 0;
10068       else if (unformat (i, "del-chain"))
10069         {
10070           is_add = 0;
10071           del_chain = 1;
10072         }
10073       else if (unformat (i, "buckets %d", &nbuckets))
10074         ;
10075       else if (unformat (i, "memory_size %d", &memory_size))
10076         ;
10077       else if (unformat (i, "skip %d", &skip))
10078         ;
10079       else if (unformat (i, "match %d", &match))
10080         ;
10081       else if (unformat (i, "table %d", &table_index))
10082         ;
10083       else if (unformat (i, "mask %U", unformat_classify_mask,
10084                          &mask, &skip, &match))
10085         ;
10086       else if (unformat (i, "next-table %d", &next_table_index))
10087         ;
10088       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10089                          &miss_next_index))
10090         ;
10091       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10092                          &miss_next_index))
10093         ;
10094       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10095                          &miss_next_index))
10096         ;
10097       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10098         ;
10099       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10100         ;
10101       else
10102         break;
10103     }
10104
10105   if (is_add && mask == 0)
10106     {
10107       errmsg ("Mask required");
10108       return -99;
10109     }
10110
10111   if (is_add && skip == ~0)
10112     {
10113       errmsg ("skip count required");
10114       return -99;
10115     }
10116
10117   if (is_add && match == ~0)
10118     {
10119       errmsg ("match count required");
10120       return -99;
10121     }
10122
10123   if (!is_add && table_index == ~0)
10124     {
10125       errmsg ("table index required for delete");
10126       return -99;
10127     }
10128
10129   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10130
10131   mp->is_add = is_add;
10132   mp->del_chain = del_chain;
10133   mp->table_index = ntohl (table_index);
10134   mp->nbuckets = ntohl (nbuckets);
10135   mp->memory_size = ntohl (memory_size);
10136   mp->skip_n_vectors = ntohl (skip);
10137   mp->match_n_vectors = ntohl (match);
10138   mp->next_table_index = ntohl (next_table_index);
10139   mp->miss_next_index = ntohl (miss_next_index);
10140   mp->current_data_flag = ntohl (current_data_flag);
10141   mp->current_data_offset = ntohl (current_data_offset);
10142   mp->mask_len = ntohl (vec_len (mask));
10143   clib_memcpy (mp->mask, mask, vec_len (mask));
10144
10145   vec_free (mask);
10146
10147   S (mp);
10148   W (ret);
10149   return ret;
10150 }
10151
10152 #if VPP_API_TEST_BUILTIN == 0
10153 uword
10154 unformat_l4_match (unformat_input_t * input, va_list * args)
10155 {
10156   u8 **matchp = va_arg (*args, u8 **);
10157
10158   u8 *proto_header = 0;
10159   int src_port = 0;
10160   int dst_port = 0;
10161
10162   tcpudp_header_t h;
10163
10164   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10165     {
10166       if (unformat (input, "src_port %d", &src_port))
10167         ;
10168       else if (unformat (input, "dst_port %d", &dst_port))
10169         ;
10170       else
10171         return 0;
10172     }
10173
10174   h.src_port = clib_host_to_net_u16 (src_port);
10175   h.dst_port = clib_host_to_net_u16 (dst_port);
10176   vec_validate (proto_header, sizeof (h) - 1);
10177   memcpy (proto_header, &h, sizeof (h));
10178
10179   *matchp = proto_header;
10180
10181   return 1;
10182 }
10183
10184 uword
10185 unformat_ip4_match (unformat_input_t * input, va_list * args)
10186 {
10187   u8 **matchp = va_arg (*args, u8 **);
10188   u8 *match = 0;
10189   ip4_header_t *ip;
10190   int version = 0;
10191   u32 version_val;
10192   int hdr_length = 0;
10193   u32 hdr_length_val;
10194   int src = 0, dst = 0;
10195   ip4_address_t src_val, dst_val;
10196   int proto = 0;
10197   u32 proto_val;
10198   int tos = 0;
10199   u32 tos_val;
10200   int length = 0;
10201   u32 length_val;
10202   int fragment_id = 0;
10203   u32 fragment_id_val;
10204   int ttl = 0;
10205   int ttl_val;
10206   int checksum = 0;
10207   u32 checksum_val;
10208
10209   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10210     {
10211       if (unformat (input, "version %d", &version_val))
10212         version = 1;
10213       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10214         hdr_length = 1;
10215       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10216         src = 1;
10217       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10218         dst = 1;
10219       else if (unformat (input, "proto %d", &proto_val))
10220         proto = 1;
10221       else if (unformat (input, "tos %d", &tos_val))
10222         tos = 1;
10223       else if (unformat (input, "length %d", &length_val))
10224         length = 1;
10225       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10226         fragment_id = 1;
10227       else if (unformat (input, "ttl %d", &ttl_val))
10228         ttl = 1;
10229       else if (unformat (input, "checksum %d", &checksum_val))
10230         checksum = 1;
10231       else
10232         break;
10233     }
10234
10235   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10236       + ttl + checksum == 0)
10237     return 0;
10238
10239   /*
10240    * Aligned because we use the real comparison functions
10241    */
10242   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10243
10244   ip = (ip4_header_t *) match;
10245
10246   /* These are realistically matched in practice */
10247   if (src)
10248     ip->src_address.as_u32 = src_val.as_u32;
10249
10250   if (dst)
10251     ip->dst_address.as_u32 = dst_val.as_u32;
10252
10253   if (proto)
10254     ip->protocol = proto_val;
10255
10256
10257   /* These are not, but they're included for completeness */
10258   if (version)
10259     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10260
10261   if (hdr_length)
10262     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10263
10264   if (tos)
10265     ip->tos = tos_val;
10266
10267   if (length)
10268     ip->length = clib_host_to_net_u16 (length_val);
10269
10270   if (ttl)
10271     ip->ttl = ttl_val;
10272
10273   if (checksum)
10274     ip->checksum = clib_host_to_net_u16 (checksum_val);
10275
10276   *matchp = match;
10277   return 1;
10278 }
10279
10280 uword
10281 unformat_ip6_match (unformat_input_t * input, va_list * args)
10282 {
10283   u8 **matchp = va_arg (*args, u8 **);
10284   u8 *match = 0;
10285   ip6_header_t *ip;
10286   int version = 0;
10287   u32 version_val;
10288   u8 traffic_class = 0;
10289   u32 traffic_class_val = 0;
10290   u8 flow_label = 0;
10291   u8 flow_label_val;
10292   int src = 0, dst = 0;
10293   ip6_address_t src_val, dst_val;
10294   int proto = 0;
10295   u32 proto_val;
10296   int payload_length = 0;
10297   u32 payload_length_val;
10298   int hop_limit = 0;
10299   int hop_limit_val;
10300   u32 ip_version_traffic_class_and_flow_label;
10301
10302   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10303     {
10304       if (unformat (input, "version %d", &version_val))
10305         version = 1;
10306       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10307         traffic_class = 1;
10308       else if (unformat (input, "flow_label %d", &flow_label_val))
10309         flow_label = 1;
10310       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10311         src = 1;
10312       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10313         dst = 1;
10314       else if (unformat (input, "proto %d", &proto_val))
10315         proto = 1;
10316       else if (unformat (input, "payload_length %d", &payload_length_val))
10317         payload_length = 1;
10318       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10319         hop_limit = 1;
10320       else
10321         break;
10322     }
10323
10324   if (version + traffic_class + flow_label + src + dst + proto +
10325       payload_length + hop_limit == 0)
10326     return 0;
10327
10328   /*
10329    * Aligned because we use the real comparison functions
10330    */
10331   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10332
10333   ip = (ip6_header_t *) match;
10334
10335   if (src)
10336     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10337
10338   if (dst)
10339     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10340
10341   if (proto)
10342     ip->protocol = proto_val;
10343
10344   ip_version_traffic_class_and_flow_label = 0;
10345
10346   if (version)
10347     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10348
10349   if (traffic_class)
10350     ip_version_traffic_class_and_flow_label |=
10351       (traffic_class_val & 0xFF) << 20;
10352
10353   if (flow_label)
10354     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10355
10356   ip->ip_version_traffic_class_and_flow_label =
10357     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10358
10359   if (payload_length)
10360     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10361
10362   if (hop_limit)
10363     ip->hop_limit = hop_limit_val;
10364
10365   *matchp = match;
10366   return 1;
10367 }
10368
10369 uword
10370 unformat_l3_match (unformat_input_t * input, va_list * args)
10371 {
10372   u8 **matchp = va_arg (*args, u8 **);
10373
10374   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10375     {
10376       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10377         return 1;
10378       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10379         return 1;
10380       else
10381         break;
10382     }
10383   return 0;
10384 }
10385
10386 uword
10387 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10388 {
10389   u8 *tagp = va_arg (*args, u8 *);
10390   u32 tag;
10391
10392   if (unformat (input, "%d", &tag))
10393     {
10394       tagp[0] = (tag >> 8) & 0x0F;
10395       tagp[1] = tag & 0xFF;
10396       return 1;
10397     }
10398
10399   return 0;
10400 }
10401
10402 uword
10403 unformat_l2_match (unformat_input_t * input, va_list * args)
10404 {
10405   u8 **matchp = va_arg (*args, u8 **);
10406   u8 *match = 0;
10407   u8 src = 0;
10408   u8 src_val[6];
10409   u8 dst = 0;
10410   u8 dst_val[6];
10411   u8 proto = 0;
10412   u16 proto_val;
10413   u8 tag1 = 0;
10414   u8 tag1_val[2];
10415   u8 tag2 = 0;
10416   u8 tag2_val[2];
10417   int len = 14;
10418   u8 ignore_tag1 = 0;
10419   u8 ignore_tag2 = 0;
10420   u8 cos1 = 0;
10421   u8 cos2 = 0;
10422   u32 cos1_val = 0;
10423   u32 cos2_val = 0;
10424
10425   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10426     {
10427       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10428         src = 1;
10429       else
10430         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10431         dst = 1;
10432       else if (unformat (input, "proto %U",
10433                          unformat_ethernet_type_host_byte_order, &proto_val))
10434         proto = 1;
10435       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10436         tag1 = 1;
10437       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10438         tag2 = 1;
10439       else if (unformat (input, "ignore-tag1"))
10440         ignore_tag1 = 1;
10441       else if (unformat (input, "ignore-tag2"))
10442         ignore_tag2 = 1;
10443       else if (unformat (input, "cos1 %d", &cos1_val))
10444         cos1 = 1;
10445       else if (unformat (input, "cos2 %d", &cos2_val))
10446         cos2 = 1;
10447       else
10448         break;
10449     }
10450   if ((src + dst + proto + tag1 + tag2 +
10451        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10452     return 0;
10453
10454   if (tag1 || ignore_tag1 || cos1)
10455     len = 18;
10456   if (tag2 || ignore_tag2 || cos2)
10457     len = 22;
10458
10459   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10460
10461   if (dst)
10462     clib_memcpy (match, dst_val, 6);
10463
10464   if (src)
10465     clib_memcpy (match + 6, src_val, 6);
10466
10467   if (tag2)
10468     {
10469       /* inner vlan tag */
10470       match[19] = tag2_val[1];
10471       match[18] = tag2_val[0];
10472       if (cos2)
10473         match[18] |= (cos2_val & 0x7) << 5;
10474       if (proto)
10475         {
10476           match[21] = proto_val & 0xff;
10477           match[20] = proto_val >> 8;
10478         }
10479       if (tag1)
10480         {
10481           match[15] = tag1_val[1];
10482           match[14] = tag1_val[0];
10483         }
10484       if (cos1)
10485         match[14] |= (cos1_val & 0x7) << 5;
10486       *matchp = match;
10487       return 1;
10488     }
10489   if (tag1)
10490     {
10491       match[15] = tag1_val[1];
10492       match[14] = tag1_val[0];
10493       if (proto)
10494         {
10495           match[17] = proto_val & 0xff;
10496           match[16] = proto_val >> 8;
10497         }
10498       if (cos1)
10499         match[14] |= (cos1_val & 0x7) << 5;
10500
10501       *matchp = match;
10502       return 1;
10503     }
10504   if (cos2)
10505     match[18] |= (cos2_val & 0x7) << 5;
10506   if (cos1)
10507     match[14] |= (cos1_val & 0x7) << 5;
10508   if (proto)
10509     {
10510       match[13] = proto_val & 0xff;
10511       match[12] = proto_val >> 8;
10512     }
10513
10514   *matchp = match;
10515   return 1;
10516 }
10517
10518 uword
10519 unformat_qos_source (unformat_input_t * input, va_list * args)
10520 {
10521   int *qs = va_arg (*args, int *);
10522
10523   if (unformat (input, "ip"))
10524     *qs = QOS_SOURCE_IP;
10525   else if (unformat (input, "mpls"))
10526     *qs = QOS_SOURCE_MPLS;
10527   else if (unformat (input, "ext"))
10528     *qs = QOS_SOURCE_EXT;
10529   else if (unformat (input, "vlan"))
10530     *qs = QOS_SOURCE_VLAN;
10531   else
10532     return 0;
10533
10534   return 1;
10535 }
10536 #endif
10537
10538 uword
10539 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10540 {
10541   u8 **matchp = va_arg (*args, u8 **);
10542   u32 skip_n_vectors = va_arg (*args, u32);
10543   u32 match_n_vectors = va_arg (*args, u32);
10544
10545   u8 *match = 0;
10546   u8 *l2 = 0;
10547   u8 *l3 = 0;
10548   u8 *l4 = 0;
10549
10550   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10551     {
10552       if (unformat (input, "hex %U", unformat_hex_string, &match))
10553         ;
10554       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10555         ;
10556       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10557         ;
10558       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10559         ;
10560       else
10561         break;
10562     }
10563
10564   if (l4 && !l3)
10565     {
10566       vec_free (match);
10567       vec_free (l2);
10568       vec_free (l4);
10569       return 0;
10570     }
10571
10572   if (match || l2 || l3 || l4)
10573     {
10574       if (l2 || l3 || l4)
10575         {
10576           /* "Win a free Ethernet header in every packet" */
10577           if (l2 == 0)
10578             vec_validate_aligned (l2, 13, sizeof (u32x4));
10579           match = l2;
10580           if (vec_len (l3))
10581             {
10582               vec_append_aligned (match, l3, sizeof (u32x4));
10583               vec_free (l3);
10584             }
10585           if (vec_len (l4))
10586             {
10587               vec_append_aligned (match, l4, sizeof (u32x4));
10588               vec_free (l4);
10589             }
10590         }
10591
10592       /* Make sure the vector is big enough even if key is all 0's */
10593       vec_validate_aligned
10594         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
10595          sizeof (u32x4));
10596
10597       /* Set size, include skipped vectors */
10598       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
10599
10600       *matchp = match;
10601
10602       return 1;
10603     }
10604
10605   return 0;
10606 }
10607
10608 static int
10609 api_classify_add_del_session (vat_main_t * vam)
10610 {
10611   unformat_input_t *i = vam->input;
10612   vl_api_classify_add_del_session_t *mp;
10613   int is_add = 1;
10614   u32 table_index = ~0;
10615   u32 hit_next_index = ~0;
10616   u32 opaque_index = ~0;
10617   u8 *match = 0;
10618   i32 advance = 0;
10619   u32 skip_n_vectors = 0;
10620   u32 match_n_vectors = 0;
10621   u32 action = 0;
10622   u32 metadata = 0;
10623   int ret;
10624
10625   /*
10626    * Warning: you have to supply skip_n and match_n
10627    * because the API client cant simply look at the classify
10628    * table object.
10629    */
10630
10631   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10632     {
10633       if (unformat (i, "del"))
10634         is_add = 0;
10635       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
10636                          &hit_next_index))
10637         ;
10638       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10639                          &hit_next_index))
10640         ;
10641       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
10642                          &hit_next_index))
10643         ;
10644       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10645         ;
10646       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10647         ;
10648       else if (unformat (i, "opaque-index %d", &opaque_index))
10649         ;
10650       else if (unformat (i, "skip_n %d", &skip_n_vectors))
10651         ;
10652       else if (unformat (i, "match_n %d", &match_n_vectors))
10653         ;
10654       else if (unformat (i, "match %U", api_unformat_classify_match,
10655                          &match, skip_n_vectors, match_n_vectors))
10656         ;
10657       else if (unformat (i, "advance %d", &advance))
10658         ;
10659       else if (unformat (i, "table-index %d", &table_index))
10660         ;
10661       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10662         action = 1;
10663       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10664         action = 2;
10665       else if (unformat (i, "action %d", &action))
10666         ;
10667       else if (unformat (i, "metadata %d", &metadata))
10668         ;
10669       else
10670         break;
10671     }
10672
10673   if (table_index == ~0)
10674     {
10675       errmsg ("Table index required");
10676       return -99;
10677     }
10678
10679   if (is_add && match == 0)
10680     {
10681       errmsg ("Match value required");
10682       return -99;
10683     }
10684
10685   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10686
10687   mp->is_add = is_add;
10688   mp->table_index = ntohl (table_index);
10689   mp->hit_next_index = ntohl (hit_next_index);
10690   mp->opaque_index = ntohl (opaque_index);
10691   mp->advance = ntohl (advance);
10692   mp->action = action;
10693   mp->metadata = ntohl (metadata);
10694   mp->match_len = ntohl (vec_len (match));
10695   clib_memcpy (mp->match, match, vec_len (match));
10696   vec_free (match);
10697
10698   S (mp);
10699   W (ret);
10700   return ret;
10701 }
10702
10703 static int
10704 api_classify_set_interface_ip_table (vat_main_t * vam)
10705 {
10706   unformat_input_t *i = vam->input;
10707   vl_api_classify_set_interface_ip_table_t *mp;
10708   u32 sw_if_index;
10709   int sw_if_index_set;
10710   u32 table_index = ~0;
10711   u8 is_ipv6 = 0;
10712   int ret;
10713
10714   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10715     {
10716       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10717         sw_if_index_set = 1;
10718       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10719         sw_if_index_set = 1;
10720       else if (unformat (i, "table %d", &table_index))
10721         ;
10722       else
10723         {
10724           clib_warning ("parse error '%U'", format_unformat_error, i);
10725           return -99;
10726         }
10727     }
10728
10729   if (sw_if_index_set == 0)
10730     {
10731       errmsg ("missing interface name or sw_if_index");
10732       return -99;
10733     }
10734
10735
10736   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10737
10738   mp->sw_if_index = ntohl (sw_if_index);
10739   mp->table_index = ntohl (table_index);
10740   mp->is_ipv6 = is_ipv6;
10741
10742   S (mp);
10743   W (ret);
10744   return ret;
10745 }
10746
10747 static int
10748 api_classify_set_interface_l2_tables (vat_main_t * vam)
10749 {
10750   unformat_input_t *i = vam->input;
10751   vl_api_classify_set_interface_l2_tables_t *mp;
10752   u32 sw_if_index;
10753   int sw_if_index_set;
10754   u32 ip4_table_index = ~0;
10755   u32 ip6_table_index = ~0;
10756   u32 other_table_index = ~0;
10757   u32 is_input = 1;
10758   int ret;
10759
10760   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10761     {
10762       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10763         sw_if_index_set = 1;
10764       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10765         sw_if_index_set = 1;
10766       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10767         ;
10768       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10769         ;
10770       else if (unformat (i, "other-table %d", &other_table_index))
10771         ;
10772       else if (unformat (i, "is-input %d", &is_input))
10773         ;
10774       else
10775         {
10776           clib_warning ("parse error '%U'", format_unformat_error, i);
10777           return -99;
10778         }
10779     }
10780
10781   if (sw_if_index_set == 0)
10782     {
10783       errmsg ("missing interface name or sw_if_index");
10784       return -99;
10785     }
10786
10787
10788   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10789
10790   mp->sw_if_index = ntohl (sw_if_index);
10791   mp->ip4_table_index = ntohl (ip4_table_index);
10792   mp->ip6_table_index = ntohl (ip6_table_index);
10793   mp->other_table_index = ntohl (other_table_index);
10794   mp->is_input = (u8) is_input;
10795
10796   S (mp);
10797   W (ret);
10798   return ret;
10799 }
10800
10801 static int
10802 api_set_ipfix_exporter (vat_main_t * vam)
10803 {
10804   unformat_input_t *i = vam->input;
10805   vl_api_set_ipfix_exporter_t *mp;
10806   ip4_address_t collector_address;
10807   u8 collector_address_set = 0;
10808   u32 collector_port = ~0;
10809   ip4_address_t src_address;
10810   u8 src_address_set = 0;
10811   u32 vrf_id = ~0;
10812   u32 path_mtu = ~0;
10813   u32 template_interval = ~0;
10814   u8 udp_checksum = 0;
10815   int ret;
10816
10817   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10818     {
10819       if (unformat (i, "collector_address %U", unformat_ip4_address,
10820                     &collector_address))
10821         collector_address_set = 1;
10822       else if (unformat (i, "collector_port %d", &collector_port))
10823         ;
10824       else if (unformat (i, "src_address %U", unformat_ip4_address,
10825                          &src_address))
10826         src_address_set = 1;
10827       else if (unformat (i, "vrf_id %d", &vrf_id))
10828         ;
10829       else if (unformat (i, "path_mtu %d", &path_mtu))
10830         ;
10831       else if (unformat (i, "template_interval %d", &template_interval))
10832         ;
10833       else if (unformat (i, "udp_checksum"))
10834         udp_checksum = 1;
10835       else
10836         break;
10837     }
10838
10839   if (collector_address_set == 0)
10840     {
10841       errmsg ("collector_address required");
10842       return -99;
10843     }
10844
10845   if (src_address_set == 0)
10846     {
10847       errmsg ("src_address required");
10848       return -99;
10849     }
10850
10851   M (SET_IPFIX_EXPORTER, mp);
10852
10853   memcpy (mp->collector_address.un.ip4, collector_address.data,
10854           sizeof (collector_address.data));
10855   mp->collector_port = htons ((u16) collector_port);
10856   memcpy (mp->src_address.un.ip4, src_address.data,
10857           sizeof (src_address.data));
10858   mp->vrf_id = htonl (vrf_id);
10859   mp->path_mtu = htonl (path_mtu);
10860   mp->template_interval = htonl (template_interval);
10861   mp->udp_checksum = udp_checksum;
10862
10863   S (mp);
10864   W (ret);
10865   return ret;
10866 }
10867
10868 static int
10869 api_set_ipfix_classify_stream (vat_main_t * vam)
10870 {
10871   unformat_input_t *i = vam->input;
10872   vl_api_set_ipfix_classify_stream_t *mp;
10873   u32 domain_id = 0;
10874   u32 src_port = UDP_DST_PORT_ipfix;
10875   int ret;
10876
10877   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10878     {
10879       if (unformat (i, "domain %d", &domain_id))
10880         ;
10881       else if (unformat (i, "src_port %d", &src_port))
10882         ;
10883       else
10884         {
10885           errmsg ("unknown input `%U'", format_unformat_error, i);
10886           return -99;
10887         }
10888     }
10889
10890   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10891
10892   mp->domain_id = htonl (domain_id);
10893   mp->src_port = htons ((u16) src_port);
10894
10895   S (mp);
10896   W (ret);
10897   return ret;
10898 }
10899
10900 static int
10901 api_ipfix_classify_table_add_del (vat_main_t * vam)
10902 {
10903   unformat_input_t *i = vam->input;
10904   vl_api_ipfix_classify_table_add_del_t *mp;
10905   int is_add = -1;
10906   u32 classify_table_index = ~0;
10907   u8 ip_version = 0;
10908   u8 transport_protocol = 255;
10909   int ret;
10910
10911   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10912     {
10913       if (unformat (i, "add"))
10914         is_add = 1;
10915       else if (unformat (i, "del"))
10916         is_add = 0;
10917       else if (unformat (i, "table %d", &classify_table_index))
10918         ;
10919       else if (unformat (i, "ip4"))
10920         ip_version = 4;
10921       else if (unformat (i, "ip6"))
10922         ip_version = 6;
10923       else if (unformat (i, "tcp"))
10924         transport_protocol = 6;
10925       else if (unformat (i, "udp"))
10926         transport_protocol = 17;
10927       else
10928         {
10929           errmsg ("unknown input `%U'", format_unformat_error, i);
10930           return -99;
10931         }
10932     }
10933
10934   if (is_add == -1)
10935     {
10936       errmsg ("expecting: add|del");
10937       return -99;
10938     }
10939   if (classify_table_index == ~0)
10940     {
10941       errmsg ("classifier table not specified");
10942       return -99;
10943     }
10944   if (ip_version == 0)
10945     {
10946       errmsg ("IP version not specified");
10947       return -99;
10948     }
10949
10950   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10951
10952   mp->is_add = is_add;
10953   mp->table_id = htonl (classify_table_index);
10954   mp->ip_version = ip_version;
10955   mp->transport_protocol = transport_protocol;
10956
10957   S (mp);
10958   W (ret);
10959   return ret;
10960 }
10961
10962 static int
10963 api_get_node_index (vat_main_t * vam)
10964 {
10965   unformat_input_t *i = vam->input;
10966   vl_api_get_node_index_t *mp;
10967   u8 *name = 0;
10968   int ret;
10969
10970   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10971     {
10972       if (unformat (i, "node %s", &name))
10973         ;
10974       else
10975         break;
10976     }
10977   if (name == 0)
10978     {
10979       errmsg ("node name required");
10980       return -99;
10981     }
10982   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10983     {
10984       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10985       return -99;
10986     }
10987
10988   M (GET_NODE_INDEX, mp);
10989   clib_memcpy (mp->node_name, name, vec_len (name));
10990   vec_free (name);
10991
10992   S (mp);
10993   W (ret);
10994   return ret;
10995 }
10996
10997 static int
10998 api_get_next_index (vat_main_t * vam)
10999 {
11000   unformat_input_t *i = vam->input;
11001   vl_api_get_next_index_t *mp;
11002   u8 *node_name = 0, *next_node_name = 0;
11003   int ret;
11004
11005   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11006     {
11007       if (unformat (i, "node-name %s", &node_name))
11008         ;
11009       else if (unformat (i, "next-node-name %s", &next_node_name))
11010         break;
11011     }
11012
11013   if (node_name == 0)
11014     {
11015       errmsg ("node name required");
11016       return -99;
11017     }
11018   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11019     {
11020       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11021       return -99;
11022     }
11023
11024   if (next_node_name == 0)
11025     {
11026       errmsg ("next node name required");
11027       return -99;
11028     }
11029   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11030     {
11031       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11032       return -99;
11033     }
11034
11035   M (GET_NEXT_INDEX, mp);
11036   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11037   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11038   vec_free (node_name);
11039   vec_free (next_node_name);
11040
11041   S (mp);
11042   W (ret);
11043   return ret;
11044 }
11045
11046 static int
11047 api_add_node_next (vat_main_t * vam)
11048 {
11049   unformat_input_t *i = vam->input;
11050   vl_api_add_node_next_t *mp;
11051   u8 *name = 0;
11052   u8 *next = 0;
11053   int ret;
11054
11055   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11056     {
11057       if (unformat (i, "node %s", &name))
11058         ;
11059       else if (unformat (i, "next %s", &next))
11060         ;
11061       else
11062         break;
11063     }
11064   if (name == 0)
11065     {
11066       errmsg ("node name required");
11067       return -99;
11068     }
11069   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11070     {
11071       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11072       return -99;
11073     }
11074   if (next == 0)
11075     {
11076       errmsg ("next node required");
11077       return -99;
11078     }
11079   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11080     {
11081       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11082       return -99;
11083     }
11084
11085   M (ADD_NODE_NEXT, mp);
11086   clib_memcpy (mp->node_name, name, vec_len (name));
11087   clib_memcpy (mp->next_name, next, vec_len (next));
11088   vec_free (name);
11089   vec_free (next);
11090
11091   S (mp);
11092   W (ret);
11093   return ret;
11094 }
11095
11096 static int
11097 api_l2tpv3_create_tunnel (vat_main_t * vam)
11098 {
11099   unformat_input_t *i = vam->input;
11100   ip6_address_t client_address, our_address;
11101   int client_address_set = 0;
11102   int our_address_set = 0;
11103   u32 local_session_id = 0;
11104   u32 remote_session_id = 0;
11105   u64 local_cookie = 0;
11106   u64 remote_cookie = 0;
11107   u8 l2_sublayer_present = 0;
11108   vl_api_l2tpv3_create_tunnel_t *mp;
11109   int ret;
11110
11111   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11112     {
11113       if (unformat (i, "client_address %U", unformat_ip6_address,
11114                     &client_address))
11115         client_address_set = 1;
11116       else if (unformat (i, "our_address %U", unformat_ip6_address,
11117                          &our_address))
11118         our_address_set = 1;
11119       else if (unformat (i, "local_session_id %d", &local_session_id))
11120         ;
11121       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11122         ;
11123       else if (unformat (i, "local_cookie %lld", &local_cookie))
11124         ;
11125       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11126         ;
11127       else if (unformat (i, "l2-sublayer-present"))
11128         l2_sublayer_present = 1;
11129       else
11130         break;
11131     }
11132
11133   if (client_address_set == 0)
11134     {
11135       errmsg ("client_address required");
11136       return -99;
11137     }
11138
11139   if (our_address_set == 0)
11140     {
11141       errmsg ("our_address required");
11142       return -99;
11143     }
11144
11145   M (L2TPV3_CREATE_TUNNEL, mp);
11146
11147   clib_memcpy (mp->client_address.un.ip6, client_address.as_u8,
11148                sizeof (ip6_address_t));
11149
11150   clib_memcpy (mp->our_address.un.ip6, our_address.as_u8,
11151                sizeof (ip6_address_t));
11152
11153   mp->local_session_id = ntohl (local_session_id);
11154   mp->remote_session_id = ntohl (remote_session_id);
11155   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11156   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11157   mp->l2_sublayer_present = l2_sublayer_present;
11158
11159   S (mp);
11160   W (ret);
11161   return ret;
11162 }
11163
11164 static int
11165 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11166 {
11167   unformat_input_t *i = vam->input;
11168   u32 sw_if_index;
11169   u8 sw_if_index_set = 0;
11170   u64 new_local_cookie = 0;
11171   u64 new_remote_cookie = 0;
11172   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11173   int ret;
11174
11175   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11176     {
11177       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11178         sw_if_index_set = 1;
11179       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11180         sw_if_index_set = 1;
11181       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11182         ;
11183       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11184         ;
11185       else
11186         break;
11187     }
11188
11189   if (sw_if_index_set == 0)
11190     {
11191       errmsg ("missing interface name or sw_if_index");
11192       return -99;
11193     }
11194
11195   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11196
11197   mp->sw_if_index = ntohl (sw_if_index);
11198   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11199   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11200
11201   S (mp);
11202   W (ret);
11203   return ret;
11204 }
11205
11206 static int
11207 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11208 {
11209   unformat_input_t *i = vam->input;
11210   vl_api_l2tpv3_interface_enable_disable_t *mp;
11211   u32 sw_if_index;
11212   u8 sw_if_index_set = 0;
11213   u8 enable_disable = 1;
11214   int ret;
11215
11216   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11217     {
11218       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11219         sw_if_index_set = 1;
11220       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11221         sw_if_index_set = 1;
11222       else if (unformat (i, "enable"))
11223         enable_disable = 1;
11224       else if (unformat (i, "disable"))
11225         enable_disable = 0;
11226       else
11227         break;
11228     }
11229
11230   if (sw_if_index_set == 0)
11231     {
11232       errmsg ("missing interface name or sw_if_index");
11233       return -99;
11234     }
11235
11236   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11237
11238   mp->sw_if_index = ntohl (sw_if_index);
11239   mp->enable_disable = enable_disable;
11240
11241   S (mp);
11242   W (ret);
11243   return ret;
11244 }
11245
11246 static int
11247 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11248 {
11249   unformat_input_t *i = vam->input;
11250   vl_api_l2tpv3_set_lookup_key_t *mp;
11251   u8 key = ~0;
11252   int ret;
11253
11254   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11255     {
11256       if (unformat (i, "lookup_v6_src"))
11257         key = L2T_LOOKUP_SRC_ADDRESS;
11258       else if (unformat (i, "lookup_v6_dst"))
11259         key = L2T_LOOKUP_DST_ADDRESS;
11260       else if (unformat (i, "lookup_session_id"))
11261         key = L2T_LOOKUP_SESSION_ID;
11262       else
11263         break;
11264     }
11265
11266   if (key == (u8) ~ 0)
11267     {
11268       errmsg ("l2tp session lookup key unset");
11269       return -99;
11270     }
11271
11272   M (L2TPV3_SET_LOOKUP_KEY, mp);
11273
11274   mp->key = key;
11275
11276   S (mp);
11277   W (ret);
11278   return ret;
11279 }
11280
11281 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11282   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11283 {
11284   vat_main_t *vam = &vat_main;
11285
11286   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11287          format_ip6_address, mp->our_address,
11288          format_ip6_address, mp->client_address,
11289          clib_net_to_host_u32 (mp->sw_if_index));
11290
11291   print (vam->ofp,
11292          "   local cookies %016llx %016llx remote cookie %016llx",
11293          clib_net_to_host_u64 (mp->local_cookie[0]),
11294          clib_net_to_host_u64 (mp->local_cookie[1]),
11295          clib_net_to_host_u64 (mp->remote_cookie));
11296
11297   print (vam->ofp, "   local session-id %d remote session-id %d",
11298          clib_net_to_host_u32 (mp->local_session_id),
11299          clib_net_to_host_u32 (mp->remote_session_id));
11300
11301   print (vam->ofp, "   l2 specific sublayer %s\n",
11302          mp->l2_sublayer_present ? "preset" : "absent");
11303
11304 }
11305
11306 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11307   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11308 {
11309   vat_main_t *vam = &vat_main;
11310   vat_json_node_t *node = NULL;
11311   struct in6_addr addr;
11312
11313   if (VAT_JSON_ARRAY != vam->json_tree.type)
11314     {
11315       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11316       vat_json_init_array (&vam->json_tree);
11317     }
11318   node = vat_json_array_add (&vam->json_tree);
11319
11320   vat_json_init_object (node);
11321
11322   clib_memcpy (&addr, mp->our_address.un.ip6, sizeof (addr));
11323   vat_json_object_add_ip6 (node, "our_address", addr);
11324   clib_memcpy (&addr, mp->client_address.un.ip6, sizeof (addr));
11325   vat_json_object_add_ip6 (node, "client_address", addr);
11326
11327   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11328   vat_json_init_array (lc);
11329   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11330   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11331   vat_json_object_add_uint (node, "remote_cookie",
11332                             clib_net_to_host_u64 (mp->remote_cookie));
11333
11334   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11335   vat_json_object_add_uint (node, "local_session_id",
11336                             clib_net_to_host_u32 (mp->local_session_id));
11337   vat_json_object_add_uint (node, "remote_session_id",
11338                             clib_net_to_host_u32 (mp->remote_session_id));
11339   vat_json_object_add_string_copy (node, "l2_sublayer",
11340                                    mp->l2_sublayer_present ? (u8 *) "present"
11341                                    : (u8 *) "absent");
11342 }
11343
11344 static int
11345 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11346 {
11347   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11348   vl_api_control_ping_t *mp_ping;
11349   int ret;
11350
11351   /* Get list of l2tpv3-tunnel interfaces */
11352   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11353   S (mp);
11354
11355   /* Use a control ping for synchronization */
11356   MPING (CONTROL_PING, mp_ping);
11357   S (mp_ping);
11358
11359   W (ret);
11360   return ret;
11361 }
11362
11363
11364 static void vl_api_sw_interface_tap_v2_details_t_handler
11365   (vl_api_sw_interface_tap_v2_details_t * mp)
11366 {
11367   vat_main_t *vam = &vat_main;
11368
11369   u8 *ip4 =
11370     format (0, "%U/%d", format_ip4_address, mp->host_ip4_prefix.address,
11371             mp->host_ip4_prefix.len);
11372   u8 *ip6 =
11373     format (0, "%U/%d", format_ip6_address, mp->host_ip6_prefix.address,
11374             mp->host_ip6_prefix.len);
11375
11376   print (vam->ofp,
11377          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
11378          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
11379          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11380          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
11381          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
11382
11383   vec_free (ip4);
11384   vec_free (ip6);
11385 }
11386
11387 static void vl_api_sw_interface_tap_v2_details_t_handler_json
11388   (vl_api_sw_interface_tap_v2_details_t * mp)
11389 {
11390   vat_main_t *vam = &vat_main;
11391   vat_json_node_t *node = NULL;
11392
11393   if (VAT_JSON_ARRAY != vam->json_tree.type)
11394     {
11395       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11396       vat_json_init_array (&vam->json_tree);
11397     }
11398   node = vat_json_array_add (&vam->json_tree);
11399
11400   vat_json_init_object (node);
11401   vat_json_object_add_uint (node, "id", ntohl (mp->id));
11402   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11403   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
11404   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11405   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11406   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11407   vat_json_object_add_string_copy (node, "host_mac_addr",
11408                                    format (0, "%U", format_ethernet_address,
11409                                            &mp->host_mac_addr));
11410   vat_json_object_add_string_copy (node, "host_namespace",
11411                                    mp->host_namespace);
11412   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
11413   vat_json_object_add_string_copy (node, "host_ip4_addr",
11414                                    format (0, "%U/%d", format_ip4_address,
11415                                            mp->host_ip4_prefix.address,
11416                                            mp->host_ip4_prefix.len));
11417   vat_json_object_add_string_copy (node, "host_ip6_prefix",
11418                                    format (0, "%U/%d", format_ip6_address,
11419                                            mp->host_ip6_prefix.address,
11420                                            mp->host_ip6_prefix.len));
11421
11422 }
11423
11424 static int
11425 api_sw_interface_tap_v2_dump (vat_main_t * vam)
11426 {
11427   vl_api_sw_interface_tap_v2_dump_t *mp;
11428   vl_api_control_ping_t *mp_ping;
11429   int ret;
11430
11431   print (vam->ofp,
11432          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
11433          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
11434          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
11435          "host_ip6_addr");
11436
11437   /* Get list of tap interfaces */
11438   M (SW_INTERFACE_TAP_V2_DUMP, mp);
11439   S (mp);
11440
11441   /* Use a control ping for synchronization */
11442   MPING (CONTROL_PING, mp_ping);
11443   S (mp_ping);
11444
11445   W (ret);
11446   return ret;
11447 }
11448
11449 static void vl_api_sw_interface_virtio_pci_details_t_handler
11450   (vl_api_sw_interface_virtio_pci_details_t * mp)
11451 {
11452   vat_main_t *vam = &vat_main;
11453
11454   typedef union
11455   {
11456     struct
11457     {
11458       u16 domain;
11459       u8 bus;
11460       u8 slot:5;
11461       u8 function:3;
11462     };
11463     u32 as_u32;
11464   } pci_addr_t;
11465   pci_addr_t addr;
11466
11467   addr.domain = ntohs (mp->pci_addr.domain);
11468   addr.bus = mp->pci_addr.bus;
11469   addr.slot = mp->pci_addr.slot;
11470   addr.function = mp->pci_addr.function;
11471
11472   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
11473                          addr.slot, addr.function);
11474
11475   print (vam->ofp,
11476          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
11477          pci_addr, ntohl (mp->sw_if_index),
11478          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11479          format_ethernet_address, mp->mac_addr,
11480          clib_net_to_host_u64 (mp->features));
11481   vec_free (pci_addr);
11482 }
11483
11484 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
11485   (vl_api_sw_interface_virtio_pci_details_t * mp)
11486 {
11487   vat_main_t *vam = &vat_main;
11488   vat_json_node_t *node = NULL;
11489   vlib_pci_addr_t pci_addr;
11490
11491   if (VAT_JSON_ARRAY != vam->json_tree.type)
11492     {
11493       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11494       vat_json_init_array (&vam->json_tree);
11495     }
11496   node = vat_json_array_add (&vam->json_tree);
11497
11498   pci_addr.domain = ntohs (mp->pci_addr.domain);
11499   pci_addr.bus = mp->pci_addr.bus;
11500   pci_addr.slot = mp->pci_addr.slot;
11501   pci_addr.function = mp->pci_addr.function;
11502
11503   vat_json_init_object (node);
11504   vat_json_object_add_uint (node, "pci-addr", pci_addr.as_u32);
11505   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11506   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11507   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11508   vat_json_object_add_uint (node, "features",
11509                             clib_net_to_host_u64 (mp->features));
11510   vat_json_object_add_string_copy (node, "mac_addr",
11511                                    format (0, "%U", format_ethernet_address,
11512                                            &mp->mac_addr));
11513 }
11514
11515 static int
11516 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
11517 {
11518   vl_api_sw_interface_virtio_pci_dump_t *mp;
11519   vl_api_control_ping_t *mp_ping;
11520   int ret;
11521
11522   print (vam->ofp,
11523          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
11524          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
11525          "mac_addr", "features");
11526
11527   /* Get list of tap interfaces */
11528   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
11529   S (mp);
11530
11531   /* Use a control ping for synchronization */
11532   MPING (CONTROL_PING, mp_ping);
11533   S (mp_ping);
11534
11535   W (ret);
11536   return ret;
11537 }
11538
11539 static int
11540 api_vxlan_offload_rx (vat_main_t * vam)
11541 {
11542   unformat_input_t *line_input = vam->input;
11543   vl_api_vxlan_offload_rx_t *mp;
11544   u32 hw_if_index = ~0, rx_if_index = ~0;
11545   u8 is_add = 1;
11546   int ret;
11547
11548   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11549     {
11550       if (unformat (line_input, "del"))
11551         is_add = 0;
11552       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
11553                          &hw_if_index))
11554         ;
11555       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
11556         ;
11557       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
11558                          &rx_if_index))
11559         ;
11560       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
11561         ;
11562       else
11563         {
11564           errmsg ("parse error '%U'", format_unformat_error, line_input);
11565           return -99;
11566         }
11567     }
11568
11569   if (hw_if_index == ~0)
11570     {
11571       errmsg ("no hw interface");
11572       return -99;
11573     }
11574
11575   if (rx_if_index == ~0)
11576     {
11577       errmsg ("no rx tunnel");
11578       return -99;
11579     }
11580
11581   M (VXLAN_OFFLOAD_RX, mp);
11582
11583   mp->hw_if_index = ntohl (hw_if_index);
11584   mp->sw_if_index = ntohl (rx_if_index);
11585   mp->enable = is_add;
11586
11587   S (mp);
11588   W (ret);
11589   return ret;
11590 }
11591
11592 static uword unformat_vxlan_decap_next
11593   (unformat_input_t * input, va_list * args)
11594 {
11595   u32 *result = va_arg (*args, u32 *);
11596   u32 tmp;
11597
11598   if (unformat (input, "l2"))
11599     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11600   else if (unformat (input, "%d", &tmp))
11601     *result = tmp;
11602   else
11603     return 0;
11604   return 1;
11605 }
11606
11607 static int
11608 api_vxlan_add_del_tunnel (vat_main_t * vam)
11609 {
11610   unformat_input_t *line_input = vam->input;
11611   vl_api_vxlan_add_del_tunnel_t *mp;
11612   ip46_address_t src, dst;
11613   u8 is_add = 1;
11614   u8 ipv4_set = 0, ipv6_set = 0;
11615   u8 src_set = 0;
11616   u8 dst_set = 0;
11617   u8 grp_set = 0;
11618   u32 instance = ~0;
11619   u32 mcast_sw_if_index = ~0;
11620   u32 encap_vrf_id = 0;
11621   u32 decap_next_index = ~0;
11622   u32 vni = 0;
11623   int ret;
11624
11625   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11626   clib_memset (&src, 0, sizeof src);
11627   clib_memset (&dst, 0, sizeof dst);
11628
11629   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11630     {
11631       if (unformat (line_input, "del"))
11632         is_add = 0;
11633       else if (unformat (line_input, "instance %d", &instance))
11634         ;
11635       else
11636         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11637         {
11638           ipv4_set = 1;
11639           src_set = 1;
11640         }
11641       else
11642         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11643         {
11644           ipv4_set = 1;
11645           dst_set = 1;
11646         }
11647       else
11648         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11649         {
11650           ipv6_set = 1;
11651           src_set = 1;
11652         }
11653       else
11654         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11655         {
11656           ipv6_set = 1;
11657           dst_set = 1;
11658         }
11659       else if (unformat (line_input, "group %U %U",
11660                          unformat_ip4_address, &dst.ip4,
11661                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11662         {
11663           grp_set = dst_set = 1;
11664           ipv4_set = 1;
11665         }
11666       else if (unformat (line_input, "group %U",
11667                          unformat_ip4_address, &dst.ip4))
11668         {
11669           grp_set = dst_set = 1;
11670           ipv4_set = 1;
11671         }
11672       else if (unformat (line_input, "group %U %U",
11673                          unformat_ip6_address, &dst.ip6,
11674                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11675         {
11676           grp_set = dst_set = 1;
11677           ipv6_set = 1;
11678         }
11679       else if (unformat (line_input, "group %U",
11680                          unformat_ip6_address, &dst.ip6))
11681         {
11682           grp_set = dst_set = 1;
11683           ipv6_set = 1;
11684         }
11685       else
11686         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11687         ;
11688       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11689         ;
11690       else if (unformat (line_input, "decap-next %U",
11691                          unformat_vxlan_decap_next, &decap_next_index))
11692         ;
11693       else if (unformat (line_input, "vni %d", &vni))
11694         ;
11695       else
11696         {
11697           errmsg ("parse error '%U'", format_unformat_error, line_input);
11698           return -99;
11699         }
11700     }
11701
11702   if (src_set == 0)
11703     {
11704       errmsg ("tunnel src address not specified");
11705       return -99;
11706     }
11707   if (dst_set == 0)
11708     {
11709       errmsg ("tunnel dst address not specified");
11710       return -99;
11711     }
11712
11713   if (grp_set && !ip46_address_is_multicast (&dst))
11714     {
11715       errmsg ("tunnel group address not multicast");
11716       return -99;
11717     }
11718   if (grp_set && mcast_sw_if_index == ~0)
11719     {
11720       errmsg ("tunnel nonexistent multicast device");
11721       return -99;
11722     }
11723   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11724     {
11725       errmsg ("tunnel dst address must be unicast");
11726       return -99;
11727     }
11728
11729
11730   if (ipv4_set && ipv6_set)
11731     {
11732       errmsg ("both IPv4 and IPv6 addresses specified");
11733       return -99;
11734     }
11735
11736   if ((vni == 0) || (vni >> 24))
11737     {
11738       errmsg ("vni not specified or out of range");
11739       return -99;
11740     }
11741
11742   M (VXLAN_ADD_DEL_TUNNEL, mp);
11743
11744   if (ipv6_set)
11745     {
11746       clib_memcpy (mp->src_address.un.ip6, &src.ip6, sizeof (src.ip6));
11747       clib_memcpy (mp->dst_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
11748     }
11749   else
11750     {
11751       clib_memcpy (mp->src_address.un.ip4, &src.ip4, sizeof (src.ip4));
11752       clib_memcpy (mp->dst_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
11753     }
11754   mp->src_address.af = ipv6_set;
11755   mp->dst_address.af = ipv6_set;
11756
11757   mp->instance = htonl (instance);
11758   mp->encap_vrf_id = ntohl (encap_vrf_id);
11759   mp->decap_next_index = ntohl (decap_next_index);
11760   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11761   mp->vni = ntohl (vni);
11762   mp->is_add = is_add;
11763
11764   S (mp);
11765   W (ret);
11766   return ret;
11767 }
11768
11769 static void vl_api_vxlan_tunnel_details_t_handler
11770   (vl_api_vxlan_tunnel_details_t * mp)
11771 {
11772   vat_main_t *vam = &vat_main;
11773   ip46_address_t src =
11774     to_ip46 (mp->dst_address.af, (u8 *) & mp->dst_address.un);
11775   ip46_address_t dst =
11776     to_ip46 (mp->dst_address.af, (u8 *) & mp->src_address.un);
11777
11778   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
11779          ntohl (mp->sw_if_index),
11780          ntohl (mp->instance),
11781          format_ip46_address, &src, IP46_TYPE_ANY,
11782          format_ip46_address, &dst, IP46_TYPE_ANY,
11783          ntohl (mp->encap_vrf_id),
11784          ntohl (mp->decap_next_index), ntohl (mp->vni),
11785          ntohl (mp->mcast_sw_if_index));
11786 }
11787
11788 static void vl_api_vxlan_tunnel_details_t_handler_json
11789   (vl_api_vxlan_tunnel_details_t * mp)
11790 {
11791   vat_main_t *vam = &vat_main;
11792   vat_json_node_t *node = NULL;
11793
11794   if (VAT_JSON_ARRAY != vam->json_tree.type)
11795     {
11796       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11797       vat_json_init_array (&vam->json_tree);
11798     }
11799   node = vat_json_array_add (&vam->json_tree);
11800
11801   vat_json_init_object (node);
11802   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11803
11804   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
11805
11806   if (mp->src_address.af)
11807     {
11808       struct in6_addr ip6;
11809
11810       clib_memcpy (&ip6, mp->src_address.un.ip6, sizeof (ip6));
11811       vat_json_object_add_ip6 (node, "src_address", ip6);
11812       clib_memcpy (&ip6, mp->dst_address.un.ip6, sizeof (ip6));
11813       vat_json_object_add_ip6 (node, "dst_address", ip6);
11814     }
11815   else
11816     {
11817       struct in_addr ip4;
11818
11819       clib_memcpy (&ip4, mp->src_address.un.ip4, sizeof (ip4));
11820       vat_json_object_add_ip4 (node, "src_address", ip4);
11821       clib_memcpy (&ip4, mp->dst_address.un.ip4, sizeof (ip4));
11822       vat_json_object_add_ip4 (node, "dst_address", ip4);
11823     }
11824   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11825   vat_json_object_add_uint (node, "decap_next_index",
11826                             ntohl (mp->decap_next_index));
11827   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11828   vat_json_object_add_uint (node, "mcast_sw_if_index",
11829                             ntohl (mp->mcast_sw_if_index));
11830 }
11831
11832 static int
11833 api_vxlan_tunnel_dump (vat_main_t * vam)
11834 {
11835   unformat_input_t *i = vam->input;
11836   vl_api_vxlan_tunnel_dump_t *mp;
11837   vl_api_control_ping_t *mp_ping;
11838   u32 sw_if_index;
11839   u8 sw_if_index_set = 0;
11840   int ret;
11841
11842   /* Parse args required to build the message */
11843   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11844     {
11845       if (unformat (i, "sw_if_index %d", &sw_if_index))
11846         sw_if_index_set = 1;
11847       else
11848         break;
11849     }
11850
11851   if (sw_if_index_set == 0)
11852     {
11853       sw_if_index = ~0;
11854     }
11855
11856   if (!vam->json_output)
11857     {
11858       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
11859              "sw_if_index", "instance", "src_address", "dst_address",
11860              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
11861     }
11862
11863   /* Get list of vxlan-tunnel interfaces */
11864   M (VXLAN_TUNNEL_DUMP, mp);
11865
11866   mp->sw_if_index = htonl (sw_if_index);
11867
11868   S (mp);
11869
11870   /* Use a control ping for synchronization */
11871   MPING (CONTROL_PING, mp_ping);
11872   S (mp_ping);
11873
11874   W (ret);
11875   return ret;
11876 }
11877
11878 static uword unformat_geneve_decap_next
11879   (unformat_input_t * input, va_list * args)
11880 {
11881   u32 *result = va_arg (*args, u32 *);
11882   u32 tmp;
11883
11884   if (unformat (input, "l2"))
11885     *result = GENEVE_INPUT_NEXT_L2_INPUT;
11886   else if (unformat (input, "%d", &tmp))
11887     *result = tmp;
11888   else
11889     return 0;
11890   return 1;
11891 }
11892
11893 static int
11894 api_geneve_add_del_tunnel (vat_main_t * vam)
11895 {
11896   unformat_input_t *line_input = vam->input;
11897   vl_api_geneve_add_del_tunnel_t *mp;
11898   ip46_address_t src, dst;
11899   u8 is_add = 1;
11900   u8 ipv4_set = 0, ipv6_set = 0;
11901   u8 src_set = 0;
11902   u8 dst_set = 0;
11903   u8 grp_set = 0;
11904   u32 mcast_sw_if_index = ~0;
11905   u32 encap_vrf_id = 0;
11906   u32 decap_next_index = ~0;
11907   u32 vni = 0;
11908   int ret;
11909
11910   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11911   clib_memset (&src, 0, sizeof src);
11912   clib_memset (&dst, 0, sizeof dst);
11913
11914   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11915     {
11916       if (unformat (line_input, "del"))
11917         is_add = 0;
11918       else
11919         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11920         {
11921           ipv4_set = 1;
11922           src_set = 1;
11923         }
11924       else
11925         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11926         {
11927           ipv4_set = 1;
11928           dst_set = 1;
11929         }
11930       else
11931         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11932         {
11933           ipv6_set = 1;
11934           src_set = 1;
11935         }
11936       else
11937         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11938         {
11939           ipv6_set = 1;
11940           dst_set = 1;
11941         }
11942       else if (unformat (line_input, "group %U %U",
11943                          unformat_ip4_address, &dst.ip4,
11944                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11945         {
11946           grp_set = dst_set = 1;
11947           ipv4_set = 1;
11948         }
11949       else if (unformat (line_input, "group %U",
11950                          unformat_ip4_address, &dst.ip4))
11951         {
11952           grp_set = dst_set = 1;
11953           ipv4_set = 1;
11954         }
11955       else if (unformat (line_input, "group %U %U",
11956                          unformat_ip6_address, &dst.ip6,
11957                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11958         {
11959           grp_set = dst_set = 1;
11960           ipv6_set = 1;
11961         }
11962       else if (unformat (line_input, "group %U",
11963                          unformat_ip6_address, &dst.ip6))
11964         {
11965           grp_set = dst_set = 1;
11966           ipv6_set = 1;
11967         }
11968       else
11969         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11970         ;
11971       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11972         ;
11973       else if (unformat (line_input, "decap-next %U",
11974                          unformat_geneve_decap_next, &decap_next_index))
11975         ;
11976       else if (unformat (line_input, "vni %d", &vni))
11977         ;
11978       else
11979         {
11980           errmsg ("parse error '%U'", format_unformat_error, line_input);
11981           return -99;
11982         }
11983     }
11984
11985   if (src_set == 0)
11986     {
11987       errmsg ("tunnel src address not specified");
11988       return -99;
11989     }
11990   if (dst_set == 0)
11991     {
11992       errmsg ("tunnel dst address not specified");
11993       return -99;
11994     }
11995
11996   if (grp_set && !ip46_address_is_multicast (&dst))
11997     {
11998       errmsg ("tunnel group address not multicast");
11999       return -99;
12000     }
12001   if (grp_set && mcast_sw_if_index == ~0)
12002     {
12003       errmsg ("tunnel nonexistent multicast device");
12004       return -99;
12005     }
12006   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12007     {
12008       errmsg ("tunnel dst address must be unicast");
12009       return -99;
12010     }
12011
12012
12013   if (ipv4_set && ipv6_set)
12014     {
12015       errmsg ("both IPv4 and IPv6 addresses specified");
12016       return -99;
12017     }
12018
12019   if ((vni == 0) || (vni >> 24))
12020     {
12021       errmsg ("vni not specified or out of range");
12022       return -99;
12023     }
12024
12025   M (GENEVE_ADD_DEL_TUNNEL, mp);
12026
12027   if (ipv6_set)
12028     {
12029       clib_memcpy (&mp->local_address.un.ip6, &src.ip6, sizeof (src.ip6));
12030       clib_memcpy (&mp->remote_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
12031     }
12032   else
12033     {
12034       clib_memcpy (&mp->local_address.un.ip4, &src.ip4, sizeof (src.ip4));
12035       clib_memcpy (&mp->remote_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
12036     }
12037   mp->encap_vrf_id = ntohl (encap_vrf_id);
12038   mp->decap_next_index = ntohl (decap_next_index);
12039   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12040   mp->vni = ntohl (vni);
12041   mp->is_add = is_add;
12042
12043   S (mp);
12044   W (ret);
12045   return ret;
12046 }
12047
12048 static void vl_api_geneve_tunnel_details_t_handler
12049   (vl_api_geneve_tunnel_details_t * mp)
12050 {
12051   vat_main_t *vam = &vat_main;
12052   ip46_address_t src = {.as_u64[0] = 0,.as_u64[1] = 0 };
12053   ip46_address_t dst = {.as_u64[0] = 0,.as_u64[1] = 0 };
12054
12055   if (mp->src_address.af == ADDRESS_IP6)
12056     {
12057       clib_memcpy (&src.ip6, &mp->src_address.un.ip6, sizeof (ip6_address_t));
12058       clib_memcpy (&dst.ip6, &mp->dst_address.un.ip6, sizeof (ip6_address_t));
12059     }
12060   else
12061     {
12062       clib_memcpy (&src.ip4, &mp->src_address.un.ip4, sizeof (ip4_address_t));
12063       clib_memcpy (&dst.ip4, &mp->dst_address.un.ip4, sizeof (ip4_address_t));
12064     }
12065
12066   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12067          ntohl (mp->sw_if_index),
12068          format_ip46_address, &src, IP46_TYPE_ANY,
12069          format_ip46_address, &dst, IP46_TYPE_ANY,
12070          ntohl (mp->encap_vrf_id),
12071          ntohl (mp->decap_next_index), ntohl (mp->vni),
12072          ntohl (mp->mcast_sw_if_index));
12073 }
12074
12075 static void vl_api_geneve_tunnel_details_t_handler_json
12076   (vl_api_geneve_tunnel_details_t * mp)
12077 {
12078   vat_main_t *vam = &vat_main;
12079   vat_json_node_t *node = NULL;
12080   bool is_ipv6;
12081
12082   if (VAT_JSON_ARRAY != vam->json_tree.type)
12083     {
12084       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12085       vat_json_init_array (&vam->json_tree);
12086     }
12087   node = vat_json_array_add (&vam->json_tree);
12088
12089   vat_json_init_object (node);
12090   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12091   is_ipv6 = mp->src_address.af == ADDRESS_IP6;
12092   if (is_ipv6)
12093     {
12094       struct in6_addr ip6;
12095
12096       clib_memcpy (&ip6, &mp->src_address.un.ip6, sizeof (ip6));
12097       vat_json_object_add_ip6 (node, "src_address", ip6);
12098       clib_memcpy (&ip6, &mp->dst_address.un.ip6, sizeof (ip6));
12099       vat_json_object_add_ip6 (node, "dst_address", ip6);
12100     }
12101   else
12102     {
12103       struct in_addr ip4;
12104
12105       clib_memcpy (&ip4, &mp->src_address.un.ip4, sizeof (ip4));
12106       vat_json_object_add_ip4 (node, "src_address", ip4);
12107       clib_memcpy (&ip4, &mp->dst_address.un.ip4, sizeof (ip4));
12108       vat_json_object_add_ip4 (node, "dst_address", ip4);
12109     }
12110   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12111   vat_json_object_add_uint (node, "decap_next_index",
12112                             ntohl (mp->decap_next_index));
12113   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12114   vat_json_object_add_uint (node, "mcast_sw_if_index",
12115                             ntohl (mp->mcast_sw_if_index));
12116 }
12117
12118 static int
12119 api_geneve_tunnel_dump (vat_main_t * vam)
12120 {
12121   unformat_input_t *i = vam->input;
12122   vl_api_geneve_tunnel_dump_t *mp;
12123   vl_api_control_ping_t *mp_ping;
12124   u32 sw_if_index;
12125   u8 sw_if_index_set = 0;
12126   int ret;
12127
12128   /* Parse args required to build the message */
12129   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12130     {
12131       if (unformat (i, "sw_if_index %d", &sw_if_index))
12132         sw_if_index_set = 1;
12133       else
12134         break;
12135     }
12136
12137   if (sw_if_index_set == 0)
12138     {
12139       sw_if_index = ~0;
12140     }
12141
12142   if (!vam->json_output)
12143     {
12144       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12145              "sw_if_index", "local_address", "remote_address",
12146              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12147     }
12148
12149   /* Get list of geneve-tunnel interfaces */
12150   M (GENEVE_TUNNEL_DUMP, mp);
12151
12152   mp->sw_if_index = htonl (sw_if_index);
12153
12154   S (mp);
12155
12156   /* Use a control ping for synchronization */
12157   M (CONTROL_PING, mp_ping);
12158   S (mp_ping);
12159
12160   W (ret);
12161   return ret;
12162 }
12163
12164 static int
12165 api_gre_tunnel_add_del (vat_main_t * vam)
12166 {
12167   unformat_input_t *line_input = vam->input;
12168   vl_api_address_t src = { }, dst =
12169   {
12170   };
12171   vl_api_gre_tunnel_add_del_t *mp;
12172   vl_api_gre_tunnel_type_t t_type;
12173   u8 is_add = 1;
12174   u8 src_set = 0;
12175   u8 dst_set = 0;
12176   u32 outer_table_id = 0;
12177   u32 session_id = 0;
12178   u32 instance = ~0;
12179   int ret;
12180
12181   t_type = GRE_API_TUNNEL_TYPE_L3;
12182
12183   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12184     {
12185       if (unformat (line_input, "del"))
12186         is_add = 0;
12187       else if (unformat (line_input, "instance %d", &instance))
12188         ;
12189       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
12190         {
12191           src_set = 1;
12192         }
12193       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
12194         {
12195           dst_set = 1;
12196         }
12197       else if (unformat (line_input, "outer-table-id %d", &outer_table_id))
12198         ;
12199       else if (unformat (line_input, "teb"))
12200         t_type = GRE_API_TUNNEL_TYPE_TEB;
12201       else if (unformat (line_input, "erspan %d", &session_id))
12202         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
12203       else
12204         {
12205           errmsg ("parse error '%U'", format_unformat_error, line_input);
12206           return -99;
12207         }
12208     }
12209
12210   if (src_set == 0)
12211     {
12212       errmsg ("tunnel src address not specified");
12213       return -99;
12214     }
12215   if (dst_set == 0)
12216     {
12217       errmsg ("tunnel dst address not specified");
12218       return -99;
12219     }
12220
12221   M (GRE_TUNNEL_ADD_DEL, mp);
12222
12223   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
12224   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
12225
12226   mp->tunnel.instance = htonl (instance);
12227   mp->tunnel.outer_table_id = htonl (outer_table_id);
12228   mp->is_add = is_add;
12229   mp->tunnel.session_id = htons ((u16) session_id);
12230   mp->tunnel.type = htonl (t_type);
12231
12232   S (mp);
12233   W (ret);
12234   return ret;
12235 }
12236
12237 static void vl_api_gre_tunnel_details_t_handler
12238   (vl_api_gre_tunnel_details_t * mp)
12239 {
12240   vat_main_t *vam = &vat_main;
12241
12242   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
12243          ntohl (mp->tunnel.sw_if_index),
12244          ntohl (mp->tunnel.instance),
12245          format_vl_api_address, &mp->tunnel.src,
12246          format_vl_api_address, &mp->tunnel.dst,
12247          mp->tunnel.type, ntohl (mp->tunnel.outer_table_id),
12248          ntohl (mp->tunnel.session_id));
12249 }
12250
12251 static void vl_api_gre_tunnel_details_t_handler_json
12252   (vl_api_gre_tunnel_details_t * mp)
12253 {
12254   vat_main_t *vam = &vat_main;
12255   vat_json_node_t *node = NULL;
12256
12257   if (VAT_JSON_ARRAY != vam->json_tree.type)
12258     {
12259       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12260       vat_json_init_array (&vam->json_tree);
12261     }
12262   node = vat_json_array_add (&vam->json_tree);
12263
12264   vat_json_init_object (node);
12265   vat_json_object_add_uint (node, "sw_if_index",
12266                             ntohl (mp->tunnel.sw_if_index));
12267   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
12268
12269   vat_json_object_add_address (node, "src", &mp->tunnel.src);
12270   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
12271   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
12272   vat_json_object_add_uint (node, "outer_table_id",
12273                             ntohl (mp->tunnel.outer_table_id));
12274   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
12275 }
12276
12277 static int
12278 api_gre_tunnel_dump (vat_main_t * vam)
12279 {
12280   unformat_input_t *i = vam->input;
12281   vl_api_gre_tunnel_dump_t *mp;
12282   vl_api_control_ping_t *mp_ping;
12283   u32 sw_if_index;
12284   u8 sw_if_index_set = 0;
12285   int ret;
12286
12287   /* Parse args required to build the message */
12288   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12289     {
12290       if (unformat (i, "sw_if_index %d", &sw_if_index))
12291         sw_if_index_set = 1;
12292       else
12293         break;
12294     }
12295
12296   if (sw_if_index_set == 0)
12297     {
12298       sw_if_index = ~0;
12299     }
12300
12301   if (!vam->json_output)
12302     {
12303       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
12304              "sw_if_index", "instance", "src_address", "dst_address",
12305              "tunnel_type", "outer_fib_id", "session_id");
12306     }
12307
12308   /* Get list of gre-tunnel interfaces */
12309   M (GRE_TUNNEL_DUMP, mp);
12310
12311   mp->sw_if_index = htonl (sw_if_index);
12312
12313   S (mp);
12314
12315   /* Use a control ping for synchronization */
12316   MPING (CONTROL_PING, mp_ping);
12317   S (mp_ping);
12318
12319   W (ret);
12320   return ret;
12321 }
12322
12323 static int
12324 api_l2_fib_clear_table (vat_main_t * vam)
12325 {
12326 //  unformat_input_t * i = vam->input;
12327   vl_api_l2_fib_clear_table_t *mp;
12328   int ret;
12329
12330   M (L2_FIB_CLEAR_TABLE, mp);
12331
12332   S (mp);
12333   W (ret);
12334   return ret;
12335 }
12336
12337 static int
12338 api_l2_interface_efp_filter (vat_main_t * vam)
12339 {
12340   unformat_input_t *i = vam->input;
12341   vl_api_l2_interface_efp_filter_t *mp;
12342   u32 sw_if_index;
12343   u8 enable = 1;
12344   u8 sw_if_index_set = 0;
12345   int ret;
12346
12347   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12348     {
12349       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12350         sw_if_index_set = 1;
12351       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12352         sw_if_index_set = 1;
12353       else if (unformat (i, "enable"))
12354         enable = 1;
12355       else if (unformat (i, "disable"))
12356         enable = 0;
12357       else
12358         {
12359           clib_warning ("parse error '%U'", format_unformat_error, i);
12360           return -99;
12361         }
12362     }
12363
12364   if (sw_if_index_set == 0)
12365     {
12366       errmsg ("missing sw_if_index");
12367       return -99;
12368     }
12369
12370   M (L2_INTERFACE_EFP_FILTER, mp);
12371
12372   mp->sw_if_index = ntohl (sw_if_index);
12373   mp->enable_disable = enable;
12374
12375   S (mp);
12376   W (ret);
12377   return ret;
12378 }
12379
12380 #define foreach_vtr_op                          \
12381 _("disable",  L2_VTR_DISABLED)                  \
12382 _("push-1",  L2_VTR_PUSH_1)                     \
12383 _("push-2",  L2_VTR_PUSH_2)                     \
12384 _("pop-1",  L2_VTR_POP_1)                       \
12385 _("pop-2",  L2_VTR_POP_2)                       \
12386 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12387 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12388 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12389 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12390
12391 static int
12392 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12393 {
12394   unformat_input_t *i = vam->input;
12395   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12396   u32 sw_if_index;
12397   u8 sw_if_index_set = 0;
12398   u8 vtr_op_set = 0;
12399   u32 vtr_op = 0;
12400   u32 push_dot1q = 1;
12401   u32 tag1 = ~0;
12402   u32 tag2 = ~0;
12403   int ret;
12404
12405   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12406     {
12407       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12408         sw_if_index_set = 1;
12409       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12410         sw_if_index_set = 1;
12411       else if (unformat (i, "vtr_op %d", &vtr_op))
12412         vtr_op_set = 1;
12413 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12414       foreach_vtr_op
12415 #undef _
12416         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12417         ;
12418       else if (unformat (i, "tag1 %d", &tag1))
12419         ;
12420       else if (unformat (i, "tag2 %d", &tag2))
12421         ;
12422       else
12423         {
12424           clib_warning ("parse error '%U'", format_unformat_error, i);
12425           return -99;
12426         }
12427     }
12428
12429   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12430     {
12431       errmsg ("missing vtr operation or sw_if_index");
12432       return -99;
12433     }
12434
12435   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12436   mp->sw_if_index = ntohl (sw_if_index);
12437   mp->vtr_op = ntohl (vtr_op);
12438   mp->push_dot1q = ntohl (push_dot1q);
12439   mp->tag1 = ntohl (tag1);
12440   mp->tag2 = ntohl (tag2);
12441
12442   S (mp);
12443   W (ret);
12444   return ret;
12445 }
12446
12447 static int
12448 api_create_vhost_user_if (vat_main_t * vam)
12449 {
12450   unformat_input_t *i = vam->input;
12451   vl_api_create_vhost_user_if_t *mp;
12452   u8 *file_name;
12453   u8 is_server = 0;
12454   u8 file_name_set = 0;
12455   u32 custom_dev_instance = ~0;
12456   u8 hwaddr[6];
12457   u8 use_custom_mac = 0;
12458   u8 disable_mrg_rxbuf = 0;
12459   u8 disable_indirect_desc = 0;
12460   u8 *tag = 0;
12461   u8 enable_gso = 0;
12462   u8 enable_packed = 0;
12463   int ret;
12464
12465   /* Shut up coverity */
12466   clib_memset (hwaddr, 0, sizeof (hwaddr));
12467
12468   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12469     {
12470       if (unformat (i, "socket %s", &file_name))
12471         {
12472           file_name_set = 1;
12473         }
12474       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12475         ;
12476       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12477         use_custom_mac = 1;
12478       else if (unformat (i, "server"))
12479         is_server = 1;
12480       else if (unformat (i, "disable_mrg_rxbuf"))
12481         disable_mrg_rxbuf = 1;
12482       else if (unformat (i, "disable_indirect_desc"))
12483         disable_indirect_desc = 1;
12484       else if (unformat (i, "gso"))
12485         enable_gso = 1;
12486       else if (unformat (i, "packed"))
12487         enable_packed = 1;
12488       else if (unformat (i, "tag %s", &tag))
12489         ;
12490       else
12491         break;
12492     }
12493
12494   if (file_name_set == 0)
12495     {
12496       errmsg ("missing socket file name");
12497       return -99;
12498     }
12499
12500   if (vec_len (file_name) > 255)
12501     {
12502       errmsg ("socket file name too long");
12503       return -99;
12504     }
12505   vec_add1 (file_name, 0);
12506
12507   M (CREATE_VHOST_USER_IF, mp);
12508
12509   mp->is_server = is_server;
12510   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
12511   mp->disable_indirect_desc = disable_indirect_desc;
12512   mp->enable_gso = enable_gso;
12513   mp->enable_packed = enable_packed;
12514   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12515   vec_free (file_name);
12516   if (custom_dev_instance != ~0)
12517     {
12518       mp->renumber = 1;
12519       mp->custom_dev_instance = ntohl (custom_dev_instance);
12520     }
12521
12522   mp->use_custom_mac = use_custom_mac;
12523   clib_memcpy (mp->mac_address, hwaddr, 6);
12524   if (tag)
12525     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
12526   vec_free (tag);
12527
12528   S (mp);
12529   W (ret);
12530   return ret;
12531 }
12532
12533 static int
12534 api_modify_vhost_user_if (vat_main_t * vam)
12535 {
12536   unformat_input_t *i = vam->input;
12537   vl_api_modify_vhost_user_if_t *mp;
12538   u8 *file_name;
12539   u8 is_server = 0;
12540   u8 file_name_set = 0;
12541   u32 custom_dev_instance = ~0;
12542   u8 sw_if_index_set = 0;
12543   u32 sw_if_index = (u32) ~ 0;
12544   u8 enable_gso = 0;
12545   u8 enable_packed = 0;
12546   int ret;
12547
12548   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12549     {
12550       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12551         sw_if_index_set = 1;
12552       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12553         sw_if_index_set = 1;
12554       else if (unformat (i, "socket %s", &file_name))
12555         {
12556           file_name_set = 1;
12557         }
12558       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12559         ;
12560       else if (unformat (i, "server"))
12561         is_server = 1;
12562       else if (unformat (i, "gso"))
12563         enable_gso = 1;
12564       else if (unformat (i, "packed"))
12565         enable_packed = 1;
12566       else
12567         break;
12568     }
12569
12570   if (sw_if_index_set == 0)
12571     {
12572       errmsg ("missing sw_if_index or interface name");
12573       return -99;
12574     }
12575
12576   if (file_name_set == 0)
12577     {
12578       errmsg ("missing socket file name");
12579       return -99;
12580     }
12581
12582   if (vec_len (file_name) > 255)
12583     {
12584       errmsg ("socket file name too long");
12585       return -99;
12586     }
12587   vec_add1 (file_name, 0);
12588
12589   M (MODIFY_VHOST_USER_IF, mp);
12590
12591   mp->sw_if_index = ntohl (sw_if_index);
12592   mp->is_server = is_server;
12593   mp->enable_gso = enable_gso;
12594   mp->enable_packed = enable_packed;
12595   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12596   vec_free (file_name);
12597   if (custom_dev_instance != ~0)
12598     {
12599       mp->renumber = 1;
12600       mp->custom_dev_instance = ntohl (custom_dev_instance);
12601     }
12602
12603   S (mp);
12604   W (ret);
12605   return ret;
12606 }
12607
12608 static int
12609 api_delete_vhost_user_if (vat_main_t * vam)
12610 {
12611   unformat_input_t *i = vam->input;
12612   vl_api_delete_vhost_user_if_t *mp;
12613   u32 sw_if_index = ~0;
12614   u8 sw_if_index_set = 0;
12615   int ret;
12616
12617   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12618     {
12619       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12620         sw_if_index_set = 1;
12621       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12622         sw_if_index_set = 1;
12623       else
12624         break;
12625     }
12626
12627   if (sw_if_index_set == 0)
12628     {
12629       errmsg ("missing sw_if_index or interface name");
12630       return -99;
12631     }
12632
12633
12634   M (DELETE_VHOST_USER_IF, mp);
12635
12636   mp->sw_if_index = ntohl (sw_if_index);
12637
12638   S (mp);
12639   W (ret);
12640   return ret;
12641 }
12642
12643 static void vl_api_sw_interface_vhost_user_details_t_handler
12644   (vl_api_sw_interface_vhost_user_details_t * mp)
12645 {
12646   vat_main_t *vam = &vat_main;
12647   u64 features;
12648
12649   features =
12650     clib_net_to_host_u32 (mp->features_first_32) | ((u64)
12651                                                     clib_net_to_host_u32
12652                                                     (mp->features_last_32) <<
12653                                                     32);
12654
12655   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
12656          (char *) mp->interface_name,
12657          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
12658          features, mp->is_server,
12659          ntohl (mp->num_regions), (char *) mp->sock_filename);
12660   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
12661 }
12662
12663 static void vl_api_sw_interface_vhost_user_details_t_handler_json
12664   (vl_api_sw_interface_vhost_user_details_t * mp)
12665 {
12666   vat_main_t *vam = &vat_main;
12667   vat_json_node_t *node = NULL;
12668
12669   if (VAT_JSON_ARRAY != vam->json_tree.type)
12670     {
12671       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12672       vat_json_init_array (&vam->json_tree);
12673     }
12674   node = vat_json_array_add (&vam->json_tree);
12675
12676   vat_json_init_object (node);
12677   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12678   vat_json_object_add_string_copy (node, "interface_name",
12679                                    mp->interface_name);
12680   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
12681                             ntohl (mp->virtio_net_hdr_sz));
12682   vat_json_object_add_uint (node, "features_first_32",
12683                             clib_net_to_host_u32 (mp->features_first_32));
12684   vat_json_object_add_uint (node, "features_last_32",
12685                             clib_net_to_host_u32 (mp->features_last_32));
12686   vat_json_object_add_uint (node, "is_server", mp->is_server);
12687   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
12688   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
12689   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
12690 }
12691
12692 static int
12693 api_sw_interface_vhost_user_dump (vat_main_t * vam)
12694 {
12695   unformat_input_t *i = vam->input;
12696   vl_api_sw_interface_vhost_user_dump_t *mp;
12697   vl_api_control_ping_t *mp_ping;
12698   int ret;
12699   u32 sw_if_index = ~0;
12700
12701   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12702     {
12703       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12704         ;
12705       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12706         ;
12707       else
12708         break;
12709     }
12710
12711   print (vam->ofp,
12712          "Interface name            idx hdr_sz features server regions filename");
12713
12714   /* Get list of vhost-user interfaces */
12715   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
12716   mp->sw_if_index = ntohl (sw_if_index);
12717   S (mp);
12718
12719   /* Use a control ping for synchronization */
12720   MPING (CONTROL_PING, mp_ping);
12721   S (mp_ping);
12722
12723   W (ret);
12724   return ret;
12725 }
12726
12727 static int
12728 api_show_version (vat_main_t * vam)
12729 {
12730   vl_api_show_version_t *mp;
12731   int ret;
12732
12733   M (SHOW_VERSION, mp);
12734
12735   S (mp);
12736   W (ret);
12737   return ret;
12738 }
12739
12740
12741 static int
12742 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
12743 {
12744   unformat_input_t *line_input = vam->input;
12745   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
12746   ip46_address_t local, remote;
12747   u8 is_add = 1;
12748   u8 local_set = 0;
12749   u8 remote_set = 0;
12750   u8 grp_set = 0;
12751   u32 mcast_sw_if_index = ~0;
12752   u32 encap_vrf_id = 0;
12753   u32 decap_vrf_id = 0;
12754   u8 protocol = ~0;
12755   u32 vni;
12756   u8 vni_set = 0;
12757   int ret;
12758
12759   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12760     {
12761       if (unformat (line_input, "del"))
12762         is_add = 0;
12763       else if (unformat (line_input, "local %U",
12764                          unformat_ip46_address, &local))
12765         {
12766           local_set = 1;
12767         }
12768       else if (unformat (line_input, "remote %U",
12769                          unformat_ip46_address, &remote))
12770         {
12771           remote_set = 1;
12772         }
12773       else if (unformat (line_input, "group %U %U",
12774                          unformat_ip46_address, &remote,
12775                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12776         {
12777           grp_set = remote_set = 1;
12778         }
12779       else if (unformat (line_input, "group %U",
12780                          unformat_ip46_address, &remote))
12781         {
12782           grp_set = remote_set = 1;
12783         }
12784       else
12785         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12786         ;
12787       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12788         ;
12789       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
12790         ;
12791       else if (unformat (line_input, "vni %d", &vni))
12792         vni_set = 1;
12793       else if (unformat (line_input, "next-ip4"))
12794         protocol = 1;
12795       else if (unformat (line_input, "next-ip6"))
12796         protocol = 2;
12797       else if (unformat (line_input, "next-ethernet"))
12798         protocol = 3;
12799       else if (unformat (line_input, "next-nsh"))
12800         protocol = 4;
12801       else
12802         {
12803           errmsg ("parse error '%U'", format_unformat_error, line_input);
12804           return -99;
12805         }
12806     }
12807
12808   if (local_set == 0)
12809     {
12810       errmsg ("tunnel local address not specified");
12811       return -99;
12812     }
12813   if (remote_set == 0)
12814     {
12815       errmsg ("tunnel remote address not specified");
12816       return -99;
12817     }
12818   if (grp_set && mcast_sw_if_index == ~0)
12819     {
12820       errmsg ("tunnel nonexistent multicast device");
12821       return -99;
12822     }
12823   if (ip46_address_is_ip4 (&local) != ip46_address_is_ip4 (&remote))
12824     {
12825       errmsg ("both IPv4 and IPv6 addresses specified");
12826       return -99;
12827     }
12828
12829   if (vni_set == 0)
12830     {
12831       errmsg ("vni not specified");
12832       return -99;
12833     }
12834
12835   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
12836
12837   ip_address_encode (&local,
12838                      ip46_address_is_ip4 (&local) ? IP46_TYPE_IP4 :
12839                      IP46_TYPE_IP6, &mp->local);
12840   ip_address_encode (&remote,
12841                      ip46_address_is_ip4 (&remote) ? IP46_TYPE_IP4 :
12842                      IP46_TYPE_IP6, &mp->remote);
12843
12844   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12845   mp->encap_vrf_id = ntohl (encap_vrf_id);
12846   mp->decap_vrf_id = ntohl (decap_vrf_id);
12847   mp->protocol = protocol;
12848   mp->vni = ntohl (vni);
12849   mp->is_add = is_add;
12850
12851   S (mp);
12852   W (ret);
12853   return ret;
12854 }
12855
12856 static void vl_api_vxlan_gpe_tunnel_details_t_handler
12857   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12858 {
12859   vat_main_t *vam = &vat_main;
12860   ip46_address_t local, remote;
12861
12862   ip_address_decode (&mp->local, &local);
12863   ip_address_decode (&mp->remote, &remote);
12864
12865   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
12866          ntohl (mp->sw_if_index),
12867          format_ip46_address, &local, IP46_TYPE_ANY,
12868          format_ip46_address, &remote, IP46_TYPE_ANY,
12869          ntohl (mp->vni), mp->protocol,
12870          ntohl (mp->mcast_sw_if_index),
12871          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
12872 }
12873
12874
12875 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
12876   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12877 {
12878   vat_main_t *vam = &vat_main;
12879   vat_json_node_t *node = NULL;
12880   struct in_addr ip4;
12881   struct in6_addr ip6;
12882   ip46_address_t local, remote;
12883
12884   ip_address_decode (&mp->local, &local);
12885   ip_address_decode (&mp->remote, &remote);
12886
12887   if (VAT_JSON_ARRAY != vam->json_tree.type)
12888     {
12889       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12890       vat_json_init_array (&vam->json_tree);
12891     }
12892   node = vat_json_array_add (&vam->json_tree);
12893
12894   vat_json_init_object (node);
12895   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12896   if (ip46_address_is_ip4 (&local))
12897     {
12898       clib_memcpy (&ip4, &local.ip4, sizeof (ip4));
12899       vat_json_object_add_ip4 (node, "local", ip4);
12900       clib_memcpy (&ip4, &remote.ip4, sizeof (ip4));
12901       vat_json_object_add_ip4 (node, "remote", ip4);
12902     }
12903   else
12904     {
12905       clib_memcpy (&ip6, &local.ip6, sizeof (ip6));
12906       vat_json_object_add_ip6 (node, "local", ip6);
12907       clib_memcpy (&ip6, &remote.ip6, sizeof (ip6));
12908       vat_json_object_add_ip6 (node, "remote", ip6);
12909     }
12910   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12911   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
12912   vat_json_object_add_uint (node, "mcast_sw_if_index",
12913                             ntohl (mp->mcast_sw_if_index));
12914   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12915   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
12916   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12917 }
12918
12919 static int
12920 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
12921 {
12922   unformat_input_t *i = vam->input;
12923   vl_api_vxlan_gpe_tunnel_dump_t *mp;
12924   vl_api_control_ping_t *mp_ping;
12925   u32 sw_if_index;
12926   u8 sw_if_index_set = 0;
12927   int ret;
12928
12929   /* Parse args required to build the message */
12930   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12931     {
12932       if (unformat (i, "sw_if_index %d", &sw_if_index))
12933         sw_if_index_set = 1;
12934       else
12935         break;
12936     }
12937
12938   if (sw_if_index_set == 0)
12939     {
12940       sw_if_index = ~0;
12941     }
12942
12943   if (!vam->json_output)
12944     {
12945       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
12946              "sw_if_index", "local", "remote", "vni",
12947              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
12948     }
12949
12950   /* Get list of vxlan-tunnel interfaces */
12951   M (VXLAN_GPE_TUNNEL_DUMP, mp);
12952
12953   mp->sw_if_index = htonl (sw_if_index);
12954
12955   S (mp);
12956
12957   /* Use a control ping for synchronization */
12958   MPING (CONTROL_PING, mp_ping);
12959   S (mp_ping);
12960
12961   W (ret);
12962   return ret;
12963 }
12964
12965 static void vl_api_l2_fib_table_details_t_handler
12966   (vl_api_l2_fib_table_details_t * mp)
12967 {
12968   vat_main_t *vam = &vat_main;
12969
12970   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
12971          "       %d       %d     %d",
12972          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
12973          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
12974          mp->bvi_mac);
12975 }
12976
12977 static void vl_api_l2_fib_table_details_t_handler_json
12978   (vl_api_l2_fib_table_details_t * mp)
12979 {
12980   vat_main_t *vam = &vat_main;
12981   vat_json_node_t *node = NULL;
12982
12983   if (VAT_JSON_ARRAY != vam->json_tree.type)
12984     {
12985       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12986       vat_json_init_array (&vam->json_tree);
12987     }
12988   node = vat_json_array_add (&vam->json_tree);
12989
12990   vat_json_init_object (node);
12991   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
12992   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
12993   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12994   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
12995   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
12996   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
12997 }
12998
12999 static int
13000 api_l2_fib_table_dump (vat_main_t * vam)
13001 {
13002   unformat_input_t *i = vam->input;
13003   vl_api_l2_fib_table_dump_t *mp;
13004   vl_api_control_ping_t *mp_ping;
13005   u32 bd_id;
13006   u8 bd_id_set = 0;
13007   int ret;
13008
13009   /* Parse args required to build the message */
13010   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13011     {
13012       if (unformat (i, "bd_id %d", &bd_id))
13013         bd_id_set = 1;
13014       else
13015         break;
13016     }
13017
13018   if (bd_id_set == 0)
13019     {
13020       errmsg ("missing bridge domain");
13021       return -99;
13022     }
13023
13024   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13025
13026   /* Get list of l2 fib entries */
13027   M (L2_FIB_TABLE_DUMP, mp);
13028
13029   mp->bd_id = ntohl (bd_id);
13030   S (mp);
13031
13032   /* Use a control ping for synchronization */
13033   MPING (CONTROL_PING, mp_ping);
13034   S (mp_ping);
13035
13036   W (ret);
13037   return ret;
13038 }
13039
13040
13041 static int
13042 api_interface_name_renumber (vat_main_t * vam)
13043 {
13044   unformat_input_t *line_input = vam->input;
13045   vl_api_interface_name_renumber_t *mp;
13046   u32 sw_if_index = ~0;
13047   u32 new_show_dev_instance = ~0;
13048   int ret;
13049
13050   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13051     {
13052       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13053                     &sw_if_index))
13054         ;
13055       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13056         ;
13057       else if (unformat (line_input, "new_show_dev_instance %d",
13058                          &new_show_dev_instance))
13059         ;
13060       else
13061         break;
13062     }
13063
13064   if (sw_if_index == ~0)
13065     {
13066       errmsg ("missing interface name or sw_if_index");
13067       return -99;
13068     }
13069
13070   if (new_show_dev_instance == ~0)
13071     {
13072       errmsg ("missing new_show_dev_instance");
13073       return -99;
13074     }
13075
13076   M (INTERFACE_NAME_RENUMBER, mp);
13077
13078   mp->sw_if_index = ntohl (sw_if_index);
13079   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13080
13081   S (mp);
13082   W (ret);
13083   return ret;
13084 }
13085
13086 static int
13087 api_want_l2_macs_events (vat_main_t * vam)
13088 {
13089   unformat_input_t *line_input = vam->input;
13090   vl_api_want_l2_macs_events_t *mp;
13091   u8 enable_disable = 1;
13092   u32 scan_delay = 0;
13093   u32 max_macs_in_event = 0;
13094   u32 learn_limit = 0;
13095   int ret;
13096
13097   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13098     {
13099       if (unformat (line_input, "learn-limit %d", &learn_limit))
13100         ;
13101       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13102         ;
13103       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13104         ;
13105       else if (unformat (line_input, "disable"))
13106         enable_disable = 0;
13107       else
13108         break;
13109     }
13110
13111   M (WANT_L2_MACS_EVENTS, mp);
13112   mp->enable_disable = enable_disable;
13113   mp->pid = htonl (getpid ());
13114   mp->learn_limit = htonl (learn_limit);
13115   mp->scan_delay = (u8) scan_delay;
13116   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13117   S (mp);
13118   W (ret);
13119   return ret;
13120 }
13121
13122 static int
13123 api_input_acl_set_interface (vat_main_t * vam)
13124 {
13125   unformat_input_t *i = vam->input;
13126   vl_api_input_acl_set_interface_t *mp;
13127   u32 sw_if_index;
13128   int sw_if_index_set;
13129   u32 ip4_table_index = ~0;
13130   u32 ip6_table_index = ~0;
13131   u32 l2_table_index = ~0;
13132   u8 is_add = 1;
13133   int ret;
13134
13135   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13136     {
13137       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13138         sw_if_index_set = 1;
13139       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13140         sw_if_index_set = 1;
13141       else if (unformat (i, "del"))
13142         is_add = 0;
13143       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13144         ;
13145       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13146         ;
13147       else if (unformat (i, "l2-table %d", &l2_table_index))
13148         ;
13149       else
13150         {
13151           clib_warning ("parse error '%U'", format_unformat_error, i);
13152           return -99;
13153         }
13154     }
13155
13156   if (sw_if_index_set == 0)
13157     {
13158       errmsg ("missing interface name or sw_if_index");
13159       return -99;
13160     }
13161
13162   M (INPUT_ACL_SET_INTERFACE, mp);
13163
13164   mp->sw_if_index = ntohl (sw_if_index);
13165   mp->ip4_table_index = ntohl (ip4_table_index);
13166   mp->ip6_table_index = ntohl (ip6_table_index);
13167   mp->l2_table_index = ntohl (l2_table_index);
13168   mp->is_add = is_add;
13169
13170   S (mp);
13171   W (ret);
13172   return ret;
13173 }
13174
13175 static int
13176 api_output_acl_set_interface (vat_main_t * vam)
13177 {
13178   unformat_input_t *i = vam->input;
13179   vl_api_output_acl_set_interface_t *mp;
13180   u32 sw_if_index;
13181   int sw_if_index_set;
13182   u32 ip4_table_index = ~0;
13183   u32 ip6_table_index = ~0;
13184   u32 l2_table_index = ~0;
13185   u8 is_add = 1;
13186   int ret;
13187
13188   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13189     {
13190       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13191         sw_if_index_set = 1;
13192       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13193         sw_if_index_set = 1;
13194       else if (unformat (i, "del"))
13195         is_add = 0;
13196       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13197         ;
13198       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13199         ;
13200       else if (unformat (i, "l2-table %d", &l2_table_index))
13201         ;
13202       else
13203         {
13204           clib_warning ("parse error '%U'", format_unformat_error, i);
13205           return -99;
13206         }
13207     }
13208
13209   if (sw_if_index_set == 0)
13210     {
13211       errmsg ("missing interface name or sw_if_index");
13212       return -99;
13213     }
13214
13215   M (OUTPUT_ACL_SET_INTERFACE, mp);
13216
13217   mp->sw_if_index = ntohl (sw_if_index);
13218   mp->ip4_table_index = ntohl (ip4_table_index);
13219   mp->ip6_table_index = ntohl (ip6_table_index);
13220   mp->l2_table_index = ntohl (l2_table_index);
13221   mp->is_add = is_add;
13222
13223   S (mp);
13224   W (ret);
13225   return ret;
13226 }
13227
13228 static int
13229 api_ip_address_dump (vat_main_t * vam)
13230 {
13231   unformat_input_t *i = vam->input;
13232   vl_api_ip_address_dump_t *mp;
13233   vl_api_control_ping_t *mp_ping;
13234   u32 sw_if_index = ~0;
13235   u8 sw_if_index_set = 0;
13236   u8 ipv4_set = 0;
13237   u8 ipv6_set = 0;
13238   int ret;
13239
13240   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13241     {
13242       if (unformat (i, "sw_if_index %d", &sw_if_index))
13243         sw_if_index_set = 1;
13244       else
13245         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13246         sw_if_index_set = 1;
13247       else if (unformat (i, "ipv4"))
13248         ipv4_set = 1;
13249       else if (unformat (i, "ipv6"))
13250         ipv6_set = 1;
13251       else
13252         break;
13253     }
13254
13255   if (ipv4_set && ipv6_set)
13256     {
13257       errmsg ("ipv4 and ipv6 flags cannot be both set");
13258       return -99;
13259     }
13260
13261   if ((!ipv4_set) && (!ipv6_set))
13262     {
13263       errmsg ("no ipv4 nor ipv6 flag set");
13264       return -99;
13265     }
13266
13267   if (sw_if_index_set == 0)
13268     {
13269       errmsg ("missing interface name or sw_if_index");
13270       return -99;
13271     }
13272
13273   vam->current_sw_if_index = sw_if_index;
13274   vam->is_ipv6 = ipv6_set;
13275
13276   M (IP_ADDRESS_DUMP, mp);
13277   mp->sw_if_index = ntohl (sw_if_index);
13278   mp->is_ipv6 = ipv6_set;
13279   S (mp);
13280
13281   /* Use a control ping for synchronization */
13282   MPING (CONTROL_PING, mp_ping);
13283   S (mp_ping);
13284
13285   W (ret);
13286   return ret;
13287 }
13288
13289 static int
13290 api_ip_dump (vat_main_t * vam)
13291 {
13292   vl_api_ip_dump_t *mp;
13293   vl_api_control_ping_t *mp_ping;
13294   unformat_input_t *in = vam->input;
13295   int ipv4_set = 0;
13296   int ipv6_set = 0;
13297   int is_ipv6;
13298   int i;
13299   int ret;
13300
13301   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13302     {
13303       if (unformat (in, "ipv4"))
13304         ipv4_set = 1;
13305       else if (unformat (in, "ipv6"))
13306         ipv6_set = 1;
13307       else
13308         break;
13309     }
13310
13311   if (ipv4_set && ipv6_set)
13312     {
13313       errmsg ("ipv4 and ipv6 flags cannot be both set");
13314       return -99;
13315     }
13316
13317   if ((!ipv4_set) && (!ipv6_set))
13318     {
13319       errmsg ("no ipv4 nor ipv6 flag set");
13320       return -99;
13321     }
13322
13323   is_ipv6 = ipv6_set;
13324   vam->is_ipv6 = is_ipv6;
13325
13326   /* free old data */
13327   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13328     {
13329       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13330     }
13331   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13332
13333   M (IP_DUMP, mp);
13334   mp->is_ipv6 = ipv6_set;
13335   S (mp);
13336
13337   /* Use a control ping for synchronization */
13338   MPING (CONTROL_PING, mp_ping);
13339   S (mp_ping);
13340
13341   W (ret);
13342   return ret;
13343 }
13344
13345 static int
13346 api_ipsec_spd_add_del (vat_main_t * vam)
13347 {
13348   unformat_input_t *i = vam->input;
13349   vl_api_ipsec_spd_add_del_t *mp;
13350   u32 spd_id = ~0;
13351   u8 is_add = 1;
13352   int ret;
13353
13354   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13355     {
13356       if (unformat (i, "spd_id %d", &spd_id))
13357         ;
13358       else if (unformat (i, "del"))
13359         is_add = 0;
13360       else
13361         {
13362           clib_warning ("parse error '%U'", format_unformat_error, i);
13363           return -99;
13364         }
13365     }
13366   if (spd_id == ~0)
13367     {
13368       errmsg ("spd_id must be set");
13369       return -99;
13370     }
13371
13372   M (IPSEC_SPD_ADD_DEL, mp);
13373
13374   mp->spd_id = ntohl (spd_id);
13375   mp->is_add = is_add;
13376
13377   S (mp);
13378   W (ret);
13379   return ret;
13380 }
13381
13382 static int
13383 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13384 {
13385   unformat_input_t *i = vam->input;
13386   vl_api_ipsec_interface_add_del_spd_t *mp;
13387   u32 sw_if_index;
13388   u8 sw_if_index_set = 0;
13389   u32 spd_id = (u32) ~ 0;
13390   u8 is_add = 1;
13391   int ret;
13392
13393   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13394     {
13395       if (unformat (i, "del"))
13396         is_add = 0;
13397       else if (unformat (i, "spd_id %d", &spd_id))
13398         ;
13399       else
13400         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13401         sw_if_index_set = 1;
13402       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13403         sw_if_index_set = 1;
13404       else
13405         {
13406           clib_warning ("parse error '%U'", format_unformat_error, i);
13407           return -99;
13408         }
13409
13410     }
13411
13412   if (spd_id == (u32) ~ 0)
13413     {
13414       errmsg ("spd_id must be set");
13415       return -99;
13416     }
13417
13418   if (sw_if_index_set == 0)
13419     {
13420       errmsg ("missing interface name or sw_if_index");
13421       return -99;
13422     }
13423
13424   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
13425
13426   mp->spd_id = ntohl (spd_id);
13427   mp->sw_if_index = ntohl (sw_if_index);
13428   mp->is_add = is_add;
13429
13430   S (mp);
13431   W (ret);
13432   return ret;
13433 }
13434
13435 static int
13436 api_ipsec_spd_entry_add_del (vat_main_t * vam)
13437 {
13438   unformat_input_t *i = vam->input;
13439   vl_api_ipsec_spd_entry_add_del_t *mp;
13440   u8 is_add = 1, is_outbound = 0;
13441   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
13442   i32 priority = 0;
13443   u32 rport_start = 0, rport_stop = (u32) ~ 0;
13444   u32 lport_start = 0, lport_stop = (u32) ~ 0;
13445   vl_api_address_t laddr_start = { }, laddr_stop =
13446   {
13447   }, raddr_start =
13448   {
13449   }, raddr_stop =
13450   {
13451   };
13452   int ret;
13453
13454   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13455     {
13456       if (unformat (i, "del"))
13457         is_add = 0;
13458       if (unformat (i, "outbound"))
13459         is_outbound = 1;
13460       if (unformat (i, "inbound"))
13461         is_outbound = 0;
13462       else if (unformat (i, "spd_id %d", &spd_id))
13463         ;
13464       else if (unformat (i, "sa_id %d", &sa_id))
13465         ;
13466       else if (unformat (i, "priority %d", &priority))
13467         ;
13468       else if (unformat (i, "protocol %d", &protocol))
13469         ;
13470       else if (unformat (i, "lport_start %d", &lport_start))
13471         ;
13472       else if (unformat (i, "lport_stop %d", &lport_stop))
13473         ;
13474       else if (unformat (i, "rport_start %d", &rport_start))
13475         ;
13476       else if (unformat (i, "rport_stop %d", &rport_stop))
13477         ;
13478       else if (unformat (i, "laddr_start %U",
13479                          unformat_vl_api_address, &laddr_start))
13480         ;
13481       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
13482                          &laddr_stop))
13483         ;
13484       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
13485                          &raddr_start))
13486         ;
13487       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
13488                          &raddr_stop))
13489         ;
13490       else
13491         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
13492         {
13493           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
13494             {
13495               clib_warning ("unsupported action: 'resolve'");
13496               return -99;
13497             }
13498         }
13499       else
13500         {
13501           clib_warning ("parse error '%U'", format_unformat_error, i);
13502           return -99;
13503         }
13504
13505     }
13506
13507   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
13508
13509   mp->is_add = is_add;
13510
13511   mp->entry.spd_id = ntohl (spd_id);
13512   mp->entry.priority = ntohl (priority);
13513   mp->entry.is_outbound = is_outbound;
13514
13515   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
13516                sizeof (vl_api_address_t));
13517   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
13518                sizeof (vl_api_address_t));
13519   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
13520                sizeof (vl_api_address_t));
13521   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
13522                sizeof (vl_api_address_t));
13523
13524   mp->entry.protocol = (u8) protocol;
13525   mp->entry.local_port_start = ntohs ((u16) lport_start);
13526   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
13527   mp->entry.remote_port_start = ntohs ((u16) rport_start);
13528   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
13529   mp->entry.policy = (u8) policy;
13530   mp->entry.sa_id = ntohl (sa_id);
13531
13532   S (mp);
13533   W (ret);
13534   return ret;
13535 }
13536
13537 static int
13538 api_ipsec_sad_entry_add_del (vat_main_t * vam)
13539 {
13540   unformat_input_t *i = vam->input;
13541   vl_api_ipsec_sad_entry_add_del_t *mp;
13542   u32 sad_id = 0, spi = 0;
13543   u8 *ck = 0, *ik = 0;
13544   u8 is_add = 1;
13545
13546   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
13547   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
13548   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
13549   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
13550   vl_api_address_t tun_src, tun_dst;
13551   int ret;
13552
13553   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13554     {
13555       if (unformat (i, "del"))
13556         is_add = 0;
13557       else if (unformat (i, "sad_id %d", &sad_id))
13558         ;
13559       else if (unformat (i, "spi %d", &spi))
13560         ;
13561       else if (unformat (i, "esp"))
13562         protocol = IPSEC_API_PROTO_ESP;
13563       else
13564         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
13565         {
13566           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13567           if (ADDRESS_IP6 == tun_src.af)
13568             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13569         }
13570       else
13571         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
13572         {
13573           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13574           if (ADDRESS_IP6 == tun_src.af)
13575             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13576         }
13577       else
13578         if (unformat (i, "crypto_alg %U",
13579                       unformat_ipsec_api_crypto_alg, &crypto_alg))
13580         ;
13581       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13582         ;
13583       else if (unformat (i, "integ_alg %U",
13584                          unformat_ipsec_api_integ_alg, &integ_alg))
13585         ;
13586       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13587         ;
13588       else
13589         {
13590           clib_warning ("parse error '%U'", format_unformat_error, i);
13591           return -99;
13592         }
13593
13594     }
13595
13596   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
13597
13598   mp->is_add = is_add;
13599   mp->entry.sad_id = ntohl (sad_id);
13600   mp->entry.protocol = protocol;
13601   mp->entry.spi = ntohl (spi);
13602   mp->entry.flags = flags;
13603
13604   mp->entry.crypto_algorithm = crypto_alg;
13605   mp->entry.integrity_algorithm = integ_alg;
13606   mp->entry.crypto_key.length = vec_len (ck);
13607   mp->entry.integrity_key.length = vec_len (ik);
13608
13609   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
13610     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
13611
13612   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
13613     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
13614
13615   if (ck)
13616     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
13617   if (ik)
13618     clib_memcpy (mp->entry.integrity_key.data, ik,
13619                  mp->entry.integrity_key.length);
13620
13621   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
13622     {
13623       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
13624                    sizeof (mp->entry.tunnel_src));
13625       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
13626                    sizeof (mp->entry.tunnel_dst));
13627     }
13628
13629   S (mp);
13630   W (ret);
13631   return ret;
13632 }
13633
13634 static int
13635 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
13636 {
13637   unformat_input_t *i = vam->input;
13638   vl_api_ipsec_tunnel_if_add_del_t *mp;
13639   u32 local_spi = 0, remote_spi = 0;
13640   u32 crypto_alg = 0, integ_alg = 0;
13641   u8 *lck = NULL, *rck = NULL;
13642   u8 *lik = NULL, *rik = NULL;
13643   vl_api_address_t local_ip = { 0 };
13644   vl_api_address_t remote_ip = { 0 };
13645   f64 before = 0;
13646   u8 is_add = 1;
13647   u8 esn = 0;
13648   u8 anti_replay = 0;
13649   u8 renumber = 0;
13650   u32 instance = ~0;
13651   u32 count = 1, jj;
13652   int ret = -1;
13653
13654   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13655     {
13656       if (unformat (i, "del"))
13657         is_add = 0;
13658       else if (unformat (i, "esn"))
13659         esn = 1;
13660       else if (unformat (i, "anti-replay"))
13661         anti_replay = 1;
13662       else if (unformat (i, "count %d", &count))
13663         ;
13664       else if (unformat (i, "local_spi %d", &local_spi))
13665         ;
13666       else if (unformat (i, "remote_spi %d", &remote_spi))
13667         ;
13668       else
13669         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
13670         ;
13671       else
13672         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
13673         ;
13674       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
13675         ;
13676       else
13677         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
13678         ;
13679       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
13680         ;
13681       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
13682         ;
13683       else
13684         if (unformat
13685             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
13686         {
13687           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
13688             {
13689               errmsg ("unsupported crypto-alg: '%U'\n",
13690                       format_ipsec_crypto_alg, crypto_alg);
13691               return -99;
13692             }
13693         }
13694       else
13695         if (unformat
13696             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
13697         {
13698           if (integ_alg >= IPSEC_INTEG_N_ALG)
13699             {
13700               errmsg ("unsupported integ-alg: '%U'\n",
13701                       format_ipsec_integ_alg, integ_alg);
13702               return -99;
13703             }
13704         }
13705       else if (unformat (i, "instance %u", &instance))
13706         renumber = 1;
13707       else
13708         {
13709           errmsg ("parse error '%U'\n", format_unformat_error, i);
13710           return -99;
13711         }
13712     }
13713
13714   if (count > 1)
13715     {
13716       /* Turn on async mode */
13717       vam->async_mode = 1;
13718       vam->async_errors = 0;
13719       before = vat_time_now (vam);
13720     }
13721
13722   for (jj = 0; jj < count; jj++)
13723     {
13724       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
13725
13726       mp->is_add = is_add;
13727       mp->esn = esn;
13728       mp->anti_replay = anti_replay;
13729
13730       if (jj > 0)
13731         increment_address (&remote_ip);
13732
13733       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
13734       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
13735
13736       mp->local_spi = htonl (local_spi + jj);
13737       mp->remote_spi = htonl (remote_spi + jj);
13738       mp->crypto_alg = (u8) crypto_alg;
13739
13740       mp->local_crypto_key_len = 0;
13741       if (lck)
13742         {
13743           mp->local_crypto_key_len = vec_len (lck);
13744           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
13745             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
13746           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
13747         }
13748
13749       mp->remote_crypto_key_len = 0;
13750       if (rck)
13751         {
13752           mp->remote_crypto_key_len = vec_len (rck);
13753           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
13754             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
13755           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
13756         }
13757
13758       mp->integ_alg = (u8) integ_alg;
13759
13760       mp->local_integ_key_len = 0;
13761       if (lik)
13762         {
13763           mp->local_integ_key_len = vec_len (lik);
13764           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
13765             mp->local_integ_key_len = sizeof (mp->local_integ_key);
13766           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
13767         }
13768
13769       mp->remote_integ_key_len = 0;
13770       if (rik)
13771         {
13772           mp->remote_integ_key_len = vec_len (rik);
13773           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
13774             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
13775           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
13776         }
13777
13778       if (renumber)
13779         {
13780           mp->renumber = renumber;
13781           mp->show_instance = ntohl (instance);
13782         }
13783       S (mp);
13784     }
13785
13786   /* When testing multiple add/del ops, use a control-ping to sync */
13787   if (count > 1)
13788     {
13789       vl_api_control_ping_t *mp_ping;
13790       f64 after;
13791       f64 timeout;
13792
13793       /* Shut off async mode */
13794       vam->async_mode = 0;
13795
13796       MPING (CONTROL_PING, mp_ping);
13797       S (mp_ping);
13798
13799       timeout = vat_time_now (vam) + 1.0;
13800       while (vat_time_now (vam) < timeout)
13801         if (vam->result_ready == 1)
13802           goto out;
13803       vam->retval = -99;
13804
13805     out:
13806       if (vam->retval == -99)
13807         errmsg ("timeout");
13808
13809       if (vam->async_errors > 0)
13810         {
13811           errmsg ("%d asynchronous errors", vam->async_errors);
13812           vam->retval = -98;
13813         }
13814       vam->async_errors = 0;
13815       after = vat_time_now (vam);
13816
13817       /* slim chance, but we might have eaten SIGTERM on the first iteration */
13818       if (jj > 0)
13819         count = jj;
13820
13821       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
13822              count, after - before, count / (after - before));
13823     }
13824   else
13825     {
13826       /* Wait for a reply... */
13827       W (ret);
13828       return ret;
13829     }
13830
13831   return ret;
13832 }
13833
13834 static void
13835 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
13836 {
13837   vat_main_t *vam = &vat_main;
13838
13839   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
13840          "crypto_key %U integ_alg %u integ_key %U flags %x "
13841          "tunnel_src_addr %U tunnel_dst_addr %U "
13842          "salt %u seq_outbound %lu last_seq_inbound %lu "
13843          "replay_window %lu stat_index %u\n",
13844          ntohl (mp->entry.sad_id),
13845          ntohl (mp->sw_if_index),
13846          ntohl (mp->entry.spi),
13847          ntohl (mp->entry.protocol),
13848          ntohl (mp->entry.crypto_algorithm),
13849          format_hex_bytes, mp->entry.crypto_key.data,
13850          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
13851          format_hex_bytes, mp->entry.integrity_key.data,
13852          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
13853          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
13854          &mp->entry.tunnel_dst, ntohl (mp->salt),
13855          clib_net_to_host_u64 (mp->seq_outbound),
13856          clib_net_to_host_u64 (mp->last_seq_inbound),
13857          clib_net_to_host_u64 (mp->replay_window), ntohl (mp->stat_index));
13858 }
13859
13860 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
13861 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
13862
13863 static void vl_api_ipsec_sa_details_t_handler_json
13864   (vl_api_ipsec_sa_details_t * mp)
13865 {
13866   vat_main_t *vam = &vat_main;
13867   vat_json_node_t *node = NULL;
13868   vl_api_ipsec_sad_flags_t flags;
13869
13870   if (VAT_JSON_ARRAY != vam->json_tree.type)
13871     {
13872       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13873       vat_json_init_array (&vam->json_tree);
13874     }
13875   node = vat_json_array_add (&vam->json_tree);
13876
13877   vat_json_init_object (node);
13878   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
13879   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13880   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
13881   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
13882   vat_json_object_add_uint (node, "crypto_alg",
13883                             ntohl (mp->entry.crypto_algorithm));
13884   vat_json_object_add_uint (node, "integ_alg",
13885                             ntohl (mp->entry.integrity_algorithm));
13886   flags = ntohl (mp->entry.flags);
13887   vat_json_object_add_uint (node, "use_esn",
13888                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
13889   vat_json_object_add_uint (node, "use_anti_replay",
13890                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
13891   vat_json_object_add_uint (node, "is_tunnel",
13892                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
13893   vat_json_object_add_uint (node, "is_tunnel_ip6",
13894                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
13895   vat_json_object_add_uint (node, "udp_encap",
13896                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
13897   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
13898                              mp->entry.crypto_key.length);
13899   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
13900                              mp->entry.integrity_key.length);
13901   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
13902   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
13903   vat_json_object_add_uint (node, "replay_window",
13904                             clib_net_to_host_u64 (mp->replay_window));
13905   vat_json_object_add_uint (node, "stat_index", ntohl (mp->stat_index));
13906 }
13907
13908 static int
13909 api_ipsec_sa_dump (vat_main_t * vam)
13910 {
13911   unformat_input_t *i = vam->input;
13912   vl_api_ipsec_sa_dump_t *mp;
13913   vl_api_control_ping_t *mp_ping;
13914   u32 sa_id = ~0;
13915   int ret;
13916
13917   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13918     {
13919       if (unformat (i, "sa_id %d", &sa_id))
13920         ;
13921       else
13922         {
13923           clib_warning ("parse error '%U'", format_unformat_error, i);
13924           return -99;
13925         }
13926     }
13927
13928   M (IPSEC_SA_DUMP, mp);
13929
13930   mp->sa_id = ntohl (sa_id);
13931
13932   S (mp);
13933
13934   /* Use a control ping for synchronization */
13935   M (CONTROL_PING, mp_ping);
13936   S (mp_ping);
13937
13938   W (ret);
13939   return ret;
13940 }
13941
13942 static int
13943 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
13944 {
13945   unformat_input_t *i = vam->input;
13946   vl_api_ipsec_tunnel_if_set_sa_t *mp;
13947   u32 sw_if_index = ~0;
13948   u32 sa_id = ~0;
13949   u8 is_outbound = (u8) ~ 0;
13950   int ret;
13951
13952   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13953     {
13954       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13955         ;
13956       else if (unformat (i, "sa_id %d", &sa_id))
13957         ;
13958       else if (unformat (i, "outbound"))
13959         is_outbound = 1;
13960       else if (unformat (i, "inbound"))
13961         is_outbound = 0;
13962       else
13963         {
13964           clib_warning ("parse error '%U'", format_unformat_error, i);
13965           return -99;
13966         }
13967     }
13968
13969   if (sw_if_index == ~0)
13970     {
13971       errmsg ("interface must be specified");
13972       return -99;
13973     }
13974
13975   if (sa_id == ~0)
13976     {
13977       errmsg ("SA ID must be specified");
13978       return -99;
13979     }
13980
13981   M (IPSEC_TUNNEL_IF_SET_SA, mp);
13982
13983   mp->sw_if_index = htonl (sw_if_index);
13984   mp->sa_id = htonl (sa_id);
13985   mp->is_outbound = is_outbound;
13986
13987   S (mp);
13988   W (ret);
13989
13990   return ret;
13991 }
13992
13993 static int
13994 api_get_first_msg_id (vat_main_t * vam)
13995 {
13996   vl_api_get_first_msg_id_t *mp;
13997   unformat_input_t *i = vam->input;
13998   u8 *name;
13999   u8 name_set = 0;
14000   int ret;
14001
14002   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14003     {
14004       if (unformat (i, "client %s", &name))
14005         name_set = 1;
14006       else
14007         break;
14008     }
14009
14010   if (name_set == 0)
14011     {
14012       errmsg ("missing client name");
14013       return -99;
14014     }
14015   vec_add1 (name, 0);
14016
14017   if (vec_len (name) > 63)
14018     {
14019       errmsg ("client name too long");
14020       return -99;
14021     }
14022
14023   M (GET_FIRST_MSG_ID, mp);
14024   clib_memcpy (mp->name, name, vec_len (name));
14025   S (mp);
14026   W (ret);
14027   return ret;
14028 }
14029
14030 static int
14031 api_cop_interface_enable_disable (vat_main_t * vam)
14032 {
14033   unformat_input_t *line_input = vam->input;
14034   vl_api_cop_interface_enable_disable_t *mp;
14035   u32 sw_if_index = ~0;
14036   u8 enable_disable = 1;
14037   int ret;
14038
14039   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14040     {
14041       if (unformat (line_input, "disable"))
14042         enable_disable = 0;
14043       if (unformat (line_input, "enable"))
14044         enable_disable = 1;
14045       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14046                          vam, &sw_if_index))
14047         ;
14048       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14049         ;
14050       else
14051         break;
14052     }
14053
14054   if (sw_if_index == ~0)
14055     {
14056       errmsg ("missing interface name or sw_if_index");
14057       return -99;
14058     }
14059
14060   /* Construct the API message */
14061   M (COP_INTERFACE_ENABLE_DISABLE, mp);
14062   mp->sw_if_index = ntohl (sw_if_index);
14063   mp->enable_disable = enable_disable;
14064
14065   /* send it... */
14066   S (mp);
14067   /* Wait for the reply */
14068   W (ret);
14069   return ret;
14070 }
14071
14072 static int
14073 api_cop_whitelist_enable_disable (vat_main_t * vam)
14074 {
14075   unformat_input_t *line_input = vam->input;
14076   vl_api_cop_whitelist_enable_disable_t *mp;
14077   u32 sw_if_index = ~0;
14078   u8 ip4 = 0, ip6 = 0, default_cop = 0;
14079   u32 fib_id = 0;
14080   int ret;
14081
14082   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14083     {
14084       if (unformat (line_input, "ip4"))
14085         ip4 = 1;
14086       else if (unformat (line_input, "ip6"))
14087         ip6 = 1;
14088       else if (unformat (line_input, "default"))
14089         default_cop = 1;
14090       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14091                          vam, &sw_if_index))
14092         ;
14093       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14094         ;
14095       else if (unformat (line_input, "fib-id %d", &fib_id))
14096         ;
14097       else
14098         break;
14099     }
14100
14101   if (sw_if_index == ~0)
14102     {
14103       errmsg ("missing interface name or sw_if_index");
14104       return -99;
14105     }
14106
14107   /* Construct the API message */
14108   M (COP_WHITELIST_ENABLE_DISABLE, mp);
14109   mp->sw_if_index = ntohl (sw_if_index);
14110   mp->fib_id = ntohl (fib_id);
14111   mp->ip4 = ip4;
14112   mp->ip6 = ip6;
14113   mp->default_cop = default_cop;
14114
14115   /* send it... */
14116   S (mp);
14117   /* Wait for the reply */
14118   W (ret);
14119   return ret;
14120 }
14121
14122 static int
14123 api_get_node_graph (vat_main_t * vam)
14124 {
14125   vl_api_get_node_graph_t *mp;
14126   int ret;
14127
14128   M (GET_NODE_GRAPH, mp);
14129
14130   /* send it... */
14131   S (mp);
14132   /* Wait for the reply */
14133   W (ret);
14134   return ret;
14135 }
14136
14137 /* *INDENT-OFF* */
14138 /** Used for parsing LISP eids */
14139 typedef CLIB_PACKED(struct{
14140   union {
14141           ip46_address_t ip;
14142           mac_address_t mac;
14143           lisp_nsh_api_t nsh;
14144   } addr;
14145   u32 len;       /**< prefix length if IP */
14146   u8 type;      /**< type of eid */
14147 }) lisp_eid_vat_t;
14148 /* *INDENT-ON* */
14149
14150 static uword
14151 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
14152 {
14153   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
14154
14155   clib_memset (a, 0, sizeof (a[0]));
14156
14157   if (unformat (input, "%U/%d", unformat_ip46_address, a->addr.ip, &a->len))
14158     {
14159       a->type = 0;              /* ip prefix type */
14160     }
14161   else if (unformat (input, "%U", unformat_ethernet_address, a->addr.mac))
14162     {
14163       a->type = 1;              /* mac type */
14164     }
14165   else if (unformat (input, "%U", unformat_nsh_address, a->addr.nsh))
14166     {
14167       a->type = 2;              /* NSH type */
14168       a->addr.nsh.spi = clib_host_to_net_u32 (a->addr.nsh.spi);
14169     }
14170   else
14171     {
14172       return 0;
14173     }
14174
14175   if (a->type == 0)
14176     {
14177       if (ip46_address_is_ip4 (&a->addr.ip))
14178         return a->len > 32 ? 1 : 0;
14179       else
14180         return a->len > 128 ? 1 : 0;
14181     }
14182
14183   return 1;
14184 }
14185
14186 static void
14187 lisp_eid_put_vat (vl_api_eid_t * eid, const lisp_eid_vat_t * vat_eid)
14188 {
14189   eid->type = vat_eid->type;
14190   switch (eid->type)
14191     {
14192     case EID_TYPE_API_PREFIX:
14193       if (ip46_address_is_ip4 (&vat_eid->addr.ip))
14194         {
14195           clib_memcpy (&eid->address.prefix.address.un.ip4,
14196                        &vat_eid->addr.ip.ip4, 4);
14197           eid->address.prefix.address.af = ADDRESS_IP4;
14198           eid->address.prefix.len = vat_eid->len;
14199         }
14200       else
14201         {
14202           clib_memcpy (&eid->address.prefix.address.un.ip6,
14203                        &vat_eid->addr.ip.ip6, 16);
14204           eid->address.prefix.address.af = ADDRESS_IP6;
14205           eid->address.prefix.len = vat_eid->len;
14206         }
14207       return;
14208     case EID_TYPE_API_MAC:
14209       clib_memcpy (&eid->address.mac, &vat_eid->addr.mac,
14210                    sizeof (eid->address.mac));
14211       return;
14212     case EID_TYPE_API_NSH:
14213       clib_memcpy (&eid->address.nsh, &vat_eid->addr.nsh,
14214                    sizeof (eid->address.nsh));
14215       return;
14216     default:
14217       ASSERT (0);
14218       return;
14219     }
14220 }
14221
14222 static int
14223 api_one_add_del_locator_set (vat_main_t * vam)
14224 {
14225   unformat_input_t *input = vam->input;
14226   vl_api_one_add_del_locator_set_t *mp;
14227   u8 is_add = 1;
14228   u8 *locator_set_name = NULL;
14229   u8 locator_set_name_set = 0;
14230   vl_api_local_locator_t locator, *locators = 0;
14231   u32 sw_if_index, priority, weight;
14232   u32 data_len = 0;
14233
14234   int ret;
14235   /* Parse args required to build the message */
14236   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14237     {
14238       if (unformat (input, "del"))
14239         {
14240           is_add = 0;
14241         }
14242       else if (unformat (input, "locator-set %s", &locator_set_name))
14243         {
14244           locator_set_name_set = 1;
14245         }
14246       else if (unformat (input, "sw_if_index %u p %u w %u",
14247                          &sw_if_index, &priority, &weight))
14248         {
14249           locator.sw_if_index = htonl (sw_if_index);
14250           locator.priority = priority;
14251           locator.weight = weight;
14252           vec_add1 (locators, locator);
14253         }
14254       else
14255         if (unformat
14256             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14257              &sw_if_index, &priority, &weight))
14258         {
14259           locator.sw_if_index = htonl (sw_if_index);
14260           locator.priority = priority;
14261           locator.weight = weight;
14262           vec_add1 (locators, locator);
14263         }
14264       else
14265         break;
14266     }
14267
14268   if (locator_set_name_set == 0)
14269     {
14270       errmsg ("missing locator-set name");
14271       vec_free (locators);
14272       return -99;
14273     }
14274
14275   if (vec_len (locator_set_name) > 64)
14276     {
14277       errmsg ("locator-set name too long");
14278       vec_free (locator_set_name);
14279       vec_free (locators);
14280       return -99;
14281     }
14282   vec_add1 (locator_set_name, 0);
14283
14284   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14285
14286   /* Construct the API message */
14287   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14288
14289   mp->is_add = is_add;
14290   clib_memcpy (mp->locator_set_name, locator_set_name,
14291                vec_len (locator_set_name));
14292   vec_free (locator_set_name);
14293
14294   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14295   if (locators)
14296     clib_memcpy (mp->locators, locators, data_len);
14297   vec_free (locators);
14298
14299   /* send it... */
14300   S (mp);
14301
14302   /* Wait for a reply... */
14303   W (ret);
14304   return ret;
14305 }
14306
14307 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14308
14309 static int
14310 api_one_add_del_locator (vat_main_t * vam)
14311 {
14312   unformat_input_t *input = vam->input;
14313   vl_api_one_add_del_locator_t *mp;
14314   u32 tmp_if_index = ~0;
14315   u32 sw_if_index = ~0;
14316   u8 sw_if_index_set = 0;
14317   u8 sw_if_index_if_name_set = 0;
14318   u32 priority = ~0;
14319   u8 priority_set = 0;
14320   u32 weight = ~0;
14321   u8 weight_set = 0;
14322   u8 is_add = 1;
14323   u8 *locator_set_name = NULL;
14324   u8 locator_set_name_set = 0;
14325   int ret;
14326
14327   /* Parse args required to build the message */
14328   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14329     {
14330       if (unformat (input, "del"))
14331         {
14332           is_add = 0;
14333         }
14334       else if (unformat (input, "locator-set %s", &locator_set_name))
14335         {
14336           locator_set_name_set = 1;
14337         }
14338       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14339                          &tmp_if_index))
14340         {
14341           sw_if_index_if_name_set = 1;
14342           sw_if_index = tmp_if_index;
14343         }
14344       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14345         {
14346           sw_if_index_set = 1;
14347           sw_if_index = tmp_if_index;
14348         }
14349       else if (unformat (input, "p %d", &priority))
14350         {
14351           priority_set = 1;
14352         }
14353       else if (unformat (input, "w %d", &weight))
14354         {
14355           weight_set = 1;
14356         }
14357       else
14358         break;
14359     }
14360
14361   if (locator_set_name_set == 0)
14362     {
14363       errmsg ("missing locator-set name");
14364       return -99;
14365     }
14366
14367   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14368     {
14369       errmsg ("missing sw_if_index");
14370       vec_free (locator_set_name);
14371       return -99;
14372     }
14373
14374   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14375     {
14376       errmsg ("cannot use both params interface name and sw_if_index");
14377       vec_free (locator_set_name);
14378       return -99;
14379     }
14380
14381   if (priority_set == 0)
14382     {
14383       errmsg ("missing locator-set priority");
14384       vec_free (locator_set_name);
14385       return -99;
14386     }
14387
14388   if (weight_set == 0)
14389     {
14390       errmsg ("missing locator-set weight");
14391       vec_free (locator_set_name);
14392       return -99;
14393     }
14394
14395   if (vec_len (locator_set_name) > 64)
14396     {
14397       errmsg ("locator-set name too long");
14398       vec_free (locator_set_name);
14399       return -99;
14400     }
14401   vec_add1 (locator_set_name, 0);
14402
14403   /* Construct the API message */
14404   M (ONE_ADD_DEL_LOCATOR, mp);
14405
14406   mp->is_add = is_add;
14407   mp->sw_if_index = ntohl (sw_if_index);
14408   mp->priority = priority;
14409   mp->weight = weight;
14410   clib_memcpy (mp->locator_set_name, locator_set_name,
14411                vec_len (locator_set_name));
14412   vec_free (locator_set_name);
14413
14414   /* send it... */
14415   S (mp);
14416
14417   /* Wait for a reply... */
14418   W (ret);
14419   return ret;
14420 }
14421
14422 #define api_lisp_add_del_locator api_one_add_del_locator
14423
14424 uword
14425 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
14426 {
14427   u32 *key_id = va_arg (*args, u32 *);
14428   u8 *s = 0;
14429
14430   if (unformat (input, "%s", &s))
14431     {
14432       if (!strcmp ((char *) s, "sha1"))
14433         key_id[0] = HMAC_SHA_1_96;
14434       else if (!strcmp ((char *) s, "sha256"))
14435         key_id[0] = HMAC_SHA_256_128;
14436       else
14437         {
14438           clib_warning ("invalid key_id: '%s'", s);
14439           key_id[0] = HMAC_NO_KEY;
14440         }
14441     }
14442   else
14443     return 0;
14444
14445   vec_free (s);
14446   return 1;
14447 }
14448
14449 static int
14450 api_one_add_del_local_eid (vat_main_t * vam)
14451 {
14452   unformat_input_t *input = vam->input;
14453   vl_api_one_add_del_local_eid_t *mp;
14454   u8 is_add = 1;
14455   u8 eid_set = 0;
14456   lisp_eid_vat_t _eid, *eid = &_eid;
14457   u8 *locator_set_name = 0;
14458   u8 locator_set_name_set = 0;
14459   u32 vni = 0;
14460   u16 key_id = 0;
14461   u8 *key = 0;
14462   int ret;
14463
14464   /* Parse args required to build the message */
14465   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14466     {
14467       if (unformat (input, "del"))
14468         {
14469           is_add = 0;
14470         }
14471       else if (unformat (input, "vni %d", &vni))
14472         {
14473           ;
14474         }
14475       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14476         {
14477           eid_set = 1;
14478         }
14479       else if (unformat (input, "locator-set %s", &locator_set_name))
14480         {
14481           locator_set_name_set = 1;
14482         }
14483       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
14484         ;
14485       else if (unformat (input, "secret-key %_%v%_", &key))
14486         ;
14487       else
14488         break;
14489     }
14490
14491   if (locator_set_name_set == 0)
14492     {
14493       errmsg ("missing locator-set name");
14494       return -99;
14495     }
14496
14497   if (0 == eid_set)
14498     {
14499       errmsg ("EID address not set!");
14500       vec_free (locator_set_name);
14501       return -99;
14502     }
14503
14504   if (key && (0 == key_id))
14505     {
14506       errmsg ("invalid key_id!");
14507       return -99;
14508     }
14509
14510   if (vec_len (key) > 64)
14511     {
14512       errmsg ("key too long");
14513       vec_free (key);
14514       return -99;
14515     }
14516
14517   if (vec_len (locator_set_name) > 64)
14518     {
14519       errmsg ("locator-set name too long");
14520       vec_free (locator_set_name);
14521       return -99;
14522     }
14523   vec_add1 (locator_set_name, 0);
14524
14525   /* Construct the API message */
14526   M (ONE_ADD_DEL_LOCAL_EID, mp);
14527
14528   mp->is_add = is_add;
14529   lisp_eid_put_vat (&mp->eid, eid);
14530   mp->vni = clib_host_to_net_u32 (vni);
14531   mp->key.id = key_id;
14532   clib_memcpy (mp->locator_set_name, locator_set_name,
14533                vec_len (locator_set_name));
14534   clib_memcpy (mp->key.key, key, vec_len (key));
14535
14536   vec_free (locator_set_name);
14537   vec_free (key);
14538
14539   /* send it... */
14540   S (mp);
14541
14542   /* Wait for a reply... */
14543   W (ret);
14544   return ret;
14545 }
14546
14547 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
14548
14549 static int
14550 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
14551 {
14552   u32 dp_table = 0, vni = 0;;
14553   unformat_input_t *input = vam->input;
14554   vl_api_gpe_add_del_fwd_entry_t *mp;
14555   u8 is_add = 1;
14556   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
14557   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
14558   u8 rmt_eid_set = 0, lcl_eid_set = 0;
14559   u32 action = ~0, w;
14560   ip4_address_t rmt_rloc4, lcl_rloc4;
14561   ip6_address_t rmt_rloc6, lcl_rloc6;
14562   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
14563   int ret;
14564
14565   clib_memset (&rloc, 0, sizeof (rloc));
14566
14567   /* Parse args required to build the message */
14568   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14569     {
14570       if (unformat (input, "del"))
14571         is_add = 0;
14572       else if (unformat (input, "add"))
14573         is_add = 1;
14574       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
14575         {
14576           rmt_eid_set = 1;
14577         }
14578       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
14579         {
14580           lcl_eid_set = 1;
14581         }
14582       else if (unformat (input, "vrf %d", &dp_table))
14583         ;
14584       else if (unformat (input, "bd %d", &dp_table))
14585         ;
14586       else if (unformat (input, "vni %d", &vni))
14587         ;
14588       else if (unformat (input, "w %d", &w))
14589         {
14590           if (!curr_rloc)
14591             {
14592               errmsg ("No RLOC configured for setting priority/weight!");
14593               return -99;
14594             }
14595           curr_rloc->weight = w;
14596         }
14597       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14598                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14599         {
14600           rloc.addr.af = 0;
14601           clib_memcpy (&rloc.addr.un.ip4, &lcl_rloc4, sizeof (lcl_rloc4));
14602           rloc.weight = 0;
14603           vec_add1 (lcl_locs, rloc);
14604
14605           clib_memcpy (&rloc.addr.un.ip4, &rmt_rloc4, sizeof (rmt_rloc4));
14606           vec_add1 (rmt_locs, rloc);
14607           /* weight saved in rmt loc */
14608           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14609         }
14610       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14611                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14612         {
14613           rloc.addr.af = 1;
14614           clib_memcpy (&rloc.addr.un.ip6, &lcl_rloc6, sizeof (lcl_rloc6));
14615           rloc.weight = 0;
14616           vec_add1 (lcl_locs, rloc);
14617
14618           clib_memcpy (&rloc.addr.un.ip6, &rmt_rloc6, sizeof (rmt_rloc6));
14619           vec_add1 (rmt_locs, rloc);
14620           /* weight saved in rmt loc */
14621           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14622         }
14623       else if (unformat (input, "action %d", &action))
14624         {
14625           ;
14626         }
14627       else
14628         {
14629           clib_warning ("parse error '%U'", format_unformat_error, input);
14630           return -99;
14631         }
14632     }
14633
14634   if (!rmt_eid_set)
14635     {
14636       errmsg ("remote eid addresses not set");
14637       return -99;
14638     }
14639
14640   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14641     {
14642       errmsg ("eid types don't match");
14643       return -99;
14644     }
14645
14646   if (0 == rmt_locs && (u32) ~ 0 == action)
14647     {
14648       errmsg ("action not set for negative mapping");
14649       return -99;
14650     }
14651
14652   /* Construct the API message */
14653   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14654       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
14655
14656   mp->is_add = is_add;
14657   lisp_eid_put_vat (&mp->rmt_eid, rmt_eid);
14658   lisp_eid_put_vat (&mp->lcl_eid, lcl_eid);
14659   mp->dp_table = clib_host_to_net_u32 (dp_table);
14660   mp->vni = clib_host_to_net_u32 (vni);
14661   mp->action = action;
14662
14663   if (0 != rmt_locs && 0 != lcl_locs)
14664     {
14665       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14666       clib_memcpy (mp->locs, lcl_locs,
14667                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
14668
14669       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14670       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14671                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
14672     }
14673   vec_free (lcl_locs);
14674   vec_free (rmt_locs);
14675
14676   /* send it... */
14677   S (mp);
14678
14679   /* Wait for a reply... */
14680   W (ret);
14681   return ret;
14682 }
14683
14684 static int
14685 api_one_add_del_map_server (vat_main_t * vam)
14686 {
14687   unformat_input_t *input = vam->input;
14688   vl_api_one_add_del_map_server_t *mp;
14689   u8 is_add = 1;
14690   u8 ipv4_set = 0;
14691   u8 ipv6_set = 0;
14692   ip4_address_t ipv4;
14693   ip6_address_t ipv6;
14694   int ret;
14695
14696   /* Parse args required to build the message */
14697   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14698     {
14699       if (unformat (input, "del"))
14700         {
14701           is_add = 0;
14702         }
14703       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14704         {
14705           ipv4_set = 1;
14706         }
14707       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14708         {
14709           ipv6_set = 1;
14710         }
14711       else
14712         break;
14713     }
14714
14715   if (ipv4_set && ipv6_set)
14716     {
14717       errmsg ("both eid v4 and v6 addresses set");
14718       return -99;
14719     }
14720
14721   if (!ipv4_set && !ipv6_set)
14722     {
14723       errmsg ("eid addresses not set");
14724       return -99;
14725     }
14726
14727   /* Construct the API message */
14728   M (ONE_ADD_DEL_MAP_SERVER, mp);
14729
14730   mp->is_add = is_add;
14731   if (ipv6_set)
14732     {
14733       mp->ip_address.af = 1;
14734       clib_memcpy (mp->ip_address.un.ip6, &ipv6, sizeof (ipv6));
14735     }
14736   else
14737     {
14738       mp->ip_address.af = 0;
14739       clib_memcpy (mp->ip_address.un.ip4, &ipv4, sizeof (ipv4));
14740     }
14741
14742   /* send it... */
14743   S (mp);
14744
14745   /* Wait for a reply... */
14746   W (ret);
14747   return ret;
14748 }
14749
14750 #define api_lisp_add_del_map_server api_one_add_del_map_server
14751
14752 static int
14753 api_one_add_del_map_resolver (vat_main_t * vam)
14754 {
14755   unformat_input_t *input = vam->input;
14756   vl_api_one_add_del_map_resolver_t *mp;
14757   u8 is_add = 1;
14758   u8 ipv4_set = 0;
14759   u8 ipv6_set = 0;
14760   ip4_address_t ipv4;
14761   ip6_address_t ipv6;
14762   int ret;
14763
14764   /* Parse args required to build the message */
14765   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14766     {
14767       if (unformat (input, "del"))
14768         {
14769           is_add = 0;
14770         }
14771       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14772         {
14773           ipv4_set = 1;
14774         }
14775       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14776         {
14777           ipv6_set = 1;
14778         }
14779       else
14780         break;
14781     }
14782
14783   if (ipv4_set && ipv6_set)
14784     {
14785       errmsg ("both eid v4 and v6 addresses set");
14786       return -99;
14787     }
14788
14789   if (!ipv4_set && !ipv6_set)
14790     {
14791       errmsg ("eid addresses not set");
14792       return -99;
14793     }
14794
14795   /* Construct the API message */
14796   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
14797
14798   mp->is_add = is_add;
14799   if (ipv6_set)
14800     {
14801       mp->ip_address.af = 1;
14802       clib_memcpy (mp->ip_address.un.ip6, &ipv6, sizeof (ipv6));
14803     }
14804   else
14805     {
14806       mp->ip_address.af = 0;
14807       clib_memcpy (mp->ip_address.un.ip6, &ipv4, sizeof (ipv4));
14808     }
14809
14810   /* send it... */
14811   S (mp);
14812
14813   /* Wait for a reply... */
14814   W (ret);
14815   return ret;
14816 }
14817
14818 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14819
14820 static int
14821 api_lisp_gpe_enable_disable (vat_main_t * vam)
14822 {
14823   unformat_input_t *input = vam->input;
14824   vl_api_gpe_enable_disable_t *mp;
14825   u8 is_set = 0;
14826   u8 is_enable = 1;
14827   int ret;
14828
14829   /* Parse args required to build the message */
14830   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14831     {
14832       if (unformat (input, "enable"))
14833         {
14834           is_set = 1;
14835           is_enable = 1;
14836         }
14837       else if (unformat (input, "disable"))
14838         {
14839           is_set = 1;
14840           is_enable = 0;
14841         }
14842       else
14843         break;
14844     }
14845
14846   if (is_set == 0)
14847     {
14848       errmsg ("Value not set");
14849       return -99;
14850     }
14851
14852   /* Construct the API message */
14853   M (GPE_ENABLE_DISABLE, mp);
14854
14855   mp->is_enable = is_enable;
14856
14857   /* send it... */
14858   S (mp);
14859
14860   /* Wait for a reply... */
14861   W (ret);
14862   return ret;
14863 }
14864
14865 static int
14866 api_one_rloc_probe_enable_disable (vat_main_t * vam)
14867 {
14868   unformat_input_t *input = vam->input;
14869   vl_api_one_rloc_probe_enable_disable_t *mp;
14870   u8 is_set = 0;
14871   u8 is_enable = 0;
14872   int ret;
14873
14874   /* Parse args required to build the message */
14875   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14876     {
14877       if (unformat (input, "enable"))
14878         {
14879           is_set = 1;
14880           is_enable = 1;
14881         }
14882       else if (unformat (input, "disable"))
14883         is_set = 1;
14884       else
14885         break;
14886     }
14887
14888   if (!is_set)
14889     {
14890       errmsg ("Value not set");
14891       return -99;
14892     }
14893
14894   /* Construct the API message */
14895   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
14896
14897   mp->is_enable = is_enable;
14898
14899   /* send it... */
14900   S (mp);
14901
14902   /* Wait for a reply... */
14903   W (ret);
14904   return ret;
14905 }
14906
14907 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14908
14909 static int
14910 api_one_map_register_enable_disable (vat_main_t * vam)
14911 {
14912   unformat_input_t *input = vam->input;
14913   vl_api_one_map_register_enable_disable_t *mp;
14914   u8 is_set = 0;
14915   u8 is_enable = 0;
14916   int ret;
14917
14918   /* Parse args required to build the message */
14919   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14920     {
14921       if (unformat (input, "enable"))
14922         {
14923           is_set = 1;
14924           is_enable = 1;
14925         }
14926       else if (unformat (input, "disable"))
14927         is_set = 1;
14928       else
14929         break;
14930     }
14931
14932   if (!is_set)
14933     {
14934       errmsg ("Value not set");
14935       return -99;
14936     }
14937
14938   /* Construct the API message */
14939   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
14940
14941   mp->is_enable = is_enable;
14942
14943   /* send it... */
14944   S (mp);
14945
14946   /* Wait for a reply... */
14947   W (ret);
14948   return ret;
14949 }
14950
14951 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14952
14953 static int
14954 api_one_enable_disable (vat_main_t * vam)
14955 {
14956   unformat_input_t *input = vam->input;
14957   vl_api_one_enable_disable_t *mp;
14958   u8 is_set = 0;
14959   u8 is_enable = 0;
14960   int ret;
14961
14962   /* Parse args required to build the message */
14963   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14964     {
14965       if (unformat (input, "enable"))
14966         {
14967           is_set = 1;
14968           is_enable = 1;
14969         }
14970       else if (unformat (input, "disable"))
14971         {
14972           is_set = 1;
14973         }
14974       else
14975         break;
14976     }
14977
14978   if (!is_set)
14979     {
14980       errmsg ("Value not set");
14981       return -99;
14982     }
14983
14984   /* Construct the API message */
14985   M (ONE_ENABLE_DISABLE, mp);
14986
14987   mp->is_enable = is_enable;
14988
14989   /* send it... */
14990   S (mp);
14991
14992   /* Wait for a reply... */
14993   W (ret);
14994   return ret;
14995 }
14996
14997 #define api_lisp_enable_disable api_one_enable_disable
14998
14999 static int
15000 api_one_enable_disable_xtr_mode (vat_main_t * vam)
15001 {
15002   unformat_input_t *input = vam->input;
15003   vl_api_one_enable_disable_xtr_mode_t *mp;
15004   u8 is_set = 0;
15005   u8 is_enable = 0;
15006   int ret;
15007
15008   /* Parse args required to build the message */
15009   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15010     {
15011       if (unformat (input, "enable"))
15012         {
15013           is_set = 1;
15014           is_enable = 1;
15015         }
15016       else if (unformat (input, "disable"))
15017         {
15018           is_set = 1;
15019         }
15020       else
15021         break;
15022     }
15023
15024   if (!is_set)
15025     {
15026       errmsg ("Value not set");
15027       return -99;
15028     }
15029
15030   /* Construct the API message */
15031   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
15032
15033   mp->is_enable = is_enable;
15034
15035   /* send it... */
15036   S (mp);
15037
15038   /* Wait for a reply... */
15039   W (ret);
15040   return ret;
15041 }
15042
15043 static int
15044 api_one_show_xtr_mode (vat_main_t * vam)
15045 {
15046   vl_api_one_show_xtr_mode_t *mp;
15047   int ret;
15048
15049   /* Construct the API message */
15050   M (ONE_SHOW_XTR_MODE, mp);
15051
15052   /* send it... */
15053   S (mp);
15054
15055   /* Wait for a reply... */
15056   W (ret);
15057   return ret;
15058 }
15059
15060 static int
15061 api_one_enable_disable_pitr_mode (vat_main_t * vam)
15062 {
15063   unformat_input_t *input = vam->input;
15064   vl_api_one_enable_disable_pitr_mode_t *mp;
15065   u8 is_set = 0;
15066   u8 is_enable = 0;
15067   int ret;
15068
15069   /* Parse args required to build the message */
15070   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15071     {
15072       if (unformat (input, "enable"))
15073         {
15074           is_set = 1;
15075           is_enable = 1;
15076         }
15077       else if (unformat (input, "disable"))
15078         {
15079           is_set = 1;
15080         }
15081       else
15082         break;
15083     }
15084
15085   if (!is_set)
15086     {
15087       errmsg ("Value not set");
15088       return -99;
15089     }
15090
15091   /* Construct the API message */
15092   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
15093
15094   mp->is_enable = is_enable;
15095
15096   /* send it... */
15097   S (mp);
15098
15099   /* Wait for a reply... */
15100   W (ret);
15101   return ret;
15102 }
15103
15104 static int
15105 api_one_show_pitr_mode (vat_main_t * vam)
15106 {
15107   vl_api_one_show_pitr_mode_t *mp;
15108   int ret;
15109
15110   /* Construct the API message */
15111   M (ONE_SHOW_PITR_MODE, mp);
15112
15113   /* send it... */
15114   S (mp);
15115
15116   /* Wait for a reply... */
15117   W (ret);
15118   return ret;
15119 }
15120
15121 static int
15122 api_one_enable_disable_petr_mode (vat_main_t * vam)
15123 {
15124   unformat_input_t *input = vam->input;
15125   vl_api_one_enable_disable_petr_mode_t *mp;
15126   u8 is_set = 0;
15127   u8 is_enable = 0;
15128   int ret;
15129
15130   /* Parse args required to build the message */
15131   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15132     {
15133       if (unformat (input, "enable"))
15134         {
15135           is_set = 1;
15136           is_enable = 1;
15137         }
15138       else if (unformat (input, "disable"))
15139         {
15140           is_set = 1;
15141         }
15142       else
15143         break;
15144     }
15145
15146   if (!is_set)
15147     {
15148       errmsg ("Value not set");
15149       return -99;
15150     }
15151
15152   /* Construct the API message */
15153   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
15154
15155   mp->is_enable = is_enable;
15156
15157   /* send it... */
15158   S (mp);
15159
15160   /* Wait for a reply... */
15161   W (ret);
15162   return ret;
15163 }
15164
15165 static int
15166 api_one_show_petr_mode (vat_main_t * vam)
15167 {
15168   vl_api_one_show_petr_mode_t *mp;
15169   int ret;
15170
15171   /* Construct the API message */
15172   M (ONE_SHOW_PETR_MODE, mp);
15173
15174   /* send it... */
15175   S (mp);
15176
15177   /* Wait for a reply... */
15178   W (ret);
15179   return ret;
15180 }
15181
15182 static int
15183 api_show_one_map_register_state (vat_main_t * vam)
15184 {
15185   vl_api_show_one_map_register_state_t *mp;
15186   int ret;
15187
15188   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
15189
15190   /* send */
15191   S (mp);
15192
15193   /* wait for reply */
15194   W (ret);
15195   return ret;
15196 }
15197
15198 #define api_show_lisp_map_register_state api_show_one_map_register_state
15199
15200 static int
15201 api_show_one_rloc_probe_state (vat_main_t * vam)
15202 {
15203   vl_api_show_one_rloc_probe_state_t *mp;
15204   int ret;
15205
15206   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
15207
15208   /* send */
15209   S (mp);
15210
15211   /* wait for reply */
15212   W (ret);
15213   return ret;
15214 }
15215
15216 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
15217
15218 static int
15219 api_one_add_del_ndp_entry (vat_main_t * vam)
15220 {
15221   vl_api_one_add_del_ndp_entry_t *mp;
15222   unformat_input_t *input = vam->input;
15223   u8 is_add = 1;
15224   u8 mac_set = 0;
15225   u8 bd_set = 0;
15226   u8 ip_set = 0;
15227   u8 mac[6] = { 0, };
15228   u8 ip6[16] = { 0, };
15229   u32 bd = ~0;
15230   int ret;
15231
15232   /* Parse args required to build the message */
15233   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15234     {
15235       if (unformat (input, "del"))
15236         is_add = 0;
15237       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15238         mac_set = 1;
15239       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
15240         ip_set = 1;
15241       else if (unformat (input, "bd %d", &bd))
15242         bd_set = 1;
15243       else
15244         {
15245           errmsg ("parse error '%U'", format_unformat_error, input);
15246           return -99;
15247         }
15248     }
15249
15250   if (!bd_set || !ip_set || (!mac_set && is_add))
15251     {
15252       errmsg ("Missing BD, IP or MAC!");
15253       return -99;
15254     }
15255
15256   M (ONE_ADD_DEL_NDP_ENTRY, mp);
15257   mp->is_add = is_add;
15258   clib_memcpy (&mp->entry.mac, mac, 6);
15259   mp->bd = clib_host_to_net_u32 (bd);
15260   clib_memcpy (&mp->entry.ip6, ip6, sizeof (mp->entry.ip6));
15261
15262   /* send */
15263   S (mp);
15264
15265   /* wait for reply */
15266   W (ret);
15267   return ret;
15268 }
15269
15270 static int
15271 api_one_add_del_l2_arp_entry (vat_main_t * vam)
15272 {
15273   vl_api_one_add_del_l2_arp_entry_t *mp;
15274   unformat_input_t *input = vam->input;
15275   u8 is_add = 1;
15276   u8 mac_set = 0;
15277   u8 bd_set = 0;
15278   u8 ip_set = 0;
15279   u8 mac[6] = { 0, };
15280   u32 ip4 = 0, bd = ~0;
15281   int ret;
15282
15283   /* Parse args required to build the message */
15284   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15285     {
15286       if (unformat (input, "del"))
15287         is_add = 0;
15288       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15289         mac_set = 1;
15290       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
15291         ip_set = 1;
15292       else if (unformat (input, "bd %d", &bd))
15293         bd_set = 1;
15294       else
15295         {
15296           errmsg ("parse error '%U'", format_unformat_error, input);
15297           return -99;
15298         }
15299     }
15300
15301   if (!bd_set || !ip_set || (!mac_set && is_add))
15302     {
15303       errmsg ("Missing BD, IP or MAC!");
15304       return -99;
15305     }
15306
15307   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
15308   mp->is_add = is_add;
15309   clib_memcpy (&mp->entry.mac, mac, 6);
15310   mp->bd = clib_host_to_net_u32 (bd);
15311   clib_memcpy (mp->entry.ip4, &ip4, sizeof (mp->entry.ip4));
15312
15313   /* send */
15314   S (mp);
15315
15316   /* wait for reply */
15317   W (ret);
15318   return ret;
15319 }
15320
15321 static int
15322 api_one_ndp_bd_get (vat_main_t * vam)
15323 {
15324   vl_api_one_ndp_bd_get_t *mp;
15325   int ret;
15326
15327   M (ONE_NDP_BD_GET, mp);
15328
15329   /* send */
15330   S (mp);
15331
15332   /* wait for reply */
15333   W (ret);
15334   return ret;
15335 }
15336
15337 static int
15338 api_one_ndp_entries_get (vat_main_t * vam)
15339 {
15340   vl_api_one_ndp_entries_get_t *mp;
15341   unformat_input_t *input = vam->input;
15342   u8 bd_set = 0;
15343   u32 bd = ~0;
15344   int ret;
15345
15346   /* Parse args required to build the message */
15347   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15348     {
15349       if (unformat (input, "bd %d", &bd))
15350         bd_set = 1;
15351       else
15352         {
15353           errmsg ("parse error '%U'", format_unformat_error, input);
15354           return -99;
15355         }
15356     }
15357
15358   if (!bd_set)
15359     {
15360       errmsg ("Expected bridge domain!");
15361       return -99;
15362     }
15363
15364   M (ONE_NDP_ENTRIES_GET, mp);
15365   mp->bd = clib_host_to_net_u32 (bd);
15366
15367   /* send */
15368   S (mp);
15369
15370   /* wait for reply */
15371   W (ret);
15372   return ret;
15373 }
15374
15375 static int
15376 api_one_l2_arp_bd_get (vat_main_t * vam)
15377 {
15378   vl_api_one_l2_arp_bd_get_t *mp;
15379   int ret;
15380
15381   M (ONE_L2_ARP_BD_GET, mp);
15382
15383   /* send */
15384   S (mp);
15385
15386   /* wait for reply */
15387   W (ret);
15388   return ret;
15389 }
15390
15391 static int
15392 api_one_l2_arp_entries_get (vat_main_t * vam)
15393 {
15394   vl_api_one_l2_arp_entries_get_t *mp;
15395   unformat_input_t *input = vam->input;
15396   u8 bd_set = 0;
15397   u32 bd = ~0;
15398   int ret;
15399
15400   /* Parse args required to build the message */
15401   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15402     {
15403       if (unformat (input, "bd %d", &bd))
15404         bd_set = 1;
15405       else
15406         {
15407           errmsg ("parse error '%U'", format_unformat_error, input);
15408           return -99;
15409         }
15410     }
15411
15412   if (!bd_set)
15413     {
15414       errmsg ("Expected bridge domain!");
15415       return -99;
15416     }
15417
15418   M (ONE_L2_ARP_ENTRIES_GET, mp);
15419   mp->bd = clib_host_to_net_u32 (bd);
15420
15421   /* send */
15422   S (mp);
15423
15424   /* wait for reply */
15425   W (ret);
15426   return ret;
15427 }
15428
15429 static int
15430 api_one_stats_enable_disable (vat_main_t * vam)
15431 {
15432   vl_api_one_stats_enable_disable_t *mp;
15433   unformat_input_t *input = vam->input;
15434   u8 is_set = 0;
15435   u8 is_enable = 0;
15436   int ret;
15437
15438   /* Parse args required to build the message */
15439   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15440     {
15441       if (unformat (input, "enable"))
15442         {
15443           is_set = 1;
15444           is_enable = 1;
15445         }
15446       else if (unformat (input, "disable"))
15447         {
15448           is_set = 1;
15449         }
15450       else
15451         break;
15452     }
15453
15454   if (!is_set)
15455     {
15456       errmsg ("Value not set");
15457       return -99;
15458     }
15459
15460   M (ONE_STATS_ENABLE_DISABLE, mp);
15461   mp->is_enable = is_enable;
15462
15463   /* send */
15464   S (mp);
15465
15466   /* wait for reply */
15467   W (ret);
15468   return ret;
15469 }
15470
15471 static int
15472 api_show_one_stats_enable_disable (vat_main_t * vam)
15473 {
15474   vl_api_show_one_stats_enable_disable_t *mp;
15475   int ret;
15476
15477   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
15478
15479   /* send */
15480   S (mp);
15481
15482   /* wait for reply */
15483   W (ret);
15484   return ret;
15485 }
15486
15487 static int
15488 api_show_one_map_request_mode (vat_main_t * vam)
15489 {
15490   vl_api_show_one_map_request_mode_t *mp;
15491   int ret;
15492
15493   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
15494
15495   /* send */
15496   S (mp);
15497
15498   /* wait for reply */
15499   W (ret);
15500   return ret;
15501 }
15502
15503 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
15504
15505 static int
15506 api_one_map_request_mode (vat_main_t * vam)
15507 {
15508   unformat_input_t *input = vam->input;
15509   vl_api_one_map_request_mode_t *mp;
15510   u8 mode = 0;
15511   int ret;
15512
15513   /* Parse args required to build the message */
15514   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15515     {
15516       if (unformat (input, "dst-only"))
15517         mode = 0;
15518       else if (unformat (input, "src-dst"))
15519         mode = 1;
15520       else
15521         {
15522           errmsg ("parse error '%U'", format_unformat_error, input);
15523           return -99;
15524         }
15525     }
15526
15527   M (ONE_MAP_REQUEST_MODE, mp);
15528
15529   mp->mode = mode;
15530
15531   /* send */
15532   S (mp);
15533
15534   /* wait for reply */
15535   W (ret);
15536   return ret;
15537 }
15538
15539 #define api_lisp_map_request_mode api_one_map_request_mode
15540
15541 /**
15542  * Enable/disable ONE proxy ITR.
15543  *
15544  * @param vam vpp API test context
15545  * @return return code
15546  */
15547 static int
15548 api_one_pitr_set_locator_set (vat_main_t * vam)
15549 {
15550   u8 ls_name_set = 0;
15551   unformat_input_t *input = vam->input;
15552   vl_api_one_pitr_set_locator_set_t *mp;
15553   u8 is_add = 1;
15554   u8 *ls_name = 0;
15555   int ret;
15556
15557   /* Parse args required to build the message */
15558   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15559     {
15560       if (unformat (input, "del"))
15561         is_add = 0;
15562       else if (unformat (input, "locator-set %s", &ls_name))
15563         ls_name_set = 1;
15564       else
15565         {
15566           errmsg ("parse error '%U'", format_unformat_error, input);
15567           return -99;
15568         }
15569     }
15570
15571   if (!ls_name_set)
15572     {
15573       errmsg ("locator-set name not set!");
15574       return -99;
15575     }
15576
15577   M (ONE_PITR_SET_LOCATOR_SET, mp);
15578
15579   mp->is_add = is_add;
15580   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15581   vec_free (ls_name);
15582
15583   /* send */
15584   S (mp);
15585
15586   /* wait for reply */
15587   W (ret);
15588   return ret;
15589 }
15590
15591 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
15592
15593 static int
15594 api_one_nsh_set_locator_set (vat_main_t * vam)
15595 {
15596   u8 ls_name_set = 0;
15597   unformat_input_t *input = vam->input;
15598   vl_api_one_nsh_set_locator_set_t *mp;
15599   u8 is_add = 1;
15600   u8 *ls_name = 0;
15601   int ret;
15602
15603   /* Parse args required to build the message */
15604   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15605     {
15606       if (unformat (input, "del"))
15607         is_add = 0;
15608       else if (unformat (input, "ls %s", &ls_name))
15609         ls_name_set = 1;
15610       else
15611         {
15612           errmsg ("parse error '%U'", format_unformat_error, input);
15613           return -99;
15614         }
15615     }
15616
15617   if (!ls_name_set && is_add)
15618     {
15619       errmsg ("locator-set name not set!");
15620       return -99;
15621     }
15622
15623   M (ONE_NSH_SET_LOCATOR_SET, mp);
15624
15625   mp->is_add = is_add;
15626   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15627   vec_free (ls_name);
15628
15629   /* send */
15630   S (mp);
15631
15632   /* wait for reply */
15633   W (ret);
15634   return ret;
15635 }
15636
15637 static int
15638 api_show_one_pitr (vat_main_t * vam)
15639 {
15640   vl_api_show_one_pitr_t *mp;
15641   int ret;
15642
15643   if (!vam->json_output)
15644     {
15645       print (vam->ofp, "%=20s", "lisp status:");
15646     }
15647
15648   M (SHOW_ONE_PITR, mp);
15649   /* send it... */
15650   S (mp);
15651
15652   /* Wait for a reply... */
15653   W (ret);
15654   return ret;
15655 }
15656
15657 #define api_show_lisp_pitr api_show_one_pitr
15658
15659 static int
15660 api_one_use_petr (vat_main_t * vam)
15661 {
15662   unformat_input_t *input = vam->input;
15663   vl_api_one_use_petr_t *mp;
15664   u8 is_add = 0;
15665   ip_address_t ip;
15666   int ret;
15667
15668   clib_memset (&ip, 0, sizeof (ip));
15669
15670   /* Parse args required to build the message */
15671   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15672     {
15673       if (unformat (input, "disable"))
15674         is_add = 0;
15675       else
15676         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
15677         {
15678           is_add = 1;
15679           ip_addr_version (&ip) = AF_IP4;
15680         }
15681       else
15682         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
15683         {
15684           is_add = 1;
15685           ip_addr_version (&ip) = AF_IP6;
15686         }
15687       else
15688         {
15689           errmsg ("parse error '%U'", format_unformat_error, input);
15690           return -99;
15691         }
15692     }
15693
15694   M (ONE_USE_PETR, mp);
15695
15696   mp->is_add = is_add;
15697   if (is_add)
15698     {
15699       mp->ip_address.af = ip_addr_version (&ip) == AF_IP4 ? 0 : 1;
15700       if (mp->ip_address.af)
15701         clib_memcpy (mp->ip_address.un.ip6, &ip, 16);
15702       else
15703         clib_memcpy (mp->ip_address.un.ip4, &ip, 4);
15704     }
15705
15706   /* send */
15707   S (mp);
15708
15709   /* wait for reply */
15710   W (ret);
15711   return ret;
15712 }
15713
15714 #define api_lisp_use_petr api_one_use_petr
15715
15716 static int
15717 api_show_one_nsh_mapping (vat_main_t * vam)
15718 {
15719   vl_api_show_one_use_petr_t *mp;
15720   int ret;
15721
15722   if (!vam->json_output)
15723     {
15724       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
15725     }
15726
15727   M (SHOW_ONE_NSH_MAPPING, mp);
15728   /* send it... */
15729   S (mp);
15730
15731   /* Wait for a reply... */
15732   W (ret);
15733   return ret;
15734 }
15735
15736 static int
15737 api_show_one_use_petr (vat_main_t * vam)
15738 {
15739   vl_api_show_one_use_petr_t *mp;
15740   int ret;
15741
15742   if (!vam->json_output)
15743     {
15744       print (vam->ofp, "%=20s", "Proxy-ETR status:");
15745     }
15746
15747   M (SHOW_ONE_USE_PETR, mp);
15748   /* send it... */
15749   S (mp);
15750
15751   /* Wait for a reply... */
15752   W (ret);
15753   return ret;
15754 }
15755
15756 #define api_show_lisp_use_petr api_show_one_use_petr
15757
15758 /**
15759  * Add/delete mapping between vni and vrf
15760  */
15761 static int
15762 api_one_eid_table_add_del_map (vat_main_t * vam)
15763 {
15764   unformat_input_t *input = vam->input;
15765   vl_api_one_eid_table_add_del_map_t *mp;
15766   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
15767   u32 vni, vrf, bd_index;
15768   int ret;
15769
15770   /* Parse args required to build the message */
15771   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15772     {
15773       if (unformat (input, "del"))
15774         is_add = 0;
15775       else if (unformat (input, "vrf %d", &vrf))
15776         vrf_set = 1;
15777       else if (unformat (input, "bd_index %d", &bd_index))
15778         bd_index_set = 1;
15779       else if (unformat (input, "vni %d", &vni))
15780         vni_set = 1;
15781       else
15782         break;
15783     }
15784
15785   if (!vni_set || (!vrf_set && !bd_index_set))
15786     {
15787       errmsg ("missing arguments!");
15788       return -99;
15789     }
15790
15791   if (vrf_set && bd_index_set)
15792     {
15793       errmsg ("error: both vrf and bd entered!");
15794       return -99;
15795     }
15796
15797   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
15798
15799   mp->is_add = is_add;
15800   mp->vni = htonl (vni);
15801   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
15802   mp->is_l2 = bd_index_set;
15803
15804   /* send */
15805   S (mp);
15806
15807   /* wait for reply */
15808   W (ret);
15809   return ret;
15810 }
15811
15812 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
15813
15814 uword
15815 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
15816 {
15817   u32 *action = va_arg (*args, u32 *);
15818   u8 *s = 0;
15819
15820   if (unformat (input, "%s", &s))
15821     {
15822       if (!strcmp ((char *) s, "no-action"))
15823         action[0] = 0;
15824       else if (!strcmp ((char *) s, "natively-forward"))
15825         action[0] = 1;
15826       else if (!strcmp ((char *) s, "send-map-request"))
15827         action[0] = 2;
15828       else if (!strcmp ((char *) s, "drop"))
15829         action[0] = 3;
15830       else
15831         {
15832           clib_warning ("invalid action: '%s'", s);
15833           action[0] = 3;
15834         }
15835     }
15836   else
15837     return 0;
15838
15839   vec_free (s);
15840   return 1;
15841 }
15842
15843 /**
15844  * Add/del remote mapping to/from ONE control plane
15845  *
15846  * @param vam vpp API test context
15847  * @return return code
15848  */
15849 static int
15850 api_one_add_del_remote_mapping (vat_main_t * vam)
15851 {
15852   unformat_input_t *input = vam->input;
15853   vl_api_one_add_del_remote_mapping_t *mp;
15854   u32 vni = 0;
15855   lisp_eid_vat_t _eid, *eid = &_eid;
15856   lisp_eid_vat_t _seid, *seid = &_seid;
15857   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
15858   u32 action = ~0, p, w, data_len;
15859   ip4_address_t rloc4;
15860   ip6_address_t rloc6;
15861   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
15862   int ret;
15863
15864   clib_memset (&rloc, 0, sizeof (rloc));
15865
15866   /* Parse args required to build the message */
15867   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15868     {
15869       if (unformat (input, "del-all"))
15870         {
15871           del_all = 1;
15872         }
15873       else if (unformat (input, "del"))
15874         {
15875           is_add = 0;
15876         }
15877       else if (unformat (input, "add"))
15878         {
15879           is_add = 1;
15880         }
15881       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15882         {
15883           eid_set = 1;
15884         }
15885       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
15886         {
15887           seid_set = 1;
15888         }
15889       else if (unformat (input, "vni %d", &vni))
15890         {
15891           ;
15892         }
15893       else if (unformat (input, "p %d w %d", &p, &w))
15894         {
15895           if (!curr_rloc)
15896             {
15897               errmsg ("No RLOC configured for setting priority/weight!");
15898               return -99;
15899             }
15900           curr_rloc->priority = p;
15901           curr_rloc->weight = w;
15902         }
15903       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
15904         {
15905           rloc.ip_address.af = 0;
15906           clib_memcpy (&rloc.ip_address.un.ip6, &rloc6, sizeof (rloc6));
15907           vec_add1 (rlocs, rloc);
15908           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15909         }
15910       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
15911         {
15912           rloc.ip_address.af = 1;
15913           clib_memcpy (&rloc.ip_address.un.ip4, &rloc4, sizeof (rloc4));
15914           vec_add1 (rlocs, rloc);
15915           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15916         }
15917       else if (unformat (input, "action %U",
15918                          unformat_negative_mapping_action, &action))
15919         {
15920           ;
15921         }
15922       else
15923         {
15924           clib_warning ("parse error '%U'", format_unformat_error, input);
15925           return -99;
15926         }
15927     }
15928
15929   if (0 == eid_set)
15930     {
15931       errmsg ("missing params!");
15932       return -99;
15933     }
15934
15935   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
15936     {
15937       errmsg ("no action set for negative map-reply!");
15938       return -99;
15939     }
15940
15941   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
15942
15943   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
15944   mp->is_add = is_add;
15945   mp->vni = htonl (vni);
15946   mp->action = (u8) action;
15947   mp->is_src_dst = seid_set;
15948   mp->del_all = del_all;
15949   lisp_eid_put_vat (&mp->deid, eid);
15950   lisp_eid_put_vat (&mp->seid, seid);
15951
15952   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
15953   clib_memcpy (mp->rlocs, rlocs, data_len);
15954   vec_free (rlocs);
15955
15956   /* send it... */
15957   S (mp);
15958
15959   /* Wait for a reply... */
15960   W (ret);
15961   return ret;
15962 }
15963
15964 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
15965
15966 /**
15967  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
15968  * forwarding entries in data-plane accordingly.
15969  *
15970  * @param vam vpp API test context
15971  * @return return code
15972  */
15973 static int
15974 api_one_add_del_adjacency (vat_main_t * vam)
15975 {
15976   unformat_input_t *input = vam->input;
15977   vl_api_one_add_del_adjacency_t *mp;
15978   u32 vni = 0;
15979   u8 is_add = 1;
15980   int ret;
15981   lisp_eid_vat_t leid, reid;
15982
15983   leid.type = reid.type = (u8) ~ 0;
15984
15985   /* Parse args required to build the message */
15986   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15987     {
15988       if (unformat (input, "del"))
15989         {
15990           is_add = 0;
15991         }
15992       else if (unformat (input, "add"))
15993         {
15994           is_add = 1;
15995         }
15996       else if (unformat (input, "reid %U/%d", unformat_ip46_address,
15997                          &reid.addr.ip, &reid.len))
15998         {
15999           reid.type = 0;        /* ipv4 */
16000         }
16001       else if (unformat (input, "reid %U", unformat_ethernet_address,
16002                          &reid.addr.mac))
16003         {
16004           reid.type = 1;        /* mac */
16005         }
16006       else if (unformat (input, "leid %U/%d", unformat_ip46_address,
16007                          &leid.addr.ip, &leid.len))
16008         {
16009           leid.type = 0;        /* ipv4 */
16010         }
16011       else if (unformat (input, "leid %U", unformat_ethernet_address,
16012                          &leid.addr.mac))
16013         {
16014           leid.type = 1;        /* mac */
16015         }
16016       else if (unformat (input, "vni %d", &vni))
16017         {
16018           ;
16019         }
16020       else
16021         {
16022           errmsg ("parse error '%U'", format_unformat_error, input);
16023           return -99;
16024         }
16025     }
16026
16027   if ((u8) ~ 0 == reid.type)
16028     {
16029       errmsg ("missing params!");
16030       return -99;
16031     }
16032
16033   if (leid.type != reid.type)
16034     {
16035       errmsg ("remote and local EIDs are of different types!");
16036       return -99;
16037     }
16038
16039   M (ONE_ADD_DEL_ADJACENCY, mp);
16040   mp->is_add = is_add;
16041   mp->vni = htonl (vni);
16042   lisp_eid_put_vat (&mp->leid, &leid);
16043   lisp_eid_put_vat (&mp->reid, &reid);
16044
16045   /* send it... */
16046   S (mp);
16047
16048   /* Wait for a reply... */
16049   W (ret);
16050   return ret;
16051 }
16052
16053 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
16054
16055 uword
16056 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
16057 {
16058   u32 *mode = va_arg (*args, u32 *);
16059
16060   if (unformat (input, "lisp"))
16061     *mode = 0;
16062   else if (unformat (input, "vxlan"))
16063     *mode = 1;
16064   else
16065     return 0;
16066
16067   return 1;
16068 }
16069
16070 static int
16071 api_gpe_get_encap_mode (vat_main_t * vam)
16072 {
16073   vl_api_gpe_get_encap_mode_t *mp;
16074   int ret;
16075
16076   /* Construct the API message */
16077   M (GPE_GET_ENCAP_MODE, mp);
16078
16079   /* send it... */
16080   S (mp);
16081
16082   /* Wait for a reply... */
16083   W (ret);
16084   return ret;
16085 }
16086
16087 static int
16088 api_gpe_set_encap_mode (vat_main_t * vam)
16089 {
16090   unformat_input_t *input = vam->input;
16091   vl_api_gpe_set_encap_mode_t *mp;
16092   int ret;
16093   u32 mode = 0;
16094
16095   /* Parse args required to build the message */
16096   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16097     {
16098       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
16099         ;
16100       else
16101         break;
16102     }
16103
16104   /* Construct the API message */
16105   M (GPE_SET_ENCAP_MODE, mp);
16106
16107   mp->is_vxlan = mode;
16108
16109   /* send it... */
16110   S (mp);
16111
16112   /* Wait for a reply... */
16113   W (ret);
16114   return ret;
16115 }
16116
16117 static int
16118 api_lisp_gpe_add_del_iface (vat_main_t * vam)
16119 {
16120   unformat_input_t *input = vam->input;
16121   vl_api_gpe_add_del_iface_t *mp;
16122   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
16123   u32 dp_table = 0, vni = 0;
16124   int ret;
16125
16126   /* Parse args required to build the message */
16127   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16128     {
16129       if (unformat (input, "up"))
16130         {
16131           action_set = 1;
16132           is_add = 1;
16133         }
16134       else if (unformat (input, "down"))
16135         {
16136           action_set = 1;
16137           is_add = 0;
16138         }
16139       else if (unformat (input, "table_id %d", &dp_table))
16140         {
16141           dp_table_set = 1;
16142         }
16143       else if (unformat (input, "bd_id %d", &dp_table))
16144         {
16145           dp_table_set = 1;
16146           is_l2 = 1;
16147         }
16148       else if (unformat (input, "vni %d", &vni))
16149         {
16150           vni_set = 1;
16151         }
16152       else
16153         break;
16154     }
16155
16156   if (action_set == 0)
16157     {
16158       errmsg ("Action not set");
16159       return -99;
16160     }
16161   if (dp_table_set == 0 || vni_set == 0)
16162     {
16163       errmsg ("vni and dp_table must be set");
16164       return -99;
16165     }
16166
16167   /* Construct the API message */
16168   M (GPE_ADD_DEL_IFACE, mp);
16169
16170   mp->is_add = is_add;
16171   mp->dp_table = clib_host_to_net_u32 (dp_table);
16172   mp->is_l2 = is_l2;
16173   mp->vni = clib_host_to_net_u32 (vni);
16174
16175   /* send it... */
16176   S (mp);
16177
16178   /* Wait for a reply... */
16179   W (ret);
16180   return ret;
16181 }
16182
16183 static int
16184 api_one_map_register_fallback_threshold (vat_main_t * vam)
16185 {
16186   unformat_input_t *input = vam->input;
16187   vl_api_one_map_register_fallback_threshold_t *mp;
16188   u32 value = 0;
16189   u8 is_set = 0;
16190   int ret;
16191
16192   /* Parse args required to build the message */
16193   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16194     {
16195       if (unformat (input, "%u", &value))
16196         is_set = 1;
16197       else
16198         {
16199           clib_warning ("parse error '%U'", format_unformat_error, input);
16200           return -99;
16201         }
16202     }
16203
16204   if (!is_set)
16205     {
16206       errmsg ("fallback threshold value is missing!");
16207       return -99;
16208     }
16209
16210   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16211   mp->value = clib_host_to_net_u32 (value);
16212
16213   /* send it... */
16214   S (mp);
16215
16216   /* Wait for a reply... */
16217   W (ret);
16218   return ret;
16219 }
16220
16221 static int
16222 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
16223 {
16224   vl_api_show_one_map_register_fallback_threshold_t *mp;
16225   int ret;
16226
16227   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16228
16229   /* send it... */
16230   S (mp);
16231
16232   /* Wait for a reply... */
16233   W (ret);
16234   return ret;
16235 }
16236
16237 uword
16238 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
16239 {
16240   u32 *proto = va_arg (*args, u32 *);
16241
16242   if (unformat (input, "udp"))
16243     *proto = 1;
16244   else if (unformat (input, "api"))
16245     *proto = 2;
16246   else
16247     return 0;
16248
16249   return 1;
16250 }
16251
16252 static int
16253 api_one_set_transport_protocol (vat_main_t * vam)
16254 {
16255   unformat_input_t *input = vam->input;
16256   vl_api_one_set_transport_protocol_t *mp;
16257   u8 is_set = 0;
16258   u32 protocol = 0;
16259   int ret;
16260
16261   /* Parse args required to build the message */
16262   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16263     {
16264       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
16265         is_set = 1;
16266       else
16267         {
16268           clib_warning ("parse error '%U'", format_unformat_error, input);
16269           return -99;
16270         }
16271     }
16272
16273   if (!is_set)
16274     {
16275       errmsg ("Transport protocol missing!");
16276       return -99;
16277     }
16278
16279   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
16280   mp->protocol = (u8) protocol;
16281
16282   /* send it... */
16283   S (mp);
16284
16285   /* Wait for a reply... */
16286   W (ret);
16287   return ret;
16288 }
16289
16290 static int
16291 api_one_get_transport_protocol (vat_main_t * vam)
16292 {
16293   vl_api_one_get_transport_protocol_t *mp;
16294   int ret;
16295
16296   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
16297
16298   /* send it... */
16299   S (mp);
16300
16301   /* Wait for a reply... */
16302   W (ret);
16303   return ret;
16304 }
16305
16306 static int
16307 api_one_map_register_set_ttl (vat_main_t * vam)
16308 {
16309   unformat_input_t *input = vam->input;
16310   vl_api_one_map_register_set_ttl_t *mp;
16311   u32 ttl = 0;
16312   u8 is_set = 0;
16313   int ret;
16314
16315   /* Parse args required to build the message */
16316   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16317     {
16318       if (unformat (input, "%u", &ttl))
16319         is_set = 1;
16320       else
16321         {
16322           clib_warning ("parse error '%U'", format_unformat_error, input);
16323           return -99;
16324         }
16325     }
16326
16327   if (!is_set)
16328     {
16329       errmsg ("TTL value missing!");
16330       return -99;
16331     }
16332
16333   M (ONE_MAP_REGISTER_SET_TTL, mp);
16334   mp->ttl = clib_host_to_net_u32 (ttl);
16335
16336   /* send it... */
16337   S (mp);
16338
16339   /* Wait for a reply... */
16340   W (ret);
16341   return ret;
16342 }
16343
16344 static int
16345 api_show_one_map_register_ttl (vat_main_t * vam)
16346 {
16347   vl_api_show_one_map_register_ttl_t *mp;
16348   int ret;
16349
16350   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
16351
16352   /* send it... */
16353   S (mp);
16354
16355   /* Wait for a reply... */
16356   W (ret);
16357   return ret;
16358 }
16359
16360 /**
16361  * Add/del map request itr rlocs from ONE control plane and updates
16362  *
16363  * @param vam vpp API test context
16364  * @return return code
16365  */
16366 static int
16367 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
16368 {
16369   unformat_input_t *input = vam->input;
16370   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
16371   u8 *locator_set_name = 0;
16372   u8 locator_set_name_set = 0;
16373   u8 is_add = 1;
16374   int ret;
16375
16376   /* Parse args required to build the message */
16377   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16378     {
16379       if (unformat (input, "del"))
16380         {
16381           is_add = 0;
16382         }
16383       else if (unformat (input, "%_%v%_", &locator_set_name))
16384         {
16385           locator_set_name_set = 1;
16386         }
16387       else
16388         {
16389           clib_warning ("parse error '%U'", format_unformat_error, input);
16390           return -99;
16391         }
16392     }
16393
16394   if (is_add && !locator_set_name_set)
16395     {
16396       errmsg ("itr-rloc is not set!");
16397       return -99;
16398     }
16399
16400   if (is_add && vec_len (locator_set_name) > 64)
16401     {
16402       errmsg ("itr-rloc locator-set name too long");
16403       vec_free (locator_set_name);
16404       return -99;
16405     }
16406
16407   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
16408   mp->is_add = is_add;
16409   if (is_add)
16410     {
16411       clib_memcpy (mp->locator_set_name, locator_set_name,
16412                    vec_len (locator_set_name));
16413     }
16414   else
16415     {
16416       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
16417     }
16418   vec_free (locator_set_name);
16419
16420   /* send it... */
16421   S (mp);
16422
16423   /* Wait for a reply... */
16424   W (ret);
16425   return ret;
16426 }
16427
16428 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
16429
16430 static int
16431 api_one_locator_dump (vat_main_t * vam)
16432 {
16433   unformat_input_t *input = vam->input;
16434   vl_api_one_locator_dump_t *mp;
16435   vl_api_control_ping_t *mp_ping;
16436   u8 is_index_set = 0, is_name_set = 0;
16437   u8 *ls_name = 0;
16438   u32 ls_index = ~0;
16439   int ret;
16440
16441   /* Parse args required to build the message */
16442   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16443     {
16444       if (unformat (input, "ls_name %_%v%_", &ls_name))
16445         {
16446           is_name_set = 1;
16447         }
16448       else if (unformat (input, "ls_index %d", &ls_index))
16449         {
16450           is_index_set = 1;
16451         }
16452       else
16453         {
16454           errmsg ("parse error '%U'", format_unformat_error, input);
16455           return -99;
16456         }
16457     }
16458
16459   if (!is_index_set && !is_name_set)
16460     {
16461       errmsg ("error: expected one of index or name!");
16462       return -99;
16463     }
16464
16465   if (is_index_set && is_name_set)
16466     {
16467       errmsg ("error: only one param expected!");
16468       return -99;
16469     }
16470
16471   if (vec_len (ls_name) > 62)
16472     {
16473       errmsg ("error: locator set name too long!");
16474       return -99;
16475     }
16476
16477   if (!vam->json_output)
16478     {
16479       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
16480     }
16481
16482   M (ONE_LOCATOR_DUMP, mp);
16483   mp->is_index_set = is_index_set;
16484
16485   if (is_index_set)
16486     mp->ls_index = clib_host_to_net_u32 (ls_index);
16487   else
16488     {
16489       vec_add1 (ls_name, 0);
16490       strncpy ((char *) mp->ls_name, (char *) ls_name,
16491                sizeof (mp->ls_name) - 1);
16492     }
16493
16494   /* send it... */
16495   S (mp);
16496
16497   /* Use a control ping for synchronization */
16498   MPING (CONTROL_PING, mp_ping);
16499   S (mp_ping);
16500
16501   /* Wait for a reply... */
16502   W (ret);
16503   return ret;
16504 }
16505
16506 #define api_lisp_locator_dump api_one_locator_dump
16507
16508 static int
16509 api_one_locator_set_dump (vat_main_t * vam)
16510 {
16511   vl_api_one_locator_set_dump_t *mp;
16512   vl_api_control_ping_t *mp_ping;
16513   unformat_input_t *input = vam->input;
16514   u8 filter = 0;
16515   int ret;
16516
16517   /* Parse args required to build the message */
16518   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16519     {
16520       if (unformat (input, "local"))
16521         {
16522           filter = 1;
16523         }
16524       else if (unformat (input, "remote"))
16525         {
16526           filter = 2;
16527         }
16528       else
16529         {
16530           errmsg ("parse error '%U'", format_unformat_error, input);
16531           return -99;
16532         }
16533     }
16534
16535   if (!vam->json_output)
16536     {
16537       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
16538     }
16539
16540   M (ONE_LOCATOR_SET_DUMP, mp);
16541
16542   mp->filter = filter;
16543
16544   /* send it... */
16545   S (mp);
16546
16547   /* Use a control ping for synchronization */
16548   MPING (CONTROL_PING, mp_ping);
16549   S (mp_ping);
16550
16551   /* Wait for a reply... */
16552   W (ret);
16553   return ret;
16554 }
16555
16556 #define api_lisp_locator_set_dump api_one_locator_set_dump
16557
16558 static int
16559 api_one_eid_table_map_dump (vat_main_t * vam)
16560 {
16561   u8 is_l2 = 0;
16562   u8 mode_set = 0;
16563   unformat_input_t *input = vam->input;
16564   vl_api_one_eid_table_map_dump_t *mp;
16565   vl_api_control_ping_t *mp_ping;
16566   int ret;
16567
16568   /* Parse args required to build the message */
16569   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16570     {
16571       if (unformat (input, "l2"))
16572         {
16573           is_l2 = 1;
16574           mode_set = 1;
16575         }
16576       else if (unformat (input, "l3"))
16577         {
16578           is_l2 = 0;
16579           mode_set = 1;
16580         }
16581       else
16582         {
16583           errmsg ("parse error '%U'", format_unformat_error, input);
16584           return -99;
16585         }
16586     }
16587
16588   if (!mode_set)
16589     {
16590       errmsg ("expected one of 'l2' or 'l3' parameter!");
16591       return -99;
16592     }
16593
16594   if (!vam->json_output)
16595     {
16596       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
16597     }
16598
16599   M (ONE_EID_TABLE_MAP_DUMP, mp);
16600   mp->is_l2 = is_l2;
16601
16602   /* send it... */
16603   S (mp);
16604
16605   /* Use a control ping for synchronization */
16606   MPING (CONTROL_PING, mp_ping);
16607   S (mp_ping);
16608
16609   /* Wait for a reply... */
16610   W (ret);
16611   return ret;
16612 }
16613
16614 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
16615
16616 static int
16617 api_one_eid_table_vni_dump (vat_main_t * vam)
16618 {
16619   vl_api_one_eid_table_vni_dump_t *mp;
16620   vl_api_control_ping_t *mp_ping;
16621   int ret;
16622
16623   if (!vam->json_output)
16624     {
16625       print (vam->ofp, "VNI");
16626     }
16627
16628   M (ONE_EID_TABLE_VNI_DUMP, mp);
16629
16630   /* send it... */
16631   S (mp);
16632
16633   /* Use a control ping for synchronization */
16634   MPING (CONTROL_PING, mp_ping);
16635   S (mp_ping);
16636
16637   /* Wait for a reply... */
16638   W (ret);
16639   return ret;
16640 }
16641
16642 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
16643
16644 static int
16645 api_one_eid_table_dump (vat_main_t * vam)
16646 {
16647   unformat_input_t *i = vam->input;
16648   vl_api_one_eid_table_dump_t *mp;
16649   vl_api_control_ping_t *mp_ping;
16650   u8 filter = 0;
16651   int ret;
16652   u32 vni, t = 0;
16653   lisp_eid_vat_t eid;
16654   u8 eid_set = 0;
16655
16656   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16657     {
16658       if (unformat
16659           (i, "eid %U/%d", unformat_ip46_address, &eid.addr.ip, &eid.len))
16660         {
16661           eid_set = 1;
16662           eid.type = 0;
16663         }
16664       else
16665         if (unformat (i, "eid %U", unformat_ethernet_address, &eid.addr.mac))
16666         {
16667           eid_set = 1;
16668           eid.type = 1;
16669         }
16670       else if (unformat (i, "eid %U", unformat_nsh_address, &eid.addr.nsh))
16671         {
16672           eid_set = 1;
16673           eid.type = 2;
16674         }
16675       else if (unformat (i, "vni %d", &t))
16676         {
16677           vni = t;
16678         }
16679       else if (unformat (i, "local"))
16680         {
16681           filter = 1;
16682         }
16683       else if (unformat (i, "remote"))
16684         {
16685           filter = 2;
16686         }
16687       else
16688         {
16689           errmsg ("parse error '%U'", format_unformat_error, i);
16690           return -99;
16691         }
16692     }
16693
16694   if (!vam->json_output)
16695     {
16696       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
16697              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
16698     }
16699
16700   M (ONE_EID_TABLE_DUMP, mp);
16701
16702   mp->filter = filter;
16703   if (eid_set)
16704     {
16705       mp->eid_set = 1;
16706       mp->vni = htonl (vni);
16707       lisp_eid_put_vat (&mp->eid, &eid);
16708     }
16709
16710   /* send it... */
16711   S (mp);
16712
16713   /* Use a control ping for synchronization */
16714   MPING (CONTROL_PING, mp_ping);
16715   S (mp_ping);
16716
16717   /* Wait for a reply... */
16718   W (ret);
16719   return ret;
16720 }
16721
16722 #define api_lisp_eid_table_dump api_one_eid_table_dump
16723
16724 static int
16725 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
16726 {
16727   unformat_input_t *i = vam->input;
16728   vl_api_gpe_fwd_entries_get_t *mp;
16729   u8 vni_set = 0;
16730   u32 vni = ~0;
16731   int ret;
16732
16733   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16734     {
16735       if (unformat (i, "vni %d", &vni))
16736         {
16737           vni_set = 1;
16738         }
16739       else
16740         {
16741           errmsg ("parse error '%U'", format_unformat_error, i);
16742           return -99;
16743         }
16744     }
16745
16746   if (!vni_set)
16747     {
16748       errmsg ("vni not set!");
16749       return -99;
16750     }
16751
16752   if (!vam->json_output)
16753     {
16754       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
16755              "leid", "reid");
16756     }
16757
16758   M (GPE_FWD_ENTRIES_GET, mp);
16759   mp->vni = clib_host_to_net_u32 (vni);
16760
16761   /* send it... */
16762   S (mp);
16763
16764   /* Wait for a reply... */
16765   W (ret);
16766   return ret;
16767 }
16768
16769 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
16770 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
16771 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
16772 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
16773 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
16774 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
16775 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
16776 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
16777
16778 static int
16779 api_one_adjacencies_get (vat_main_t * vam)
16780 {
16781   unformat_input_t *i = vam->input;
16782   vl_api_one_adjacencies_get_t *mp;
16783   u8 vni_set = 0;
16784   u32 vni = ~0;
16785   int ret;
16786
16787   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16788     {
16789       if (unformat (i, "vni %d", &vni))
16790         {
16791           vni_set = 1;
16792         }
16793       else
16794         {
16795           errmsg ("parse error '%U'", format_unformat_error, i);
16796           return -99;
16797         }
16798     }
16799
16800   if (!vni_set)
16801     {
16802       errmsg ("vni not set!");
16803       return -99;
16804     }
16805
16806   if (!vam->json_output)
16807     {
16808       print (vam->ofp, "%s %40s", "leid", "reid");
16809     }
16810
16811   M (ONE_ADJACENCIES_GET, mp);
16812   mp->vni = clib_host_to_net_u32 (vni);
16813
16814   /* send it... */
16815   S (mp);
16816
16817   /* Wait for a reply... */
16818   W (ret);
16819   return ret;
16820 }
16821
16822 #define api_lisp_adjacencies_get api_one_adjacencies_get
16823
16824 static int
16825 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
16826 {
16827   unformat_input_t *i = vam->input;
16828   vl_api_gpe_native_fwd_rpaths_get_t *mp;
16829   int ret;
16830   u8 ip_family_set = 0, is_ip4 = 1;
16831
16832   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16833     {
16834       if (unformat (i, "ip4"))
16835         {
16836           ip_family_set = 1;
16837           is_ip4 = 1;
16838         }
16839       else if (unformat (i, "ip6"))
16840         {
16841           ip_family_set = 1;
16842           is_ip4 = 0;
16843         }
16844       else
16845         {
16846           errmsg ("parse error '%U'", format_unformat_error, i);
16847           return -99;
16848         }
16849     }
16850
16851   if (!ip_family_set)
16852     {
16853       errmsg ("ip family not set!");
16854       return -99;
16855     }
16856
16857   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
16858   mp->is_ip4 = is_ip4;
16859
16860   /* send it... */
16861   S (mp);
16862
16863   /* Wait for a reply... */
16864   W (ret);
16865   return ret;
16866 }
16867
16868 static int
16869 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
16870 {
16871   vl_api_gpe_fwd_entry_vnis_get_t *mp;
16872   int ret;
16873
16874   if (!vam->json_output)
16875     {
16876       print (vam->ofp, "VNIs");
16877     }
16878
16879   M (GPE_FWD_ENTRY_VNIS_GET, mp);
16880
16881   /* send it... */
16882   S (mp);
16883
16884   /* Wait for a reply... */
16885   W (ret);
16886   return ret;
16887 }
16888
16889 static int
16890 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
16891 {
16892   unformat_input_t *i = vam->input;
16893   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
16894   int ret = 0;
16895   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
16896   struct in_addr ip4;
16897   struct in6_addr ip6;
16898   u32 table_id = 0, nh_sw_if_index = ~0;
16899
16900   clib_memset (&ip4, 0, sizeof (ip4));
16901   clib_memset (&ip6, 0, sizeof (ip6));
16902
16903   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16904     {
16905       if (unformat (i, "del"))
16906         is_add = 0;
16907       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
16908                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16909         {
16910           ip_set = 1;
16911           is_ip4 = 1;
16912         }
16913       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
16914                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16915         {
16916           ip_set = 1;
16917           is_ip4 = 0;
16918         }
16919       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
16920         {
16921           ip_set = 1;
16922           is_ip4 = 1;
16923           nh_sw_if_index = ~0;
16924         }
16925       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
16926         {
16927           ip_set = 1;
16928           is_ip4 = 0;
16929           nh_sw_if_index = ~0;
16930         }
16931       else if (unformat (i, "table %d", &table_id))
16932         ;
16933       else
16934         {
16935           errmsg ("parse error '%U'", format_unformat_error, i);
16936           return -99;
16937         }
16938     }
16939
16940   if (!ip_set)
16941     {
16942       errmsg ("nh addr not set!");
16943       return -99;
16944     }
16945
16946   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
16947   mp->is_add = is_add;
16948   mp->table_id = clib_host_to_net_u32 (table_id);
16949   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
16950   mp->nh_addr.af = is_ip4 ? 0 : 1;
16951   if (is_ip4)
16952     clib_memcpy (mp->nh_addr.un.ip4, &ip4, sizeof (ip4));
16953   else
16954     clib_memcpy (mp->nh_addr.un.ip6, &ip6, sizeof (ip6));
16955
16956   /* send it... */
16957   S (mp);
16958
16959   /* Wait for a reply... */
16960   W (ret);
16961   return ret;
16962 }
16963
16964 static int
16965 api_one_map_server_dump (vat_main_t * vam)
16966 {
16967   vl_api_one_map_server_dump_t *mp;
16968   vl_api_control_ping_t *mp_ping;
16969   int ret;
16970
16971   if (!vam->json_output)
16972     {
16973       print (vam->ofp, "%=20s", "Map server");
16974     }
16975
16976   M (ONE_MAP_SERVER_DUMP, mp);
16977   /* send it... */
16978   S (mp);
16979
16980   /* Use a control ping for synchronization */
16981   MPING (CONTROL_PING, mp_ping);
16982   S (mp_ping);
16983
16984   /* Wait for a reply... */
16985   W (ret);
16986   return ret;
16987 }
16988
16989 #define api_lisp_map_server_dump api_one_map_server_dump
16990
16991 static int
16992 api_one_map_resolver_dump (vat_main_t * vam)
16993 {
16994   vl_api_one_map_resolver_dump_t *mp;
16995   vl_api_control_ping_t *mp_ping;
16996   int ret;
16997
16998   if (!vam->json_output)
16999     {
17000       print (vam->ofp, "%=20s", "Map resolver");
17001     }
17002
17003   M (ONE_MAP_RESOLVER_DUMP, mp);
17004   /* send it... */
17005   S (mp);
17006
17007   /* Use a control ping for synchronization */
17008   MPING (CONTROL_PING, mp_ping);
17009   S (mp_ping);
17010
17011   /* Wait for a reply... */
17012   W (ret);
17013   return ret;
17014 }
17015
17016 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
17017
17018 static int
17019 api_one_stats_flush (vat_main_t * vam)
17020 {
17021   vl_api_one_stats_flush_t *mp;
17022   int ret = 0;
17023
17024   M (ONE_STATS_FLUSH, mp);
17025   S (mp);
17026   W (ret);
17027   return ret;
17028 }
17029
17030 static int
17031 api_one_stats_dump (vat_main_t * vam)
17032 {
17033   vl_api_one_stats_dump_t *mp;
17034   vl_api_control_ping_t *mp_ping;
17035   int ret;
17036
17037   M (ONE_STATS_DUMP, mp);
17038   /* send it... */
17039   S (mp);
17040
17041   /* Use a control ping for synchronization */
17042   MPING (CONTROL_PING, mp_ping);
17043   S (mp_ping);
17044
17045   /* Wait for a reply... */
17046   W (ret);
17047   return ret;
17048 }
17049
17050 static int
17051 api_show_one_status (vat_main_t * vam)
17052 {
17053   vl_api_show_one_status_t *mp;
17054   int ret;
17055
17056   if (!vam->json_output)
17057     {
17058       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
17059     }
17060
17061   M (SHOW_ONE_STATUS, mp);
17062   /* send it... */
17063   S (mp);
17064   /* Wait for a reply... */
17065   W (ret);
17066   return ret;
17067 }
17068
17069 #define api_show_lisp_status api_show_one_status
17070
17071 static int
17072 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
17073 {
17074   vl_api_gpe_fwd_entry_path_dump_t *mp;
17075   vl_api_control_ping_t *mp_ping;
17076   unformat_input_t *i = vam->input;
17077   u32 fwd_entry_index = ~0;
17078   int ret;
17079
17080   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17081     {
17082       if (unformat (i, "index %d", &fwd_entry_index))
17083         ;
17084       else
17085         break;
17086     }
17087
17088   if (~0 == fwd_entry_index)
17089     {
17090       errmsg ("no index specified!");
17091       return -99;
17092     }
17093
17094   if (!vam->json_output)
17095     {
17096       print (vam->ofp, "first line");
17097     }
17098
17099   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
17100
17101   /* send it... */
17102   S (mp);
17103   /* Use a control ping for synchronization */
17104   MPING (CONTROL_PING, mp_ping);
17105   S (mp_ping);
17106
17107   /* Wait for a reply... */
17108   W (ret);
17109   return ret;
17110 }
17111
17112 static int
17113 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
17114 {
17115   vl_api_one_get_map_request_itr_rlocs_t *mp;
17116   int ret;
17117
17118   if (!vam->json_output)
17119     {
17120       print (vam->ofp, "%=20s", "itr-rlocs:");
17121     }
17122
17123   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
17124   /* send it... */
17125   S (mp);
17126   /* Wait for a reply... */
17127   W (ret);
17128   return ret;
17129 }
17130
17131 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
17132
17133 static int
17134 api_af_packet_create (vat_main_t * vam)
17135 {
17136   unformat_input_t *i = vam->input;
17137   vl_api_af_packet_create_t *mp;
17138   u8 *host_if_name = 0;
17139   u8 hw_addr[6];
17140   u8 random_hw_addr = 1;
17141   int ret;
17142
17143   clib_memset (hw_addr, 0, sizeof (hw_addr));
17144
17145   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17146     {
17147       if (unformat (i, "name %s", &host_if_name))
17148         vec_add1 (host_if_name, 0);
17149       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17150         random_hw_addr = 0;
17151       else
17152         break;
17153     }
17154
17155   if (!vec_len (host_if_name))
17156     {
17157       errmsg ("host-interface name must be specified");
17158       return -99;
17159     }
17160
17161   if (vec_len (host_if_name) > 64)
17162     {
17163       errmsg ("host-interface name too long");
17164       return -99;
17165     }
17166
17167   M (AF_PACKET_CREATE, mp);
17168
17169   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17170   clib_memcpy (mp->hw_addr, hw_addr, 6);
17171   mp->use_random_hw_addr = random_hw_addr;
17172   vec_free (host_if_name);
17173
17174   S (mp);
17175
17176   /* *INDENT-OFF* */
17177   W2 (ret,
17178       ({
17179         if (ret == 0)
17180           fprintf (vam->ofp ? vam->ofp : stderr,
17181                    " new sw_if_index = %d\n", vam->sw_if_index);
17182       }));
17183   /* *INDENT-ON* */
17184   return ret;
17185 }
17186
17187 static int
17188 api_af_packet_delete (vat_main_t * vam)
17189 {
17190   unformat_input_t *i = vam->input;
17191   vl_api_af_packet_delete_t *mp;
17192   u8 *host_if_name = 0;
17193   int ret;
17194
17195   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17196     {
17197       if (unformat (i, "name %s", &host_if_name))
17198         vec_add1 (host_if_name, 0);
17199       else
17200         break;
17201     }
17202
17203   if (!vec_len (host_if_name))
17204     {
17205       errmsg ("host-interface name must be specified");
17206       return -99;
17207     }
17208
17209   if (vec_len (host_if_name) > 64)
17210     {
17211       errmsg ("host-interface name too long");
17212       return -99;
17213     }
17214
17215   M (AF_PACKET_DELETE, mp);
17216
17217   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17218   vec_free (host_if_name);
17219
17220   S (mp);
17221   W (ret);
17222   return ret;
17223 }
17224
17225 static void vl_api_af_packet_details_t_handler
17226   (vl_api_af_packet_details_t * mp)
17227 {
17228   vat_main_t *vam = &vat_main;
17229
17230   print (vam->ofp, "%-16s %d",
17231          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
17232 }
17233
17234 static void vl_api_af_packet_details_t_handler_json
17235   (vl_api_af_packet_details_t * mp)
17236 {
17237   vat_main_t *vam = &vat_main;
17238   vat_json_node_t *node = NULL;
17239
17240   if (VAT_JSON_ARRAY != vam->json_tree.type)
17241     {
17242       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17243       vat_json_init_array (&vam->json_tree);
17244     }
17245   node = vat_json_array_add (&vam->json_tree);
17246
17247   vat_json_init_object (node);
17248   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17249   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
17250 }
17251
17252 static int
17253 api_af_packet_dump (vat_main_t * vam)
17254 {
17255   vl_api_af_packet_dump_t *mp;
17256   vl_api_control_ping_t *mp_ping;
17257   int ret;
17258
17259   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
17260   /* Get list of tap interfaces */
17261   M (AF_PACKET_DUMP, mp);
17262   S (mp);
17263
17264   /* Use a control ping for synchronization */
17265   MPING (CONTROL_PING, mp_ping);
17266   S (mp_ping);
17267
17268   W (ret);
17269   return ret;
17270 }
17271
17272 static int
17273 api_policer_add_del (vat_main_t * vam)
17274 {
17275   unformat_input_t *i = vam->input;
17276   vl_api_policer_add_del_t *mp;
17277   u8 is_add = 1;
17278   u8 *name = 0;
17279   u32 cir = 0;
17280   u32 eir = 0;
17281   u64 cb = 0;
17282   u64 eb = 0;
17283   u8 rate_type = 0;
17284   u8 round_type = 0;
17285   u8 type = 0;
17286   u8 color_aware = 0;
17287   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
17288   int ret;
17289
17290   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
17291   conform_action.dscp = 0;
17292   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
17293   exceed_action.dscp = 0;
17294   violate_action.action_type = SSE2_QOS_ACTION_DROP;
17295   violate_action.dscp = 0;
17296
17297   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17298     {
17299       if (unformat (i, "del"))
17300         is_add = 0;
17301       else if (unformat (i, "name %s", &name))
17302         vec_add1 (name, 0);
17303       else if (unformat (i, "cir %u", &cir))
17304         ;
17305       else if (unformat (i, "eir %u", &eir))
17306         ;
17307       else if (unformat (i, "cb %u", &cb))
17308         ;
17309       else if (unformat (i, "eb %u", &eb))
17310         ;
17311       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
17312                          &rate_type))
17313         ;
17314       else if (unformat (i, "round_type %U", unformat_policer_round_type,
17315                          &round_type))
17316         ;
17317       else if (unformat (i, "type %U", unformat_policer_type, &type))
17318         ;
17319       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
17320                          &conform_action))
17321         ;
17322       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
17323                          &exceed_action))
17324         ;
17325       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
17326                          &violate_action))
17327         ;
17328       else if (unformat (i, "color-aware"))
17329         color_aware = 1;
17330       else
17331         break;
17332     }
17333
17334   if (!vec_len (name))
17335     {
17336       errmsg ("policer name must be specified");
17337       return -99;
17338     }
17339
17340   if (vec_len (name) > 64)
17341     {
17342       errmsg ("policer name too long");
17343       return -99;
17344     }
17345
17346   M (POLICER_ADD_DEL, mp);
17347
17348   clib_memcpy (mp->name, name, vec_len (name));
17349   vec_free (name);
17350   mp->is_add = is_add;
17351   mp->cir = ntohl (cir);
17352   mp->eir = ntohl (eir);
17353   mp->cb = clib_net_to_host_u64 (cb);
17354   mp->eb = clib_net_to_host_u64 (eb);
17355   mp->rate_type = rate_type;
17356   mp->round_type = round_type;
17357   mp->type = type;
17358   mp->conform_action.type = conform_action.action_type;
17359   mp->conform_action.dscp = conform_action.dscp;
17360   mp->exceed_action.type = exceed_action.action_type;
17361   mp->exceed_action.dscp = exceed_action.dscp;
17362   mp->violate_action.type = violate_action.action_type;
17363   mp->violate_action.dscp = violate_action.dscp;
17364   mp->color_aware = color_aware;
17365
17366   S (mp);
17367   W (ret);
17368   return ret;
17369 }
17370
17371 static int
17372 api_policer_dump (vat_main_t * vam)
17373 {
17374   unformat_input_t *i = vam->input;
17375   vl_api_policer_dump_t *mp;
17376   vl_api_control_ping_t *mp_ping;
17377   u8 *match_name = 0;
17378   u8 match_name_valid = 0;
17379   int ret;
17380
17381   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17382     {
17383       if (unformat (i, "name %s", &match_name))
17384         {
17385           vec_add1 (match_name, 0);
17386           match_name_valid = 1;
17387         }
17388       else
17389         break;
17390     }
17391
17392   M (POLICER_DUMP, mp);
17393   mp->match_name_valid = match_name_valid;
17394   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
17395   vec_free (match_name);
17396   /* send it... */
17397   S (mp);
17398
17399   /* Use a control ping for synchronization */
17400   MPING (CONTROL_PING, mp_ping);
17401   S (mp_ping);
17402
17403   /* Wait for a reply... */
17404   W (ret);
17405   return ret;
17406 }
17407
17408 static int
17409 api_policer_classify_set_interface (vat_main_t * vam)
17410 {
17411   unformat_input_t *i = vam->input;
17412   vl_api_policer_classify_set_interface_t *mp;
17413   u32 sw_if_index;
17414   int sw_if_index_set;
17415   u32 ip4_table_index = ~0;
17416   u32 ip6_table_index = ~0;
17417   u32 l2_table_index = ~0;
17418   u8 is_add = 1;
17419   int ret;
17420
17421   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17422     {
17423       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17424         sw_if_index_set = 1;
17425       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17426         sw_if_index_set = 1;
17427       else if (unformat (i, "del"))
17428         is_add = 0;
17429       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17430         ;
17431       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17432         ;
17433       else if (unformat (i, "l2-table %d", &l2_table_index))
17434         ;
17435       else
17436         {
17437           clib_warning ("parse error '%U'", format_unformat_error, i);
17438           return -99;
17439         }
17440     }
17441
17442   if (sw_if_index_set == 0)
17443     {
17444       errmsg ("missing interface name or sw_if_index");
17445       return -99;
17446     }
17447
17448   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
17449
17450   mp->sw_if_index = ntohl (sw_if_index);
17451   mp->ip4_table_index = ntohl (ip4_table_index);
17452   mp->ip6_table_index = ntohl (ip6_table_index);
17453   mp->l2_table_index = ntohl (l2_table_index);
17454   mp->is_add = is_add;
17455
17456   S (mp);
17457   W (ret);
17458   return ret;
17459 }
17460
17461 static int
17462 api_policer_classify_dump (vat_main_t * vam)
17463 {
17464   unformat_input_t *i = vam->input;
17465   vl_api_policer_classify_dump_t *mp;
17466   vl_api_control_ping_t *mp_ping;
17467   u8 type = POLICER_CLASSIFY_N_TABLES;
17468   int ret;
17469
17470   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
17471     ;
17472   else
17473     {
17474       errmsg ("classify table type must be specified");
17475       return -99;
17476     }
17477
17478   if (!vam->json_output)
17479     {
17480       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17481     }
17482
17483   M (POLICER_CLASSIFY_DUMP, mp);
17484   mp->type = type;
17485   /* send it... */
17486   S (mp);
17487
17488   /* Use a control ping for synchronization */
17489   MPING (CONTROL_PING, mp_ping);
17490   S (mp_ping);
17491
17492   /* Wait for a reply... */
17493   W (ret);
17494   return ret;
17495 }
17496
17497 static u8 *
17498 format_fib_api_path_nh_proto (u8 * s, va_list * args)
17499 {
17500   vl_api_fib_path_nh_proto_t proto =
17501     va_arg (*args, vl_api_fib_path_nh_proto_t);
17502
17503   switch (proto)
17504     {
17505     case FIB_API_PATH_NH_PROTO_IP4:
17506       s = format (s, "ip4");
17507       break;
17508     case FIB_API_PATH_NH_PROTO_IP6:
17509       s = format (s, "ip6");
17510       break;
17511     case FIB_API_PATH_NH_PROTO_MPLS:
17512       s = format (s, "mpls");
17513       break;
17514     case FIB_API_PATH_NH_PROTO_BIER:
17515       s = format (s, "bier");
17516       break;
17517     case FIB_API_PATH_NH_PROTO_ETHERNET:
17518       s = format (s, "ethernet");
17519       break;
17520     }
17521
17522   return (s);
17523 }
17524
17525 static u8 *
17526 format_vl_api_ip_address_union (u8 * s, va_list * args)
17527 {
17528   vl_api_address_family_t af = va_arg (*args, int);
17529   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
17530
17531   switch (af)
17532     {
17533     case ADDRESS_IP4:
17534       s = format (s, "%U", format_ip4_address, u->ip4);
17535       break;
17536     case ADDRESS_IP6:
17537       s = format (s, "%U", format_ip6_address, u->ip6);
17538       break;
17539     }
17540   return (s);
17541 }
17542
17543 static u8 *
17544 format_vl_api_fib_path_type (u8 * s, va_list * args)
17545 {
17546   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
17547
17548   switch (t)
17549     {
17550     case FIB_API_PATH_TYPE_NORMAL:
17551       s = format (s, "normal");
17552       break;
17553     case FIB_API_PATH_TYPE_LOCAL:
17554       s = format (s, "local");
17555       break;
17556     case FIB_API_PATH_TYPE_DROP:
17557       s = format (s, "drop");
17558       break;
17559     case FIB_API_PATH_TYPE_UDP_ENCAP:
17560       s = format (s, "udp-encap");
17561       break;
17562     case FIB_API_PATH_TYPE_BIER_IMP:
17563       s = format (s, "bier-imp");
17564       break;
17565     case FIB_API_PATH_TYPE_ICMP_UNREACH:
17566       s = format (s, "unreach");
17567       break;
17568     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
17569       s = format (s, "prohibit");
17570       break;
17571     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
17572       s = format (s, "src-lookup");
17573       break;
17574     case FIB_API_PATH_TYPE_DVR:
17575       s = format (s, "dvr");
17576       break;
17577     case FIB_API_PATH_TYPE_INTERFACE_RX:
17578       s = format (s, "interface-rx");
17579       break;
17580     case FIB_API_PATH_TYPE_CLASSIFY:
17581       s = format (s, "classify");
17582       break;
17583     }
17584
17585   return (s);
17586 }
17587
17588 static void
17589 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
17590 {
17591   print (vam->ofp,
17592          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
17593          ntohl (fp->weight), ntohl (fp->sw_if_index),
17594          format_vl_api_fib_path_type, fp->type,
17595          format_fib_api_path_nh_proto, fp->proto,
17596          format_vl_api_ip_address_union, &fp->nh.address);
17597 }
17598
17599 static void
17600 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
17601                                  vl_api_fib_path_t * fp)
17602 {
17603   struct in_addr ip4;
17604   struct in6_addr ip6;
17605
17606   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17607   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17608   vat_json_object_add_uint (node, "type", fp->type);
17609   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
17610   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
17611     {
17612       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
17613       vat_json_object_add_ip4 (node, "next_hop", ip4);
17614     }
17615   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP6)
17616     {
17617       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
17618       vat_json_object_add_ip6 (node, "next_hop", ip6);
17619     }
17620 }
17621
17622 static void
17623 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
17624 {
17625   vat_main_t *vam = &vat_main;
17626   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17627   vl_api_fib_path_t *fp;
17628   i32 i;
17629
17630   print (vam->ofp, "sw_if_index %d via:",
17631          ntohl (mp->mt_tunnel.mt_sw_if_index));
17632   fp = mp->mt_tunnel.mt_paths;
17633   for (i = 0; i < count; i++)
17634     {
17635       vl_api_fib_path_print (vam, fp);
17636       fp++;
17637     }
17638
17639   print (vam->ofp, "");
17640 }
17641
17642 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
17643 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
17644
17645 static void
17646 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
17647 {
17648   vat_main_t *vam = &vat_main;
17649   vat_json_node_t *node = NULL;
17650   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17651   vl_api_fib_path_t *fp;
17652   i32 i;
17653
17654   if (VAT_JSON_ARRAY != vam->json_tree.type)
17655     {
17656       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17657       vat_json_init_array (&vam->json_tree);
17658     }
17659   node = vat_json_array_add (&vam->json_tree);
17660
17661   vat_json_init_object (node);
17662   vat_json_object_add_uint (node, "sw_if_index",
17663                             ntohl (mp->mt_tunnel.mt_sw_if_index));
17664
17665   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
17666
17667   fp = mp->mt_tunnel.mt_paths;
17668   for (i = 0; i < count; i++)
17669     {
17670       vl_api_mpls_fib_path_json_print (node, fp);
17671       fp++;
17672     }
17673 }
17674
17675 static int
17676 api_mpls_tunnel_dump (vat_main_t * vam)
17677 {
17678   vl_api_mpls_tunnel_dump_t *mp;
17679   vl_api_control_ping_t *mp_ping;
17680   int ret;
17681
17682   M (MPLS_TUNNEL_DUMP, mp);
17683
17684   S (mp);
17685
17686   /* Use a control ping for synchronization */
17687   MPING (CONTROL_PING, mp_ping);
17688   S (mp_ping);
17689
17690   W (ret);
17691   return ret;
17692 }
17693
17694 #define vl_api_mpls_table_details_t_endian vl_noop_handler
17695 #define vl_api_mpls_table_details_t_print vl_noop_handler
17696
17697
17698 static void
17699 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
17700 {
17701   vat_main_t *vam = &vat_main;
17702
17703   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
17704 }
17705
17706 static void vl_api_mpls_table_details_t_handler_json
17707   (vl_api_mpls_table_details_t * mp)
17708 {
17709   vat_main_t *vam = &vat_main;
17710   vat_json_node_t *node = NULL;
17711
17712   if (VAT_JSON_ARRAY != vam->json_tree.type)
17713     {
17714       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17715       vat_json_init_array (&vam->json_tree);
17716     }
17717   node = vat_json_array_add (&vam->json_tree);
17718
17719   vat_json_init_object (node);
17720   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
17721 }
17722
17723 static int
17724 api_mpls_table_dump (vat_main_t * vam)
17725 {
17726   vl_api_mpls_table_dump_t *mp;
17727   vl_api_control_ping_t *mp_ping;
17728   int ret;
17729
17730   M (MPLS_TABLE_DUMP, mp);
17731   S (mp);
17732
17733   /* Use a control ping for synchronization */
17734   MPING (CONTROL_PING, mp_ping);
17735   S (mp_ping);
17736
17737   W (ret);
17738   return ret;
17739 }
17740
17741 #define vl_api_mpls_route_details_t_endian vl_noop_handler
17742 #define vl_api_mpls_route_details_t_print vl_noop_handler
17743
17744 static void
17745 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
17746 {
17747   vat_main_t *vam = &vat_main;
17748   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
17749   vl_api_fib_path_t *fp;
17750   int i;
17751
17752   print (vam->ofp,
17753          "table-id %d, label %u, ess_bit %u",
17754          ntohl (mp->mr_route.mr_table_id),
17755          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
17756   fp = mp->mr_route.mr_paths;
17757   for (i = 0; i < count; i++)
17758     {
17759       vl_api_fib_path_print (vam, fp);
17760       fp++;
17761     }
17762 }
17763
17764 static void vl_api_mpls_route_details_t_handler_json
17765   (vl_api_mpls_route_details_t * mp)
17766 {
17767   vat_main_t *vam = &vat_main;
17768   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
17769   vat_json_node_t *node = NULL;
17770   vl_api_fib_path_t *fp;
17771   int i;
17772
17773   if (VAT_JSON_ARRAY != vam->json_tree.type)
17774     {
17775       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17776       vat_json_init_array (&vam->json_tree);
17777     }
17778   node = vat_json_array_add (&vam->json_tree);
17779
17780   vat_json_init_object (node);
17781   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
17782   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
17783   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
17784   vat_json_object_add_uint (node, "path_count", count);
17785   fp = mp->mr_route.mr_paths;
17786   for (i = 0; i < count; i++)
17787     {
17788       vl_api_mpls_fib_path_json_print (node, fp);
17789       fp++;
17790     }
17791 }
17792
17793 static int
17794 api_mpls_route_dump (vat_main_t * vam)
17795 {
17796   unformat_input_t *input = vam->input;
17797   vl_api_mpls_route_dump_t *mp;
17798   vl_api_control_ping_t *mp_ping;
17799   u32 table_id;
17800   int ret;
17801
17802   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17803     {
17804       if (unformat (input, "table_id %d", &table_id))
17805         ;
17806       else
17807         break;
17808     }
17809   if (table_id == ~0)
17810     {
17811       errmsg ("missing table id");
17812       return -99;
17813     }
17814
17815   M (MPLS_ROUTE_DUMP, mp);
17816
17817   mp->table.mt_table_id = ntohl (table_id);
17818   S (mp);
17819
17820   /* Use a control ping for synchronization */
17821   MPING (CONTROL_PING, mp_ping);
17822   S (mp_ping);
17823
17824   W (ret);
17825   return ret;
17826 }
17827
17828 #define vl_api_ip_table_details_t_endian vl_noop_handler
17829 #define vl_api_ip_table_details_t_print vl_noop_handler
17830
17831 static void
17832 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
17833 {
17834   vat_main_t *vam = &vat_main;
17835
17836   print (vam->ofp,
17837          "%s; table-id %d, prefix %U/%d",
17838          mp->table.name, ntohl (mp->table.table_id));
17839 }
17840
17841
17842 static void vl_api_ip_table_details_t_handler_json
17843   (vl_api_ip_table_details_t * mp)
17844 {
17845   vat_main_t *vam = &vat_main;
17846   vat_json_node_t *node = NULL;
17847
17848   if (VAT_JSON_ARRAY != vam->json_tree.type)
17849     {
17850       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17851       vat_json_init_array (&vam->json_tree);
17852     }
17853   node = vat_json_array_add (&vam->json_tree);
17854
17855   vat_json_init_object (node);
17856   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
17857 }
17858
17859 static int
17860 api_ip_table_dump (vat_main_t * vam)
17861 {
17862   vl_api_ip_table_dump_t *mp;
17863   vl_api_control_ping_t *mp_ping;
17864   int ret;
17865
17866   M (IP_TABLE_DUMP, mp);
17867   S (mp);
17868
17869   /* Use a control ping for synchronization */
17870   MPING (CONTROL_PING, mp_ping);
17871   S (mp_ping);
17872
17873   W (ret);
17874   return ret;
17875 }
17876
17877 static int
17878 api_ip_mtable_dump (vat_main_t * vam)
17879 {
17880   vl_api_ip_mtable_dump_t *mp;
17881   vl_api_control_ping_t *mp_ping;
17882   int ret;
17883
17884   M (IP_MTABLE_DUMP, mp);
17885   S (mp);
17886
17887   /* Use a control ping for synchronization */
17888   MPING (CONTROL_PING, mp_ping);
17889   S (mp_ping);
17890
17891   W (ret);
17892   return ret;
17893 }
17894
17895 static int
17896 api_ip_mroute_dump (vat_main_t * vam)
17897 {
17898   unformat_input_t *input = vam->input;
17899   vl_api_control_ping_t *mp_ping;
17900   vl_api_ip_mroute_dump_t *mp;
17901   int ret, is_ip6;
17902   u32 table_id;
17903
17904   is_ip6 = 0;
17905   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17906     {
17907       if (unformat (input, "table_id %d", &table_id))
17908         ;
17909       else if (unformat (input, "ip6"))
17910         is_ip6 = 1;
17911       else if (unformat (input, "ip4"))
17912         is_ip6 = 0;
17913       else
17914         break;
17915     }
17916   if (table_id == ~0)
17917     {
17918       errmsg ("missing table id");
17919       return -99;
17920     }
17921
17922   M (IP_MROUTE_DUMP, mp);
17923   mp->table.table_id = table_id;
17924   mp->table.is_ip6 = is_ip6;
17925   S (mp);
17926
17927   /* Use a control ping for synchronization */
17928   MPING (CONTROL_PING, mp_ping);
17929   S (mp_ping);
17930
17931   W (ret);
17932   return ret;
17933 }
17934
17935 #define vl_api_ip_route_details_t_endian vl_noop_handler
17936 #define vl_api_ip_route_details_t_print vl_noop_handler
17937
17938 static void
17939 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
17940 {
17941   vat_main_t *vam = &vat_main;
17942   u8 count = mp->route.n_paths;
17943   vl_api_fib_path_t *fp;
17944   int i;
17945
17946   print (vam->ofp,
17947          "table-id %d, prefix %U/%d",
17948          ntohl (mp->route.table_id),
17949          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
17950   for (i = 0; i < count; i++)
17951     {
17952       fp = &mp->route.paths[i];
17953
17954       vl_api_fib_path_print (vam, fp);
17955       fp++;
17956     }
17957 }
17958
17959 static void vl_api_ip_route_details_t_handler_json
17960   (vl_api_ip_route_details_t * mp)
17961 {
17962   vat_main_t *vam = &vat_main;
17963   u8 count = mp->route.n_paths;
17964   vat_json_node_t *node = NULL;
17965   struct in_addr ip4;
17966   struct in6_addr ip6;
17967   vl_api_fib_path_t *fp;
17968   int i;
17969
17970   if (VAT_JSON_ARRAY != vam->json_tree.type)
17971     {
17972       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17973       vat_json_init_array (&vam->json_tree);
17974     }
17975   node = vat_json_array_add (&vam->json_tree);
17976
17977   vat_json_init_object (node);
17978   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
17979   if (ADDRESS_IP6 == mp->route.prefix.address.af)
17980     {
17981       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
17982       vat_json_object_add_ip6 (node, "prefix", ip6);
17983     }
17984   else
17985     {
17986       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
17987       vat_json_object_add_ip4 (node, "prefix", ip4);
17988     }
17989   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
17990   vat_json_object_add_uint (node, "path_count", count);
17991   for (i = 0; i < count; i++)
17992     {
17993       fp = &mp->route.paths[i];
17994       vl_api_mpls_fib_path_json_print (node, fp);
17995     }
17996 }
17997
17998 static int
17999 api_ip_route_dump (vat_main_t * vam)
18000 {
18001   unformat_input_t *input = vam->input;
18002   vl_api_ip_route_dump_t *mp;
18003   vl_api_control_ping_t *mp_ping;
18004   u32 table_id;
18005   u8 is_ip6;
18006   int ret;
18007
18008   is_ip6 = 0;
18009   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18010     {
18011       if (unformat (input, "table_id %d", &table_id))
18012         ;
18013       else if (unformat (input, "ip6"))
18014         is_ip6 = 1;
18015       else if (unformat (input, "ip4"))
18016         is_ip6 = 0;
18017       else
18018         break;
18019     }
18020   if (table_id == ~0)
18021     {
18022       errmsg ("missing table id");
18023       return -99;
18024     }
18025
18026   M (IP_ROUTE_DUMP, mp);
18027
18028   mp->table.table_id = table_id;
18029   mp->table.is_ip6 = is_ip6;
18030
18031   S (mp);
18032
18033   /* Use a control ping for synchronization */
18034   MPING (CONTROL_PING, mp_ping);
18035   S (mp_ping);
18036
18037   W (ret);
18038   return ret;
18039 }
18040
18041 int
18042 api_classify_table_ids (vat_main_t * vam)
18043 {
18044   vl_api_classify_table_ids_t *mp;
18045   int ret;
18046
18047   /* Construct the API message */
18048   M (CLASSIFY_TABLE_IDS, mp);
18049   mp->context = 0;
18050
18051   S (mp);
18052   W (ret);
18053   return ret;
18054 }
18055
18056 int
18057 api_classify_table_by_interface (vat_main_t * vam)
18058 {
18059   unformat_input_t *input = vam->input;
18060   vl_api_classify_table_by_interface_t *mp;
18061
18062   u32 sw_if_index = ~0;
18063   int ret;
18064   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18065     {
18066       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18067         ;
18068       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18069         ;
18070       else
18071         break;
18072     }
18073   if (sw_if_index == ~0)
18074     {
18075       errmsg ("missing interface name or sw_if_index");
18076       return -99;
18077     }
18078
18079   /* Construct the API message */
18080   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
18081   mp->context = 0;
18082   mp->sw_if_index = ntohl (sw_if_index);
18083
18084   S (mp);
18085   W (ret);
18086   return ret;
18087 }
18088
18089 int
18090 api_classify_table_info (vat_main_t * vam)
18091 {
18092   unformat_input_t *input = vam->input;
18093   vl_api_classify_table_info_t *mp;
18094
18095   u32 table_id = ~0;
18096   int ret;
18097   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18098     {
18099       if (unformat (input, "table_id %d", &table_id))
18100         ;
18101       else
18102         break;
18103     }
18104   if (table_id == ~0)
18105     {
18106       errmsg ("missing table id");
18107       return -99;
18108     }
18109
18110   /* Construct the API message */
18111   M (CLASSIFY_TABLE_INFO, mp);
18112   mp->context = 0;
18113   mp->table_id = ntohl (table_id);
18114
18115   S (mp);
18116   W (ret);
18117   return ret;
18118 }
18119
18120 int
18121 api_classify_session_dump (vat_main_t * vam)
18122 {
18123   unformat_input_t *input = vam->input;
18124   vl_api_classify_session_dump_t *mp;
18125   vl_api_control_ping_t *mp_ping;
18126
18127   u32 table_id = ~0;
18128   int ret;
18129   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18130     {
18131       if (unformat (input, "table_id %d", &table_id))
18132         ;
18133       else
18134         break;
18135     }
18136   if (table_id == ~0)
18137     {
18138       errmsg ("missing table id");
18139       return -99;
18140     }
18141
18142   /* Construct the API message */
18143   M (CLASSIFY_SESSION_DUMP, mp);
18144   mp->context = 0;
18145   mp->table_id = ntohl (table_id);
18146   S (mp);
18147
18148   /* Use a control ping for synchronization */
18149   MPING (CONTROL_PING, mp_ping);
18150   S (mp_ping);
18151
18152   W (ret);
18153   return ret;
18154 }
18155
18156 static void
18157 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
18158 {
18159   vat_main_t *vam = &vat_main;
18160
18161   print (vam->ofp, "collector_address %U, collector_port %d, "
18162          "src_address %U, vrf_id %d, path_mtu %u, "
18163          "template_interval %u, udp_checksum %d",
18164          format_ip4_address, mp->collector_address,
18165          ntohs (mp->collector_port),
18166          format_ip4_address, mp->src_address,
18167          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
18168          ntohl (mp->template_interval), mp->udp_checksum);
18169
18170   vam->retval = 0;
18171   vam->result_ready = 1;
18172 }
18173
18174 static void
18175   vl_api_ipfix_exporter_details_t_handler_json
18176   (vl_api_ipfix_exporter_details_t * mp)
18177 {
18178   vat_main_t *vam = &vat_main;
18179   vat_json_node_t node;
18180   struct in_addr collector_address;
18181   struct in_addr src_address;
18182
18183   vat_json_init_object (&node);
18184   clib_memcpy (&collector_address, &mp->collector_address,
18185                sizeof (collector_address));
18186   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
18187   vat_json_object_add_uint (&node, "collector_port",
18188                             ntohs (mp->collector_port));
18189   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
18190   vat_json_object_add_ip4 (&node, "src_address", src_address);
18191   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
18192   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
18193   vat_json_object_add_uint (&node, "template_interval",
18194                             ntohl (mp->template_interval));
18195   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
18196
18197   vat_json_print (vam->ofp, &node);
18198   vat_json_free (&node);
18199   vam->retval = 0;
18200   vam->result_ready = 1;
18201 }
18202
18203 int
18204 api_ipfix_exporter_dump (vat_main_t * vam)
18205 {
18206   vl_api_ipfix_exporter_dump_t *mp;
18207   int ret;
18208
18209   /* Construct the API message */
18210   M (IPFIX_EXPORTER_DUMP, mp);
18211   mp->context = 0;
18212
18213   S (mp);
18214   W (ret);
18215   return ret;
18216 }
18217
18218 static int
18219 api_ipfix_classify_stream_dump (vat_main_t * vam)
18220 {
18221   vl_api_ipfix_classify_stream_dump_t *mp;
18222   int ret;
18223
18224   /* Construct the API message */
18225   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
18226   mp->context = 0;
18227
18228   S (mp);
18229   W (ret);
18230   return ret;
18231   /* NOTREACHED */
18232   return 0;
18233 }
18234
18235 static void
18236   vl_api_ipfix_classify_stream_details_t_handler
18237   (vl_api_ipfix_classify_stream_details_t * mp)
18238 {
18239   vat_main_t *vam = &vat_main;
18240   print (vam->ofp, "domain_id %d, src_port %d",
18241          ntohl (mp->domain_id), ntohs (mp->src_port));
18242   vam->retval = 0;
18243   vam->result_ready = 1;
18244 }
18245
18246 static void
18247   vl_api_ipfix_classify_stream_details_t_handler_json
18248   (vl_api_ipfix_classify_stream_details_t * mp)
18249 {
18250   vat_main_t *vam = &vat_main;
18251   vat_json_node_t node;
18252
18253   vat_json_init_object (&node);
18254   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
18255   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
18256
18257   vat_json_print (vam->ofp, &node);
18258   vat_json_free (&node);
18259   vam->retval = 0;
18260   vam->result_ready = 1;
18261 }
18262
18263 static int
18264 api_ipfix_classify_table_dump (vat_main_t * vam)
18265 {
18266   vl_api_ipfix_classify_table_dump_t *mp;
18267   vl_api_control_ping_t *mp_ping;
18268   int ret;
18269
18270   if (!vam->json_output)
18271     {
18272       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
18273              "transport_protocol");
18274     }
18275
18276   /* Construct the API message */
18277   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
18278
18279   /* send it... */
18280   S (mp);
18281
18282   /* Use a control ping for synchronization */
18283   MPING (CONTROL_PING, mp_ping);
18284   S (mp_ping);
18285
18286   W (ret);
18287   return ret;
18288 }
18289
18290 static void
18291   vl_api_ipfix_classify_table_details_t_handler
18292   (vl_api_ipfix_classify_table_details_t * mp)
18293 {
18294   vat_main_t *vam = &vat_main;
18295   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
18296          mp->transport_protocol);
18297 }
18298
18299 static void
18300   vl_api_ipfix_classify_table_details_t_handler_json
18301   (vl_api_ipfix_classify_table_details_t * mp)
18302 {
18303   vat_json_node_t *node = NULL;
18304   vat_main_t *vam = &vat_main;
18305
18306   if (VAT_JSON_ARRAY != vam->json_tree.type)
18307     {
18308       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18309       vat_json_init_array (&vam->json_tree);
18310     }
18311
18312   node = vat_json_array_add (&vam->json_tree);
18313   vat_json_init_object (node);
18314
18315   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
18316   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
18317   vat_json_object_add_uint (node, "transport_protocol",
18318                             mp->transport_protocol);
18319 }
18320
18321 static int
18322 api_sw_interface_span_enable_disable (vat_main_t * vam)
18323 {
18324   unformat_input_t *i = vam->input;
18325   vl_api_sw_interface_span_enable_disable_t *mp;
18326   u32 src_sw_if_index = ~0;
18327   u32 dst_sw_if_index = ~0;
18328   u8 state = 3;
18329   int ret;
18330   u8 is_l2 = 0;
18331
18332   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18333     {
18334       if (unformat
18335           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
18336         ;
18337       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
18338         ;
18339       else
18340         if (unformat
18341             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
18342         ;
18343       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
18344         ;
18345       else if (unformat (i, "disable"))
18346         state = 0;
18347       else if (unformat (i, "rx"))
18348         state = 1;
18349       else if (unformat (i, "tx"))
18350         state = 2;
18351       else if (unformat (i, "both"))
18352         state = 3;
18353       else if (unformat (i, "l2"))
18354         is_l2 = 1;
18355       else
18356         break;
18357     }
18358
18359   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
18360
18361   mp->sw_if_index_from = htonl (src_sw_if_index);
18362   mp->sw_if_index_to = htonl (dst_sw_if_index);
18363   mp->state = state;
18364   mp->is_l2 = is_l2;
18365
18366   S (mp);
18367   W (ret);
18368   return ret;
18369 }
18370
18371 static void
18372 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
18373                                             * mp)
18374 {
18375   vat_main_t *vam = &vat_main;
18376   u8 *sw_if_from_name = 0;
18377   u8 *sw_if_to_name = 0;
18378   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18379   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18380   char *states[] = { "none", "rx", "tx", "both" };
18381   hash_pair_t *p;
18382
18383   /* *INDENT-OFF* */
18384   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18385   ({
18386     if ((u32) p->value[0] == sw_if_index_from)
18387       {
18388         sw_if_from_name = (u8 *)(p->key);
18389         if (sw_if_to_name)
18390           break;
18391       }
18392     if ((u32) p->value[0] == sw_if_index_to)
18393       {
18394         sw_if_to_name = (u8 *)(p->key);
18395         if (sw_if_from_name)
18396           break;
18397       }
18398   }));
18399   /* *INDENT-ON* */
18400   print (vam->ofp, "%20s => %20s (%s) %s",
18401          sw_if_from_name, sw_if_to_name, states[mp->state],
18402          mp->is_l2 ? "l2" : "device");
18403 }
18404
18405 static void
18406   vl_api_sw_interface_span_details_t_handler_json
18407   (vl_api_sw_interface_span_details_t * mp)
18408 {
18409   vat_main_t *vam = &vat_main;
18410   vat_json_node_t *node = NULL;
18411   u8 *sw_if_from_name = 0;
18412   u8 *sw_if_to_name = 0;
18413   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18414   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18415   hash_pair_t *p;
18416
18417   /* *INDENT-OFF* */
18418   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18419   ({
18420     if ((u32) p->value[0] == sw_if_index_from)
18421       {
18422         sw_if_from_name = (u8 *)(p->key);
18423         if (sw_if_to_name)
18424           break;
18425       }
18426     if ((u32) p->value[0] == sw_if_index_to)
18427       {
18428         sw_if_to_name = (u8 *)(p->key);
18429         if (sw_if_from_name)
18430           break;
18431       }
18432   }));
18433   /* *INDENT-ON* */
18434
18435   if (VAT_JSON_ARRAY != vam->json_tree.type)
18436     {
18437       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18438       vat_json_init_array (&vam->json_tree);
18439     }
18440   node = vat_json_array_add (&vam->json_tree);
18441
18442   vat_json_init_object (node);
18443   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
18444   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
18445   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
18446   if (0 != sw_if_to_name)
18447     {
18448       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
18449     }
18450   vat_json_object_add_uint (node, "state", mp->state);
18451   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
18452 }
18453
18454 static int
18455 api_sw_interface_span_dump (vat_main_t * vam)
18456 {
18457   unformat_input_t *input = vam->input;
18458   vl_api_sw_interface_span_dump_t *mp;
18459   vl_api_control_ping_t *mp_ping;
18460   u8 is_l2 = 0;
18461   int ret;
18462
18463   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18464     {
18465       if (unformat (input, "l2"))
18466         is_l2 = 1;
18467       else
18468         break;
18469     }
18470
18471   M (SW_INTERFACE_SPAN_DUMP, mp);
18472   mp->is_l2 = is_l2;
18473   S (mp);
18474
18475   /* Use a control ping for synchronization */
18476   MPING (CONTROL_PING, mp_ping);
18477   S (mp_ping);
18478
18479   W (ret);
18480   return ret;
18481 }
18482
18483 int
18484 api_pg_create_interface (vat_main_t * vam)
18485 {
18486   unformat_input_t *input = vam->input;
18487   vl_api_pg_create_interface_t *mp;
18488
18489   u32 if_id = ~0, gso_size = 0;
18490   u8 gso_enabled = 0;
18491   int ret;
18492   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18493     {
18494       if (unformat (input, "if_id %d", &if_id))
18495         ;
18496       else if (unformat (input, "gso-enabled"))
18497         {
18498           gso_enabled = 1;
18499           if (unformat (input, "gso-size %u", &gso_size))
18500             ;
18501           else
18502             {
18503               errmsg ("missing gso-size");
18504               return -99;
18505             }
18506         }
18507       else
18508         break;
18509     }
18510   if (if_id == ~0)
18511     {
18512       errmsg ("missing pg interface index");
18513       return -99;
18514     }
18515
18516   /* Construct the API message */
18517   M (PG_CREATE_INTERFACE, mp);
18518   mp->context = 0;
18519   mp->interface_id = ntohl (if_id);
18520   mp->gso_enabled = gso_enabled;
18521
18522   S (mp);
18523   W (ret);
18524   return ret;
18525 }
18526
18527 int
18528 api_pg_capture (vat_main_t * vam)
18529 {
18530   unformat_input_t *input = vam->input;
18531   vl_api_pg_capture_t *mp;
18532
18533   u32 if_id = ~0;
18534   u8 enable = 1;
18535   u32 count = 1;
18536   u8 pcap_file_set = 0;
18537   u8 *pcap_file = 0;
18538   int ret;
18539   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18540     {
18541       if (unformat (input, "if_id %d", &if_id))
18542         ;
18543       else if (unformat (input, "pcap %s", &pcap_file))
18544         pcap_file_set = 1;
18545       else if (unformat (input, "count %d", &count))
18546         ;
18547       else if (unformat (input, "disable"))
18548         enable = 0;
18549       else
18550         break;
18551     }
18552   if (if_id == ~0)
18553     {
18554       errmsg ("missing pg interface index");
18555       return -99;
18556     }
18557   if (pcap_file_set > 0)
18558     {
18559       if (vec_len (pcap_file) > 255)
18560         {
18561           errmsg ("pcap file name is too long");
18562           return -99;
18563         }
18564     }
18565
18566   /* Construct the API message */
18567   M (PG_CAPTURE, mp);
18568   mp->context = 0;
18569   mp->interface_id = ntohl (if_id);
18570   mp->is_enabled = enable;
18571   mp->count = ntohl (count);
18572   if (pcap_file_set != 0)
18573     {
18574       vl_api_vec_to_api_string (pcap_file, &mp->pcap_file_name);
18575     }
18576   vec_free (pcap_file);
18577
18578   S (mp);
18579   W (ret);
18580   return ret;
18581 }
18582
18583 int
18584 api_pg_enable_disable (vat_main_t * vam)
18585 {
18586   unformat_input_t *input = vam->input;
18587   vl_api_pg_enable_disable_t *mp;
18588
18589   u8 enable = 1;
18590   u8 stream_name_set = 0;
18591   u8 *stream_name = 0;
18592   int ret;
18593   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18594     {
18595       if (unformat (input, "stream %s", &stream_name))
18596         stream_name_set = 1;
18597       else if (unformat (input, "disable"))
18598         enable = 0;
18599       else
18600         break;
18601     }
18602
18603   if (stream_name_set > 0)
18604     {
18605       if (vec_len (stream_name) > 255)
18606         {
18607           errmsg ("stream name too long");
18608           return -99;
18609         }
18610     }
18611
18612   /* Construct the API message */
18613   M (PG_ENABLE_DISABLE, mp);
18614   mp->context = 0;
18615   mp->is_enabled = enable;
18616   if (stream_name_set != 0)
18617     {
18618       vl_api_vec_to_api_string (stream_name, &mp->stream_name);
18619     }
18620   vec_free (stream_name);
18621
18622   S (mp);
18623   W (ret);
18624   return ret;
18625 }
18626
18627 int
18628 api_pg_interface_enable_disable_coalesce (vat_main_t * vam)
18629 {
18630   unformat_input_t *input = vam->input;
18631   vl_api_pg_interface_enable_disable_coalesce_t *mp;
18632
18633   u32 sw_if_index = ~0;
18634   u8 enable = 1;
18635   int ret;
18636   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18637     {
18638       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18639         ;
18640       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18641         ;
18642       else if (unformat (input, "disable"))
18643         enable = 0;
18644       else
18645         break;
18646     }
18647
18648   if (sw_if_index == ~0)
18649     {
18650       errmsg ("Interface required but not specified");
18651       return -99;
18652     }
18653
18654   /* Construct the API message */
18655   M (PG_INTERFACE_ENABLE_DISABLE_COALESCE, mp);
18656   mp->context = 0;
18657   mp->coalesce_enabled = enable;
18658   mp->sw_if_index = htonl (sw_if_index);
18659
18660   S (mp);
18661   W (ret);
18662   return ret;
18663 }
18664
18665 int
18666 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
18667 {
18668   unformat_input_t *input = vam->input;
18669   vl_api_ip_source_and_port_range_check_add_del_t *mp;
18670
18671   u16 *low_ports = 0;
18672   u16 *high_ports = 0;
18673   u16 this_low;
18674   u16 this_hi;
18675   vl_api_prefix_t prefix;
18676   u32 tmp, tmp2;
18677   u8 prefix_set = 0;
18678   u32 vrf_id = ~0;
18679   u8 is_add = 1;
18680   int ret;
18681
18682   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18683     {
18684       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
18685         prefix_set = 1;
18686       else if (unformat (input, "vrf %d", &vrf_id))
18687         ;
18688       else if (unformat (input, "del"))
18689         is_add = 0;
18690       else if (unformat (input, "port %d", &tmp))
18691         {
18692           if (tmp == 0 || tmp > 65535)
18693             {
18694               errmsg ("port %d out of range", tmp);
18695               return -99;
18696             }
18697           this_low = tmp;
18698           this_hi = this_low + 1;
18699           vec_add1 (low_ports, this_low);
18700           vec_add1 (high_ports, this_hi);
18701         }
18702       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
18703         {
18704           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
18705             {
18706               errmsg ("incorrect range parameters");
18707               return -99;
18708             }
18709           this_low = tmp;
18710           /* Note: in debug CLI +1 is added to high before
18711              passing to real fn that does "the work"
18712              (ip_source_and_port_range_check_add_del).
18713              This fn is a wrapper around the binary API fn a
18714              control plane will call, which expects this increment
18715              to have occurred. Hence letting the binary API control
18716              plane fn do the increment for consistency between VAT
18717              and other control planes.
18718            */
18719           this_hi = tmp2;
18720           vec_add1 (low_ports, this_low);
18721           vec_add1 (high_ports, this_hi);
18722         }
18723       else
18724         break;
18725     }
18726
18727   if (prefix_set == 0)
18728     {
18729       errmsg ("<address>/<mask> not specified");
18730       return -99;
18731     }
18732
18733   if (vrf_id == ~0)
18734     {
18735       errmsg ("VRF ID required, not specified");
18736       return -99;
18737     }
18738
18739   if (vrf_id == 0)
18740     {
18741       errmsg
18742         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18743       return -99;
18744     }
18745
18746   if (vec_len (low_ports) == 0)
18747     {
18748       errmsg ("At least one port or port range required");
18749       return -99;
18750     }
18751
18752   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
18753
18754   mp->is_add = is_add;
18755
18756   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
18757
18758   mp->number_of_ranges = vec_len (low_ports);
18759
18760   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
18761   vec_free (low_ports);
18762
18763   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
18764   vec_free (high_ports);
18765
18766   mp->vrf_id = ntohl (vrf_id);
18767
18768   S (mp);
18769   W (ret);
18770   return ret;
18771 }
18772
18773 int
18774 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
18775 {
18776   unformat_input_t *input = vam->input;
18777   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
18778   u32 sw_if_index = ~0;
18779   int vrf_set = 0;
18780   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
18781   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
18782   u8 is_add = 1;
18783   int ret;
18784
18785   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18786     {
18787       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18788         ;
18789       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18790         ;
18791       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
18792         vrf_set = 1;
18793       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
18794         vrf_set = 1;
18795       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
18796         vrf_set = 1;
18797       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
18798         vrf_set = 1;
18799       else if (unformat (input, "del"))
18800         is_add = 0;
18801       else
18802         break;
18803     }
18804
18805   if (sw_if_index == ~0)
18806     {
18807       errmsg ("Interface required but not specified");
18808       return -99;
18809     }
18810
18811   if (vrf_set == 0)
18812     {
18813       errmsg ("VRF ID required but not specified");
18814       return -99;
18815     }
18816
18817   if (tcp_out_vrf_id == 0
18818       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
18819     {
18820       errmsg
18821         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18822       return -99;
18823     }
18824
18825   /* Construct the API message */
18826   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
18827
18828   mp->sw_if_index = ntohl (sw_if_index);
18829   mp->is_add = is_add;
18830   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
18831   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
18832   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
18833   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
18834
18835   /* send it... */
18836   S (mp);
18837
18838   /* Wait for a reply... */
18839   W (ret);
18840   return ret;
18841 }
18842
18843 static int
18844 api_set_punt (vat_main_t * vam)
18845 {
18846   unformat_input_t *i = vam->input;
18847   vl_api_address_family_t af;
18848   vl_api_set_punt_t *mp;
18849   u32 protocol = ~0;
18850   u32 port = ~0;
18851   int is_add = 1;
18852   int ret;
18853
18854   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18855     {
18856       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
18857         ;
18858       else if (unformat (i, "protocol %d", &protocol))
18859         ;
18860       else if (unformat (i, "port %d", &port))
18861         ;
18862       else if (unformat (i, "del"))
18863         is_add = 0;
18864       else
18865         {
18866           clib_warning ("parse error '%U'", format_unformat_error, i);
18867           return -99;
18868         }
18869     }
18870
18871   M (SET_PUNT, mp);
18872
18873   mp->is_add = (u8) is_add;
18874   mp->punt.type = PUNT_API_TYPE_L4;
18875   mp->punt.punt.l4.af = af;
18876   mp->punt.punt.l4.protocol = (u8) protocol;
18877   mp->punt.punt.l4.port = htons ((u16) port);
18878
18879   S (mp);
18880   W (ret);
18881   return ret;
18882 }
18883
18884 static int
18885 api_delete_subif (vat_main_t * vam)
18886 {
18887   unformat_input_t *i = vam->input;
18888   vl_api_delete_subif_t *mp;
18889   u32 sw_if_index = ~0;
18890   int ret;
18891
18892   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18893     {
18894       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18895         ;
18896       if (unformat (i, "sw_if_index %d", &sw_if_index))
18897         ;
18898       else
18899         break;
18900     }
18901
18902   if (sw_if_index == ~0)
18903     {
18904       errmsg ("missing sw_if_index");
18905       return -99;
18906     }
18907
18908   /* Construct the API message */
18909   M (DELETE_SUBIF, mp);
18910   mp->sw_if_index = ntohl (sw_if_index);
18911
18912   S (mp);
18913   W (ret);
18914   return ret;
18915 }
18916
18917 #define foreach_pbb_vtr_op      \
18918 _("disable",  L2_VTR_DISABLED)  \
18919 _("pop",  L2_VTR_POP_2)         \
18920 _("push",  L2_VTR_PUSH_2)
18921
18922 static int
18923 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
18924 {
18925   unformat_input_t *i = vam->input;
18926   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
18927   u32 sw_if_index = ~0, vtr_op = ~0;
18928   u16 outer_tag = ~0;
18929   u8 dmac[6], smac[6];
18930   u8 dmac_set = 0, smac_set = 0;
18931   u16 vlanid = 0;
18932   u32 sid = ~0;
18933   u32 tmp;
18934   int ret;
18935
18936   /* Shut up coverity */
18937   clib_memset (dmac, 0, sizeof (dmac));
18938   clib_memset (smac, 0, sizeof (smac));
18939
18940   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18941     {
18942       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18943         ;
18944       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18945         ;
18946       else if (unformat (i, "vtr_op %d", &vtr_op))
18947         ;
18948 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
18949       foreach_pbb_vtr_op
18950 #undef _
18951         else if (unformat (i, "translate_pbb_stag"))
18952         {
18953           if (unformat (i, "%d", &tmp))
18954             {
18955               vtr_op = L2_VTR_TRANSLATE_2_1;
18956               outer_tag = tmp;
18957             }
18958           else
18959             {
18960               errmsg
18961                 ("translate_pbb_stag operation requires outer tag definition");
18962               return -99;
18963             }
18964         }
18965       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
18966         dmac_set++;
18967       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
18968         smac_set++;
18969       else if (unformat (i, "sid %d", &sid))
18970         ;
18971       else if (unformat (i, "vlanid %d", &tmp))
18972         vlanid = tmp;
18973       else
18974         {
18975           clib_warning ("parse error '%U'", format_unformat_error, i);
18976           return -99;
18977         }
18978     }
18979
18980   if ((sw_if_index == ~0) || (vtr_op == ~0))
18981     {
18982       errmsg ("missing sw_if_index or vtr operation");
18983       return -99;
18984     }
18985   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
18986       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
18987     {
18988       errmsg
18989         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
18990       return -99;
18991     }
18992
18993   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
18994   mp->sw_if_index = ntohl (sw_if_index);
18995   mp->vtr_op = ntohl (vtr_op);
18996   mp->outer_tag = ntohs (outer_tag);
18997   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
18998   clib_memcpy (mp->b_smac, smac, sizeof (smac));
18999   mp->b_vlanid = ntohs (vlanid);
19000   mp->i_sid = ntohl (sid);
19001
19002   S (mp);
19003   W (ret);
19004   return ret;
19005 }
19006
19007 static int
19008 api_flow_classify_set_interface (vat_main_t * vam)
19009 {
19010   unformat_input_t *i = vam->input;
19011   vl_api_flow_classify_set_interface_t *mp;
19012   u32 sw_if_index;
19013   int sw_if_index_set;
19014   u32 ip4_table_index = ~0;
19015   u32 ip6_table_index = ~0;
19016   u8 is_add = 1;
19017   int ret;
19018
19019   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19020     {
19021       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19022         sw_if_index_set = 1;
19023       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19024         sw_if_index_set = 1;
19025       else if (unformat (i, "del"))
19026         is_add = 0;
19027       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19028         ;
19029       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19030         ;
19031       else
19032         {
19033           clib_warning ("parse error '%U'", format_unformat_error, i);
19034           return -99;
19035         }
19036     }
19037
19038   if (sw_if_index_set == 0)
19039     {
19040       errmsg ("missing interface name or sw_if_index");
19041       return -99;
19042     }
19043
19044   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
19045
19046   mp->sw_if_index = ntohl (sw_if_index);
19047   mp->ip4_table_index = ntohl (ip4_table_index);
19048   mp->ip6_table_index = ntohl (ip6_table_index);
19049   mp->is_add = is_add;
19050
19051   S (mp);
19052   W (ret);
19053   return ret;
19054 }
19055
19056 static int
19057 api_flow_classify_dump (vat_main_t * vam)
19058 {
19059   unformat_input_t *i = vam->input;
19060   vl_api_flow_classify_dump_t *mp;
19061   vl_api_control_ping_t *mp_ping;
19062   u8 type = FLOW_CLASSIFY_N_TABLES;
19063   int ret;
19064
19065   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
19066     ;
19067   else
19068     {
19069       errmsg ("classify table type must be specified");
19070       return -99;
19071     }
19072
19073   if (!vam->json_output)
19074     {
19075       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19076     }
19077
19078   M (FLOW_CLASSIFY_DUMP, mp);
19079   mp->type = type;
19080   /* send it... */
19081   S (mp);
19082
19083   /* Use a control ping for synchronization */
19084   MPING (CONTROL_PING, mp_ping);
19085   S (mp_ping);
19086
19087   /* Wait for a reply... */
19088   W (ret);
19089   return ret;
19090 }
19091
19092 static int
19093 api_feature_enable_disable (vat_main_t * vam)
19094 {
19095   unformat_input_t *i = vam->input;
19096   vl_api_feature_enable_disable_t *mp;
19097   u8 *arc_name = 0;
19098   u8 *feature_name = 0;
19099   u32 sw_if_index = ~0;
19100   u8 enable = 1;
19101   int ret;
19102
19103   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19104     {
19105       if (unformat (i, "arc_name %s", &arc_name))
19106         ;
19107       else if (unformat (i, "feature_name %s", &feature_name))
19108         ;
19109       else
19110         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19111         ;
19112       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19113         ;
19114       else if (unformat (i, "disable"))
19115         enable = 0;
19116       else
19117         break;
19118     }
19119
19120   if (arc_name == 0)
19121     {
19122       errmsg ("missing arc name");
19123       return -99;
19124     }
19125   if (vec_len (arc_name) > 63)
19126     {
19127       errmsg ("arc name too long");
19128     }
19129
19130   if (feature_name == 0)
19131     {
19132       errmsg ("missing feature name");
19133       return -99;
19134     }
19135   if (vec_len (feature_name) > 63)
19136     {
19137       errmsg ("feature name too long");
19138     }
19139
19140   if (sw_if_index == ~0)
19141     {
19142       errmsg ("missing interface name or sw_if_index");
19143       return -99;
19144     }
19145
19146   /* Construct the API message */
19147   M (FEATURE_ENABLE_DISABLE, mp);
19148   mp->sw_if_index = ntohl (sw_if_index);
19149   mp->enable = enable;
19150   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
19151   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
19152   vec_free (arc_name);
19153   vec_free (feature_name);
19154
19155   S (mp);
19156   W (ret);
19157   return ret;
19158 }
19159
19160 static int
19161 api_feature_gso_enable_disable (vat_main_t * vam)
19162 {
19163   unformat_input_t *i = vam->input;
19164   vl_api_feature_gso_enable_disable_t *mp;
19165   u32 sw_if_index = ~0;
19166   u8 enable = 1;
19167   int ret;
19168
19169   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19170     {
19171       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19172         ;
19173       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19174         ;
19175       else if (unformat (i, "enable"))
19176         enable = 1;
19177       else if (unformat (i, "disable"))
19178         enable = 0;
19179       else
19180         break;
19181     }
19182
19183   if (sw_if_index == ~0)
19184     {
19185       errmsg ("missing interface name or sw_if_index");
19186       return -99;
19187     }
19188
19189   /* Construct the API message */
19190   M (FEATURE_GSO_ENABLE_DISABLE, mp);
19191   mp->sw_if_index = ntohl (sw_if_index);
19192   mp->enable_disable = enable;
19193
19194   S (mp);
19195   W (ret);
19196   return ret;
19197 }
19198
19199 static int
19200 api_sw_interface_tag_add_del (vat_main_t * vam)
19201 {
19202   unformat_input_t *i = vam->input;
19203   vl_api_sw_interface_tag_add_del_t *mp;
19204   u32 sw_if_index = ~0;
19205   u8 *tag = 0;
19206   u8 enable = 1;
19207   int ret;
19208
19209   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19210     {
19211       if (unformat (i, "tag %s", &tag))
19212         ;
19213       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19214         ;
19215       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19216         ;
19217       else if (unformat (i, "del"))
19218         enable = 0;
19219       else
19220         break;
19221     }
19222
19223   if (sw_if_index == ~0)
19224     {
19225       errmsg ("missing interface name or sw_if_index");
19226       return -99;
19227     }
19228
19229   if (enable && (tag == 0))
19230     {
19231       errmsg ("no tag specified");
19232       return -99;
19233     }
19234
19235   /* Construct the API message */
19236   M (SW_INTERFACE_TAG_ADD_DEL, mp);
19237   mp->sw_if_index = ntohl (sw_if_index);
19238   mp->is_add = enable;
19239   if (enable)
19240     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
19241   vec_free (tag);
19242
19243   S (mp);
19244   W (ret);
19245   return ret;
19246 }
19247
19248 static int
19249 api_sw_interface_add_del_mac_address (vat_main_t * vam)
19250 {
19251   unformat_input_t *i = vam->input;
19252   vl_api_mac_address_t mac = { 0 };
19253   vl_api_sw_interface_add_del_mac_address_t *mp;
19254   u32 sw_if_index = ~0;
19255   u8 is_add = 1;
19256   u8 mac_set = 0;
19257   int ret;
19258
19259   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19260     {
19261       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19262         ;
19263       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19264         ;
19265       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
19266         mac_set++;
19267       else if (unformat (i, "del"))
19268         is_add = 0;
19269       else
19270         break;
19271     }
19272
19273   if (sw_if_index == ~0)
19274     {
19275       errmsg ("missing interface name or sw_if_index");
19276       return -99;
19277     }
19278
19279   if (!mac_set)
19280     {
19281       errmsg ("missing MAC address");
19282       return -99;
19283     }
19284
19285   /* Construct the API message */
19286   M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
19287   mp->sw_if_index = ntohl (sw_if_index);
19288   mp->is_add = is_add;
19289   clib_memcpy (&mp->addr, &mac, sizeof (mac));
19290
19291   S (mp);
19292   W (ret);
19293   return ret;
19294 }
19295
19296 static void vl_api_l2_xconnect_details_t_handler
19297   (vl_api_l2_xconnect_details_t * mp)
19298 {
19299   vat_main_t *vam = &vat_main;
19300
19301   print (vam->ofp, "%15d%15d",
19302          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
19303 }
19304
19305 static void vl_api_l2_xconnect_details_t_handler_json
19306   (vl_api_l2_xconnect_details_t * mp)
19307 {
19308   vat_main_t *vam = &vat_main;
19309   vat_json_node_t *node = NULL;
19310
19311   if (VAT_JSON_ARRAY != vam->json_tree.type)
19312     {
19313       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19314       vat_json_init_array (&vam->json_tree);
19315     }
19316   node = vat_json_array_add (&vam->json_tree);
19317
19318   vat_json_init_object (node);
19319   vat_json_object_add_uint (node, "rx_sw_if_index",
19320                             ntohl (mp->rx_sw_if_index));
19321   vat_json_object_add_uint (node, "tx_sw_if_index",
19322                             ntohl (mp->tx_sw_if_index));
19323 }
19324
19325 static int
19326 api_l2_xconnect_dump (vat_main_t * vam)
19327 {
19328   vl_api_l2_xconnect_dump_t *mp;
19329   vl_api_control_ping_t *mp_ping;
19330   int ret;
19331
19332   if (!vam->json_output)
19333     {
19334       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
19335     }
19336
19337   M (L2_XCONNECT_DUMP, mp);
19338
19339   S (mp);
19340
19341   /* Use a control ping for synchronization */
19342   MPING (CONTROL_PING, mp_ping);
19343   S (mp_ping);
19344
19345   W (ret);
19346   return ret;
19347 }
19348
19349 static int
19350 api_hw_interface_set_mtu (vat_main_t * vam)
19351 {
19352   unformat_input_t *i = vam->input;
19353   vl_api_hw_interface_set_mtu_t *mp;
19354   u32 sw_if_index = ~0;
19355   u32 mtu = 0;
19356   int ret;
19357
19358   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19359     {
19360       if (unformat (i, "mtu %d", &mtu))
19361         ;
19362       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19363         ;
19364       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19365         ;
19366       else
19367         break;
19368     }
19369
19370   if (sw_if_index == ~0)
19371     {
19372       errmsg ("missing interface name or sw_if_index");
19373       return -99;
19374     }
19375
19376   if (mtu == 0)
19377     {
19378       errmsg ("no mtu specified");
19379       return -99;
19380     }
19381
19382   /* Construct the API message */
19383   M (HW_INTERFACE_SET_MTU, mp);
19384   mp->sw_if_index = ntohl (sw_if_index);
19385   mp->mtu = ntohs ((u16) mtu);
19386
19387   S (mp);
19388   W (ret);
19389   return ret;
19390 }
19391
19392 static int
19393 api_p2p_ethernet_add (vat_main_t * vam)
19394 {
19395   unformat_input_t *i = vam->input;
19396   vl_api_p2p_ethernet_add_t *mp;
19397   u32 parent_if_index = ~0;
19398   u32 sub_id = ~0;
19399   u8 remote_mac[6];
19400   u8 mac_set = 0;
19401   int ret;
19402
19403   clib_memset (remote_mac, 0, sizeof (remote_mac));
19404   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19405     {
19406       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19407         ;
19408       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19409         ;
19410       else
19411         if (unformat
19412             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19413         mac_set++;
19414       else if (unformat (i, "sub_id %d", &sub_id))
19415         ;
19416       else
19417         {
19418           clib_warning ("parse error '%U'", format_unformat_error, i);
19419           return -99;
19420         }
19421     }
19422
19423   if (parent_if_index == ~0)
19424     {
19425       errmsg ("missing interface name or sw_if_index");
19426       return -99;
19427     }
19428   if (mac_set == 0)
19429     {
19430       errmsg ("missing remote mac address");
19431       return -99;
19432     }
19433   if (sub_id == ~0)
19434     {
19435       errmsg ("missing sub-interface id");
19436       return -99;
19437     }
19438
19439   M (P2P_ETHERNET_ADD, mp);
19440   mp->parent_if_index = ntohl (parent_if_index);
19441   mp->subif_id = ntohl (sub_id);
19442   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19443
19444   S (mp);
19445   W (ret);
19446   return ret;
19447 }
19448
19449 static int
19450 api_p2p_ethernet_del (vat_main_t * vam)
19451 {
19452   unformat_input_t *i = vam->input;
19453   vl_api_p2p_ethernet_del_t *mp;
19454   u32 parent_if_index = ~0;
19455   u8 remote_mac[6];
19456   u8 mac_set = 0;
19457   int ret;
19458
19459   clib_memset (remote_mac, 0, sizeof (remote_mac));
19460   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19461     {
19462       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19463         ;
19464       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19465         ;
19466       else
19467         if (unformat
19468             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19469         mac_set++;
19470       else
19471         {
19472           clib_warning ("parse error '%U'", format_unformat_error, i);
19473           return -99;
19474         }
19475     }
19476
19477   if (parent_if_index == ~0)
19478     {
19479       errmsg ("missing interface name or sw_if_index");
19480       return -99;
19481     }
19482   if (mac_set == 0)
19483     {
19484       errmsg ("missing remote mac address");
19485       return -99;
19486     }
19487
19488   M (P2P_ETHERNET_DEL, mp);
19489   mp->parent_if_index = ntohl (parent_if_index);
19490   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19491
19492   S (mp);
19493   W (ret);
19494   return ret;
19495 }
19496
19497 static int
19498 api_lldp_config (vat_main_t * vam)
19499 {
19500   unformat_input_t *i = vam->input;
19501   vl_api_lldp_config_t *mp;
19502   int tx_hold = 0;
19503   int tx_interval = 0;
19504   u8 *sys_name = NULL;
19505   int ret;
19506
19507   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19508     {
19509       if (unformat (i, "system-name %s", &sys_name))
19510         ;
19511       else if (unformat (i, "tx-hold %d", &tx_hold))
19512         ;
19513       else if (unformat (i, "tx-interval %d", &tx_interval))
19514         ;
19515       else
19516         {
19517           clib_warning ("parse error '%U'", format_unformat_error, i);
19518           return -99;
19519         }
19520     }
19521
19522   vec_add1 (sys_name, 0);
19523
19524   M (LLDP_CONFIG, mp);
19525   mp->tx_hold = htonl (tx_hold);
19526   mp->tx_interval = htonl (tx_interval);
19527   vl_api_vec_to_api_string (sys_name, &mp->system_name);
19528   vec_free (sys_name);
19529
19530   S (mp);
19531   W (ret);
19532   return ret;
19533 }
19534
19535 static int
19536 api_sw_interface_set_lldp (vat_main_t * vam)
19537 {
19538   unformat_input_t *i = vam->input;
19539   vl_api_sw_interface_set_lldp_t *mp;
19540   u32 sw_if_index = ~0;
19541   u32 enable = 1;
19542   u8 *port_desc = NULL, *mgmt_oid = NULL;
19543   ip4_address_t ip4_addr;
19544   ip6_address_t ip6_addr;
19545   int ret;
19546
19547   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
19548   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
19549
19550   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19551     {
19552       if (unformat (i, "disable"))
19553         enable = 0;
19554       else
19555         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19556         ;
19557       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19558         ;
19559       else if (unformat (i, "port-desc %s", &port_desc))
19560         ;
19561       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
19562         ;
19563       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
19564         ;
19565       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
19566         ;
19567       else
19568         break;
19569     }
19570
19571   if (sw_if_index == ~0)
19572     {
19573       errmsg ("missing interface name or sw_if_index");
19574       return -99;
19575     }
19576
19577   /* Construct the API message */
19578   vec_add1 (port_desc, 0);
19579   vec_add1 (mgmt_oid, 0);
19580   M (SW_INTERFACE_SET_LLDP, mp);
19581   mp->sw_if_index = ntohl (sw_if_index);
19582   mp->enable = enable;
19583   vl_api_vec_to_api_string (port_desc, &mp->port_desc);
19584   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
19585   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
19586   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
19587   vec_free (port_desc);
19588   vec_free (mgmt_oid);
19589
19590   S (mp);
19591   W (ret);
19592   return ret;
19593 }
19594
19595 static int
19596 api_tcp_configure_src_addresses (vat_main_t * vam)
19597 {
19598   vl_api_tcp_configure_src_addresses_t *mp;
19599   unformat_input_t *i = vam->input;
19600   vl_api_address_t first, last;
19601   u8 range_set = 0;
19602   u32 vrf_id = 0;
19603   int ret;
19604
19605   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19606     {
19607       if (unformat (i, "%U - %U",
19608                     unformat_vl_api_address, &first,
19609                     unformat_vl_api_address, &last))
19610         {
19611           if (range_set)
19612             {
19613               errmsg ("one range per message (range already set)");
19614               return -99;
19615             }
19616           range_set = 1;
19617         }
19618       else if (unformat (i, "vrf %d", &vrf_id))
19619         ;
19620       else
19621         break;
19622     }
19623
19624   if (range_set == 0)
19625     {
19626       errmsg ("address range not set");
19627       return -99;
19628     }
19629
19630   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
19631
19632   mp->vrf_id = ntohl (vrf_id);
19633   clib_memcpy (&mp->first_address, &first, sizeof (first));
19634   clib_memcpy (&mp->last_address, &last, sizeof (last));
19635
19636   S (mp);
19637   W (ret);
19638   return ret;
19639 }
19640
19641 static void vl_api_app_namespace_add_del_reply_t_handler
19642   (vl_api_app_namespace_add_del_reply_t * mp)
19643 {
19644   vat_main_t *vam = &vat_main;
19645   i32 retval = ntohl (mp->retval);
19646   if (vam->async_mode)
19647     {
19648       vam->async_errors += (retval < 0);
19649     }
19650   else
19651     {
19652       vam->retval = retval;
19653       if (retval == 0)
19654         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
19655       vam->result_ready = 1;
19656     }
19657 }
19658
19659 static void vl_api_app_namespace_add_del_reply_t_handler_json
19660   (vl_api_app_namespace_add_del_reply_t * mp)
19661 {
19662   vat_main_t *vam = &vat_main;
19663   vat_json_node_t node;
19664
19665   vat_json_init_object (&node);
19666   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
19667   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
19668
19669   vat_json_print (vam->ofp, &node);
19670   vat_json_free (&node);
19671
19672   vam->retval = ntohl (mp->retval);
19673   vam->result_ready = 1;
19674 }
19675
19676 static int
19677 api_app_namespace_add_del (vat_main_t * vam)
19678 {
19679   vl_api_app_namespace_add_del_t *mp;
19680   unformat_input_t *i = vam->input;
19681   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
19682   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
19683   u64 secret;
19684   int ret;
19685
19686   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19687     {
19688       if (unformat (i, "id %_%v%_", &ns_id))
19689         ;
19690       else if (unformat (i, "secret %lu", &secret))
19691         secret_set = 1;
19692       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19693         sw_if_index_set = 1;
19694       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
19695         ;
19696       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
19697         ;
19698       else
19699         break;
19700     }
19701   if (!ns_id || !secret_set || !sw_if_index_set)
19702     {
19703       errmsg ("namespace id, secret and sw_if_index must be set");
19704       return -99;
19705     }
19706   if (vec_len (ns_id) > 64)
19707     {
19708       errmsg ("namespace id too long");
19709       return -99;
19710     }
19711   M (APP_NAMESPACE_ADD_DEL, mp);
19712
19713   vl_api_vec_to_api_string (ns_id, &mp->namespace_id);
19714   mp->secret = clib_host_to_net_u64 (secret);
19715   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
19716   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
19717   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
19718   vec_free (ns_id);
19719   S (mp);
19720   W (ret);
19721   return ret;
19722 }
19723
19724 static int
19725 api_sock_init_shm (vat_main_t * vam)
19726 {
19727 #if VPP_API_TEST_BUILTIN == 0
19728   unformat_input_t *i = vam->input;
19729   vl_api_shm_elem_config_t *config = 0;
19730   u64 size = 64 << 20;
19731   int rv;
19732
19733   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19734     {
19735       if (unformat (i, "size %U", unformat_memory_size, &size))
19736         ;
19737       else
19738         break;
19739     }
19740
19741   /*
19742    * Canned custom ring allocator config.
19743    * Should probably parse all of this
19744    */
19745   vec_validate (config, 6);
19746   config[0].type = VL_API_VLIB_RING;
19747   config[0].size = 256;
19748   config[0].count = 32;
19749
19750   config[1].type = VL_API_VLIB_RING;
19751   config[1].size = 1024;
19752   config[1].count = 16;
19753
19754   config[2].type = VL_API_VLIB_RING;
19755   config[2].size = 4096;
19756   config[2].count = 2;
19757
19758   config[3].type = VL_API_CLIENT_RING;
19759   config[3].size = 256;
19760   config[3].count = 32;
19761
19762   config[4].type = VL_API_CLIENT_RING;
19763   config[4].size = 1024;
19764   config[4].count = 16;
19765
19766   config[5].type = VL_API_CLIENT_RING;
19767   config[5].size = 4096;
19768   config[5].count = 2;
19769
19770   config[6].type = VL_API_QUEUE;
19771   config[6].count = 128;
19772   config[6].size = sizeof (uword);
19773
19774   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
19775   if (!rv)
19776     vam->client_index_invalid = 1;
19777   return rv;
19778 #else
19779   return -99;
19780 #endif
19781 }
19782
19783 static void
19784 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
19785 {
19786   vat_main_t *vam = &vat_main;
19787   fib_prefix_t lcl, rmt;
19788
19789   ip_prefix_decode (&mp->lcl, &lcl);
19790   ip_prefix_decode (&mp->rmt, &rmt);
19791
19792   if (lcl.fp_proto == FIB_PROTOCOL_IP4)
19793     {
19794       print (vam->ofp,
19795              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19796              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19797              mp->scope, format_ip4_address, &lcl.fp_addr.ip4, lcl.fp_len,
19798              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
19799              &rmt.fp_addr.ip4, rmt.fp_len,
19800              clib_net_to_host_u16 (mp->rmt_port),
19801              clib_net_to_host_u32 (mp->action_index), mp->tag);
19802     }
19803   else
19804     {
19805       print (vam->ofp,
19806              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19807              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19808              mp->scope, format_ip6_address, &lcl.fp_addr.ip6, lcl.fp_len,
19809              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
19810              &rmt.fp_addr.ip6, rmt.fp_len,
19811              clib_net_to_host_u16 (mp->rmt_port),
19812              clib_net_to_host_u32 (mp->action_index), mp->tag);
19813     }
19814 }
19815
19816 static void
19817 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
19818                                              mp)
19819 {
19820   vat_main_t *vam = &vat_main;
19821   vat_json_node_t *node = NULL;
19822   struct in6_addr ip6;
19823   struct in_addr ip4;
19824
19825   fib_prefix_t lcl, rmt;
19826
19827   ip_prefix_decode (&mp->lcl, &lcl);
19828   ip_prefix_decode (&mp->rmt, &rmt);
19829
19830   if (VAT_JSON_ARRAY != vam->json_tree.type)
19831     {
19832       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19833       vat_json_init_array (&vam->json_tree);
19834     }
19835   node = vat_json_array_add (&vam->json_tree);
19836   vat_json_init_object (node);
19837
19838   vat_json_object_add_uint (node, "appns_index",
19839                             clib_net_to_host_u32 (mp->appns_index));
19840   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
19841   vat_json_object_add_uint (node, "scope", mp->scope);
19842   vat_json_object_add_uint (node, "action_index",
19843                             clib_net_to_host_u32 (mp->action_index));
19844   vat_json_object_add_uint (node, "lcl_port",
19845                             clib_net_to_host_u16 (mp->lcl_port));
19846   vat_json_object_add_uint (node, "rmt_port",
19847                             clib_net_to_host_u16 (mp->rmt_port));
19848   vat_json_object_add_uint (node, "lcl_plen", lcl.fp_len);
19849   vat_json_object_add_uint (node, "rmt_plen", rmt.fp_len);
19850   vat_json_object_add_string_copy (node, "tag", mp->tag);
19851   if (lcl.fp_proto == FIB_PROTOCOL_IP4)
19852     {
19853       clib_memcpy (&ip4, &lcl.fp_addr.ip4, sizeof (ip4));
19854       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
19855       clib_memcpy (&ip4, &rmt.fp_addr.ip4, sizeof (ip4));
19856       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
19857     }
19858   else
19859     {
19860       clib_memcpy (&ip6, &lcl.fp_addr.ip6, sizeof (ip6));
19861       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
19862       clib_memcpy (&ip6, &rmt.fp_addr.ip6, sizeof (ip6));
19863       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
19864     }
19865 }
19866
19867 static int
19868 api_session_rule_add_del (vat_main_t * vam)
19869 {
19870   vl_api_session_rule_add_del_t *mp;
19871   unformat_input_t *i = vam->input;
19872   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
19873   u32 appns_index = 0, scope = 0;
19874   ip4_address_t lcl_ip4, rmt_ip4;
19875   ip6_address_t lcl_ip6, rmt_ip6;
19876   u8 is_ip4 = 1, conn_set = 0;
19877   u8 is_add = 1, *tag = 0;
19878   int ret;
19879   fib_prefix_t lcl, rmt;
19880
19881   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19882     {
19883       if (unformat (i, "del"))
19884         is_add = 0;
19885       else if (unformat (i, "add"))
19886         ;
19887       else if (unformat (i, "proto tcp"))
19888         proto = 0;
19889       else if (unformat (i, "proto udp"))
19890         proto = 1;
19891       else if (unformat (i, "appns %d", &appns_index))
19892         ;
19893       else if (unformat (i, "scope %d", &scope))
19894         ;
19895       else if (unformat (i, "tag %_%v%_", &tag))
19896         ;
19897       else
19898         if (unformat
19899             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
19900              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
19901              &rmt_port))
19902         {
19903           is_ip4 = 1;
19904           conn_set = 1;
19905         }
19906       else
19907         if (unformat
19908             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
19909              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
19910              &rmt_port))
19911         {
19912           is_ip4 = 0;
19913           conn_set = 1;
19914         }
19915       else if (unformat (i, "action %d", &action))
19916         ;
19917       else
19918         break;
19919     }
19920   if (proto == ~0 || !conn_set || action == ~0)
19921     {
19922       errmsg ("transport proto, connection and action must be set");
19923       return -99;
19924     }
19925
19926   if (scope > 3)
19927     {
19928       errmsg ("scope should be 0-3");
19929       return -99;
19930     }
19931
19932   M (SESSION_RULE_ADD_DEL, mp);
19933
19934   clib_memset (&lcl, 0, sizeof (lcl));
19935   clib_memset (&rmt, 0, sizeof (rmt));
19936   if (is_ip4)
19937     {
19938       ip_set (&lcl.fp_addr, &lcl_ip4, 1);
19939       ip_set (&rmt.fp_addr, &rmt_ip4, 1);
19940       lcl.fp_len = lcl_plen;
19941       rmt.fp_len = rmt_plen;
19942     }
19943   else
19944     {
19945       ip_set (&lcl.fp_addr, &lcl_ip6, 0);
19946       ip_set (&rmt.fp_addr, &rmt_ip6, 0);
19947       lcl.fp_len = lcl_plen;
19948       rmt.fp_len = rmt_plen;
19949     }
19950
19951
19952   ip_prefix_encode (&lcl, &mp->lcl);
19953   ip_prefix_encode (&rmt, &mp->rmt);
19954   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
19955   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
19956   mp->transport_proto =
19957     proto ? TRANSPORT_PROTO_API_UDP : TRANSPORT_PROTO_API_TCP;
19958   mp->action_index = clib_host_to_net_u32 (action);
19959   mp->appns_index = clib_host_to_net_u32 (appns_index);
19960   mp->scope = scope;
19961   mp->is_add = is_add;
19962   if (tag)
19963     {
19964       clib_memcpy (mp->tag, tag, vec_len (tag));
19965       vec_free (tag);
19966     }
19967
19968   S (mp);
19969   W (ret);
19970   return ret;
19971 }
19972
19973 static int
19974 api_session_rules_dump (vat_main_t * vam)
19975 {
19976   vl_api_session_rules_dump_t *mp;
19977   vl_api_control_ping_t *mp_ping;
19978   int ret;
19979
19980   if (!vam->json_output)
19981     {
19982       print (vam->ofp, "%=20s", "Session Rules");
19983     }
19984
19985   M (SESSION_RULES_DUMP, mp);
19986   /* send it... */
19987   S (mp);
19988
19989   /* Use a control ping for synchronization */
19990   MPING (CONTROL_PING, mp_ping);
19991   S (mp_ping);
19992
19993   /* Wait for a reply... */
19994   W (ret);
19995   return ret;
19996 }
19997
19998 static int
19999 api_ip_container_proxy_add_del (vat_main_t * vam)
20000 {
20001   vl_api_ip_container_proxy_add_del_t *mp;
20002   unformat_input_t *i = vam->input;
20003   u32 sw_if_index = ~0;
20004   vl_api_prefix_t pfx = { };
20005   u8 is_add = 1;
20006   int ret;
20007
20008   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20009     {
20010       if (unformat (i, "del"))
20011         is_add = 0;
20012       else if (unformat (i, "add"))
20013         ;
20014       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
20015         ;
20016       else if (unformat (i, "sw_if_index %u", &sw_if_index))
20017         ;
20018       else
20019         break;
20020     }
20021   if (sw_if_index == ~0 || pfx.len == 0)
20022     {
20023       errmsg ("address and sw_if_index must be set");
20024       return -99;
20025     }
20026
20027   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
20028
20029   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20030   mp->is_add = is_add;
20031   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
20032
20033   S (mp);
20034   W (ret);
20035   return ret;
20036 }
20037
20038 static int
20039 api_qos_record_enable_disable (vat_main_t * vam)
20040 {
20041   unformat_input_t *i = vam->input;
20042   vl_api_qos_record_enable_disable_t *mp;
20043   u32 sw_if_index, qs = 0xff;
20044   u8 sw_if_index_set = 0;
20045   u8 enable = 1;
20046   int ret;
20047
20048   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20049     {
20050       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20051         sw_if_index_set = 1;
20052       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20053         sw_if_index_set = 1;
20054       else if (unformat (i, "%U", unformat_qos_source, &qs))
20055         ;
20056       else if (unformat (i, "disable"))
20057         enable = 0;
20058       else
20059         {
20060           clib_warning ("parse error '%U'", format_unformat_error, i);
20061           return -99;
20062         }
20063     }
20064
20065   if (sw_if_index_set == 0)
20066     {
20067       errmsg ("missing interface name or sw_if_index");
20068       return -99;
20069     }
20070   if (qs == 0xff)
20071     {
20072       errmsg ("input location must be specified");
20073       return -99;
20074     }
20075
20076   M (QOS_RECORD_ENABLE_DISABLE, mp);
20077
20078   mp->record.sw_if_index = ntohl (sw_if_index);
20079   mp->record.input_source = qs;
20080   mp->enable = enable;
20081
20082   S (mp);
20083   W (ret);
20084   return ret;
20085 }
20086
20087
20088 static int
20089 q_or_quit (vat_main_t * vam)
20090 {
20091 #if VPP_API_TEST_BUILTIN == 0
20092   longjmp (vam->jump_buf, 1);
20093 #endif
20094   return 0;                     /* not so much */
20095 }
20096
20097 static int
20098 q (vat_main_t * vam)
20099 {
20100   return q_or_quit (vam);
20101 }
20102
20103 static int
20104 quit (vat_main_t * vam)
20105 {
20106   return q_or_quit (vam);
20107 }
20108
20109 static int
20110 comment (vat_main_t * vam)
20111 {
20112   return 0;
20113 }
20114
20115 static int
20116 elog_save (vat_main_t * vam)
20117 {
20118 #if VPP_API_TEST_BUILTIN == 0
20119   elog_main_t *em = &vam->elog_main;
20120   unformat_input_t *i = vam->input;
20121   char *file, *chroot_file;
20122   clib_error_t *error;
20123
20124   if (!unformat (i, "%s", &file))
20125     {
20126       errmsg ("expected file name, got `%U'", format_unformat_error, i);
20127       return 0;
20128     }
20129
20130   /* It's fairly hard to get "../oopsie" through unformat; just in case */
20131   if (strstr (file, "..") || index (file, '/'))
20132     {
20133       errmsg ("illegal characters in filename '%s'", file);
20134       return 0;
20135     }
20136
20137   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
20138
20139   vec_free (file);
20140
20141   errmsg ("Saving %wd of %wd events to %s",
20142           elog_n_events_in_buffer (em),
20143           elog_buffer_capacity (em), chroot_file);
20144
20145   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
20146   vec_free (chroot_file);
20147
20148   if (error)
20149     clib_error_report (error);
20150 #else
20151   errmsg ("Use the vpp event loger...");
20152 #endif
20153
20154   return 0;
20155 }
20156
20157 static int
20158 elog_setup (vat_main_t * vam)
20159 {
20160 #if VPP_API_TEST_BUILTIN == 0
20161   elog_main_t *em = &vam->elog_main;
20162   unformat_input_t *i = vam->input;
20163   u32 nevents = 128 << 10;
20164
20165   (void) unformat (i, "nevents %d", &nevents);
20166
20167   elog_init (em, nevents);
20168   vl_api_set_elog_main (em);
20169   vl_api_set_elog_trace_api_messages (1);
20170   errmsg ("Event logger initialized with %u events", nevents);
20171 #else
20172   errmsg ("Use the vpp event loger...");
20173 #endif
20174   return 0;
20175 }
20176
20177 static int
20178 elog_enable (vat_main_t * vam)
20179 {
20180 #if VPP_API_TEST_BUILTIN == 0
20181   elog_main_t *em = &vam->elog_main;
20182
20183   elog_enable_disable (em, 1 /* enable */ );
20184   vl_api_set_elog_trace_api_messages (1);
20185   errmsg ("Event logger enabled...");
20186 #else
20187   errmsg ("Use the vpp event loger...");
20188 #endif
20189   return 0;
20190 }
20191
20192 static int
20193 elog_disable (vat_main_t * vam)
20194 {
20195 #if VPP_API_TEST_BUILTIN == 0
20196   elog_main_t *em = &vam->elog_main;
20197
20198   elog_enable_disable (em, 0 /* enable */ );
20199   vl_api_set_elog_trace_api_messages (1);
20200   errmsg ("Event logger disabled...");
20201 #else
20202   errmsg ("Use the vpp event loger...");
20203 #endif
20204   return 0;
20205 }
20206
20207 static int
20208 statseg (vat_main_t * vam)
20209 {
20210   ssvm_private_t *ssvmp = &vam->stat_segment;
20211   ssvm_shared_header_t *shared_header = ssvmp->sh;
20212   vlib_counter_t **counters;
20213   u64 thread0_index1_packets;
20214   u64 thread0_index1_bytes;
20215   f64 vector_rate, input_rate;
20216   uword *p;
20217
20218   uword *counter_vector_by_name;
20219   if (vam->stat_segment_lockp == 0)
20220     {
20221       errmsg ("Stat segment not mapped...");
20222       return -99;
20223     }
20224
20225   /* look up "/if/rx for sw_if_index 1 as a test */
20226
20227   clib_spinlock_lock (vam->stat_segment_lockp);
20228
20229   counter_vector_by_name = (uword *) shared_header->opaque[1];
20230
20231   p = hash_get_mem (counter_vector_by_name, "/if/rx");
20232   if (p == 0)
20233     {
20234       clib_spinlock_unlock (vam->stat_segment_lockp);
20235       errmsg ("/if/tx not found?");
20236       return -99;
20237     }
20238
20239   /* Fish per-thread vector of combined counters from shared memory */
20240   counters = (vlib_counter_t **) p[0];
20241
20242   if (vec_len (counters[0]) < 2)
20243     {
20244       clib_spinlock_unlock (vam->stat_segment_lockp);
20245       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
20246       return -99;
20247     }
20248
20249   /* Read thread 0 sw_if_index 1 counter */
20250   thread0_index1_packets = counters[0][1].packets;
20251   thread0_index1_bytes = counters[0][1].bytes;
20252
20253   p = hash_get_mem (counter_vector_by_name, "vector_rate");
20254   if (p == 0)
20255     {
20256       clib_spinlock_unlock (vam->stat_segment_lockp);
20257       errmsg ("vector_rate not found?");
20258       return -99;
20259     }
20260
20261   vector_rate = *(f64 *) (p[0]);
20262   p = hash_get_mem (counter_vector_by_name, "input_rate");
20263   if (p == 0)
20264     {
20265       clib_spinlock_unlock (vam->stat_segment_lockp);
20266       errmsg ("input_rate not found?");
20267       return -99;
20268     }
20269   input_rate = *(f64 *) (p[0]);
20270
20271   clib_spinlock_unlock (vam->stat_segment_lockp);
20272
20273   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
20274          vector_rate, input_rate);
20275   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
20276          thread0_index1_packets, thread0_index1_bytes);
20277
20278   return 0;
20279 }
20280
20281 static int
20282 cmd_cmp (void *a1, void *a2)
20283 {
20284   u8 **c1 = a1;
20285   u8 **c2 = a2;
20286
20287   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
20288 }
20289
20290 static int
20291 help (vat_main_t * vam)
20292 {
20293   u8 **cmds = 0;
20294   u8 *name = 0;
20295   hash_pair_t *p;
20296   unformat_input_t *i = vam->input;
20297   int j;
20298
20299   if (unformat (i, "%s", &name))
20300     {
20301       uword *hs;
20302
20303       vec_add1 (name, 0);
20304
20305       hs = hash_get_mem (vam->help_by_name, name);
20306       if (hs)
20307         print (vam->ofp, "usage: %s %s", name, hs[0]);
20308       else
20309         print (vam->ofp, "No such msg / command '%s'", name);
20310       vec_free (name);
20311       return 0;
20312     }
20313
20314   print (vam->ofp, "Help is available for the following:");
20315
20316     /* *INDENT-OFF* */
20317     hash_foreach_pair (p, vam->function_by_name,
20318     ({
20319       vec_add1 (cmds, (u8 *)(p->key));
20320     }));
20321     /* *INDENT-ON* */
20322
20323   vec_sort_with_function (cmds, cmd_cmp);
20324
20325   for (j = 0; j < vec_len (cmds); j++)
20326     print (vam->ofp, "%s", cmds[j]);
20327
20328   vec_free (cmds);
20329   return 0;
20330 }
20331
20332 static int
20333 set (vat_main_t * vam)
20334 {
20335   u8 *name = 0, *value = 0;
20336   unformat_input_t *i = vam->input;
20337
20338   if (unformat (i, "%s", &name))
20339     {
20340       /* The input buffer is a vector, not a string. */
20341       value = vec_dup (i->buffer);
20342       vec_delete (value, i->index, 0);
20343       /* Almost certainly has a trailing newline */
20344       if (value[vec_len (value) - 1] == '\n')
20345         value[vec_len (value) - 1] = 0;
20346       /* Make sure it's a proper string, one way or the other */
20347       vec_add1 (value, 0);
20348       (void) clib_macro_set_value (&vam->macro_main,
20349                                    (char *) name, (char *) value);
20350     }
20351   else
20352     errmsg ("usage: set <name> <value>");
20353
20354   vec_free (name);
20355   vec_free (value);
20356   return 0;
20357 }
20358
20359 static int
20360 unset (vat_main_t * vam)
20361 {
20362   u8 *name = 0;
20363
20364   if (unformat (vam->input, "%s", &name))
20365     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
20366       errmsg ("unset: %s wasn't set", name);
20367   vec_free (name);
20368   return 0;
20369 }
20370
20371 typedef struct
20372 {
20373   u8 *name;
20374   u8 *value;
20375 } macro_sort_t;
20376
20377
20378 static int
20379 macro_sort_cmp (void *a1, void *a2)
20380 {
20381   macro_sort_t *s1 = a1;
20382   macro_sort_t *s2 = a2;
20383
20384   return strcmp ((char *) (s1->name), (char *) (s2->name));
20385 }
20386
20387 static int
20388 dump_macro_table (vat_main_t * vam)
20389 {
20390   macro_sort_t *sort_me = 0, *sm;
20391   int i;
20392   hash_pair_t *p;
20393
20394     /* *INDENT-OFF* */
20395     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
20396     ({
20397       vec_add2 (sort_me, sm, 1);
20398       sm->name = (u8 *)(p->key);
20399       sm->value = (u8 *) (p->value[0]);
20400     }));
20401     /* *INDENT-ON* */
20402
20403   vec_sort_with_function (sort_me, macro_sort_cmp);
20404
20405   if (vec_len (sort_me))
20406     print (vam->ofp, "%-15s%s", "Name", "Value");
20407   else
20408     print (vam->ofp, "The macro table is empty...");
20409
20410   for (i = 0; i < vec_len (sort_me); i++)
20411     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
20412   return 0;
20413 }
20414
20415 static int
20416 dump_node_table (vat_main_t * vam)
20417 {
20418   int i, j;
20419   vlib_node_t *node, *next_node;
20420
20421   if (vec_len (vam->graph_nodes) == 0)
20422     {
20423       print (vam->ofp, "Node table empty, issue get_node_graph...");
20424       return 0;
20425     }
20426
20427   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
20428     {
20429       node = vam->graph_nodes[0][i];
20430       print (vam->ofp, "[%d] %s", i, node->name);
20431       for (j = 0; j < vec_len (node->next_nodes); j++)
20432         {
20433           if (node->next_nodes[j] != ~0)
20434             {
20435               next_node = vam->graph_nodes[0][node->next_nodes[j]];
20436               print (vam->ofp, "  [%d] %s", j, next_node->name);
20437             }
20438         }
20439     }
20440   return 0;
20441 }
20442
20443 static int
20444 value_sort_cmp (void *a1, void *a2)
20445 {
20446   name_sort_t *n1 = a1;
20447   name_sort_t *n2 = a2;
20448
20449   if (n1->value < n2->value)
20450     return -1;
20451   if (n1->value > n2->value)
20452     return 1;
20453   return 0;
20454 }
20455
20456
20457 static int
20458 dump_msg_api_table (vat_main_t * vam)
20459 {
20460   api_main_t *am = vlibapi_get_main ();
20461   name_sort_t *nses = 0, *ns;
20462   hash_pair_t *hp;
20463   int i;
20464
20465   /* *INDENT-OFF* */
20466   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
20467   ({
20468     vec_add2 (nses, ns, 1);
20469     ns->name = (u8 *)(hp->key);
20470     ns->value = (u32) hp->value[0];
20471   }));
20472   /* *INDENT-ON* */
20473
20474   vec_sort_with_function (nses, value_sort_cmp);
20475
20476   for (i = 0; i < vec_len (nses); i++)
20477     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
20478   vec_free (nses);
20479   return 0;
20480 }
20481
20482 static int
20483 get_msg_id (vat_main_t * vam)
20484 {
20485   u8 *name_and_crc;
20486   u32 message_index;
20487
20488   if (unformat (vam->input, "%s", &name_and_crc))
20489     {
20490       message_index = vl_msg_api_get_msg_index (name_and_crc);
20491       if (message_index == ~0)
20492         {
20493           print (vam->ofp, " '%s' not found", name_and_crc);
20494           return 0;
20495         }
20496       print (vam->ofp, " '%s' has message index %d",
20497              name_and_crc, message_index);
20498       return 0;
20499     }
20500   errmsg ("name_and_crc required...");
20501   return 0;
20502 }
20503
20504 static int
20505 search_node_table (vat_main_t * vam)
20506 {
20507   unformat_input_t *line_input = vam->input;
20508   u8 *node_to_find;
20509   int j;
20510   vlib_node_t *node, *next_node;
20511   uword *p;
20512
20513   if (vam->graph_node_index_by_name == 0)
20514     {
20515       print (vam->ofp, "Node table empty, issue get_node_graph...");
20516       return 0;
20517     }
20518
20519   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20520     {
20521       if (unformat (line_input, "%s", &node_to_find))
20522         {
20523           vec_add1 (node_to_find, 0);
20524           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
20525           if (p == 0)
20526             {
20527               print (vam->ofp, "%s not found...", node_to_find);
20528               goto out;
20529             }
20530           node = vam->graph_nodes[0][p[0]];
20531           print (vam->ofp, "[%d] %s", p[0], node->name);
20532           for (j = 0; j < vec_len (node->next_nodes); j++)
20533             {
20534               if (node->next_nodes[j] != ~0)
20535                 {
20536                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
20537                   print (vam->ofp, "  [%d] %s", j, next_node->name);
20538                 }
20539             }
20540         }
20541
20542       else
20543         {
20544           clib_warning ("parse error '%U'", format_unformat_error,
20545                         line_input);
20546           return -99;
20547         }
20548
20549     out:
20550       vec_free (node_to_find);
20551
20552     }
20553
20554   return 0;
20555 }
20556
20557
20558 static int
20559 script (vat_main_t * vam)
20560 {
20561 #if (VPP_API_TEST_BUILTIN==0)
20562   u8 *s = 0;
20563   char *save_current_file;
20564   unformat_input_t save_input;
20565   jmp_buf save_jump_buf;
20566   u32 save_line_number;
20567
20568   FILE *new_fp, *save_ifp;
20569
20570   if (unformat (vam->input, "%s", &s))
20571     {
20572       new_fp = fopen ((char *) s, "r");
20573       if (new_fp == 0)
20574         {
20575           errmsg ("Couldn't open script file %s", s);
20576           vec_free (s);
20577           return -99;
20578         }
20579     }
20580   else
20581     {
20582       errmsg ("Missing script name");
20583       return -99;
20584     }
20585
20586   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
20587   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
20588   save_ifp = vam->ifp;
20589   save_line_number = vam->input_line_number;
20590   save_current_file = (char *) vam->current_file;
20591
20592   vam->input_line_number = 0;
20593   vam->ifp = new_fp;
20594   vam->current_file = s;
20595   do_one_file (vam);
20596
20597   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
20598   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
20599   vam->ifp = save_ifp;
20600   vam->input_line_number = save_line_number;
20601   vam->current_file = (u8 *) save_current_file;
20602   vec_free (s);
20603
20604   return 0;
20605 #else
20606   clib_warning ("use the exec command...");
20607   return -99;
20608 #endif
20609 }
20610
20611 static int
20612 echo (vat_main_t * vam)
20613 {
20614   print (vam->ofp, "%v", vam->input->buffer);
20615   return 0;
20616 }
20617
20618 /* List of API message constructors, CLI names map to api_xxx */
20619 #define foreach_vpe_api_msg                                             \
20620 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
20621 _(sw_interface_dump,"")                                                 \
20622 _(sw_interface_set_flags,                                               \
20623   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
20624 _(sw_interface_add_del_address,                                         \
20625   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
20626 _(sw_interface_set_rx_mode,                                             \
20627   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
20628 _(sw_interface_set_rx_placement,                                        \
20629   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
20630 _(sw_interface_rx_placement_dump,                                       \
20631   "[<intfc> | sw_if_index <id>]")                                         \
20632 _(sw_interface_set_table,                                               \
20633   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
20634 _(sw_interface_set_mpls_enable,                                         \
20635   "<intfc> | sw_if_index [disable | dis]")                              \
20636 _(sw_interface_set_vpath,                                               \
20637   "<intfc> | sw_if_index <id> enable | disable")                        \
20638 _(sw_interface_set_vxlan_bypass,                                        \
20639   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20640 _(sw_interface_set_geneve_bypass,                                       \
20641   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20642 _(sw_interface_set_l2_xconnect,                                         \
20643   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20644   "enable | disable")                                                   \
20645 _(sw_interface_set_l2_bridge,                                           \
20646   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
20647   "[shg <split-horizon-group>] [bvi]\n"                                 \
20648   "enable | disable")                                                   \
20649 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
20650 _(bridge_domain_add_del,                                                \
20651   "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") \
20652 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
20653 _(l2fib_add_del,                                                        \
20654   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
20655 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
20656 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
20657 _(l2_flags,                                                             \
20658   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20659 _(bridge_flags,                                                         \
20660   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20661 _(tap_create_v2,                                                        \
20662   "id <num> [hw-addr <mac-addr>] [host-if-name <name>] [host-ns <name>] [num-rx-queues <num>] [rx-ring-size <num>] [tx-ring-size <num>] [host-bridge <name>] [host-mac-addr <mac-addr>] [host-ip4-addr <ip4addr/mask>] [host-ip6-addr <ip6addr/mask>] [host-mtu-size <mtu>] [gso | no-gso | csum-offload | gro-coalesce] [persist] [attach] [tun]") \
20663 _(tap_delete_v2,                                                        \
20664   "<vpp-if-name> | sw_if_index <id>")                                   \
20665 _(sw_interface_tap_v2_dump, "")                                         \
20666 _(virtio_pci_create,                                                    \
20667   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled | csum-offload-enabled]") \
20668 _(virtio_pci_delete,                                                    \
20669   "<vpp-if-name> | sw_if_index <id>")                                   \
20670 _(sw_interface_virtio_pci_dump, "")                                     \
20671 _(bond_create,                                                          \
20672   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
20673   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
20674   "[id <if-id>]")                                                       \
20675 _(bond_delete,                                                          \
20676   "<vpp-if-name> | sw_if_index <id>")                                   \
20677 _(bond_add_member,                                                      \
20678   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
20679 _(bond_detach_member,                                                   \
20680   "sw_if_index <n>")                                                    \
20681  _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
20682  _(sw_bond_interface_dump, "<intfc> | sw_if_index <nn>")                \
20683  _(sw_member_interface_dump,                                            \
20684   "<vpp-if-name> | sw_if_index <id>")                                   \
20685 _(ip_table_add_del,                                                     \
20686   "table <n> [ipv6] [add | del]\n")                                     \
20687 _(ip_route_add_del,                                                     \
20688   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
20689   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
20690   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
20691   "[multipath] [count <n>] [del]")                                      \
20692 _(ip_mroute_add_del,                                                    \
20693   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
20694   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
20695 _(mpls_table_add_del,                                                   \
20696   "table <n> [add | del]\n")                                            \
20697 _(mpls_route_add_del,                                                   \
20698   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
20699   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
20700   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
20701   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
20702   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
20703   "[count <n>] [del]")                                                  \
20704 _(mpls_ip_bind_unbind,                                                  \
20705   "<label> <addr/len>")                                                 \
20706 _(mpls_tunnel_add_del,                                                  \
20707   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
20708   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
20709   "[l2-only]  [out-label <n>]")                                         \
20710 _(sr_mpls_policy_add,                                                   \
20711   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
20712 _(sr_mpls_policy_del,                                                   \
20713   "bsid <id>")                                                          \
20714 _(bier_table_add_del,                                                   \
20715   "<label> <sub-domain> <set> <bsl> [del]")                             \
20716 _(bier_route_add_del,                                                   \
20717   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
20718   "[<intfc> | sw_if_index <id>]"                                        \
20719   "[weight <n>] [del] [multipath]")                                     \
20720 _(sw_interface_set_unnumbered,                                          \
20721   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
20722 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
20723 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
20724   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
20725   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
20726   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
20727 _(ip_table_replace_begin, "table <n> [ipv6]")                           \
20728 _(ip_table_flush, "table <n> [ipv6]")                                   \
20729 _(ip_table_replace_end, "table <n> [ipv6]")                             \
20730 _(set_ip_flow_hash,                                                     \
20731   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
20732 _(sw_interface_ip6_enable_disable,                                      \
20733   "<intfc> | sw_if_index <id> enable | disable")                        \
20734 _(l2_patch_add_del,                                                     \
20735   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20736   "enable | disable")                                                   \
20737 _(sr_localsid_add_del,                                                  \
20738   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
20739   "fib-table <num> (end.psp) sw_if_index <num>")                        \
20740 _(classify_add_del_table,                                               \
20741   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
20742   " [del] [del-chain] mask <mask-value>\n"                              \
20743   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
20744   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
20745 _(classify_add_del_session,                                             \
20746   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
20747   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
20748   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
20749   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
20750 _(classify_set_interface_ip_table,                                      \
20751   "<intfc> | sw_if_index <nn> table <nn>")                              \
20752 _(classify_set_interface_l2_tables,                                     \
20753   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20754   "  [other-table <nn>]")                                               \
20755 _(get_node_index, "node <node-name")                                    \
20756 _(add_node_next, "node <node-name> next <next-node-name>")              \
20757 _(l2tpv3_create_tunnel,                                                 \
20758   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
20759   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
20760   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
20761 _(l2tpv3_set_tunnel_cookies,                                            \
20762   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
20763   "[new_remote_cookie <nn>]\n")                                         \
20764 _(l2tpv3_interface_enable_disable,                                      \
20765   "<intfc> | sw_if_index <nn> enable | disable")                        \
20766 _(l2tpv3_set_lookup_key,                                                \
20767   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
20768 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
20769 _(vxlan_offload_rx,                                                     \
20770   "hw { <interface name> | hw_if_index <nn>} "                          \
20771   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
20772 _(vxlan_add_del_tunnel,                                                 \
20773   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20774   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
20775   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20776 _(geneve_add_del_tunnel,                                                \
20777   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20778   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20779   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20780 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
20781 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
20782 _(gre_tunnel_add_del,                                                   \
20783   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
20784   "[teb | erspan <session-id>] [del]")                                  \
20785 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
20786 _(l2_fib_clear_table, "")                                               \
20787 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
20788 _(l2_interface_vlan_tag_rewrite,                                        \
20789   "<intfc> | sw_if_index <nn> \n"                                       \
20790   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
20791   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
20792 _(create_vhost_user_if,                                                 \
20793         "socket <filename> [server] [renumber <dev_instance>] "         \
20794         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
20795         "[mac <mac_address>] [packed]")                                 \
20796 _(modify_vhost_user_if,                                                 \
20797         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
20798         "[server] [renumber <dev_instance>] [gso] [packed]")            \
20799 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
20800 _(sw_interface_vhost_user_dump, "<intfc> | sw_if_index <nn>")           \
20801 _(show_version, "")                                                     \
20802 _(show_threads, "")                                                     \
20803 _(vxlan_gpe_add_del_tunnel,                                             \
20804   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
20805   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20806   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
20807   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
20808 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
20809 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
20810 _(interface_name_renumber,                                              \
20811   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
20812 _(input_acl_set_interface,                                              \
20813   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20814   "  [l2-table <nn>] [del]")                                            \
20815 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
20816 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
20817 _(ip_dump, "ipv4 | ipv6")                                               \
20818 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
20819 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
20820   "  spid_id <n> ")                                                     \
20821 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
20822   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
20823   "  integ_alg <alg> integ_key <hex>")                                  \
20824 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
20825   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
20826   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
20827   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
20828 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
20829   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
20830   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
20831   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
20832   "  [instance <n>]")     \
20833 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
20834 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
20835 _(delete_loopback,"sw_if_index <nn>")                                   \
20836 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
20837 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
20838 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
20839 _(want_interface_events,  "enable|disable")                             \
20840 _(get_first_msg_id, "client <name>")                                    \
20841 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
20842 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
20843   "fib-id <nn> [ip4][ip6][default]")                                    \
20844 _(get_node_graph, " ")                                                  \
20845 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
20846 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
20847 _(ioam_disable, "")                                                     \
20848 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
20849                             " sw_if_index <sw_if_index> p <priority> "  \
20850                             "w <weight>] [del]")                        \
20851 _(one_add_del_locator, "locator-set <locator_name> "                    \
20852                         "iface <intf> | sw_if_index <sw_if_index> "     \
20853                         "p <priority> w <weight> [del]")                \
20854 _(one_add_del_local_eid,"vni <vni> eid "                                \
20855                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20856                          "locator-set <locator_name> [del]"             \
20857                          "[key-id sha1|sha256 secret-key <secret-key>]")\
20858 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
20859 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
20860 _(one_enable_disable, "enable|disable")                                 \
20861 _(one_map_register_enable_disable, "enable|disable")                    \
20862 _(one_map_register_fallback_threshold, "<value>")                       \
20863 _(one_rloc_probe_enable_disable, "enable|disable")                      \
20864 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
20865                                "[seid <seid>] "                         \
20866                                "rloc <locator> p <prio> "               \
20867                                "w <weight> [rloc <loc> ... ] "          \
20868                                "action <action> [del-all]")             \
20869 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
20870                           "<local-eid>")                                \
20871 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
20872 _(one_use_petr, "ip-address> | disable")                                \
20873 _(one_map_request_mode, "src-dst|dst-only")                             \
20874 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
20875 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
20876 _(one_locator_set_dump, "[local | remote]")                             \
20877 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
20878 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
20879                        "[local] | [remote]")                            \
20880 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
20881 _(one_ndp_bd_get, "")                                                   \
20882 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
20883 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
20884 _(one_l2_arp_bd_get, "")                                                \
20885 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
20886 _(one_stats_enable_disable, "enable|disable")                           \
20887 _(show_one_stats_enable_disable, "")                                    \
20888 _(one_eid_table_vni_dump, "")                                           \
20889 _(one_eid_table_map_dump, "l2|l3")                                      \
20890 _(one_map_resolver_dump, "")                                            \
20891 _(one_map_server_dump, "")                                              \
20892 _(one_adjacencies_get, "vni <vni>")                                     \
20893 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
20894 _(show_one_rloc_probe_state, "")                                        \
20895 _(show_one_map_register_state, "")                                      \
20896 _(show_one_status, "")                                                  \
20897 _(one_stats_dump, "")                                                   \
20898 _(one_stats_flush, "")                                                  \
20899 _(one_get_map_request_itr_rlocs, "")                                    \
20900 _(one_map_register_set_ttl, "<ttl>")                                    \
20901 _(one_set_transport_protocol, "udp|api")                                \
20902 _(one_get_transport_protocol, "")                                       \
20903 _(one_enable_disable_xtr_mode, "enable|disable")                        \
20904 _(one_show_xtr_mode, "")                                                \
20905 _(one_enable_disable_pitr_mode, "enable|disable")                       \
20906 _(one_show_pitr_mode, "")                                               \
20907 _(one_enable_disable_petr_mode, "enable|disable")                       \
20908 _(one_show_petr_mode, "")                                               \
20909 _(show_one_nsh_mapping, "")                                             \
20910 _(show_one_pitr, "")                                                    \
20911 _(show_one_use_petr, "")                                                \
20912 _(show_one_map_request_mode, "")                                        \
20913 _(show_one_map_register_ttl, "")                                        \
20914 _(show_one_map_register_fallback_threshold, "")                         \
20915 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
20916                             " sw_if_index <sw_if_index> p <priority> "  \
20917                             "w <weight>] [del]")                        \
20918 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
20919                         "iface <intf> | sw_if_index <sw_if_index> "     \
20920                         "p <priority> w <weight> [del]")                \
20921 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
20922                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20923                          "locator-set <locator_name> [del]"             \
20924                          "[key-id sha1|sha256 secret-key <secret-key>]") \
20925 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
20926 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
20927 _(lisp_enable_disable, "enable|disable")                                \
20928 _(lisp_map_register_enable_disable, "enable|disable")                   \
20929 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
20930 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
20931                                "[seid <seid>] "                         \
20932                                "rloc <locator> p <prio> "               \
20933                                "w <weight> [rloc <loc> ... ] "          \
20934                                "action <action> [del-all]")             \
20935 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
20936                           "<local-eid>")                                \
20937 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
20938 _(lisp_use_petr, "<ip-address> | disable")                              \
20939 _(lisp_map_request_mode, "src-dst|dst-only")                            \
20940 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
20941 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
20942 _(lisp_locator_set_dump, "[local | remote]")                            \
20943 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
20944 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
20945                        "[local] | [remote]")                            \
20946 _(lisp_eid_table_vni_dump, "")                                          \
20947 _(lisp_eid_table_map_dump, "l2|l3")                                     \
20948 _(lisp_map_resolver_dump, "")                                           \
20949 _(lisp_map_server_dump, "")                                             \
20950 _(lisp_adjacencies_get, "vni <vni>")                                    \
20951 _(gpe_fwd_entry_vnis_get, "")                                           \
20952 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
20953 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
20954                                 "[table <table-id>]")                   \
20955 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
20956 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
20957 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
20958 _(gpe_get_encap_mode, "")                                               \
20959 _(lisp_gpe_add_del_iface, "up|down")                                    \
20960 _(lisp_gpe_enable_disable, "enable|disable")                            \
20961 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
20962   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
20963 _(show_lisp_rloc_probe_state, "")                                       \
20964 _(show_lisp_map_register_state, "")                                     \
20965 _(show_lisp_status, "")                                                 \
20966 _(lisp_get_map_request_itr_rlocs, "")                                   \
20967 _(show_lisp_pitr, "")                                                   \
20968 _(show_lisp_use_petr, "")                                               \
20969 _(show_lisp_map_request_mode, "")                                       \
20970 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
20971 _(af_packet_delete, "name <host interface name>")                       \
20972 _(af_packet_dump, "")                                                   \
20973 _(policer_add_del, "name <policer name> <params> [del]")                \
20974 _(policer_dump, "[name <policer name>]")                                \
20975 _(policer_classify_set_interface,                                       \
20976   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20977   "  [l2-table <nn>] [del]")                                            \
20978 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
20979 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
20980 _(mpls_table_dump, "")                                                  \
20981 _(mpls_route_dump, "table-id <ID>")                                     \
20982 _(classify_table_ids, "")                                               \
20983 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
20984 _(classify_table_info, "table_id <nn>")                                 \
20985 _(classify_session_dump, "table_id <nn>")                               \
20986 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
20987     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
20988     "[template_interval <nn>] [udp_checksum]")                          \
20989 _(ipfix_exporter_dump, "")                                              \
20990 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
20991 _(ipfix_classify_stream_dump, "")                                       \
20992 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
20993 _(ipfix_classify_table_dump, "")                                        \
20994 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
20995 _(sw_interface_span_dump, "[l2]")                                           \
20996 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
20997 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
20998 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
20999 _(pg_enable_disable, "[stream <id>] disable")                           \
21000 _(pg_interface_enable_disable_coalesce, "<intf> | sw_if_index <nn> enable | disable")  \
21001 _(ip_source_and_port_range_check_add_del,                               \
21002   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
21003 _(ip_source_and_port_range_check_interface_add_del,                     \
21004   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
21005   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
21006 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
21007 _(l2_interface_pbb_tag_rewrite,                                         \
21008   "<intfc> | sw_if_index <nn> \n"                                       \
21009   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
21010   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
21011 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
21012 _(flow_classify_set_interface,                                          \
21013   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
21014 _(flow_classify_dump, "type [ip4|ip6]")                                 \
21015 _(ip_table_dump, "")                                                    \
21016 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
21017 _(ip_mtable_dump, "")                                                   \
21018 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
21019 _(feature_enable_disable, "arc_name <arc_name> "                        \
21020   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
21021 _(feature_gso_enable_disable, "<intfc> | sw_if_index <nn> "             \
21022   "[enable | disable] ")                                                \
21023 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
21024 "[disable]")                                                            \
21025 _(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> "       \
21026   "mac <mac-address> [del]")                                            \
21027 _(l2_xconnect_dump, "")                                                 \
21028 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
21029 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
21030 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
21031 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
21032 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
21033 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
21034   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
21035 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
21036 _(sock_init_shm, "size <nnn>")                                          \
21037 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
21038 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
21039   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
21040 _(session_rules_dump, "")                                               \
21041 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
21042 _(output_acl_set_interface,                                             \
21043   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21044   "  [l2-table <nn>] [del]")                                            \
21045 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
21046
21047 /* List of command functions, CLI names map directly to functions */
21048 #define foreach_cli_function                                    \
21049 _(comment, "usage: comment <ignore-rest-of-line>")              \
21050 _(dump_interface_table, "usage: dump_interface_table")          \
21051 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
21052 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
21053 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
21054 _(dump_macro_table, "usage: dump_macro_table ")                 \
21055 _(dump_node_table, "usage: dump_node_table")                    \
21056 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
21057 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
21058 _(elog_disable, "usage: elog_disable")                          \
21059 _(elog_enable, "usage: elog_enable")                            \
21060 _(elog_save, "usage: elog_save <filename>")                     \
21061 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
21062 _(echo, "usage: echo <message>")                                \
21063 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
21064 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
21065 _(help, "usage: help")                                          \
21066 _(q, "usage: quit")                                             \
21067 _(quit, "usage: quit")                                          \
21068 _(search_node_table, "usage: search_node_table <name>...")      \
21069 _(set, "usage: set <variable-name> <value>")                    \
21070 _(script, "usage: script <file-name>")                          \
21071 _(statseg, "usage: statseg")                                    \
21072 _(unset, "usage: unset <variable-name>")
21073
21074 #define _(N,n)                                  \
21075     static void vl_api_##n##_t_handler_uni      \
21076     (vl_api_##n##_t * mp)                       \
21077     {                                           \
21078         vat_main_t * vam = &vat_main;           \
21079         if (vam->json_output) {                 \
21080             vl_api_##n##_t_handler_json(mp);    \
21081         } else {                                \
21082             vl_api_##n##_t_handler(mp);         \
21083         }                                       \
21084     }
21085 foreach_vpe_api_reply_msg;
21086 #if VPP_API_TEST_BUILTIN == 0
21087 foreach_standalone_reply_msg;
21088 #endif
21089 #undef _
21090
21091 void
21092 vat_api_hookup (vat_main_t * vam)
21093 {
21094 #define _(N,n)                                                  \
21095     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
21096                            vl_api_##n##_t_handler_uni,          \
21097                            vl_noop_handler,                     \
21098                            vl_api_##n##_t_endian,               \
21099                            vl_api_##n##_t_print,                \
21100                            sizeof(vl_api_##n##_t), 1);
21101   foreach_vpe_api_reply_msg;
21102 #if VPP_API_TEST_BUILTIN == 0
21103   foreach_standalone_reply_msg;
21104 #endif
21105 #undef _
21106
21107 #if (VPP_API_TEST_BUILTIN==0)
21108   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
21109
21110   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
21111
21112   vam->function_by_name = hash_create_string (0, sizeof (uword));
21113
21114   vam->help_by_name = hash_create_string (0, sizeof (uword));
21115 #endif
21116
21117   /* API messages we can send */
21118 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
21119   foreach_vpe_api_msg;
21120 #undef _
21121
21122   /* Help strings */
21123 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21124   foreach_vpe_api_msg;
21125 #undef _
21126
21127   /* CLI functions */
21128 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
21129   foreach_cli_function;
21130 #undef _
21131
21132   /* Help strings */
21133 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21134   foreach_cli_function;
21135 #undef _
21136 }
21137
21138 #if VPP_API_TEST_BUILTIN
21139 static clib_error_t *
21140 vat_api_hookup_shim (vlib_main_t * vm)
21141 {
21142   vat_api_hookup (&vat_main);
21143   return 0;
21144 }
21145
21146 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
21147 #endif
21148
21149 /*
21150  * fd.io coding-style-patch-verification: ON
21151  *
21152  * Local Variables:
21153  * eval: (c-set-style "gnu")
21154  * End:
21155  */