tap: add virtio 1.1 API flag
[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 if (unformat (i, "packed"))
7394         tap_flags |= TAP_API_FLAG_PACKED;
7395       else if (unformat (i, "in-order"))
7396         tap_flags |= TAP_API_FLAG_IN_ORDER;
7397       else
7398         break;
7399     }
7400
7401   if (vec_len (host_if_name) > 63)
7402     {
7403       errmsg ("tap name too long. ");
7404       return -99;
7405     }
7406   if (vec_len (host_ns) > 63)
7407     {
7408       errmsg ("host name space too long. ");
7409       return -99;
7410     }
7411   if (vec_len (host_bridge) > 63)
7412     {
7413       errmsg ("host bridge name too long. ");
7414       return -99;
7415     }
7416   if (host_ip4_prefix_len > 32)
7417     {
7418       errmsg ("host ip4 prefix length not valid. ");
7419       return -99;
7420     }
7421   if (host_ip6_prefix_len > 128)
7422     {
7423       errmsg ("host ip6 prefix length not valid. ");
7424       return -99;
7425     }
7426   if (!is_pow2 (rx_ring_sz))
7427     {
7428       errmsg ("rx ring size must be power of 2. ");
7429       return -99;
7430     }
7431   if (rx_ring_sz > 32768)
7432     {
7433       errmsg ("rx ring size must be 32768 or lower. ");
7434       return -99;
7435     }
7436   if (!is_pow2 (tx_ring_sz))
7437     {
7438       errmsg ("tx ring size must be power of 2. ");
7439       return -99;
7440     }
7441   if (tx_ring_sz > 32768)
7442     {
7443       errmsg ("tx ring size must be 32768 or lower. ");
7444       return -99;
7445     }
7446   if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
7447     {
7448       errmsg ("host MTU size must be in between 64 and 65355. ");
7449       return -99;
7450     }
7451
7452   /* Construct the API message */
7453   M (TAP_CREATE_V2, mp);
7454
7455   mp->id = ntohl (id);
7456   mp->use_random_mac = random_mac;
7457   mp->num_rx_queues = (u8) num_rx_queues;
7458   mp->tx_ring_sz = ntohs (tx_ring_sz);
7459   mp->rx_ring_sz = ntohs (rx_ring_sz);
7460   mp->host_mtu_set = host_mtu_set;
7461   mp->host_mtu_size = ntohl (host_mtu_size);
7462   mp->host_mac_addr_set = host_mac_addr_set;
7463   mp->host_ip4_prefix_set = host_ip4_prefix_set;
7464   mp->host_ip6_prefix_set = host_ip6_prefix_set;
7465   mp->host_ip4_gw_set = host_ip4_gw_set;
7466   mp->host_ip6_gw_set = host_ip6_gw_set;
7467   mp->tap_flags = ntohl (tap_flags);
7468   mp->host_namespace_set = host_ns_set;
7469   mp->host_if_name_set = host_if_name_set;
7470   mp->host_bridge_set = host_bridge_set;
7471
7472   if (random_mac == 0)
7473     clib_memcpy (mp->mac_address, mac_address, 6);
7474   if (host_mac_addr_set)
7475     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7476   if (host_if_name_set)
7477     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7478   if (host_ns_set)
7479     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7480   if (host_bridge_set)
7481     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7482   if (host_ip4_prefix_set)
7483     {
7484       clib_memcpy (mp->host_ip4_prefix.address, &host_ip4_addr, 4);
7485       mp->host_ip4_prefix.len = (u8) host_ip4_prefix_len;
7486     }
7487   if (host_ip6_prefix_set)
7488     {
7489       clib_memcpy (mp->host_ip6_prefix.address, &host_ip6_addr, 16);
7490       mp->host_ip6_prefix.len = (u8) host_ip6_prefix_len;
7491     }
7492   if (host_ip4_gw_set)
7493     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7494   if (host_ip6_gw_set)
7495     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7496
7497   vec_free (host_ns);
7498   vec_free (host_if_name);
7499   vec_free (host_bridge);
7500
7501   /* send it... */
7502   S (mp);
7503
7504   /* Wait for a reply... */
7505   W (ret);
7506   return ret;
7507 }
7508
7509 static int
7510 api_tap_delete_v2 (vat_main_t * vam)
7511 {
7512   unformat_input_t *i = vam->input;
7513   vl_api_tap_delete_v2_t *mp;
7514   u32 sw_if_index = ~0;
7515   u8 sw_if_index_set = 0;
7516   int ret;
7517
7518   /* Parse args required to build the message */
7519   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7520     {
7521       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7522         sw_if_index_set = 1;
7523       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7524         sw_if_index_set = 1;
7525       else
7526         break;
7527     }
7528
7529   if (sw_if_index_set == 0)
7530     {
7531       errmsg ("missing vpp interface name. ");
7532       return -99;
7533     }
7534
7535   /* Construct the API message */
7536   M (TAP_DELETE_V2, mp);
7537
7538   mp->sw_if_index = ntohl (sw_if_index);
7539
7540   /* send it... */
7541   S (mp);
7542
7543   /* Wait for a reply... */
7544   W (ret);
7545   return ret;
7546 }
7547
7548 uword
7549 unformat_vlib_pci_addr (unformat_input_t * input, va_list * args)
7550 {
7551   vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
7552   u32 x[4];
7553
7554   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7555     return 0;
7556
7557   addr->domain = x[0];
7558   addr->bus = x[1];
7559   addr->slot = x[2];
7560   addr->function = x[3];
7561
7562   return 1;
7563 }
7564
7565 static int
7566 api_virtio_pci_create (vat_main_t * vam)
7567 {
7568   unformat_input_t *i = vam->input;
7569   vl_api_virtio_pci_create_t *mp;
7570   u8 mac_address[6];
7571   u8 random_mac = 1;
7572   u8 gso_enabled = 0;
7573   u8 checksum_offload_enabled = 0;
7574   u32 pci_addr = 0;
7575   u64 features = (u64) ~ (0ULL);
7576   int ret;
7577
7578   clib_memset (mac_address, 0, sizeof (mac_address));
7579
7580   /* Parse args required to build the message */
7581   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7582     {
7583       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7584         {
7585           random_mac = 0;
7586         }
7587       else if (unformat (i, "pci-addr %U", unformat_vlib_pci_addr, &pci_addr))
7588         ;
7589       else if (unformat (i, "features 0x%llx", &features))
7590         ;
7591       else if (unformat (i, "gso-enabled"))
7592         gso_enabled = 1;
7593       else if (unformat (i, "csum-offload-enabled"))
7594         checksum_offload_enabled = 1;
7595       else
7596         break;
7597     }
7598
7599   if (pci_addr == 0)
7600     {
7601       errmsg ("pci address must be non zero. ");
7602       return -99;
7603     }
7604
7605   /* Construct the API message */
7606   M (VIRTIO_PCI_CREATE, mp);
7607
7608   mp->use_random_mac = random_mac;
7609
7610   mp->pci_addr.domain = htons (((vlib_pci_addr_t) pci_addr).domain);
7611   mp->pci_addr.bus = ((vlib_pci_addr_t) pci_addr).bus;
7612   mp->pci_addr.slot = ((vlib_pci_addr_t) pci_addr).slot;
7613   mp->pci_addr.function = ((vlib_pci_addr_t) pci_addr).function;
7614
7615   mp->features = clib_host_to_net_u64 (features);
7616   mp->gso_enabled = gso_enabled;
7617   mp->checksum_offload_enabled = checksum_offload_enabled;
7618
7619   if (random_mac == 0)
7620     clib_memcpy (mp->mac_address, mac_address, 6);
7621
7622   /* send it... */
7623   S (mp);
7624
7625   /* Wait for a reply... */
7626   W (ret);
7627   return ret;
7628 }
7629
7630 static int
7631 api_virtio_pci_delete (vat_main_t * vam)
7632 {
7633   unformat_input_t *i = vam->input;
7634   vl_api_virtio_pci_delete_t *mp;
7635   u32 sw_if_index = ~0;
7636   u8 sw_if_index_set = 0;
7637   int ret;
7638
7639   /* Parse args required to build the message */
7640   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7641     {
7642       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7643         sw_if_index_set = 1;
7644       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7645         sw_if_index_set = 1;
7646       else
7647         break;
7648     }
7649
7650   if (sw_if_index_set == 0)
7651     {
7652       errmsg ("missing vpp interface name. ");
7653       return -99;
7654     }
7655
7656   /* Construct the API message */
7657   M (VIRTIO_PCI_DELETE, mp);
7658
7659   mp->sw_if_index = htonl (sw_if_index);
7660
7661   /* send it... */
7662   S (mp);
7663
7664   /* Wait for a reply... */
7665   W (ret);
7666   return ret;
7667 }
7668
7669 static int
7670 api_bond_create (vat_main_t * vam)
7671 {
7672   unformat_input_t *i = vam->input;
7673   vl_api_bond_create_t *mp;
7674   u8 mac_address[6];
7675   u8 custom_mac = 0;
7676   int ret;
7677   u8 mode;
7678   u8 lb;
7679   u8 mode_is_set = 0;
7680   u32 id = ~0;
7681   u8 numa_only = 0;
7682
7683   clib_memset (mac_address, 0, sizeof (mac_address));
7684   lb = BOND_LB_L2;
7685
7686   /* Parse args required to build the message */
7687   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7688     {
7689       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7690         mode_is_set = 1;
7691       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7692                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7693         ;
7694       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7695                          mac_address))
7696         custom_mac = 1;
7697       else if (unformat (i, "numa-only"))
7698         numa_only = 1;
7699       else if (unformat (i, "id %u", &id))
7700         ;
7701       else
7702         break;
7703     }
7704
7705   if (mode_is_set == 0)
7706     {
7707       errmsg ("Missing bond mode. ");
7708       return -99;
7709     }
7710
7711   /* Construct the API message */
7712   M (BOND_CREATE, mp);
7713
7714   mp->use_custom_mac = custom_mac;
7715
7716   mp->mode = htonl (mode);
7717   mp->lb = htonl (lb);
7718   mp->id = htonl (id);
7719   mp->numa_only = numa_only;
7720
7721   if (custom_mac)
7722     clib_memcpy (mp->mac_address, mac_address, 6);
7723
7724   /* send it... */
7725   S (mp);
7726
7727   /* Wait for a reply... */
7728   W (ret);
7729   return ret;
7730 }
7731
7732 static int
7733 api_bond_delete (vat_main_t * vam)
7734 {
7735   unformat_input_t *i = vam->input;
7736   vl_api_bond_delete_t *mp;
7737   u32 sw_if_index = ~0;
7738   u8 sw_if_index_set = 0;
7739   int ret;
7740
7741   /* Parse args required to build the message */
7742   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7743     {
7744       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7745         sw_if_index_set = 1;
7746       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7747         sw_if_index_set = 1;
7748       else
7749         break;
7750     }
7751
7752   if (sw_if_index_set == 0)
7753     {
7754       errmsg ("missing vpp interface name. ");
7755       return -99;
7756     }
7757
7758   /* Construct the API message */
7759   M (BOND_DELETE, mp);
7760
7761   mp->sw_if_index = ntohl (sw_if_index);
7762
7763   /* send it... */
7764   S (mp);
7765
7766   /* Wait for a reply... */
7767   W (ret);
7768   return ret;
7769 }
7770
7771 static int
7772 api_bond_add_member (vat_main_t * vam)
7773 {
7774   unformat_input_t *i = vam->input;
7775   vl_api_bond_add_member_t *mp;
7776   u32 bond_sw_if_index;
7777   int ret;
7778   u8 is_passive;
7779   u8 is_long_timeout;
7780   u32 bond_sw_if_index_is_set = 0;
7781   u32 sw_if_index;
7782   u8 sw_if_index_is_set = 0;
7783
7784   /* Parse args required to build the message */
7785   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7786     {
7787       if (unformat (i, "sw_if_index %d", &sw_if_index))
7788         sw_if_index_is_set = 1;
7789       else if (unformat (i, "bond %u", &bond_sw_if_index))
7790         bond_sw_if_index_is_set = 1;
7791       else if (unformat (i, "passive %d", &is_passive))
7792         ;
7793       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7794         ;
7795       else
7796         break;
7797     }
7798
7799   if (bond_sw_if_index_is_set == 0)
7800     {
7801       errmsg ("Missing bond sw_if_index. ");
7802       return -99;
7803     }
7804   if (sw_if_index_is_set == 0)
7805     {
7806       errmsg ("Missing member sw_if_index. ");
7807       return -99;
7808     }
7809
7810   /* Construct the API message */
7811   M (BOND_ADD_MEMBER, mp);
7812
7813   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7814   mp->sw_if_index = ntohl (sw_if_index);
7815   mp->is_long_timeout = is_long_timeout;
7816   mp->is_passive = is_passive;
7817
7818   /* send it... */
7819   S (mp);
7820
7821   /* Wait for a reply... */
7822   W (ret);
7823   return ret;
7824 }
7825
7826 static int
7827 api_bond_detach_member (vat_main_t * vam)
7828 {
7829   unformat_input_t *i = vam->input;
7830   vl_api_bond_detach_member_t *mp;
7831   u32 sw_if_index = ~0;
7832   u8 sw_if_index_set = 0;
7833   int ret;
7834
7835   /* Parse args required to build the message */
7836   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7837     {
7838       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7839         sw_if_index_set = 1;
7840       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7841         sw_if_index_set = 1;
7842       else
7843         break;
7844     }
7845
7846   if (sw_if_index_set == 0)
7847     {
7848       errmsg ("missing vpp interface name. ");
7849       return -99;
7850     }
7851
7852   /* Construct the API message */
7853   M (BOND_DETACH_MEMBER, mp);
7854
7855   mp->sw_if_index = ntohl (sw_if_index);
7856
7857   /* send it... */
7858   S (mp);
7859
7860   /* Wait for a reply... */
7861   W (ret);
7862   return ret;
7863 }
7864
7865 static int
7866 api_ip_table_add_del (vat_main_t * vam)
7867 {
7868   unformat_input_t *i = vam->input;
7869   vl_api_ip_table_add_del_t *mp;
7870   u32 table_id = ~0;
7871   u8 is_ipv6 = 0;
7872   u8 is_add = 1;
7873   int ret = 0;
7874
7875   /* Parse args required to build the message */
7876   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7877     {
7878       if (unformat (i, "ipv6"))
7879         is_ipv6 = 1;
7880       else if (unformat (i, "del"))
7881         is_add = 0;
7882       else if (unformat (i, "add"))
7883         is_add = 1;
7884       else if (unformat (i, "table %d", &table_id))
7885         ;
7886       else
7887         {
7888           clib_warning ("parse error '%U'", format_unformat_error, i);
7889           return -99;
7890         }
7891     }
7892
7893   if (~0 == table_id)
7894     {
7895       errmsg ("missing table-ID");
7896       return -99;
7897     }
7898
7899   /* Construct the API message */
7900   M (IP_TABLE_ADD_DEL, mp);
7901
7902   mp->table.table_id = ntohl (table_id);
7903   mp->table.is_ip6 = is_ipv6;
7904   mp->is_add = is_add;
7905
7906   /* send it... */
7907   S (mp);
7908
7909   /* Wait for a reply... */
7910   W (ret);
7911
7912   return ret;
7913 }
7914
7915 uword
7916 unformat_fib_path (unformat_input_t * input, va_list * args)
7917 {
7918   vat_main_t *vam = va_arg (*args, vat_main_t *);
7919   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
7920   u32 weight, preference;
7921   mpls_label_t out_label;
7922
7923   clib_memset (path, 0, sizeof (*path));
7924   path->weight = 1;
7925   path->sw_if_index = ~0;
7926   path->rpf_id = ~0;
7927   path->n_labels = 0;
7928
7929   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7930     {
7931       if (unformat (input, "%U %U",
7932                     unformat_vl_api_ip4_address,
7933                     &path->nh.address.ip4,
7934                     api_unformat_sw_if_index, vam, &path->sw_if_index))
7935         {
7936           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7937         }
7938       else if (unformat (input, "%U %U",
7939                          unformat_vl_api_ip6_address,
7940                          &path->nh.address.ip6,
7941                          api_unformat_sw_if_index, vam, &path->sw_if_index))
7942         {
7943           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7944         }
7945       else if (unformat (input, "weight %u", &weight))
7946         {
7947           path->weight = weight;
7948         }
7949       else if (unformat (input, "preference %u", &preference))
7950         {
7951           path->preference = preference;
7952         }
7953       else if (unformat (input, "%U next-hop-table %d",
7954                          unformat_vl_api_ip4_address,
7955                          &path->nh.address.ip4, &path->table_id))
7956         {
7957           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7958         }
7959       else if (unformat (input, "%U next-hop-table %d",
7960                          unformat_vl_api_ip6_address,
7961                          &path->nh.address.ip6, &path->table_id))
7962         {
7963           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7964         }
7965       else if (unformat (input, "%U",
7966                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
7967         {
7968           /*
7969            * the recursive next-hops are by default in the default table
7970            */
7971           path->table_id = 0;
7972           path->sw_if_index = ~0;
7973           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7974         }
7975       else if (unformat (input, "%U",
7976                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
7977         {
7978           /*
7979            * the recursive next-hops are by default in the default table
7980            */
7981           path->table_id = 0;
7982           path->sw_if_index = ~0;
7983           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7984         }
7985       else if (unformat (input, "resolve-via-host"))
7986         {
7987           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
7988         }
7989       else if (unformat (input, "resolve-via-attached"))
7990         {
7991           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
7992         }
7993       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
7994         {
7995           path->type = FIB_API_PATH_TYPE_LOCAL;
7996           path->sw_if_index = ~0;
7997           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7998         }
7999       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
8000         {
8001           path->type = FIB_API_PATH_TYPE_LOCAL;
8002           path->sw_if_index = ~0;
8003           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8004         }
8005       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
8006         ;
8007       else if (unformat (input, "via-label %d", &path->nh.via_label))
8008         {
8009           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
8010           path->sw_if_index = ~0;
8011         }
8012       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
8013         {
8014           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
8015           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
8016         }
8017       else if (unformat (input, "local"))
8018         {
8019           path->type = FIB_API_PATH_TYPE_LOCAL;
8020         }
8021       else if (unformat (input, "out-labels"))
8022         {
8023           while (unformat (input, "%d", &out_label))
8024             {
8025               path->label_stack[path->n_labels].label = out_label;
8026               path->label_stack[path->n_labels].is_uniform = 0;
8027               path->label_stack[path->n_labels].ttl = 64;
8028               path->n_labels++;
8029             }
8030         }
8031       else if (unformat (input, "via"))
8032         {
8033           /* new path, back up and return */
8034           unformat_put_input (input);
8035           unformat_put_input (input);
8036           unformat_put_input (input);
8037           unformat_put_input (input);
8038           break;
8039         }
8040       else
8041         {
8042           return (0);
8043         }
8044     }
8045
8046   path->proto = ntohl (path->proto);
8047   path->type = ntohl (path->type);
8048   path->flags = ntohl (path->flags);
8049   path->table_id = ntohl (path->table_id);
8050   path->sw_if_index = ntohl (path->sw_if_index);
8051
8052   return (1);
8053 }
8054
8055 static int
8056 api_ip_route_add_del (vat_main_t * vam)
8057 {
8058   unformat_input_t *i = vam->input;
8059   vl_api_ip_route_add_del_t *mp;
8060   u32 vrf_id = 0;
8061   u8 is_add = 1;
8062   u8 is_multipath = 0;
8063   u8 prefix_set = 0;
8064   u8 path_count = 0;
8065   vl_api_prefix_t pfx = { };
8066   vl_api_fib_path_t paths[8];
8067   int count = 1;
8068   int j;
8069   f64 before = 0;
8070   u32 random_add_del = 0;
8071   u32 *random_vector = 0;
8072   u32 random_seed = 0xdeaddabe;
8073
8074   /* Parse args required to build the message */
8075   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8076     {
8077       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8078         prefix_set = 1;
8079       else if (unformat (i, "del"))
8080         is_add = 0;
8081       else if (unformat (i, "add"))
8082         is_add = 1;
8083       else if (unformat (i, "vrf %d", &vrf_id))
8084         ;
8085       else if (unformat (i, "count %d", &count))
8086         ;
8087       else if (unformat (i, "random"))
8088         random_add_del = 1;
8089       else if (unformat (i, "multipath"))
8090         is_multipath = 1;
8091       else if (unformat (i, "seed %d", &random_seed))
8092         ;
8093       else
8094         if (unformat
8095             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8096         {
8097           path_count++;
8098           if (8 == path_count)
8099             {
8100               errmsg ("max 8 paths");
8101               return -99;
8102             }
8103         }
8104       else
8105         {
8106           clib_warning ("parse error '%U'", format_unformat_error, i);
8107           return -99;
8108         }
8109     }
8110
8111   if (!path_count)
8112     {
8113       errmsg ("specify a path; via ...");
8114       return -99;
8115     }
8116   if (prefix_set == 0)
8117     {
8118       errmsg ("missing prefix");
8119       return -99;
8120     }
8121
8122   /* Generate a pile of unique, random routes */
8123   if (random_add_del)
8124     {
8125       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
8126       u32 this_random_address;
8127       uword *random_hash;
8128
8129       random_hash = hash_create (count, sizeof (uword));
8130
8131       hash_set (random_hash, i->as_u32, 1);
8132       for (j = 0; j <= count; j++)
8133         {
8134           do
8135             {
8136               this_random_address = random_u32 (&random_seed);
8137               this_random_address =
8138                 clib_host_to_net_u32 (this_random_address);
8139             }
8140           while (hash_get (random_hash, this_random_address));
8141           vec_add1 (random_vector, this_random_address);
8142           hash_set (random_hash, this_random_address, 1);
8143         }
8144       hash_free (random_hash);
8145       set_ip4_address (&pfx.address, random_vector[0]);
8146     }
8147
8148   if (count > 1)
8149     {
8150       /* Turn on async mode */
8151       vam->async_mode = 1;
8152       vam->async_errors = 0;
8153       before = vat_time_now (vam);
8154     }
8155
8156   for (j = 0; j < count; j++)
8157     {
8158       /* Construct the API message */
8159       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8160
8161       mp->is_add = is_add;
8162       mp->is_multipath = is_multipath;
8163
8164       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8165       mp->route.table_id = ntohl (vrf_id);
8166       mp->route.n_paths = path_count;
8167
8168       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
8169
8170       if (random_add_del)
8171         set_ip4_address (&pfx.address, random_vector[j + 1]);
8172       else
8173         increment_address (&pfx.address);
8174       /* send it... */
8175       S (mp);
8176       /* If we receive SIGTERM, stop now... */
8177       if (vam->do_exit)
8178         break;
8179     }
8180
8181   /* When testing multiple add/del ops, use a control-ping to sync */
8182   if (count > 1)
8183     {
8184       vl_api_control_ping_t *mp_ping;
8185       f64 after;
8186       f64 timeout;
8187
8188       /* Shut off async mode */
8189       vam->async_mode = 0;
8190
8191       MPING (CONTROL_PING, mp_ping);
8192       S (mp_ping);
8193
8194       timeout = vat_time_now (vam) + 1.0;
8195       while (vat_time_now (vam) < timeout)
8196         if (vam->result_ready == 1)
8197           goto out;
8198       vam->retval = -99;
8199
8200     out:
8201       if (vam->retval == -99)
8202         errmsg ("timeout");
8203
8204       if (vam->async_errors > 0)
8205         {
8206           errmsg ("%d asynchronous errors", vam->async_errors);
8207           vam->retval = -98;
8208         }
8209       vam->async_errors = 0;
8210       after = vat_time_now (vam);
8211
8212       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8213       if (j > 0)
8214         count = j;
8215
8216       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8217              count, after - before, count / (after - before));
8218     }
8219   else
8220     {
8221       int ret;
8222
8223       /* Wait for a reply... */
8224       W (ret);
8225       return ret;
8226     }
8227
8228   /* Return the good/bad news */
8229   return (vam->retval);
8230 }
8231
8232 static int
8233 api_ip_mroute_add_del (vat_main_t * vam)
8234 {
8235   unformat_input_t *i = vam->input;
8236   u8 path_set = 0, prefix_set = 0, is_add = 1;
8237   vl_api_ip_mroute_add_del_t *mp;
8238   mfib_entry_flags_t eflags = 0;
8239   vl_api_mfib_path_t path;
8240   vl_api_mprefix_t pfx = { };
8241   u32 vrf_id = 0;
8242   int ret;
8243
8244   /* Parse args required to build the message */
8245   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8246     {
8247       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
8248         {
8249           prefix_set = 1;
8250           pfx.grp_address_length = htons (pfx.grp_address_length);
8251         }
8252       else if (unformat (i, "del"))
8253         is_add = 0;
8254       else if (unformat (i, "add"))
8255         is_add = 1;
8256       else if (unformat (i, "vrf %d", &vrf_id))
8257         ;
8258       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
8259         path.itf_flags = htonl (path.itf_flags);
8260       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8261         ;
8262       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
8263         path_set = 1;
8264       else
8265         {
8266           clib_warning ("parse error '%U'", format_unformat_error, i);
8267           return -99;
8268         }
8269     }
8270
8271   if (prefix_set == 0)
8272     {
8273       errmsg ("missing addresses\n");
8274       return -99;
8275     }
8276   if (path_set == 0)
8277     {
8278       errmsg ("missing path\n");
8279       return -99;
8280     }
8281
8282   /* Construct the API message */
8283   M (IP_MROUTE_ADD_DEL, mp);
8284
8285   mp->is_add = is_add;
8286   mp->is_multipath = 1;
8287
8288   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8289   mp->route.table_id = htonl (vrf_id);
8290   mp->route.n_paths = 1;
8291   mp->route.entry_flags = htonl (eflags);
8292
8293   clib_memcpy (&mp->route.paths, &path, sizeof (path));
8294
8295   /* send it... */
8296   S (mp);
8297   /* Wait for a reply... */
8298   W (ret);
8299   return ret;
8300 }
8301
8302 static int
8303 api_mpls_table_add_del (vat_main_t * vam)
8304 {
8305   unformat_input_t *i = vam->input;
8306   vl_api_mpls_table_add_del_t *mp;
8307   u32 table_id = ~0;
8308   u8 is_add = 1;
8309   int ret = 0;
8310
8311   /* Parse args required to build the message */
8312   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8313     {
8314       if (unformat (i, "table %d", &table_id))
8315         ;
8316       else if (unformat (i, "del"))
8317         is_add = 0;
8318       else if (unformat (i, "add"))
8319         is_add = 1;
8320       else
8321         {
8322           clib_warning ("parse error '%U'", format_unformat_error, i);
8323           return -99;
8324         }
8325     }
8326
8327   if (~0 == table_id)
8328     {
8329       errmsg ("missing table-ID");
8330       return -99;
8331     }
8332
8333   /* Construct the API message */
8334   M (MPLS_TABLE_ADD_DEL, mp);
8335
8336   mp->mt_table.mt_table_id = ntohl (table_id);
8337   mp->mt_is_add = is_add;
8338
8339   /* send it... */
8340   S (mp);
8341
8342   /* Wait for a reply... */
8343   W (ret);
8344
8345   return ret;
8346 }
8347
8348 static int
8349 api_mpls_route_add_del (vat_main_t * vam)
8350 {
8351   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
8352   mpls_label_t local_label = MPLS_LABEL_INVALID;
8353   unformat_input_t *i = vam->input;
8354   vl_api_mpls_route_add_del_t *mp;
8355   vl_api_fib_path_t paths[8];
8356   int count = 1, j;
8357   f64 before = 0;
8358
8359   /* Parse args required to build the message */
8360   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8361     {
8362       if (unformat (i, "%d", &local_label))
8363         ;
8364       else if (unformat (i, "eos"))
8365         is_eos = 1;
8366       else if (unformat (i, "non-eos"))
8367         is_eos = 0;
8368       else if (unformat (i, "del"))
8369         is_add = 0;
8370       else if (unformat (i, "add"))
8371         is_add = 1;
8372       else if (unformat (i, "multipath"))
8373         is_multipath = 1;
8374       else if (unformat (i, "count %d", &count))
8375         ;
8376       else
8377         if (unformat
8378             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8379         {
8380           path_count++;
8381           if (8 == path_count)
8382             {
8383               errmsg ("max 8 paths");
8384               return -99;
8385             }
8386         }
8387       else
8388         {
8389           clib_warning ("parse error '%U'", format_unformat_error, i);
8390           return -99;
8391         }
8392     }
8393
8394   if (!path_count)
8395     {
8396       errmsg ("specify a path; via ...");
8397       return -99;
8398     }
8399
8400   if (MPLS_LABEL_INVALID == local_label)
8401     {
8402       errmsg ("missing label");
8403       return -99;
8404     }
8405
8406   if (count > 1)
8407     {
8408       /* Turn on async mode */
8409       vam->async_mode = 1;
8410       vam->async_errors = 0;
8411       before = vat_time_now (vam);
8412     }
8413
8414   for (j = 0; j < count; j++)
8415     {
8416       /* Construct the API message */
8417       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8418
8419       mp->mr_is_add = is_add;
8420       mp->mr_is_multipath = is_multipath;
8421
8422       mp->mr_route.mr_label = local_label;
8423       mp->mr_route.mr_eos = is_eos;
8424       mp->mr_route.mr_table_id = 0;
8425       mp->mr_route.mr_n_paths = path_count;
8426
8427       clib_memcpy (&mp->mr_route.mr_paths, paths,
8428                    sizeof (paths[0]) * path_count);
8429
8430       local_label++;
8431
8432       /* send it... */
8433       S (mp);
8434       /* If we receive SIGTERM, stop now... */
8435       if (vam->do_exit)
8436         break;
8437     }
8438
8439   /* When testing multiple add/del ops, use a control-ping to sync */
8440   if (count > 1)
8441     {
8442       vl_api_control_ping_t *mp_ping;
8443       f64 after;
8444       f64 timeout;
8445
8446       /* Shut off async mode */
8447       vam->async_mode = 0;
8448
8449       MPING (CONTROL_PING, mp_ping);
8450       S (mp_ping);
8451
8452       timeout = vat_time_now (vam) + 1.0;
8453       while (vat_time_now (vam) < timeout)
8454         if (vam->result_ready == 1)
8455           goto out;
8456       vam->retval = -99;
8457
8458     out:
8459       if (vam->retval == -99)
8460         errmsg ("timeout");
8461
8462       if (vam->async_errors > 0)
8463         {
8464           errmsg ("%d asynchronous errors", vam->async_errors);
8465           vam->retval = -98;
8466         }
8467       vam->async_errors = 0;
8468       after = vat_time_now (vam);
8469
8470       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8471       if (j > 0)
8472         count = j;
8473
8474       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8475              count, after - before, count / (after - before));
8476     }
8477   else
8478     {
8479       int ret;
8480
8481       /* Wait for a reply... */
8482       W (ret);
8483       return ret;
8484     }
8485
8486   /* Return the good/bad news */
8487   return (vam->retval);
8488   return (0);
8489 }
8490
8491 static int
8492 api_mpls_ip_bind_unbind (vat_main_t * vam)
8493 {
8494   unformat_input_t *i = vam->input;
8495   vl_api_mpls_ip_bind_unbind_t *mp;
8496   u32 ip_table_id = 0;
8497   u8 is_bind = 1;
8498   vl_api_prefix_t pfx;
8499   u8 prefix_set = 0;
8500   mpls_label_t local_label = MPLS_LABEL_INVALID;
8501   int ret;
8502
8503   /* Parse args required to build the message */
8504   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8505     {
8506       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8507         prefix_set = 1;
8508       else if (unformat (i, "%d", &local_label))
8509         ;
8510       else if (unformat (i, "table-id %d", &ip_table_id))
8511         ;
8512       else if (unformat (i, "unbind"))
8513         is_bind = 0;
8514       else if (unformat (i, "bind"))
8515         is_bind = 1;
8516       else
8517         {
8518           clib_warning ("parse error '%U'", format_unformat_error, i);
8519           return -99;
8520         }
8521     }
8522
8523   if (!prefix_set)
8524     {
8525       errmsg ("IP prefix not set");
8526       return -99;
8527     }
8528
8529   if (MPLS_LABEL_INVALID == local_label)
8530     {
8531       errmsg ("missing label");
8532       return -99;
8533     }
8534
8535   /* Construct the API message */
8536   M (MPLS_IP_BIND_UNBIND, mp);
8537
8538   mp->mb_is_bind = is_bind;
8539   mp->mb_ip_table_id = ntohl (ip_table_id);
8540   mp->mb_mpls_table_id = 0;
8541   mp->mb_label = ntohl (local_label);
8542   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
8543
8544   /* send it... */
8545   S (mp);
8546
8547   /* Wait for a reply... */
8548   W (ret);
8549   return ret;
8550   return (0);
8551 }
8552
8553 static int
8554 api_sr_mpls_policy_add (vat_main_t * vam)
8555 {
8556   unformat_input_t *i = vam->input;
8557   vl_api_sr_mpls_policy_add_t *mp;
8558   u32 bsid = 0;
8559   u32 weight = 1;
8560   u8 type = 0;
8561   u8 n_segments = 0;
8562   u32 sid;
8563   u32 *segments = NULL;
8564   int ret;
8565
8566   /* Parse args required to build the message */
8567   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8568     {
8569       if (unformat (i, "bsid %d", &bsid))
8570         ;
8571       else if (unformat (i, "weight %d", &weight))
8572         ;
8573       else if (unformat (i, "spray"))
8574         type = 1;
8575       else if (unformat (i, "next %d", &sid))
8576         {
8577           n_segments += 1;
8578           vec_add1 (segments, htonl (sid));
8579         }
8580       else
8581         {
8582           clib_warning ("parse error '%U'", format_unformat_error, i);
8583           return -99;
8584         }
8585     }
8586
8587   if (bsid == 0)
8588     {
8589       errmsg ("bsid not set");
8590       return -99;
8591     }
8592
8593   if (n_segments == 0)
8594     {
8595       errmsg ("no sid in segment stack");
8596       return -99;
8597     }
8598
8599   /* Construct the API message */
8600   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8601
8602   mp->bsid = htonl (bsid);
8603   mp->weight = htonl (weight);
8604   mp->is_spray = type;
8605   mp->n_segments = n_segments;
8606   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8607   vec_free (segments);
8608
8609   /* send it... */
8610   S (mp);
8611
8612   /* Wait for a reply... */
8613   W (ret);
8614   return ret;
8615 }
8616
8617 static int
8618 api_sr_mpls_policy_del (vat_main_t * vam)
8619 {
8620   unformat_input_t *i = vam->input;
8621   vl_api_sr_mpls_policy_del_t *mp;
8622   u32 bsid = 0;
8623   int ret;
8624
8625   /* Parse args required to build the message */
8626   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8627     {
8628       if (unformat (i, "bsid %d", &bsid))
8629         ;
8630       else
8631         {
8632           clib_warning ("parse error '%U'", format_unformat_error, i);
8633           return -99;
8634         }
8635     }
8636
8637   if (bsid == 0)
8638     {
8639       errmsg ("bsid not set");
8640       return -99;
8641     }
8642
8643   /* Construct the API message */
8644   M (SR_MPLS_POLICY_DEL, mp);
8645
8646   mp->bsid = htonl (bsid);
8647
8648   /* send it... */
8649   S (mp);
8650
8651   /* Wait for a reply... */
8652   W (ret);
8653   return ret;
8654 }
8655
8656 static int
8657 api_bier_table_add_del (vat_main_t * vam)
8658 {
8659   unformat_input_t *i = vam->input;
8660   vl_api_bier_table_add_del_t *mp;
8661   u8 is_add = 1;
8662   u32 set = 0, sub_domain = 0, hdr_len = 3;
8663   mpls_label_t local_label = MPLS_LABEL_INVALID;
8664   int ret;
8665
8666   /* Parse args required to build the message */
8667   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8668     {
8669       if (unformat (i, "sub-domain %d", &sub_domain))
8670         ;
8671       else if (unformat (i, "set %d", &set))
8672         ;
8673       else if (unformat (i, "label %d", &local_label))
8674         ;
8675       else if (unformat (i, "hdr-len %d", &hdr_len))
8676         ;
8677       else if (unformat (i, "add"))
8678         is_add = 1;
8679       else if (unformat (i, "del"))
8680         is_add = 0;
8681       else
8682         {
8683           clib_warning ("parse error '%U'", format_unformat_error, i);
8684           return -99;
8685         }
8686     }
8687
8688   if (MPLS_LABEL_INVALID == local_label)
8689     {
8690       errmsg ("missing label\n");
8691       return -99;
8692     }
8693
8694   /* Construct the API message */
8695   M (BIER_TABLE_ADD_DEL, mp);
8696
8697   mp->bt_is_add = is_add;
8698   mp->bt_label = ntohl (local_label);
8699   mp->bt_tbl_id.bt_set = set;
8700   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8701   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8702
8703   /* send it... */
8704   S (mp);
8705
8706   /* Wait for a reply... */
8707   W (ret);
8708
8709   return (ret);
8710 }
8711
8712 static int
8713 api_bier_route_add_del (vat_main_t * vam)
8714 {
8715   unformat_input_t *i = vam->input;
8716   vl_api_bier_route_add_del_t *mp;
8717   u8 is_add = 1;
8718   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8719   ip4_address_t v4_next_hop_address;
8720   ip6_address_t v6_next_hop_address;
8721   u8 next_hop_set = 0;
8722   u8 next_hop_proto_is_ip4 = 1;
8723   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8724   int ret;
8725
8726   /* Parse args required to build the message */
8727   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8728     {
8729       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8730         {
8731           next_hop_proto_is_ip4 = 1;
8732           next_hop_set = 1;
8733         }
8734       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8735         {
8736           next_hop_proto_is_ip4 = 0;
8737           next_hop_set = 1;
8738         }
8739       if (unformat (i, "sub-domain %d", &sub_domain))
8740         ;
8741       else if (unformat (i, "set %d", &set))
8742         ;
8743       else if (unformat (i, "hdr-len %d", &hdr_len))
8744         ;
8745       else if (unformat (i, "bp %d", &bp))
8746         ;
8747       else if (unformat (i, "add"))
8748         is_add = 1;
8749       else if (unformat (i, "del"))
8750         is_add = 0;
8751       else if (unformat (i, "out-label %d", &next_hop_out_label))
8752         ;
8753       else
8754         {
8755           clib_warning ("parse error '%U'", format_unformat_error, i);
8756           return -99;
8757         }
8758     }
8759
8760   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8761     {
8762       errmsg ("next hop / label set\n");
8763       return -99;
8764     }
8765   if (0 == bp)
8766     {
8767       errmsg ("bit=position not set\n");
8768       return -99;
8769     }
8770
8771   /* Construct the API message */
8772   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
8773
8774   mp->br_is_add = is_add;
8775   mp->br_route.br_tbl_id.bt_set = set;
8776   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
8777   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
8778   mp->br_route.br_bp = ntohs (bp);
8779   mp->br_route.br_n_paths = 1;
8780   mp->br_route.br_paths[0].n_labels = 1;
8781   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
8782   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
8783                                     FIB_API_PATH_NH_PROTO_IP4 :
8784                                     FIB_API_PATH_NH_PROTO_IP6);
8785
8786   if (next_hop_proto_is_ip4)
8787     {
8788       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
8789                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8790     }
8791   else
8792     {
8793       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
8794                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8795     }
8796
8797   /* send it... */
8798   S (mp);
8799
8800   /* Wait for a reply... */
8801   W (ret);
8802
8803   return (ret);
8804 }
8805
8806 static int
8807 api_mpls_tunnel_add_del (vat_main_t * vam)
8808 {
8809   unformat_input_t *i = vam->input;
8810   vl_api_mpls_tunnel_add_del_t *mp;
8811
8812   vl_api_fib_path_t paths[8];
8813   u32 sw_if_index = ~0;
8814   u8 path_count = 0;
8815   u8 l2_only = 0;
8816   u8 is_add = 1;
8817   int ret;
8818
8819   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8820     {
8821       if (unformat (i, "add"))
8822         is_add = 1;
8823       else
8824         if (unformat
8825             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
8826         is_add = 0;
8827       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8828         is_add = 0;
8829       else if (unformat (i, "l2-only"))
8830         l2_only = 1;
8831       else
8832         if (unformat
8833             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8834         {
8835           path_count++;
8836           if (8 == path_count)
8837             {
8838               errmsg ("max 8 paths");
8839               return -99;
8840             }
8841         }
8842       else
8843         {
8844           clib_warning ("parse error '%U'", format_unformat_error, i);
8845           return -99;
8846         }
8847     }
8848
8849   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8850
8851   mp->mt_is_add = is_add;
8852   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
8853   mp->mt_tunnel.mt_l2_only = l2_only;
8854   mp->mt_tunnel.mt_is_multicast = 0;
8855   mp->mt_tunnel.mt_n_paths = path_count;
8856
8857   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
8858                sizeof (paths[0]) * path_count);
8859
8860   S (mp);
8861   W (ret);
8862   return ret;
8863 }
8864
8865 static int
8866 api_sw_interface_set_unnumbered (vat_main_t * vam)
8867 {
8868   unformat_input_t *i = vam->input;
8869   vl_api_sw_interface_set_unnumbered_t *mp;
8870   u32 sw_if_index;
8871   u32 unnum_sw_index = ~0;
8872   u8 is_add = 1;
8873   u8 sw_if_index_set = 0;
8874   int ret;
8875
8876   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8877     {
8878       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8879         sw_if_index_set = 1;
8880       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8881         sw_if_index_set = 1;
8882       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8883         ;
8884       else if (unformat (i, "del"))
8885         is_add = 0;
8886       else
8887         {
8888           clib_warning ("parse error '%U'", format_unformat_error, i);
8889           return -99;
8890         }
8891     }
8892
8893   if (sw_if_index_set == 0)
8894     {
8895       errmsg ("missing interface name or sw_if_index");
8896       return -99;
8897     }
8898
8899   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8900
8901   mp->sw_if_index = ntohl (sw_if_index);
8902   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8903   mp->is_add = is_add;
8904
8905   S (mp);
8906   W (ret);
8907   return ret;
8908 }
8909
8910
8911 static int
8912 api_create_vlan_subif (vat_main_t * vam)
8913 {
8914   unformat_input_t *i = vam->input;
8915   vl_api_create_vlan_subif_t *mp;
8916   u32 sw_if_index;
8917   u8 sw_if_index_set = 0;
8918   u32 vlan_id;
8919   u8 vlan_id_set = 0;
8920   int ret;
8921
8922   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8923     {
8924       if (unformat (i, "sw_if_index %d", &sw_if_index))
8925         sw_if_index_set = 1;
8926       else
8927         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8928         sw_if_index_set = 1;
8929       else if (unformat (i, "vlan %d", &vlan_id))
8930         vlan_id_set = 1;
8931       else
8932         {
8933           clib_warning ("parse error '%U'", format_unformat_error, i);
8934           return -99;
8935         }
8936     }
8937
8938   if (sw_if_index_set == 0)
8939     {
8940       errmsg ("missing interface name or sw_if_index");
8941       return -99;
8942     }
8943
8944   if (vlan_id_set == 0)
8945     {
8946       errmsg ("missing vlan_id");
8947       return -99;
8948     }
8949   M (CREATE_VLAN_SUBIF, mp);
8950
8951   mp->sw_if_index = ntohl (sw_if_index);
8952   mp->vlan_id = ntohl (vlan_id);
8953
8954   S (mp);
8955   W (ret);
8956   return ret;
8957 }
8958
8959 #define foreach_create_subif_bit                \
8960 _(no_tags)                                      \
8961 _(one_tag)                                      \
8962 _(two_tags)                                     \
8963 _(dot1ad)                                       \
8964 _(exact_match)                                  \
8965 _(default_sub)                                  \
8966 _(outer_vlan_id_any)                            \
8967 _(inner_vlan_id_any)
8968
8969 #define foreach_create_subif_flag               \
8970 _(0, "no_tags")                                 \
8971 _(1, "one_tag")                                 \
8972 _(2, "two_tags")                                \
8973 _(3, "dot1ad")                                  \
8974 _(4, "exact_match")                             \
8975 _(5, "default_sub")                             \
8976 _(6, "outer_vlan_id_any")                       \
8977 _(7, "inner_vlan_id_any")
8978
8979 static int
8980 api_create_subif (vat_main_t * vam)
8981 {
8982   unformat_input_t *i = vam->input;
8983   vl_api_create_subif_t *mp;
8984   u32 sw_if_index;
8985   u8 sw_if_index_set = 0;
8986   u32 sub_id;
8987   u8 sub_id_set = 0;
8988   u32 __attribute__ ((unused)) no_tags = 0;
8989   u32 __attribute__ ((unused)) one_tag = 0;
8990   u32 __attribute__ ((unused)) two_tags = 0;
8991   u32 __attribute__ ((unused)) dot1ad = 0;
8992   u32 __attribute__ ((unused)) exact_match = 0;
8993   u32 __attribute__ ((unused)) default_sub = 0;
8994   u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
8995   u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
8996   u32 tmp;
8997   u16 outer_vlan_id = 0;
8998   u16 inner_vlan_id = 0;
8999   int ret;
9000
9001   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9002     {
9003       if (unformat (i, "sw_if_index %d", &sw_if_index))
9004         sw_if_index_set = 1;
9005       else
9006         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9007         sw_if_index_set = 1;
9008       else if (unformat (i, "sub_id %d", &sub_id))
9009         sub_id_set = 1;
9010       else if (unformat (i, "outer_vlan_id %d", &tmp))
9011         outer_vlan_id = tmp;
9012       else if (unformat (i, "inner_vlan_id %d", &tmp))
9013         inner_vlan_id = tmp;
9014
9015 #define _(a) else if (unformat (i, #a)) a = 1 ;
9016       foreach_create_subif_bit
9017 #undef _
9018         else
9019         {
9020           clib_warning ("parse error '%U'", format_unformat_error, i);
9021           return -99;
9022         }
9023     }
9024
9025   if (sw_if_index_set == 0)
9026     {
9027       errmsg ("missing interface name or sw_if_index");
9028       return -99;
9029     }
9030
9031   if (sub_id_set == 0)
9032     {
9033       errmsg ("missing sub_id");
9034       return -99;
9035     }
9036   M (CREATE_SUBIF, mp);
9037
9038   mp->sw_if_index = ntohl (sw_if_index);
9039   mp->sub_id = ntohl (sub_id);
9040
9041 #define _(a,b) mp->sub_if_flags |= (1 << a);
9042   foreach_create_subif_flag;
9043 #undef _
9044
9045   mp->outer_vlan_id = ntohs (outer_vlan_id);
9046   mp->inner_vlan_id = ntohs (inner_vlan_id);
9047
9048   S (mp);
9049   W (ret);
9050   return ret;
9051 }
9052
9053 static int
9054 api_ip_table_replace_begin (vat_main_t * vam)
9055 {
9056   unformat_input_t *i = vam->input;
9057   vl_api_ip_table_replace_begin_t *mp;
9058   u32 table_id = 0;
9059   u8 is_ipv6 = 0;
9060
9061   int ret;
9062   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9063     {
9064       if (unformat (i, "table %d", &table_id))
9065         ;
9066       else if (unformat (i, "ipv6"))
9067         is_ipv6 = 1;
9068       else
9069         {
9070           clib_warning ("parse error '%U'", format_unformat_error, i);
9071           return -99;
9072         }
9073     }
9074
9075   M (IP_TABLE_REPLACE_BEGIN, mp);
9076
9077   mp->table.table_id = ntohl (table_id);
9078   mp->table.is_ip6 = is_ipv6;
9079
9080   S (mp);
9081   W (ret);
9082   return ret;
9083 }
9084
9085 static int
9086 api_ip_table_flush (vat_main_t * vam)
9087 {
9088   unformat_input_t *i = vam->input;
9089   vl_api_ip_table_flush_t *mp;
9090   u32 table_id = 0;
9091   u8 is_ipv6 = 0;
9092
9093   int ret;
9094   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9095     {
9096       if (unformat (i, "table %d", &table_id))
9097         ;
9098       else if (unformat (i, "ipv6"))
9099         is_ipv6 = 1;
9100       else
9101         {
9102           clib_warning ("parse error '%U'", format_unformat_error, i);
9103           return -99;
9104         }
9105     }
9106
9107   M (IP_TABLE_FLUSH, mp);
9108
9109   mp->table.table_id = ntohl (table_id);
9110   mp->table.is_ip6 = is_ipv6;
9111
9112   S (mp);
9113   W (ret);
9114   return ret;
9115 }
9116
9117 static int
9118 api_ip_table_replace_end (vat_main_t * vam)
9119 {
9120   unformat_input_t *i = vam->input;
9121   vl_api_ip_table_replace_end_t *mp;
9122   u32 table_id = 0;
9123   u8 is_ipv6 = 0;
9124
9125   int ret;
9126   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9127     {
9128       if (unformat (i, "table %d", &table_id))
9129         ;
9130       else if (unformat (i, "ipv6"))
9131         is_ipv6 = 1;
9132       else
9133         {
9134           clib_warning ("parse error '%U'", format_unformat_error, i);
9135           return -99;
9136         }
9137     }
9138
9139   M (IP_TABLE_REPLACE_END, mp);
9140
9141   mp->table.table_id = ntohl (table_id);
9142   mp->table.is_ip6 = is_ipv6;
9143
9144   S (mp);
9145   W (ret);
9146   return ret;
9147 }
9148
9149 static int
9150 api_set_ip_flow_hash (vat_main_t * vam)
9151 {
9152   unformat_input_t *i = vam->input;
9153   vl_api_set_ip_flow_hash_t *mp;
9154   u32 vrf_id = 0;
9155   u8 is_ipv6 = 0;
9156   u8 vrf_id_set = 0;
9157   u8 src = 0;
9158   u8 dst = 0;
9159   u8 sport = 0;
9160   u8 dport = 0;
9161   u8 proto = 0;
9162   u8 reverse = 0;
9163   int ret;
9164
9165   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9166     {
9167       if (unformat (i, "vrf %d", &vrf_id))
9168         vrf_id_set = 1;
9169       else if (unformat (i, "ipv6"))
9170         is_ipv6 = 1;
9171       else if (unformat (i, "src"))
9172         src = 1;
9173       else if (unformat (i, "dst"))
9174         dst = 1;
9175       else if (unformat (i, "sport"))
9176         sport = 1;
9177       else if (unformat (i, "dport"))
9178         dport = 1;
9179       else if (unformat (i, "proto"))
9180         proto = 1;
9181       else if (unformat (i, "reverse"))
9182         reverse = 1;
9183
9184       else
9185         {
9186           clib_warning ("parse error '%U'", format_unformat_error, i);
9187           return -99;
9188         }
9189     }
9190
9191   if (vrf_id_set == 0)
9192     {
9193       errmsg ("missing vrf id");
9194       return -99;
9195     }
9196
9197   M (SET_IP_FLOW_HASH, mp);
9198   mp->src = src;
9199   mp->dst = dst;
9200   mp->sport = sport;
9201   mp->dport = dport;
9202   mp->proto = proto;
9203   mp->reverse = reverse;
9204   mp->vrf_id = ntohl (vrf_id);
9205   mp->is_ipv6 = is_ipv6;
9206
9207   S (mp);
9208   W (ret);
9209   return ret;
9210 }
9211
9212 static int
9213 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9214 {
9215   unformat_input_t *i = vam->input;
9216   vl_api_sw_interface_ip6_enable_disable_t *mp;
9217   u32 sw_if_index;
9218   u8 sw_if_index_set = 0;
9219   u8 enable = 0;
9220   int ret;
9221
9222   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9223     {
9224       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9225         sw_if_index_set = 1;
9226       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9227         sw_if_index_set = 1;
9228       else if (unformat (i, "enable"))
9229         enable = 1;
9230       else if (unformat (i, "disable"))
9231         enable = 0;
9232       else
9233         {
9234           clib_warning ("parse error '%U'", format_unformat_error, i);
9235           return -99;
9236         }
9237     }
9238
9239   if (sw_if_index_set == 0)
9240     {
9241       errmsg ("missing interface name or sw_if_index");
9242       return -99;
9243     }
9244
9245   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9246
9247   mp->sw_if_index = ntohl (sw_if_index);
9248   mp->enable = enable;
9249
9250   S (mp);
9251   W (ret);
9252   return ret;
9253 }
9254
9255
9256 static int
9257 api_l2_patch_add_del (vat_main_t * vam)
9258 {
9259   unformat_input_t *i = vam->input;
9260   vl_api_l2_patch_add_del_t *mp;
9261   u32 rx_sw_if_index;
9262   u8 rx_sw_if_index_set = 0;
9263   u32 tx_sw_if_index;
9264   u8 tx_sw_if_index_set = 0;
9265   u8 is_add = 1;
9266   int ret;
9267
9268   /* Parse args required to build the message */
9269   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9270     {
9271       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9272         rx_sw_if_index_set = 1;
9273       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9274         tx_sw_if_index_set = 1;
9275       else if (unformat (i, "rx"))
9276         {
9277           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9278             {
9279               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9280                             &rx_sw_if_index))
9281                 rx_sw_if_index_set = 1;
9282             }
9283           else
9284             break;
9285         }
9286       else if (unformat (i, "tx"))
9287         {
9288           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9289             {
9290               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9291                             &tx_sw_if_index))
9292                 tx_sw_if_index_set = 1;
9293             }
9294           else
9295             break;
9296         }
9297       else if (unformat (i, "del"))
9298         is_add = 0;
9299       else
9300         break;
9301     }
9302
9303   if (rx_sw_if_index_set == 0)
9304     {
9305       errmsg ("missing rx interface name or rx_sw_if_index");
9306       return -99;
9307     }
9308
9309   if (tx_sw_if_index_set == 0)
9310     {
9311       errmsg ("missing tx interface name or tx_sw_if_index");
9312       return -99;
9313     }
9314
9315   M (L2_PATCH_ADD_DEL, mp);
9316
9317   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9318   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9319   mp->is_add = is_add;
9320
9321   S (mp);
9322   W (ret);
9323   return ret;
9324 }
9325
9326 u8 is_del;
9327 u8 localsid_addr[16];
9328 u8 end_psp;
9329 u8 behavior;
9330 u32 sw_if_index;
9331 u32 vlan_index;
9332 u32 fib_table;
9333 u8 nh_addr[16];
9334
9335 static int
9336 api_sr_localsid_add_del (vat_main_t * vam)
9337 {
9338   unformat_input_t *i = vam->input;
9339   vl_api_sr_localsid_add_del_t *mp;
9340
9341   u8 is_del;
9342   ip6_address_t localsid;
9343   u8 end_psp = 0;
9344   u8 behavior = ~0;
9345   u32 sw_if_index;
9346   u32 fib_table = ~(u32) 0;
9347   ip46_address_t nh_addr;
9348   clib_memset (&nh_addr, 0, sizeof (ip46_address_t));
9349
9350   bool nexthop_set = 0;
9351
9352   int ret;
9353
9354   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9355     {
9356       if (unformat (i, "del"))
9357         is_del = 1;
9358       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9359       else if (unformat (i, "next-hop %U", unformat_ip46_address, &nh_addr))
9360         nexthop_set = 1;
9361       else if (unformat (i, "behavior %u", &behavior));
9362       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9363       else if (unformat (i, "fib-table %u", &fib_table));
9364       else if (unformat (i, "end.psp %u", &behavior));
9365       else
9366         break;
9367     }
9368
9369   M (SR_LOCALSID_ADD_DEL, mp);
9370
9371   clib_memcpy (mp->localsid, &localsid, sizeof (mp->localsid));
9372
9373   if (nexthop_set)
9374     {
9375       clib_memcpy (&mp->nh_addr.un, &nh_addr, sizeof (mp->nh_addr.un));
9376     }
9377   mp->behavior = behavior;
9378   mp->sw_if_index = ntohl (sw_if_index);
9379   mp->fib_table = ntohl (fib_table);
9380   mp->end_psp = end_psp;
9381   mp->is_del = is_del;
9382
9383   S (mp);
9384   W (ret);
9385   return ret;
9386 }
9387
9388 static int
9389 api_ioam_enable (vat_main_t * vam)
9390 {
9391   unformat_input_t *input = vam->input;
9392   vl_api_ioam_enable_t *mp;
9393   u32 id = 0;
9394   int has_trace_option = 0;
9395   int has_pot_option = 0;
9396   int has_seqno_option = 0;
9397   int has_analyse_option = 0;
9398   int ret;
9399
9400   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9401     {
9402       if (unformat (input, "trace"))
9403         has_trace_option = 1;
9404       else if (unformat (input, "pot"))
9405         has_pot_option = 1;
9406       else if (unformat (input, "seqno"))
9407         has_seqno_option = 1;
9408       else if (unformat (input, "analyse"))
9409         has_analyse_option = 1;
9410       else
9411         break;
9412     }
9413   M (IOAM_ENABLE, mp);
9414   mp->id = htons (id);
9415   mp->seqno = has_seqno_option;
9416   mp->analyse = has_analyse_option;
9417   mp->pot_enable = has_pot_option;
9418   mp->trace_enable = has_trace_option;
9419
9420   S (mp);
9421   W (ret);
9422   return ret;
9423 }
9424
9425
9426 static int
9427 api_ioam_disable (vat_main_t * vam)
9428 {
9429   vl_api_ioam_disable_t *mp;
9430   int ret;
9431
9432   M (IOAM_DISABLE, mp);
9433   S (mp);
9434   W (ret);
9435   return ret;
9436 }
9437
9438 #define foreach_tcp_proto_field                 \
9439 _(src_port)                                     \
9440 _(dst_port)
9441
9442 #define foreach_udp_proto_field                 \
9443 _(src_port)                                     \
9444 _(dst_port)
9445
9446 #define foreach_ip4_proto_field                 \
9447 _(src_address)                                  \
9448 _(dst_address)                                  \
9449 _(tos)                                          \
9450 _(length)                                       \
9451 _(fragment_id)                                  \
9452 _(ttl)                                          \
9453 _(protocol)                                     \
9454 _(checksum)
9455
9456 typedef struct
9457 {
9458   u16 src_port, dst_port;
9459 } tcpudp_header_t;
9460
9461 #if VPP_API_TEST_BUILTIN == 0
9462 uword
9463 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9464 {
9465   u8 **maskp = va_arg (*args, u8 **);
9466   u8 *mask = 0;
9467   u8 found_something = 0;
9468   tcp_header_t *tcp;
9469
9470 #define _(a) u8 a=0;
9471   foreach_tcp_proto_field;
9472 #undef _
9473
9474   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9475     {
9476       if (0);
9477 #define _(a) else if (unformat (input, #a)) a=1;
9478       foreach_tcp_proto_field
9479 #undef _
9480         else
9481         break;
9482     }
9483
9484 #define _(a) found_something += a;
9485   foreach_tcp_proto_field;
9486 #undef _
9487
9488   if (found_something == 0)
9489     return 0;
9490
9491   vec_validate (mask, sizeof (*tcp) - 1);
9492
9493   tcp = (tcp_header_t *) mask;
9494
9495 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
9496   foreach_tcp_proto_field;
9497 #undef _
9498
9499   *maskp = mask;
9500   return 1;
9501 }
9502
9503 uword
9504 unformat_udp_mask (unformat_input_t * input, va_list * args)
9505 {
9506   u8 **maskp = va_arg (*args, u8 **);
9507   u8 *mask = 0;
9508   u8 found_something = 0;
9509   udp_header_t *udp;
9510
9511 #define _(a) u8 a=0;
9512   foreach_udp_proto_field;
9513 #undef _
9514
9515   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9516     {
9517       if (0);
9518 #define _(a) else if (unformat (input, #a)) a=1;
9519       foreach_udp_proto_field
9520 #undef _
9521         else
9522         break;
9523     }
9524
9525 #define _(a) found_something += a;
9526   foreach_udp_proto_field;
9527 #undef _
9528
9529   if (found_something == 0)
9530     return 0;
9531
9532   vec_validate (mask, sizeof (*udp) - 1);
9533
9534   udp = (udp_header_t *) mask;
9535
9536 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
9537   foreach_udp_proto_field;
9538 #undef _
9539
9540   *maskp = mask;
9541   return 1;
9542 }
9543
9544 uword
9545 unformat_l4_mask (unformat_input_t * input, va_list * args)
9546 {
9547   u8 **maskp = va_arg (*args, u8 **);
9548   u16 src_port = 0, dst_port = 0;
9549   tcpudp_header_t *tcpudp;
9550
9551   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9552     {
9553       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9554         return 1;
9555       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9556         return 1;
9557       else if (unformat (input, "src_port"))
9558         src_port = 0xFFFF;
9559       else if (unformat (input, "dst_port"))
9560         dst_port = 0xFFFF;
9561       else
9562         return 0;
9563     }
9564
9565   if (!src_port && !dst_port)
9566     return 0;
9567
9568   u8 *mask = 0;
9569   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9570
9571   tcpudp = (tcpudp_header_t *) mask;
9572   tcpudp->src_port = src_port;
9573   tcpudp->dst_port = dst_port;
9574
9575   *maskp = mask;
9576
9577   return 1;
9578 }
9579
9580 uword
9581 unformat_ip4_mask (unformat_input_t * input, va_list * args)
9582 {
9583   u8 **maskp = va_arg (*args, u8 **);
9584   u8 *mask = 0;
9585   u8 found_something = 0;
9586   ip4_header_t *ip;
9587
9588 #define _(a) u8 a=0;
9589   foreach_ip4_proto_field;
9590 #undef _
9591   u8 version = 0;
9592   u8 hdr_length = 0;
9593
9594
9595   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9596     {
9597       if (unformat (input, "version"))
9598         version = 1;
9599       else if (unformat (input, "hdr_length"))
9600         hdr_length = 1;
9601       else if (unformat (input, "src"))
9602         src_address = 1;
9603       else if (unformat (input, "dst"))
9604         dst_address = 1;
9605       else if (unformat (input, "proto"))
9606         protocol = 1;
9607
9608 #define _(a) else if (unformat (input, #a)) a=1;
9609       foreach_ip4_proto_field
9610 #undef _
9611         else
9612         break;
9613     }
9614
9615 #define _(a) found_something += a;
9616   foreach_ip4_proto_field;
9617 #undef _
9618
9619   if (found_something == 0)
9620     return 0;
9621
9622   vec_validate (mask, sizeof (*ip) - 1);
9623
9624   ip = (ip4_header_t *) mask;
9625
9626 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
9627   foreach_ip4_proto_field;
9628 #undef _
9629
9630   ip->ip_version_and_header_length = 0;
9631
9632   if (version)
9633     ip->ip_version_and_header_length |= 0xF0;
9634
9635   if (hdr_length)
9636     ip->ip_version_and_header_length |= 0x0F;
9637
9638   *maskp = mask;
9639   return 1;
9640 }
9641
9642 #define foreach_ip6_proto_field                 \
9643 _(src_address)                                  \
9644 _(dst_address)                                  \
9645 _(payload_length)                               \
9646 _(hop_limit)                                    \
9647 _(protocol)
9648
9649 uword
9650 unformat_ip6_mask (unformat_input_t * input, va_list * args)
9651 {
9652   u8 **maskp = va_arg (*args, u8 **);
9653   u8 *mask = 0;
9654   u8 found_something = 0;
9655   ip6_header_t *ip;
9656   u32 ip_version_traffic_class_and_flow_label;
9657
9658 #define _(a) u8 a=0;
9659   foreach_ip6_proto_field;
9660 #undef _
9661   u8 version = 0;
9662   u8 traffic_class = 0;
9663   u8 flow_label = 0;
9664
9665   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9666     {
9667       if (unformat (input, "version"))
9668         version = 1;
9669       else if (unformat (input, "traffic-class"))
9670         traffic_class = 1;
9671       else if (unformat (input, "flow-label"))
9672         flow_label = 1;
9673       else if (unformat (input, "src"))
9674         src_address = 1;
9675       else if (unformat (input, "dst"))
9676         dst_address = 1;
9677       else if (unformat (input, "proto"))
9678         protocol = 1;
9679
9680 #define _(a) else if (unformat (input, #a)) a=1;
9681       foreach_ip6_proto_field
9682 #undef _
9683         else
9684         break;
9685     }
9686
9687 #define _(a) found_something += a;
9688   foreach_ip6_proto_field;
9689 #undef _
9690
9691   if (found_something == 0)
9692     return 0;
9693
9694   vec_validate (mask, sizeof (*ip) - 1);
9695
9696   ip = (ip6_header_t *) mask;
9697
9698 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
9699   foreach_ip6_proto_field;
9700 #undef _
9701
9702   ip_version_traffic_class_and_flow_label = 0;
9703
9704   if (version)
9705     ip_version_traffic_class_and_flow_label |= 0xF0000000;
9706
9707   if (traffic_class)
9708     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9709
9710   if (flow_label)
9711     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9712
9713   ip->ip_version_traffic_class_and_flow_label =
9714     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9715
9716   *maskp = mask;
9717   return 1;
9718 }
9719
9720 uword
9721 unformat_l3_mask (unformat_input_t * input, va_list * args)
9722 {
9723   u8 **maskp = va_arg (*args, u8 **);
9724
9725   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9726     {
9727       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9728         return 1;
9729       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9730         return 1;
9731       else
9732         break;
9733     }
9734   return 0;
9735 }
9736
9737 uword
9738 unformat_l2_mask (unformat_input_t * input, va_list * args)
9739 {
9740   u8 **maskp = va_arg (*args, u8 **);
9741   u8 *mask = 0;
9742   u8 src = 0;
9743   u8 dst = 0;
9744   u8 proto = 0;
9745   u8 tag1 = 0;
9746   u8 tag2 = 0;
9747   u8 ignore_tag1 = 0;
9748   u8 ignore_tag2 = 0;
9749   u8 cos1 = 0;
9750   u8 cos2 = 0;
9751   u8 dot1q = 0;
9752   u8 dot1ad = 0;
9753   int len = 14;
9754
9755   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9756     {
9757       if (unformat (input, "src"))
9758         src = 1;
9759       else if (unformat (input, "dst"))
9760         dst = 1;
9761       else if (unformat (input, "proto"))
9762         proto = 1;
9763       else if (unformat (input, "tag1"))
9764         tag1 = 1;
9765       else if (unformat (input, "tag2"))
9766         tag2 = 1;
9767       else if (unformat (input, "ignore-tag1"))
9768         ignore_tag1 = 1;
9769       else if (unformat (input, "ignore-tag2"))
9770         ignore_tag2 = 1;
9771       else if (unformat (input, "cos1"))
9772         cos1 = 1;
9773       else if (unformat (input, "cos2"))
9774         cos2 = 1;
9775       else if (unformat (input, "dot1q"))
9776         dot1q = 1;
9777       else if (unformat (input, "dot1ad"))
9778         dot1ad = 1;
9779       else
9780         break;
9781     }
9782   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9783        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9784     return 0;
9785
9786   if (tag1 || ignore_tag1 || cos1 || dot1q)
9787     len = 18;
9788   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9789     len = 22;
9790
9791   vec_validate (mask, len - 1);
9792
9793   if (dst)
9794     clib_memset (mask, 0xff, 6);
9795
9796   if (src)
9797     clib_memset (mask + 6, 0xff, 6);
9798
9799   if (tag2 || dot1ad)
9800     {
9801       /* inner vlan tag */
9802       if (tag2)
9803         {
9804           mask[19] = 0xff;
9805           mask[18] = 0x0f;
9806         }
9807       if (cos2)
9808         mask[18] |= 0xe0;
9809       if (proto)
9810         mask[21] = mask[20] = 0xff;
9811       if (tag1)
9812         {
9813           mask[15] = 0xff;
9814           mask[14] = 0x0f;
9815         }
9816       if (cos1)
9817         mask[14] |= 0xe0;
9818       *maskp = mask;
9819       return 1;
9820     }
9821   if (tag1 | dot1q)
9822     {
9823       if (tag1)
9824         {
9825           mask[15] = 0xff;
9826           mask[14] = 0x0f;
9827         }
9828       if (cos1)
9829         mask[14] |= 0xe0;
9830       if (proto)
9831         mask[16] = mask[17] = 0xff;
9832
9833       *maskp = mask;
9834       return 1;
9835     }
9836   if (cos2)
9837     mask[18] |= 0xe0;
9838   if (cos1)
9839     mask[14] |= 0xe0;
9840   if (proto)
9841     mask[12] = mask[13] = 0xff;
9842
9843   *maskp = mask;
9844   return 1;
9845 }
9846
9847 uword
9848 unformat_classify_mask (unformat_input_t * input, va_list * args)
9849 {
9850   u8 **maskp = va_arg (*args, u8 **);
9851   u32 *skipp = va_arg (*args, u32 *);
9852   u32 *matchp = va_arg (*args, u32 *);
9853   u32 match;
9854   u8 *mask = 0;
9855   u8 *l2 = 0;
9856   u8 *l3 = 0;
9857   u8 *l4 = 0;
9858   int i;
9859
9860   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9861     {
9862       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9863         ;
9864       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9865         ;
9866       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9867         ;
9868       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9869         ;
9870       else
9871         break;
9872     }
9873
9874   if (l4 && !l3)
9875     {
9876       vec_free (mask);
9877       vec_free (l2);
9878       vec_free (l4);
9879       return 0;
9880     }
9881
9882   if (mask || l2 || l3 || l4)
9883     {
9884       if (l2 || l3 || l4)
9885         {
9886           /* "With a free Ethernet header in every package" */
9887           if (l2 == 0)
9888             vec_validate (l2, 13);
9889           mask = l2;
9890           if (vec_len (l3))
9891             {
9892               vec_append (mask, l3);
9893               vec_free (l3);
9894             }
9895           if (vec_len (l4))
9896             {
9897               vec_append (mask, l4);
9898               vec_free (l4);
9899             }
9900         }
9901
9902       /* Scan forward looking for the first significant mask octet */
9903       for (i = 0; i < vec_len (mask); i++)
9904         if (mask[i])
9905           break;
9906
9907       /* compute (skip, match) params */
9908       *skipp = i / sizeof (u32x4);
9909       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9910
9911       /* Pad mask to an even multiple of the vector size */
9912       while (vec_len (mask) % sizeof (u32x4))
9913         vec_add1 (mask, 0);
9914
9915       match = vec_len (mask) / sizeof (u32x4);
9916
9917       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9918         {
9919           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9920           if (*tmp || *(tmp + 1))
9921             break;
9922           match--;
9923         }
9924       if (match == 0)
9925         clib_warning ("BUG: match 0");
9926
9927       _vec_len (mask) = match * sizeof (u32x4);
9928
9929       *matchp = match;
9930       *maskp = mask;
9931
9932       return 1;
9933     }
9934
9935   return 0;
9936 }
9937 #endif /* VPP_API_TEST_BUILTIN */
9938
9939 #define foreach_l2_next                         \
9940 _(drop, DROP)                                   \
9941 _(ethernet, ETHERNET_INPUT)                     \
9942 _(ip4, IP4_INPUT)                               \
9943 _(ip6, IP6_INPUT)
9944
9945 uword
9946 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9947 {
9948   u32 *miss_next_indexp = va_arg (*args, u32 *);
9949   u32 next_index = 0;
9950   u32 tmp;
9951
9952 #define _(n,N) \
9953   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9954   foreach_l2_next;
9955 #undef _
9956
9957   if (unformat (input, "%d", &tmp))
9958     {
9959       next_index = tmp;
9960       goto out;
9961     }
9962
9963   return 0;
9964
9965 out:
9966   *miss_next_indexp = next_index;
9967   return 1;
9968 }
9969
9970 #define foreach_ip_next                         \
9971 _(drop, DROP)                                   \
9972 _(local, LOCAL)                                 \
9973 _(rewrite, REWRITE)
9974
9975 uword
9976 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9977 {
9978   u32 *miss_next_indexp = va_arg (*args, u32 *);
9979   u32 next_index = 0;
9980   u32 tmp;
9981
9982 #define _(n,N) \
9983   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9984   foreach_ip_next;
9985 #undef _
9986
9987   if (unformat (input, "%d", &tmp))
9988     {
9989       next_index = tmp;
9990       goto out;
9991     }
9992
9993   return 0;
9994
9995 out:
9996   *miss_next_indexp = next_index;
9997   return 1;
9998 }
9999
10000 #define foreach_acl_next                        \
10001 _(deny, DENY)
10002
10003 uword
10004 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10005 {
10006   u32 *miss_next_indexp = va_arg (*args, u32 *);
10007   u32 next_index = 0;
10008   u32 tmp;
10009
10010 #define _(n,N) \
10011   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10012   foreach_acl_next;
10013 #undef _
10014
10015   if (unformat (input, "permit"))
10016     {
10017       next_index = ~0;
10018       goto out;
10019     }
10020   else if (unformat (input, "%d", &tmp))
10021     {
10022       next_index = tmp;
10023       goto out;
10024     }
10025
10026   return 0;
10027
10028 out:
10029   *miss_next_indexp = next_index;
10030   return 1;
10031 }
10032
10033 uword
10034 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10035 {
10036   u32 *r = va_arg (*args, u32 *);
10037
10038   if (unformat (input, "conform-color"))
10039     *r = POLICE_CONFORM;
10040   else if (unformat (input, "exceed-color"))
10041     *r = POLICE_EXCEED;
10042   else
10043     return 0;
10044
10045   return 1;
10046 }
10047
10048 static int
10049 api_classify_add_del_table (vat_main_t * vam)
10050 {
10051   unformat_input_t *i = vam->input;
10052   vl_api_classify_add_del_table_t *mp;
10053
10054   u32 nbuckets = 2;
10055   u32 skip = ~0;
10056   u32 match = ~0;
10057   int is_add = 1;
10058   int del_chain = 0;
10059   u32 table_index = ~0;
10060   u32 next_table_index = ~0;
10061   u32 miss_next_index = ~0;
10062   u32 memory_size = 32 << 20;
10063   u8 *mask = 0;
10064   u32 current_data_flag = 0;
10065   int current_data_offset = 0;
10066   int ret;
10067
10068   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10069     {
10070       if (unformat (i, "del"))
10071         is_add = 0;
10072       else if (unformat (i, "del-chain"))
10073         {
10074           is_add = 0;
10075           del_chain = 1;
10076         }
10077       else if (unformat (i, "buckets %d", &nbuckets))
10078         ;
10079       else if (unformat (i, "memory_size %d", &memory_size))
10080         ;
10081       else if (unformat (i, "skip %d", &skip))
10082         ;
10083       else if (unformat (i, "match %d", &match))
10084         ;
10085       else if (unformat (i, "table %d", &table_index))
10086         ;
10087       else if (unformat (i, "mask %U", unformat_classify_mask,
10088                          &mask, &skip, &match))
10089         ;
10090       else if (unformat (i, "next-table %d", &next_table_index))
10091         ;
10092       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10093                          &miss_next_index))
10094         ;
10095       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10096                          &miss_next_index))
10097         ;
10098       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10099                          &miss_next_index))
10100         ;
10101       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10102         ;
10103       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10104         ;
10105       else
10106         break;
10107     }
10108
10109   if (is_add && mask == 0)
10110     {
10111       errmsg ("Mask required");
10112       return -99;
10113     }
10114
10115   if (is_add && skip == ~0)
10116     {
10117       errmsg ("skip count required");
10118       return -99;
10119     }
10120
10121   if (is_add && match == ~0)
10122     {
10123       errmsg ("match count required");
10124       return -99;
10125     }
10126
10127   if (!is_add && table_index == ~0)
10128     {
10129       errmsg ("table index required for delete");
10130       return -99;
10131     }
10132
10133   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10134
10135   mp->is_add = is_add;
10136   mp->del_chain = del_chain;
10137   mp->table_index = ntohl (table_index);
10138   mp->nbuckets = ntohl (nbuckets);
10139   mp->memory_size = ntohl (memory_size);
10140   mp->skip_n_vectors = ntohl (skip);
10141   mp->match_n_vectors = ntohl (match);
10142   mp->next_table_index = ntohl (next_table_index);
10143   mp->miss_next_index = ntohl (miss_next_index);
10144   mp->current_data_flag = ntohl (current_data_flag);
10145   mp->current_data_offset = ntohl (current_data_offset);
10146   mp->mask_len = ntohl (vec_len (mask));
10147   clib_memcpy (mp->mask, mask, vec_len (mask));
10148
10149   vec_free (mask);
10150
10151   S (mp);
10152   W (ret);
10153   return ret;
10154 }
10155
10156 #if VPP_API_TEST_BUILTIN == 0
10157 uword
10158 unformat_l4_match (unformat_input_t * input, va_list * args)
10159 {
10160   u8 **matchp = va_arg (*args, u8 **);
10161
10162   u8 *proto_header = 0;
10163   int src_port = 0;
10164   int dst_port = 0;
10165
10166   tcpudp_header_t h;
10167
10168   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10169     {
10170       if (unformat (input, "src_port %d", &src_port))
10171         ;
10172       else if (unformat (input, "dst_port %d", &dst_port))
10173         ;
10174       else
10175         return 0;
10176     }
10177
10178   h.src_port = clib_host_to_net_u16 (src_port);
10179   h.dst_port = clib_host_to_net_u16 (dst_port);
10180   vec_validate (proto_header, sizeof (h) - 1);
10181   memcpy (proto_header, &h, sizeof (h));
10182
10183   *matchp = proto_header;
10184
10185   return 1;
10186 }
10187
10188 uword
10189 unformat_ip4_match (unformat_input_t * input, va_list * args)
10190 {
10191   u8 **matchp = va_arg (*args, u8 **);
10192   u8 *match = 0;
10193   ip4_header_t *ip;
10194   int version = 0;
10195   u32 version_val;
10196   int hdr_length = 0;
10197   u32 hdr_length_val;
10198   int src = 0, dst = 0;
10199   ip4_address_t src_val, dst_val;
10200   int proto = 0;
10201   u32 proto_val;
10202   int tos = 0;
10203   u32 tos_val;
10204   int length = 0;
10205   u32 length_val;
10206   int fragment_id = 0;
10207   u32 fragment_id_val;
10208   int ttl = 0;
10209   int ttl_val;
10210   int checksum = 0;
10211   u32 checksum_val;
10212
10213   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10214     {
10215       if (unformat (input, "version %d", &version_val))
10216         version = 1;
10217       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10218         hdr_length = 1;
10219       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10220         src = 1;
10221       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10222         dst = 1;
10223       else if (unformat (input, "proto %d", &proto_val))
10224         proto = 1;
10225       else if (unformat (input, "tos %d", &tos_val))
10226         tos = 1;
10227       else if (unformat (input, "length %d", &length_val))
10228         length = 1;
10229       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10230         fragment_id = 1;
10231       else if (unformat (input, "ttl %d", &ttl_val))
10232         ttl = 1;
10233       else if (unformat (input, "checksum %d", &checksum_val))
10234         checksum = 1;
10235       else
10236         break;
10237     }
10238
10239   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10240       + ttl + checksum == 0)
10241     return 0;
10242
10243   /*
10244    * Aligned because we use the real comparison functions
10245    */
10246   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10247
10248   ip = (ip4_header_t *) match;
10249
10250   /* These are realistically matched in practice */
10251   if (src)
10252     ip->src_address.as_u32 = src_val.as_u32;
10253
10254   if (dst)
10255     ip->dst_address.as_u32 = dst_val.as_u32;
10256
10257   if (proto)
10258     ip->protocol = proto_val;
10259
10260
10261   /* These are not, but they're included for completeness */
10262   if (version)
10263     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10264
10265   if (hdr_length)
10266     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10267
10268   if (tos)
10269     ip->tos = tos_val;
10270
10271   if (length)
10272     ip->length = clib_host_to_net_u16 (length_val);
10273
10274   if (ttl)
10275     ip->ttl = ttl_val;
10276
10277   if (checksum)
10278     ip->checksum = clib_host_to_net_u16 (checksum_val);
10279
10280   *matchp = match;
10281   return 1;
10282 }
10283
10284 uword
10285 unformat_ip6_match (unformat_input_t * input, va_list * args)
10286 {
10287   u8 **matchp = va_arg (*args, u8 **);
10288   u8 *match = 0;
10289   ip6_header_t *ip;
10290   int version = 0;
10291   u32 version_val;
10292   u8 traffic_class = 0;
10293   u32 traffic_class_val = 0;
10294   u8 flow_label = 0;
10295   u8 flow_label_val;
10296   int src = 0, dst = 0;
10297   ip6_address_t src_val, dst_val;
10298   int proto = 0;
10299   u32 proto_val;
10300   int payload_length = 0;
10301   u32 payload_length_val;
10302   int hop_limit = 0;
10303   int hop_limit_val;
10304   u32 ip_version_traffic_class_and_flow_label;
10305
10306   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10307     {
10308       if (unformat (input, "version %d", &version_val))
10309         version = 1;
10310       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10311         traffic_class = 1;
10312       else if (unformat (input, "flow_label %d", &flow_label_val))
10313         flow_label = 1;
10314       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10315         src = 1;
10316       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10317         dst = 1;
10318       else if (unformat (input, "proto %d", &proto_val))
10319         proto = 1;
10320       else if (unformat (input, "payload_length %d", &payload_length_val))
10321         payload_length = 1;
10322       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10323         hop_limit = 1;
10324       else
10325         break;
10326     }
10327
10328   if (version + traffic_class + flow_label + src + dst + proto +
10329       payload_length + hop_limit == 0)
10330     return 0;
10331
10332   /*
10333    * Aligned because we use the real comparison functions
10334    */
10335   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10336
10337   ip = (ip6_header_t *) match;
10338
10339   if (src)
10340     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10341
10342   if (dst)
10343     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10344
10345   if (proto)
10346     ip->protocol = proto_val;
10347
10348   ip_version_traffic_class_and_flow_label = 0;
10349
10350   if (version)
10351     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10352
10353   if (traffic_class)
10354     ip_version_traffic_class_and_flow_label |=
10355       (traffic_class_val & 0xFF) << 20;
10356
10357   if (flow_label)
10358     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10359
10360   ip->ip_version_traffic_class_and_flow_label =
10361     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10362
10363   if (payload_length)
10364     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10365
10366   if (hop_limit)
10367     ip->hop_limit = hop_limit_val;
10368
10369   *matchp = match;
10370   return 1;
10371 }
10372
10373 uword
10374 unformat_l3_match (unformat_input_t * input, va_list * args)
10375 {
10376   u8 **matchp = va_arg (*args, u8 **);
10377
10378   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10379     {
10380       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10381         return 1;
10382       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10383         return 1;
10384       else
10385         break;
10386     }
10387   return 0;
10388 }
10389
10390 uword
10391 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10392 {
10393   u8 *tagp = va_arg (*args, u8 *);
10394   u32 tag;
10395
10396   if (unformat (input, "%d", &tag))
10397     {
10398       tagp[0] = (tag >> 8) & 0x0F;
10399       tagp[1] = tag & 0xFF;
10400       return 1;
10401     }
10402
10403   return 0;
10404 }
10405
10406 uword
10407 unformat_l2_match (unformat_input_t * input, va_list * args)
10408 {
10409   u8 **matchp = va_arg (*args, u8 **);
10410   u8 *match = 0;
10411   u8 src = 0;
10412   u8 src_val[6];
10413   u8 dst = 0;
10414   u8 dst_val[6];
10415   u8 proto = 0;
10416   u16 proto_val;
10417   u8 tag1 = 0;
10418   u8 tag1_val[2];
10419   u8 tag2 = 0;
10420   u8 tag2_val[2];
10421   int len = 14;
10422   u8 ignore_tag1 = 0;
10423   u8 ignore_tag2 = 0;
10424   u8 cos1 = 0;
10425   u8 cos2 = 0;
10426   u32 cos1_val = 0;
10427   u32 cos2_val = 0;
10428
10429   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10430     {
10431       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10432         src = 1;
10433       else
10434         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10435         dst = 1;
10436       else if (unformat (input, "proto %U",
10437                          unformat_ethernet_type_host_byte_order, &proto_val))
10438         proto = 1;
10439       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10440         tag1 = 1;
10441       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10442         tag2 = 1;
10443       else if (unformat (input, "ignore-tag1"))
10444         ignore_tag1 = 1;
10445       else if (unformat (input, "ignore-tag2"))
10446         ignore_tag2 = 1;
10447       else if (unformat (input, "cos1 %d", &cos1_val))
10448         cos1 = 1;
10449       else if (unformat (input, "cos2 %d", &cos2_val))
10450         cos2 = 1;
10451       else
10452         break;
10453     }
10454   if ((src + dst + proto + tag1 + tag2 +
10455        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10456     return 0;
10457
10458   if (tag1 || ignore_tag1 || cos1)
10459     len = 18;
10460   if (tag2 || ignore_tag2 || cos2)
10461     len = 22;
10462
10463   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10464
10465   if (dst)
10466     clib_memcpy (match, dst_val, 6);
10467
10468   if (src)
10469     clib_memcpy (match + 6, src_val, 6);
10470
10471   if (tag2)
10472     {
10473       /* inner vlan tag */
10474       match[19] = tag2_val[1];
10475       match[18] = tag2_val[0];
10476       if (cos2)
10477         match[18] |= (cos2_val & 0x7) << 5;
10478       if (proto)
10479         {
10480           match[21] = proto_val & 0xff;
10481           match[20] = proto_val >> 8;
10482         }
10483       if (tag1)
10484         {
10485           match[15] = tag1_val[1];
10486           match[14] = tag1_val[0];
10487         }
10488       if (cos1)
10489         match[14] |= (cos1_val & 0x7) << 5;
10490       *matchp = match;
10491       return 1;
10492     }
10493   if (tag1)
10494     {
10495       match[15] = tag1_val[1];
10496       match[14] = tag1_val[0];
10497       if (proto)
10498         {
10499           match[17] = proto_val & 0xff;
10500           match[16] = proto_val >> 8;
10501         }
10502       if (cos1)
10503         match[14] |= (cos1_val & 0x7) << 5;
10504
10505       *matchp = match;
10506       return 1;
10507     }
10508   if (cos2)
10509     match[18] |= (cos2_val & 0x7) << 5;
10510   if (cos1)
10511     match[14] |= (cos1_val & 0x7) << 5;
10512   if (proto)
10513     {
10514       match[13] = proto_val & 0xff;
10515       match[12] = proto_val >> 8;
10516     }
10517
10518   *matchp = match;
10519   return 1;
10520 }
10521
10522 uword
10523 unformat_qos_source (unformat_input_t * input, va_list * args)
10524 {
10525   int *qs = va_arg (*args, int *);
10526
10527   if (unformat (input, "ip"))
10528     *qs = QOS_SOURCE_IP;
10529   else if (unformat (input, "mpls"))
10530     *qs = QOS_SOURCE_MPLS;
10531   else if (unformat (input, "ext"))
10532     *qs = QOS_SOURCE_EXT;
10533   else if (unformat (input, "vlan"))
10534     *qs = QOS_SOURCE_VLAN;
10535   else
10536     return 0;
10537
10538   return 1;
10539 }
10540 #endif
10541
10542 uword
10543 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10544 {
10545   u8 **matchp = va_arg (*args, u8 **);
10546   u32 skip_n_vectors = va_arg (*args, u32);
10547   u32 match_n_vectors = va_arg (*args, u32);
10548
10549   u8 *match = 0;
10550   u8 *l2 = 0;
10551   u8 *l3 = 0;
10552   u8 *l4 = 0;
10553
10554   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10555     {
10556       if (unformat (input, "hex %U", unformat_hex_string, &match))
10557         ;
10558       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10559         ;
10560       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10561         ;
10562       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10563         ;
10564       else
10565         break;
10566     }
10567
10568   if (l4 && !l3)
10569     {
10570       vec_free (match);
10571       vec_free (l2);
10572       vec_free (l4);
10573       return 0;
10574     }
10575
10576   if (match || l2 || l3 || l4)
10577     {
10578       if (l2 || l3 || l4)
10579         {
10580           /* "Win a free Ethernet header in every packet" */
10581           if (l2 == 0)
10582             vec_validate_aligned (l2, 13, sizeof (u32x4));
10583           match = l2;
10584           if (vec_len (l3))
10585             {
10586               vec_append_aligned (match, l3, sizeof (u32x4));
10587               vec_free (l3);
10588             }
10589           if (vec_len (l4))
10590             {
10591               vec_append_aligned (match, l4, sizeof (u32x4));
10592               vec_free (l4);
10593             }
10594         }
10595
10596       /* Make sure the vector is big enough even if key is all 0's */
10597       vec_validate_aligned
10598         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
10599          sizeof (u32x4));
10600
10601       /* Set size, include skipped vectors */
10602       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
10603
10604       *matchp = match;
10605
10606       return 1;
10607     }
10608
10609   return 0;
10610 }
10611
10612 static int
10613 api_classify_add_del_session (vat_main_t * vam)
10614 {
10615   unformat_input_t *i = vam->input;
10616   vl_api_classify_add_del_session_t *mp;
10617   int is_add = 1;
10618   u32 table_index = ~0;
10619   u32 hit_next_index = ~0;
10620   u32 opaque_index = ~0;
10621   u8 *match = 0;
10622   i32 advance = 0;
10623   u32 skip_n_vectors = 0;
10624   u32 match_n_vectors = 0;
10625   u32 action = 0;
10626   u32 metadata = 0;
10627   int ret;
10628
10629   /*
10630    * Warning: you have to supply skip_n and match_n
10631    * because the API client cant simply look at the classify
10632    * table object.
10633    */
10634
10635   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10636     {
10637       if (unformat (i, "del"))
10638         is_add = 0;
10639       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
10640                          &hit_next_index))
10641         ;
10642       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10643                          &hit_next_index))
10644         ;
10645       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
10646                          &hit_next_index))
10647         ;
10648       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10649         ;
10650       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10651         ;
10652       else if (unformat (i, "opaque-index %d", &opaque_index))
10653         ;
10654       else if (unformat (i, "skip_n %d", &skip_n_vectors))
10655         ;
10656       else if (unformat (i, "match_n %d", &match_n_vectors))
10657         ;
10658       else if (unformat (i, "match %U", api_unformat_classify_match,
10659                          &match, skip_n_vectors, match_n_vectors))
10660         ;
10661       else if (unformat (i, "advance %d", &advance))
10662         ;
10663       else if (unformat (i, "table-index %d", &table_index))
10664         ;
10665       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10666         action = 1;
10667       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10668         action = 2;
10669       else if (unformat (i, "action %d", &action))
10670         ;
10671       else if (unformat (i, "metadata %d", &metadata))
10672         ;
10673       else
10674         break;
10675     }
10676
10677   if (table_index == ~0)
10678     {
10679       errmsg ("Table index required");
10680       return -99;
10681     }
10682
10683   if (is_add && match == 0)
10684     {
10685       errmsg ("Match value required");
10686       return -99;
10687     }
10688
10689   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10690
10691   mp->is_add = is_add;
10692   mp->table_index = ntohl (table_index);
10693   mp->hit_next_index = ntohl (hit_next_index);
10694   mp->opaque_index = ntohl (opaque_index);
10695   mp->advance = ntohl (advance);
10696   mp->action = action;
10697   mp->metadata = ntohl (metadata);
10698   mp->match_len = ntohl (vec_len (match));
10699   clib_memcpy (mp->match, match, vec_len (match));
10700   vec_free (match);
10701
10702   S (mp);
10703   W (ret);
10704   return ret;
10705 }
10706
10707 static int
10708 api_classify_set_interface_ip_table (vat_main_t * vam)
10709 {
10710   unformat_input_t *i = vam->input;
10711   vl_api_classify_set_interface_ip_table_t *mp;
10712   u32 sw_if_index;
10713   int sw_if_index_set;
10714   u32 table_index = ~0;
10715   u8 is_ipv6 = 0;
10716   int ret;
10717
10718   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10719     {
10720       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10721         sw_if_index_set = 1;
10722       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10723         sw_if_index_set = 1;
10724       else if (unformat (i, "table %d", &table_index))
10725         ;
10726       else
10727         {
10728           clib_warning ("parse error '%U'", format_unformat_error, i);
10729           return -99;
10730         }
10731     }
10732
10733   if (sw_if_index_set == 0)
10734     {
10735       errmsg ("missing interface name or sw_if_index");
10736       return -99;
10737     }
10738
10739
10740   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10741
10742   mp->sw_if_index = ntohl (sw_if_index);
10743   mp->table_index = ntohl (table_index);
10744   mp->is_ipv6 = is_ipv6;
10745
10746   S (mp);
10747   W (ret);
10748   return ret;
10749 }
10750
10751 static int
10752 api_classify_set_interface_l2_tables (vat_main_t * vam)
10753 {
10754   unformat_input_t *i = vam->input;
10755   vl_api_classify_set_interface_l2_tables_t *mp;
10756   u32 sw_if_index;
10757   int sw_if_index_set;
10758   u32 ip4_table_index = ~0;
10759   u32 ip6_table_index = ~0;
10760   u32 other_table_index = ~0;
10761   u32 is_input = 1;
10762   int ret;
10763
10764   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10765     {
10766       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10767         sw_if_index_set = 1;
10768       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10769         sw_if_index_set = 1;
10770       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10771         ;
10772       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10773         ;
10774       else if (unformat (i, "other-table %d", &other_table_index))
10775         ;
10776       else if (unformat (i, "is-input %d", &is_input))
10777         ;
10778       else
10779         {
10780           clib_warning ("parse error '%U'", format_unformat_error, i);
10781           return -99;
10782         }
10783     }
10784
10785   if (sw_if_index_set == 0)
10786     {
10787       errmsg ("missing interface name or sw_if_index");
10788       return -99;
10789     }
10790
10791
10792   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10793
10794   mp->sw_if_index = ntohl (sw_if_index);
10795   mp->ip4_table_index = ntohl (ip4_table_index);
10796   mp->ip6_table_index = ntohl (ip6_table_index);
10797   mp->other_table_index = ntohl (other_table_index);
10798   mp->is_input = (u8) is_input;
10799
10800   S (mp);
10801   W (ret);
10802   return ret;
10803 }
10804
10805 static int
10806 api_set_ipfix_exporter (vat_main_t * vam)
10807 {
10808   unformat_input_t *i = vam->input;
10809   vl_api_set_ipfix_exporter_t *mp;
10810   ip4_address_t collector_address;
10811   u8 collector_address_set = 0;
10812   u32 collector_port = ~0;
10813   ip4_address_t src_address;
10814   u8 src_address_set = 0;
10815   u32 vrf_id = ~0;
10816   u32 path_mtu = ~0;
10817   u32 template_interval = ~0;
10818   u8 udp_checksum = 0;
10819   int ret;
10820
10821   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10822     {
10823       if (unformat (i, "collector_address %U", unformat_ip4_address,
10824                     &collector_address))
10825         collector_address_set = 1;
10826       else if (unformat (i, "collector_port %d", &collector_port))
10827         ;
10828       else if (unformat (i, "src_address %U", unformat_ip4_address,
10829                          &src_address))
10830         src_address_set = 1;
10831       else if (unformat (i, "vrf_id %d", &vrf_id))
10832         ;
10833       else if (unformat (i, "path_mtu %d", &path_mtu))
10834         ;
10835       else if (unformat (i, "template_interval %d", &template_interval))
10836         ;
10837       else if (unformat (i, "udp_checksum"))
10838         udp_checksum = 1;
10839       else
10840         break;
10841     }
10842
10843   if (collector_address_set == 0)
10844     {
10845       errmsg ("collector_address required");
10846       return -99;
10847     }
10848
10849   if (src_address_set == 0)
10850     {
10851       errmsg ("src_address required");
10852       return -99;
10853     }
10854
10855   M (SET_IPFIX_EXPORTER, mp);
10856
10857   memcpy (mp->collector_address.un.ip4, collector_address.data,
10858           sizeof (collector_address.data));
10859   mp->collector_port = htons ((u16) collector_port);
10860   memcpy (mp->src_address.un.ip4, src_address.data,
10861           sizeof (src_address.data));
10862   mp->vrf_id = htonl (vrf_id);
10863   mp->path_mtu = htonl (path_mtu);
10864   mp->template_interval = htonl (template_interval);
10865   mp->udp_checksum = udp_checksum;
10866
10867   S (mp);
10868   W (ret);
10869   return ret;
10870 }
10871
10872 static int
10873 api_set_ipfix_classify_stream (vat_main_t * vam)
10874 {
10875   unformat_input_t *i = vam->input;
10876   vl_api_set_ipfix_classify_stream_t *mp;
10877   u32 domain_id = 0;
10878   u32 src_port = UDP_DST_PORT_ipfix;
10879   int ret;
10880
10881   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10882     {
10883       if (unformat (i, "domain %d", &domain_id))
10884         ;
10885       else if (unformat (i, "src_port %d", &src_port))
10886         ;
10887       else
10888         {
10889           errmsg ("unknown input `%U'", format_unformat_error, i);
10890           return -99;
10891         }
10892     }
10893
10894   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10895
10896   mp->domain_id = htonl (domain_id);
10897   mp->src_port = htons ((u16) src_port);
10898
10899   S (mp);
10900   W (ret);
10901   return ret;
10902 }
10903
10904 static int
10905 api_ipfix_classify_table_add_del (vat_main_t * vam)
10906 {
10907   unformat_input_t *i = vam->input;
10908   vl_api_ipfix_classify_table_add_del_t *mp;
10909   int is_add = -1;
10910   u32 classify_table_index = ~0;
10911   u8 ip_version = 0;
10912   u8 transport_protocol = 255;
10913   int ret;
10914
10915   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10916     {
10917       if (unformat (i, "add"))
10918         is_add = 1;
10919       else if (unformat (i, "del"))
10920         is_add = 0;
10921       else if (unformat (i, "table %d", &classify_table_index))
10922         ;
10923       else if (unformat (i, "ip4"))
10924         ip_version = 4;
10925       else if (unformat (i, "ip6"))
10926         ip_version = 6;
10927       else if (unformat (i, "tcp"))
10928         transport_protocol = 6;
10929       else if (unformat (i, "udp"))
10930         transport_protocol = 17;
10931       else
10932         {
10933           errmsg ("unknown input `%U'", format_unformat_error, i);
10934           return -99;
10935         }
10936     }
10937
10938   if (is_add == -1)
10939     {
10940       errmsg ("expecting: add|del");
10941       return -99;
10942     }
10943   if (classify_table_index == ~0)
10944     {
10945       errmsg ("classifier table not specified");
10946       return -99;
10947     }
10948   if (ip_version == 0)
10949     {
10950       errmsg ("IP version not specified");
10951       return -99;
10952     }
10953
10954   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10955
10956   mp->is_add = is_add;
10957   mp->table_id = htonl (classify_table_index);
10958   mp->ip_version = ip_version;
10959   mp->transport_protocol = transport_protocol;
10960
10961   S (mp);
10962   W (ret);
10963   return ret;
10964 }
10965
10966 static int
10967 api_get_node_index (vat_main_t * vam)
10968 {
10969   unformat_input_t *i = vam->input;
10970   vl_api_get_node_index_t *mp;
10971   u8 *name = 0;
10972   int ret;
10973
10974   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10975     {
10976       if (unformat (i, "node %s", &name))
10977         ;
10978       else
10979         break;
10980     }
10981   if (name == 0)
10982     {
10983       errmsg ("node name required");
10984       return -99;
10985     }
10986   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10987     {
10988       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10989       return -99;
10990     }
10991
10992   M (GET_NODE_INDEX, mp);
10993   clib_memcpy (mp->node_name, name, vec_len (name));
10994   vec_free (name);
10995
10996   S (mp);
10997   W (ret);
10998   return ret;
10999 }
11000
11001 static int
11002 api_get_next_index (vat_main_t * vam)
11003 {
11004   unformat_input_t *i = vam->input;
11005   vl_api_get_next_index_t *mp;
11006   u8 *node_name = 0, *next_node_name = 0;
11007   int ret;
11008
11009   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11010     {
11011       if (unformat (i, "node-name %s", &node_name))
11012         ;
11013       else if (unformat (i, "next-node-name %s", &next_node_name))
11014         break;
11015     }
11016
11017   if (node_name == 0)
11018     {
11019       errmsg ("node name required");
11020       return -99;
11021     }
11022   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11023     {
11024       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11025       return -99;
11026     }
11027
11028   if (next_node_name == 0)
11029     {
11030       errmsg ("next node name required");
11031       return -99;
11032     }
11033   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11034     {
11035       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11036       return -99;
11037     }
11038
11039   M (GET_NEXT_INDEX, mp);
11040   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11041   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11042   vec_free (node_name);
11043   vec_free (next_node_name);
11044
11045   S (mp);
11046   W (ret);
11047   return ret;
11048 }
11049
11050 static int
11051 api_add_node_next (vat_main_t * vam)
11052 {
11053   unformat_input_t *i = vam->input;
11054   vl_api_add_node_next_t *mp;
11055   u8 *name = 0;
11056   u8 *next = 0;
11057   int ret;
11058
11059   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11060     {
11061       if (unformat (i, "node %s", &name))
11062         ;
11063       else if (unformat (i, "next %s", &next))
11064         ;
11065       else
11066         break;
11067     }
11068   if (name == 0)
11069     {
11070       errmsg ("node name required");
11071       return -99;
11072     }
11073   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11074     {
11075       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11076       return -99;
11077     }
11078   if (next == 0)
11079     {
11080       errmsg ("next node required");
11081       return -99;
11082     }
11083   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11084     {
11085       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11086       return -99;
11087     }
11088
11089   M (ADD_NODE_NEXT, mp);
11090   clib_memcpy (mp->node_name, name, vec_len (name));
11091   clib_memcpy (mp->next_name, next, vec_len (next));
11092   vec_free (name);
11093   vec_free (next);
11094
11095   S (mp);
11096   W (ret);
11097   return ret;
11098 }
11099
11100 static int
11101 api_l2tpv3_create_tunnel (vat_main_t * vam)
11102 {
11103   unformat_input_t *i = vam->input;
11104   ip6_address_t client_address, our_address;
11105   int client_address_set = 0;
11106   int our_address_set = 0;
11107   u32 local_session_id = 0;
11108   u32 remote_session_id = 0;
11109   u64 local_cookie = 0;
11110   u64 remote_cookie = 0;
11111   u8 l2_sublayer_present = 0;
11112   vl_api_l2tpv3_create_tunnel_t *mp;
11113   int ret;
11114
11115   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11116     {
11117       if (unformat (i, "client_address %U", unformat_ip6_address,
11118                     &client_address))
11119         client_address_set = 1;
11120       else if (unformat (i, "our_address %U", unformat_ip6_address,
11121                          &our_address))
11122         our_address_set = 1;
11123       else if (unformat (i, "local_session_id %d", &local_session_id))
11124         ;
11125       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11126         ;
11127       else if (unformat (i, "local_cookie %lld", &local_cookie))
11128         ;
11129       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11130         ;
11131       else if (unformat (i, "l2-sublayer-present"))
11132         l2_sublayer_present = 1;
11133       else
11134         break;
11135     }
11136
11137   if (client_address_set == 0)
11138     {
11139       errmsg ("client_address required");
11140       return -99;
11141     }
11142
11143   if (our_address_set == 0)
11144     {
11145       errmsg ("our_address required");
11146       return -99;
11147     }
11148
11149   M (L2TPV3_CREATE_TUNNEL, mp);
11150
11151   clib_memcpy (mp->client_address.un.ip6, client_address.as_u8,
11152                sizeof (ip6_address_t));
11153
11154   clib_memcpy (mp->our_address.un.ip6, our_address.as_u8,
11155                sizeof (ip6_address_t));
11156
11157   mp->local_session_id = ntohl (local_session_id);
11158   mp->remote_session_id = ntohl (remote_session_id);
11159   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11160   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11161   mp->l2_sublayer_present = l2_sublayer_present;
11162
11163   S (mp);
11164   W (ret);
11165   return ret;
11166 }
11167
11168 static int
11169 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11170 {
11171   unformat_input_t *i = vam->input;
11172   u32 sw_if_index;
11173   u8 sw_if_index_set = 0;
11174   u64 new_local_cookie = 0;
11175   u64 new_remote_cookie = 0;
11176   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11177   int ret;
11178
11179   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11180     {
11181       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11182         sw_if_index_set = 1;
11183       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11184         sw_if_index_set = 1;
11185       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11186         ;
11187       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11188         ;
11189       else
11190         break;
11191     }
11192
11193   if (sw_if_index_set == 0)
11194     {
11195       errmsg ("missing interface name or sw_if_index");
11196       return -99;
11197     }
11198
11199   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11200
11201   mp->sw_if_index = ntohl (sw_if_index);
11202   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11203   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11204
11205   S (mp);
11206   W (ret);
11207   return ret;
11208 }
11209
11210 static int
11211 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11212 {
11213   unformat_input_t *i = vam->input;
11214   vl_api_l2tpv3_interface_enable_disable_t *mp;
11215   u32 sw_if_index;
11216   u8 sw_if_index_set = 0;
11217   u8 enable_disable = 1;
11218   int ret;
11219
11220   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11221     {
11222       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11223         sw_if_index_set = 1;
11224       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11225         sw_if_index_set = 1;
11226       else if (unformat (i, "enable"))
11227         enable_disable = 1;
11228       else if (unformat (i, "disable"))
11229         enable_disable = 0;
11230       else
11231         break;
11232     }
11233
11234   if (sw_if_index_set == 0)
11235     {
11236       errmsg ("missing interface name or sw_if_index");
11237       return -99;
11238     }
11239
11240   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11241
11242   mp->sw_if_index = ntohl (sw_if_index);
11243   mp->enable_disable = enable_disable;
11244
11245   S (mp);
11246   W (ret);
11247   return ret;
11248 }
11249
11250 static int
11251 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11252 {
11253   unformat_input_t *i = vam->input;
11254   vl_api_l2tpv3_set_lookup_key_t *mp;
11255   u8 key = ~0;
11256   int ret;
11257
11258   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11259     {
11260       if (unformat (i, "lookup_v6_src"))
11261         key = L2T_LOOKUP_SRC_ADDRESS;
11262       else if (unformat (i, "lookup_v6_dst"))
11263         key = L2T_LOOKUP_DST_ADDRESS;
11264       else if (unformat (i, "lookup_session_id"))
11265         key = L2T_LOOKUP_SESSION_ID;
11266       else
11267         break;
11268     }
11269
11270   if (key == (u8) ~ 0)
11271     {
11272       errmsg ("l2tp session lookup key unset");
11273       return -99;
11274     }
11275
11276   M (L2TPV3_SET_LOOKUP_KEY, mp);
11277
11278   mp->key = key;
11279
11280   S (mp);
11281   W (ret);
11282   return ret;
11283 }
11284
11285 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11286   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11287 {
11288   vat_main_t *vam = &vat_main;
11289
11290   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11291          format_ip6_address, mp->our_address,
11292          format_ip6_address, mp->client_address,
11293          clib_net_to_host_u32 (mp->sw_if_index));
11294
11295   print (vam->ofp,
11296          "   local cookies %016llx %016llx remote cookie %016llx",
11297          clib_net_to_host_u64 (mp->local_cookie[0]),
11298          clib_net_to_host_u64 (mp->local_cookie[1]),
11299          clib_net_to_host_u64 (mp->remote_cookie));
11300
11301   print (vam->ofp, "   local session-id %d remote session-id %d",
11302          clib_net_to_host_u32 (mp->local_session_id),
11303          clib_net_to_host_u32 (mp->remote_session_id));
11304
11305   print (vam->ofp, "   l2 specific sublayer %s\n",
11306          mp->l2_sublayer_present ? "preset" : "absent");
11307
11308 }
11309
11310 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11311   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11312 {
11313   vat_main_t *vam = &vat_main;
11314   vat_json_node_t *node = NULL;
11315   struct in6_addr addr;
11316
11317   if (VAT_JSON_ARRAY != vam->json_tree.type)
11318     {
11319       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11320       vat_json_init_array (&vam->json_tree);
11321     }
11322   node = vat_json_array_add (&vam->json_tree);
11323
11324   vat_json_init_object (node);
11325
11326   clib_memcpy (&addr, mp->our_address.un.ip6, sizeof (addr));
11327   vat_json_object_add_ip6 (node, "our_address", addr);
11328   clib_memcpy (&addr, mp->client_address.un.ip6, sizeof (addr));
11329   vat_json_object_add_ip6 (node, "client_address", addr);
11330
11331   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11332   vat_json_init_array (lc);
11333   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11334   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11335   vat_json_object_add_uint (node, "remote_cookie",
11336                             clib_net_to_host_u64 (mp->remote_cookie));
11337
11338   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11339   vat_json_object_add_uint (node, "local_session_id",
11340                             clib_net_to_host_u32 (mp->local_session_id));
11341   vat_json_object_add_uint (node, "remote_session_id",
11342                             clib_net_to_host_u32 (mp->remote_session_id));
11343   vat_json_object_add_string_copy (node, "l2_sublayer",
11344                                    mp->l2_sublayer_present ? (u8 *) "present"
11345                                    : (u8 *) "absent");
11346 }
11347
11348 static int
11349 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11350 {
11351   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11352   vl_api_control_ping_t *mp_ping;
11353   int ret;
11354
11355   /* Get list of l2tpv3-tunnel interfaces */
11356   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11357   S (mp);
11358
11359   /* Use a control ping for synchronization */
11360   MPING (CONTROL_PING, mp_ping);
11361   S (mp_ping);
11362
11363   W (ret);
11364   return ret;
11365 }
11366
11367
11368 static void vl_api_sw_interface_tap_v2_details_t_handler
11369   (vl_api_sw_interface_tap_v2_details_t * mp)
11370 {
11371   vat_main_t *vam = &vat_main;
11372
11373   u8 *ip4 =
11374     format (0, "%U/%d", format_ip4_address, mp->host_ip4_prefix.address,
11375             mp->host_ip4_prefix.len);
11376   u8 *ip6 =
11377     format (0, "%U/%d", format_ip6_address, mp->host_ip6_prefix.address,
11378             mp->host_ip6_prefix.len);
11379
11380   print (vam->ofp,
11381          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
11382          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
11383          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11384          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
11385          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
11386
11387   vec_free (ip4);
11388   vec_free (ip6);
11389 }
11390
11391 static void vl_api_sw_interface_tap_v2_details_t_handler_json
11392   (vl_api_sw_interface_tap_v2_details_t * mp)
11393 {
11394   vat_main_t *vam = &vat_main;
11395   vat_json_node_t *node = NULL;
11396
11397   if (VAT_JSON_ARRAY != vam->json_tree.type)
11398     {
11399       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11400       vat_json_init_array (&vam->json_tree);
11401     }
11402   node = vat_json_array_add (&vam->json_tree);
11403
11404   vat_json_init_object (node);
11405   vat_json_object_add_uint (node, "id", ntohl (mp->id));
11406   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11407   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
11408   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11409   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11410   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11411   vat_json_object_add_string_copy (node, "host_mac_addr",
11412                                    format (0, "%U", format_ethernet_address,
11413                                            &mp->host_mac_addr));
11414   vat_json_object_add_string_copy (node, "host_namespace",
11415                                    mp->host_namespace);
11416   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
11417   vat_json_object_add_string_copy (node, "host_ip4_addr",
11418                                    format (0, "%U/%d", format_ip4_address,
11419                                            mp->host_ip4_prefix.address,
11420                                            mp->host_ip4_prefix.len));
11421   vat_json_object_add_string_copy (node, "host_ip6_prefix",
11422                                    format (0, "%U/%d", format_ip6_address,
11423                                            mp->host_ip6_prefix.address,
11424                                            mp->host_ip6_prefix.len));
11425
11426 }
11427
11428 static int
11429 api_sw_interface_tap_v2_dump (vat_main_t * vam)
11430 {
11431   vl_api_sw_interface_tap_v2_dump_t *mp;
11432   vl_api_control_ping_t *mp_ping;
11433   int ret;
11434
11435   print (vam->ofp,
11436          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
11437          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
11438          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
11439          "host_ip6_addr");
11440
11441   /* Get list of tap interfaces */
11442   M (SW_INTERFACE_TAP_V2_DUMP, mp);
11443   S (mp);
11444
11445   /* Use a control ping for synchronization */
11446   MPING (CONTROL_PING, mp_ping);
11447   S (mp_ping);
11448
11449   W (ret);
11450   return ret;
11451 }
11452
11453 static void vl_api_sw_interface_virtio_pci_details_t_handler
11454   (vl_api_sw_interface_virtio_pci_details_t * mp)
11455 {
11456   vat_main_t *vam = &vat_main;
11457
11458   typedef union
11459   {
11460     struct
11461     {
11462       u16 domain;
11463       u8 bus;
11464       u8 slot:5;
11465       u8 function:3;
11466     };
11467     u32 as_u32;
11468   } pci_addr_t;
11469   pci_addr_t addr;
11470
11471   addr.domain = ntohs (mp->pci_addr.domain);
11472   addr.bus = mp->pci_addr.bus;
11473   addr.slot = mp->pci_addr.slot;
11474   addr.function = mp->pci_addr.function;
11475
11476   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
11477                          addr.slot, addr.function);
11478
11479   print (vam->ofp,
11480          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
11481          pci_addr, ntohl (mp->sw_if_index),
11482          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11483          format_ethernet_address, mp->mac_addr,
11484          clib_net_to_host_u64 (mp->features));
11485   vec_free (pci_addr);
11486 }
11487
11488 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
11489   (vl_api_sw_interface_virtio_pci_details_t * mp)
11490 {
11491   vat_main_t *vam = &vat_main;
11492   vat_json_node_t *node = NULL;
11493   vlib_pci_addr_t pci_addr;
11494
11495   if (VAT_JSON_ARRAY != vam->json_tree.type)
11496     {
11497       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11498       vat_json_init_array (&vam->json_tree);
11499     }
11500   node = vat_json_array_add (&vam->json_tree);
11501
11502   pci_addr.domain = ntohs (mp->pci_addr.domain);
11503   pci_addr.bus = mp->pci_addr.bus;
11504   pci_addr.slot = mp->pci_addr.slot;
11505   pci_addr.function = mp->pci_addr.function;
11506
11507   vat_json_init_object (node);
11508   vat_json_object_add_uint (node, "pci-addr", pci_addr.as_u32);
11509   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11510   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11511   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11512   vat_json_object_add_uint (node, "features",
11513                             clib_net_to_host_u64 (mp->features));
11514   vat_json_object_add_string_copy (node, "mac_addr",
11515                                    format (0, "%U", format_ethernet_address,
11516                                            &mp->mac_addr));
11517 }
11518
11519 static int
11520 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
11521 {
11522   vl_api_sw_interface_virtio_pci_dump_t *mp;
11523   vl_api_control_ping_t *mp_ping;
11524   int ret;
11525
11526   print (vam->ofp,
11527          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
11528          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
11529          "mac_addr", "features");
11530
11531   /* Get list of tap interfaces */
11532   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
11533   S (mp);
11534
11535   /* Use a control ping for synchronization */
11536   MPING (CONTROL_PING, mp_ping);
11537   S (mp_ping);
11538
11539   W (ret);
11540   return ret;
11541 }
11542
11543 static int
11544 api_vxlan_offload_rx (vat_main_t * vam)
11545 {
11546   unformat_input_t *line_input = vam->input;
11547   vl_api_vxlan_offload_rx_t *mp;
11548   u32 hw_if_index = ~0, rx_if_index = ~0;
11549   u8 is_add = 1;
11550   int ret;
11551
11552   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11553     {
11554       if (unformat (line_input, "del"))
11555         is_add = 0;
11556       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
11557                          &hw_if_index))
11558         ;
11559       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
11560         ;
11561       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
11562                          &rx_if_index))
11563         ;
11564       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
11565         ;
11566       else
11567         {
11568           errmsg ("parse error '%U'", format_unformat_error, line_input);
11569           return -99;
11570         }
11571     }
11572
11573   if (hw_if_index == ~0)
11574     {
11575       errmsg ("no hw interface");
11576       return -99;
11577     }
11578
11579   if (rx_if_index == ~0)
11580     {
11581       errmsg ("no rx tunnel");
11582       return -99;
11583     }
11584
11585   M (VXLAN_OFFLOAD_RX, mp);
11586
11587   mp->hw_if_index = ntohl (hw_if_index);
11588   mp->sw_if_index = ntohl (rx_if_index);
11589   mp->enable = is_add;
11590
11591   S (mp);
11592   W (ret);
11593   return ret;
11594 }
11595
11596 static uword unformat_vxlan_decap_next
11597   (unformat_input_t * input, va_list * args)
11598 {
11599   u32 *result = va_arg (*args, u32 *);
11600   u32 tmp;
11601
11602   if (unformat (input, "l2"))
11603     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11604   else if (unformat (input, "%d", &tmp))
11605     *result = tmp;
11606   else
11607     return 0;
11608   return 1;
11609 }
11610
11611 static int
11612 api_vxlan_add_del_tunnel (vat_main_t * vam)
11613 {
11614   unformat_input_t *line_input = vam->input;
11615   vl_api_vxlan_add_del_tunnel_t *mp;
11616   ip46_address_t src, dst;
11617   u8 is_add = 1;
11618   u8 ipv4_set = 0, ipv6_set = 0;
11619   u8 src_set = 0;
11620   u8 dst_set = 0;
11621   u8 grp_set = 0;
11622   u32 instance = ~0;
11623   u32 mcast_sw_if_index = ~0;
11624   u32 encap_vrf_id = 0;
11625   u32 decap_next_index = ~0;
11626   u32 vni = 0;
11627   int ret;
11628
11629   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11630   clib_memset (&src, 0, sizeof src);
11631   clib_memset (&dst, 0, sizeof dst);
11632
11633   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11634     {
11635       if (unformat (line_input, "del"))
11636         is_add = 0;
11637       else if (unformat (line_input, "instance %d", &instance))
11638         ;
11639       else
11640         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11641         {
11642           ipv4_set = 1;
11643           src_set = 1;
11644         }
11645       else
11646         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11647         {
11648           ipv4_set = 1;
11649           dst_set = 1;
11650         }
11651       else
11652         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11653         {
11654           ipv6_set = 1;
11655           src_set = 1;
11656         }
11657       else
11658         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11659         {
11660           ipv6_set = 1;
11661           dst_set = 1;
11662         }
11663       else if (unformat (line_input, "group %U %U",
11664                          unformat_ip4_address, &dst.ip4,
11665                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11666         {
11667           grp_set = dst_set = 1;
11668           ipv4_set = 1;
11669         }
11670       else if (unformat (line_input, "group %U",
11671                          unformat_ip4_address, &dst.ip4))
11672         {
11673           grp_set = dst_set = 1;
11674           ipv4_set = 1;
11675         }
11676       else if (unformat (line_input, "group %U %U",
11677                          unformat_ip6_address, &dst.ip6,
11678                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11679         {
11680           grp_set = dst_set = 1;
11681           ipv6_set = 1;
11682         }
11683       else if (unformat (line_input, "group %U",
11684                          unformat_ip6_address, &dst.ip6))
11685         {
11686           grp_set = dst_set = 1;
11687           ipv6_set = 1;
11688         }
11689       else
11690         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11691         ;
11692       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11693         ;
11694       else if (unformat (line_input, "decap-next %U",
11695                          unformat_vxlan_decap_next, &decap_next_index))
11696         ;
11697       else if (unformat (line_input, "vni %d", &vni))
11698         ;
11699       else
11700         {
11701           errmsg ("parse error '%U'", format_unformat_error, line_input);
11702           return -99;
11703         }
11704     }
11705
11706   if (src_set == 0)
11707     {
11708       errmsg ("tunnel src address not specified");
11709       return -99;
11710     }
11711   if (dst_set == 0)
11712     {
11713       errmsg ("tunnel dst address not specified");
11714       return -99;
11715     }
11716
11717   if (grp_set && !ip46_address_is_multicast (&dst))
11718     {
11719       errmsg ("tunnel group address not multicast");
11720       return -99;
11721     }
11722   if (grp_set && mcast_sw_if_index == ~0)
11723     {
11724       errmsg ("tunnel nonexistent multicast device");
11725       return -99;
11726     }
11727   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11728     {
11729       errmsg ("tunnel dst address must be unicast");
11730       return -99;
11731     }
11732
11733
11734   if (ipv4_set && ipv6_set)
11735     {
11736       errmsg ("both IPv4 and IPv6 addresses specified");
11737       return -99;
11738     }
11739
11740   if ((vni == 0) || (vni >> 24))
11741     {
11742       errmsg ("vni not specified or out of range");
11743       return -99;
11744     }
11745
11746   M (VXLAN_ADD_DEL_TUNNEL, mp);
11747
11748   if (ipv6_set)
11749     {
11750       clib_memcpy (mp->src_address.un.ip6, &src.ip6, sizeof (src.ip6));
11751       clib_memcpy (mp->dst_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
11752     }
11753   else
11754     {
11755       clib_memcpy (mp->src_address.un.ip4, &src.ip4, sizeof (src.ip4));
11756       clib_memcpy (mp->dst_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
11757     }
11758   mp->src_address.af = ipv6_set;
11759   mp->dst_address.af = ipv6_set;
11760
11761   mp->instance = htonl (instance);
11762   mp->encap_vrf_id = ntohl (encap_vrf_id);
11763   mp->decap_next_index = ntohl (decap_next_index);
11764   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11765   mp->vni = ntohl (vni);
11766   mp->is_add = is_add;
11767
11768   S (mp);
11769   W (ret);
11770   return ret;
11771 }
11772
11773 static void vl_api_vxlan_tunnel_details_t_handler
11774   (vl_api_vxlan_tunnel_details_t * mp)
11775 {
11776   vat_main_t *vam = &vat_main;
11777   ip46_address_t src =
11778     to_ip46 (mp->dst_address.af, (u8 *) & mp->dst_address.un);
11779   ip46_address_t dst =
11780     to_ip46 (mp->dst_address.af, (u8 *) & mp->src_address.un);
11781
11782   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
11783          ntohl (mp->sw_if_index),
11784          ntohl (mp->instance),
11785          format_ip46_address, &src, IP46_TYPE_ANY,
11786          format_ip46_address, &dst, IP46_TYPE_ANY,
11787          ntohl (mp->encap_vrf_id),
11788          ntohl (mp->decap_next_index), ntohl (mp->vni),
11789          ntohl (mp->mcast_sw_if_index));
11790 }
11791
11792 static void vl_api_vxlan_tunnel_details_t_handler_json
11793   (vl_api_vxlan_tunnel_details_t * mp)
11794 {
11795   vat_main_t *vam = &vat_main;
11796   vat_json_node_t *node = NULL;
11797
11798   if (VAT_JSON_ARRAY != vam->json_tree.type)
11799     {
11800       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11801       vat_json_init_array (&vam->json_tree);
11802     }
11803   node = vat_json_array_add (&vam->json_tree);
11804
11805   vat_json_init_object (node);
11806   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11807
11808   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
11809
11810   if (mp->src_address.af)
11811     {
11812       struct in6_addr ip6;
11813
11814       clib_memcpy (&ip6, mp->src_address.un.ip6, sizeof (ip6));
11815       vat_json_object_add_ip6 (node, "src_address", ip6);
11816       clib_memcpy (&ip6, mp->dst_address.un.ip6, sizeof (ip6));
11817       vat_json_object_add_ip6 (node, "dst_address", ip6);
11818     }
11819   else
11820     {
11821       struct in_addr ip4;
11822
11823       clib_memcpy (&ip4, mp->src_address.un.ip4, sizeof (ip4));
11824       vat_json_object_add_ip4 (node, "src_address", ip4);
11825       clib_memcpy (&ip4, mp->dst_address.un.ip4, sizeof (ip4));
11826       vat_json_object_add_ip4 (node, "dst_address", ip4);
11827     }
11828   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11829   vat_json_object_add_uint (node, "decap_next_index",
11830                             ntohl (mp->decap_next_index));
11831   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11832   vat_json_object_add_uint (node, "mcast_sw_if_index",
11833                             ntohl (mp->mcast_sw_if_index));
11834 }
11835
11836 static int
11837 api_vxlan_tunnel_dump (vat_main_t * vam)
11838 {
11839   unformat_input_t *i = vam->input;
11840   vl_api_vxlan_tunnel_dump_t *mp;
11841   vl_api_control_ping_t *mp_ping;
11842   u32 sw_if_index;
11843   u8 sw_if_index_set = 0;
11844   int ret;
11845
11846   /* Parse args required to build the message */
11847   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11848     {
11849       if (unformat (i, "sw_if_index %d", &sw_if_index))
11850         sw_if_index_set = 1;
11851       else
11852         break;
11853     }
11854
11855   if (sw_if_index_set == 0)
11856     {
11857       sw_if_index = ~0;
11858     }
11859
11860   if (!vam->json_output)
11861     {
11862       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
11863              "sw_if_index", "instance", "src_address", "dst_address",
11864              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
11865     }
11866
11867   /* Get list of vxlan-tunnel interfaces */
11868   M (VXLAN_TUNNEL_DUMP, mp);
11869
11870   mp->sw_if_index = htonl (sw_if_index);
11871
11872   S (mp);
11873
11874   /* Use a control ping for synchronization */
11875   MPING (CONTROL_PING, mp_ping);
11876   S (mp_ping);
11877
11878   W (ret);
11879   return ret;
11880 }
11881
11882 static uword unformat_geneve_decap_next
11883   (unformat_input_t * input, va_list * args)
11884 {
11885   u32 *result = va_arg (*args, u32 *);
11886   u32 tmp;
11887
11888   if (unformat (input, "l2"))
11889     *result = GENEVE_INPUT_NEXT_L2_INPUT;
11890   else if (unformat (input, "%d", &tmp))
11891     *result = tmp;
11892   else
11893     return 0;
11894   return 1;
11895 }
11896
11897 static int
11898 api_geneve_add_del_tunnel (vat_main_t * vam)
11899 {
11900   unformat_input_t *line_input = vam->input;
11901   vl_api_geneve_add_del_tunnel_t *mp;
11902   ip46_address_t src, dst;
11903   u8 is_add = 1;
11904   u8 ipv4_set = 0, ipv6_set = 0;
11905   u8 src_set = 0;
11906   u8 dst_set = 0;
11907   u8 grp_set = 0;
11908   u32 mcast_sw_if_index = ~0;
11909   u32 encap_vrf_id = 0;
11910   u32 decap_next_index = ~0;
11911   u32 vni = 0;
11912   int ret;
11913
11914   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11915   clib_memset (&src, 0, sizeof src);
11916   clib_memset (&dst, 0, sizeof dst);
11917
11918   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11919     {
11920       if (unformat (line_input, "del"))
11921         is_add = 0;
11922       else
11923         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11924         {
11925           ipv4_set = 1;
11926           src_set = 1;
11927         }
11928       else
11929         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11930         {
11931           ipv4_set = 1;
11932           dst_set = 1;
11933         }
11934       else
11935         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11936         {
11937           ipv6_set = 1;
11938           src_set = 1;
11939         }
11940       else
11941         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11942         {
11943           ipv6_set = 1;
11944           dst_set = 1;
11945         }
11946       else if (unformat (line_input, "group %U %U",
11947                          unformat_ip4_address, &dst.ip4,
11948                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11949         {
11950           grp_set = dst_set = 1;
11951           ipv4_set = 1;
11952         }
11953       else if (unformat (line_input, "group %U",
11954                          unformat_ip4_address, &dst.ip4))
11955         {
11956           grp_set = dst_set = 1;
11957           ipv4_set = 1;
11958         }
11959       else if (unformat (line_input, "group %U %U",
11960                          unformat_ip6_address, &dst.ip6,
11961                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11962         {
11963           grp_set = dst_set = 1;
11964           ipv6_set = 1;
11965         }
11966       else if (unformat (line_input, "group %U",
11967                          unformat_ip6_address, &dst.ip6))
11968         {
11969           grp_set = dst_set = 1;
11970           ipv6_set = 1;
11971         }
11972       else
11973         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11974         ;
11975       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11976         ;
11977       else if (unformat (line_input, "decap-next %U",
11978                          unformat_geneve_decap_next, &decap_next_index))
11979         ;
11980       else if (unformat (line_input, "vni %d", &vni))
11981         ;
11982       else
11983         {
11984           errmsg ("parse error '%U'", format_unformat_error, line_input);
11985           return -99;
11986         }
11987     }
11988
11989   if (src_set == 0)
11990     {
11991       errmsg ("tunnel src address not specified");
11992       return -99;
11993     }
11994   if (dst_set == 0)
11995     {
11996       errmsg ("tunnel dst address not specified");
11997       return -99;
11998     }
11999
12000   if (grp_set && !ip46_address_is_multicast (&dst))
12001     {
12002       errmsg ("tunnel group address not multicast");
12003       return -99;
12004     }
12005   if (grp_set && mcast_sw_if_index == ~0)
12006     {
12007       errmsg ("tunnel nonexistent multicast device");
12008       return -99;
12009     }
12010   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12011     {
12012       errmsg ("tunnel dst address must be unicast");
12013       return -99;
12014     }
12015
12016
12017   if (ipv4_set && ipv6_set)
12018     {
12019       errmsg ("both IPv4 and IPv6 addresses specified");
12020       return -99;
12021     }
12022
12023   if ((vni == 0) || (vni >> 24))
12024     {
12025       errmsg ("vni not specified or out of range");
12026       return -99;
12027     }
12028
12029   M (GENEVE_ADD_DEL_TUNNEL, mp);
12030
12031   if (ipv6_set)
12032     {
12033       clib_memcpy (&mp->local_address.un.ip6, &src.ip6, sizeof (src.ip6));
12034       clib_memcpy (&mp->remote_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
12035     }
12036   else
12037     {
12038       clib_memcpy (&mp->local_address.un.ip4, &src.ip4, sizeof (src.ip4));
12039       clib_memcpy (&mp->remote_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
12040     }
12041   mp->encap_vrf_id = ntohl (encap_vrf_id);
12042   mp->decap_next_index = ntohl (decap_next_index);
12043   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12044   mp->vni = ntohl (vni);
12045   mp->is_add = is_add;
12046
12047   S (mp);
12048   W (ret);
12049   return ret;
12050 }
12051
12052 static void vl_api_geneve_tunnel_details_t_handler
12053   (vl_api_geneve_tunnel_details_t * mp)
12054 {
12055   vat_main_t *vam = &vat_main;
12056   ip46_address_t src = {.as_u64[0] = 0,.as_u64[1] = 0 };
12057   ip46_address_t dst = {.as_u64[0] = 0,.as_u64[1] = 0 };
12058
12059   if (mp->src_address.af == ADDRESS_IP6)
12060     {
12061       clib_memcpy (&src.ip6, &mp->src_address.un.ip6, sizeof (ip6_address_t));
12062       clib_memcpy (&dst.ip6, &mp->dst_address.un.ip6, sizeof (ip6_address_t));
12063     }
12064   else
12065     {
12066       clib_memcpy (&src.ip4, &mp->src_address.un.ip4, sizeof (ip4_address_t));
12067       clib_memcpy (&dst.ip4, &mp->dst_address.un.ip4, sizeof (ip4_address_t));
12068     }
12069
12070   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12071          ntohl (mp->sw_if_index),
12072          format_ip46_address, &src, IP46_TYPE_ANY,
12073          format_ip46_address, &dst, IP46_TYPE_ANY,
12074          ntohl (mp->encap_vrf_id),
12075          ntohl (mp->decap_next_index), ntohl (mp->vni),
12076          ntohl (mp->mcast_sw_if_index));
12077 }
12078
12079 static void vl_api_geneve_tunnel_details_t_handler_json
12080   (vl_api_geneve_tunnel_details_t * mp)
12081 {
12082   vat_main_t *vam = &vat_main;
12083   vat_json_node_t *node = NULL;
12084   bool is_ipv6;
12085
12086   if (VAT_JSON_ARRAY != vam->json_tree.type)
12087     {
12088       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12089       vat_json_init_array (&vam->json_tree);
12090     }
12091   node = vat_json_array_add (&vam->json_tree);
12092
12093   vat_json_init_object (node);
12094   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12095   is_ipv6 = mp->src_address.af == ADDRESS_IP6;
12096   if (is_ipv6)
12097     {
12098       struct in6_addr ip6;
12099
12100       clib_memcpy (&ip6, &mp->src_address.un.ip6, sizeof (ip6));
12101       vat_json_object_add_ip6 (node, "src_address", ip6);
12102       clib_memcpy (&ip6, &mp->dst_address.un.ip6, sizeof (ip6));
12103       vat_json_object_add_ip6 (node, "dst_address", ip6);
12104     }
12105   else
12106     {
12107       struct in_addr ip4;
12108
12109       clib_memcpy (&ip4, &mp->src_address.un.ip4, sizeof (ip4));
12110       vat_json_object_add_ip4 (node, "src_address", ip4);
12111       clib_memcpy (&ip4, &mp->dst_address.un.ip4, sizeof (ip4));
12112       vat_json_object_add_ip4 (node, "dst_address", ip4);
12113     }
12114   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12115   vat_json_object_add_uint (node, "decap_next_index",
12116                             ntohl (mp->decap_next_index));
12117   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12118   vat_json_object_add_uint (node, "mcast_sw_if_index",
12119                             ntohl (mp->mcast_sw_if_index));
12120 }
12121
12122 static int
12123 api_geneve_tunnel_dump (vat_main_t * vam)
12124 {
12125   unformat_input_t *i = vam->input;
12126   vl_api_geneve_tunnel_dump_t *mp;
12127   vl_api_control_ping_t *mp_ping;
12128   u32 sw_if_index;
12129   u8 sw_if_index_set = 0;
12130   int ret;
12131
12132   /* Parse args required to build the message */
12133   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12134     {
12135       if (unformat (i, "sw_if_index %d", &sw_if_index))
12136         sw_if_index_set = 1;
12137       else
12138         break;
12139     }
12140
12141   if (sw_if_index_set == 0)
12142     {
12143       sw_if_index = ~0;
12144     }
12145
12146   if (!vam->json_output)
12147     {
12148       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12149              "sw_if_index", "local_address", "remote_address",
12150              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12151     }
12152
12153   /* Get list of geneve-tunnel interfaces */
12154   M (GENEVE_TUNNEL_DUMP, mp);
12155
12156   mp->sw_if_index = htonl (sw_if_index);
12157
12158   S (mp);
12159
12160   /* Use a control ping for synchronization */
12161   M (CONTROL_PING, mp_ping);
12162   S (mp_ping);
12163
12164   W (ret);
12165   return ret;
12166 }
12167
12168 static int
12169 api_gre_tunnel_add_del (vat_main_t * vam)
12170 {
12171   unformat_input_t *line_input = vam->input;
12172   vl_api_address_t src = { }, dst =
12173   {
12174   };
12175   vl_api_gre_tunnel_add_del_t *mp;
12176   vl_api_gre_tunnel_type_t t_type;
12177   u8 is_add = 1;
12178   u8 src_set = 0;
12179   u8 dst_set = 0;
12180   u32 outer_table_id = 0;
12181   u32 session_id = 0;
12182   u32 instance = ~0;
12183   int ret;
12184
12185   t_type = GRE_API_TUNNEL_TYPE_L3;
12186
12187   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12188     {
12189       if (unformat (line_input, "del"))
12190         is_add = 0;
12191       else if (unformat (line_input, "instance %d", &instance))
12192         ;
12193       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
12194         {
12195           src_set = 1;
12196         }
12197       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
12198         {
12199           dst_set = 1;
12200         }
12201       else if (unformat (line_input, "outer-table-id %d", &outer_table_id))
12202         ;
12203       else if (unformat (line_input, "teb"))
12204         t_type = GRE_API_TUNNEL_TYPE_TEB;
12205       else if (unformat (line_input, "erspan %d", &session_id))
12206         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
12207       else
12208         {
12209           errmsg ("parse error '%U'", format_unformat_error, line_input);
12210           return -99;
12211         }
12212     }
12213
12214   if (src_set == 0)
12215     {
12216       errmsg ("tunnel src address not specified");
12217       return -99;
12218     }
12219   if (dst_set == 0)
12220     {
12221       errmsg ("tunnel dst address not specified");
12222       return -99;
12223     }
12224
12225   M (GRE_TUNNEL_ADD_DEL, mp);
12226
12227   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
12228   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
12229
12230   mp->tunnel.instance = htonl (instance);
12231   mp->tunnel.outer_table_id = htonl (outer_table_id);
12232   mp->is_add = is_add;
12233   mp->tunnel.session_id = htons ((u16) session_id);
12234   mp->tunnel.type = htonl (t_type);
12235
12236   S (mp);
12237   W (ret);
12238   return ret;
12239 }
12240
12241 static void vl_api_gre_tunnel_details_t_handler
12242   (vl_api_gre_tunnel_details_t * mp)
12243 {
12244   vat_main_t *vam = &vat_main;
12245
12246   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
12247          ntohl (mp->tunnel.sw_if_index),
12248          ntohl (mp->tunnel.instance),
12249          format_vl_api_address, &mp->tunnel.src,
12250          format_vl_api_address, &mp->tunnel.dst,
12251          mp->tunnel.type, ntohl (mp->tunnel.outer_table_id),
12252          ntohl (mp->tunnel.session_id));
12253 }
12254
12255 static void vl_api_gre_tunnel_details_t_handler_json
12256   (vl_api_gre_tunnel_details_t * mp)
12257 {
12258   vat_main_t *vam = &vat_main;
12259   vat_json_node_t *node = NULL;
12260
12261   if (VAT_JSON_ARRAY != vam->json_tree.type)
12262     {
12263       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12264       vat_json_init_array (&vam->json_tree);
12265     }
12266   node = vat_json_array_add (&vam->json_tree);
12267
12268   vat_json_init_object (node);
12269   vat_json_object_add_uint (node, "sw_if_index",
12270                             ntohl (mp->tunnel.sw_if_index));
12271   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
12272
12273   vat_json_object_add_address (node, "src", &mp->tunnel.src);
12274   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
12275   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
12276   vat_json_object_add_uint (node, "outer_table_id",
12277                             ntohl (mp->tunnel.outer_table_id));
12278   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
12279 }
12280
12281 static int
12282 api_gre_tunnel_dump (vat_main_t * vam)
12283 {
12284   unformat_input_t *i = vam->input;
12285   vl_api_gre_tunnel_dump_t *mp;
12286   vl_api_control_ping_t *mp_ping;
12287   u32 sw_if_index;
12288   u8 sw_if_index_set = 0;
12289   int ret;
12290
12291   /* Parse args required to build the message */
12292   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12293     {
12294       if (unformat (i, "sw_if_index %d", &sw_if_index))
12295         sw_if_index_set = 1;
12296       else
12297         break;
12298     }
12299
12300   if (sw_if_index_set == 0)
12301     {
12302       sw_if_index = ~0;
12303     }
12304
12305   if (!vam->json_output)
12306     {
12307       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
12308              "sw_if_index", "instance", "src_address", "dst_address",
12309              "tunnel_type", "outer_fib_id", "session_id");
12310     }
12311
12312   /* Get list of gre-tunnel interfaces */
12313   M (GRE_TUNNEL_DUMP, mp);
12314
12315   mp->sw_if_index = htonl (sw_if_index);
12316
12317   S (mp);
12318
12319   /* Use a control ping for synchronization */
12320   MPING (CONTROL_PING, mp_ping);
12321   S (mp_ping);
12322
12323   W (ret);
12324   return ret;
12325 }
12326
12327 static int
12328 api_l2_fib_clear_table (vat_main_t * vam)
12329 {
12330 //  unformat_input_t * i = vam->input;
12331   vl_api_l2_fib_clear_table_t *mp;
12332   int ret;
12333
12334   M (L2_FIB_CLEAR_TABLE, mp);
12335
12336   S (mp);
12337   W (ret);
12338   return ret;
12339 }
12340
12341 static int
12342 api_l2_interface_efp_filter (vat_main_t * vam)
12343 {
12344   unformat_input_t *i = vam->input;
12345   vl_api_l2_interface_efp_filter_t *mp;
12346   u32 sw_if_index;
12347   u8 enable = 1;
12348   u8 sw_if_index_set = 0;
12349   int ret;
12350
12351   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12352     {
12353       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12354         sw_if_index_set = 1;
12355       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12356         sw_if_index_set = 1;
12357       else if (unformat (i, "enable"))
12358         enable = 1;
12359       else if (unformat (i, "disable"))
12360         enable = 0;
12361       else
12362         {
12363           clib_warning ("parse error '%U'", format_unformat_error, i);
12364           return -99;
12365         }
12366     }
12367
12368   if (sw_if_index_set == 0)
12369     {
12370       errmsg ("missing sw_if_index");
12371       return -99;
12372     }
12373
12374   M (L2_INTERFACE_EFP_FILTER, mp);
12375
12376   mp->sw_if_index = ntohl (sw_if_index);
12377   mp->enable_disable = enable;
12378
12379   S (mp);
12380   W (ret);
12381   return ret;
12382 }
12383
12384 #define foreach_vtr_op                          \
12385 _("disable",  L2_VTR_DISABLED)                  \
12386 _("push-1",  L2_VTR_PUSH_1)                     \
12387 _("push-2",  L2_VTR_PUSH_2)                     \
12388 _("pop-1",  L2_VTR_POP_1)                       \
12389 _("pop-2",  L2_VTR_POP_2)                       \
12390 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12391 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12392 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12393 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12394
12395 static int
12396 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12397 {
12398   unformat_input_t *i = vam->input;
12399   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12400   u32 sw_if_index;
12401   u8 sw_if_index_set = 0;
12402   u8 vtr_op_set = 0;
12403   u32 vtr_op = 0;
12404   u32 push_dot1q = 1;
12405   u32 tag1 = ~0;
12406   u32 tag2 = ~0;
12407   int ret;
12408
12409   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12410     {
12411       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12412         sw_if_index_set = 1;
12413       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12414         sw_if_index_set = 1;
12415       else if (unformat (i, "vtr_op %d", &vtr_op))
12416         vtr_op_set = 1;
12417 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12418       foreach_vtr_op
12419 #undef _
12420         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12421         ;
12422       else if (unformat (i, "tag1 %d", &tag1))
12423         ;
12424       else if (unformat (i, "tag2 %d", &tag2))
12425         ;
12426       else
12427         {
12428           clib_warning ("parse error '%U'", format_unformat_error, i);
12429           return -99;
12430         }
12431     }
12432
12433   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12434     {
12435       errmsg ("missing vtr operation or sw_if_index");
12436       return -99;
12437     }
12438
12439   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12440   mp->sw_if_index = ntohl (sw_if_index);
12441   mp->vtr_op = ntohl (vtr_op);
12442   mp->push_dot1q = ntohl (push_dot1q);
12443   mp->tag1 = ntohl (tag1);
12444   mp->tag2 = ntohl (tag2);
12445
12446   S (mp);
12447   W (ret);
12448   return ret;
12449 }
12450
12451 static int
12452 api_create_vhost_user_if (vat_main_t * vam)
12453 {
12454   unformat_input_t *i = vam->input;
12455   vl_api_create_vhost_user_if_t *mp;
12456   u8 *file_name;
12457   u8 is_server = 0;
12458   u8 file_name_set = 0;
12459   u32 custom_dev_instance = ~0;
12460   u8 hwaddr[6];
12461   u8 use_custom_mac = 0;
12462   u8 disable_mrg_rxbuf = 0;
12463   u8 disable_indirect_desc = 0;
12464   u8 *tag = 0;
12465   u8 enable_gso = 0;
12466   u8 enable_packed = 0;
12467   int ret;
12468
12469   /* Shut up coverity */
12470   clib_memset (hwaddr, 0, sizeof (hwaddr));
12471
12472   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12473     {
12474       if (unformat (i, "socket %s", &file_name))
12475         {
12476           file_name_set = 1;
12477         }
12478       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12479         ;
12480       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12481         use_custom_mac = 1;
12482       else if (unformat (i, "server"))
12483         is_server = 1;
12484       else if (unformat (i, "disable_mrg_rxbuf"))
12485         disable_mrg_rxbuf = 1;
12486       else if (unformat (i, "disable_indirect_desc"))
12487         disable_indirect_desc = 1;
12488       else if (unformat (i, "gso"))
12489         enable_gso = 1;
12490       else if (unformat (i, "packed"))
12491         enable_packed = 1;
12492       else if (unformat (i, "tag %s", &tag))
12493         ;
12494       else
12495         break;
12496     }
12497
12498   if (file_name_set == 0)
12499     {
12500       errmsg ("missing socket file name");
12501       return -99;
12502     }
12503
12504   if (vec_len (file_name) > 255)
12505     {
12506       errmsg ("socket file name too long");
12507       return -99;
12508     }
12509   vec_add1 (file_name, 0);
12510
12511   M (CREATE_VHOST_USER_IF, mp);
12512
12513   mp->is_server = is_server;
12514   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
12515   mp->disable_indirect_desc = disable_indirect_desc;
12516   mp->enable_gso = enable_gso;
12517   mp->enable_packed = enable_packed;
12518   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12519   vec_free (file_name);
12520   if (custom_dev_instance != ~0)
12521     {
12522       mp->renumber = 1;
12523       mp->custom_dev_instance = ntohl (custom_dev_instance);
12524     }
12525
12526   mp->use_custom_mac = use_custom_mac;
12527   clib_memcpy (mp->mac_address, hwaddr, 6);
12528   if (tag)
12529     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
12530   vec_free (tag);
12531
12532   S (mp);
12533   W (ret);
12534   return ret;
12535 }
12536
12537 static int
12538 api_modify_vhost_user_if (vat_main_t * vam)
12539 {
12540   unformat_input_t *i = vam->input;
12541   vl_api_modify_vhost_user_if_t *mp;
12542   u8 *file_name;
12543   u8 is_server = 0;
12544   u8 file_name_set = 0;
12545   u32 custom_dev_instance = ~0;
12546   u8 sw_if_index_set = 0;
12547   u32 sw_if_index = (u32) ~ 0;
12548   u8 enable_gso = 0;
12549   u8 enable_packed = 0;
12550   int ret;
12551
12552   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12553     {
12554       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12555         sw_if_index_set = 1;
12556       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12557         sw_if_index_set = 1;
12558       else if (unformat (i, "socket %s", &file_name))
12559         {
12560           file_name_set = 1;
12561         }
12562       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12563         ;
12564       else if (unformat (i, "server"))
12565         is_server = 1;
12566       else if (unformat (i, "gso"))
12567         enable_gso = 1;
12568       else if (unformat (i, "packed"))
12569         enable_packed = 1;
12570       else
12571         break;
12572     }
12573
12574   if (sw_if_index_set == 0)
12575     {
12576       errmsg ("missing sw_if_index or interface name");
12577       return -99;
12578     }
12579
12580   if (file_name_set == 0)
12581     {
12582       errmsg ("missing socket file name");
12583       return -99;
12584     }
12585
12586   if (vec_len (file_name) > 255)
12587     {
12588       errmsg ("socket file name too long");
12589       return -99;
12590     }
12591   vec_add1 (file_name, 0);
12592
12593   M (MODIFY_VHOST_USER_IF, mp);
12594
12595   mp->sw_if_index = ntohl (sw_if_index);
12596   mp->is_server = is_server;
12597   mp->enable_gso = enable_gso;
12598   mp->enable_packed = enable_packed;
12599   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12600   vec_free (file_name);
12601   if (custom_dev_instance != ~0)
12602     {
12603       mp->renumber = 1;
12604       mp->custom_dev_instance = ntohl (custom_dev_instance);
12605     }
12606
12607   S (mp);
12608   W (ret);
12609   return ret;
12610 }
12611
12612 static int
12613 api_delete_vhost_user_if (vat_main_t * vam)
12614 {
12615   unformat_input_t *i = vam->input;
12616   vl_api_delete_vhost_user_if_t *mp;
12617   u32 sw_if_index = ~0;
12618   u8 sw_if_index_set = 0;
12619   int ret;
12620
12621   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12622     {
12623       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12624         sw_if_index_set = 1;
12625       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12626         sw_if_index_set = 1;
12627       else
12628         break;
12629     }
12630
12631   if (sw_if_index_set == 0)
12632     {
12633       errmsg ("missing sw_if_index or interface name");
12634       return -99;
12635     }
12636
12637
12638   M (DELETE_VHOST_USER_IF, mp);
12639
12640   mp->sw_if_index = ntohl (sw_if_index);
12641
12642   S (mp);
12643   W (ret);
12644   return ret;
12645 }
12646
12647 static void vl_api_sw_interface_vhost_user_details_t_handler
12648   (vl_api_sw_interface_vhost_user_details_t * mp)
12649 {
12650   vat_main_t *vam = &vat_main;
12651   u64 features;
12652
12653   features =
12654     clib_net_to_host_u32 (mp->features_first_32) | ((u64)
12655                                                     clib_net_to_host_u32
12656                                                     (mp->features_last_32) <<
12657                                                     32);
12658
12659   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
12660          (char *) mp->interface_name,
12661          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
12662          features, mp->is_server,
12663          ntohl (mp->num_regions), (char *) mp->sock_filename);
12664   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
12665 }
12666
12667 static void vl_api_sw_interface_vhost_user_details_t_handler_json
12668   (vl_api_sw_interface_vhost_user_details_t * mp)
12669 {
12670   vat_main_t *vam = &vat_main;
12671   vat_json_node_t *node = NULL;
12672
12673   if (VAT_JSON_ARRAY != vam->json_tree.type)
12674     {
12675       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12676       vat_json_init_array (&vam->json_tree);
12677     }
12678   node = vat_json_array_add (&vam->json_tree);
12679
12680   vat_json_init_object (node);
12681   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12682   vat_json_object_add_string_copy (node, "interface_name",
12683                                    mp->interface_name);
12684   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
12685                             ntohl (mp->virtio_net_hdr_sz));
12686   vat_json_object_add_uint (node, "features_first_32",
12687                             clib_net_to_host_u32 (mp->features_first_32));
12688   vat_json_object_add_uint (node, "features_last_32",
12689                             clib_net_to_host_u32 (mp->features_last_32));
12690   vat_json_object_add_uint (node, "is_server", mp->is_server);
12691   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
12692   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
12693   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
12694 }
12695
12696 static int
12697 api_sw_interface_vhost_user_dump (vat_main_t * vam)
12698 {
12699   unformat_input_t *i = vam->input;
12700   vl_api_sw_interface_vhost_user_dump_t *mp;
12701   vl_api_control_ping_t *mp_ping;
12702   int ret;
12703   u32 sw_if_index = ~0;
12704
12705   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12706     {
12707       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12708         ;
12709       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12710         ;
12711       else
12712         break;
12713     }
12714
12715   print (vam->ofp,
12716          "Interface name            idx hdr_sz features server regions filename");
12717
12718   /* Get list of vhost-user interfaces */
12719   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
12720   mp->sw_if_index = ntohl (sw_if_index);
12721   S (mp);
12722
12723   /* Use a control ping for synchronization */
12724   MPING (CONTROL_PING, mp_ping);
12725   S (mp_ping);
12726
12727   W (ret);
12728   return ret;
12729 }
12730
12731 static int
12732 api_show_version (vat_main_t * vam)
12733 {
12734   vl_api_show_version_t *mp;
12735   int ret;
12736
12737   M (SHOW_VERSION, mp);
12738
12739   S (mp);
12740   W (ret);
12741   return ret;
12742 }
12743
12744
12745 static int
12746 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
12747 {
12748   unformat_input_t *line_input = vam->input;
12749   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
12750   ip46_address_t local, remote;
12751   u8 is_add = 1;
12752   u8 local_set = 0;
12753   u8 remote_set = 0;
12754   u8 grp_set = 0;
12755   u32 mcast_sw_if_index = ~0;
12756   u32 encap_vrf_id = 0;
12757   u32 decap_vrf_id = 0;
12758   u8 protocol = ~0;
12759   u32 vni;
12760   u8 vni_set = 0;
12761   int ret;
12762
12763   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12764     {
12765       if (unformat (line_input, "del"))
12766         is_add = 0;
12767       else if (unformat (line_input, "local %U",
12768                          unformat_ip46_address, &local))
12769         {
12770           local_set = 1;
12771         }
12772       else if (unformat (line_input, "remote %U",
12773                          unformat_ip46_address, &remote))
12774         {
12775           remote_set = 1;
12776         }
12777       else if (unformat (line_input, "group %U %U",
12778                          unformat_ip46_address, &remote,
12779                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12780         {
12781           grp_set = remote_set = 1;
12782         }
12783       else if (unformat (line_input, "group %U",
12784                          unformat_ip46_address, &remote))
12785         {
12786           grp_set = remote_set = 1;
12787         }
12788       else
12789         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12790         ;
12791       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12792         ;
12793       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
12794         ;
12795       else if (unformat (line_input, "vni %d", &vni))
12796         vni_set = 1;
12797       else if (unformat (line_input, "next-ip4"))
12798         protocol = 1;
12799       else if (unformat (line_input, "next-ip6"))
12800         protocol = 2;
12801       else if (unformat (line_input, "next-ethernet"))
12802         protocol = 3;
12803       else if (unformat (line_input, "next-nsh"))
12804         protocol = 4;
12805       else
12806         {
12807           errmsg ("parse error '%U'", format_unformat_error, line_input);
12808           return -99;
12809         }
12810     }
12811
12812   if (local_set == 0)
12813     {
12814       errmsg ("tunnel local address not specified");
12815       return -99;
12816     }
12817   if (remote_set == 0)
12818     {
12819       errmsg ("tunnel remote address not specified");
12820       return -99;
12821     }
12822   if (grp_set && mcast_sw_if_index == ~0)
12823     {
12824       errmsg ("tunnel nonexistent multicast device");
12825       return -99;
12826     }
12827   if (ip46_address_is_ip4 (&local) != ip46_address_is_ip4 (&remote))
12828     {
12829       errmsg ("both IPv4 and IPv6 addresses specified");
12830       return -99;
12831     }
12832
12833   if (vni_set == 0)
12834     {
12835       errmsg ("vni not specified");
12836       return -99;
12837     }
12838
12839   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
12840
12841   ip_address_encode (&local,
12842                      ip46_address_is_ip4 (&local) ? IP46_TYPE_IP4 :
12843                      IP46_TYPE_IP6, &mp->local);
12844   ip_address_encode (&remote,
12845                      ip46_address_is_ip4 (&remote) ? IP46_TYPE_IP4 :
12846                      IP46_TYPE_IP6, &mp->remote);
12847
12848   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12849   mp->encap_vrf_id = ntohl (encap_vrf_id);
12850   mp->decap_vrf_id = ntohl (decap_vrf_id);
12851   mp->protocol = protocol;
12852   mp->vni = ntohl (vni);
12853   mp->is_add = is_add;
12854
12855   S (mp);
12856   W (ret);
12857   return ret;
12858 }
12859
12860 static void vl_api_vxlan_gpe_tunnel_details_t_handler
12861   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12862 {
12863   vat_main_t *vam = &vat_main;
12864   ip46_address_t local, remote;
12865
12866   ip_address_decode (&mp->local, &local);
12867   ip_address_decode (&mp->remote, &remote);
12868
12869   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
12870          ntohl (mp->sw_if_index),
12871          format_ip46_address, &local, IP46_TYPE_ANY,
12872          format_ip46_address, &remote, IP46_TYPE_ANY,
12873          ntohl (mp->vni), mp->protocol,
12874          ntohl (mp->mcast_sw_if_index),
12875          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
12876 }
12877
12878
12879 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
12880   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12881 {
12882   vat_main_t *vam = &vat_main;
12883   vat_json_node_t *node = NULL;
12884   struct in_addr ip4;
12885   struct in6_addr ip6;
12886   ip46_address_t local, remote;
12887
12888   ip_address_decode (&mp->local, &local);
12889   ip_address_decode (&mp->remote, &remote);
12890
12891   if (VAT_JSON_ARRAY != vam->json_tree.type)
12892     {
12893       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12894       vat_json_init_array (&vam->json_tree);
12895     }
12896   node = vat_json_array_add (&vam->json_tree);
12897
12898   vat_json_init_object (node);
12899   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12900   if (ip46_address_is_ip4 (&local))
12901     {
12902       clib_memcpy (&ip4, &local.ip4, sizeof (ip4));
12903       vat_json_object_add_ip4 (node, "local", ip4);
12904       clib_memcpy (&ip4, &remote.ip4, sizeof (ip4));
12905       vat_json_object_add_ip4 (node, "remote", ip4);
12906     }
12907   else
12908     {
12909       clib_memcpy (&ip6, &local.ip6, sizeof (ip6));
12910       vat_json_object_add_ip6 (node, "local", ip6);
12911       clib_memcpy (&ip6, &remote.ip6, sizeof (ip6));
12912       vat_json_object_add_ip6 (node, "remote", ip6);
12913     }
12914   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12915   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
12916   vat_json_object_add_uint (node, "mcast_sw_if_index",
12917                             ntohl (mp->mcast_sw_if_index));
12918   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12919   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
12920   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12921 }
12922
12923 static int
12924 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
12925 {
12926   unformat_input_t *i = vam->input;
12927   vl_api_vxlan_gpe_tunnel_dump_t *mp;
12928   vl_api_control_ping_t *mp_ping;
12929   u32 sw_if_index;
12930   u8 sw_if_index_set = 0;
12931   int ret;
12932
12933   /* Parse args required to build the message */
12934   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12935     {
12936       if (unformat (i, "sw_if_index %d", &sw_if_index))
12937         sw_if_index_set = 1;
12938       else
12939         break;
12940     }
12941
12942   if (sw_if_index_set == 0)
12943     {
12944       sw_if_index = ~0;
12945     }
12946
12947   if (!vam->json_output)
12948     {
12949       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
12950              "sw_if_index", "local", "remote", "vni",
12951              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
12952     }
12953
12954   /* Get list of vxlan-tunnel interfaces */
12955   M (VXLAN_GPE_TUNNEL_DUMP, mp);
12956
12957   mp->sw_if_index = htonl (sw_if_index);
12958
12959   S (mp);
12960
12961   /* Use a control ping for synchronization */
12962   MPING (CONTROL_PING, mp_ping);
12963   S (mp_ping);
12964
12965   W (ret);
12966   return ret;
12967 }
12968
12969 static void vl_api_l2_fib_table_details_t_handler
12970   (vl_api_l2_fib_table_details_t * mp)
12971 {
12972   vat_main_t *vam = &vat_main;
12973
12974   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
12975          "       %d       %d     %d",
12976          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
12977          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
12978          mp->bvi_mac);
12979 }
12980
12981 static void vl_api_l2_fib_table_details_t_handler_json
12982   (vl_api_l2_fib_table_details_t * mp)
12983 {
12984   vat_main_t *vam = &vat_main;
12985   vat_json_node_t *node = NULL;
12986
12987   if (VAT_JSON_ARRAY != vam->json_tree.type)
12988     {
12989       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12990       vat_json_init_array (&vam->json_tree);
12991     }
12992   node = vat_json_array_add (&vam->json_tree);
12993
12994   vat_json_init_object (node);
12995   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
12996   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
12997   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12998   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
12999   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13000   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13001 }
13002
13003 static int
13004 api_l2_fib_table_dump (vat_main_t * vam)
13005 {
13006   unformat_input_t *i = vam->input;
13007   vl_api_l2_fib_table_dump_t *mp;
13008   vl_api_control_ping_t *mp_ping;
13009   u32 bd_id;
13010   u8 bd_id_set = 0;
13011   int ret;
13012
13013   /* Parse args required to build the message */
13014   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13015     {
13016       if (unformat (i, "bd_id %d", &bd_id))
13017         bd_id_set = 1;
13018       else
13019         break;
13020     }
13021
13022   if (bd_id_set == 0)
13023     {
13024       errmsg ("missing bridge domain");
13025       return -99;
13026     }
13027
13028   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13029
13030   /* Get list of l2 fib entries */
13031   M (L2_FIB_TABLE_DUMP, mp);
13032
13033   mp->bd_id = ntohl (bd_id);
13034   S (mp);
13035
13036   /* Use a control ping for synchronization */
13037   MPING (CONTROL_PING, mp_ping);
13038   S (mp_ping);
13039
13040   W (ret);
13041   return ret;
13042 }
13043
13044
13045 static int
13046 api_interface_name_renumber (vat_main_t * vam)
13047 {
13048   unformat_input_t *line_input = vam->input;
13049   vl_api_interface_name_renumber_t *mp;
13050   u32 sw_if_index = ~0;
13051   u32 new_show_dev_instance = ~0;
13052   int ret;
13053
13054   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13055     {
13056       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13057                     &sw_if_index))
13058         ;
13059       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13060         ;
13061       else if (unformat (line_input, "new_show_dev_instance %d",
13062                          &new_show_dev_instance))
13063         ;
13064       else
13065         break;
13066     }
13067
13068   if (sw_if_index == ~0)
13069     {
13070       errmsg ("missing interface name or sw_if_index");
13071       return -99;
13072     }
13073
13074   if (new_show_dev_instance == ~0)
13075     {
13076       errmsg ("missing new_show_dev_instance");
13077       return -99;
13078     }
13079
13080   M (INTERFACE_NAME_RENUMBER, mp);
13081
13082   mp->sw_if_index = ntohl (sw_if_index);
13083   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13084
13085   S (mp);
13086   W (ret);
13087   return ret;
13088 }
13089
13090 static int
13091 api_want_l2_macs_events (vat_main_t * vam)
13092 {
13093   unformat_input_t *line_input = vam->input;
13094   vl_api_want_l2_macs_events_t *mp;
13095   u8 enable_disable = 1;
13096   u32 scan_delay = 0;
13097   u32 max_macs_in_event = 0;
13098   u32 learn_limit = 0;
13099   int ret;
13100
13101   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13102     {
13103       if (unformat (line_input, "learn-limit %d", &learn_limit))
13104         ;
13105       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13106         ;
13107       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13108         ;
13109       else if (unformat (line_input, "disable"))
13110         enable_disable = 0;
13111       else
13112         break;
13113     }
13114
13115   M (WANT_L2_MACS_EVENTS, mp);
13116   mp->enable_disable = enable_disable;
13117   mp->pid = htonl (getpid ());
13118   mp->learn_limit = htonl (learn_limit);
13119   mp->scan_delay = (u8) scan_delay;
13120   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13121   S (mp);
13122   W (ret);
13123   return ret;
13124 }
13125
13126 static int
13127 api_input_acl_set_interface (vat_main_t * vam)
13128 {
13129   unformat_input_t *i = vam->input;
13130   vl_api_input_acl_set_interface_t *mp;
13131   u32 sw_if_index;
13132   int sw_if_index_set;
13133   u32 ip4_table_index = ~0;
13134   u32 ip6_table_index = ~0;
13135   u32 l2_table_index = ~0;
13136   u8 is_add = 1;
13137   int ret;
13138
13139   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13140     {
13141       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13142         sw_if_index_set = 1;
13143       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13144         sw_if_index_set = 1;
13145       else if (unformat (i, "del"))
13146         is_add = 0;
13147       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13148         ;
13149       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13150         ;
13151       else if (unformat (i, "l2-table %d", &l2_table_index))
13152         ;
13153       else
13154         {
13155           clib_warning ("parse error '%U'", format_unformat_error, i);
13156           return -99;
13157         }
13158     }
13159
13160   if (sw_if_index_set == 0)
13161     {
13162       errmsg ("missing interface name or sw_if_index");
13163       return -99;
13164     }
13165
13166   M (INPUT_ACL_SET_INTERFACE, mp);
13167
13168   mp->sw_if_index = ntohl (sw_if_index);
13169   mp->ip4_table_index = ntohl (ip4_table_index);
13170   mp->ip6_table_index = ntohl (ip6_table_index);
13171   mp->l2_table_index = ntohl (l2_table_index);
13172   mp->is_add = is_add;
13173
13174   S (mp);
13175   W (ret);
13176   return ret;
13177 }
13178
13179 static int
13180 api_output_acl_set_interface (vat_main_t * vam)
13181 {
13182   unformat_input_t *i = vam->input;
13183   vl_api_output_acl_set_interface_t *mp;
13184   u32 sw_if_index;
13185   int sw_if_index_set;
13186   u32 ip4_table_index = ~0;
13187   u32 ip6_table_index = ~0;
13188   u32 l2_table_index = ~0;
13189   u8 is_add = 1;
13190   int ret;
13191
13192   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13193     {
13194       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13195         sw_if_index_set = 1;
13196       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13197         sw_if_index_set = 1;
13198       else if (unformat (i, "del"))
13199         is_add = 0;
13200       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13201         ;
13202       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13203         ;
13204       else if (unformat (i, "l2-table %d", &l2_table_index))
13205         ;
13206       else
13207         {
13208           clib_warning ("parse error '%U'", format_unformat_error, i);
13209           return -99;
13210         }
13211     }
13212
13213   if (sw_if_index_set == 0)
13214     {
13215       errmsg ("missing interface name or sw_if_index");
13216       return -99;
13217     }
13218
13219   M (OUTPUT_ACL_SET_INTERFACE, mp);
13220
13221   mp->sw_if_index = ntohl (sw_if_index);
13222   mp->ip4_table_index = ntohl (ip4_table_index);
13223   mp->ip6_table_index = ntohl (ip6_table_index);
13224   mp->l2_table_index = ntohl (l2_table_index);
13225   mp->is_add = is_add;
13226
13227   S (mp);
13228   W (ret);
13229   return ret;
13230 }
13231
13232 static int
13233 api_ip_address_dump (vat_main_t * vam)
13234 {
13235   unformat_input_t *i = vam->input;
13236   vl_api_ip_address_dump_t *mp;
13237   vl_api_control_ping_t *mp_ping;
13238   u32 sw_if_index = ~0;
13239   u8 sw_if_index_set = 0;
13240   u8 ipv4_set = 0;
13241   u8 ipv6_set = 0;
13242   int ret;
13243
13244   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13245     {
13246       if (unformat (i, "sw_if_index %d", &sw_if_index))
13247         sw_if_index_set = 1;
13248       else
13249         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13250         sw_if_index_set = 1;
13251       else if (unformat (i, "ipv4"))
13252         ipv4_set = 1;
13253       else if (unformat (i, "ipv6"))
13254         ipv6_set = 1;
13255       else
13256         break;
13257     }
13258
13259   if (ipv4_set && ipv6_set)
13260     {
13261       errmsg ("ipv4 and ipv6 flags cannot be both set");
13262       return -99;
13263     }
13264
13265   if ((!ipv4_set) && (!ipv6_set))
13266     {
13267       errmsg ("no ipv4 nor ipv6 flag set");
13268       return -99;
13269     }
13270
13271   if (sw_if_index_set == 0)
13272     {
13273       errmsg ("missing interface name or sw_if_index");
13274       return -99;
13275     }
13276
13277   vam->current_sw_if_index = sw_if_index;
13278   vam->is_ipv6 = ipv6_set;
13279
13280   M (IP_ADDRESS_DUMP, mp);
13281   mp->sw_if_index = ntohl (sw_if_index);
13282   mp->is_ipv6 = ipv6_set;
13283   S (mp);
13284
13285   /* Use a control ping for synchronization */
13286   MPING (CONTROL_PING, mp_ping);
13287   S (mp_ping);
13288
13289   W (ret);
13290   return ret;
13291 }
13292
13293 static int
13294 api_ip_dump (vat_main_t * vam)
13295 {
13296   vl_api_ip_dump_t *mp;
13297   vl_api_control_ping_t *mp_ping;
13298   unformat_input_t *in = vam->input;
13299   int ipv4_set = 0;
13300   int ipv6_set = 0;
13301   int is_ipv6;
13302   int i;
13303   int ret;
13304
13305   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13306     {
13307       if (unformat (in, "ipv4"))
13308         ipv4_set = 1;
13309       else if (unformat (in, "ipv6"))
13310         ipv6_set = 1;
13311       else
13312         break;
13313     }
13314
13315   if (ipv4_set && ipv6_set)
13316     {
13317       errmsg ("ipv4 and ipv6 flags cannot be both set");
13318       return -99;
13319     }
13320
13321   if ((!ipv4_set) && (!ipv6_set))
13322     {
13323       errmsg ("no ipv4 nor ipv6 flag set");
13324       return -99;
13325     }
13326
13327   is_ipv6 = ipv6_set;
13328   vam->is_ipv6 = is_ipv6;
13329
13330   /* free old data */
13331   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13332     {
13333       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13334     }
13335   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13336
13337   M (IP_DUMP, mp);
13338   mp->is_ipv6 = ipv6_set;
13339   S (mp);
13340
13341   /* Use a control ping for synchronization */
13342   MPING (CONTROL_PING, mp_ping);
13343   S (mp_ping);
13344
13345   W (ret);
13346   return ret;
13347 }
13348
13349 static int
13350 api_ipsec_spd_add_del (vat_main_t * vam)
13351 {
13352   unformat_input_t *i = vam->input;
13353   vl_api_ipsec_spd_add_del_t *mp;
13354   u32 spd_id = ~0;
13355   u8 is_add = 1;
13356   int ret;
13357
13358   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13359     {
13360       if (unformat (i, "spd_id %d", &spd_id))
13361         ;
13362       else if (unformat (i, "del"))
13363         is_add = 0;
13364       else
13365         {
13366           clib_warning ("parse error '%U'", format_unformat_error, i);
13367           return -99;
13368         }
13369     }
13370   if (spd_id == ~0)
13371     {
13372       errmsg ("spd_id must be set");
13373       return -99;
13374     }
13375
13376   M (IPSEC_SPD_ADD_DEL, mp);
13377
13378   mp->spd_id = ntohl (spd_id);
13379   mp->is_add = is_add;
13380
13381   S (mp);
13382   W (ret);
13383   return ret;
13384 }
13385
13386 static int
13387 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13388 {
13389   unformat_input_t *i = vam->input;
13390   vl_api_ipsec_interface_add_del_spd_t *mp;
13391   u32 sw_if_index;
13392   u8 sw_if_index_set = 0;
13393   u32 spd_id = (u32) ~ 0;
13394   u8 is_add = 1;
13395   int ret;
13396
13397   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13398     {
13399       if (unformat (i, "del"))
13400         is_add = 0;
13401       else if (unformat (i, "spd_id %d", &spd_id))
13402         ;
13403       else
13404         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13405         sw_if_index_set = 1;
13406       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13407         sw_if_index_set = 1;
13408       else
13409         {
13410           clib_warning ("parse error '%U'", format_unformat_error, i);
13411           return -99;
13412         }
13413
13414     }
13415
13416   if (spd_id == (u32) ~ 0)
13417     {
13418       errmsg ("spd_id must be set");
13419       return -99;
13420     }
13421
13422   if (sw_if_index_set == 0)
13423     {
13424       errmsg ("missing interface name or sw_if_index");
13425       return -99;
13426     }
13427
13428   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
13429
13430   mp->spd_id = ntohl (spd_id);
13431   mp->sw_if_index = ntohl (sw_if_index);
13432   mp->is_add = is_add;
13433
13434   S (mp);
13435   W (ret);
13436   return ret;
13437 }
13438
13439 static int
13440 api_ipsec_spd_entry_add_del (vat_main_t * vam)
13441 {
13442   unformat_input_t *i = vam->input;
13443   vl_api_ipsec_spd_entry_add_del_t *mp;
13444   u8 is_add = 1, is_outbound = 0;
13445   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
13446   i32 priority = 0;
13447   u32 rport_start = 0, rport_stop = (u32) ~ 0;
13448   u32 lport_start = 0, lport_stop = (u32) ~ 0;
13449   vl_api_address_t laddr_start = { }, laddr_stop =
13450   {
13451   }, raddr_start =
13452   {
13453   }, raddr_stop =
13454   {
13455   };
13456   int ret;
13457
13458   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13459     {
13460       if (unformat (i, "del"))
13461         is_add = 0;
13462       if (unformat (i, "outbound"))
13463         is_outbound = 1;
13464       if (unformat (i, "inbound"))
13465         is_outbound = 0;
13466       else if (unformat (i, "spd_id %d", &spd_id))
13467         ;
13468       else if (unformat (i, "sa_id %d", &sa_id))
13469         ;
13470       else if (unformat (i, "priority %d", &priority))
13471         ;
13472       else if (unformat (i, "protocol %d", &protocol))
13473         ;
13474       else if (unformat (i, "lport_start %d", &lport_start))
13475         ;
13476       else if (unformat (i, "lport_stop %d", &lport_stop))
13477         ;
13478       else if (unformat (i, "rport_start %d", &rport_start))
13479         ;
13480       else if (unformat (i, "rport_stop %d", &rport_stop))
13481         ;
13482       else if (unformat (i, "laddr_start %U",
13483                          unformat_vl_api_address, &laddr_start))
13484         ;
13485       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
13486                          &laddr_stop))
13487         ;
13488       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
13489                          &raddr_start))
13490         ;
13491       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
13492                          &raddr_stop))
13493         ;
13494       else
13495         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
13496         {
13497           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
13498             {
13499               clib_warning ("unsupported action: 'resolve'");
13500               return -99;
13501             }
13502         }
13503       else
13504         {
13505           clib_warning ("parse error '%U'", format_unformat_error, i);
13506           return -99;
13507         }
13508
13509     }
13510
13511   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
13512
13513   mp->is_add = is_add;
13514
13515   mp->entry.spd_id = ntohl (spd_id);
13516   mp->entry.priority = ntohl (priority);
13517   mp->entry.is_outbound = is_outbound;
13518
13519   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
13520                sizeof (vl_api_address_t));
13521   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
13522                sizeof (vl_api_address_t));
13523   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
13524                sizeof (vl_api_address_t));
13525   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
13526                sizeof (vl_api_address_t));
13527
13528   mp->entry.protocol = (u8) protocol;
13529   mp->entry.local_port_start = ntohs ((u16) lport_start);
13530   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
13531   mp->entry.remote_port_start = ntohs ((u16) rport_start);
13532   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
13533   mp->entry.policy = (u8) policy;
13534   mp->entry.sa_id = ntohl (sa_id);
13535
13536   S (mp);
13537   W (ret);
13538   return ret;
13539 }
13540
13541 static int
13542 api_ipsec_sad_entry_add_del (vat_main_t * vam)
13543 {
13544   unformat_input_t *i = vam->input;
13545   vl_api_ipsec_sad_entry_add_del_t *mp;
13546   u32 sad_id = 0, spi = 0;
13547   u8 *ck = 0, *ik = 0;
13548   u8 is_add = 1;
13549
13550   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
13551   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
13552   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
13553   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
13554   vl_api_address_t tun_src, tun_dst;
13555   int ret;
13556
13557   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13558     {
13559       if (unformat (i, "del"))
13560         is_add = 0;
13561       else if (unformat (i, "sad_id %d", &sad_id))
13562         ;
13563       else if (unformat (i, "spi %d", &spi))
13564         ;
13565       else if (unformat (i, "esp"))
13566         protocol = IPSEC_API_PROTO_ESP;
13567       else
13568         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
13569         {
13570           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13571           if (ADDRESS_IP6 == tun_src.af)
13572             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13573         }
13574       else
13575         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
13576         {
13577           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13578           if (ADDRESS_IP6 == tun_src.af)
13579             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13580         }
13581       else
13582         if (unformat (i, "crypto_alg %U",
13583                       unformat_ipsec_api_crypto_alg, &crypto_alg))
13584         ;
13585       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13586         ;
13587       else if (unformat (i, "integ_alg %U",
13588                          unformat_ipsec_api_integ_alg, &integ_alg))
13589         ;
13590       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13591         ;
13592       else
13593         {
13594           clib_warning ("parse error '%U'", format_unformat_error, i);
13595           return -99;
13596         }
13597
13598     }
13599
13600   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
13601
13602   mp->is_add = is_add;
13603   mp->entry.sad_id = ntohl (sad_id);
13604   mp->entry.protocol = protocol;
13605   mp->entry.spi = ntohl (spi);
13606   mp->entry.flags = flags;
13607
13608   mp->entry.crypto_algorithm = crypto_alg;
13609   mp->entry.integrity_algorithm = integ_alg;
13610   mp->entry.crypto_key.length = vec_len (ck);
13611   mp->entry.integrity_key.length = vec_len (ik);
13612
13613   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
13614     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
13615
13616   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
13617     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
13618
13619   if (ck)
13620     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
13621   if (ik)
13622     clib_memcpy (mp->entry.integrity_key.data, ik,
13623                  mp->entry.integrity_key.length);
13624
13625   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
13626     {
13627       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
13628                    sizeof (mp->entry.tunnel_src));
13629       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
13630                    sizeof (mp->entry.tunnel_dst));
13631     }
13632
13633   S (mp);
13634   W (ret);
13635   return ret;
13636 }
13637
13638 static int
13639 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
13640 {
13641   unformat_input_t *i = vam->input;
13642   vl_api_ipsec_tunnel_if_add_del_t *mp;
13643   u32 local_spi = 0, remote_spi = 0;
13644   u32 crypto_alg = 0, integ_alg = 0;
13645   u8 *lck = NULL, *rck = NULL;
13646   u8 *lik = NULL, *rik = NULL;
13647   vl_api_address_t local_ip = { 0 };
13648   vl_api_address_t remote_ip = { 0 };
13649   f64 before = 0;
13650   u8 is_add = 1;
13651   u8 esn = 0;
13652   u8 anti_replay = 0;
13653   u8 renumber = 0;
13654   u32 instance = ~0;
13655   u32 count = 1, jj;
13656   int ret = -1;
13657
13658   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13659     {
13660       if (unformat (i, "del"))
13661         is_add = 0;
13662       else if (unformat (i, "esn"))
13663         esn = 1;
13664       else if (unformat (i, "anti-replay"))
13665         anti_replay = 1;
13666       else if (unformat (i, "count %d", &count))
13667         ;
13668       else if (unformat (i, "local_spi %d", &local_spi))
13669         ;
13670       else if (unformat (i, "remote_spi %d", &remote_spi))
13671         ;
13672       else
13673         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
13674         ;
13675       else
13676         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
13677         ;
13678       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
13679         ;
13680       else
13681         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
13682         ;
13683       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
13684         ;
13685       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
13686         ;
13687       else
13688         if (unformat
13689             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
13690         {
13691           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
13692             {
13693               errmsg ("unsupported crypto-alg: '%U'\n",
13694                       format_ipsec_crypto_alg, crypto_alg);
13695               return -99;
13696             }
13697         }
13698       else
13699         if (unformat
13700             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
13701         {
13702           if (integ_alg >= IPSEC_INTEG_N_ALG)
13703             {
13704               errmsg ("unsupported integ-alg: '%U'\n",
13705                       format_ipsec_integ_alg, integ_alg);
13706               return -99;
13707             }
13708         }
13709       else if (unformat (i, "instance %u", &instance))
13710         renumber = 1;
13711       else
13712         {
13713           errmsg ("parse error '%U'\n", format_unformat_error, i);
13714           return -99;
13715         }
13716     }
13717
13718   if (count > 1)
13719     {
13720       /* Turn on async mode */
13721       vam->async_mode = 1;
13722       vam->async_errors = 0;
13723       before = vat_time_now (vam);
13724     }
13725
13726   for (jj = 0; jj < count; jj++)
13727     {
13728       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
13729
13730       mp->is_add = is_add;
13731       mp->esn = esn;
13732       mp->anti_replay = anti_replay;
13733
13734       if (jj > 0)
13735         increment_address (&remote_ip);
13736
13737       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
13738       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
13739
13740       mp->local_spi = htonl (local_spi + jj);
13741       mp->remote_spi = htonl (remote_spi + jj);
13742       mp->crypto_alg = (u8) crypto_alg;
13743
13744       mp->local_crypto_key_len = 0;
13745       if (lck)
13746         {
13747           mp->local_crypto_key_len = vec_len (lck);
13748           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
13749             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
13750           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
13751         }
13752
13753       mp->remote_crypto_key_len = 0;
13754       if (rck)
13755         {
13756           mp->remote_crypto_key_len = vec_len (rck);
13757           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
13758             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
13759           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
13760         }
13761
13762       mp->integ_alg = (u8) integ_alg;
13763
13764       mp->local_integ_key_len = 0;
13765       if (lik)
13766         {
13767           mp->local_integ_key_len = vec_len (lik);
13768           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
13769             mp->local_integ_key_len = sizeof (mp->local_integ_key);
13770           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
13771         }
13772
13773       mp->remote_integ_key_len = 0;
13774       if (rik)
13775         {
13776           mp->remote_integ_key_len = vec_len (rik);
13777           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
13778             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
13779           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
13780         }
13781
13782       if (renumber)
13783         {
13784           mp->renumber = renumber;
13785           mp->show_instance = ntohl (instance);
13786         }
13787       S (mp);
13788     }
13789
13790   /* When testing multiple add/del ops, use a control-ping to sync */
13791   if (count > 1)
13792     {
13793       vl_api_control_ping_t *mp_ping;
13794       f64 after;
13795       f64 timeout;
13796
13797       /* Shut off async mode */
13798       vam->async_mode = 0;
13799
13800       MPING (CONTROL_PING, mp_ping);
13801       S (mp_ping);
13802
13803       timeout = vat_time_now (vam) + 1.0;
13804       while (vat_time_now (vam) < timeout)
13805         if (vam->result_ready == 1)
13806           goto out;
13807       vam->retval = -99;
13808
13809     out:
13810       if (vam->retval == -99)
13811         errmsg ("timeout");
13812
13813       if (vam->async_errors > 0)
13814         {
13815           errmsg ("%d asynchronous errors", vam->async_errors);
13816           vam->retval = -98;
13817         }
13818       vam->async_errors = 0;
13819       after = vat_time_now (vam);
13820
13821       /* slim chance, but we might have eaten SIGTERM on the first iteration */
13822       if (jj > 0)
13823         count = jj;
13824
13825       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
13826              count, after - before, count / (after - before));
13827     }
13828   else
13829     {
13830       /* Wait for a reply... */
13831       W (ret);
13832       return ret;
13833     }
13834
13835   return ret;
13836 }
13837
13838 static void
13839 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
13840 {
13841   vat_main_t *vam = &vat_main;
13842
13843   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
13844          "crypto_key %U integ_alg %u integ_key %U flags %x "
13845          "tunnel_src_addr %U tunnel_dst_addr %U "
13846          "salt %u seq_outbound %lu last_seq_inbound %lu "
13847          "replay_window %lu stat_index %u\n",
13848          ntohl (mp->entry.sad_id),
13849          ntohl (mp->sw_if_index),
13850          ntohl (mp->entry.spi),
13851          ntohl (mp->entry.protocol),
13852          ntohl (mp->entry.crypto_algorithm),
13853          format_hex_bytes, mp->entry.crypto_key.data,
13854          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
13855          format_hex_bytes, mp->entry.integrity_key.data,
13856          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
13857          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
13858          &mp->entry.tunnel_dst, ntohl (mp->salt),
13859          clib_net_to_host_u64 (mp->seq_outbound),
13860          clib_net_to_host_u64 (mp->last_seq_inbound),
13861          clib_net_to_host_u64 (mp->replay_window), ntohl (mp->stat_index));
13862 }
13863
13864 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
13865 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
13866
13867 static void vl_api_ipsec_sa_details_t_handler_json
13868   (vl_api_ipsec_sa_details_t * mp)
13869 {
13870   vat_main_t *vam = &vat_main;
13871   vat_json_node_t *node = NULL;
13872   vl_api_ipsec_sad_flags_t flags;
13873
13874   if (VAT_JSON_ARRAY != vam->json_tree.type)
13875     {
13876       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13877       vat_json_init_array (&vam->json_tree);
13878     }
13879   node = vat_json_array_add (&vam->json_tree);
13880
13881   vat_json_init_object (node);
13882   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
13883   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13884   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
13885   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
13886   vat_json_object_add_uint (node, "crypto_alg",
13887                             ntohl (mp->entry.crypto_algorithm));
13888   vat_json_object_add_uint (node, "integ_alg",
13889                             ntohl (mp->entry.integrity_algorithm));
13890   flags = ntohl (mp->entry.flags);
13891   vat_json_object_add_uint (node, "use_esn",
13892                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
13893   vat_json_object_add_uint (node, "use_anti_replay",
13894                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
13895   vat_json_object_add_uint (node, "is_tunnel",
13896                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
13897   vat_json_object_add_uint (node, "is_tunnel_ip6",
13898                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
13899   vat_json_object_add_uint (node, "udp_encap",
13900                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
13901   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
13902                              mp->entry.crypto_key.length);
13903   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
13904                              mp->entry.integrity_key.length);
13905   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
13906   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
13907   vat_json_object_add_uint (node, "replay_window",
13908                             clib_net_to_host_u64 (mp->replay_window));
13909   vat_json_object_add_uint (node, "stat_index", ntohl (mp->stat_index));
13910 }
13911
13912 static int
13913 api_ipsec_sa_dump (vat_main_t * vam)
13914 {
13915   unformat_input_t *i = vam->input;
13916   vl_api_ipsec_sa_dump_t *mp;
13917   vl_api_control_ping_t *mp_ping;
13918   u32 sa_id = ~0;
13919   int ret;
13920
13921   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13922     {
13923       if (unformat (i, "sa_id %d", &sa_id))
13924         ;
13925       else
13926         {
13927           clib_warning ("parse error '%U'", format_unformat_error, i);
13928           return -99;
13929         }
13930     }
13931
13932   M (IPSEC_SA_DUMP, mp);
13933
13934   mp->sa_id = ntohl (sa_id);
13935
13936   S (mp);
13937
13938   /* Use a control ping for synchronization */
13939   M (CONTROL_PING, mp_ping);
13940   S (mp_ping);
13941
13942   W (ret);
13943   return ret;
13944 }
13945
13946 static int
13947 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
13948 {
13949   unformat_input_t *i = vam->input;
13950   vl_api_ipsec_tunnel_if_set_sa_t *mp;
13951   u32 sw_if_index = ~0;
13952   u32 sa_id = ~0;
13953   u8 is_outbound = (u8) ~ 0;
13954   int ret;
13955
13956   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13957     {
13958       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13959         ;
13960       else if (unformat (i, "sa_id %d", &sa_id))
13961         ;
13962       else if (unformat (i, "outbound"))
13963         is_outbound = 1;
13964       else if (unformat (i, "inbound"))
13965         is_outbound = 0;
13966       else
13967         {
13968           clib_warning ("parse error '%U'", format_unformat_error, i);
13969           return -99;
13970         }
13971     }
13972
13973   if (sw_if_index == ~0)
13974     {
13975       errmsg ("interface must be specified");
13976       return -99;
13977     }
13978
13979   if (sa_id == ~0)
13980     {
13981       errmsg ("SA ID must be specified");
13982       return -99;
13983     }
13984
13985   M (IPSEC_TUNNEL_IF_SET_SA, mp);
13986
13987   mp->sw_if_index = htonl (sw_if_index);
13988   mp->sa_id = htonl (sa_id);
13989   mp->is_outbound = is_outbound;
13990
13991   S (mp);
13992   W (ret);
13993
13994   return ret;
13995 }
13996
13997 static int
13998 api_get_first_msg_id (vat_main_t * vam)
13999 {
14000   vl_api_get_first_msg_id_t *mp;
14001   unformat_input_t *i = vam->input;
14002   u8 *name;
14003   u8 name_set = 0;
14004   int ret;
14005
14006   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14007     {
14008       if (unformat (i, "client %s", &name))
14009         name_set = 1;
14010       else
14011         break;
14012     }
14013
14014   if (name_set == 0)
14015     {
14016       errmsg ("missing client name");
14017       return -99;
14018     }
14019   vec_add1 (name, 0);
14020
14021   if (vec_len (name) > 63)
14022     {
14023       errmsg ("client name too long");
14024       return -99;
14025     }
14026
14027   M (GET_FIRST_MSG_ID, mp);
14028   clib_memcpy (mp->name, name, vec_len (name));
14029   S (mp);
14030   W (ret);
14031   return ret;
14032 }
14033
14034 static int
14035 api_cop_interface_enable_disable (vat_main_t * vam)
14036 {
14037   unformat_input_t *line_input = vam->input;
14038   vl_api_cop_interface_enable_disable_t *mp;
14039   u32 sw_if_index = ~0;
14040   u8 enable_disable = 1;
14041   int ret;
14042
14043   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14044     {
14045       if (unformat (line_input, "disable"))
14046         enable_disable = 0;
14047       if (unformat (line_input, "enable"))
14048         enable_disable = 1;
14049       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14050                          vam, &sw_if_index))
14051         ;
14052       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14053         ;
14054       else
14055         break;
14056     }
14057
14058   if (sw_if_index == ~0)
14059     {
14060       errmsg ("missing interface name or sw_if_index");
14061       return -99;
14062     }
14063
14064   /* Construct the API message */
14065   M (COP_INTERFACE_ENABLE_DISABLE, mp);
14066   mp->sw_if_index = ntohl (sw_if_index);
14067   mp->enable_disable = enable_disable;
14068
14069   /* send it... */
14070   S (mp);
14071   /* Wait for the reply */
14072   W (ret);
14073   return ret;
14074 }
14075
14076 static int
14077 api_cop_whitelist_enable_disable (vat_main_t * vam)
14078 {
14079   unformat_input_t *line_input = vam->input;
14080   vl_api_cop_whitelist_enable_disable_t *mp;
14081   u32 sw_if_index = ~0;
14082   u8 ip4 = 0, ip6 = 0, default_cop = 0;
14083   u32 fib_id = 0;
14084   int ret;
14085
14086   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14087     {
14088       if (unformat (line_input, "ip4"))
14089         ip4 = 1;
14090       else if (unformat (line_input, "ip6"))
14091         ip6 = 1;
14092       else if (unformat (line_input, "default"))
14093         default_cop = 1;
14094       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14095                          vam, &sw_if_index))
14096         ;
14097       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14098         ;
14099       else if (unformat (line_input, "fib-id %d", &fib_id))
14100         ;
14101       else
14102         break;
14103     }
14104
14105   if (sw_if_index == ~0)
14106     {
14107       errmsg ("missing interface name or sw_if_index");
14108       return -99;
14109     }
14110
14111   /* Construct the API message */
14112   M (COP_WHITELIST_ENABLE_DISABLE, mp);
14113   mp->sw_if_index = ntohl (sw_if_index);
14114   mp->fib_id = ntohl (fib_id);
14115   mp->ip4 = ip4;
14116   mp->ip6 = ip6;
14117   mp->default_cop = default_cop;
14118
14119   /* send it... */
14120   S (mp);
14121   /* Wait for the reply */
14122   W (ret);
14123   return ret;
14124 }
14125
14126 static int
14127 api_get_node_graph (vat_main_t * vam)
14128 {
14129   vl_api_get_node_graph_t *mp;
14130   int ret;
14131
14132   M (GET_NODE_GRAPH, mp);
14133
14134   /* send it... */
14135   S (mp);
14136   /* Wait for the reply */
14137   W (ret);
14138   return ret;
14139 }
14140
14141 /* *INDENT-OFF* */
14142 /** Used for parsing LISP eids */
14143 typedef CLIB_PACKED(struct{
14144   union {
14145           ip46_address_t ip;
14146           mac_address_t mac;
14147           lisp_nsh_api_t nsh;
14148   } addr;
14149   u32 len;       /**< prefix length if IP */
14150   u8 type;      /**< type of eid */
14151 }) lisp_eid_vat_t;
14152 /* *INDENT-ON* */
14153
14154 static uword
14155 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
14156 {
14157   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
14158
14159   clib_memset (a, 0, sizeof (a[0]));
14160
14161   if (unformat (input, "%U/%d", unformat_ip46_address, a->addr.ip, &a->len))
14162     {
14163       a->type = 0;              /* ip prefix type */
14164     }
14165   else if (unformat (input, "%U", unformat_ethernet_address, a->addr.mac))
14166     {
14167       a->type = 1;              /* mac type */
14168     }
14169   else if (unformat (input, "%U", unformat_nsh_address, a->addr.nsh))
14170     {
14171       a->type = 2;              /* NSH type */
14172       a->addr.nsh.spi = clib_host_to_net_u32 (a->addr.nsh.spi);
14173     }
14174   else
14175     {
14176       return 0;
14177     }
14178
14179   if (a->type == 0)
14180     {
14181       if (ip46_address_is_ip4 (&a->addr.ip))
14182         return a->len > 32 ? 1 : 0;
14183       else
14184         return a->len > 128 ? 1 : 0;
14185     }
14186
14187   return 1;
14188 }
14189
14190 static void
14191 lisp_eid_put_vat (vl_api_eid_t * eid, const lisp_eid_vat_t * vat_eid)
14192 {
14193   eid->type = vat_eid->type;
14194   switch (eid->type)
14195     {
14196     case EID_TYPE_API_PREFIX:
14197       if (ip46_address_is_ip4 (&vat_eid->addr.ip))
14198         {
14199           clib_memcpy (&eid->address.prefix.address.un.ip4,
14200                        &vat_eid->addr.ip.ip4, 4);
14201           eid->address.prefix.address.af = ADDRESS_IP4;
14202           eid->address.prefix.len = vat_eid->len;
14203         }
14204       else
14205         {
14206           clib_memcpy (&eid->address.prefix.address.un.ip6,
14207                        &vat_eid->addr.ip.ip6, 16);
14208           eid->address.prefix.address.af = ADDRESS_IP6;
14209           eid->address.prefix.len = vat_eid->len;
14210         }
14211       return;
14212     case EID_TYPE_API_MAC:
14213       clib_memcpy (&eid->address.mac, &vat_eid->addr.mac,
14214                    sizeof (eid->address.mac));
14215       return;
14216     case EID_TYPE_API_NSH:
14217       clib_memcpy (&eid->address.nsh, &vat_eid->addr.nsh,
14218                    sizeof (eid->address.nsh));
14219       return;
14220     default:
14221       ASSERT (0);
14222       return;
14223     }
14224 }
14225
14226 static int
14227 api_one_add_del_locator_set (vat_main_t * vam)
14228 {
14229   unformat_input_t *input = vam->input;
14230   vl_api_one_add_del_locator_set_t *mp;
14231   u8 is_add = 1;
14232   u8 *locator_set_name = NULL;
14233   u8 locator_set_name_set = 0;
14234   vl_api_local_locator_t locator, *locators = 0;
14235   u32 sw_if_index, priority, weight;
14236   u32 data_len = 0;
14237
14238   int ret;
14239   /* Parse args required to build the message */
14240   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14241     {
14242       if (unformat (input, "del"))
14243         {
14244           is_add = 0;
14245         }
14246       else if (unformat (input, "locator-set %s", &locator_set_name))
14247         {
14248           locator_set_name_set = 1;
14249         }
14250       else if (unformat (input, "sw_if_index %u p %u w %u",
14251                          &sw_if_index, &priority, &weight))
14252         {
14253           locator.sw_if_index = htonl (sw_if_index);
14254           locator.priority = priority;
14255           locator.weight = weight;
14256           vec_add1 (locators, locator);
14257         }
14258       else
14259         if (unformat
14260             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14261              &sw_if_index, &priority, &weight))
14262         {
14263           locator.sw_if_index = htonl (sw_if_index);
14264           locator.priority = priority;
14265           locator.weight = weight;
14266           vec_add1 (locators, locator);
14267         }
14268       else
14269         break;
14270     }
14271
14272   if (locator_set_name_set == 0)
14273     {
14274       errmsg ("missing locator-set name");
14275       vec_free (locators);
14276       return -99;
14277     }
14278
14279   if (vec_len (locator_set_name) > 64)
14280     {
14281       errmsg ("locator-set name too long");
14282       vec_free (locator_set_name);
14283       vec_free (locators);
14284       return -99;
14285     }
14286   vec_add1 (locator_set_name, 0);
14287
14288   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14289
14290   /* Construct the API message */
14291   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14292
14293   mp->is_add = is_add;
14294   clib_memcpy (mp->locator_set_name, locator_set_name,
14295                vec_len (locator_set_name));
14296   vec_free (locator_set_name);
14297
14298   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14299   if (locators)
14300     clib_memcpy (mp->locators, locators, data_len);
14301   vec_free (locators);
14302
14303   /* send it... */
14304   S (mp);
14305
14306   /* Wait for a reply... */
14307   W (ret);
14308   return ret;
14309 }
14310
14311 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14312
14313 static int
14314 api_one_add_del_locator (vat_main_t * vam)
14315 {
14316   unformat_input_t *input = vam->input;
14317   vl_api_one_add_del_locator_t *mp;
14318   u32 tmp_if_index = ~0;
14319   u32 sw_if_index = ~0;
14320   u8 sw_if_index_set = 0;
14321   u8 sw_if_index_if_name_set = 0;
14322   u32 priority = ~0;
14323   u8 priority_set = 0;
14324   u32 weight = ~0;
14325   u8 weight_set = 0;
14326   u8 is_add = 1;
14327   u8 *locator_set_name = NULL;
14328   u8 locator_set_name_set = 0;
14329   int ret;
14330
14331   /* Parse args required to build the message */
14332   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14333     {
14334       if (unformat (input, "del"))
14335         {
14336           is_add = 0;
14337         }
14338       else if (unformat (input, "locator-set %s", &locator_set_name))
14339         {
14340           locator_set_name_set = 1;
14341         }
14342       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14343                          &tmp_if_index))
14344         {
14345           sw_if_index_if_name_set = 1;
14346           sw_if_index = tmp_if_index;
14347         }
14348       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14349         {
14350           sw_if_index_set = 1;
14351           sw_if_index = tmp_if_index;
14352         }
14353       else if (unformat (input, "p %d", &priority))
14354         {
14355           priority_set = 1;
14356         }
14357       else if (unformat (input, "w %d", &weight))
14358         {
14359           weight_set = 1;
14360         }
14361       else
14362         break;
14363     }
14364
14365   if (locator_set_name_set == 0)
14366     {
14367       errmsg ("missing locator-set name");
14368       return -99;
14369     }
14370
14371   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14372     {
14373       errmsg ("missing sw_if_index");
14374       vec_free (locator_set_name);
14375       return -99;
14376     }
14377
14378   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14379     {
14380       errmsg ("cannot use both params interface name and sw_if_index");
14381       vec_free (locator_set_name);
14382       return -99;
14383     }
14384
14385   if (priority_set == 0)
14386     {
14387       errmsg ("missing locator-set priority");
14388       vec_free (locator_set_name);
14389       return -99;
14390     }
14391
14392   if (weight_set == 0)
14393     {
14394       errmsg ("missing locator-set weight");
14395       vec_free (locator_set_name);
14396       return -99;
14397     }
14398
14399   if (vec_len (locator_set_name) > 64)
14400     {
14401       errmsg ("locator-set name too long");
14402       vec_free (locator_set_name);
14403       return -99;
14404     }
14405   vec_add1 (locator_set_name, 0);
14406
14407   /* Construct the API message */
14408   M (ONE_ADD_DEL_LOCATOR, mp);
14409
14410   mp->is_add = is_add;
14411   mp->sw_if_index = ntohl (sw_if_index);
14412   mp->priority = priority;
14413   mp->weight = weight;
14414   clib_memcpy (mp->locator_set_name, locator_set_name,
14415                vec_len (locator_set_name));
14416   vec_free (locator_set_name);
14417
14418   /* send it... */
14419   S (mp);
14420
14421   /* Wait for a reply... */
14422   W (ret);
14423   return ret;
14424 }
14425
14426 #define api_lisp_add_del_locator api_one_add_del_locator
14427
14428 uword
14429 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
14430 {
14431   u32 *key_id = va_arg (*args, u32 *);
14432   u8 *s = 0;
14433
14434   if (unformat (input, "%s", &s))
14435     {
14436       if (!strcmp ((char *) s, "sha1"))
14437         key_id[0] = HMAC_SHA_1_96;
14438       else if (!strcmp ((char *) s, "sha256"))
14439         key_id[0] = HMAC_SHA_256_128;
14440       else
14441         {
14442           clib_warning ("invalid key_id: '%s'", s);
14443           key_id[0] = HMAC_NO_KEY;
14444         }
14445     }
14446   else
14447     return 0;
14448
14449   vec_free (s);
14450   return 1;
14451 }
14452
14453 static int
14454 api_one_add_del_local_eid (vat_main_t * vam)
14455 {
14456   unformat_input_t *input = vam->input;
14457   vl_api_one_add_del_local_eid_t *mp;
14458   u8 is_add = 1;
14459   u8 eid_set = 0;
14460   lisp_eid_vat_t _eid, *eid = &_eid;
14461   u8 *locator_set_name = 0;
14462   u8 locator_set_name_set = 0;
14463   u32 vni = 0;
14464   u16 key_id = 0;
14465   u8 *key = 0;
14466   int ret;
14467
14468   /* Parse args required to build the message */
14469   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14470     {
14471       if (unformat (input, "del"))
14472         {
14473           is_add = 0;
14474         }
14475       else if (unformat (input, "vni %d", &vni))
14476         {
14477           ;
14478         }
14479       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14480         {
14481           eid_set = 1;
14482         }
14483       else if (unformat (input, "locator-set %s", &locator_set_name))
14484         {
14485           locator_set_name_set = 1;
14486         }
14487       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
14488         ;
14489       else if (unformat (input, "secret-key %_%v%_", &key))
14490         ;
14491       else
14492         break;
14493     }
14494
14495   if (locator_set_name_set == 0)
14496     {
14497       errmsg ("missing locator-set name");
14498       return -99;
14499     }
14500
14501   if (0 == eid_set)
14502     {
14503       errmsg ("EID address not set!");
14504       vec_free (locator_set_name);
14505       return -99;
14506     }
14507
14508   if (key && (0 == key_id))
14509     {
14510       errmsg ("invalid key_id!");
14511       return -99;
14512     }
14513
14514   if (vec_len (key) > 64)
14515     {
14516       errmsg ("key too long");
14517       vec_free (key);
14518       return -99;
14519     }
14520
14521   if (vec_len (locator_set_name) > 64)
14522     {
14523       errmsg ("locator-set name too long");
14524       vec_free (locator_set_name);
14525       return -99;
14526     }
14527   vec_add1 (locator_set_name, 0);
14528
14529   /* Construct the API message */
14530   M (ONE_ADD_DEL_LOCAL_EID, mp);
14531
14532   mp->is_add = is_add;
14533   lisp_eid_put_vat (&mp->eid, eid);
14534   mp->vni = clib_host_to_net_u32 (vni);
14535   mp->key.id = key_id;
14536   clib_memcpy (mp->locator_set_name, locator_set_name,
14537                vec_len (locator_set_name));
14538   clib_memcpy (mp->key.key, key, vec_len (key));
14539
14540   vec_free (locator_set_name);
14541   vec_free (key);
14542
14543   /* send it... */
14544   S (mp);
14545
14546   /* Wait for a reply... */
14547   W (ret);
14548   return ret;
14549 }
14550
14551 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
14552
14553 static int
14554 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
14555 {
14556   u32 dp_table = 0, vni = 0;;
14557   unformat_input_t *input = vam->input;
14558   vl_api_gpe_add_del_fwd_entry_t *mp;
14559   u8 is_add = 1;
14560   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
14561   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
14562   u8 rmt_eid_set = 0, lcl_eid_set = 0;
14563   u32 action = ~0, w;
14564   ip4_address_t rmt_rloc4, lcl_rloc4;
14565   ip6_address_t rmt_rloc6, lcl_rloc6;
14566   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
14567   int ret;
14568
14569   clib_memset (&rloc, 0, sizeof (rloc));
14570
14571   /* Parse args required to build the message */
14572   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14573     {
14574       if (unformat (input, "del"))
14575         is_add = 0;
14576       else if (unformat (input, "add"))
14577         is_add = 1;
14578       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
14579         {
14580           rmt_eid_set = 1;
14581         }
14582       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
14583         {
14584           lcl_eid_set = 1;
14585         }
14586       else if (unformat (input, "vrf %d", &dp_table))
14587         ;
14588       else if (unformat (input, "bd %d", &dp_table))
14589         ;
14590       else if (unformat (input, "vni %d", &vni))
14591         ;
14592       else if (unformat (input, "w %d", &w))
14593         {
14594           if (!curr_rloc)
14595             {
14596               errmsg ("No RLOC configured for setting priority/weight!");
14597               return -99;
14598             }
14599           curr_rloc->weight = w;
14600         }
14601       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14602                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14603         {
14604           rloc.addr.af = 0;
14605           clib_memcpy (&rloc.addr.un.ip4, &lcl_rloc4, sizeof (lcl_rloc4));
14606           rloc.weight = 0;
14607           vec_add1 (lcl_locs, rloc);
14608
14609           clib_memcpy (&rloc.addr.un.ip4, &rmt_rloc4, sizeof (rmt_rloc4));
14610           vec_add1 (rmt_locs, rloc);
14611           /* weight saved in rmt loc */
14612           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14613         }
14614       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14615                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14616         {
14617           rloc.addr.af = 1;
14618           clib_memcpy (&rloc.addr.un.ip6, &lcl_rloc6, sizeof (lcl_rloc6));
14619           rloc.weight = 0;
14620           vec_add1 (lcl_locs, rloc);
14621
14622           clib_memcpy (&rloc.addr.un.ip6, &rmt_rloc6, sizeof (rmt_rloc6));
14623           vec_add1 (rmt_locs, rloc);
14624           /* weight saved in rmt loc */
14625           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14626         }
14627       else if (unformat (input, "action %d", &action))
14628         {
14629           ;
14630         }
14631       else
14632         {
14633           clib_warning ("parse error '%U'", format_unformat_error, input);
14634           return -99;
14635         }
14636     }
14637
14638   if (!rmt_eid_set)
14639     {
14640       errmsg ("remote eid addresses not set");
14641       return -99;
14642     }
14643
14644   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14645     {
14646       errmsg ("eid types don't match");
14647       return -99;
14648     }
14649
14650   if (0 == rmt_locs && (u32) ~ 0 == action)
14651     {
14652       errmsg ("action not set for negative mapping");
14653       return -99;
14654     }
14655
14656   /* Construct the API message */
14657   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14658       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
14659
14660   mp->is_add = is_add;
14661   lisp_eid_put_vat (&mp->rmt_eid, rmt_eid);
14662   lisp_eid_put_vat (&mp->lcl_eid, lcl_eid);
14663   mp->dp_table = clib_host_to_net_u32 (dp_table);
14664   mp->vni = clib_host_to_net_u32 (vni);
14665   mp->action = action;
14666
14667   if (0 != rmt_locs && 0 != lcl_locs)
14668     {
14669       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14670       clib_memcpy (mp->locs, lcl_locs,
14671                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
14672
14673       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14674       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14675                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
14676     }
14677   vec_free (lcl_locs);
14678   vec_free (rmt_locs);
14679
14680   /* send it... */
14681   S (mp);
14682
14683   /* Wait for a reply... */
14684   W (ret);
14685   return ret;
14686 }
14687
14688 static int
14689 api_one_add_del_map_server (vat_main_t * vam)
14690 {
14691   unformat_input_t *input = vam->input;
14692   vl_api_one_add_del_map_server_t *mp;
14693   u8 is_add = 1;
14694   u8 ipv4_set = 0;
14695   u8 ipv6_set = 0;
14696   ip4_address_t ipv4;
14697   ip6_address_t ipv6;
14698   int ret;
14699
14700   /* Parse args required to build the message */
14701   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14702     {
14703       if (unformat (input, "del"))
14704         {
14705           is_add = 0;
14706         }
14707       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14708         {
14709           ipv4_set = 1;
14710         }
14711       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14712         {
14713           ipv6_set = 1;
14714         }
14715       else
14716         break;
14717     }
14718
14719   if (ipv4_set && ipv6_set)
14720     {
14721       errmsg ("both eid v4 and v6 addresses set");
14722       return -99;
14723     }
14724
14725   if (!ipv4_set && !ipv6_set)
14726     {
14727       errmsg ("eid addresses not set");
14728       return -99;
14729     }
14730
14731   /* Construct the API message */
14732   M (ONE_ADD_DEL_MAP_SERVER, mp);
14733
14734   mp->is_add = is_add;
14735   if (ipv6_set)
14736     {
14737       mp->ip_address.af = 1;
14738       clib_memcpy (mp->ip_address.un.ip6, &ipv6, sizeof (ipv6));
14739     }
14740   else
14741     {
14742       mp->ip_address.af = 0;
14743       clib_memcpy (mp->ip_address.un.ip4, &ipv4, sizeof (ipv4));
14744     }
14745
14746   /* send it... */
14747   S (mp);
14748
14749   /* Wait for a reply... */
14750   W (ret);
14751   return ret;
14752 }
14753
14754 #define api_lisp_add_del_map_server api_one_add_del_map_server
14755
14756 static int
14757 api_one_add_del_map_resolver (vat_main_t * vam)
14758 {
14759   unformat_input_t *input = vam->input;
14760   vl_api_one_add_del_map_resolver_t *mp;
14761   u8 is_add = 1;
14762   u8 ipv4_set = 0;
14763   u8 ipv6_set = 0;
14764   ip4_address_t ipv4;
14765   ip6_address_t ipv6;
14766   int ret;
14767
14768   /* Parse args required to build the message */
14769   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14770     {
14771       if (unformat (input, "del"))
14772         {
14773           is_add = 0;
14774         }
14775       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14776         {
14777           ipv4_set = 1;
14778         }
14779       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14780         {
14781           ipv6_set = 1;
14782         }
14783       else
14784         break;
14785     }
14786
14787   if (ipv4_set && ipv6_set)
14788     {
14789       errmsg ("both eid v4 and v6 addresses set");
14790       return -99;
14791     }
14792
14793   if (!ipv4_set && !ipv6_set)
14794     {
14795       errmsg ("eid addresses not set");
14796       return -99;
14797     }
14798
14799   /* Construct the API message */
14800   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
14801
14802   mp->is_add = is_add;
14803   if (ipv6_set)
14804     {
14805       mp->ip_address.af = 1;
14806       clib_memcpy (mp->ip_address.un.ip6, &ipv6, sizeof (ipv6));
14807     }
14808   else
14809     {
14810       mp->ip_address.af = 0;
14811       clib_memcpy (mp->ip_address.un.ip6, &ipv4, sizeof (ipv4));
14812     }
14813
14814   /* send it... */
14815   S (mp);
14816
14817   /* Wait for a reply... */
14818   W (ret);
14819   return ret;
14820 }
14821
14822 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14823
14824 static int
14825 api_lisp_gpe_enable_disable (vat_main_t * vam)
14826 {
14827   unformat_input_t *input = vam->input;
14828   vl_api_gpe_enable_disable_t *mp;
14829   u8 is_set = 0;
14830   u8 is_enable = 1;
14831   int ret;
14832
14833   /* Parse args required to build the message */
14834   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14835     {
14836       if (unformat (input, "enable"))
14837         {
14838           is_set = 1;
14839           is_enable = 1;
14840         }
14841       else if (unformat (input, "disable"))
14842         {
14843           is_set = 1;
14844           is_enable = 0;
14845         }
14846       else
14847         break;
14848     }
14849
14850   if (is_set == 0)
14851     {
14852       errmsg ("Value not set");
14853       return -99;
14854     }
14855
14856   /* Construct the API message */
14857   M (GPE_ENABLE_DISABLE, mp);
14858
14859   mp->is_enable = is_enable;
14860
14861   /* send it... */
14862   S (mp);
14863
14864   /* Wait for a reply... */
14865   W (ret);
14866   return ret;
14867 }
14868
14869 static int
14870 api_one_rloc_probe_enable_disable (vat_main_t * vam)
14871 {
14872   unformat_input_t *input = vam->input;
14873   vl_api_one_rloc_probe_enable_disable_t *mp;
14874   u8 is_set = 0;
14875   u8 is_enable = 0;
14876   int ret;
14877
14878   /* Parse args required to build the message */
14879   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14880     {
14881       if (unformat (input, "enable"))
14882         {
14883           is_set = 1;
14884           is_enable = 1;
14885         }
14886       else if (unformat (input, "disable"))
14887         is_set = 1;
14888       else
14889         break;
14890     }
14891
14892   if (!is_set)
14893     {
14894       errmsg ("Value not set");
14895       return -99;
14896     }
14897
14898   /* Construct the API message */
14899   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
14900
14901   mp->is_enable = is_enable;
14902
14903   /* send it... */
14904   S (mp);
14905
14906   /* Wait for a reply... */
14907   W (ret);
14908   return ret;
14909 }
14910
14911 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14912
14913 static int
14914 api_one_map_register_enable_disable (vat_main_t * vam)
14915 {
14916   unformat_input_t *input = vam->input;
14917   vl_api_one_map_register_enable_disable_t *mp;
14918   u8 is_set = 0;
14919   u8 is_enable = 0;
14920   int ret;
14921
14922   /* Parse args required to build the message */
14923   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14924     {
14925       if (unformat (input, "enable"))
14926         {
14927           is_set = 1;
14928           is_enable = 1;
14929         }
14930       else if (unformat (input, "disable"))
14931         is_set = 1;
14932       else
14933         break;
14934     }
14935
14936   if (!is_set)
14937     {
14938       errmsg ("Value not set");
14939       return -99;
14940     }
14941
14942   /* Construct the API message */
14943   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
14944
14945   mp->is_enable = is_enable;
14946
14947   /* send it... */
14948   S (mp);
14949
14950   /* Wait for a reply... */
14951   W (ret);
14952   return ret;
14953 }
14954
14955 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14956
14957 static int
14958 api_one_enable_disable (vat_main_t * vam)
14959 {
14960   unformat_input_t *input = vam->input;
14961   vl_api_one_enable_disable_t *mp;
14962   u8 is_set = 0;
14963   u8 is_enable = 0;
14964   int ret;
14965
14966   /* Parse args required to build the message */
14967   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14968     {
14969       if (unformat (input, "enable"))
14970         {
14971           is_set = 1;
14972           is_enable = 1;
14973         }
14974       else if (unformat (input, "disable"))
14975         {
14976           is_set = 1;
14977         }
14978       else
14979         break;
14980     }
14981
14982   if (!is_set)
14983     {
14984       errmsg ("Value not set");
14985       return -99;
14986     }
14987
14988   /* Construct the API message */
14989   M (ONE_ENABLE_DISABLE, mp);
14990
14991   mp->is_enable = is_enable;
14992
14993   /* send it... */
14994   S (mp);
14995
14996   /* Wait for a reply... */
14997   W (ret);
14998   return ret;
14999 }
15000
15001 #define api_lisp_enable_disable api_one_enable_disable
15002
15003 static int
15004 api_one_enable_disable_xtr_mode (vat_main_t * vam)
15005 {
15006   unformat_input_t *input = vam->input;
15007   vl_api_one_enable_disable_xtr_mode_t *mp;
15008   u8 is_set = 0;
15009   u8 is_enable = 0;
15010   int ret;
15011
15012   /* Parse args required to build the message */
15013   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15014     {
15015       if (unformat (input, "enable"))
15016         {
15017           is_set = 1;
15018           is_enable = 1;
15019         }
15020       else if (unformat (input, "disable"))
15021         {
15022           is_set = 1;
15023         }
15024       else
15025         break;
15026     }
15027
15028   if (!is_set)
15029     {
15030       errmsg ("Value not set");
15031       return -99;
15032     }
15033
15034   /* Construct the API message */
15035   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
15036
15037   mp->is_enable = is_enable;
15038
15039   /* send it... */
15040   S (mp);
15041
15042   /* Wait for a reply... */
15043   W (ret);
15044   return ret;
15045 }
15046
15047 static int
15048 api_one_show_xtr_mode (vat_main_t * vam)
15049 {
15050   vl_api_one_show_xtr_mode_t *mp;
15051   int ret;
15052
15053   /* Construct the API message */
15054   M (ONE_SHOW_XTR_MODE, mp);
15055
15056   /* send it... */
15057   S (mp);
15058
15059   /* Wait for a reply... */
15060   W (ret);
15061   return ret;
15062 }
15063
15064 static int
15065 api_one_enable_disable_pitr_mode (vat_main_t * vam)
15066 {
15067   unformat_input_t *input = vam->input;
15068   vl_api_one_enable_disable_pitr_mode_t *mp;
15069   u8 is_set = 0;
15070   u8 is_enable = 0;
15071   int ret;
15072
15073   /* Parse args required to build the message */
15074   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15075     {
15076       if (unformat (input, "enable"))
15077         {
15078           is_set = 1;
15079           is_enable = 1;
15080         }
15081       else if (unformat (input, "disable"))
15082         {
15083           is_set = 1;
15084         }
15085       else
15086         break;
15087     }
15088
15089   if (!is_set)
15090     {
15091       errmsg ("Value not set");
15092       return -99;
15093     }
15094
15095   /* Construct the API message */
15096   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
15097
15098   mp->is_enable = is_enable;
15099
15100   /* send it... */
15101   S (mp);
15102
15103   /* Wait for a reply... */
15104   W (ret);
15105   return ret;
15106 }
15107
15108 static int
15109 api_one_show_pitr_mode (vat_main_t * vam)
15110 {
15111   vl_api_one_show_pitr_mode_t *mp;
15112   int ret;
15113
15114   /* Construct the API message */
15115   M (ONE_SHOW_PITR_MODE, mp);
15116
15117   /* send it... */
15118   S (mp);
15119
15120   /* Wait for a reply... */
15121   W (ret);
15122   return ret;
15123 }
15124
15125 static int
15126 api_one_enable_disable_petr_mode (vat_main_t * vam)
15127 {
15128   unformat_input_t *input = vam->input;
15129   vl_api_one_enable_disable_petr_mode_t *mp;
15130   u8 is_set = 0;
15131   u8 is_enable = 0;
15132   int ret;
15133
15134   /* Parse args required to build the message */
15135   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15136     {
15137       if (unformat (input, "enable"))
15138         {
15139           is_set = 1;
15140           is_enable = 1;
15141         }
15142       else if (unformat (input, "disable"))
15143         {
15144           is_set = 1;
15145         }
15146       else
15147         break;
15148     }
15149
15150   if (!is_set)
15151     {
15152       errmsg ("Value not set");
15153       return -99;
15154     }
15155
15156   /* Construct the API message */
15157   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
15158
15159   mp->is_enable = is_enable;
15160
15161   /* send it... */
15162   S (mp);
15163
15164   /* Wait for a reply... */
15165   W (ret);
15166   return ret;
15167 }
15168
15169 static int
15170 api_one_show_petr_mode (vat_main_t * vam)
15171 {
15172   vl_api_one_show_petr_mode_t *mp;
15173   int ret;
15174
15175   /* Construct the API message */
15176   M (ONE_SHOW_PETR_MODE, mp);
15177
15178   /* send it... */
15179   S (mp);
15180
15181   /* Wait for a reply... */
15182   W (ret);
15183   return ret;
15184 }
15185
15186 static int
15187 api_show_one_map_register_state (vat_main_t * vam)
15188 {
15189   vl_api_show_one_map_register_state_t *mp;
15190   int ret;
15191
15192   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
15193
15194   /* send */
15195   S (mp);
15196
15197   /* wait for reply */
15198   W (ret);
15199   return ret;
15200 }
15201
15202 #define api_show_lisp_map_register_state api_show_one_map_register_state
15203
15204 static int
15205 api_show_one_rloc_probe_state (vat_main_t * vam)
15206 {
15207   vl_api_show_one_rloc_probe_state_t *mp;
15208   int ret;
15209
15210   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
15211
15212   /* send */
15213   S (mp);
15214
15215   /* wait for reply */
15216   W (ret);
15217   return ret;
15218 }
15219
15220 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
15221
15222 static int
15223 api_one_add_del_ndp_entry (vat_main_t * vam)
15224 {
15225   vl_api_one_add_del_ndp_entry_t *mp;
15226   unformat_input_t *input = vam->input;
15227   u8 is_add = 1;
15228   u8 mac_set = 0;
15229   u8 bd_set = 0;
15230   u8 ip_set = 0;
15231   u8 mac[6] = { 0, };
15232   u8 ip6[16] = { 0, };
15233   u32 bd = ~0;
15234   int ret;
15235
15236   /* Parse args required to build the message */
15237   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15238     {
15239       if (unformat (input, "del"))
15240         is_add = 0;
15241       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15242         mac_set = 1;
15243       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
15244         ip_set = 1;
15245       else if (unformat (input, "bd %d", &bd))
15246         bd_set = 1;
15247       else
15248         {
15249           errmsg ("parse error '%U'", format_unformat_error, input);
15250           return -99;
15251         }
15252     }
15253
15254   if (!bd_set || !ip_set || (!mac_set && is_add))
15255     {
15256       errmsg ("Missing BD, IP or MAC!");
15257       return -99;
15258     }
15259
15260   M (ONE_ADD_DEL_NDP_ENTRY, mp);
15261   mp->is_add = is_add;
15262   clib_memcpy (&mp->entry.mac, mac, 6);
15263   mp->bd = clib_host_to_net_u32 (bd);
15264   clib_memcpy (&mp->entry.ip6, ip6, sizeof (mp->entry.ip6));
15265
15266   /* send */
15267   S (mp);
15268
15269   /* wait for reply */
15270   W (ret);
15271   return ret;
15272 }
15273
15274 static int
15275 api_one_add_del_l2_arp_entry (vat_main_t * vam)
15276 {
15277   vl_api_one_add_del_l2_arp_entry_t *mp;
15278   unformat_input_t *input = vam->input;
15279   u8 is_add = 1;
15280   u8 mac_set = 0;
15281   u8 bd_set = 0;
15282   u8 ip_set = 0;
15283   u8 mac[6] = { 0, };
15284   u32 ip4 = 0, bd = ~0;
15285   int ret;
15286
15287   /* Parse args required to build the message */
15288   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15289     {
15290       if (unformat (input, "del"))
15291         is_add = 0;
15292       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15293         mac_set = 1;
15294       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
15295         ip_set = 1;
15296       else if (unformat (input, "bd %d", &bd))
15297         bd_set = 1;
15298       else
15299         {
15300           errmsg ("parse error '%U'", format_unformat_error, input);
15301           return -99;
15302         }
15303     }
15304
15305   if (!bd_set || !ip_set || (!mac_set && is_add))
15306     {
15307       errmsg ("Missing BD, IP or MAC!");
15308       return -99;
15309     }
15310
15311   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
15312   mp->is_add = is_add;
15313   clib_memcpy (&mp->entry.mac, mac, 6);
15314   mp->bd = clib_host_to_net_u32 (bd);
15315   clib_memcpy (mp->entry.ip4, &ip4, sizeof (mp->entry.ip4));
15316
15317   /* send */
15318   S (mp);
15319
15320   /* wait for reply */
15321   W (ret);
15322   return ret;
15323 }
15324
15325 static int
15326 api_one_ndp_bd_get (vat_main_t * vam)
15327 {
15328   vl_api_one_ndp_bd_get_t *mp;
15329   int ret;
15330
15331   M (ONE_NDP_BD_GET, mp);
15332
15333   /* send */
15334   S (mp);
15335
15336   /* wait for reply */
15337   W (ret);
15338   return ret;
15339 }
15340
15341 static int
15342 api_one_ndp_entries_get (vat_main_t * vam)
15343 {
15344   vl_api_one_ndp_entries_get_t *mp;
15345   unformat_input_t *input = vam->input;
15346   u8 bd_set = 0;
15347   u32 bd = ~0;
15348   int ret;
15349
15350   /* Parse args required to build the message */
15351   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15352     {
15353       if (unformat (input, "bd %d", &bd))
15354         bd_set = 1;
15355       else
15356         {
15357           errmsg ("parse error '%U'", format_unformat_error, input);
15358           return -99;
15359         }
15360     }
15361
15362   if (!bd_set)
15363     {
15364       errmsg ("Expected bridge domain!");
15365       return -99;
15366     }
15367
15368   M (ONE_NDP_ENTRIES_GET, mp);
15369   mp->bd = clib_host_to_net_u32 (bd);
15370
15371   /* send */
15372   S (mp);
15373
15374   /* wait for reply */
15375   W (ret);
15376   return ret;
15377 }
15378
15379 static int
15380 api_one_l2_arp_bd_get (vat_main_t * vam)
15381 {
15382   vl_api_one_l2_arp_bd_get_t *mp;
15383   int ret;
15384
15385   M (ONE_L2_ARP_BD_GET, mp);
15386
15387   /* send */
15388   S (mp);
15389
15390   /* wait for reply */
15391   W (ret);
15392   return ret;
15393 }
15394
15395 static int
15396 api_one_l2_arp_entries_get (vat_main_t * vam)
15397 {
15398   vl_api_one_l2_arp_entries_get_t *mp;
15399   unformat_input_t *input = vam->input;
15400   u8 bd_set = 0;
15401   u32 bd = ~0;
15402   int ret;
15403
15404   /* Parse args required to build the message */
15405   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15406     {
15407       if (unformat (input, "bd %d", &bd))
15408         bd_set = 1;
15409       else
15410         {
15411           errmsg ("parse error '%U'", format_unformat_error, input);
15412           return -99;
15413         }
15414     }
15415
15416   if (!bd_set)
15417     {
15418       errmsg ("Expected bridge domain!");
15419       return -99;
15420     }
15421
15422   M (ONE_L2_ARP_ENTRIES_GET, mp);
15423   mp->bd = clib_host_to_net_u32 (bd);
15424
15425   /* send */
15426   S (mp);
15427
15428   /* wait for reply */
15429   W (ret);
15430   return ret;
15431 }
15432
15433 static int
15434 api_one_stats_enable_disable (vat_main_t * vam)
15435 {
15436   vl_api_one_stats_enable_disable_t *mp;
15437   unformat_input_t *input = vam->input;
15438   u8 is_set = 0;
15439   u8 is_enable = 0;
15440   int ret;
15441
15442   /* Parse args required to build the message */
15443   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15444     {
15445       if (unformat (input, "enable"))
15446         {
15447           is_set = 1;
15448           is_enable = 1;
15449         }
15450       else if (unformat (input, "disable"))
15451         {
15452           is_set = 1;
15453         }
15454       else
15455         break;
15456     }
15457
15458   if (!is_set)
15459     {
15460       errmsg ("Value not set");
15461       return -99;
15462     }
15463
15464   M (ONE_STATS_ENABLE_DISABLE, mp);
15465   mp->is_enable = is_enable;
15466
15467   /* send */
15468   S (mp);
15469
15470   /* wait for reply */
15471   W (ret);
15472   return ret;
15473 }
15474
15475 static int
15476 api_show_one_stats_enable_disable (vat_main_t * vam)
15477 {
15478   vl_api_show_one_stats_enable_disable_t *mp;
15479   int ret;
15480
15481   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
15482
15483   /* send */
15484   S (mp);
15485
15486   /* wait for reply */
15487   W (ret);
15488   return ret;
15489 }
15490
15491 static int
15492 api_show_one_map_request_mode (vat_main_t * vam)
15493 {
15494   vl_api_show_one_map_request_mode_t *mp;
15495   int ret;
15496
15497   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
15498
15499   /* send */
15500   S (mp);
15501
15502   /* wait for reply */
15503   W (ret);
15504   return ret;
15505 }
15506
15507 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
15508
15509 static int
15510 api_one_map_request_mode (vat_main_t * vam)
15511 {
15512   unformat_input_t *input = vam->input;
15513   vl_api_one_map_request_mode_t *mp;
15514   u8 mode = 0;
15515   int ret;
15516
15517   /* Parse args required to build the message */
15518   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15519     {
15520       if (unformat (input, "dst-only"))
15521         mode = 0;
15522       else if (unformat (input, "src-dst"))
15523         mode = 1;
15524       else
15525         {
15526           errmsg ("parse error '%U'", format_unformat_error, input);
15527           return -99;
15528         }
15529     }
15530
15531   M (ONE_MAP_REQUEST_MODE, mp);
15532
15533   mp->mode = mode;
15534
15535   /* send */
15536   S (mp);
15537
15538   /* wait for reply */
15539   W (ret);
15540   return ret;
15541 }
15542
15543 #define api_lisp_map_request_mode api_one_map_request_mode
15544
15545 /**
15546  * Enable/disable ONE proxy ITR.
15547  *
15548  * @param vam vpp API test context
15549  * @return return code
15550  */
15551 static int
15552 api_one_pitr_set_locator_set (vat_main_t * vam)
15553 {
15554   u8 ls_name_set = 0;
15555   unformat_input_t *input = vam->input;
15556   vl_api_one_pitr_set_locator_set_t *mp;
15557   u8 is_add = 1;
15558   u8 *ls_name = 0;
15559   int ret;
15560
15561   /* Parse args required to build the message */
15562   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15563     {
15564       if (unformat (input, "del"))
15565         is_add = 0;
15566       else if (unformat (input, "locator-set %s", &ls_name))
15567         ls_name_set = 1;
15568       else
15569         {
15570           errmsg ("parse error '%U'", format_unformat_error, input);
15571           return -99;
15572         }
15573     }
15574
15575   if (!ls_name_set)
15576     {
15577       errmsg ("locator-set name not set!");
15578       return -99;
15579     }
15580
15581   M (ONE_PITR_SET_LOCATOR_SET, mp);
15582
15583   mp->is_add = is_add;
15584   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15585   vec_free (ls_name);
15586
15587   /* send */
15588   S (mp);
15589
15590   /* wait for reply */
15591   W (ret);
15592   return ret;
15593 }
15594
15595 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
15596
15597 static int
15598 api_one_nsh_set_locator_set (vat_main_t * vam)
15599 {
15600   u8 ls_name_set = 0;
15601   unformat_input_t *input = vam->input;
15602   vl_api_one_nsh_set_locator_set_t *mp;
15603   u8 is_add = 1;
15604   u8 *ls_name = 0;
15605   int ret;
15606
15607   /* Parse args required to build the message */
15608   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15609     {
15610       if (unformat (input, "del"))
15611         is_add = 0;
15612       else if (unformat (input, "ls %s", &ls_name))
15613         ls_name_set = 1;
15614       else
15615         {
15616           errmsg ("parse error '%U'", format_unformat_error, input);
15617           return -99;
15618         }
15619     }
15620
15621   if (!ls_name_set && is_add)
15622     {
15623       errmsg ("locator-set name not set!");
15624       return -99;
15625     }
15626
15627   M (ONE_NSH_SET_LOCATOR_SET, mp);
15628
15629   mp->is_add = is_add;
15630   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15631   vec_free (ls_name);
15632
15633   /* send */
15634   S (mp);
15635
15636   /* wait for reply */
15637   W (ret);
15638   return ret;
15639 }
15640
15641 static int
15642 api_show_one_pitr (vat_main_t * vam)
15643 {
15644   vl_api_show_one_pitr_t *mp;
15645   int ret;
15646
15647   if (!vam->json_output)
15648     {
15649       print (vam->ofp, "%=20s", "lisp status:");
15650     }
15651
15652   M (SHOW_ONE_PITR, mp);
15653   /* send it... */
15654   S (mp);
15655
15656   /* Wait for a reply... */
15657   W (ret);
15658   return ret;
15659 }
15660
15661 #define api_show_lisp_pitr api_show_one_pitr
15662
15663 static int
15664 api_one_use_petr (vat_main_t * vam)
15665 {
15666   unformat_input_t *input = vam->input;
15667   vl_api_one_use_petr_t *mp;
15668   u8 is_add = 0;
15669   ip_address_t ip;
15670   int ret;
15671
15672   clib_memset (&ip, 0, sizeof (ip));
15673
15674   /* Parse args required to build the message */
15675   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15676     {
15677       if (unformat (input, "disable"))
15678         is_add = 0;
15679       else
15680         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
15681         {
15682           is_add = 1;
15683           ip_addr_version (&ip) = AF_IP4;
15684         }
15685       else
15686         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
15687         {
15688           is_add = 1;
15689           ip_addr_version (&ip) = AF_IP6;
15690         }
15691       else
15692         {
15693           errmsg ("parse error '%U'", format_unformat_error, input);
15694           return -99;
15695         }
15696     }
15697
15698   M (ONE_USE_PETR, mp);
15699
15700   mp->is_add = is_add;
15701   if (is_add)
15702     {
15703       mp->ip_address.af = ip_addr_version (&ip) == AF_IP4 ? 0 : 1;
15704       if (mp->ip_address.af)
15705         clib_memcpy (mp->ip_address.un.ip6, &ip, 16);
15706       else
15707         clib_memcpy (mp->ip_address.un.ip4, &ip, 4);
15708     }
15709
15710   /* send */
15711   S (mp);
15712
15713   /* wait for reply */
15714   W (ret);
15715   return ret;
15716 }
15717
15718 #define api_lisp_use_petr api_one_use_petr
15719
15720 static int
15721 api_show_one_nsh_mapping (vat_main_t * vam)
15722 {
15723   vl_api_show_one_use_petr_t *mp;
15724   int ret;
15725
15726   if (!vam->json_output)
15727     {
15728       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
15729     }
15730
15731   M (SHOW_ONE_NSH_MAPPING, mp);
15732   /* send it... */
15733   S (mp);
15734
15735   /* Wait for a reply... */
15736   W (ret);
15737   return ret;
15738 }
15739
15740 static int
15741 api_show_one_use_petr (vat_main_t * vam)
15742 {
15743   vl_api_show_one_use_petr_t *mp;
15744   int ret;
15745
15746   if (!vam->json_output)
15747     {
15748       print (vam->ofp, "%=20s", "Proxy-ETR status:");
15749     }
15750
15751   M (SHOW_ONE_USE_PETR, mp);
15752   /* send it... */
15753   S (mp);
15754
15755   /* Wait for a reply... */
15756   W (ret);
15757   return ret;
15758 }
15759
15760 #define api_show_lisp_use_petr api_show_one_use_petr
15761
15762 /**
15763  * Add/delete mapping between vni and vrf
15764  */
15765 static int
15766 api_one_eid_table_add_del_map (vat_main_t * vam)
15767 {
15768   unformat_input_t *input = vam->input;
15769   vl_api_one_eid_table_add_del_map_t *mp;
15770   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
15771   u32 vni, vrf, bd_index;
15772   int ret;
15773
15774   /* Parse args required to build the message */
15775   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15776     {
15777       if (unformat (input, "del"))
15778         is_add = 0;
15779       else if (unformat (input, "vrf %d", &vrf))
15780         vrf_set = 1;
15781       else if (unformat (input, "bd_index %d", &bd_index))
15782         bd_index_set = 1;
15783       else if (unformat (input, "vni %d", &vni))
15784         vni_set = 1;
15785       else
15786         break;
15787     }
15788
15789   if (!vni_set || (!vrf_set && !bd_index_set))
15790     {
15791       errmsg ("missing arguments!");
15792       return -99;
15793     }
15794
15795   if (vrf_set && bd_index_set)
15796     {
15797       errmsg ("error: both vrf and bd entered!");
15798       return -99;
15799     }
15800
15801   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
15802
15803   mp->is_add = is_add;
15804   mp->vni = htonl (vni);
15805   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
15806   mp->is_l2 = bd_index_set;
15807
15808   /* send */
15809   S (mp);
15810
15811   /* wait for reply */
15812   W (ret);
15813   return ret;
15814 }
15815
15816 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
15817
15818 uword
15819 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
15820 {
15821   u32 *action = va_arg (*args, u32 *);
15822   u8 *s = 0;
15823
15824   if (unformat (input, "%s", &s))
15825     {
15826       if (!strcmp ((char *) s, "no-action"))
15827         action[0] = 0;
15828       else if (!strcmp ((char *) s, "natively-forward"))
15829         action[0] = 1;
15830       else if (!strcmp ((char *) s, "send-map-request"))
15831         action[0] = 2;
15832       else if (!strcmp ((char *) s, "drop"))
15833         action[0] = 3;
15834       else
15835         {
15836           clib_warning ("invalid action: '%s'", s);
15837           action[0] = 3;
15838         }
15839     }
15840   else
15841     return 0;
15842
15843   vec_free (s);
15844   return 1;
15845 }
15846
15847 /**
15848  * Add/del remote mapping to/from ONE control plane
15849  *
15850  * @param vam vpp API test context
15851  * @return return code
15852  */
15853 static int
15854 api_one_add_del_remote_mapping (vat_main_t * vam)
15855 {
15856   unformat_input_t *input = vam->input;
15857   vl_api_one_add_del_remote_mapping_t *mp;
15858   u32 vni = 0;
15859   lisp_eid_vat_t _eid, *eid = &_eid;
15860   lisp_eid_vat_t _seid, *seid = &_seid;
15861   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
15862   u32 action = ~0, p, w, data_len;
15863   ip4_address_t rloc4;
15864   ip6_address_t rloc6;
15865   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
15866   int ret;
15867
15868   clib_memset (&rloc, 0, sizeof (rloc));
15869
15870   /* Parse args required to build the message */
15871   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15872     {
15873       if (unformat (input, "del-all"))
15874         {
15875           del_all = 1;
15876         }
15877       else if (unformat (input, "del"))
15878         {
15879           is_add = 0;
15880         }
15881       else if (unformat (input, "add"))
15882         {
15883           is_add = 1;
15884         }
15885       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15886         {
15887           eid_set = 1;
15888         }
15889       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
15890         {
15891           seid_set = 1;
15892         }
15893       else if (unformat (input, "vni %d", &vni))
15894         {
15895           ;
15896         }
15897       else if (unformat (input, "p %d w %d", &p, &w))
15898         {
15899           if (!curr_rloc)
15900             {
15901               errmsg ("No RLOC configured for setting priority/weight!");
15902               return -99;
15903             }
15904           curr_rloc->priority = p;
15905           curr_rloc->weight = w;
15906         }
15907       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
15908         {
15909           rloc.ip_address.af = 0;
15910           clib_memcpy (&rloc.ip_address.un.ip6, &rloc6, sizeof (rloc6));
15911           vec_add1 (rlocs, rloc);
15912           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15913         }
15914       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
15915         {
15916           rloc.ip_address.af = 1;
15917           clib_memcpy (&rloc.ip_address.un.ip4, &rloc4, sizeof (rloc4));
15918           vec_add1 (rlocs, rloc);
15919           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15920         }
15921       else if (unformat (input, "action %U",
15922                          unformat_negative_mapping_action, &action))
15923         {
15924           ;
15925         }
15926       else
15927         {
15928           clib_warning ("parse error '%U'", format_unformat_error, input);
15929           return -99;
15930         }
15931     }
15932
15933   if (0 == eid_set)
15934     {
15935       errmsg ("missing params!");
15936       return -99;
15937     }
15938
15939   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
15940     {
15941       errmsg ("no action set for negative map-reply!");
15942       return -99;
15943     }
15944
15945   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
15946
15947   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
15948   mp->is_add = is_add;
15949   mp->vni = htonl (vni);
15950   mp->action = (u8) action;
15951   mp->is_src_dst = seid_set;
15952   mp->del_all = del_all;
15953   lisp_eid_put_vat (&mp->deid, eid);
15954   lisp_eid_put_vat (&mp->seid, seid);
15955
15956   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
15957   clib_memcpy (mp->rlocs, rlocs, data_len);
15958   vec_free (rlocs);
15959
15960   /* send it... */
15961   S (mp);
15962
15963   /* Wait for a reply... */
15964   W (ret);
15965   return ret;
15966 }
15967
15968 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
15969
15970 /**
15971  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
15972  * forwarding entries in data-plane accordingly.
15973  *
15974  * @param vam vpp API test context
15975  * @return return code
15976  */
15977 static int
15978 api_one_add_del_adjacency (vat_main_t * vam)
15979 {
15980   unformat_input_t *input = vam->input;
15981   vl_api_one_add_del_adjacency_t *mp;
15982   u32 vni = 0;
15983   u8 is_add = 1;
15984   int ret;
15985   lisp_eid_vat_t leid, reid;
15986
15987   leid.type = reid.type = (u8) ~ 0;
15988
15989   /* Parse args required to build the message */
15990   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15991     {
15992       if (unformat (input, "del"))
15993         {
15994           is_add = 0;
15995         }
15996       else if (unformat (input, "add"))
15997         {
15998           is_add = 1;
15999         }
16000       else if (unformat (input, "reid %U/%d", unformat_ip46_address,
16001                          &reid.addr.ip, &reid.len))
16002         {
16003           reid.type = 0;        /* ipv4 */
16004         }
16005       else if (unformat (input, "reid %U", unformat_ethernet_address,
16006                          &reid.addr.mac))
16007         {
16008           reid.type = 1;        /* mac */
16009         }
16010       else if (unformat (input, "leid %U/%d", unformat_ip46_address,
16011                          &leid.addr.ip, &leid.len))
16012         {
16013           leid.type = 0;        /* ipv4 */
16014         }
16015       else if (unformat (input, "leid %U", unformat_ethernet_address,
16016                          &leid.addr.mac))
16017         {
16018           leid.type = 1;        /* mac */
16019         }
16020       else if (unformat (input, "vni %d", &vni))
16021         {
16022           ;
16023         }
16024       else
16025         {
16026           errmsg ("parse error '%U'", format_unformat_error, input);
16027           return -99;
16028         }
16029     }
16030
16031   if ((u8) ~ 0 == reid.type)
16032     {
16033       errmsg ("missing params!");
16034       return -99;
16035     }
16036
16037   if (leid.type != reid.type)
16038     {
16039       errmsg ("remote and local EIDs are of different types!");
16040       return -99;
16041     }
16042
16043   M (ONE_ADD_DEL_ADJACENCY, mp);
16044   mp->is_add = is_add;
16045   mp->vni = htonl (vni);
16046   lisp_eid_put_vat (&mp->leid, &leid);
16047   lisp_eid_put_vat (&mp->reid, &reid);
16048
16049   /* send it... */
16050   S (mp);
16051
16052   /* Wait for a reply... */
16053   W (ret);
16054   return ret;
16055 }
16056
16057 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
16058
16059 uword
16060 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
16061 {
16062   u32 *mode = va_arg (*args, u32 *);
16063
16064   if (unformat (input, "lisp"))
16065     *mode = 0;
16066   else if (unformat (input, "vxlan"))
16067     *mode = 1;
16068   else
16069     return 0;
16070
16071   return 1;
16072 }
16073
16074 static int
16075 api_gpe_get_encap_mode (vat_main_t * vam)
16076 {
16077   vl_api_gpe_get_encap_mode_t *mp;
16078   int ret;
16079
16080   /* Construct the API message */
16081   M (GPE_GET_ENCAP_MODE, mp);
16082
16083   /* send it... */
16084   S (mp);
16085
16086   /* Wait for a reply... */
16087   W (ret);
16088   return ret;
16089 }
16090
16091 static int
16092 api_gpe_set_encap_mode (vat_main_t * vam)
16093 {
16094   unformat_input_t *input = vam->input;
16095   vl_api_gpe_set_encap_mode_t *mp;
16096   int ret;
16097   u32 mode = 0;
16098
16099   /* Parse args required to build the message */
16100   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16101     {
16102       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
16103         ;
16104       else
16105         break;
16106     }
16107
16108   /* Construct the API message */
16109   M (GPE_SET_ENCAP_MODE, mp);
16110
16111   mp->is_vxlan = mode;
16112
16113   /* send it... */
16114   S (mp);
16115
16116   /* Wait for a reply... */
16117   W (ret);
16118   return ret;
16119 }
16120
16121 static int
16122 api_lisp_gpe_add_del_iface (vat_main_t * vam)
16123 {
16124   unformat_input_t *input = vam->input;
16125   vl_api_gpe_add_del_iface_t *mp;
16126   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
16127   u32 dp_table = 0, vni = 0;
16128   int ret;
16129
16130   /* Parse args required to build the message */
16131   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16132     {
16133       if (unformat (input, "up"))
16134         {
16135           action_set = 1;
16136           is_add = 1;
16137         }
16138       else if (unformat (input, "down"))
16139         {
16140           action_set = 1;
16141           is_add = 0;
16142         }
16143       else if (unformat (input, "table_id %d", &dp_table))
16144         {
16145           dp_table_set = 1;
16146         }
16147       else if (unformat (input, "bd_id %d", &dp_table))
16148         {
16149           dp_table_set = 1;
16150           is_l2 = 1;
16151         }
16152       else if (unformat (input, "vni %d", &vni))
16153         {
16154           vni_set = 1;
16155         }
16156       else
16157         break;
16158     }
16159
16160   if (action_set == 0)
16161     {
16162       errmsg ("Action not set");
16163       return -99;
16164     }
16165   if (dp_table_set == 0 || vni_set == 0)
16166     {
16167       errmsg ("vni and dp_table must be set");
16168       return -99;
16169     }
16170
16171   /* Construct the API message */
16172   M (GPE_ADD_DEL_IFACE, mp);
16173
16174   mp->is_add = is_add;
16175   mp->dp_table = clib_host_to_net_u32 (dp_table);
16176   mp->is_l2 = is_l2;
16177   mp->vni = clib_host_to_net_u32 (vni);
16178
16179   /* send it... */
16180   S (mp);
16181
16182   /* Wait for a reply... */
16183   W (ret);
16184   return ret;
16185 }
16186
16187 static int
16188 api_one_map_register_fallback_threshold (vat_main_t * vam)
16189 {
16190   unformat_input_t *input = vam->input;
16191   vl_api_one_map_register_fallback_threshold_t *mp;
16192   u32 value = 0;
16193   u8 is_set = 0;
16194   int ret;
16195
16196   /* Parse args required to build the message */
16197   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16198     {
16199       if (unformat (input, "%u", &value))
16200         is_set = 1;
16201       else
16202         {
16203           clib_warning ("parse error '%U'", format_unformat_error, input);
16204           return -99;
16205         }
16206     }
16207
16208   if (!is_set)
16209     {
16210       errmsg ("fallback threshold value is missing!");
16211       return -99;
16212     }
16213
16214   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16215   mp->value = clib_host_to_net_u32 (value);
16216
16217   /* send it... */
16218   S (mp);
16219
16220   /* Wait for a reply... */
16221   W (ret);
16222   return ret;
16223 }
16224
16225 static int
16226 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
16227 {
16228   vl_api_show_one_map_register_fallback_threshold_t *mp;
16229   int ret;
16230
16231   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16232
16233   /* send it... */
16234   S (mp);
16235
16236   /* Wait for a reply... */
16237   W (ret);
16238   return ret;
16239 }
16240
16241 uword
16242 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
16243 {
16244   u32 *proto = va_arg (*args, u32 *);
16245
16246   if (unformat (input, "udp"))
16247     *proto = 1;
16248   else if (unformat (input, "api"))
16249     *proto = 2;
16250   else
16251     return 0;
16252
16253   return 1;
16254 }
16255
16256 static int
16257 api_one_set_transport_protocol (vat_main_t * vam)
16258 {
16259   unformat_input_t *input = vam->input;
16260   vl_api_one_set_transport_protocol_t *mp;
16261   u8 is_set = 0;
16262   u32 protocol = 0;
16263   int ret;
16264
16265   /* Parse args required to build the message */
16266   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16267     {
16268       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
16269         is_set = 1;
16270       else
16271         {
16272           clib_warning ("parse error '%U'", format_unformat_error, input);
16273           return -99;
16274         }
16275     }
16276
16277   if (!is_set)
16278     {
16279       errmsg ("Transport protocol missing!");
16280       return -99;
16281     }
16282
16283   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
16284   mp->protocol = (u8) protocol;
16285
16286   /* send it... */
16287   S (mp);
16288
16289   /* Wait for a reply... */
16290   W (ret);
16291   return ret;
16292 }
16293
16294 static int
16295 api_one_get_transport_protocol (vat_main_t * vam)
16296 {
16297   vl_api_one_get_transport_protocol_t *mp;
16298   int ret;
16299
16300   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
16301
16302   /* send it... */
16303   S (mp);
16304
16305   /* Wait for a reply... */
16306   W (ret);
16307   return ret;
16308 }
16309
16310 static int
16311 api_one_map_register_set_ttl (vat_main_t * vam)
16312 {
16313   unformat_input_t *input = vam->input;
16314   vl_api_one_map_register_set_ttl_t *mp;
16315   u32 ttl = 0;
16316   u8 is_set = 0;
16317   int ret;
16318
16319   /* Parse args required to build the message */
16320   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16321     {
16322       if (unformat (input, "%u", &ttl))
16323         is_set = 1;
16324       else
16325         {
16326           clib_warning ("parse error '%U'", format_unformat_error, input);
16327           return -99;
16328         }
16329     }
16330
16331   if (!is_set)
16332     {
16333       errmsg ("TTL value missing!");
16334       return -99;
16335     }
16336
16337   M (ONE_MAP_REGISTER_SET_TTL, mp);
16338   mp->ttl = clib_host_to_net_u32 (ttl);
16339
16340   /* send it... */
16341   S (mp);
16342
16343   /* Wait for a reply... */
16344   W (ret);
16345   return ret;
16346 }
16347
16348 static int
16349 api_show_one_map_register_ttl (vat_main_t * vam)
16350 {
16351   vl_api_show_one_map_register_ttl_t *mp;
16352   int ret;
16353
16354   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
16355
16356   /* send it... */
16357   S (mp);
16358
16359   /* Wait for a reply... */
16360   W (ret);
16361   return ret;
16362 }
16363
16364 /**
16365  * Add/del map request itr rlocs from ONE control plane and updates
16366  *
16367  * @param vam vpp API test context
16368  * @return return code
16369  */
16370 static int
16371 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
16372 {
16373   unformat_input_t *input = vam->input;
16374   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
16375   u8 *locator_set_name = 0;
16376   u8 locator_set_name_set = 0;
16377   u8 is_add = 1;
16378   int ret;
16379
16380   /* Parse args required to build the message */
16381   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16382     {
16383       if (unformat (input, "del"))
16384         {
16385           is_add = 0;
16386         }
16387       else if (unformat (input, "%_%v%_", &locator_set_name))
16388         {
16389           locator_set_name_set = 1;
16390         }
16391       else
16392         {
16393           clib_warning ("parse error '%U'", format_unformat_error, input);
16394           return -99;
16395         }
16396     }
16397
16398   if (is_add && !locator_set_name_set)
16399     {
16400       errmsg ("itr-rloc is not set!");
16401       return -99;
16402     }
16403
16404   if (is_add && vec_len (locator_set_name) > 64)
16405     {
16406       errmsg ("itr-rloc locator-set name too long");
16407       vec_free (locator_set_name);
16408       return -99;
16409     }
16410
16411   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
16412   mp->is_add = is_add;
16413   if (is_add)
16414     {
16415       clib_memcpy (mp->locator_set_name, locator_set_name,
16416                    vec_len (locator_set_name));
16417     }
16418   else
16419     {
16420       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
16421     }
16422   vec_free (locator_set_name);
16423
16424   /* send it... */
16425   S (mp);
16426
16427   /* Wait for a reply... */
16428   W (ret);
16429   return ret;
16430 }
16431
16432 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
16433
16434 static int
16435 api_one_locator_dump (vat_main_t * vam)
16436 {
16437   unformat_input_t *input = vam->input;
16438   vl_api_one_locator_dump_t *mp;
16439   vl_api_control_ping_t *mp_ping;
16440   u8 is_index_set = 0, is_name_set = 0;
16441   u8 *ls_name = 0;
16442   u32 ls_index = ~0;
16443   int ret;
16444
16445   /* Parse args required to build the message */
16446   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16447     {
16448       if (unformat (input, "ls_name %_%v%_", &ls_name))
16449         {
16450           is_name_set = 1;
16451         }
16452       else if (unformat (input, "ls_index %d", &ls_index))
16453         {
16454           is_index_set = 1;
16455         }
16456       else
16457         {
16458           errmsg ("parse error '%U'", format_unformat_error, input);
16459           return -99;
16460         }
16461     }
16462
16463   if (!is_index_set && !is_name_set)
16464     {
16465       errmsg ("error: expected one of index or name!");
16466       return -99;
16467     }
16468
16469   if (is_index_set && is_name_set)
16470     {
16471       errmsg ("error: only one param expected!");
16472       return -99;
16473     }
16474
16475   if (vec_len (ls_name) > 62)
16476     {
16477       errmsg ("error: locator set name too long!");
16478       return -99;
16479     }
16480
16481   if (!vam->json_output)
16482     {
16483       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
16484     }
16485
16486   M (ONE_LOCATOR_DUMP, mp);
16487   mp->is_index_set = is_index_set;
16488
16489   if (is_index_set)
16490     mp->ls_index = clib_host_to_net_u32 (ls_index);
16491   else
16492     {
16493       vec_add1 (ls_name, 0);
16494       strncpy ((char *) mp->ls_name, (char *) ls_name,
16495                sizeof (mp->ls_name) - 1);
16496     }
16497
16498   /* send it... */
16499   S (mp);
16500
16501   /* Use a control ping for synchronization */
16502   MPING (CONTROL_PING, mp_ping);
16503   S (mp_ping);
16504
16505   /* Wait for a reply... */
16506   W (ret);
16507   return ret;
16508 }
16509
16510 #define api_lisp_locator_dump api_one_locator_dump
16511
16512 static int
16513 api_one_locator_set_dump (vat_main_t * vam)
16514 {
16515   vl_api_one_locator_set_dump_t *mp;
16516   vl_api_control_ping_t *mp_ping;
16517   unformat_input_t *input = vam->input;
16518   u8 filter = 0;
16519   int ret;
16520
16521   /* Parse args required to build the message */
16522   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16523     {
16524       if (unformat (input, "local"))
16525         {
16526           filter = 1;
16527         }
16528       else if (unformat (input, "remote"))
16529         {
16530           filter = 2;
16531         }
16532       else
16533         {
16534           errmsg ("parse error '%U'", format_unformat_error, input);
16535           return -99;
16536         }
16537     }
16538
16539   if (!vam->json_output)
16540     {
16541       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
16542     }
16543
16544   M (ONE_LOCATOR_SET_DUMP, mp);
16545
16546   mp->filter = filter;
16547
16548   /* send it... */
16549   S (mp);
16550
16551   /* Use a control ping for synchronization */
16552   MPING (CONTROL_PING, mp_ping);
16553   S (mp_ping);
16554
16555   /* Wait for a reply... */
16556   W (ret);
16557   return ret;
16558 }
16559
16560 #define api_lisp_locator_set_dump api_one_locator_set_dump
16561
16562 static int
16563 api_one_eid_table_map_dump (vat_main_t * vam)
16564 {
16565   u8 is_l2 = 0;
16566   u8 mode_set = 0;
16567   unformat_input_t *input = vam->input;
16568   vl_api_one_eid_table_map_dump_t *mp;
16569   vl_api_control_ping_t *mp_ping;
16570   int ret;
16571
16572   /* Parse args required to build the message */
16573   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16574     {
16575       if (unformat (input, "l2"))
16576         {
16577           is_l2 = 1;
16578           mode_set = 1;
16579         }
16580       else if (unformat (input, "l3"))
16581         {
16582           is_l2 = 0;
16583           mode_set = 1;
16584         }
16585       else
16586         {
16587           errmsg ("parse error '%U'", format_unformat_error, input);
16588           return -99;
16589         }
16590     }
16591
16592   if (!mode_set)
16593     {
16594       errmsg ("expected one of 'l2' or 'l3' parameter!");
16595       return -99;
16596     }
16597
16598   if (!vam->json_output)
16599     {
16600       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
16601     }
16602
16603   M (ONE_EID_TABLE_MAP_DUMP, mp);
16604   mp->is_l2 = is_l2;
16605
16606   /* send it... */
16607   S (mp);
16608
16609   /* Use a control ping for synchronization */
16610   MPING (CONTROL_PING, mp_ping);
16611   S (mp_ping);
16612
16613   /* Wait for a reply... */
16614   W (ret);
16615   return ret;
16616 }
16617
16618 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
16619
16620 static int
16621 api_one_eid_table_vni_dump (vat_main_t * vam)
16622 {
16623   vl_api_one_eid_table_vni_dump_t *mp;
16624   vl_api_control_ping_t *mp_ping;
16625   int ret;
16626
16627   if (!vam->json_output)
16628     {
16629       print (vam->ofp, "VNI");
16630     }
16631
16632   M (ONE_EID_TABLE_VNI_DUMP, mp);
16633
16634   /* send it... */
16635   S (mp);
16636
16637   /* Use a control ping for synchronization */
16638   MPING (CONTROL_PING, mp_ping);
16639   S (mp_ping);
16640
16641   /* Wait for a reply... */
16642   W (ret);
16643   return ret;
16644 }
16645
16646 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
16647
16648 static int
16649 api_one_eid_table_dump (vat_main_t * vam)
16650 {
16651   unformat_input_t *i = vam->input;
16652   vl_api_one_eid_table_dump_t *mp;
16653   vl_api_control_ping_t *mp_ping;
16654   u8 filter = 0;
16655   int ret;
16656   u32 vni, t = 0;
16657   lisp_eid_vat_t eid;
16658   u8 eid_set = 0;
16659
16660   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16661     {
16662       if (unformat
16663           (i, "eid %U/%d", unformat_ip46_address, &eid.addr.ip, &eid.len))
16664         {
16665           eid_set = 1;
16666           eid.type = 0;
16667         }
16668       else
16669         if (unformat (i, "eid %U", unformat_ethernet_address, &eid.addr.mac))
16670         {
16671           eid_set = 1;
16672           eid.type = 1;
16673         }
16674       else if (unformat (i, "eid %U", unformat_nsh_address, &eid.addr.nsh))
16675         {
16676           eid_set = 1;
16677           eid.type = 2;
16678         }
16679       else if (unformat (i, "vni %d", &t))
16680         {
16681           vni = t;
16682         }
16683       else if (unformat (i, "local"))
16684         {
16685           filter = 1;
16686         }
16687       else if (unformat (i, "remote"))
16688         {
16689           filter = 2;
16690         }
16691       else
16692         {
16693           errmsg ("parse error '%U'", format_unformat_error, i);
16694           return -99;
16695         }
16696     }
16697
16698   if (!vam->json_output)
16699     {
16700       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
16701              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
16702     }
16703
16704   M (ONE_EID_TABLE_DUMP, mp);
16705
16706   mp->filter = filter;
16707   if (eid_set)
16708     {
16709       mp->eid_set = 1;
16710       mp->vni = htonl (vni);
16711       lisp_eid_put_vat (&mp->eid, &eid);
16712     }
16713
16714   /* send it... */
16715   S (mp);
16716
16717   /* Use a control ping for synchronization */
16718   MPING (CONTROL_PING, mp_ping);
16719   S (mp_ping);
16720
16721   /* Wait for a reply... */
16722   W (ret);
16723   return ret;
16724 }
16725
16726 #define api_lisp_eid_table_dump api_one_eid_table_dump
16727
16728 static int
16729 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
16730 {
16731   unformat_input_t *i = vam->input;
16732   vl_api_gpe_fwd_entries_get_t *mp;
16733   u8 vni_set = 0;
16734   u32 vni = ~0;
16735   int ret;
16736
16737   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16738     {
16739       if (unformat (i, "vni %d", &vni))
16740         {
16741           vni_set = 1;
16742         }
16743       else
16744         {
16745           errmsg ("parse error '%U'", format_unformat_error, i);
16746           return -99;
16747         }
16748     }
16749
16750   if (!vni_set)
16751     {
16752       errmsg ("vni not set!");
16753       return -99;
16754     }
16755
16756   if (!vam->json_output)
16757     {
16758       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
16759              "leid", "reid");
16760     }
16761
16762   M (GPE_FWD_ENTRIES_GET, mp);
16763   mp->vni = clib_host_to_net_u32 (vni);
16764
16765   /* send it... */
16766   S (mp);
16767
16768   /* Wait for a reply... */
16769   W (ret);
16770   return ret;
16771 }
16772
16773 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
16774 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
16775 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
16776 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
16777 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
16778 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
16779 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
16780 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
16781
16782 static int
16783 api_one_adjacencies_get (vat_main_t * vam)
16784 {
16785   unformat_input_t *i = vam->input;
16786   vl_api_one_adjacencies_get_t *mp;
16787   u8 vni_set = 0;
16788   u32 vni = ~0;
16789   int ret;
16790
16791   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16792     {
16793       if (unformat (i, "vni %d", &vni))
16794         {
16795           vni_set = 1;
16796         }
16797       else
16798         {
16799           errmsg ("parse error '%U'", format_unformat_error, i);
16800           return -99;
16801         }
16802     }
16803
16804   if (!vni_set)
16805     {
16806       errmsg ("vni not set!");
16807       return -99;
16808     }
16809
16810   if (!vam->json_output)
16811     {
16812       print (vam->ofp, "%s %40s", "leid", "reid");
16813     }
16814
16815   M (ONE_ADJACENCIES_GET, mp);
16816   mp->vni = clib_host_to_net_u32 (vni);
16817
16818   /* send it... */
16819   S (mp);
16820
16821   /* Wait for a reply... */
16822   W (ret);
16823   return ret;
16824 }
16825
16826 #define api_lisp_adjacencies_get api_one_adjacencies_get
16827
16828 static int
16829 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
16830 {
16831   unformat_input_t *i = vam->input;
16832   vl_api_gpe_native_fwd_rpaths_get_t *mp;
16833   int ret;
16834   u8 ip_family_set = 0, is_ip4 = 1;
16835
16836   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16837     {
16838       if (unformat (i, "ip4"))
16839         {
16840           ip_family_set = 1;
16841           is_ip4 = 1;
16842         }
16843       else if (unformat (i, "ip6"))
16844         {
16845           ip_family_set = 1;
16846           is_ip4 = 0;
16847         }
16848       else
16849         {
16850           errmsg ("parse error '%U'", format_unformat_error, i);
16851           return -99;
16852         }
16853     }
16854
16855   if (!ip_family_set)
16856     {
16857       errmsg ("ip family not set!");
16858       return -99;
16859     }
16860
16861   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
16862   mp->is_ip4 = is_ip4;
16863
16864   /* send it... */
16865   S (mp);
16866
16867   /* Wait for a reply... */
16868   W (ret);
16869   return ret;
16870 }
16871
16872 static int
16873 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
16874 {
16875   vl_api_gpe_fwd_entry_vnis_get_t *mp;
16876   int ret;
16877
16878   if (!vam->json_output)
16879     {
16880       print (vam->ofp, "VNIs");
16881     }
16882
16883   M (GPE_FWD_ENTRY_VNIS_GET, mp);
16884
16885   /* send it... */
16886   S (mp);
16887
16888   /* Wait for a reply... */
16889   W (ret);
16890   return ret;
16891 }
16892
16893 static int
16894 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
16895 {
16896   unformat_input_t *i = vam->input;
16897   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
16898   int ret = 0;
16899   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
16900   struct in_addr ip4;
16901   struct in6_addr ip6;
16902   u32 table_id = 0, nh_sw_if_index = ~0;
16903
16904   clib_memset (&ip4, 0, sizeof (ip4));
16905   clib_memset (&ip6, 0, sizeof (ip6));
16906
16907   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16908     {
16909       if (unformat (i, "del"))
16910         is_add = 0;
16911       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
16912                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16913         {
16914           ip_set = 1;
16915           is_ip4 = 1;
16916         }
16917       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
16918                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16919         {
16920           ip_set = 1;
16921           is_ip4 = 0;
16922         }
16923       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
16924         {
16925           ip_set = 1;
16926           is_ip4 = 1;
16927           nh_sw_if_index = ~0;
16928         }
16929       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
16930         {
16931           ip_set = 1;
16932           is_ip4 = 0;
16933           nh_sw_if_index = ~0;
16934         }
16935       else if (unformat (i, "table %d", &table_id))
16936         ;
16937       else
16938         {
16939           errmsg ("parse error '%U'", format_unformat_error, i);
16940           return -99;
16941         }
16942     }
16943
16944   if (!ip_set)
16945     {
16946       errmsg ("nh addr not set!");
16947       return -99;
16948     }
16949
16950   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
16951   mp->is_add = is_add;
16952   mp->table_id = clib_host_to_net_u32 (table_id);
16953   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
16954   mp->nh_addr.af = is_ip4 ? 0 : 1;
16955   if (is_ip4)
16956     clib_memcpy (mp->nh_addr.un.ip4, &ip4, sizeof (ip4));
16957   else
16958     clib_memcpy (mp->nh_addr.un.ip6, &ip6, sizeof (ip6));
16959
16960   /* send it... */
16961   S (mp);
16962
16963   /* Wait for a reply... */
16964   W (ret);
16965   return ret;
16966 }
16967
16968 static int
16969 api_one_map_server_dump (vat_main_t * vam)
16970 {
16971   vl_api_one_map_server_dump_t *mp;
16972   vl_api_control_ping_t *mp_ping;
16973   int ret;
16974
16975   if (!vam->json_output)
16976     {
16977       print (vam->ofp, "%=20s", "Map server");
16978     }
16979
16980   M (ONE_MAP_SERVER_DUMP, mp);
16981   /* send it... */
16982   S (mp);
16983
16984   /* Use a control ping for synchronization */
16985   MPING (CONTROL_PING, mp_ping);
16986   S (mp_ping);
16987
16988   /* Wait for a reply... */
16989   W (ret);
16990   return ret;
16991 }
16992
16993 #define api_lisp_map_server_dump api_one_map_server_dump
16994
16995 static int
16996 api_one_map_resolver_dump (vat_main_t * vam)
16997 {
16998   vl_api_one_map_resolver_dump_t *mp;
16999   vl_api_control_ping_t *mp_ping;
17000   int ret;
17001
17002   if (!vam->json_output)
17003     {
17004       print (vam->ofp, "%=20s", "Map resolver");
17005     }
17006
17007   M (ONE_MAP_RESOLVER_DUMP, mp);
17008   /* send it... */
17009   S (mp);
17010
17011   /* Use a control ping for synchronization */
17012   MPING (CONTROL_PING, mp_ping);
17013   S (mp_ping);
17014
17015   /* Wait for a reply... */
17016   W (ret);
17017   return ret;
17018 }
17019
17020 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
17021
17022 static int
17023 api_one_stats_flush (vat_main_t * vam)
17024 {
17025   vl_api_one_stats_flush_t *mp;
17026   int ret = 0;
17027
17028   M (ONE_STATS_FLUSH, mp);
17029   S (mp);
17030   W (ret);
17031   return ret;
17032 }
17033
17034 static int
17035 api_one_stats_dump (vat_main_t * vam)
17036 {
17037   vl_api_one_stats_dump_t *mp;
17038   vl_api_control_ping_t *mp_ping;
17039   int ret;
17040
17041   M (ONE_STATS_DUMP, mp);
17042   /* send it... */
17043   S (mp);
17044
17045   /* Use a control ping for synchronization */
17046   MPING (CONTROL_PING, mp_ping);
17047   S (mp_ping);
17048
17049   /* Wait for a reply... */
17050   W (ret);
17051   return ret;
17052 }
17053
17054 static int
17055 api_show_one_status (vat_main_t * vam)
17056 {
17057   vl_api_show_one_status_t *mp;
17058   int ret;
17059
17060   if (!vam->json_output)
17061     {
17062       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
17063     }
17064
17065   M (SHOW_ONE_STATUS, mp);
17066   /* send it... */
17067   S (mp);
17068   /* Wait for a reply... */
17069   W (ret);
17070   return ret;
17071 }
17072
17073 #define api_show_lisp_status api_show_one_status
17074
17075 static int
17076 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
17077 {
17078   vl_api_gpe_fwd_entry_path_dump_t *mp;
17079   vl_api_control_ping_t *mp_ping;
17080   unformat_input_t *i = vam->input;
17081   u32 fwd_entry_index = ~0;
17082   int ret;
17083
17084   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17085     {
17086       if (unformat (i, "index %d", &fwd_entry_index))
17087         ;
17088       else
17089         break;
17090     }
17091
17092   if (~0 == fwd_entry_index)
17093     {
17094       errmsg ("no index specified!");
17095       return -99;
17096     }
17097
17098   if (!vam->json_output)
17099     {
17100       print (vam->ofp, "first line");
17101     }
17102
17103   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
17104
17105   /* send it... */
17106   S (mp);
17107   /* Use a control ping for synchronization */
17108   MPING (CONTROL_PING, mp_ping);
17109   S (mp_ping);
17110
17111   /* Wait for a reply... */
17112   W (ret);
17113   return ret;
17114 }
17115
17116 static int
17117 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
17118 {
17119   vl_api_one_get_map_request_itr_rlocs_t *mp;
17120   int ret;
17121
17122   if (!vam->json_output)
17123     {
17124       print (vam->ofp, "%=20s", "itr-rlocs:");
17125     }
17126
17127   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
17128   /* send it... */
17129   S (mp);
17130   /* Wait for a reply... */
17131   W (ret);
17132   return ret;
17133 }
17134
17135 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
17136
17137 static int
17138 api_af_packet_create (vat_main_t * vam)
17139 {
17140   unformat_input_t *i = vam->input;
17141   vl_api_af_packet_create_t *mp;
17142   u8 *host_if_name = 0;
17143   u8 hw_addr[6];
17144   u8 random_hw_addr = 1;
17145   int ret;
17146
17147   clib_memset (hw_addr, 0, sizeof (hw_addr));
17148
17149   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17150     {
17151       if (unformat (i, "name %s", &host_if_name))
17152         vec_add1 (host_if_name, 0);
17153       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17154         random_hw_addr = 0;
17155       else
17156         break;
17157     }
17158
17159   if (!vec_len (host_if_name))
17160     {
17161       errmsg ("host-interface name must be specified");
17162       return -99;
17163     }
17164
17165   if (vec_len (host_if_name) > 64)
17166     {
17167       errmsg ("host-interface name too long");
17168       return -99;
17169     }
17170
17171   M (AF_PACKET_CREATE, mp);
17172
17173   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17174   clib_memcpy (mp->hw_addr, hw_addr, 6);
17175   mp->use_random_hw_addr = random_hw_addr;
17176   vec_free (host_if_name);
17177
17178   S (mp);
17179
17180   /* *INDENT-OFF* */
17181   W2 (ret,
17182       ({
17183         if (ret == 0)
17184           fprintf (vam->ofp ? vam->ofp : stderr,
17185                    " new sw_if_index = %d\n", vam->sw_if_index);
17186       }));
17187   /* *INDENT-ON* */
17188   return ret;
17189 }
17190
17191 static int
17192 api_af_packet_delete (vat_main_t * vam)
17193 {
17194   unformat_input_t *i = vam->input;
17195   vl_api_af_packet_delete_t *mp;
17196   u8 *host_if_name = 0;
17197   int ret;
17198
17199   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17200     {
17201       if (unformat (i, "name %s", &host_if_name))
17202         vec_add1 (host_if_name, 0);
17203       else
17204         break;
17205     }
17206
17207   if (!vec_len (host_if_name))
17208     {
17209       errmsg ("host-interface name must be specified");
17210       return -99;
17211     }
17212
17213   if (vec_len (host_if_name) > 64)
17214     {
17215       errmsg ("host-interface name too long");
17216       return -99;
17217     }
17218
17219   M (AF_PACKET_DELETE, mp);
17220
17221   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17222   vec_free (host_if_name);
17223
17224   S (mp);
17225   W (ret);
17226   return ret;
17227 }
17228
17229 static void vl_api_af_packet_details_t_handler
17230   (vl_api_af_packet_details_t * mp)
17231 {
17232   vat_main_t *vam = &vat_main;
17233
17234   print (vam->ofp, "%-16s %d",
17235          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
17236 }
17237
17238 static void vl_api_af_packet_details_t_handler_json
17239   (vl_api_af_packet_details_t * mp)
17240 {
17241   vat_main_t *vam = &vat_main;
17242   vat_json_node_t *node = NULL;
17243
17244   if (VAT_JSON_ARRAY != vam->json_tree.type)
17245     {
17246       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17247       vat_json_init_array (&vam->json_tree);
17248     }
17249   node = vat_json_array_add (&vam->json_tree);
17250
17251   vat_json_init_object (node);
17252   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17253   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
17254 }
17255
17256 static int
17257 api_af_packet_dump (vat_main_t * vam)
17258 {
17259   vl_api_af_packet_dump_t *mp;
17260   vl_api_control_ping_t *mp_ping;
17261   int ret;
17262
17263   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
17264   /* Get list of tap interfaces */
17265   M (AF_PACKET_DUMP, mp);
17266   S (mp);
17267
17268   /* Use a control ping for synchronization */
17269   MPING (CONTROL_PING, mp_ping);
17270   S (mp_ping);
17271
17272   W (ret);
17273   return ret;
17274 }
17275
17276 static int
17277 api_policer_add_del (vat_main_t * vam)
17278 {
17279   unformat_input_t *i = vam->input;
17280   vl_api_policer_add_del_t *mp;
17281   u8 is_add = 1;
17282   u8 *name = 0;
17283   u32 cir = 0;
17284   u32 eir = 0;
17285   u64 cb = 0;
17286   u64 eb = 0;
17287   u8 rate_type = 0;
17288   u8 round_type = 0;
17289   u8 type = 0;
17290   u8 color_aware = 0;
17291   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
17292   int ret;
17293
17294   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
17295   conform_action.dscp = 0;
17296   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
17297   exceed_action.dscp = 0;
17298   violate_action.action_type = SSE2_QOS_ACTION_DROP;
17299   violate_action.dscp = 0;
17300
17301   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17302     {
17303       if (unformat (i, "del"))
17304         is_add = 0;
17305       else if (unformat (i, "name %s", &name))
17306         vec_add1 (name, 0);
17307       else if (unformat (i, "cir %u", &cir))
17308         ;
17309       else if (unformat (i, "eir %u", &eir))
17310         ;
17311       else if (unformat (i, "cb %u", &cb))
17312         ;
17313       else if (unformat (i, "eb %u", &eb))
17314         ;
17315       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
17316                          &rate_type))
17317         ;
17318       else if (unformat (i, "round_type %U", unformat_policer_round_type,
17319                          &round_type))
17320         ;
17321       else if (unformat (i, "type %U", unformat_policer_type, &type))
17322         ;
17323       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
17324                          &conform_action))
17325         ;
17326       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
17327                          &exceed_action))
17328         ;
17329       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
17330                          &violate_action))
17331         ;
17332       else if (unformat (i, "color-aware"))
17333         color_aware = 1;
17334       else
17335         break;
17336     }
17337
17338   if (!vec_len (name))
17339     {
17340       errmsg ("policer name must be specified");
17341       return -99;
17342     }
17343
17344   if (vec_len (name) > 64)
17345     {
17346       errmsg ("policer name too long");
17347       return -99;
17348     }
17349
17350   M (POLICER_ADD_DEL, mp);
17351
17352   clib_memcpy (mp->name, name, vec_len (name));
17353   vec_free (name);
17354   mp->is_add = is_add;
17355   mp->cir = ntohl (cir);
17356   mp->eir = ntohl (eir);
17357   mp->cb = clib_net_to_host_u64 (cb);
17358   mp->eb = clib_net_to_host_u64 (eb);
17359   mp->rate_type = rate_type;
17360   mp->round_type = round_type;
17361   mp->type = type;
17362   mp->conform_action.type = conform_action.action_type;
17363   mp->conform_action.dscp = conform_action.dscp;
17364   mp->exceed_action.type = exceed_action.action_type;
17365   mp->exceed_action.dscp = exceed_action.dscp;
17366   mp->violate_action.type = violate_action.action_type;
17367   mp->violate_action.dscp = violate_action.dscp;
17368   mp->color_aware = color_aware;
17369
17370   S (mp);
17371   W (ret);
17372   return ret;
17373 }
17374
17375 static int
17376 api_policer_dump (vat_main_t * vam)
17377 {
17378   unformat_input_t *i = vam->input;
17379   vl_api_policer_dump_t *mp;
17380   vl_api_control_ping_t *mp_ping;
17381   u8 *match_name = 0;
17382   u8 match_name_valid = 0;
17383   int ret;
17384
17385   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17386     {
17387       if (unformat (i, "name %s", &match_name))
17388         {
17389           vec_add1 (match_name, 0);
17390           match_name_valid = 1;
17391         }
17392       else
17393         break;
17394     }
17395
17396   M (POLICER_DUMP, mp);
17397   mp->match_name_valid = match_name_valid;
17398   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
17399   vec_free (match_name);
17400   /* send it... */
17401   S (mp);
17402
17403   /* Use a control ping for synchronization */
17404   MPING (CONTROL_PING, mp_ping);
17405   S (mp_ping);
17406
17407   /* Wait for a reply... */
17408   W (ret);
17409   return ret;
17410 }
17411
17412 static int
17413 api_policer_classify_set_interface (vat_main_t * vam)
17414 {
17415   unformat_input_t *i = vam->input;
17416   vl_api_policer_classify_set_interface_t *mp;
17417   u32 sw_if_index;
17418   int sw_if_index_set;
17419   u32 ip4_table_index = ~0;
17420   u32 ip6_table_index = ~0;
17421   u32 l2_table_index = ~0;
17422   u8 is_add = 1;
17423   int ret;
17424
17425   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17426     {
17427       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17428         sw_if_index_set = 1;
17429       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17430         sw_if_index_set = 1;
17431       else if (unformat (i, "del"))
17432         is_add = 0;
17433       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17434         ;
17435       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17436         ;
17437       else if (unformat (i, "l2-table %d", &l2_table_index))
17438         ;
17439       else
17440         {
17441           clib_warning ("parse error '%U'", format_unformat_error, i);
17442           return -99;
17443         }
17444     }
17445
17446   if (sw_if_index_set == 0)
17447     {
17448       errmsg ("missing interface name or sw_if_index");
17449       return -99;
17450     }
17451
17452   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
17453
17454   mp->sw_if_index = ntohl (sw_if_index);
17455   mp->ip4_table_index = ntohl (ip4_table_index);
17456   mp->ip6_table_index = ntohl (ip6_table_index);
17457   mp->l2_table_index = ntohl (l2_table_index);
17458   mp->is_add = is_add;
17459
17460   S (mp);
17461   W (ret);
17462   return ret;
17463 }
17464
17465 static int
17466 api_policer_classify_dump (vat_main_t * vam)
17467 {
17468   unformat_input_t *i = vam->input;
17469   vl_api_policer_classify_dump_t *mp;
17470   vl_api_control_ping_t *mp_ping;
17471   u8 type = POLICER_CLASSIFY_N_TABLES;
17472   int ret;
17473
17474   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
17475     ;
17476   else
17477     {
17478       errmsg ("classify table type must be specified");
17479       return -99;
17480     }
17481
17482   if (!vam->json_output)
17483     {
17484       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17485     }
17486
17487   M (POLICER_CLASSIFY_DUMP, mp);
17488   mp->type = type;
17489   /* send it... */
17490   S (mp);
17491
17492   /* Use a control ping for synchronization */
17493   MPING (CONTROL_PING, mp_ping);
17494   S (mp_ping);
17495
17496   /* Wait for a reply... */
17497   W (ret);
17498   return ret;
17499 }
17500
17501 static u8 *
17502 format_fib_api_path_nh_proto (u8 * s, va_list * args)
17503 {
17504   vl_api_fib_path_nh_proto_t proto =
17505     va_arg (*args, vl_api_fib_path_nh_proto_t);
17506
17507   switch (proto)
17508     {
17509     case FIB_API_PATH_NH_PROTO_IP4:
17510       s = format (s, "ip4");
17511       break;
17512     case FIB_API_PATH_NH_PROTO_IP6:
17513       s = format (s, "ip6");
17514       break;
17515     case FIB_API_PATH_NH_PROTO_MPLS:
17516       s = format (s, "mpls");
17517       break;
17518     case FIB_API_PATH_NH_PROTO_BIER:
17519       s = format (s, "bier");
17520       break;
17521     case FIB_API_PATH_NH_PROTO_ETHERNET:
17522       s = format (s, "ethernet");
17523       break;
17524     }
17525
17526   return (s);
17527 }
17528
17529 static u8 *
17530 format_vl_api_ip_address_union (u8 * s, va_list * args)
17531 {
17532   vl_api_address_family_t af = va_arg (*args, int);
17533   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
17534
17535   switch (af)
17536     {
17537     case ADDRESS_IP4:
17538       s = format (s, "%U", format_ip4_address, u->ip4);
17539       break;
17540     case ADDRESS_IP6:
17541       s = format (s, "%U", format_ip6_address, u->ip6);
17542       break;
17543     }
17544   return (s);
17545 }
17546
17547 static u8 *
17548 format_vl_api_fib_path_type (u8 * s, va_list * args)
17549 {
17550   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
17551
17552   switch (t)
17553     {
17554     case FIB_API_PATH_TYPE_NORMAL:
17555       s = format (s, "normal");
17556       break;
17557     case FIB_API_PATH_TYPE_LOCAL:
17558       s = format (s, "local");
17559       break;
17560     case FIB_API_PATH_TYPE_DROP:
17561       s = format (s, "drop");
17562       break;
17563     case FIB_API_PATH_TYPE_UDP_ENCAP:
17564       s = format (s, "udp-encap");
17565       break;
17566     case FIB_API_PATH_TYPE_BIER_IMP:
17567       s = format (s, "bier-imp");
17568       break;
17569     case FIB_API_PATH_TYPE_ICMP_UNREACH:
17570       s = format (s, "unreach");
17571       break;
17572     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
17573       s = format (s, "prohibit");
17574       break;
17575     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
17576       s = format (s, "src-lookup");
17577       break;
17578     case FIB_API_PATH_TYPE_DVR:
17579       s = format (s, "dvr");
17580       break;
17581     case FIB_API_PATH_TYPE_INTERFACE_RX:
17582       s = format (s, "interface-rx");
17583       break;
17584     case FIB_API_PATH_TYPE_CLASSIFY:
17585       s = format (s, "classify");
17586       break;
17587     }
17588
17589   return (s);
17590 }
17591
17592 static void
17593 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
17594 {
17595   print (vam->ofp,
17596          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
17597          ntohl (fp->weight), ntohl (fp->sw_if_index),
17598          format_vl_api_fib_path_type, fp->type,
17599          format_fib_api_path_nh_proto, fp->proto,
17600          format_vl_api_ip_address_union, &fp->nh.address);
17601 }
17602
17603 static void
17604 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
17605                                  vl_api_fib_path_t * fp)
17606 {
17607   struct in_addr ip4;
17608   struct in6_addr ip6;
17609
17610   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17611   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17612   vat_json_object_add_uint (node, "type", fp->type);
17613   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
17614   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
17615     {
17616       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
17617       vat_json_object_add_ip4 (node, "next_hop", ip4);
17618     }
17619   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP6)
17620     {
17621       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
17622       vat_json_object_add_ip6 (node, "next_hop", ip6);
17623     }
17624 }
17625
17626 static void
17627 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
17628 {
17629   vat_main_t *vam = &vat_main;
17630   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17631   vl_api_fib_path_t *fp;
17632   i32 i;
17633
17634   print (vam->ofp, "sw_if_index %d via:",
17635          ntohl (mp->mt_tunnel.mt_sw_if_index));
17636   fp = mp->mt_tunnel.mt_paths;
17637   for (i = 0; i < count; i++)
17638     {
17639       vl_api_fib_path_print (vam, fp);
17640       fp++;
17641     }
17642
17643   print (vam->ofp, "");
17644 }
17645
17646 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
17647 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
17648
17649 static void
17650 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
17651 {
17652   vat_main_t *vam = &vat_main;
17653   vat_json_node_t *node = NULL;
17654   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17655   vl_api_fib_path_t *fp;
17656   i32 i;
17657
17658   if (VAT_JSON_ARRAY != vam->json_tree.type)
17659     {
17660       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17661       vat_json_init_array (&vam->json_tree);
17662     }
17663   node = vat_json_array_add (&vam->json_tree);
17664
17665   vat_json_init_object (node);
17666   vat_json_object_add_uint (node, "sw_if_index",
17667                             ntohl (mp->mt_tunnel.mt_sw_if_index));
17668
17669   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
17670
17671   fp = mp->mt_tunnel.mt_paths;
17672   for (i = 0; i < count; i++)
17673     {
17674       vl_api_mpls_fib_path_json_print (node, fp);
17675       fp++;
17676     }
17677 }
17678
17679 static int
17680 api_mpls_tunnel_dump (vat_main_t * vam)
17681 {
17682   vl_api_mpls_tunnel_dump_t *mp;
17683   vl_api_control_ping_t *mp_ping;
17684   int ret;
17685
17686   M (MPLS_TUNNEL_DUMP, mp);
17687
17688   S (mp);
17689
17690   /* Use a control ping for synchronization */
17691   MPING (CONTROL_PING, mp_ping);
17692   S (mp_ping);
17693
17694   W (ret);
17695   return ret;
17696 }
17697
17698 #define vl_api_mpls_table_details_t_endian vl_noop_handler
17699 #define vl_api_mpls_table_details_t_print vl_noop_handler
17700
17701
17702 static void
17703 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
17704 {
17705   vat_main_t *vam = &vat_main;
17706
17707   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
17708 }
17709
17710 static void vl_api_mpls_table_details_t_handler_json
17711   (vl_api_mpls_table_details_t * mp)
17712 {
17713   vat_main_t *vam = &vat_main;
17714   vat_json_node_t *node = NULL;
17715
17716   if (VAT_JSON_ARRAY != vam->json_tree.type)
17717     {
17718       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17719       vat_json_init_array (&vam->json_tree);
17720     }
17721   node = vat_json_array_add (&vam->json_tree);
17722
17723   vat_json_init_object (node);
17724   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
17725 }
17726
17727 static int
17728 api_mpls_table_dump (vat_main_t * vam)
17729 {
17730   vl_api_mpls_table_dump_t *mp;
17731   vl_api_control_ping_t *mp_ping;
17732   int ret;
17733
17734   M (MPLS_TABLE_DUMP, mp);
17735   S (mp);
17736
17737   /* Use a control ping for synchronization */
17738   MPING (CONTROL_PING, mp_ping);
17739   S (mp_ping);
17740
17741   W (ret);
17742   return ret;
17743 }
17744
17745 #define vl_api_mpls_route_details_t_endian vl_noop_handler
17746 #define vl_api_mpls_route_details_t_print vl_noop_handler
17747
17748 static void
17749 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
17750 {
17751   vat_main_t *vam = &vat_main;
17752   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
17753   vl_api_fib_path_t *fp;
17754   int i;
17755
17756   print (vam->ofp,
17757          "table-id %d, label %u, ess_bit %u",
17758          ntohl (mp->mr_route.mr_table_id),
17759          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
17760   fp = mp->mr_route.mr_paths;
17761   for (i = 0; i < count; i++)
17762     {
17763       vl_api_fib_path_print (vam, fp);
17764       fp++;
17765     }
17766 }
17767
17768 static void vl_api_mpls_route_details_t_handler_json
17769   (vl_api_mpls_route_details_t * mp)
17770 {
17771   vat_main_t *vam = &vat_main;
17772   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
17773   vat_json_node_t *node = NULL;
17774   vl_api_fib_path_t *fp;
17775   int i;
17776
17777   if (VAT_JSON_ARRAY != vam->json_tree.type)
17778     {
17779       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17780       vat_json_init_array (&vam->json_tree);
17781     }
17782   node = vat_json_array_add (&vam->json_tree);
17783
17784   vat_json_init_object (node);
17785   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
17786   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
17787   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
17788   vat_json_object_add_uint (node, "path_count", count);
17789   fp = mp->mr_route.mr_paths;
17790   for (i = 0; i < count; i++)
17791     {
17792       vl_api_mpls_fib_path_json_print (node, fp);
17793       fp++;
17794     }
17795 }
17796
17797 static int
17798 api_mpls_route_dump (vat_main_t * vam)
17799 {
17800   unformat_input_t *input = vam->input;
17801   vl_api_mpls_route_dump_t *mp;
17802   vl_api_control_ping_t *mp_ping;
17803   u32 table_id;
17804   int ret;
17805
17806   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17807     {
17808       if (unformat (input, "table_id %d", &table_id))
17809         ;
17810       else
17811         break;
17812     }
17813   if (table_id == ~0)
17814     {
17815       errmsg ("missing table id");
17816       return -99;
17817     }
17818
17819   M (MPLS_ROUTE_DUMP, mp);
17820
17821   mp->table.mt_table_id = ntohl (table_id);
17822   S (mp);
17823
17824   /* Use a control ping for synchronization */
17825   MPING (CONTROL_PING, mp_ping);
17826   S (mp_ping);
17827
17828   W (ret);
17829   return ret;
17830 }
17831
17832 #define vl_api_ip_table_details_t_endian vl_noop_handler
17833 #define vl_api_ip_table_details_t_print vl_noop_handler
17834
17835 static void
17836 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
17837 {
17838   vat_main_t *vam = &vat_main;
17839
17840   print (vam->ofp,
17841          "%s; table-id %d, prefix %U/%d",
17842          mp->table.name, ntohl (mp->table.table_id));
17843 }
17844
17845
17846 static void vl_api_ip_table_details_t_handler_json
17847   (vl_api_ip_table_details_t * mp)
17848 {
17849   vat_main_t *vam = &vat_main;
17850   vat_json_node_t *node = NULL;
17851
17852   if (VAT_JSON_ARRAY != vam->json_tree.type)
17853     {
17854       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17855       vat_json_init_array (&vam->json_tree);
17856     }
17857   node = vat_json_array_add (&vam->json_tree);
17858
17859   vat_json_init_object (node);
17860   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
17861 }
17862
17863 static int
17864 api_ip_table_dump (vat_main_t * vam)
17865 {
17866   vl_api_ip_table_dump_t *mp;
17867   vl_api_control_ping_t *mp_ping;
17868   int ret;
17869
17870   M (IP_TABLE_DUMP, mp);
17871   S (mp);
17872
17873   /* Use a control ping for synchronization */
17874   MPING (CONTROL_PING, mp_ping);
17875   S (mp_ping);
17876
17877   W (ret);
17878   return ret;
17879 }
17880
17881 static int
17882 api_ip_mtable_dump (vat_main_t * vam)
17883 {
17884   vl_api_ip_mtable_dump_t *mp;
17885   vl_api_control_ping_t *mp_ping;
17886   int ret;
17887
17888   M (IP_MTABLE_DUMP, mp);
17889   S (mp);
17890
17891   /* Use a control ping for synchronization */
17892   MPING (CONTROL_PING, mp_ping);
17893   S (mp_ping);
17894
17895   W (ret);
17896   return ret;
17897 }
17898
17899 static int
17900 api_ip_mroute_dump (vat_main_t * vam)
17901 {
17902   unformat_input_t *input = vam->input;
17903   vl_api_control_ping_t *mp_ping;
17904   vl_api_ip_mroute_dump_t *mp;
17905   int ret, is_ip6;
17906   u32 table_id;
17907
17908   is_ip6 = 0;
17909   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17910     {
17911       if (unformat (input, "table_id %d", &table_id))
17912         ;
17913       else if (unformat (input, "ip6"))
17914         is_ip6 = 1;
17915       else if (unformat (input, "ip4"))
17916         is_ip6 = 0;
17917       else
17918         break;
17919     }
17920   if (table_id == ~0)
17921     {
17922       errmsg ("missing table id");
17923       return -99;
17924     }
17925
17926   M (IP_MROUTE_DUMP, mp);
17927   mp->table.table_id = table_id;
17928   mp->table.is_ip6 = is_ip6;
17929   S (mp);
17930
17931   /* Use a control ping for synchronization */
17932   MPING (CONTROL_PING, mp_ping);
17933   S (mp_ping);
17934
17935   W (ret);
17936   return ret;
17937 }
17938
17939 #define vl_api_ip_route_details_t_endian vl_noop_handler
17940 #define vl_api_ip_route_details_t_print vl_noop_handler
17941
17942 static void
17943 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
17944 {
17945   vat_main_t *vam = &vat_main;
17946   u8 count = mp->route.n_paths;
17947   vl_api_fib_path_t *fp;
17948   int i;
17949
17950   print (vam->ofp,
17951          "table-id %d, prefix %U/%d",
17952          ntohl (mp->route.table_id),
17953          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
17954   for (i = 0; i < count; i++)
17955     {
17956       fp = &mp->route.paths[i];
17957
17958       vl_api_fib_path_print (vam, fp);
17959       fp++;
17960     }
17961 }
17962
17963 static void vl_api_ip_route_details_t_handler_json
17964   (vl_api_ip_route_details_t * mp)
17965 {
17966   vat_main_t *vam = &vat_main;
17967   u8 count = mp->route.n_paths;
17968   vat_json_node_t *node = NULL;
17969   struct in_addr ip4;
17970   struct in6_addr ip6;
17971   vl_api_fib_path_t *fp;
17972   int i;
17973
17974   if (VAT_JSON_ARRAY != vam->json_tree.type)
17975     {
17976       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17977       vat_json_init_array (&vam->json_tree);
17978     }
17979   node = vat_json_array_add (&vam->json_tree);
17980
17981   vat_json_init_object (node);
17982   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
17983   if (ADDRESS_IP6 == mp->route.prefix.address.af)
17984     {
17985       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
17986       vat_json_object_add_ip6 (node, "prefix", ip6);
17987     }
17988   else
17989     {
17990       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
17991       vat_json_object_add_ip4 (node, "prefix", ip4);
17992     }
17993   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
17994   vat_json_object_add_uint (node, "path_count", count);
17995   for (i = 0; i < count; i++)
17996     {
17997       fp = &mp->route.paths[i];
17998       vl_api_mpls_fib_path_json_print (node, fp);
17999     }
18000 }
18001
18002 static int
18003 api_ip_route_dump (vat_main_t * vam)
18004 {
18005   unformat_input_t *input = vam->input;
18006   vl_api_ip_route_dump_t *mp;
18007   vl_api_control_ping_t *mp_ping;
18008   u32 table_id;
18009   u8 is_ip6;
18010   int ret;
18011
18012   is_ip6 = 0;
18013   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18014     {
18015       if (unformat (input, "table_id %d", &table_id))
18016         ;
18017       else if (unformat (input, "ip6"))
18018         is_ip6 = 1;
18019       else if (unformat (input, "ip4"))
18020         is_ip6 = 0;
18021       else
18022         break;
18023     }
18024   if (table_id == ~0)
18025     {
18026       errmsg ("missing table id");
18027       return -99;
18028     }
18029
18030   M (IP_ROUTE_DUMP, mp);
18031
18032   mp->table.table_id = table_id;
18033   mp->table.is_ip6 = is_ip6;
18034
18035   S (mp);
18036
18037   /* Use a control ping for synchronization */
18038   MPING (CONTROL_PING, mp_ping);
18039   S (mp_ping);
18040
18041   W (ret);
18042   return ret;
18043 }
18044
18045 int
18046 api_classify_table_ids (vat_main_t * vam)
18047 {
18048   vl_api_classify_table_ids_t *mp;
18049   int ret;
18050
18051   /* Construct the API message */
18052   M (CLASSIFY_TABLE_IDS, mp);
18053   mp->context = 0;
18054
18055   S (mp);
18056   W (ret);
18057   return ret;
18058 }
18059
18060 int
18061 api_classify_table_by_interface (vat_main_t * vam)
18062 {
18063   unformat_input_t *input = vam->input;
18064   vl_api_classify_table_by_interface_t *mp;
18065
18066   u32 sw_if_index = ~0;
18067   int ret;
18068   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18069     {
18070       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18071         ;
18072       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18073         ;
18074       else
18075         break;
18076     }
18077   if (sw_if_index == ~0)
18078     {
18079       errmsg ("missing interface name or sw_if_index");
18080       return -99;
18081     }
18082
18083   /* Construct the API message */
18084   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
18085   mp->context = 0;
18086   mp->sw_if_index = ntohl (sw_if_index);
18087
18088   S (mp);
18089   W (ret);
18090   return ret;
18091 }
18092
18093 int
18094 api_classify_table_info (vat_main_t * vam)
18095 {
18096   unformat_input_t *input = vam->input;
18097   vl_api_classify_table_info_t *mp;
18098
18099   u32 table_id = ~0;
18100   int ret;
18101   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18102     {
18103       if (unformat (input, "table_id %d", &table_id))
18104         ;
18105       else
18106         break;
18107     }
18108   if (table_id == ~0)
18109     {
18110       errmsg ("missing table id");
18111       return -99;
18112     }
18113
18114   /* Construct the API message */
18115   M (CLASSIFY_TABLE_INFO, mp);
18116   mp->context = 0;
18117   mp->table_id = ntohl (table_id);
18118
18119   S (mp);
18120   W (ret);
18121   return ret;
18122 }
18123
18124 int
18125 api_classify_session_dump (vat_main_t * vam)
18126 {
18127   unformat_input_t *input = vam->input;
18128   vl_api_classify_session_dump_t *mp;
18129   vl_api_control_ping_t *mp_ping;
18130
18131   u32 table_id = ~0;
18132   int ret;
18133   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18134     {
18135       if (unformat (input, "table_id %d", &table_id))
18136         ;
18137       else
18138         break;
18139     }
18140   if (table_id == ~0)
18141     {
18142       errmsg ("missing table id");
18143       return -99;
18144     }
18145
18146   /* Construct the API message */
18147   M (CLASSIFY_SESSION_DUMP, mp);
18148   mp->context = 0;
18149   mp->table_id = ntohl (table_id);
18150   S (mp);
18151
18152   /* Use a control ping for synchronization */
18153   MPING (CONTROL_PING, mp_ping);
18154   S (mp_ping);
18155
18156   W (ret);
18157   return ret;
18158 }
18159
18160 static void
18161 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
18162 {
18163   vat_main_t *vam = &vat_main;
18164
18165   print (vam->ofp, "collector_address %U, collector_port %d, "
18166          "src_address %U, vrf_id %d, path_mtu %u, "
18167          "template_interval %u, udp_checksum %d",
18168          format_ip4_address, mp->collector_address,
18169          ntohs (mp->collector_port),
18170          format_ip4_address, mp->src_address,
18171          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
18172          ntohl (mp->template_interval), mp->udp_checksum);
18173
18174   vam->retval = 0;
18175   vam->result_ready = 1;
18176 }
18177
18178 static void
18179   vl_api_ipfix_exporter_details_t_handler_json
18180   (vl_api_ipfix_exporter_details_t * mp)
18181 {
18182   vat_main_t *vam = &vat_main;
18183   vat_json_node_t node;
18184   struct in_addr collector_address;
18185   struct in_addr src_address;
18186
18187   vat_json_init_object (&node);
18188   clib_memcpy (&collector_address, &mp->collector_address,
18189                sizeof (collector_address));
18190   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
18191   vat_json_object_add_uint (&node, "collector_port",
18192                             ntohs (mp->collector_port));
18193   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
18194   vat_json_object_add_ip4 (&node, "src_address", src_address);
18195   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
18196   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
18197   vat_json_object_add_uint (&node, "template_interval",
18198                             ntohl (mp->template_interval));
18199   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
18200
18201   vat_json_print (vam->ofp, &node);
18202   vat_json_free (&node);
18203   vam->retval = 0;
18204   vam->result_ready = 1;
18205 }
18206
18207 int
18208 api_ipfix_exporter_dump (vat_main_t * vam)
18209 {
18210   vl_api_ipfix_exporter_dump_t *mp;
18211   int ret;
18212
18213   /* Construct the API message */
18214   M (IPFIX_EXPORTER_DUMP, mp);
18215   mp->context = 0;
18216
18217   S (mp);
18218   W (ret);
18219   return ret;
18220 }
18221
18222 static int
18223 api_ipfix_classify_stream_dump (vat_main_t * vam)
18224 {
18225   vl_api_ipfix_classify_stream_dump_t *mp;
18226   int ret;
18227
18228   /* Construct the API message */
18229   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
18230   mp->context = 0;
18231
18232   S (mp);
18233   W (ret);
18234   return ret;
18235   /* NOTREACHED */
18236   return 0;
18237 }
18238
18239 static void
18240   vl_api_ipfix_classify_stream_details_t_handler
18241   (vl_api_ipfix_classify_stream_details_t * mp)
18242 {
18243   vat_main_t *vam = &vat_main;
18244   print (vam->ofp, "domain_id %d, src_port %d",
18245          ntohl (mp->domain_id), ntohs (mp->src_port));
18246   vam->retval = 0;
18247   vam->result_ready = 1;
18248 }
18249
18250 static void
18251   vl_api_ipfix_classify_stream_details_t_handler_json
18252   (vl_api_ipfix_classify_stream_details_t * mp)
18253 {
18254   vat_main_t *vam = &vat_main;
18255   vat_json_node_t node;
18256
18257   vat_json_init_object (&node);
18258   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
18259   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
18260
18261   vat_json_print (vam->ofp, &node);
18262   vat_json_free (&node);
18263   vam->retval = 0;
18264   vam->result_ready = 1;
18265 }
18266
18267 static int
18268 api_ipfix_classify_table_dump (vat_main_t * vam)
18269 {
18270   vl_api_ipfix_classify_table_dump_t *mp;
18271   vl_api_control_ping_t *mp_ping;
18272   int ret;
18273
18274   if (!vam->json_output)
18275     {
18276       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
18277              "transport_protocol");
18278     }
18279
18280   /* Construct the API message */
18281   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
18282
18283   /* send it... */
18284   S (mp);
18285
18286   /* Use a control ping for synchronization */
18287   MPING (CONTROL_PING, mp_ping);
18288   S (mp_ping);
18289
18290   W (ret);
18291   return ret;
18292 }
18293
18294 static void
18295   vl_api_ipfix_classify_table_details_t_handler
18296   (vl_api_ipfix_classify_table_details_t * mp)
18297 {
18298   vat_main_t *vam = &vat_main;
18299   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
18300          mp->transport_protocol);
18301 }
18302
18303 static void
18304   vl_api_ipfix_classify_table_details_t_handler_json
18305   (vl_api_ipfix_classify_table_details_t * mp)
18306 {
18307   vat_json_node_t *node = NULL;
18308   vat_main_t *vam = &vat_main;
18309
18310   if (VAT_JSON_ARRAY != vam->json_tree.type)
18311     {
18312       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18313       vat_json_init_array (&vam->json_tree);
18314     }
18315
18316   node = vat_json_array_add (&vam->json_tree);
18317   vat_json_init_object (node);
18318
18319   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
18320   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
18321   vat_json_object_add_uint (node, "transport_protocol",
18322                             mp->transport_protocol);
18323 }
18324
18325 static int
18326 api_sw_interface_span_enable_disable (vat_main_t * vam)
18327 {
18328   unformat_input_t *i = vam->input;
18329   vl_api_sw_interface_span_enable_disable_t *mp;
18330   u32 src_sw_if_index = ~0;
18331   u32 dst_sw_if_index = ~0;
18332   u8 state = 3;
18333   int ret;
18334   u8 is_l2 = 0;
18335
18336   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18337     {
18338       if (unformat
18339           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
18340         ;
18341       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
18342         ;
18343       else
18344         if (unformat
18345             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
18346         ;
18347       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
18348         ;
18349       else if (unformat (i, "disable"))
18350         state = 0;
18351       else if (unformat (i, "rx"))
18352         state = 1;
18353       else if (unformat (i, "tx"))
18354         state = 2;
18355       else if (unformat (i, "both"))
18356         state = 3;
18357       else if (unformat (i, "l2"))
18358         is_l2 = 1;
18359       else
18360         break;
18361     }
18362
18363   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
18364
18365   mp->sw_if_index_from = htonl (src_sw_if_index);
18366   mp->sw_if_index_to = htonl (dst_sw_if_index);
18367   mp->state = state;
18368   mp->is_l2 = is_l2;
18369
18370   S (mp);
18371   W (ret);
18372   return ret;
18373 }
18374
18375 static void
18376 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
18377                                             * mp)
18378 {
18379   vat_main_t *vam = &vat_main;
18380   u8 *sw_if_from_name = 0;
18381   u8 *sw_if_to_name = 0;
18382   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18383   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18384   char *states[] = { "none", "rx", "tx", "both" };
18385   hash_pair_t *p;
18386
18387   /* *INDENT-OFF* */
18388   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18389   ({
18390     if ((u32) p->value[0] == sw_if_index_from)
18391       {
18392         sw_if_from_name = (u8 *)(p->key);
18393         if (sw_if_to_name)
18394           break;
18395       }
18396     if ((u32) p->value[0] == sw_if_index_to)
18397       {
18398         sw_if_to_name = (u8 *)(p->key);
18399         if (sw_if_from_name)
18400           break;
18401       }
18402   }));
18403   /* *INDENT-ON* */
18404   print (vam->ofp, "%20s => %20s (%s) %s",
18405          sw_if_from_name, sw_if_to_name, states[mp->state],
18406          mp->is_l2 ? "l2" : "device");
18407 }
18408
18409 static void
18410   vl_api_sw_interface_span_details_t_handler_json
18411   (vl_api_sw_interface_span_details_t * mp)
18412 {
18413   vat_main_t *vam = &vat_main;
18414   vat_json_node_t *node = NULL;
18415   u8 *sw_if_from_name = 0;
18416   u8 *sw_if_to_name = 0;
18417   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18418   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18419   hash_pair_t *p;
18420
18421   /* *INDENT-OFF* */
18422   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18423   ({
18424     if ((u32) p->value[0] == sw_if_index_from)
18425       {
18426         sw_if_from_name = (u8 *)(p->key);
18427         if (sw_if_to_name)
18428           break;
18429       }
18430     if ((u32) p->value[0] == sw_if_index_to)
18431       {
18432         sw_if_to_name = (u8 *)(p->key);
18433         if (sw_if_from_name)
18434           break;
18435       }
18436   }));
18437   /* *INDENT-ON* */
18438
18439   if (VAT_JSON_ARRAY != vam->json_tree.type)
18440     {
18441       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18442       vat_json_init_array (&vam->json_tree);
18443     }
18444   node = vat_json_array_add (&vam->json_tree);
18445
18446   vat_json_init_object (node);
18447   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
18448   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
18449   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
18450   if (0 != sw_if_to_name)
18451     {
18452       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
18453     }
18454   vat_json_object_add_uint (node, "state", mp->state);
18455   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
18456 }
18457
18458 static int
18459 api_sw_interface_span_dump (vat_main_t * vam)
18460 {
18461   unformat_input_t *input = vam->input;
18462   vl_api_sw_interface_span_dump_t *mp;
18463   vl_api_control_ping_t *mp_ping;
18464   u8 is_l2 = 0;
18465   int ret;
18466
18467   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18468     {
18469       if (unformat (input, "l2"))
18470         is_l2 = 1;
18471       else
18472         break;
18473     }
18474
18475   M (SW_INTERFACE_SPAN_DUMP, mp);
18476   mp->is_l2 = is_l2;
18477   S (mp);
18478
18479   /* Use a control ping for synchronization */
18480   MPING (CONTROL_PING, mp_ping);
18481   S (mp_ping);
18482
18483   W (ret);
18484   return ret;
18485 }
18486
18487 int
18488 api_pg_create_interface (vat_main_t * vam)
18489 {
18490   unformat_input_t *input = vam->input;
18491   vl_api_pg_create_interface_t *mp;
18492
18493   u32 if_id = ~0, gso_size = 0;
18494   u8 gso_enabled = 0;
18495   int ret;
18496   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18497     {
18498       if (unformat (input, "if_id %d", &if_id))
18499         ;
18500       else if (unformat (input, "gso-enabled"))
18501         {
18502           gso_enabled = 1;
18503           if (unformat (input, "gso-size %u", &gso_size))
18504             ;
18505           else
18506             {
18507               errmsg ("missing gso-size");
18508               return -99;
18509             }
18510         }
18511       else
18512         break;
18513     }
18514   if (if_id == ~0)
18515     {
18516       errmsg ("missing pg interface index");
18517       return -99;
18518     }
18519
18520   /* Construct the API message */
18521   M (PG_CREATE_INTERFACE, mp);
18522   mp->context = 0;
18523   mp->interface_id = ntohl (if_id);
18524   mp->gso_enabled = gso_enabled;
18525
18526   S (mp);
18527   W (ret);
18528   return ret;
18529 }
18530
18531 int
18532 api_pg_capture (vat_main_t * vam)
18533 {
18534   unformat_input_t *input = vam->input;
18535   vl_api_pg_capture_t *mp;
18536
18537   u32 if_id = ~0;
18538   u8 enable = 1;
18539   u32 count = 1;
18540   u8 pcap_file_set = 0;
18541   u8 *pcap_file = 0;
18542   int ret;
18543   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18544     {
18545       if (unformat (input, "if_id %d", &if_id))
18546         ;
18547       else if (unformat (input, "pcap %s", &pcap_file))
18548         pcap_file_set = 1;
18549       else if (unformat (input, "count %d", &count))
18550         ;
18551       else if (unformat (input, "disable"))
18552         enable = 0;
18553       else
18554         break;
18555     }
18556   if (if_id == ~0)
18557     {
18558       errmsg ("missing pg interface index");
18559       return -99;
18560     }
18561   if (pcap_file_set > 0)
18562     {
18563       if (vec_len (pcap_file) > 255)
18564         {
18565           errmsg ("pcap file name is too long");
18566           return -99;
18567         }
18568     }
18569
18570   /* Construct the API message */
18571   M (PG_CAPTURE, mp);
18572   mp->context = 0;
18573   mp->interface_id = ntohl (if_id);
18574   mp->is_enabled = enable;
18575   mp->count = ntohl (count);
18576   if (pcap_file_set != 0)
18577     {
18578       vl_api_vec_to_api_string (pcap_file, &mp->pcap_file_name);
18579     }
18580   vec_free (pcap_file);
18581
18582   S (mp);
18583   W (ret);
18584   return ret;
18585 }
18586
18587 int
18588 api_pg_enable_disable (vat_main_t * vam)
18589 {
18590   unformat_input_t *input = vam->input;
18591   vl_api_pg_enable_disable_t *mp;
18592
18593   u8 enable = 1;
18594   u8 stream_name_set = 0;
18595   u8 *stream_name = 0;
18596   int ret;
18597   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18598     {
18599       if (unformat (input, "stream %s", &stream_name))
18600         stream_name_set = 1;
18601       else if (unformat (input, "disable"))
18602         enable = 0;
18603       else
18604         break;
18605     }
18606
18607   if (stream_name_set > 0)
18608     {
18609       if (vec_len (stream_name) > 255)
18610         {
18611           errmsg ("stream name too long");
18612           return -99;
18613         }
18614     }
18615
18616   /* Construct the API message */
18617   M (PG_ENABLE_DISABLE, mp);
18618   mp->context = 0;
18619   mp->is_enabled = enable;
18620   if (stream_name_set != 0)
18621     {
18622       vl_api_vec_to_api_string (stream_name, &mp->stream_name);
18623     }
18624   vec_free (stream_name);
18625
18626   S (mp);
18627   W (ret);
18628   return ret;
18629 }
18630
18631 int
18632 api_pg_interface_enable_disable_coalesce (vat_main_t * vam)
18633 {
18634   unformat_input_t *input = vam->input;
18635   vl_api_pg_interface_enable_disable_coalesce_t *mp;
18636
18637   u32 sw_if_index = ~0;
18638   u8 enable = 1;
18639   int ret;
18640   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18641     {
18642       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18643         ;
18644       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18645         ;
18646       else if (unformat (input, "disable"))
18647         enable = 0;
18648       else
18649         break;
18650     }
18651
18652   if (sw_if_index == ~0)
18653     {
18654       errmsg ("Interface required but not specified");
18655       return -99;
18656     }
18657
18658   /* Construct the API message */
18659   M (PG_INTERFACE_ENABLE_DISABLE_COALESCE, mp);
18660   mp->context = 0;
18661   mp->coalesce_enabled = enable;
18662   mp->sw_if_index = htonl (sw_if_index);
18663
18664   S (mp);
18665   W (ret);
18666   return ret;
18667 }
18668
18669 int
18670 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
18671 {
18672   unformat_input_t *input = vam->input;
18673   vl_api_ip_source_and_port_range_check_add_del_t *mp;
18674
18675   u16 *low_ports = 0;
18676   u16 *high_ports = 0;
18677   u16 this_low;
18678   u16 this_hi;
18679   vl_api_prefix_t prefix;
18680   u32 tmp, tmp2;
18681   u8 prefix_set = 0;
18682   u32 vrf_id = ~0;
18683   u8 is_add = 1;
18684   int ret;
18685
18686   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18687     {
18688       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
18689         prefix_set = 1;
18690       else if (unformat (input, "vrf %d", &vrf_id))
18691         ;
18692       else if (unformat (input, "del"))
18693         is_add = 0;
18694       else if (unformat (input, "port %d", &tmp))
18695         {
18696           if (tmp == 0 || tmp > 65535)
18697             {
18698               errmsg ("port %d out of range", tmp);
18699               return -99;
18700             }
18701           this_low = tmp;
18702           this_hi = this_low + 1;
18703           vec_add1 (low_ports, this_low);
18704           vec_add1 (high_ports, this_hi);
18705         }
18706       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
18707         {
18708           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
18709             {
18710               errmsg ("incorrect range parameters");
18711               return -99;
18712             }
18713           this_low = tmp;
18714           /* Note: in debug CLI +1 is added to high before
18715              passing to real fn that does "the work"
18716              (ip_source_and_port_range_check_add_del).
18717              This fn is a wrapper around the binary API fn a
18718              control plane will call, which expects this increment
18719              to have occurred. Hence letting the binary API control
18720              plane fn do the increment for consistency between VAT
18721              and other control planes.
18722            */
18723           this_hi = tmp2;
18724           vec_add1 (low_ports, this_low);
18725           vec_add1 (high_ports, this_hi);
18726         }
18727       else
18728         break;
18729     }
18730
18731   if (prefix_set == 0)
18732     {
18733       errmsg ("<address>/<mask> not specified");
18734       return -99;
18735     }
18736
18737   if (vrf_id == ~0)
18738     {
18739       errmsg ("VRF ID required, not specified");
18740       return -99;
18741     }
18742
18743   if (vrf_id == 0)
18744     {
18745       errmsg
18746         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18747       return -99;
18748     }
18749
18750   if (vec_len (low_ports) == 0)
18751     {
18752       errmsg ("At least one port or port range required");
18753       return -99;
18754     }
18755
18756   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
18757
18758   mp->is_add = is_add;
18759
18760   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
18761
18762   mp->number_of_ranges = vec_len (low_ports);
18763
18764   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
18765   vec_free (low_ports);
18766
18767   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
18768   vec_free (high_ports);
18769
18770   mp->vrf_id = ntohl (vrf_id);
18771
18772   S (mp);
18773   W (ret);
18774   return ret;
18775 }
18776
18777 int
18778 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
18779 {
18780   unformat_input_t *input = vam->input;
18781   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
18782   u32 sw_if_index = ~0;
18783   int vrf_set = 0;
18784   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
18785   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
18786   u8 is_add = 1;
18787   int ret;
18788
18789   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18790     {
18791       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18792         ;
18793       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18794         ;
18795       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
18796         vrf_set = 1;
18797       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
18798         vrf_set = 1;
18799       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
18800         vrf_set = 1;
18801       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
18802         vrf_set = 1;
18803       else if (unformat (input, "del"))
18804         is_add = 0;
18805       else
18806         break;
18807     }
18808
18809   if (sw_if_index == ~0)
18810     {
18811       errmsg ("Interface required but not specified");
18812       return -99;
18813     }
18814
18815   if (vrf_set == 0)
18816     {
18817       errmsg ("VRF ID required but not specified");
18818       return -99;
18819     }
18820
18821   if (tcp_out_vrf_id == 0
18822       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
18823     {
18824       errmsg
18825         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18826       return -99;
18827     }
18828
18829   /* Construct the API message */
18830   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
18831
18832   mp->sw_if_index = ntohl (sw_if_index);
18833   mp->is_add = is_add;
18834   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
18835   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
18836   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
18837   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
18838
18839   /* send it... */
18840   S (mp);
18841
18842   /* Wait for a reply... */
18843   W (ret);
18844   return ret;
18845 }
18846
18847 static int
18848 api_set_punt (vat_main_t * vam)
18849 {
18850   unformat_input_t *i = vam->input;
18851   vl_api_address_family_t af;
18852   vl_api_set_punt_t *mp;
18853   u32 protocol = ~0;
18854   u32 port = ~0;
18855   int is_add = 1;
18856   int ret;
18857
18858   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18859     {
18860       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
18861         ;
18862       else if (unformat (i, "protocol %d", &protocol))
18863         ;
18864       else if (unformat (i, "port %d", &port))
18865         ;
18866       else if (unformat (i, "del"))
18867         is_add = 0;
18868       else
18869         {
18870           clib_warning ("parse error '%U'", format_unformat_error, i);
18871           return -99;
18872         }
18873     }
18874
18875   M (SET_PUNT, mp);
18876
18877   mp->is_add = (u8) is_add;
18878   mp->punt.type = PUNT_API_TYPE_L4;
18879   mp->punt.punt.l4.af = af;
18880   mp->punt.punt.l4.protocol = (u8) protocol;
18881   mp->punt.punt.l4.port = htons ((u16) port);
18882
18883   S (mp);
18884   W (ret);
18885   return ret;
18886 }
18887
18888 static int
18889 api_delete_subif (vat_main_t * vam)
18890 {
18891   unformat_input_t *i = vam->input;
18892   vl_api_delete_subif_t *mp;
18893   u32 sw_if_index = ~0;
18894   int ret;
18895
18896   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18897     {
18898       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18899         ;
18900       if (unformat (i, "sw_if_index %d", &sw_if_index))
18901         ;
18902       else
18903         break;
18904     }
18905
18906   if (sw_if_index == ~0)
18907     {
18908       errmsg ("missing sw_if_index");
18909       return -99;
18910     }
18911
18912   /* Construct the API message */
18913   M (DELETE_SUBIF, mp);
18914   mp->sw_if_index = ntohl (sw_if_index);
18915
18916   S (mp);
18917   W (ret);
18918   return ret;
18919 }
18920
18921 #define foreach_pbb_vtr_op      \
18922 _("disable",  L2_VTR_DISABLED)  \
18923 _("pop",  L2_VTR_POP_2)         \
18924 _("push",  L2_VTR_PUSH_2)
18925
18926 static int
18927 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
18928 {
18929   unformat_input_t *i = vam->input;
18930   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
18931   u32 sw_if_index = ~0, vtr_op = ~0;
18932   u16 outer_tag = ~0;
18933   u8 dmac[6], smac[6];
18934   u8 dmac_set = 0, smac_set = 0;
18935   u16 vlanid = 0;
18936   u32 sid = ~0;
18937   u32 tmp;
18938   int ret;
18939
18940   /* Shut up coverity */
18941   clib_memset (dmac, 0, sizeof (dmac));
18942   clib_memset (smac, 0, sizeof (smac));
18943
18944   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18945     {
18946       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18947         ;
18948       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18949         ;
18950       else if (unformat (i, "vtr_op %d", &vtr_op))
18951         ;
18952 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
18953       foreach_pbb_vtr_op
18954 #undef _
18955         else if (unformat (i, "translate_pbb_stag"))
18956         {
18957           if (unformat (i, "%d", &tmp))
18958             {
18959               vtr_op = L2_VTR_TRANSLATE_2_1;
18960               outer_tag = tmp;
18961             }
18962           else
18963             {
18964               errmsg
18965                 ("translate_pbb_stag operation requires outer tag definition");
18966               return -99;
18967             }
18968         }
18969       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
18970         dmac_set++;
18971       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
18972         smac_set++;
18973       else if (unformat (i, "sid %d", &sid))
18974         ;
18975       else if (unformat (i, "vlanid %d", &tmp))
18976         vlanid = tmp;
18977       else
18978         {
18979           clib_warning ("parse error '%U'", format_unformat_error, i);
18980           return -99;
18981         }
18982     }
18983
18984   if ((sw_if_index == ~0) || (vtr_op == ~0))
18985     {
18986       errmsg ("missing sw_if_index or vtr operation");
18987       return -99;
18988     }
18989   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
18990       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
18991     {
18992       errmsg
18993         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
18994       return -99;
18995     }
18996
18997   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
18998   mp->sw_if_index = ntohl (sw_if_index);
18999   mp->vtr_op = ntohl (vtr_op);
19000   mp->outer_tag = ntohs (outer_tag);
19001   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
19002   clib_memcpy (mp->b_smac, smac, sizeof (smac));
19003   mp->b_vlanid = ntohs (vlanid);
19004   mp->i_sid = ntohl (sid);
19005
19006   S (mp);
19007   W (ret);
19008   return ret;
19009 }
19010
19011 static int
19012 api_flow_classify_set_interface (vat_main_t * vam)
19013 {
19014   unformat_input_t *i = vam->input;
19015   vl_api_flow_classify_set_interface_t *mp;
19016   u32 sw_if_index;
19017   int sw_if_index_set;
19018   u32 ip4_table_index = ~0;
19019   u32 ip6_table_index = ~0;
19020   u8 is_add = 1;
19021   int ret;
19022
19023   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19024     {
19025       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19026         sw_if_index_set = 1;
19027       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19028         sw_if_index_set = 1;
19029       else if (unformat (i, "del"))
19030         is_add = 0;
19031       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19032         ;
19033       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19034         ;
19035       else
19036         {
19037           clib_warning ("parse error '%U'", format_unformat_error, i);
19038           return -99;
19039         }
19040     }
19041
19042   if (sw_if_index_set == 0)
19043     {
19044       errmsg ("missing interface name or sw_if_index");
19045       return -99;
19046     }
19047
19048   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
19049
19050   mp->sw_if_index = ntohl (sw_if_index);
19051   mp->ip4_table_index = ntohl (ip4_table_index);
19052   mp->ip6_table_index = ntohl (ip6_table_index);
19053   mp->is_add = is_add;
19054
19055   S (mp);
19056   W (ret);
19057   return ret;
19058 }
19059
19060 static int
19061 api_flow_classify_dump (vat_main_t * vam)
19062 {
19063   unformat_input_t *i = vam->input;
19064   vl_api_flow_classify_dump_t *mp;
19065   vl_api_control_ping_t *mp_ping;
19066   u8 type = FLOW_CLASSIFY_N_TABLES;
19067   int ret;
19068
19069   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
19070     ;
19071   else
19072     {
19073       errmsg ("classify table type must be specified");
19074       return -99;
19075     }
19076
19077   if (!vam->json_output)
19078     {
19079       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19080     }
19081
19082   M (FLOW_CLASSIFY_DUMP, mp);
19083   mp->type = type;
19084   /* send it... */
19085   S (mp);
19086
19087   /* Use a control ping for synchronization */
19088   MPING (CONTROL_PING, mp_ping);
19089   S (mp_ping);
19090
19091   /* Wait for a reply... */
19092   W (ret);
19093   return ret;
19094 }
19095
19096 static int
19097 api_feature_enable_disable (vat_main_t * vam)
19098 {
19099   unformat_input_t *i = vam->input;
19100   vl_api_feature_enable_disable_t *mp;
19101   u8 *arc_name = 0;
19102   u8 *feature_name = 0;
19103   u32 sw_if_index = ~0;
19104   u8 enable = 1;
19105   int ret;
19106
19107   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19108     {
19109       if (unformat (i, "arc_name %s", &arc_name))
19110         ;
19111       else if (unformat (i, "feature_name %s", &feature_name))
19112         ;
19113       else
19114         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19115         ;
19116       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19117         ;
19118       else if (unformat (i, "disable"))
19119         enable = 0;
19120       else
19121         break;
19122     }
19123
19124   if (arc_name == 0)
19125     {
19126       errmsg ("missing arc name");
19127       return -99;
19128     }
19129   if (vec_len (arc_name) > 63)
19130     {
19131       errmsg ("arc name too long");
19132     }
19133
19134   if (feature_name == 0)
19135     {
19136       errmsg ("missing feature name");
19137       return -99;
19138     }
19139   if (vec_len (feature_name) > 63)
19140     {
19141       errmsg ("feature name too long");
19142     }
19143
19144   if (sw_if_index == ~0)
19145     {
19146       errmsg ("missing interface name or sw_if_index");
19147       return -99;
19148     }
19149
19150   /* Construct the API message */
19151   M (FEATURE_ENABLE_DISABLE, mp);
19152   mp->sw_if_index = ntohl (sw_if_index);
19153   mp->enable = enable;
19154   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
19155   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
19156   vec_free (arc_name);
19157   vec_free (feature_name);
19158
19159   S (mp);
19160   W (ret);
19161   return ret;
19162 }
19163
19164 static int
19165 api_feature_gso_enable_disable (vat_main_t * vam)
19166 {
19167   unformat_input_t *i = vam->input;
19168   vl_api_feature_gso_enable_disable_t *mp;
19169   u32 sw_if_index = ~0;
19170   u8 enable = 1;
19171   int ret;
19172
19173   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19174     {
19175       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19176         ;
19177       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19178         ;
19179       else if (unformat (i, "enable"))
19180         enable = 1;
19181       else if (unformat (i, "disable"))
19182         enable = 0;
19183       else
19184         break;
19185     }
19186
19187   if (sw_if_index == ~0)
19188     {
19189       errmsg ("missing interface name or sw_if_index");
19190       return -99;
19191     }
19192
19193   /* Construct the API message */
19194   M (FEATURE_GSO_ENABLE_DISABLE, mp);
19195   mp->sw_if_index = ntohl (sw_if_index);
19196   mp->enable_disable = enable;
19197
19198   S (mp);
19199   W (ret);
19200   return ret;
19201 }
19202
19203 static int
19204 api_sw_interface_tag_add_del (vat_main_t * vam)
19205 {
19206   unformat_input_t *i = vam->input;
19207   vl_api_sw_interface_tag_add_del_t *mp;
19208   u32 sw_if_index = ~0;
19209   u8 *tag = 0;
19210   u8 enable = 1;
19211   int ret;
19212
19213   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19214     {
19215       if (unformat (i, "tag %s", &tag))
19216         ;
19217       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19218         ;
19219       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19220         ;
19221       else if (unformat (i, "del"))
19222         enable = 0;
19223       else
19224         break;
19225     }
19226
19227   if (sw_if_index == ~0)
19228     {
19229       errmsg ("missing interface name or sw_if_index");
19230       return -99;
19231     }
19232
19233   if (enable && (tag == 0))
19234     {
19235       errmsg ("no tag specified");
19236       return -99;
19237     }
19238
19239   /* Construct the API message */
19240   M (SW_INTERFACE_TAG_ADD_DEL, mp);
19241   mp->sw_if_index = ntohl (sw_if_index);
19242   mp->is_add = enable;
19243   if (enable)
19244     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
19245   vec_free (tag);
19246
19247   S (mp);
19248   W (ret);
19249   return ret;
19250 }
19251
19252 static int
19253 api_sw_interface_add_del_mac_address (vat_main_t * vam)
19254 {
19255   unformat_input_t *i = vam->input;
19256   vl_api_mac_address_t mac = { 0 };
19257   vl_api_sw_interface_add_del_mac_address_t *mp;
19258   u32 sw_if_index = ~0;
19259   u8 is_add = 1;
19260   u8 mac_set = 0;
19261   int ret;
19262
19263   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19264     {
19265       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19266         ;
19267       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19268         ;
19269       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
19270         mac_set++;
19271       else if (unformat (i, "del"))
19272         is_add = 0;
19273       else
19274         break;
19275     }
19276
19277   if (sw_if_index == ~0)
19278     {
19279       errmsg ("missing interface name or sw_if_index");
19280       return -99;
19281     }
19282
19283   if (!mac_set)
19284     {
19285       errmsg ("missing MAC address");
19286       return -99;
19287     }
19288
19289   /* Construct the API message */
19290   M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
19291   mp->sw_if_index = ntohl (sw_if_index);
19292   mp->is_add = is_add;
19293   clib_memcpy (&mp->addr, &mac, sizeof (mac));
19294
19295   S (mp);
19296   W (ret);
19297   return ret;
19298 }
19299
19300 static void vl_api_l2_xconnect_details_t_handler
19301   (vl_api_l2_xconnect_details_t * mp)
19302 {
19303   vat_main_t *vam = &vat_main;
19304
19305   print (vam->ofp, "%15d%15d",
19306          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
19307 }
19308
19309 static void vl_api_l2_xconnect_details_t_handler_json
19310   (vl_api_l2_xconnect_details_t * mp)
19311 {
19312   vat_main_t *vam = &vat_main;
19313   vat_json_node_t *node = NULL;
19314
19315   if (VAT_JSON_ARRAY != vam->json_tree.type)
19316     {
19317       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19318       vat_json_init_array (&vam->json_tree);
19319     }
19320   node = vat_json_array_add (&vam->json_tree);
19321
19322   vat_json_init_object (node);
19323   vat_json_object_add_uint (node, "rx_sw_if_index",
19324                             ntohl (mp->rx_sw_if_index));
19325   vat_json_object_add_uint (node, "tx_sw_if_index",
19326                             ntohl (mp->tx_sw_if_index));
19327 }
19328
19329 static int
19330 api_l2_xconnect_dump (vat_main_t * vam)
19331 {
19332   vl_api_l2_xconnect_dump_t *mp;
19333   vl_api_control_ping_t *mp_ping;
19334   int ret;
19335
19336   if (!vam->json_output)
19337     {
19338       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
19339     }
19340
19341   M (L2_XCONNECT_DUMP, mp);
19342
19343   S (mp);
19344
19345   /* Use a control ping for synchronization */
19346   MPING (CONTROL_PING, mp_ping);
19347   S (mp_ping);
19348
19349   W (ret);
19350   return ret;
19351 }
19352
19353 static int
19354 api_hw_interface_set_mtu (vat_main_t * vam)
19355 {
19356   unformat_input_t *i = vam->input;
19357   vl_api_hw_interface_set_mtu_t *mp;
19358   u32 sw_if_index = ~0;
19359   u32 mtu = 0;
19360   int ret;
19361
19362   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19363     {
19364       if (unformat (i, "mtu %d", &mtu))
19365         ;
19366       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19367         ;
19368       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19369         ;
19370       else
19371         break;
19372     }
19373
19374   if (sw_if_index == ~0)
19375     {
19376       errmsg ("missing interface name or sw_if_index");
19377       return -99;
19378     }
19379
19380   if (mtu == 0)
19381     {
19382       errmsg ("no mtu specified");
19383       return -99;
19384     }
19385
19386   /* Construct the API message */
19387   M (HW_INTERFACE_SET_MTU, mp);
19388   mp->sw_if_index = ntohl (sw_if_index);
19389   mp->mtu = ntohs ((u16) mtu);
19390
19391   S (mp);
19392   W (ret);
19393   return ret;
19394 }
19395
19396 static int
19397 api_p2p_ethernet_add (vat_main_t * vam)
19398 {
19399   unformat_input_t *i = vam->input;
19400   vl_api_p2p_ethernet_add_t *mp;
19401   u32 parent_if_index = ~0;
19402   u32 sub_id = ~0;
19403   u8 remote_mac[6];
19404   u8 mac_set = 0;
19405   int ret;
19406
19407   clib_memset (remote_mac, 0, sizeof (remote_mac));
19408   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19409     {
19410       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19411         ;
19412       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19413         ;
19414       else
19415         if (unformat
19416             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19417         mac_set++;
19418       else if (unformat (i, "sub_id %d", &sub_id))
19419         ;
19420       else
19421         {
19422           clib_warning ("parse error '%U'", format_unformat_error, i);
19423           return -99;
19424         }
19425     }
19426
19427   if (parent_if_index == ~0)
19428     {
19429       errmsg ("missing interface name or sw_if_index");
19430       return -99;
19431     }
19432   if (mac_set == 0)
19433     {
19434       errmsg ("missing remote mac address");
19435       return -99;
19436     }
19437   if (sub_id == ~0)
19438     {
19439       errmsg ("missing sub-interface id");
19440       return -99;
19441     }
19442
19443   M (P2P_ETHERNET_ADD, mp);
19444   mp->parent_if_index = ntohl (parent_if_index);
19445   mp->subif_id = ntohl (sub_id);
19446   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19447
19448   S (mp);
19449   W (ret);
19450   return ret;
19451 }
19452
19453 static int
19454 api_p2p_ethernet_del (vat_main_t * vam)
19455 {
19456   unformat_input_t *i = vam->input;
19457   vl_api_p2p_ethernet_del_t *mp;
19458   u32 parent_if_index = ~0;
19459   u8 remote_mac[6];
19460   u8 mac_set = 0;
19461   int ret;
19462
19463   clib_memset (remote_mac, 0, sizeof (remote_mac));
19464   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19465     {
19466       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19467         ;
19468       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19469         ;
19470       else
19471         if (unformat
19472             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19473         mac_set++;
19474       else
19475         {
19476           clib_warning ("parse error '%U'", format_unformat_error, i);
19477           return -99;
19478         }
19479     }
19480
19481   if (parent_if_index == ~0)
19482     {
19483       errmsg ("missing interface name or sw_if_index");
19484       return -99;
19485     }
19486   if (mac_set == 0)
19487     {
19488       errmsg ("missing remote mac address");
19489       return -99;
19490     }
19491
19492   M (P2P_ETHERNET_DEL, mp);
19493   mp->parent_if_index = ntohl (parent_if_index);
19494   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19495
19496   S (mp);
19497   W (ret);
19498   return ret;
19499 }
19500
19501 static int
19502 api_lldp_config (vat_main_t * vam)
19503 {
19504   unformat_input_t *i = vam->input;
19505   vl_api_lldp_config_t *mp;
19506   int tx_hold = 0;
19507   int tx_interval = 0;
19508   u8 *sys_name = NULL;
19509   int ret;
19510
19511   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19512     {
19513       if (unformat (i, "system-name %s", &sys_name))
19514         ;
19515       else if (unformat (i, "tx-hold %d", &tx_hold))
19516         ;
19517       else if (unformat (i, "tx-interval %d", &tx_interval))
19518         ;
19519       else
19520         {
19521           clib_warning ("parse error '%U'", format_unformat_error, i);
19522           return -99;
19523         }
19524     }
19525
19526   vec_add1 (sys_name, 0);
19527
19528   M (LLDP_CONFIG, mp);
19529   mp->tx_hold = htonl (tx_hold);
19530   mp->tx_interval = htonl (tx_interval);
19531   vl_api_vec_to_api_string (sys_name, &mp->system_name);
19532   vec_free (sys_name);
19533
19534   S (mp);
19535   W (ret);
19536   return ret;
19537 }
19538
19539 static int
19540 api_sw_interface_set_lldp (vat_main_t * vam)
19541 {
19542   unformat_input_t *i = vam->input;
19543   vl_api_sw_interface_set_lldp_t *mp;
19544   u32 sw_if_index = ~0;
19545   u32 enable = 1;
19546   u8 *port_desc = NULL, *mgmt_oid = NULL;
19547   ip4_address_t ip4_addr;
19548   ip6_address_t ip6_addr;
19549   int ret;
19550
19551   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
19552   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
19553
19554   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19555     {
19556       if (unformat (i, "disable"))
19557         enable = 0;
19558       else
19559         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19560         ;
19561       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19562         ;
19563       else if (unformat (i, "port-desc %s", &port_desc))
19564         ;
19565       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
19566         ;
19567       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
19568         ;
19569       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
19570         ;
19571       else
19572         break;
19573     }
19574
19575   if (sw_if_index == ~0)
19576     {
19577       errmsg ("missing interface name or sw_if_index");
19578       return -99;
19579     }
19580
19581   /* Construct the API message */
19582   vec_add1 (port_desc, 0);
19583   vec_add1 (mgmt_oid, 0);
19584   M (SW_INTERFACE_SET_LLDP, mp);
19585   mp->sw_if_index = ntohl (sw_if_index);
19586   mp->enable = enable;
19587   vl_api_vec_to_api_string (port_desc, &mp->port_desc);
19588   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
19589   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
19590   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
19591   vec_free (port_desc);
19592   vec_free (mgmt_oid);
19593
19594   S (mp);
19595   W (ret);
19596   return ret;
19597 }
19598
19599 static int
19600 api_tcp_configure_src_addresses (vat_main_t * vam)
19601 {
19602   vl_api_tcp_configure_src_addresses_t *mp;
19603   unformat_input_t *i = vam->input;
19604   vl_api_address_t first, last;
19605   u8 range_set = 0;
19606   u32 vrf_id = 0;
19607   int ret;
19608
19609   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19610     {
19611       if (unformat (i, "%U - %U",
19612                     unformat_vl_api_address, &first,
19613                     unformat_vl_api_address, &last))
19614         {
19615           if (range_set)
19616             {
19617               errmsg ("one range per message (range already set)");
19618               return -99;
19619             }
19620           range_set = 1;
19621         }
19622       else if (unformat (i, "vrf %d", &vrf_id))
19623         ;
19624       else
19625         break;
19626     }
19627
19628   if (range_set == 0)
19629     {
19630       errmsg ("address range not set");
19631       return -99;
19632     }
19633
19634   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
19635
19636   mp->vrf_id = ntohl (vrf_id);
19637   clib_memcpy (&mp->first_address, &first, sizeof (first));
19638   clib_memcpy (&mp->last_address, &last, sizeof (last));
19639
19640   S (mp);
19641   W (ret);
19642   return ret;
19643 }
19644
19645 static void vl_api_app_namespace_add_del_reply_t_handler
19646   (vl_api_app_namespace_add_del_reply_t * mp)
19647 {
19648   vat_main_t *vam = &vat_main;
19649   i32 retval = ntohl (mp->retval);
19650   if (vam->async_mode)
19651     {
19652       vam->async_errors += (retval < 0);
19653     }
19654   else
19655     {
19656       vam->retval = retval;
19657       if (retval == 0)
19658         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
19659       vam->result_ready = 1;
19660     }
19661 }
19662
19663 static void vl_api_app_namespace_add_del_reply_t_handler_json
19664   (vl_api_app_namespace_add_del_reply_t * mp)
19665 {
19666   vat_main_t *vam = &vat_main;
19667   vat_json_node_t node;
19668
19669   vat_json_init_object (&node);
19670   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
19671   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
19672
19673   vat_json_print (vam->ofp, &node);
19674   vat_json_free (&node);
19675
19676   vam->retval = ntohl (mp->retval);
19677   vam->result_ready = 1;
19678 }
19679
19680 static int
19681 api_app_namespace_add_del (vat_main_t * vam)
19682 {
19683   vl_api_app_namespace_add_del_t *mp;
19684   unformat_input_t *i = vam->input;
19685   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
19686   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
19687   u64 secret;
19688   int ret;
19689
19690   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19691     {
19692       if (unformat (i, "id %_%v%_", &ns_id))
19693         ;
19694       else if (unformat (i, "secret %lu", &secret))
19695         secret_set = 1;
19696       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19697         sw_if_index_set = 1;
19698       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
19699         ;
19700       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
19701         ;
19702       else
19703         break;
19704     }
19705   if (!ns_id || !secret_set || !sw_if_index_set)
19706     {
19707       errmsg ("namespace id, secret and sw_if_index must be set");
19708       return -99;
19709     }
19710   if (vec_len (ns_id) > 64)
19711     {
19712       errmsg ("namespace id too long");
19713       return -99;
19714     }
19715   M (APP_NAMESPACE_ADD_DEL, mp);
19716
19717   vl_api_vec_to_api_string (ns_id, &mp->namespace_id);
19718   mp->secret = clib_host_to_net_u64 (secret);
19719   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
19720   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
19721   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
19722   vec_free (ns_id);
19723   S (mp);
19724   W (ret);
19725   return ret;
19726 }
19727
19728 static int
19729 api_sock_init_shm (vat_main_t * vam)
19730 {
19731 #if VPP_API_TEST_BUILTIN == 0
19732   unformat_input_t *i = vam->input;
19733   vl_api_shm_elem_config_t *config = 0;
19734   u64 size = 64 << 20;
19735   int rv;
19736
19737   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19738     {
19739       if (unformat (i, "size %U", unformat_memory_size, &size))
19740         ;
19741       else
19742         break;
19743     }
19744
19745   /*
19746    * Canned custom ring allocator config.
19747    * Should probably parse all of this
19748    */
19749   vec_validate (config, 6);
19750   config[0].type = VL_API_VLIB_RING;
19751   config[0].size = 256;
19752   config[0].count = 32;
19753
19754   config[1].type = VL_API_VLIB_RING;
19755   config[1].size = 1024;
19756   config[1].count = 16;
19757
19758   config[2].type = VL_API_VLIB_RING;
19759   config[2].size = 4096;
19760   config[2].count = 2;
19761
19762   config[3].type = VL_API_CLIENT_RING;
19763   config[3].size = 256;
19764   config[3].count = 32;
19765
19766   config[4].type = VL_API_CLIENT_RING;
19767   config[4].size = 1024;
19768   config[4].count = 16;
19769
19770   config[5].type = VL_API_CLIENT_RING;
19771   config[5].size = 4096;
19772   config[5].count = 2;
19773
19774   config[6].type = VL_API_QUEUE;
19775   config[6].count = 128;
19776   config[6].size = sizeof (uword);
19777
19778   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
19779   if (!rv)
19780     vam->client_index_invalid = 1;
19781   return rv;
19782 #else
19783   return -99;
19784 #endif
19785 }
19786
19787 static void
19788 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
19789 {
19790   vat_main_t *vam = &vat_main;
19791   fib_prefix_t lcl, rmt;
19792
19793   ip_prefix_decode (&mp->lcl, &lcl);
19794   ip_prefix_decode (&mp->rmt, &rmt);
19795
19796   if (lcl.fp_proto == FIB_PROTOCOL_IP4)
19797     {
19798       print (vam->ofp,
19799              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19800              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19801              mp->scope, format_ip4_address, &lcl.fp_addr.ip4, lcl.fp_len,
19802              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
19803              &rmt.fp_addr.ip4, rmt.fp_len,
19804              clib_net_to_host_u16 (mp->rmt_port),
19805              clib_net_to_host_u32 (mp->action_index), mp->tag);
19806     }
19807   else
19808     {
19809       print (vam->ofp,
19810              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19811              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19812              mp->scope, format_ip6_address, &lcl.fp_addr.ip6, lcl.fp_len,
19813              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
19814              &rmt.fp_addr.ip6, rmt.fp_len,
19815              clib_net_to_host_u16 (mp->rmt_port),
19816              clib_net_to_host_u32 (mp->action_index), mp->tag);
19817     }
19818 }
19819
19820 static void
19821 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
19822                                              mp)
19823 {
19824   vat_main_t *vam = &vat_main;
19825   vat_json_node_t *node = NULL;
19826   struct in6_addr ip6;
19827   struct in_addr ip4;
19828
19829   fib_prefix_t lcl, rmt;
19830
19831   ip_prefix_decode (&mp->lcl, &lcl);
19832   ip_prefix_decode (&mp->rmt, &rmt);
19833
19834   if (VAT_JSON_ARRAY != vam->json_tree.type)
19835     {
19836       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19837       vat_json_init_array (&vam->json_tree);
19838     }
19839   node = vat_json_array_add (&vam->json_tree);
19840   vat_json_init_object (node);
19841
19842   vat_json_object_add_uint (node, "appns_index",
19843                             clib_net_to_host_u32 (mp->appns_index));
19844   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
19845   vat_json_object_add_uint (node, "scope", mp->scope);
19846   vat_json_object_add_uint (node, "action_index",
19847                             clib_net_to_host_u32 (mp->action_index));
19848   vat_json_object_add_uint (node, "lcl_port",
19849                             clib_net_to_host_u16 (mp->lcl_port));
19850   vat_json_object_add_uint (node, "rmt_port",
19851                             clib_net_to_host_u16 (mp->rmt_port));
19852   vat_json_object_add_uint (node, "lcl_plen", lcl.fp_len);
19853   vat_json_object_add_uint (node, "rmt_plen", rmt.fp_len);
19854   vat_json_object_add_string_copy (node, "tag", mp->tag);
19855   if (lcl.fp_proto == FIB_PROTOCOL_IP4)
19856     {
19857       clib_memcpy (&ip4, &lcl.fp_addr.ip4, sizeof (ip4));
19858       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
19859       clib_memcpy (&ip4, &rmt.fp_addr.ip4, sizeof (ip4));
19860       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
19861     }
19862   else
19863     {
19864       clib_memcpy (&ip6, &lcl.fp_addr.ip6, sizeof (ip6));
19865       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
19866       clib_memcpy (&ip6, &rmt.fp_addr.ip6, sizeof (ip6));
19867       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
19868     }
19869 }
19870
19871 static int
19872 api_session_rule_add_del (vat_main_t * vam)
19873 {
19874   vl_api_session_rule_add_del_t *mp;
19875   unformat_input_t *i = vam->input;
19876   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
19877   u32 appns_index = 0, scope = 0;
19878   ip4_address_t lcl_ip4, rmt_ip4;
19879   ip6_address_t lcl_ip6, rmt_ip6;
19880   u8 is_ip4 = 1, conn_set = 0;
19881   u8 is_add = 1, *tag = 0;
19882   int ret;
19883   fib_prefix_t lcl, rmt;
19884
19885   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19886     {
19887       if (unformat (i, "del"))
19888         is_add = 0;
19889       else if (unformat (i, "add"))
19890         ;
19891       else if (unformat (i, "proto tcp"))
19892         proto = 0;
19893       else if (unformat (i, "proto udp"))
19894         proto = 1;
19895       else if (unformat (i, "appns %d", &appns_index))
19896         ;
19897       else if (unformat (i, "scope %d", &scope))
19898         ;
19899       else if (unformat (i, "tag %_%v%_", &tag))
19900         ;
19901       else
19902         if (unformat
19903             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
19904              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
19905              &rmt_port))
19906         {
19907           is_ip4 = 1;
19908           conn_set = 1;
19909         }
19910       else
19911         if (unformat
19912             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
19913              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
19914              &rmt_port))
19915         {
19916           is_ip4 = 0;
19917           conn_set = 1;
19918         }
19919       else if (unformat (i, "action %d", &action))
19920         ;
19921       else
19922         break;
19923     }
19924   if (proto == ~0 || !conn_set || action == ~0)
19925     {
19926       errmsg ("transport proto, connection and action must be set");
19927       return -99;
19928     }
19929
19930   if (scope > 3)
19931     {
19932       errmsg ("scope should be 0-3");
19933       return -99;
19934     }
19935
19936   M (SESSION_RULE_ADD_DEL, mp);
19937
19938   clib_memset (&lcl, 0, sizeof (lcl));
19939   clib_memset (&rmt, 0, sizeof (rmt));
19940   if (is_ip4)
19941     {
19942       ip_set (&lcl.fp_addr, &lcl_ip4, 1);
19943       ip_set (&rmt.fp_addr, &rmt_ip4, 1);
19944       lcl.fp_len = lcl_plen;
19945       rmt.fp_len = rmt_plen;
19946     }
19947   else
19948     {
19949       ip_set (&lcl.fp_addr, &lcl_ip6, 0);
19950       ip_set (&rmt.fp_addr, &rmt_ip6, 0);
19951       lcl.fp_len = lcl_plen;
19952       rmt.fp_len = rmt_plen;
19953     }
19954
19955
19956   ip_prefix_encode (&lcl, &mp->lcl);
19957   ip_prefix_encode (&rmt, &mp->rmt);
19958   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
19959   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
19960   mp->transport_proto =
19961     proto ? TRANSPORT_PROTO_API_UDP : TRANSPORT_PROTO_API_TCP;
19962   mp->action_index = clib_host_to_net_u32 (action);
19963   mp->appns_index = clib_host_to_net_u32 (appns_index);
19964   mp->scope = scope;
19965   mp->is_add = is_add;
19966   if (tag)
19967     {
19968       clib_memcpy (mp->tag, tag, vec_len (tag));
19969       vec_free (tag);
19970     }
19971
19972   S (mp);
19973   W (ret);
19974   return ret;
19975 }
19976
19977 static int
19978 api_session_rules_dump (vat_main_t * vam)
19979 {
19980   vl_api_session_rules_dump_t *mp;
19981   vl_api_control_ping_t *mp_ping;
19982   int ret;
19983
19984   if (!vam->json_output)
19985     {
19986       print (vam->ofp, "%=20s", "Session Rules");
19987     }
19988
19989   M (SESSION_RULES_DUMP, mp);
19990   /* send it... */
19991   S (mp);
19992
19993   /* Use a control ping for synchronization */
19994   MPING (CONTROL_PING, mp_ping);
19995   S (mp_ping);
19996
19997   /* Wait for a reply... */
19998   W (ret);
19999   return ret;
20000 }
20001
20002 static int
20003 api_ip_container_proxy_add_del (vat_main_t * vam)
20004 {
20005   vl_api_ip_container_proxy_add_del_t *mp;
20006   unformat_input_t *i = vam->input;
20007   u32 sw_if_index = ~0;
20008   vl_api_prefix_t pfx = { };
20009   u8 is_add = 1;
20010   int ret;
20011
20012   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20013     {
20014       if (unformat (i, "del"))
20015         is_add = 0;
20016       else if (unformat (i, "add"))
20017         ;
20018       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
20019         ;
20020       else if (unformat (i, "sw_if_index %u", &sw_if_index))
20021         ;
20022       else
20023         break;
20024     }
20025   if (sw_if_index == ~0 || pfx.len == 0)
20026     {
20027       errmsg ("address and sw_if_index must be set");
20028       return -99;
20029     }
20030
20031   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
20032
20033   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20034   mp->is_add = is_add;
20035   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
20036
20037   S (mp);
20038   W (ret);
20039   return ret;
20040 }
20041
20042 static int
20043 api_qos_record_enable_disable (vat_main_t * vam)
20044 {
20045   unformat_input_t *i = vam->input;
20046   vl_api_qos_record_enable_disable_t *mp;
20047   u32 sw_if_index, qs = 0xff;
20048   u8 sw_if_index_set = 0;
20049   u8 enable = 1;
20050   int ret;
20051
20052   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20053     {
20054       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20055         sw_if_index_set = 1;
20056       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20057         sw_if_index_set = 1;
20058       else if (unformat (i, "%U", unformat_qos_source, &qs))
20059         ;
20060       else if (unformat (i, "disable"))
20061         enable = 0;
20062       else
20063         {
20064           clib_warning ("parse error '%U'", format_unformat_error, i);
20065           return -99;
20066         }
20067     }
20068
20069   if (sw_if_index_set == 0)
20070     {
20071       errmsg ("missing interface name or sw_if_index");
20072       return -99;
20073     }
20074   if (qs == 0xff)
20075     {
20076       errmsg ("input location must be specified");
20077       return -99;
20078     }
20079
20080   M (QOS_RECORD_ENABLE_DISABLE, mp);
20081
20082   mp->record.sw_if_index = ntohl (sw_if_index);
20083   mp->record.input_source = qs;
20084   mp->enable = enable;
20085
20086   S (mp);
20087   W (ret);
20088   return ret;
20089 }
20090
20091
20092 static int
20093 q_or_quit (vat_main_t * vam)
20094 {
20095 #if VPP_API_TEST_BUILTIN == 0
20096   longjmp (vam->jump_buf, 1);
20097 #endif
20098   return 0;                     /* not so much */
20099 }
20100
20101 static int
20102 q (vat_main_t * vam)
20103 {
20104   return q_or_quit (vam);
20105 }
20106
20107 static int
20108 quit (vat_main_t * vam)
20109 {
20110   return q_or_quit (vam);
20111 }
20112
20113 static int
20114 comment (vat_main_t * vam)
20115 {
20116   return 0;
20117 }
20118
20119 static int
20120 elog_save (vat_main_t * vam)
20121 {
20122 #if VPP_API_TEST_BUILTIN == 0
20123   elog_main_t *em = &vam->elog_main;
20124   unformat_input_t *i = vam->input;
20125   char *file, *chroot_file;
20126   clib_error_t *error;
20127
20128   if (!unformat (i, "%s", &file))
20129     {
20130       errmsg ("expected file name, got `%U'", format_unformat_error, i);
20131       return 0;
20132     }
20133
20134   /* It's fairly hard to get "../oopsie" through unformat; just in case */
20135   if (strstr (file, "..") || index (file, '/'))
20136     {
20137       errmsg ("illegal characters in filename '%s'", file);
20138       return 0;
20139     }
20140
20141   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
20142
20143   vec_free (file);
20144
20145   errmsg ("Saving %wd of %wd events to %s",
20146           elog_n_events_in_buffer (em),
20147           elog_buffer_capacity (em), chroot_file);
20148
20149   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
20150   vec_free (chroot_file);
20151
20152   if (error)
20153     clib_error_report (error);
20154 #else
20155   errmsg ("Use the vpp event loger...");
20156 #endif
20157
20158   return 0;
20159 }
20160
20161 static int
20162 elog_setup (vat_main_t * vam)
20163 {
20164 #if VPP_API_TEST_BUILTIN == 0
20165   elog_main_t *em = &vam->elog_main;
20166   unformat_input_t *i = vam->input;
20167   u32 nevents = 128 << 10;
20168
20169   (void) unformat (i, "nevents %d", &nevents);
20170
20171   elog_init (em, nevents);
20172   vl_api_set_elog_main (em);
20173   vl_api_set_elog_trace_api_messages (1);
20174   errmsg ("Event logger initialized with %u events", nevents);
20175 #else
20176   errmsg ("Use the vpp event loger...");
20177 #endif
20178   return 0;
20179 }
20180
20181 static int
20182 elog_enable (vat_main_t * vam)
20183 {
20184 #if VPP_API_TEST_BUILTIN == 0
20185   elog_main_t *em = &vam->elog_main;
20186
20187   elog_enable_disable (em, 1 /* enable */ );
20188   vl_api_set_elog_trace_api_messages (1);
20189   errmsg ("Event logger enabled...");
20190 #else
20191   errmsg ("Use the vpp event loger...");
20192 #endif
20193   return 0;
20194 }
20195
20196 static int
20197 elog_disable (vat_main_t * vam)
20198 {
20199 #if VPP_API_TEST_BUILTIN == 0
20200   elog_main_t *em = &vam->elog_main;
20201
20202   elog_enable_disable (em, 0 /* enable */ );
20203   vl_api_set_elog_trace_api_messages (1);
20204   errmsg ("Event logger disabled...");
20205 #else
20206   errmsg ("Use the vpp event loger...");
20207 #endif
20208   return 0;
20209 }
20210
20211 static int
20212 statseg (vat_main_t * vam)
20213 {
20214   ssvm_private_t *ssvmp = &vam->stat_segment;
20215   ssvm_shared_header_t *shared_header = ssvmp->sh;
20216   vlib_counter_t **counters;
20217   u64 thread0_index1_packets;
20218   u64 thread0_index1_bytes;
20219   f64 vector_rate, input_rate;
20220   uword *p;
20221
20222   uword *counter_vector_by_name;
20223   if (vam->stat_segment_lockp == 0)
20224     {
20225       errmsg ("Stat segment not mapped...");
20226       return -99;
20227     }
20228
20229   /* look up "/if/rx for sw_if_index 1 as a test */
20230
20231   clib_spinlock_lock (vam->stat_segment_lockp);
20232
20233   counter_vector_by_name = (uword *) shared_header->opaque[1];
20234
20235   p = hash_get_mem (counter_vector_by_name, "/if/rx");
20236   if (p == 0)
20237     {
20238       clib_spinlock_unlock (vam->stat_segment_lockp);
20239       errmsg ("/if/tx not found?");
20240       return -99;
20241     }
20242
20243   /* Fish per-thread vector of combined counters from shared memory */
20244   counters = (vlib_counter_t **) p[0];
20245
20246   if (vec_len (counters[0]) < 2)
20247     {
20248       clib_spinlock_unlock (vam->stat_segment_lockp);
20249       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
20250       return -99;
20251     }
20252
20253   /* Read thread 0 sw_if_index 1 counter */
20254   thread0_index1_packets = counters[0][1].packets;
20255   thread0_index1_bytes = counters[0][1].bytes;
20256
20257   p = hash_get_mem (counter_vector_by_name, "vector_rate");
20258   if (p == 0)
20259     {
20260       clib_spinlock_unlock (vam->stat_segment_lockp);
20261       errmsg ("vector_rate not found?");
20262       return -99;
20263     }
20264
20265   vector_rate = *(f64 *) (p[0]);
20266   p = hash_get_mem (counter_vector_by_name, "input_rate");
20267   if (p == 0)
20268     {
20269       clib_spinlock_unlock (vam->stat_segment_lockp);
20270       errmsg ("input_rate not found?");
20271       return -99;
20272     }
20273   input_rate = *(f64 *) (p[0]);
20274
20275   clib_spinlock_unlock (vam->stat_segment_lockp);
20276
20277   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
20278          vector_rate, input_rate);
20279   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
20280          thread0_index1_packets, thread0_index1_bytes);
20281
20282   return 0;
20283 }
20284
20285 static int
20286 cmd_cmp (void *a1, void *a2)
20287 {
20288   u8 **c1 = a1;
20289   u8 **c2 = a2;
20290
20291   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
20292 }
20293
20294 static int
20295 help (vat_main_t * vam)
20296 {
20297   u8 **cmds = 0;
20298   u8 *name = 0;
20299   hash_pair_t *p;
20300   unformat_input_t *i = vam->input;
20301   int j;
20302
20303   if (unformat (i, "%s", &name))
20304     {
20305       uword *hs;
20306
20307       vec_add1 (name, 0);
20308
20309       hs = hash_get_mem (vam->help_by_name, name);
20310       if (hs)
20311         print (vam->ofp, "usage: %s %s", name, hs[0]);
20312       else
20313         print (vam->ofp, "No such msg / command '%s'", name);
20314       vec_free (name);
20315       return 0;
20316     }
20317
20318   print (vam->ofp, "Help is available for the following:");
20319
20320     /* *INDENT-OFF* */
20321     hash_foreach_pair (p, vam->function_by_name,
20322     ({
20323       vec_add1 (cmds, (u8 *)(p->key));
20324     }));
20325     /* *INDENT-ON* */
20326
20327   vec_sort_with_function (cmds, cmd_cmp);
20328
20329   for (j = 0; j < vec_len (cmds); j++)
20330     print (vam->ofp, "%s", cmds[j]);
20331
20332   vec_free (cmds);
20333   return 0;
20334 }
20335
20336 static int
20337 set (vat_main_t * vam)
20338 {
20339   u8 *name = 0, *value = 0;
20340   unformat_input_t *i = vam->input;
20341
20342   if (unformat (i, "%s", &name))
20343     {
20344       /* The input buffer is a vector, not a string. */
20345       value = vec_dup (i->buffer);
20346       vec_delete (value, i->index, 0);
20347       /* Almost certainly has a trailing newline */
20348       if (value[vec_len (value) - 1] == '\n')
20349         value[vec_len (value) - 1] = 0;
20350       /* Make sure it's a proper string, one way or the other */
20351       vec_add1 (value, 0);
20352       (void) clib_macro_set_value (&vam->macro_main,
20353                                    (char *) name, (char *) value);
20354     }
20355   else
20356     errmsg ("usage: set <name> <value>");
20357
20358   vec_free (name);
20359   vec_free (value);
20360   return 0;
20361 }
20362
20363 static int
20364 unset (vat_main_t * vam)
20365 {
20366   u8 *name = 0;
20367
20368   if (unformat (vam->input, "%s", &name))
20369     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
20370       errmsg ("unset: %s wasn't set", name);
20371   vec_free (name);
20372   return 0;
20373 }
20374
20375 typedef struct
20376 {
20377   u8 *name;
20378   u8 *value;
20379 } macro_sort_t;
20380
20381
20382 static int
20383 macro_sort_cmp (void *a1, void *a2)
20384 {
20385   macro_sort_t *s1 = a1;
20386   macro_sort_t *s2 = a2;
20387
20388   return strcmp ((char *) (s1->name), (char *) (s2->name));
20389 }
20390
20391 static int
20392 dump_macro_table (vat_main_t * vam)
20393 {
20394   macro_sort_t *sort_me = 0, *sm;
20395   int i;
20396   hash_pair_t *p;
20397
20398     /* *INDENT-OFF* */
20399     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
20400     ({
20401       vec_add2 (sort_me, sm, 1);
20402       sm->name = (u8 *)(p->key);
20403       sm->value = (u8 *) (p->value[0]);
20404     }));
20405     /* *INDENT-ON* */
20406
20407   vec_sort_with_function (sort_me, macro_sort_cmp);
20408
20409   if (vec_len (sort_me))
20410     print (vam->ofp, "%-15s%s", "Name", "Value");
20411   else
20412     print (vam->ofp, "The macro table is empty...");
20413
20414   for (i = 0; i < vec_len (sort_me); i++)
20415     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
20416   return 0;
20417 }
20418
20419 static int
20420 dump_node_table (vat_main_t * vam)
20421 {
20422   int i, j;
20423   vlib_node_t *node, *next_node;
20424
20425   if (vec_len (vam->graph_nodes) == 0)
20426     {
20427       print (vam->ofp, "Node table empty, issue get_node_graph...");
20428       return 0;
20429     }
20430
20431   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
20432     {
20433       node = vam->graph_nodes[0][i];
20434       print (vam->ofp, "[%d] %s", i, node->name);
20435       for (j = 0; j < vec_len (node->next_nodes); j++)
20436         {
20437           if (node->next_nodes[j] != ~0)
20438             {
20439               next_node = vam->graph_nodes[0][node->next_nodes[j]];
20440               print (vam->ofp, "  [%d] %s", j, next_node->name);
20441             }
20442         }
20443     }
20444   return 0;
20445 }
20446
20447 static int
20448 value_sort_cmp (void *a1, void *a2)
20449 {
20450   name_sort_t *n1 = a1;
20451   name_sort_t *n2 = a2;
20452
20453   if (n1->value < n2->value)
20454     return -1;
20455   if (n1->value > n2->value)
20456     return 1;
20457   return 0;
20458 }
20459
20460
20461 static int
20462 dump_msg_api_table (vat_main_t * vam)
20463 {
20464   api_main_t *am = vlibapi_get_main ();
20465   name_sort_t *nses = 0, *ns;
20466   hash_pair_t *hp;
20467   int i;
20468
20469   /* *INDENT-OFF* */
20470   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
20471   ({
20472     vec_add2 (nses, ns, 1);
20473     ns->name = (u8 *)(hp->key);
20474     ns->value = (u32) hp->value[0];
20475   }));
20476   /* *INDENT-ON* */
20477
20478   vec_sort_with_function (nses, value_sort_cmp);
20479
20480   for (i = 0; i < vec_len (nses); i++)
20481     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
20482   vec_free (nses);
20483   return 0;
20484 }
20485
20486 static int
20487 get_msg_id (vat_main_t * vam)
20488 {
20489   u8 *name_and_crc;
20490   u32 message_index;
20491
20492   if (unformat (vam->input, "%s", &name_and_crc))
20493     {
20494       message_index = vl_msg_api_get_msg_index (name_and_crc);
20495       if (message_index == ~0)
20496         {
20497           print (vam->ofp, " '%s' not found", name_and_crc);
20498           return 0;
20499         }
20500       print (vam->ofp, " '%s' has message index %d",
20501              name_and_crc, message_index);
20502       return 0;
20503     }
20504   errmsg ("name_and_crc required...");
20505   return 0;
20506 }
20507
20508 static int
20509 search_node_table (vat_main_t * vam)
20510 {
20511   unformat_input_t *line_input = vam->input;
20512   u8 *node_to_find;
20513   int j;
20514   vlib_node_t *node, *next_node;
20515   uword *p;
20516
20517   if (vam->graph_node_index_by_name == 0)
20518     {
20519       print (vam->ofp, "Node table empty, issue get_node_graph...");
20520       return 0;
20521     }
20522
20523   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20524     {
20525       if (unformat (line_input, "%s", &node_to_find))
20526         {
20527           vec_add1 (node_to_find, 0);
20528           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
20529           if (p == 0)
20530             {
20531               print (vam->ofp, "%s not found...", node_to_find);
20532               goto out;
20533             }
20534           node = vam->graph_nodes[0][p[0]];
20535           print (vam->ofp, "[%d] %s", p[0], node->name);
20536           for (j = 0; j < vec_len (node->next_nodes); j++)
20537             {
20538               if (node->next_nodes[j] != ~0)
20539                 {
20540                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
20541                   print (vam->ofp, "  [%d] %s", j, next_node->name);
20542                 }
20543             }
20544         }
20545
20546       else
20547         {
20548           clib_warning ("parse error '%U'", format_unformat_error,
20549                         line_input);
20550           return -99;
20551         }
20552
20553     out:
20554       vec_free (node_to_find);
20555
20556     }
20557
20558   return 0;
20559 }
20560
20561
20562 static int
20563 script (vat_main_t * vam)
20564 {
20565 #if (VPP_API_TEST_BUILTIN==0)
20566   u8 *s = 0;
20567   char *save_current_file;
20568   unformat_input_t save_input;
20569   jmp_buf save_jump_buf;
20570   u32 save_line_number;
20571
20572   FILE *new_fp, *save_ifp;
20573
20574   if (unformat (vam->input, "%s", &s))
20575     {
20576       new_fp = fopen ((char *) s, "r");
20577       if (new_fp == 0)
20578         {
20579           errmsg ("Couldn't open script file %s", s);
20580           vec_free (s);
20581           return -99;
20582         }
20583     }
20584   else
20585     {
20586       errmsg ("Missing script name");
20587       return -99;
20588     }
20589
20590   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
20591   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
20592   save_ifp = vam->ifp;
20593   save_line_number = vam->input_line_number;
20594   save_current_file = (char *) vam->current_file;
20595
20596   vam->input_line_number = 0;
20597   vam->ifp = new_fp;
20598   vam->current_file = s;
20599   do_one_file (vam);
20600
20601   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
20602   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
20603   vam->ifp = save_ifp;
20604   vam->input_line_number = save_line_number;
20605   vam->current_file = (u8 *) save_current_file;
20606   vec_free (s);
20607
20608   return 0;
20609 #else
20610   clib_warning ("use the exec command...");
20611   return -99;
20612 #endif
20613 }
20614
20615 static int
20616 echo (vat_main_t * vam)
20617 {
20618   print (vam->ofp, "%v", vam->input->buffer);
20619   return 0;
20620 }
20621
20622 /* List of API message constructors, CLI names map to api_xxx */
20623 #define foreach_vpe_api_msg                                             \
20624 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
20625 _(sw_interface_dump,"")                                                 \
20626 _(sw_interface_set_flags,                                               \
20627   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
20628 _(sw_interface_add_del_address,                                         \
20629   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
20630 _(sw_interface_set_rx_mode,                                             \
20631   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
20632 _(sw_interface_set_rx_placement,                                        \
20633   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
20634 _(sw_interface_rx_placement_dump,                                       \
20635   "[<intfc> | sw_if_index <id>]")                                         \
20636 _(sw_interface_set_table,                                               \
20637   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
20638 _(sw_interface_set_mpls_enable,                                         \
20639   "<intfc> | sw_if_index [disable | dis]")                              \
20640 _(sw_interface_set_vpath,                                               \
20641   "<intfc> | sw_if_index <id> enable | disable")                        \
20642 _(sw_interface_set_vxlan_bypass,                                        \
20643   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20644 _(sw_interface_set_geneve_bypass,                                       \
20645   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20646 _(sw_interface_set_l2_xconnect,                                         \
20647   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20648   "enable | disable")                                                   \
20649 _(sw_interface_set_l2_bridge,                                           \
20650   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
20651   "[shg <split-horizon-group>] [bvi]\n"                                 \
20652   "enable | disable")                                                   \
20653 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
20654 _(bridge_domain_add_del,                                                \
20655   "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") \
20656 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
20657 _(l2fib_add_del,                                                        \
20658   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
20659 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
20660 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
20661 _(l2_flags,                                                             \
20662   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20663 _(bridge_flags,                                                         \
20664   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20665 _(tap_create_v2,                                                        \
20666   "id <num> [hw-addr <mac-addr>] [host-if-name <name>] [host-ns <name>] [num-rx-queues <num>] [rx-ring-size <num>] [tx-ring-size <num>] [host-bridge <name>] [host-mac-addr <mac-addr>] [host-ip4-addr <ip4addr/mask>] [host-ip6-addr <ip6addr/mask>] [host-mtu-size <mtu>] [gso | no-gso | csum-offload | gro-coalesce] [persist] [attach] [tun] [packed] [in-order]") \
20667 _(tap_delete_v2,                                                        \
20668   "<vpp-if-name> | sw_if_index <id>")                                   \
20669 _(sw_interface_tap_v2_dump, "")                                         \
20670 _(virtio_pci_create,                                                    \
20671   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled | csum-offload-enabled]") \
20672 _(virtio_pci_delete,                                                    \
20673   "<vpp-if-name> | sw_if_index <id>")                                   \
20674 _(sw_interface_virtio_pci_dump, "")                                     \
20675 _(bond_create,                                                          \
20676   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
20677   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
20678   "[id <if-id>]")                                                       \
20679 _(bond_delete,                                                          \
20680   "<vpp-if-name> | sw_if_index <id>")                                   \
20681 _(bond_add_member,                                                      \
20682   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
20683 _(bond_detach_member,                                                   \
20684   "sw_if_index <n>")                                                    \
20685  _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
20686  _(sw_bond_interface_dump, "<intfc> | sw_if_index <nn>")                \
20687  _(sw_member_interface_dump,                                            \
20688   "<vpp-if-name> | sw_if_index <id>")                                   \
20689 _(ip_table_add_del,                                                     \
20690   "table <n> [ipv6] [add | del]\n")                                     \
20691 _(ip_route_add_del,                                                     \
20692   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
20693   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
20694   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
20695   "[multipath] [count <n>] [del]")                                      \
20696 _(ip_mroute_add_del,                                                    \
20697   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
20698   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
20699 _(mpls_table_add_del,                                                   \
20700   "table <n> [add | del]\n")                                            \
20701 _(mpls_route_add_del,                                                   \
20702   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
20703   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
20704   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
20705   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
20706   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
20707   "[count <n>] [del]")                                                  \
20708 _(mpls_ip_bind_unbind,                                                  \
20709   "<label> <addr/len>")                                                 \
20710 _(mpls_tunnel_add_del,                                                  \
20711   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
20712   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
20713   "[l2-only]  [out-label <n>]")                                         \
20714 _(sr_mpls_policy_add,                                                   \
20715   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
20716 _(sr_mpls_policy_del,                                                   \
20717   "bsid <id>")                                                          \
20718 _(bier_table_add_del,                                                   \
20719   "<label> <sub-domain> <set> <bsl> [del]")                             \
20720 _(bier_route_add_del,                                                   \
20721   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
20722   "[<intfc> | sw_if_index <id>]"                                        \
20723   "[weight <n>] [del] [multipath]")                                     \
20724 _(sw_interface_set_unnumbered,                                          \
20725   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
20726 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
20727 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
20728   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
20729   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
20730   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
20731 _(ip_table_replace_begin, "table <n> [ipv6]")                           \
20732 _(ip_table_flush, "table <n> [ipv6]")                                   \
20733 _(ip_table_replace_end, "table <n> [ipv6]")                             \
20734 _(set_ip_flow_hash,                                                     \
20735   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
20736 _(sw_interface_ip6_enable_disable,                                      \
20737   "<intfc> | sw_if_index <id> enable | disable")                        \
20738 _(l2_patch_add_del,                                                     \
20739   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20740   "enable | disable")                                                   \
20741 _(sr_localsid_add_del,                                                  \
20742   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
20743   "fib-table <num> (end.psp) sw_if_index <num>")                        \
20744 _(classify_add_del_table,                                               \
20745   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
20746   " [del] [del-chain] mask <mask-value>\n"                              \
20747   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
20748   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
20749 _(classify_add_del_session,                                             \
20750   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
20751   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
20752   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
20753   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
20754 _(classify_set_interface_ip_table,                                      \
20755   "<intfc> | sw_if_index <nn> table <nn>")                              \
20756 _(classify_set_interface_l2_tables,                                     \
20757   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20758   "  [other-table <nn>]")                                               \
20759 _(get_node_index, "node <node-name")                                    \
20760 _(add_node_next, "node <node-name> next <next-node-name>")              \
20761 _(l2tpv3_create_tunnel,                                                 \
20762   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
20763   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
20764   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
20765 _(l2tpv3_set_tunnel_cookies,                                            \
20766   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
20767   "[new_remote_cookie <nn>]\n")                                         \
20768 _(l2tpv3_interface_enable_disable,                                      \
20769   "<intfc> | sw_if_index <nn> enable | disable")                        \
20770 _(l2tpv3_set_lookup_key,                                                \
20771   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
20772 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
20773 _(vxlan_offload_rx,                                                     \
20774   "hw { <interface name> | hw_if_index <nn>} "                          \
20775   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
20776 _(vxlan_add_del_tunnel,                                                 \
20777   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20778   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
20779   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20780 _(geneve_add_del_tunnel,                                                \
20781   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20782   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20783   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20784 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
20785 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
20786 _(gre_tunnel_add_del,                                                   \
20787   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
20788   "[teb | erspan <session-id>] [del]")                                  \
20789 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
20790 _(l2_fib_clear_table, "")                                               \
20791 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
20792 _(l2_interface_vlan_tag_rewrite,                                        \
20793   "<intfc> | sw_if_index <nn> \n"                                       \
20794   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
20795   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
20796 _(create_vhost_user_if,                                                 \
20797         "socket <filename> [server] [renumber <dev_instance>] "         \
20798         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
20799         "[mac <mac_address>] [packed]")                                 \
20800 _(modify_vhost_user_if,                                                 \
20801         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
20802         "[server] [renumber <dev_instance>] [gso] [packed]")            \
20803 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
20804 _(sw_interface_vhost_user_dump, "<intfc> | sw_if_index <nn>")           \
20805 _(show_version, "")                                                     \
20806 _(show_threads, "")                                                     \
20807 _(vxlan_gpe_add_del_tunnel,                                             \
20808   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
20809   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20810   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
20811   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
20812 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
20813 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
20814 _(interface_name_renumber,                                              \
20815   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
20816 _(input_acl_set_interface,                                              \
20817   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20818   "  [l2-table <nn>] [del]")                                            \
20819 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
20820 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
20821 _(ip_dump, "ipv4 | ipv6")                                               \
20822 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
20823 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
20824   "  spid_id <n> ")                                                     \
20825 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
20826   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
20827   "  integ_alg <alg> integ_key <hex>")                                  \
20828 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
20829   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
20830   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
20831   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
20832 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
20833   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
20834   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
20835   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
20836   "  [instance <n>]")     \
20837 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
20838 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
20839 _(delete_loopback,"sw_if_index <nn>")                                   \
20840 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
20841 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
20842 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
20843 _(want_interface_events,  "enable|disable")                             \
20844 _(get_first_msg_id, "client <name>")                                    \
20845 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
20846 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
20847   "fib-id <nn> [ip4][ip6][default]")                                    \
20848 _(get_node_graph, " ")                                                  \
20849 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
20850 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
20851 _(ioam_disable, "")                                                     \
20852 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
20853                             " sw_if_index <sw_if_index> p <priority> "  \
20854                             "w <weight>] [del]")                        \
20855 _(one_add_del_locator, "locator-set <locator_name> "                    \
20856                         "iface <intf> | sw_if_index <sw_if_index> "     \
20857                         "p <priority> w <weight> [del]")                \
20858 _(one_add_del_local_eid,"vni <vni> eid "                                \
20859                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20860                          "locator-set <locator_name> [del]"             \
20861                          "[key-id sha1|sha256 secret-key <secret-key>]")\
20862 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
20863 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
20864 _(one_enable_disable, "enable|disable")                                 \
20865 _(one_map_register_enable_disable, "enable|disable")                    \
20866 _(one_map_register_fallback_threshold, "<value>")                       \
20867 _(one_rloc_probe_enable_disable, "enable|disable")                      \
20868 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
20869                                "[seid <seid>] "                         \
20870                                "rloc <locator> p <prio> "               \
20871                                "w <weight> [rloc <loc> ... ] "          \
20872                                "action <action> [del-all]")             \
20873 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
20874                           "<local-eid>")                                \
20875 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
20876 _(one_use_petr, "ip-address> | disable")                                \
20877 _(one_map_request_mode, "src-dst|dst-only")                             \
20878 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
20879 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
20880 _(one_locator_set_dump, "[local | remote]")                             \
20881 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
20882 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
20883                        "[local] | [remote]")                            \
20884 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
20885 _(one_ndp_bd_get, "")                                                   \
20886 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
20887 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
20888 _(one_l2_arp_bd_get, "")                                                \
20889 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
20890 _(one_stats_enable_disable, "enable|disable")                           \
20891 _(show_one_stats_enable_disable, "")                                    \
20892 _(one_eid_table_vni_dump, "")                                           \
20893 _(one_eid_table_map_dump, "l2|l3")                                      \
20894 _(one_map_resolver_dump, "")                                            \
20895 _(one_map_server_dump, "")                                              \
20896 _(one_adjacencies_get, "vni <vni>")                                     \
20897 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
20898 _(show_one_rloc_probe_state, "")                                        \
20899 _(show_one_map_register_state, "")                                      \
20900 _(show_one_status, "")                                                  \
20901 _(one_stats_dump, "")                                                   \
20902 _(one_stats_flush, "")                                                  \
20903 _(one_get_map_request_itr_rlocs, "")                                    \
20904 _(one_map_register_set_ttl, "<ttl>")                                    \
20905 _(one_set_transport_protocol, "udp|api")                                \
20906 _(one_get_transport_protocol, "")                                       \
20907 _(one_enable_disable_xtr_mode, "enable|disable")                        \
20908 _(one_show_xtr_mode, "")                                                \
20909 _(one_enable_disable_pitr_mode, "enable|disable")                       \
20910 _(one_show_pitr_mode, "")                                               \
20911 _(one_enable_disable_petr_mode, "enable|disable")                       \
20912 _(one_show_petr_mode, "")                                               \
20913 _(show_one_nsh_mapping, "")                                             \
20914 _(show_one_pitr, "")                                                    \
20915 _(show_one_use_petr, "")                                                \
20916 _(show_one_map_request_mode, "")                                        \
20917 _(show_one_map_register_ttl, "")                                        \
20918 _(show_one_map_register_fallback_threshold, "")                         \
20919 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
20920                             " sw_if_index <sw_if_index> p <priority> "  \
20921                             "w <weight>] [del]")                        \
20922 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
20923                         "iface <intf> | sw_if_index <sw_if_index> "     \
20924                         "p <priority> w <weight> [del]")                \
20925 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
20926                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20927                          "locator-set <locator_name> [del]"             \
20928                          "[key-id sha1|sha256 secret-key <secret-key>]") \
20929 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
20930 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
20931 _(lisp_enable_disable, "enable|disable")                                \
20932 _(lisp_map_register_enable_disable, "enable|disable")                   \
20933 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
20934 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
20935                                "[seid <seid>] "                         \
20936                                "rloc <locator> p <prio> "               \
20937                                "w <weight> [rloc <loc> ... ] "          \
20938                                "action <action> [del-all]")             \
20939 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
20940                           "<local-eid>")                                \
20941 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
20942 _(lisp_use_petr, "<ip-address> | disable")                              \
20943 _(lisp_map_request_mode, "src-dst|dst-only")                            \
20944 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
20945 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
20946 _(lisp_locator_set_dump, "[local | remote]")                            \
20947 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
20948 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
20949                        "[local] | [remote]")                            \
20950 _(lisp_eid_table_vni_dump, "")                                          \
20951 _(lisp_eid_table_map_dump, "l2|l3")                                     \
20952 _(lisp_map_resolver_dump, "")                                           \
20953 _(lisp_map_server_dump, "")                                             \
20954 _(lisp_adjacencies_get, "vni <vni>")                                    \
20955 _(gpe_fwd_entry_vnis_get, "")                                           \
20956 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
20957 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
20958                                 "[table <table-id>]")                   \
20959 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
20960 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
20961 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
20962 _(gpe_get_encap_mode, "")                                               \
20963 _(lisp_gpe_add_del_iface, "up|down")                                    \
20964 _(lisp_gpe_enable_disable, "enable|disable")                            \
20965 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
20966   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
20967 _(show_lisp_rloc_probe_state, "")                                       \
20968 _(show_lisp_map_register_state, "")                                     \
20969 _(show_lisp_status, "")                                                 \
20970 _(lisp_get_map_request_itr_rlocs, "")                                   \
20971 _(show_lisp_pitr, "")                                                   \
20972 _(show_lisp_use_petr, "")                                               \
20973 _(show_lisp_map_request_mode, "")                                       \
20974 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
20975 _(af_packet_delete, "name <host interface name>")                       \
20976 _(af_packet_dump, "")                                                   \
20977 _(policer_add_del, "name <policer name> <params> [del]")                \
20978 _(policer_dump, "[name <policer name>]")                                \
20979 _(policer_classify_set_interface,                                       \
20980   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20981   "  [l2-table <nn>] [del]")                                            \
20982 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
20983 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
20984 _(mpls_table_dump, "")                                                  \
20985 _(mpls_route_dump, "table-id <ID>")                                     \
20986 _(classify_table_ids, "")                                               \
20987 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
20988 _(classify_table_info, "table_id <nn>")                                 \
20989 _(classify_session_dump, "table_id <nn>")                               \
20990 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
20991     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
20992     "[template_interval <nn>] [udp_checksum]")                          \
20993 _(ipfix_exporter_dump, "")                                              \
20994 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
20995 _(ipfix_classify_stream_dump, "")                                       \
20996 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
20997 _(ipfix_classify_table_dump, "")                                        \
20998 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
20999 _(sw_interface_span_dump, "[l2]")                                           \
21000 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
21001 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
21002 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
21003 _(pg_enable_disable, "[stream <id>] disable")                           \
21004 _(pg_interface_enable_disable_coalesce, "<intf> | sw_if_index <nn> enable | disable")  \
21005 _(ip_source_and_port_range_check_add_del,                               \
21006   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
21007 _(ip_source_and_port_range_check_interface_add_del,                     \
21008   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
21009   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
21010 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
21011 _(l2_interface_pbb_tag_rewrite,                                         \
21012   "<intfc> | sw_if_index <nn> \n"                                       \
21013   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
21014   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
21015 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
21016 _(flow_classify_set_interface,                                          \
21017   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
21018 _(flow_classify_dump, "type [ip4|ip6]")                                 \
21019 _(ip_table_dump, "")                                                    \
21020 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
21021 _(ip_mtable_dump, "")                                                   \
21022 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
21023 _(feature_enable_disable, "arc_name <arc_name> "                        \
21024   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
21025 _(feature_gso_enable_disable, "<intfc> | sw_if_index <nn> "             \
21026   "[enable | disable] ")                                                \
21027 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
21028 "[disable]")                                                            \
21029 _(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> "       \
21030   "mac <mac-address> [del]")                                            \
21031 _(l2_xconnect_dump, "")                                                 \
21032 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
21033 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
21034 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
21035 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
21036 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
21037 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
21038   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
21039 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
21040 _(sock_init_shm, "size <nnn>")                                          \
21041 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
21042 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
21043   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
21044 _(session_rules_dump, "")                                               \
21045 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
21046 _(output_acl_set_interface,                                             \
21047   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21048   "  [l2-table <nn>] [del]")                                            \
21049 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
21050
21051 /* List of command functions, CLI names map directly to functions */
21052 #define foreach_cli_function                                    \
21053 _(comment, "usage: comment <ignore-rest-of-line>")              \
21054 _(dump_interface_table, "usage: dump_interface_table")          \
21055 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
21056 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
21057 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
21058 _(dump_macro_table, "usage: dump_macro_table ")                 \
21059 _(dump_node_table, "usage: dump_node_table")                    \
21060 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
21061 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
21062 _(elog_disable, "usage: elog_disable")                          \
21063 _(elog_enable, "usage: elog_enable")                            \
21064 _(elog_save, "usage: elog_save <filename>")                     \
21065 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
21066 _(echo, "usage: echo <message>")                                \
21067 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
21068 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
21069 _(help, "usage: help")                                          \
21070 _(q, "usage: quit")                                             \
21071 _(quit, "usage: quit")                                          \
21072 _(search_node_table, "usage: search_node_table <name>...")      \
21073 _(set, "usage: set <variable-name> <value>")                    \
21074 _(script, "usage: script <file-name>")                          \
21075 _(statseg, "usage: statseg")                                    \
21076 _(unset, "usage: unset <variable-name>")
21077
21078 #define _(N,n)                                  \
21079     static void vl_api_##n##_t_handler_uni      \
21080     (vl_api_##n##_t * mp)                       \
21081     {                                           \
21082         vat_main_t * vam = &vat_main;           \
21083         if (vam->json_output) {                 \
21084             vl_api_##n##_t_handler_json(mp);    \
21085         } else {                                \
21086             vl_api_##n##_t_handler(mp);         \
21087         }                                       \
21088     }
21089 foreach_vpe_api_reply_msg;
21090 #if VPP_API_TEST_BUILTIN == 0
21091 foreach_standalone_reply_msg;
21092 #endif
21093 #undef _
21094
21095 void
21096 vat_api_hookup (vat_main_t * vam)
21097 {
21098 #define _(N,n)                                                  \
21099     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
21100                            vl_api_##n##_t_handler_uni,          \
21101                            vl_noop_handler,                     \
21102                            vl_api_##n##_t_endian,               \
21103                            vl_api_##n##_t_print,                \
21104                            sizeof(vl_api_##n##_t), 1);
21105   foreach_vpe_api_reply_msg;
21106 #if VPP_API_TEST_BUILTIN == 0
21107   foreach_standalone_reply_msg;
21108 #endif
21109 #undef _
21110
21111 #if (VPP_API_TEST_BUILTIN==0)
21112   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
21113
21114   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
21115
21116   vam->function_by_name = hash_create_string (0, sizeof (uword));
21117
21118   vam->help_by_name = hash_create_string (0, sizeof (uword));
21119 #endif
21120
21121   /* API messages we can send */
21122 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
21123   foreach_vpe_api_msg;
21124 #undef _
21125
21126   /* Help strings */
21127 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21128   foreach_vpe_api_msg;
21129 #undef _
21130
21131   /* CLI functions */
21132 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
21133   foreach_cli_function;
21134 #undef _
21135
21136   /* Help strings */
21137 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21138   foreach_cli_function;
21139 #undef _
21140 }
21141
21142 #if VPP_API_TEST_BUILTIN
21143 static clib_error_t *
21144 vat_api_hookup_shim (vlib_main_t * vm)
21145 {
21146   vat_api_hookup (&vat_main);
21147   return 0;
21148 }
21149
21150 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
21151 #endif
21152
21153 /*
21154  * fd.io coding-style-patch-verification: ON
21155  *
21156  * Local Variables:
21157  * eval: (c-set-style "gnu")
21158  * End:
21159  */