virtio: add virtio 1.1 api flags
[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_create_v2_reply_t_handler
1833   (vl_api_virtio_pci_create_v2_reply_t * 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->sw_if_index = ntohl (mp->sw_if_index);
1845       vam->result_ready = 1;
1846     }
1847 }
1848
1849 static void vl_api_virtio_pci_create_v2_reply_t_handler_json
1850   (vl_api_virtio_pci_create_v2_reply_t * mp)
1851 {
1852   vat_main_t *vam = &vat_main;
1853   vat_json_node_t node;
1854
1855   vat_json_init_object (&node);
1856   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1857   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1858
1859   vat_json_print (vam->ofp, &node);
1860   vat_json_free (&node);
1861
1862   vam->retval = ntohl (mp->retval);
1863   vam->result_ready = 1;
1864 }
1865
1866 static void
1867 vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1868                                           mp)
1869 {
1870   vat_main_t *vam = &vat_main;
1871   i32 retval = ntohl (mp->retval);
1872   if (vam->async_mode)
1873     {
1874       vam->async_errors += (retval < 0);
1875     }
1876   else
1877     {
1878       vam->retval = retval;
1879       vam->result_ready = 1;
1880     }
1881 }
1882
1883 static void vl_api_virtio_pci_delete_reply_t_handler_json
1884   (vl_api_virtio_pci_delete_reply_t * mp)
1885 {
1886   vat_main_t *vam = &vat_main;
1887   vat_json_node_t node;
1888
1889   vat_json_init_object (&node);
1890   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
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_create_reply_t_handler (vl_api_bond_create_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->sw_if_index = ntohl (mp->sw_if_index);
1913       vam->result_ready = 1;
1914     }
1915 }
1916
1917 static void vl_api_bond_create_reply_t_handler_json
1918   (vl_api_bond_create_reply_t * mp)
1919 {
1920   vat_main_t *vam = &vat_main;
1921   vat_json_node_t node;
1922
1923   vat_json_init_object (&node);
1924   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1925   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1926
1927   vat_json_print (vam->ofp, &node);
1928   vat_json_free (&node);
1929
1930   vam->retval = ntohl (mp->retval);
1931   vam->result_ready = 1;
1932 }
1933
1934 static void
1935 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1936 {
1937   vat_main_t *vam = &vat_main;
1938   i32 retval = ntohl (mp->retval);
1939
1940   if (vam->async_mode)
1941     {
1942       vam->async_errors += (retval < 0);
1943     }
1944   else
1945     {
1946       vam->retval = retval;
1947       vam->result_ready = 1;
1948     }
1949 }
1950
1951 static void vl_api_bond_delete_reply_t_handler_json
1952   (vl_api_bond_delete_reply_t * mp)
1953 {
1954   vat_main_t *vam = &vat_main;
1955   vat_json_node_t node;
1956
1957   vat_json_init_object (&node);
1958   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1959
1960   vat_json_print (vam->ofp, &node);
1961   vat_json_free (&node);
1962
1963   vam->retval = ntohl (mp->retval);
1964   vam->result_ready = 1;
1965 }
1966
1967 static void
1968 vl_api_bond_add_member_reply_t_handler (vl_api_bond_add_member_reply_t * mp)
1969 {
1970   vat_main_t *vam = &vat_main;
1971   i32 retval = ntohl (mp->retval);
1972
1973   if (vam->async_mode)
1974     {
1975       vam->async_errors += (retval < 0);
1976     }
1977   else
1978     {
1979       vam->retval = retval;
1980       vam->result_ready = 1;
1981     }
1982 }
1983
1984 static void vl_api_bond_add_member_reply_t_handler_json
1985   (vl_api_bond_add_member_reply_t * mp)
1986 {
1987   vat_main_t *vam = &vat_main;
1988   vat_json_node_t node;
1989
1990   vat_json_init_object (&node);
1991   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1992
1993   vat_json_print (vam->ofp, &node);
1994   vat_json_free (&node);
1995
1996   vam->retval = ntohl (mp->retval);
1997   vam->result_ready = 1;
1998 }
1999
2000 static void
2001 vl_api_bond_detach_member_reply_t_handler (vl_api_bond_detach_member_reply_t *
2002                                            mp)
2003 {
2004   vat_main_t *vam = &vat_main;
2005   i32 retval = ntohl (mp->retval);
2006
2007   if (vam->async_mode)
2008     {
2009       vam->async_errors += (retval < 0);
2010     }
2011   else
2012     {
2013       vam->retval = retval;
2014       vam->result_ready = 1;
2015     }
2016 }
2017
2018 static void vl_api_bond_detach_member_reply_t_handler_json
2019   (vl_api_bond_detach_member_reply_t * mp)
2020 {
2021   vat_main_t *vam = &vat_main;
2022   vat_json_node_t node;
2023
2024   vat_json_init_object (&node);
2025   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2026
2027   vat_json_print (vam->ofp, &node);
2028   vat_json_free (&node);
2029
2030   vam->retval = ntohl (mp->retval);
2031   vam->result_ready = 1;
2032 }
2033
2034 static int
2035 api_sw_interface_set_bond_weight (vat_main_t * vam)
2036 {
2037   unformat_input_t *i = vam->input;
2038   vl_api_sw_interface_set_bond_weight_t *mp;
2039   u32 sw_if_index = ~0;
2040   u32 weight = 0;
2041   u8 weight_enter = 0;
2042   int ret;
2043
2044   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2045     {
2046       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2047         ;
2048       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2049         ;
2050       else if (unformat (i, "weight %u", &weight))
2051         weight_enter = 1;
2052       else
2053         break;
2054     }
2055
2056   if (sw_if_index == ~0)
2057     {
2058       errmsg ("missing interface name or sw_if_index");
2059       return -99;
2060     }
2061   if (weight_enter == 0)
2062     {
2063       errmsg ("missing valid weight");
2064       return -99;
2065     }
2066
2067   /* Construct the API message */
2068   M (SW_INTERFACE_SET_BOND_WEIGHT, mp);
2069   mp->sw_if_index = ntohl (sw_if_index);
2070   mp->weight = ntohl (weight);
2071
2072   S (mp);
2073   W (ret);
2074   return ret;
2075 }
2076
2077 static void vl_api_sw_bond_interface_details_t_handler
2078   (vl_api_sw_bond_interface_details_t * mp)
2079 {
2080   vat_main_t *vam = &vat_main;
2081
2082   print (vam->ofp,
2083          "%-16s %-12d %-12U %-13U %-14u %-14u",
2084          mp->interface_name, ntohl (mp->sw_if_index),
2085          format_bond_mode, ntohl (mp->mode), format_bond_load_balance,
2086          ntohl (mp->lb), ntohl (mp->active_members), ntohl (mp->members));
2087 }
2088
2089 static void vl_api_sw_bond_interface_details_t_handler_json
2090   (vl_api_sw_bond_interface_details_t * mp)
2091 {
2092   vat_main_t *vam = &vat_main;
2093   vat_json_node_t *node = NULL;
2094
2095   if (VAT_JSON_ARRAY != vam->json_tree.type)
2096     {
2097       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2098       vat_json_init_array (&vam->json_tree);
2099     }
2100   node = vat_json_array_add (&vam->json_tree);
2101
2102   vat_json_init_object (node);
2103   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2104   vat_json_object_add_string_copy (node, "interface_name",
2105                                    mp->interface_name);
2106   vat_json_object_add_uint (node, "mode", ntohl (mp->mode));
2107   vat_json_object_add_uint (node, "load_balance", ntohl (mp->lb));
2108   vat_json_object_add_uint (node, "active_members",
2109                             ntohl (mp->active_members));
2110   vat_json_object_add_uint (node, "members", ntohl (mp->members));
2111 }
2112
2113 static int
2114 api_sw_bond_interface_dump (vat_main_t * vam)
2115 {
2116   unformat_input_t *i = vam->input;
2117   vl_api_sw_bond_interface_dump_t *mp;
2118   vl_api_control_ping_t *mp_ping;
2119   int ret;
2120   u32 sw_if_index = ~0;
2121
2122   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2123     {
2124       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2125         ;
2126       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2127         ;
2128       else
2129         break;
2130     }
2131
2132   print (vam->ofp,
2133          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2134          "interface name", "sw_if_index", "mode", "load balance",
2135          "active members", "members");
2136
2137   /* Get list of bond interfaces */
2138   M (SW_BOND_INTERFACE_DUMP, mp);
2139   mp->sw_if_index = ntohl (sw_if_index);
2140   S (mp);
2141
2142   /* Use a control ping for synchronization */
2143   MPING (CONTROL_PING, mp_ping);
2144   S (mp_ping);
2145
2146   W (ret);
2147   return ret;
2148 }
2149
2150 static void vl_api_sw_member_interface_details_t_handler
2151   (vl_api_sw_member_interface_details_t * mp)
2152 {
2153   vat_main_t *vam = &vat_main;
2154
2155   print (vam->ofp,
2156          "%-25s %-12d %-7d %-12d %-10d %-10d", mp->interface_name,
2157          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout,
2158          ntohl (mp->weight), mp->is_local_numa);
2159 }
2160
2161 static void vl_api_sw_member_interface_details_t_handler_json
2162   (vl_api_sw_member_interface_details_t * mp)
2163 {
2164   vat_main_t *vam = &vat_main;
2165   vat_json_node_t *node = NULL;
2166
2167   if (VAT_JSON_ARRAY != vam->json_tree.type)
2168     {
2169       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2170       vat_json_init_array (&vam->json_tree);
2171     }
2172   node = vat_json_array_add (&vam->json_tree);
2173
2174   vat_json_init_object (node);
2175   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2176   vat_json_object_add_string_copy (node, "interface_name",
2177                                    mp->interface_name);
2178   vat_json_object_add_uint (node, "passive", mp->is_passive);
2179   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2180   vat_json_object_add_uint (node, "weight", ntohl (mp->weight));
2181   vat_json_object_add_uint (node, "is_local_numa", mp->is_local_numa);
2182 }
2183
2184 static int
2185 api_sw_member_interface_dump (vat_main_t * vam)
2186 {
2187   unformat_input_t *i = vam->input;
2188   vl_api_sw_member_interface_dump_t *mp;
2189   vl_api_control_ping_t *mp_ping;
2190   u32 sw_if_index = ~0;
2191   u8 sw_if_index_set = 0;
2192   int ret;
2193
2194   /* Parse args required to build the message */
2195   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2196     {
2197       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2198         sw_if_index_set = 1;
2199       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2200         sw_if_index_set = 1;
2201       else
2202         break;
2203     }
2204
2205   if (sw_if_index_set == 0)
2206     {
2207       errmsg ("missing vpp interface name. ");
2208       return -99;
2209     }
2210
2211   print (vam->ofp,
2212          "\n%-25s %-12s %-7s %-12s %-10s %-10s",
2213          "member interface name", "sw_if_index", "passive", "long_timeout",
2214          "weight", "local numa");
2215
2216   /* Get list of bond interfaces */
2217   M (SW_MEMBER_INTERFACE_DUMP, mp);
2218   mp->sw_if_index = ntohl (sw_if_index);
2219   S (mp);
2220
2221   /* Use a control ping for synchronization */
2222   MPING (CONTROL_PING, mp_ping);
2223   S (mp_ping);
2224
2225   W (ret);
2226   return ret;
2227 }
2228
2229 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2230   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2231 {
2232   vat_main_t *vam = &vat_main;
2233   i32 retval = ntohl (mp->retval);
2234   if (vam->async_mode)
2235     {
2236       vam->async_errors += (retval < 0);
2237     }
2238   else
2239     {
2240       vam->retval = retval;
2241       vam->sw_if_index = ntohl (mp->sw_if_index);
2242       vam->result_ready = 1;
2243     }
2244   vam->regenerate_interface_table = 1;
2245 }
2246
2247 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2248   (vl_api_mpls_tunnel_add_del_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, "tunnel_sw_if_index",
2256                             ntohl (mp->sw_if_index));
2257
2258   vat_json_print (vam->ofp, &node);
2259   vat_json_free (&node);
2260
2261   vam->retval = ntohl (mp->retval);
2262   vam->result_ready = 1;
2263 }
2264
2265 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2266   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2267 {
2268   vat_main_t *vam = &vat_main;
2269   i32 retval = ntohl (mp->retval);
2270   if (vam->async_mode)
2271     {
2272       vam->async_errors += (retval < 0);
2273     }
2274   else
2275     {
2276       vam->retval = retval;
2277       vam->sw_if_index = ntohl (mp->sw_if_index);
2278       vam->result_ready = 1;
2279     }
2280 }
2281
2282 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2283   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2284 {
2285   vat_main_t *vam = &vat_main;
2286   vat_json_node_t node;
2287
2288   vat_json_init_object (&node);
2289   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2290   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2291
2292   vat_json_print (vam->ofp, &node);
2293   vat_json_free (&node);
2294
2295   vam->retval = ntohl (mp->retval);
2296   vam->result_ready = 1;
2297 }
2298
2299 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2300   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2301 {
2302   vat_main_t *vam = &vat_main;
2303   i32 retval = ntohl (mp->retval);
2304   if (vam->async_mode)
2305     {
2306       vam->async_errors += (retval < 0);
2307     }
2308   else
2309     {
2310       vam->retval = retval;
2311       vam->result_ready = 1;
2312     }
2313 }
2314
2315 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2316   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2317 {
2318   vat_main_t *vam = &vat_main;
2319   vat_json_node_t node;
2320
2321   vat_json_init_object (&node);
2322   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2323   vat_json_object_add_uint (&node, "fwd_entry_index",
2324                             clib_net_to_host_u32 (mp->fwd_entry_index));
2325
2326   vat_json_print (vam->ofp, &node);
2327   vat_json_free (&node);
2328
2329   vam->retval = ntohl (mp->retval);
2330   vam->result_ready = 1;
2331 }
2332
2333 u8 *
2334 format_lisp_transport_protocol (u8 * s, va_list * args)
2335 {
2336   u32 proto = va_arg (*args, u32);
2337
2338   switch (proto)
2339     {
2340     case 1:
2341       return format (s, "udp");
2342     case 2:
2343       return format (s, "api");
2344     default:
2345       return 0;
2346     }
2347   return 0;
2348 }
2349
2350 static void vl_api_one_get_transport_protocol_reply_t_handler
2351   (vl_api_one_get_transport_protocol_reply_t * mp)
2352 {
2353   vat_main_t *vam = &vat_main;
2354   i32 retval = ntohl (mp->retval);
2355   if (vam->async_mode)
2356     {
2357       vam->async_errors += (retval < 0);
2358     }
2359   else
2360     {
2361       u32 proto = mp->protocol;
2362       print (vam->ofp, "Transport protocol: %U",
2363              format_lisp_transport_protocol, proto);
2364       vam->retval = retval;
2365       vam->result_ready = 1;
2366     }
2367 }
2368
2369 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2370   (vl_api_one_get_transport_protocol_reply_t * mp)
2371 {
2372   vat_main_t *vam = &vat_main;
2373   vat_json_node_t node;
2374   u8 *s;
2375
2376   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2377   vec_add1 (s, 0);
2378
2379   vat_json_init_object (&node);
2380   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2381   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2382
2383   vec_free (s);
2384   vat_json_print (vam->ofp, &node);
2385   vat_json_free (&node);
2386
2387   vam->retval = ntohl (mp->retval);
2388   vam->result_ready = 1;
2389 }
2390
2391 static void vl_api_one_add_del_locator_set_reply_t_handler
2392   (vl_api_one_add_del_locator_set_reply_t * mp)
2393 {
2394   vat_main_t *vam = &vat_main;
2395   i32 retval = ntohl (mp->retval);
2396   if (vam->async_mode)
2397     {
2398       vam->async_errors += (retval < 0);
2399     }
2400   else
2401     {
2402       vam->retval = retval;
2403       vam->result_ready = 1;
2404     }
2405 }
2406
2407 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2408   (vl_api_one_add_del_locator_set_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, "locator_set_index", ntohl (mp->ls_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_add_del_tunnel_reply_t_handler
2425   (vl_api_vxlan_add_del_tunnel_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->sw_if_index = ntohl (mp->sw_if_index);
2437       vam->result_ready = 1;
2438     }
2439   vam->regenerate_interface_table = 1;
2440 }
2441
2442 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2443   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2444 {
2445   vat_main_t *vam = &vat_main;
2446   vat_json_node_t node;
2447
2448   vat_json_init_object (&node);
2449   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2450   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2451
2452   vat_json_print (vam->ofp, &node);
2453   vat_json_free (&node);
2454
2455   vam->retval = ntohl (mp->retval);
2456   vam->result_ready = 1;
2457 }
2458
2459 static void vl_api_vxlan_offload_rx_reply_t_handler
2460   (vl_api_vxlan_offload_rx_reply_t * mp)
2461 {
2462   vat_main_t *vam = &vat_main;
2463   i32 retval = ntohl (mp->retval);
2464   if (vam->async_mode)
2465     {
2466       vam->async_errors += (retval < 0);
2467     }
2468   else
2469     {
2470       vam->retval = retval;
2471       vam->result_ready = 1;
2472     }
2473 }
2474
2475 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2476   (vl_api_vxlan_offload_rx_reply_t * mp)
2477 {
2478   vat_main_t *vam = &vat_main;
2479   vat_json_node_t node;
2480
2481   vat_json_init_object (&node);
2482   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2483
2484   vat_json_print (vam->ofp, &node);
2485   vat_json_free (&node);
2486
2487   vam->retval = ntohl (mp->retval);
2488   vam->result_ready = 1;
2489 }
2490
2491 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2492   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2493 {
2494   vat_main_t *vam = &vat_main;
2495   i32 retval = ntohl (mp->retval);
2496   if (vam->async_mode)
2497     {
2498       vam->async_errors += (retval < 0);
2499     }
2500   else
2501     {
2502       vam->retval = retval;
2503       vam->sw_if_index = ntohl (mp->sw_if_index);
2504       vam->result_ready = 1;
2505     }
2506 }
2507
2508 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2509   (vl_api_geneve_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_vxlan_gpe_add_del_tunnel_reply_t_handler
2526   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2527 {
2528   vat_main_t *vam = &vat_main;
2529   i32 retval = ntohl (mp->retval);
2530   if (vam->async_mode)
2531     {
2532       vam->async_errors += (retval < 0);
2533     }
2534   else
2535     {
2536       vam->retval = retval;
2537       vam->sw_if_index = ntohl (mp->sw_if_index);
2538       vam->result_ready = 1;
2539     }
2540   vam->regenerate_interface_table = 1;
2541 }
2542
2543 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2544   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2545 {
2546   vat_main_t *vam = &vat_main;
2547   vat_json_node_t node;
2548
2549   vat_json_init_object (&node);
2550   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2551   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2552
2553   vat_json_print (vam->ofp, &node);
2554   vat_json_free (&node);
2555
2556   vam->retval = ntohl (mp->retval);
2557   vam->result_ready = 1;
2558 }
2559
2560 static void vl_api_gre_tunnel_add_del_reply_t_handler
2561   (vl_api_gre_tunnel_add_del_reply_t * mp)
2562 {
2563   vat_main_t *vam = &vat_main;
2564   i32 retval = ntohl (mp->retval);
2565   if (vam->async_mode)
2566     {
2567       vam->async_errors += (retval < 0);
2568     }
2569   else
2570     {
2571       vam->retval = retval;
2572       vam->sw_if_index = ntohl (mp->sw_if_index);
2573       vam->result_ready = 1;
2574     }
2575 }
2576
2577 static void vl_api_gre_tunnel_add_del_reply_t_handler_json
2578   (vl_api_gre_tunnel_add_del_reply_t * mp)
2579 {
2580   vat_main_t *vam = &vat_main;
2581   vat_json_node_t node;
2582
2583   vat_json_init_object (&node);
2584   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2585   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2586
2587   vat_json_print (vam->ofp, &node);
2588   vat_json_free (&node);
2589
2590   vam->retval = ntohl (mp->retval);
2591   vam->result_ready = 1;
2592 }
2593
2594 static void vl_api_create_vhost_user_if_reply_t_handler
2595   (vl_api_create_vhost_user_if_reply_t * mp)
2596 {
2597   vat_main_t *vam = &vat_main;
2598   i32 retval = ntohl (mp->retval);
2599   if (vam->async_mode)
2600     {
2601       vam->async_errors += (retval < 0);
2602     }
2603   else
2604     {
2605       vam->retval = retval;
2606       vam->sw_if_index = ntohl (mp->sw_if_index);
2607       vam->result_ready = 1;
2608     }
2609   vam->regenerate_interface_table = 1;
2610 }
2611
2612 static void vl_api_create_vhost_user_if_reply_t_handler_json
2613   (vl_api_create_vhost_user_if_reply_t * mp)
2614 {
2615   vat_main_t *vam = &vat_main;
2616   vat_json_node_t node;
2617
2618   vat_json_init_object (&node);
2619   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2620   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2621
2622   vat_json_print (vam->ofp, &node);
2623   vat_json_free (&node);
2624
2625   vam->retval = ntohl (mp->retval);
2626   vam->result_ready = 1;
2627 }
2628
2629 static void vl_api_ip_address_details_t_handler
2630   (vl_api_ip_address_details_t * mp)
2631 {
2632   vat_main_t *vam = &vat_main;
2633   static ip_address_details_t empty_ip_address_details = { {0} };
2634   ip_address_details_t *address = NULL;
2635   ip_details_t *current_ip_details = NULL;
2636   ip_details_t *details = NULL;
2637
2638   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2639
2640   if (!details || vam->current_sw_if_index >= vec_len (details)
2641       || !details[vam->current_sw_if_index].present)
2642     {
2643       errmsg ("ip address details arrived but not stored");
2644       errmsg ("ip_dump should be called first");
2645       return;
2646     }
2647
2648   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2649
2650 #define addresses (current_ip_details->addr)
2651
2652   vec_validate_init_empty (addresses, vec_len (addresses),
2653                            empty_ip_address_details);
2654
2655   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2656
2657   clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
2658   address->prefix_length = mp->prefix.len;
2659 #undef addresses
2660 }
2661
2662 static void vl_api_ip_address_details_t_handler_json
2663   (vl_api_ip_address_details_t * mp)
2664 {
2665   vat_main_t *vam = &vat_main;
2666   vat_json_node_t *node = NULL;
2667
2668   if (VAT_JSON_ARRAY != vam->json_tree.type)
2669     {
2670       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2671       vat_json_init_array (&vam->json_tree);
2672     }
2673   node = vat_json_array_add (&vam->json_tree);
2674
2675   vat_json_init_object (node);
2676   vat_json_object_add_prefix (node, &mp->prefix);
2677 }
2678
2679 static void
2680 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2681 {
2682   vat_main_t *vam = &vat_main;
2683   static ip_details_t empty_ip_details = { 0 };
2684   ip_details_t *ip = NULL;
2685   u32 sw_if_index = ~0;
2686
2687   sw_if_index = ntohl (mp->sw_if_index);
2688
2689   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2690                            sw_if_index, empty_ip_details);
2691
2692   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2693                          sw_if_index);
2694
2695   ip->present = 1;
2696 }
2697
2698 static void
2699 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2700 {
2701   vat_main_t *vam = &vat_main;
2702
2703   if (VAT_JSON_ARRAY != vam->json_tree.type)
2704     {
2705       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2706       vat_json_init_array (&vam->json_tree);
2707     }
2708   vat_json_array_add_uint (&vam->json_tree,
2709                            clib_net_to_host_u32 (mp->sw_if_index));
2710 }
2711
2712 static void vl_api_get_first_msg_id_reply_t_handler
2713   (vl_api_get_first_msg_id_reply_t * mp)
2714 {
2715   vat_main_t *vam = &vat_main;
2716   i32 retval = ntohl (mp->retval);
2717
2718   if (vam->async_mode)
2719     {
2720       vam->async_errors += (retval < 0);
2721     }
2722   else
2723     {
2724       vam->retval = retval;
2725       vam->result_ready = 1;
2726     }
2727   if (retval >= 0)
2728     {
2729       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2730     }
2731 }
2732
2733 static void vl_api_get_first_msg_id_reply_t_handler_json
2734   (vl_api_get_first_msg_id_reply_t * mp)
2735 {
2736   vat_main_t *vam = &vat_main;
2737   vat_json_node_t node;
2738
2739   vat_json_init_object (&node);
2740   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2741   vat_json_object_add_uint (&node, "first_msg_id",
2742                             (uint) ntohs (mp->first_msg_id));
2743
2744   vat_json_print (vam->ofp, &node);
2745   vat_json_free (&node);
2746
2747   vam->retval = ntohl (mp->retval);
2748   vam->result_ready = 1;
2749 }
2750
2751 static void vl_api_get_node_graph_reply_t_handler
2752   (vl_api_get_node_graph_reply_t * mp)
2753 {
2754   vat_main_t *vam = &vat_main;
2755   i32 retval = ntohl (mp->retval);
2756   u8 *pvt_copy, *reply;
2757   void *oldheap;
2758   vlib_node_t *node;
2759   int i;
2760
2761   if (vam->async_mode)
2762     {
2763       vam->async_errors += (retval < 0);
2764     }
2765   else
2766     {
2767       vam->retval = retval;
2768       vam->result_ready = 1;
2769     }
2770
2771   /* "Should never happen..." */
2772   if (retval != 0)
2773     return;
2774
2775   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2776   pvt_copy = vec_dup (reply);
2777
2778   /* Toss the shared-memory original... */
2779   oldheap = vl_msg_push_heap ();
2780
2781   vec_free (reply);
2782
2783   vl_msg_pop_heap (oldheap);
2784
2785   if (vam->graph_nodes)
2786     {
2787       hash_free (vam->graph_node_index_by_name);
2788
2789       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2790         {
2791           node = vam->graph_nodes[0][i];
2792           vec_free (node->name);
2793           vec_free (node->next_nodes);
2794           vec_free (node);
2795         }
2796       vec_free (vam->graph_nodes[0]);
2797       vec_free (vam->graph_nodes);
2798     }
2799
2800   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2801   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2802   vec_free (pvt_copy);
2803
2804   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2805     {
2806       node = vam->graph_nodes[0][i];
2807       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2808     }
2809 }
2810
2811 static void vl_api_get_node_graph_reply_t_handler_json
2812   (vl_api_get_node_graph_reply_t * mp)
2813 {
2814   vat_main_t *vam = &vat_main;
2815   void *oldheap;
2816   vat_json_node_t node;
2817   u8 *reply;
2818
2819   /* $$$$ make this real? */
2820   vat_json_init_object (&node);
2821   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2822   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2823
2824   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2825
2826   /* Toss the shared-memory original... */
2827   oldheap = vl_msg_push_heap ();
2828
2829   vec_free (reply);
2830
2831   vl_msg_pop_heap (oldheap);
2832
2833   vat_json_print (vam->ofp, &node);
2834   vat_json_free (&node);
2835
2836   vam->retval = ntohl (mp->retval);
2837   vam->result_ready = 1;
2838 }
2839
2840 static void
2841 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2842 {
2843   vat_main_t *vam = &vat_main;
2844   u8 *s = 0;
2845
2846   if (mp->local)
2847     {
2848       s = format (s, "%=16d%=16d%=16d",
2849                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2850     }
2851   else
2852     {
2853       s = format (s, "%=16U%=16d%=16d",
2854                   format_ip46_address,
2855                   mp->ip_address, mp->priority, mp->weight);
2856     }
2857
2858   print (vam->ofp, "%v", s);
2859   vec_free (s);
2860 }
2861
2862 static void
2863 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2864 {
2865   vat_main_t *vam = &vat_main;
2866   vat_json_node_t *node = NULL;
2867   struct in6_addr ip6;
2868   struct in_addr ip4;
2869
2870   if (VAT_JSON_ARRAY != vam->json_tree.type)
2871     {
2872       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2873       vat_json_init_array (&vam->json_tree);
2874     }
2875   node = vat_json_array_add (&vam->json_tree);
2876   vat_json_init_object (node);
2877
2878   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2879   vat_json_object_add_uint (node, "priority", mp->priority);
2880   vat_json_object_add_uint (node, "weight", mp->weight);
2881
2882   if (mp->local)
2883     vat_json_object_add_uint (node, "sw_if_index",
2884                               clib_net_to_host_u32 (mp->sw_if_index));
2885   else
2886     {
2887       if (mp->ip_address.af)
2888         {
2889           clib_memcpy (&ip6, mp->ip_address.un.ip6, sizeof (ip6));
2890           vat_json_object_add_ip6 (node, "address", ip6);
2891         }
2892       else
2893         {
2894           clib_memcpy (&ip4, mp->ip_address.un.ip4, sizeof (ip4));
2895           vat_json_object_add_ip4 (node, "address", ip4);
2896         }
2897     }
2898 }
2899
2900 static void
2901 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2902                                           mp)
2903 {
2904   vat_main_t *vam = &vat_main;
2905   u8 *ls_name = 0;
2906
2907   ls_name = format (0, "%s", mp->ls_name);
2908
2909   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2910          ls_name);
2911   vec_free (ls_name);
2912 }
2913
2914 static void
2915   vl_api_one_locator_set_details_t_handler_json
2916   (vl_api_one_locator_set_details_t * mp)
2917 {
2918   vat_main_t *vam = &vat_main;
2919   vat_json_node_t *node = 0;
2920   u8 *ls_name = 0;
2921
2922   ls_name = format (0, "%s", mp->ls_name);
2923   vec_add1 (ls_name, 0);
2924
2925   if (VAT_JSON_ARRAY != vam->json_tree.type)
2926     {
2927       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2928       vat_json_init_array (&vam->json_tree);
2929     }
2930   node = vat_json_array_add (&vam->json_tree);
2931
2932   vat_json_init_object (node);
2933   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2934   vat_json_object_add_uint (node, "ls_index",
2935                             clib_net_to_host_u32 (mp->ls_index));
2936   vec_free (ls_name);
2937 }
2938
2939 typedef struct
2940 {
2941   u32 spi;
2942   u8 si;
2943 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2944
2945 uword
2946 unformat_nsh_address (unformat_input_t * input, va_list * args)
2947 {
2948   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2949   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2950 }
2951
2952 static u8 *
2953 format_nsh_address_vat (u8 * s, va_list * args)
2954 {
2955   nsh_t *a = va_arg (*args, nsh_t *);
2956   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2957 }
2958
2959 static u8 *
2960 format_lisp_flat_eid (u8 * s, va_list * args)
2961 {
2962   vl_api_eid_t *eid = va_arg (*args, vl_api_eid_t *);
2963
2964   switch (eid->type)
2965     {
2966     case EID_TYPE_API_PREFIX:
2967       if (eid->address.prefix.address.af)
2968         return format (s, "%U/%d", format_ip6_address,
2969                        eid->address.prefix.address.un.ip6,
2970                        eid->address.prefix.len);
2971       return format (s, "%U/%d", format_ip4_address,
2972                      eid->address.prefix.address.un.ip4,
2973                      eid->address.prefix.len);
2974     case EID_TYPE_API_MAC:
2975       return format (s, "%U", format_ethernet_address, eid->address.mac);
2976     case EID_TYPE_API_NSH:
2977       return format (s, "%U", format_nsh_address_vat, eid->address.nsh);
2978     }
2979   return 0;
2980 }
2981
2982 static u8 *
2983 format_lisp_eid_vat (u8 * s, va_list * args)
2984 {
2985   vl_api_eid_t *deid = va_arg (*args, vl_api_eid_t *);
2986   vl_api_eid_t *seid = va_arg (*args, vl_api_eid_t *);
2987   u8 is_src_dst = (u8) va_arg (*args, int);
2988
2989   if (is_src_dst)
2990     s = format (s, "%U|", format_lisp_flat_eid, seid);
2991
2992   s = format (s, "%U", format_lisp_flat_eid, deid);
2993
2994   return s;
2995 }
2996
2997 static void
2998 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2999 {
3000   vat_main_t *vam = &vat_main;
3001   u8 *s = 0, *eid = 0;
3002
3003   if (~0 == mp->locator_set_index)
3004     s = format (0, "action: %d", mp->action);
3005   else
3006     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3007
3008   eid = format (0, "%U", format_lisp_eid_vat,
3009                 &mp->deid, &mp->seid, mp->is_src_dst);
3010   vec_add1 (eid, 0);
3011
3012   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3013          clib_net_to_host_u32 (mp->vni),
3014          eid,
3015          mp->is_local ? "local" : "remote",
3016          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3017          clib_net_to_host_u16 (mp->key.id), mp->key.key);
3018
3019   vec_free (s);
3020   vec_free (eid);
3021 }
3022
3023 static void
3024 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3025                                              * mp)
3026 {
3027   vat_main_t *vam = &vat_main;
3028   vat_json_node_t *node = 0;
3029   u8 *eid = 0;
3030
3031   if (VAT_JSON_ARRAY != vam->json_tree.type)
3032     {
3033       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3034       vat_json_init_array (&vam->json_tree);
3035     }
3036   node = vat_json_array_add (&vam->json_tree);
3037
3038   vat_json_init_object (node);
3039   if (~0 == mp->locator_set_index)
3040     vat_json_object_add_uint (node, "action", mp->action);
3041   else
3042     vat_json_object_add_uint (node, "locator_set_index",
3043                               clib_net_to_host_u32 (mp->locator_set_index));
3044
3045   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3046   if (mp->deid.type == 3)
3047     {
3048       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3049       vat_json_init_object (nsh_json);
3050       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) & mp->deid.address.nsh;
3051       vat_json_object_add_uint (nsh_json, "spi",
3052                                 clib_net_to_host_u32 (nsh->spi));
3053       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3054     }
3055   else
3056     {
3057       eid = format (0, "%U", format_lisp_eid_vat,
3058                     &mp->deid, &mp->seid, mp->is_src_dst);
3059       vec_add1 (eid, 0);
3060       vat_json_object_add_string_copy (node, "eid", eid);
3061       vec_free (eid);
3062     }
3063   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3064   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3065   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3066
3067   if (mp->key.id)
3068     {
3069       vat_json_object_add_uint (node, "key_id",
3070                                 clib_net_to_host_u16 (mp->key.id));
3071       vat_json_object_add_string_copy (node, "key", mp->key.key);
3072     }
3073 }
3074
3075 static void
3076 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3077 {
3078   vat_main_t *vam = &vat_main;
3079   u8 *seid = 0, *deid = 0;
3080   ip46_address_t lloc, rloc;
3081
3082   deid = format (0, "%U", format_lisp_eid_vat, &mp->deid, 0, 0);
3083
3084   seid = format (0, "%U", format_lisp_eid_vat, &mp->seid, 0, 0);
3085
3086   vec_add1 (deid, 0);
3087   vec_add1 (seid, 0);
3088
3089   if (mp->lloc.af)
3090     {
3091       clib_memcpy (&lloc.ip6, mp->lloc.un.ip6, 16);
3092       clib_memcpy (&rloc.ip6, mp->rloc.un.ip6, 16);
3093     }
3094   else
3095     {
3096       clib_memcpy (&lloc.ip4, mp->lloc.un.ip4, 4);
3097       clib_memcpy (&rloc.ip4, mp->rloc.un.ip4, 4);
3098     }
3099
3100
3101   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3102          clib_net_to_host_u32 (mp->vni),
3103          seid, deid,
3104          format_ip46_address, lloc,
3105          format_ip46_address, rloc,
3106          clib_net_to_host_u32 (mp->pkt_count),
3107          clib_net_to_host_u32 (mp->bytes));
3108
3109   vec_free (deid);
3110   vec_free (seid);
3111 }
3112
3113 static void
3114 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3115 {
3116   struct in6_addr ip6;
3117   struct in_addr ip4;
3118   vat_main_t *vam = &vat_main;
3119   vat_json_node_t *node = 0;
3120   u8 *deid = 0, *seid = 0;
3121
3122   if (VAT_JSON_ARRAY != vam->json_tree.type)
3123     {
3124       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3125       vat_json_init_array (&vam->json_tree);
3126     }
3127   node = vat_json_array_add (&vam->json_tree);
3128
3129   vat_json_init_object (node);
3130   deid = format (0, "%U", format_lisp_eid_vat, &mp->deid, 0, 0);
3131
3132   seid = format (0, "%U", format_lisp_eid_vat, &mp->seid, 0, 0);
3133
3134   vec_add1 (deid, 0);
3135   vec_add1 (seid, 0);
3136
3137   vat_json_object_add_string_copy (node, "seid", seid);
3138   vat_json_object_add_string_copy (node, "deid", deid);
3139   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3140
3141   if (mp->lloc.af)
3142     {
3143       clib_memcpy (&ip6, mp->lloc.un.ip6, sizeof (ip6));
3144       vat_json_object_add_ip6 (node, "lloc", ip6);
3145       clib_memcpy (&ip6, mp->rloc.un.ip6, sizeof (ip6));
3146       vat_json_object_add_ip6 (node, "rloc", ip6);
3147
3148     }
3149   else
3150     {
3151       clib_memcpy (&ip4, mp->lloc.un.ip4, sizeof (ip4));
3152       vat_json_object_add_ip4 (node, "lloc", ip4);
3153       clib_memcpy (&ip4, mp->rloc.un.ip4, sizeof (ip4));
3154       vat_json_object_add_ip4 (node, "rloc", ip4);
3155     }
3156   vat_json_object_add_uint (node, "pkt_count",
3157                             clib_net_to_host_u32 (mp->pkt_count));
3158   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3159
3160   vec_free (deid);
3161   vec_free (seid);
3162 }
3163
3164 static void
3165   vl_api_one_eid_table_map_details_t_handler
3166   (vl_api_one_eid_table_map_details_t * mp)
3167 {
3168   vat_main_t *vam = &vat_main;
3169
3170   u8 *line = format (0, "%=10d%=10d",
3171                      clib_net_to_host_u32 (mp->vni),
3172                      clib_net_to_host_u32 (mp->dp_table));
3173   print (vam->ofp, "%v", line);
3174   vec_free (line);
3175 }
3176
3177 static void
3178   vl_api_one_eid_table_map_details_t_handler_json
3179   (vl_api_one_eid_table_map_details_t * mp)
3180 {
3181   vat_main_t *vam = &vat_main;
3182   vat_json_node_t *node = NULL;
3183
3184   if (VAT_JSON_ARRAY != vam->json_tree.type)
3185     {
3186       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3187       vat_json_init_array (&vam->json_tree);
3188     }
3189   node = vat_json_array_add (&vam->json_tree);
3190   vat_json_init_object (node);
3191   vat_json_object_add_uint (node, "dp_table",
3192                             clib_net_to_host_u32 (mp->dp_table));
3193   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3194 }
3195
3196 static void
3197   vl_api_one_eid_table_vni_details_t_handler
3198   (vl_api_one_eid_table_vni_details_t * mp)
3199 {
3200   vat_main_t *vam = &vat_main;
3201
3202   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3203   print (vam->ofp, "%v", line);
3204   vec_free (line);
3205 }
3206
3207 static void
3208   vl_api_one_eid_table_vni_details_t_handler_json
3209   (vl_api_one_eid_table_vni_details_t * mp)
3210 {
3211   vat_main_t *vam = &vat_main;
3212   vat_json_node_t *node = NULL;
3213
3214   if (VAT_JSON_ARRAY != vam->json_tree.type)
3215     {
3216       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3217       vat_json_init_array (&vam->json_tree);
3218     }
3219   node = vat_json_array_add (&vam->json_tree);
3220   vat_json_init_object (node);
3221   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3222 }
3223
3224 static void
3225   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3226   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3227 {
3228   vat_main_t *vam = &vat_main;
3229   int retval = clib_net_to_host_u32 (mp->retval);
3230
3231   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3232   print (vam->ofp, "fallback threshold value: %d", mp->value);
3233
3234   vam->retval = retval;
3235   vam->result_ready = 1;
3236 }
3237
3238 static void
3239   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3240   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3241 {
3242   vat_main_t *vam = &vat_main;
3243   vat_json_node_t _node, *node = &_node;
3244   int retval = clib_net_to_host_u32 (mp->retval);
3245
3246   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3247   vat_json_init_object (node);
3248   vat_json_object_add_uint (node, "value", mp->value);
3249
3250   vat_json_print (vam->ofp, node);
3251   vat_json_free (node);
3252
3253   vam->retval = retval;
3254   vam->result_ready = 1;
3255 }
3256
3257 static void
3258   vl_api_show_one_map_register_state_reply_t_handler
3259   (vl_api_show_one_map_register_state_reply_t * mp)
3260 {
3261   vat_main_t *vam = &vat_main;
3262   int retval = clib_net_to_host_u32 (mp->retval);
3263
3264   print (vam->ofp, "%s", mp->is_enable ? "enabled" : "disabled");
3265
3266   vam->retval = retval;
3267   vam->result_ready = 1;
3268 }
3269
3270 static void
3271   vl_api_show_one_map_register_state_reply_t_handler_json
3272   (vl_api_show_one_map_register_state_reply_t * mp)
3273 {
3274   vat_main_t *vam = &vat_main;
3275   vat_json_node_t _node, *node = &_node;
3276   int retval = clib_net_to_host_u32 (mp->retval);
3277
3278   u8 *s = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
3279
3280   vat_json_init_object (node);
3281   vat_json_object_add_string_copy (node, "state", s);
3282
3283   vat_json_print (vam->ofp, node);
3284   vat_json_free (node);
3285
3286   vam->retval = retval;
3287   vam->result_ready = 1;
3288   vec_free (s);
3289 }
3290
3291 static void
3292   vl_api_show_one_rloc_probe_state_reply_t_handler
3293   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3294 {
3295   vat_main_t *vam = &vat_main;
3296   int retval = clib_net_to_host_u32 (mp->retval);
3297
3298   if (retval)
3299     goto end;
3300
3301   print (vam->ofp, "%s", mp->is_enable ? "enabled" : "disabled");
3302 end:
3303   vam->retval = retval;
3304   vam->result_ready = 1;
3305 }
3306
3307 static void
3308   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3309   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3310 {
3311   vat_main_t *vam = &vat_main;
3312   vat_json_node_t _node, *node = &_node;
3313   int retval = clib_net_to_host_u32 (mp->retval);
3314
3315   u8 *s = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
3316   vat_json_init_object (node);
3317   vat_json_object_add_string_copy (node, "state", s);
3318
3319   vat_json_print (vam->ofp, node);
3320   vat_json_free (node);
3321
3322   vam->retval = retval;
3323   vam->result_ready = 1;
3324   vec_free (s);
3325 }
3326
3327 static void
3328   vl_api_show_one_stats_enable_disable_reply_t_handler
3329   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3330 {
3331   vat_main_t *vam = &vat_main;
3332   int retval = clib_net_to_host_u32 (mp->retval);
3333
3334   if (retval)
3335     goto end;
3336
3337   print (vam->ofp, "%s", mp->is_enable ? "enabled" : "disabled");
3338 end:
3339   vam->retval = retval;
3340   vam->result_ready = 1;
3341 }
3342
3343 static void
3344   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3345   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3346 {
3347   vat_main_t *vam = &vat_main;
3348   vat_json_node_t _node, *node = &_node;
3349   int retval = clib_net_to_host_u32 (mp->retval);
3350
3351   u8 *s = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
3352   vat_json_init_object (node);
3353   vat_json_object_add_string_copy (node, "state", s);
3354
3355   vat_json_print (vam->ofp, node);
3356   vat_json_free (node);
3357
3358   vam->retval = retval;
3359   vam->result_ready = 1;
3360   vec_free (s);
3361 }
3362
3363 static void
3364 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3365 {
3366   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3367   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3368   e->vni = clib_net_to_host_u32 (e->vni);
3369 }
3370
3371 static void
3372   gpe_fwd_entries_get_reply_t_net_to_host
3373   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3374 {
3375   u32 i;
3376
3377   mp->count = clib_net_to_host_u32 (mp->count);
3378   for (i = 0; i < mp->count; i++)
3379     {
3380       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3381     }
3382 }
3383
3384 static u8 *
3385 format_gpe_encap_mode (u8 * s, va_list * args)
3386 {
3387   u32 mode = va_arg (*args, u32);
3388
3389   switch (mode)
3390     {
3391     case 0:
3392       return format (s, "lisp");
3393     case 1:
3394       return format (s, "vxlan");
3395     }
3396   return 0;
3397 }
3398
3399 static void
3400   vl_api_gpe_get_encap_mode_reply_t_handler
3401   (vl_api_gpe_get_encap_mode_reply_t * mp)
3402 {
3403   vat_main_t *vam = &vat_main;
3404
3405   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3406   vam->retval = ntohl (mp->retval);
3407   vam->result_ready = 1;
3408 }
3409
3410 static void
3411   vl_api_gpe_get_encap_mode_reply_t_handler_json
3412   (vl_api_gpe_get_encap_mode_reply_t * mp)
3413 {
3414   vat_main_t *vam = &vat_main;
3415   vat_json_node_t node;
3416
3417   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3418   vec_add1 (encap_mode, 0);
3419
3420   vat_json_init_object (&node);
3421   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3422
3423   vec_free (encap_mode);
3424   vat_json_print (vam->ofp, &node);
3425   vat_json_free (&node);
3426
3427   vam->retval = ntohl (mp->retval);
3428   vam->result_ready = 1;
3429 }
3430
3431 static void
3432   vl_api_gpe_fwd_entry_path_details_t_handler
3433   (vl_api_gpe_fwd_entry_path_details_t * mp)
3434 {
3435   vat_main_t *vam = &vat_main;
3436   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3437
3438   if (mp->lcl_loc.addr.af)
3439     format_ip_address_fcn = format_ip6_address;
3440   else
3441     format_ip_address_fcn = format_ip4_address;
3442
3443   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3444          format_ip_address_fcn, &mp->lcl_loc.addr.un,
3445          format_ip_address_fcn, &mp->rmt_loc.addr.un);
3446 }
3447
3448 static void
3449 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3450 {
3451   struct in6_addr ip6;
3452   struct in_addr ip4;
3453
3454   if (loc->addr.af)
3455     {
3456       clib_memcpy (&ip6, loc->addr.un.ip6, sizeof (ip6));
3457       vat_json_object_add_ip6 (n, "address", ip6);
3458     }
3459   else
3460     {
3461       clib_memcpy (&ip4, loc->addr.un.ip4, sizeof (ip4));
3462       vat_json_object_add_ip4 (n, "address", ip4);
3463     }
3464   vat_json_object_add_uint (n, "weight", loc->weight);
3465 }
3466
3467 static void
3468   vl_api_gpe_fwd_entry_path_details_t_handler_json
3469   (vl_api_gpe_fwd_entry_path_details_t * mp)
3470 {
3471   vat_main_t *vam = &vat_main;
3472   vat_json_node_t *node = NULL;
3473   vat_json_node_t *loc_node;
3474
3475   if (VAT_JSON_ARRAY != vam->json_tree.type)
3476     {
3477       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3478       vat_json_init_array (&vam->json_tree);
3479     }
3480   node = vat_json_array_add (&vam->json_tree);
3481   vat_json_init_object (node);
3482
3483   loc_node = vat_json_object_add (node, "local_locator");
3484   vat_json_init_object (loc_node);
3485   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3486
3487   loc_node = vat_json_object_add (node, "remote_locator");
3488   vat_json_init_object (loc_node);
3489   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3490 }
3491
3492 static void
3493   vl_api_gpe_fwd_entries_get_reply_t_handler
3494   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3495 {
3496   vat_main_t *vam = &vat_main;
3497   u32 i;
3498   int retval = clib_net_to_host_u32 (mp->retval);
3499   vl_api_gpe_fwd_entry_t *e;
3500
3501   if (retval)
3502     goto end;
3503
3504   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3505
3506   for (i = 0; i < mp->count; i++)
3507     {
3508       e = &mp->entries[i];
3509       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3510              format_lisp_flat_eid, e->leid, format_lisp_flat_eid, e->reid);
3511     }
3512
3513 end:
3514   vam->retval = retval;
3515   vam->result_ready = 1;
3516 }
3517
3518 static void
3519   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3520   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3521 {
3522   u8 *s = 0;
3523   vat_main_t *vam = &vat_main;
3524   vat_json_node_t *e = 0, root;
3525   u32 i;
3526   int retval = clib_net_to_host_u32 (mp->retval);
3527   vl_api_gpe_fwd_entry_t *fwd;
3528
3529   if (retval)
3530     goto end;
3531
3532   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3533   vat_json_init_array (&root);
3534
3535   for (i = 0; i < mp->count; i++)
3536     {
3537       e = vat_json_array_add (&root);
3538       fwd = &mp->entries[i];
3539
3540       vat_json_init_object (e);
3541       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3542       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3543       vat_json_object_add_int (e, "vni", fwd->vni);
3544       vat_json_object_add_int (e, "action", fwd->action);
3545
3546       s = format (0, "%U", format_lisp_flat_eid, fwd->leid);
3547       vec_add1 (s, 0);
3548       vat_json_object_add_string_copy (e, "leid", s);
3549       vec_free (s);
3550
3551       s = format (0, "%U", format_lisp_flat_eid, fwd->reid);
3552       vec_add1 (s, 0);
3553       vat_json_object_add_string_copy (e, "reid", s);
3554       vec_free (s);
3555     }
3556
3557   vat_json_print (vam->ofp, &root);
3558   vat_json_free (&root);
3559
3560 end:
3561   vam->retval = retval;
3562   vam->result_ready = 1;
3563 }
3564
3565 static void
3566   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3567   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3568 {
3569   vat_main_t *vam = &vat_main;
3570   u32 i, n;
3571   int retval = clib_net_to_host_u32 (mp->retval);
3572   vl_api_gpe_native_fwd_rpath_t *r;
3573
3574   if (retval)
3575     goto end;
3576
3577   n = clib_net_to_host_u32 (mp->count);
3578
3579   for (i = 0; i < n; i++)
3580     {
3581       r = &mp->entries[i];
3582       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3583              clib_net_to_host_u32 (r->fib_index),
3584              clib_net_to_host_u32 (r->nh_sw_if_index),
3585              r->nh_addr.af ? format_ip6_address : format_ip4_address,
3586              r->nh_addr.un);
3587     }
3588
3589 end:
3590   vam->retval = retval;
3591   vam->result_ready = 1;
3592 }
3593
3594 static void
3595   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3596   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3597 {
3598   vat_main_t *vam = &vat_main;
3599   vat_json_node_t root, *e;
3600   u32 i, n;
3601   int retval = clib_net_to_host_u32 (mp->retval);
3602   vl_api_gpe_native_fwd_rpath_t *r;
3603   u8 *s;
3604
3605   if (retval)
3606     goto end;
3607
3608   n = clib_net_to_host_u32 (mp->count);
3609   vat_json_init_array (&root);
3610
3611   for (i = 0; i < n; i++)
3612     {
3613       e = vat_json_array_add (&root);
3614       vat_json_init_object (e);
3615       r = &mp->entries[i];
3616       s =
3617         format (0, "%U",
3618                 r->nh_addr.af ? format_ip6_address : format_ip4_address,
3619                 r->nh_addr.un);
3620       vec_add1 (s, 0);
3621       vat_json_object_add_string_copy (e, "ip4", s);
3622       vec_free (s);
3623
3624       vat_json_object_add_uint (e, "fib_index",
3625                                 clib_net_to_host_u32 (r->fib_index));
3626       vat_json_object_add_uint (e, "nh_sw_if_index",
3627                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3628     }
3629
3630   vat_json_print (vam->ofp, &root);
3631   vat_json_free (&root);
3632
3633 end:
3634   vam->retval = retval;
3635   vam->result_ready = 1;
3636 }
3637
3638 static void
3639   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3640   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3641 {
3642   vat_main_t *vam = &vat_main;
3643   u32 i, n;
3644   int retval = clib_net_to_host_u32 (mp->retval);
3645
3646   if (retval)
3647     goto end;
3648
3649   n = clib_net_to_host_u32 (mp->count);
3650
3651   for (i = 0; i < n; i++)
3652     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3653
3654 end:
3655   vam->retval = retval;
3656   vam->result_ready = 1;
3657 }
3658
3659 static void
3660   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3661   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3662 {
3663   vat_main_t *vam = &vat_main;
3664   vat_json_node_t root;
3665   u32 i, n;
3666   int retval = clib_net_to_host_u32 (mp->retval);
3667
3668   if (retval)
3669     goto end;
3670
3671   n = clib_net_to_host_u32 (mp->count);
3672   vat_json_init_array (&root);
3673
3674   for (i = 0; i < n; i++)
3675     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3676
3677   vat_json_print (vam->ofp, &root);
3678   vat_json_free (&root);
3679
3680 end:
3681   vam->retval = retval;
3682   vam->result_ready = 1;
3683 }
3684
3685 static void
3686   vl_api_one_ndp_entries_get_reply_t_handler
3687   (vl_api_one_ndp_entries_get_reply_t * mp)
3688 {
3689   vat_main_t *vam = &vat_main;
3690   u32 i, n;
3691   int retval = clib_net_to_host_u32 (mp->retval);
3692
3693   if (retval)
3694     goto end;
3695
3696   n = clib_net_to_host_u32 (mp->count);
3697
3698   for (i = 0; i < n; i++)
3699     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3700            format_ethernet_address, mp->entries[i].mac);
3701
3702 end:
3703   vam->retval = retval;
3704   vam->result_ready = 1;
3705 }
3706
3707 static void
3708   vl_api_one_ndp_entries_get_reply_t_handler_json
3709   (vl_api_one_ndp_entries_get_reply_t * mp)
3710 {
3711   u8 *s = 0;
3712   vat_main_t *vam = &vat_main;
3713   vat_json_node_t *e = 0, root;
3714   u32 i, n;
3715   int retval = clib_net_to_host_u32 (mp->retval);
3716   vl_api_one_ndp_entry_t *arp_entry;
3717
3718   if (retval)
3719     goto end;
3720
3721   n = clib_net_to_host_u32 (mp->count);
3722   vat_json_init_array (&root);
3723
3724   for (i = 0; i < n; i++)
3725     {
3726       e = vat_json_array_add (&root);
3727       arp_entry = &mp->entries[i];
3728
3729       vat_json_init_object (e);
3730       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3731       vec_add1 (s, 0);
3732
3733       vat_json_object_add_string_copy (e, "mac", s);
3734       vec_free (s);
3735
3736       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3737       vec_add1 (s, 0);
3738       vat_json_object_add_string_copy (e, "ip6", s);
3739       vec_free (s);
3740     }
3741
3742   vat_json_print (vam->ofp, &root);
3743   vat_json_free (&root);
3744
3745 end:
3746   vam->retval = retval;
3747   vam->result_ready = 1;
3748 }
3749
3750 static void
3751   vl_api_one_l2_arp_entries_get_reply_t_handler
3752   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3753 {
3754   vat_main_t *vam = &vat_main;
3755   u32 i, n;
3756   int retval = clib_net_to_host_u32 (mp->retval);
3757
3758   if (retval)
3759     goto end;
3760
3761   n = clib_net_to_host_u32 (mp->count);
3762
3763   for (i = 0; i < n; i++)
3764     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3765            format_ethernet_address, mp->entries[i].mac);
3766
3767 end:
3768   vam->retval = retval;
3769   vam->result_ready = 1;
3770 }
3771
3772 static void
3773   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3774   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3775 {
3776   u8 *s = 0;
3777   vat_main_t *vam = &vat_main;
3778   vat_json_node_t *e = 0, root;
3779   u32 i, n;
3780   int retval = clib_net_to_host_u32 (mp->retval);
3781   vl_api_one_l2_arp_entry_t *arp_entry;
3782
3783   if (retval)
3784     goto end;
3785
3786   n = clib_net_to_host_u32 (mp->count);
3787   vat_json_init_array (&root);
3788
3789   for (i = 0; i < n; i++)
3790     {
3791       e = vat_json_array_add (&root);
3792       arp_entry = &mp->entries[i];
3793
3794       vat_json_init_object (e);
3795       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3796       vec_add1 (s, 0);
3797
3798       vat_json_object_add_string_copy (e, "mac", s);
3799       vec_free (s);
3800
3801       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3802       vec_add1 (s, 0);
3803       vat_json_object_add_string_copy (e, "ip4", s);
3804       vec_free (s);
3805     }
3806
3807   vat_json_print (vam->ofp, &root);
3808   vat_json_free (&root);
3809
3810 end:
3811   vam->retval = retval;
3812   vam->result_ready = 1;
3813 }
3814
3815 static void
3816 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3817 {
3818   vat_main_t *vam = &vat_main;
3819   u32 i, n;
3820   int retval = clib_net_to_host_u32 (mp->retval);
3821
3822   if (retval)
3823     goto end;
3824
3825   n = clib_net_to_host_u32 (mp->count);
3826
3827   for (i = 0; i < n; i++)
3828     {
3829       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3830     }
3831
3832 end:
3833   vam->retval = retval;
3834   vam->result_ready = 1;
3835 }
3836
3837 static void
3838   vl_api_one_ndp_bd_get_reply_t_handler_json
3839   (vl_api_one_ndp_bd_get_reply_t * mp)
3840 {
3841   vat_main_t *vam = &vat_main;
3842   vat_json_node_t root;
3843   u32 i, n;
3844   int retval = clib_net_to_host_u32 (mp->retval);
3845
3846   if (retval)
3847     goto end;
3848
3849   n = clib_net_to_host_u32 (mp->count);
3850   vat_json_init_array (&root);
3851
3852   for (i = 0; i < n; i++)
3853     {
3854       vat_json_array_add_uint (&root,
3855                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3856     }
3857
3858   vat_json_print (vam->ofp, &root);
3859   vat_json_free (&root);
3860
3861 end:
3862   vam->retval = retval;
3863   vam->result_ready = 1;
3864 }
3865
3866 static void
3867   vl_api_one_l2_arp_bd_get_reply_t_handler
3868   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3869 {
3870   vat_main_t *vam = &vat_main;
3871   u32 i, n;
3872   int retval = clib_net_to_host_u32 (mp->retval);
3873
3874   if (retval)
3875     goto end;
3876
3877   n = clib_net_to_host_u32 (mp->count);
3878
3879   for (i = 0; i < n; i++)
3880     {
3881       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3882     }
3883
3884 end:
3885   vam->retval = retval;
3886   vam->result_ready = 1;
3887 }
3888
3889 static void
3890   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3891   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3892 {
3893   vat_main_t *vam = &vat_main;
3894   vat_json_node_t root;
3895   u32 i, n;
3896   int retval = clib_net_to_host_u32 (mp->retval);
3897
3898   if (retval)
3899     goto end;
3900
3901   n = clib_net_to_host_u32 (mp->count);
3902   vat_json_init_array (&root);
3903
3904   for (i = 0; i < n; i++)
3905     {
3906       vat_json_array_add_uint (&root,
3907                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3908     }
3909
3910   vat_json_print (vam->ofp, &root);
3911   vat_json_free (&root);
3912
3913 end:
3914   vam->retval = retval;
3915   vam->result_ready = 1;
3916 }
3917
3918 static void
3919   vl_api_one_adjacencies_get_reply_t_handler
3920   (vl_api_one_adjacencies_get_reply_t * mp)
3921 {
3922   vat_main_t *vam = &vat_main;
3923   u32 i, n;
3924   int retval = clib_net_to_host_u32 (mp->retval);
3925   vl_api_one_adjacency_t *a;
3926
3927   if (retval)
3928     goto end;
3929
3930   n = clib_net_to_host_u32 (mp->count);
3931
3932   for (i = 0; i < n; i++)
3933     {
3934       a = &mp->adjacencies[i];
3935       print (vam->ofp, "%U %40U",
3936              format_lisp_flat_eid, a->leid, format_lisp_flat_eid, a->reid);
3937     }
3938
3939 end:
3940   vam->retval = retval;
3941   vam->result_ready = 1;
3942 }
3943
3944 static void
3945   vl_api_one_adjacencies_get_reply_t_handler_json
3946   (vl_api_one_adjacencies_get_reply_t * mp)
3947 {
3948   u8 *s = 0;
3949   vat_main_t *vam = &vat_main;
3950   vat_json_node_t *e = 0, root;
3951   u32 i, n;
3952   int retval = clib_net_to_host_u32 (mp->retval);
3953   vl_api_one_adjacency_t *a;
3954
3955   if (retval)
3956     goto end;
3957
3958   n = clib_net_to_host_u32 (mp->count);
3959   vat_json_init_array (&root);
3960
3961   for (i = 0; i < n; i++)
3962     {
3963       e = vat_json_array_add (&root);
3964       a = &mp->adjacencies[i];
3965
3966       vat_json_init_object (e);
3967       s = format (0, "%U", format_lisp_flat_eid, a->leid);
3968       vec_add1 (s, 0);
3969       vat_json_object_add_string_copy (e, "leid", s);
3970       vec_free (s);
3971
3972       s = format (0, "%U", format_lisp_flat_eid, a->reid);
3973       vec_add1 (s, 0);
3974       vat_json_object_add_string_copy (e, "reid", s);
3975       vec_free (s);
3976     }
3977
3978   vat_json_print (vam->ofp, &root);
3979   vat_json_free (&root);
3980
3981 end:
3982   vam->retval = retval;
3983   vam->result_ready = 1;
3984 }
3985
3986 static void
3987 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3988 {
3989   vat_main_t *vam = &vat_main;
3990
3991   print (vam->ofp, "%=20U",
3992          mp->ip_address.af ? format_ip6_address : format_ip4_address,
3993          mp->ip_address.un);
3994 }
3995
3996 static void
3997   vl_api_one_map_server_details_t_handler_json
3998   (vl_api_one_map_server_details_t * mp)
3999 {
4000   vat_main_t *vam = &vat_main;
4001   vat_json_node_t *node = NULL;
4002   struct in6_addr ip6;
4003   struct in_addr ip4;
4004
4005   if (VAT_JSON_ARRAY != vam->json_tree.type)
4006     {
4007       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4008       vat_json_init_array (&vam->json_tree);
4009     }
4010   node = vat_json_array_add (&vam->json_tree);
4011
4012   vat_json_init_object (node);
4013   if (mp->ip_address.af)
4014     {
4015       clib_memcpy (&ip6, mp->ip_address.un.ip6, sizeof (ip6));
4016       vat_json_object_add_ip6 (node, "map-server", ip6);
4017     }
4018   else
4019     {
4020       clib_memcpy (&ip4, mp->ip_address.un.ip4, sizeof (ip4));
4021       vat_json_object_add_ip4 (node, "map-server", ip4);
4022     }
4023 }
4024
4025 static void
4026 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4027                                            * mp)
4028 {
4029   vat_main_t *vam = &vat_main;
4030
4031   print (vam->ofp, "%=20U",
4032          mp->ip_address.af ? format_ip6_address : format_ip4_address,
4033          mp->ip_address.un);
4034 }
4035
4036 static void
4037   vl_api_one_map_resolver_details_t_handler_json
4038   (vl_api_one_map_resolver_details_t * mp)
4039 {
4040   vat_main_t *vam = &vat_main;
4041   vat_json_node_t *node = NULL;
4042   struct in6_addr ip6;
4043   struct in_addr ip4;
4044
4045   if (VAT_JSON_ARRAY != vam->json_tree.type)
4046     {
4047       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4048       vat_json_init_array (&vam->json_tree);
4049     }
4050   node = vat_json_array_add (&vam->json_tree);
4051
4052   vat_json_init_object (node);
4053   if (mp->ip_address.af)
4054     {
4055       clib_memcpy (&ip6, mp->ip_address.un.ip6, sizeof (ip6));
4056       vat_json_object_add_ip6 (node, "map resolver", ip6);
4057     }
4058   else
4059     {
4060       clib_memcpy (&ip4, mp->ip_address.un.ip4, sizeof (ip4));
4061       vat_json_object_add_ip4 (node, "map resolver", ip4);
4062     }
4063 }
4064
4065 static void
4066 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4067 {
4068   vat_main_t *vam = &vat_main;
4069   i32 retval = ntohl (mp->retval);
4070
4071   if (0 <= retval)
4072     {
4073       print (vam->ofp, "feature: %s\ngpe: %s",
4074              mp->feature_status ? "enabled" : "disabled",
4075              mp->gpe_status ? "enabled" : "disabled");
4076     }
4077
4078   vam->retval = retval;
4079   vam->result_ready = 1;
4080 }
4081
4082 static void
4083   vl_api_show_one_status_reply_t_handler_json
4084   (vl_api_show_one_status_reply_t * mp)
4085 {
4086   vat_main_t *vam = &vat_main;
4087   vat_json_node_t node;
4088   u8 *gpe_status = NULL;
4089   u8 *feature_status = NULL;
4090
4091   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4092   feature_status = format (0, "%s",
4093                            mp->feature_status ? "enabled" : "disabled");
4094   vec_add1 (gpe_status, 0);
4095   vec_add1 (feature_status, 0);
4096
4097   vat_json_init_object (&node);
4098   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4099   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4100
4101   vec_free (gpe_status);
4102   vec_free (feature_status);
4103
4104   vat_json_print (vam->ofp, &node);
4105   vat_json_free (&node);
4106
4107   vam->retval = ntohl (mp->retval);
4108   vam->result_ready = 1;
4109 }
4110
4111 static void
4112   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4113   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4114 {
4115   vat_main_t *vam = &vat_main;
4116   i32 retval = ntohl (mp->retval);
4117
4118   if (retval >= 0)
4119     {
4120       print (vam->ofp, "%=20s", mp->locator_set_name);
4121     }
4122
4123   vam->retval = retval;
4124   vam->result_ready = 1;
4125 }
4126
4127 static void
4128   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4129   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4130 {
4131   vat_main_t *vam = &vat_main;
4132   vat_json_node_t *node = NULL;
4133
4134   if (VAT_JSON_ARRAY != vam->json_tree.type)
4135     {
4136       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4137       vat_json_init_array (&vam->json_tree);
4138     }
4139   node = vat_json_array_add (&vam->json_tree);
4140
4141   vat_json_init_object (node);
4142   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4143
4144   vat_json_print (vam->ofp, node);
4145   vat_json_free (node);
4146
4147   vam->retval = ntohl (mp->retval);
4148   vam->result_ready = 1;
4149 }
4150
4151 static u8 *
4152 format_lisp_map_request_mode (u8 * s, va_list * args)
4153 {
4154   u32 mode = va_arg (*args, u32);
4155
4156   switch (mode)
4157     {
4158     case 0:
4159       return format (0, "dst-only");
4160     case 1:
4161       return format (0, "src-dst");
4162     }
4163   return 0;
4164 }
4165
4166 static void
4167   vl_api_show_one_map_request_mode_reply_t_handler
4168   (vl_api_show_one_map_request_mode_reply_t * mp)
4169 {
4170   vat_main_t *vam = &vat_main;
4171   i32 retval = ntohl (mp->retval);
4172
4173   if (0 <= retval)
4174     {
4175       u32 mode = mp->mode;
4176       print (vam->ofp, "map_request_mode: %U",
4177              format_lisp_map_request_mode, mode);
4178     }
4179
4180   vam->retval = retval;
4181   vam->result_ready = 1;
4182 }
4183
4184 static void
4185   vl_api_show_one_map_request_mode_reply_t_handler_json
4186   (vl_api_show_one_map_request_mode_reply_t * mp)
4187 {
4188   vat_main_t *vam = &vat_main;
4189   vat_json_node_t node;
4190   u8 *s = 0;
4191   u32 mode;
4192
4193   mode = mp->mode;
4194   s = format (0, "%U", format_lisp_map_request_mode, mode);
4195   vec_add1 (s, 0);
4196
4197   vat_json_init_object (&node);
4198   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4199   vat_json_print (vam->ofp, &node);
4200   vat_json_free (&node);
4201
4202   vec_free (s);
4203   vam->retval = ntohl (mp->retval);
4204   vam->result_ready = 1;
4205 }
4206
4207 static void
4208   vl_api_one_show_xtr_mode_reply_t_handler
4209   (vl_api_one_show_xtr_mode_reply_t * mp)
4210 {
4211   vat_main_t *vam = &vat_main;
4212   i32 retval = ntohl (mp->retval);
4213
4214   if (0 <= retval)
4215     {
4216       print (vam->ofp, "%s\n", mp->is_enable ? "enabled" : "disabled");
4217     }
4218
4219   vam->retval = retval;
4220   vam->result_ready = 1;
4221 }
4222
4223 static void
4224   vl_api_one_show_xtr_mode_reply_t_handler_json
4225   (vl_api_one_show_xtr_mode_reply_t * mp)
4226 {
4227   vat_main_t *vam = &vat_main;
4228   vat_json_node_t node;
4229   u8 *status = 0;
4230
4231   status = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
4232   vec_add1 (status, 0);
4233
4234   vat_json_init_object (&node);
4235   vat_json_object_add_string_copy (&node, "status", status);
4236
4237   vec_free (status);
4238
4239   vat_json_print (vam->ofp, &node);
4240   vat_json_free (&node);
4241
4242   vam->retval = ntohl (mp->retval);
4243   vam->result_ready = 1;
4244 }
4245
4246 static void
4247   vl_api_one_show_pitr_mode_reply_t_handler
4248   (vl_api_one_show_pitr_mode_reply_t * mp)
4249 {
4250   vat_main_t *vam = &vat_main;
4251   i32 retval = ntohl (mp->retval);
4252
4253   if (0 <= retval)
4254     {
4255       print (vam->ofp, "%s\n", mp->is_enable ? "enabled" : "disabled");
4256     }
4257
4258   vam->retval = retval;
4259   vam->result_ready = 1;
4260 }
4261
4262 static void
4263   vl_api_one_show_pitr_mode_reply_t_handler_json
4264   (vl_api_one_show_pitr_mode_reply_t * mp)
4265 {
4266   vat_main_t *vam = &vat_main;
4267   vat_json_node_t node;
4268   u8 *status = 0;
4269
4270   status = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
4271   vec_add1 (status, 0);
4272
4273   vat_json_init_object (&node);
4274   vat_json_object_add_string_copy (&node, "status", status);
4275
4276   vec_free (status);
4277
4278   vat_json_print (vam->ofp, &node);
4279   vat_json_free (&node);
4280
4281   vam->retval = ntohl (mp->retval);
4282   vam->result_ready = 1;
4283 }
4284
4285 static void
4286   vl_api_one_show_petr_mode_reply_t_handler
4287   (vl_api_one_show_petr_mode_reply_t * mp)
4288 {
4289   vat_main_t *vam = &vat_main;
4290   i32 retval = ntohl (mp->retval);
4291
4292   if (0 <= retval)
4293     {
4294       print (vam->ofp, "%s\n", mp->is_enable ? "enabled" : "disabled");
4295     }
4296
4297   vam->retval = retval;
4298   vam->result_ready = 1;
4299 }
4300
4301 static void
4302   vl_api_one_show_petr_mode_reply_t_handler_json
4303   (vl_api_one_show_petr_mode_reply_t * mp)
4304 {
4305   vat_main_t *vam = &vat_main;
4306   vat_json_node_t node;
4307   u8 *status = 0;
4308
4309   status = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
4310   vec_add1 (status, 0);
4311
4312   vat_json_init_object (&node);
4313   vat_json_object_add_string_copy (&node, "status", status);
4314
4315   vec_free (status);
4316
4317   vat_json_print (vam->ofp, &node);
4318   vat_json_free (&node);
4319
4320   vam->retval = ntohl (mp->retval);
4321   vam->result_ready = 1;
4322 }
4323
4324 static void
4325   vl_api_show_one_use_petr_reply_t_handler
4326   (vl_api_show_one_use_petr_reply_t * mp)
4327 {
4328   vat_main_t *vam = &vat_main;
4329   i32 retval = ntohl (mp->retval);
4330
4331   if (0 <= retval)
4332     {
4333       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4334       if (mp->status)
4335         {
4336           print (vam->ofp, "Proxy-ETR address; %U",
4337                  mp->ip_address.af ? format_ip6_address : format_ip4_address,
4338                  mp->ip_address.un);
4339         }
4340     }
4341
4342   vam->retval = retval;
4343   vam->result_ready = 1;
4344 }
4345
4346 static void
4347   vl_api_show_one_use_petr_reply_t_handler_json
4348   (vl_api_show_one_use_petr_reply_t * mp)
4349 {
4350   vat_main_t *vam = &vat_main;
4351   vat_json_node_t node;
4352   u8 *status = 0;
4353   struct in_addr ip4;
4354   struct in6_addr ip6;
4355
4356   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4357   vec_add1 (status, 0);
4358
4359   vat_json_init_object (&node);
4360   vat_json_object_add_string_copy (&node, "status", status);
4361   if (mp->status)
4362     {
4363       if (mp->ip_address.af)
4364         {
4365           clib_memcpy (&ip6, mp->ip_address.un.ip6, sizeof (ip6));
4366           vat_json_object_add_ip6 (&node, "address", ip6);
4367         }
4368       else
4369         {
4370           clib_memcpy (&ip4, mp->ip_address.un.ip4, sizeof (ip4));
4371           vat_json_object_add_ip4 (&node, "address", ip4);
4372         }
4373     }
4374
4375   vec_free (status);
4376
4377   vat_json_print (vam->ofp, &node);
4378   vat_json_free (&node);
4379
4380   vam->retval = ntohl (mp->retval);
4381   vam->result_ready = 1;
4382 }
4383
4384 static void
4385   vl_api_show_one_nsh_mapping_reply_t_handler
4386   (vl_api_show_one_nsh_mapping_reply_t * mp)
4387 {
4388   vat_main_t *vam = &vat_main;
4389   i32 retval = ntohl (mp->retval);
4390
4391   if (0 <= retval)
4392     {
4393       print (vam->ofp, "%-20s%-16s",
4394              mp->is_set ? "set" : "not-set",
4395              mp->is_set ? (char *) mp->locator_set_name : "");
4396     }
4397
4398   vam->retval = retval;
4399   vam->result_ready = 1;
4400 }
4401
4402 static void
4403   vl_api_show_one_nsh_mapping_reply_t_handler_json
4404   (vl_api_show_one_nsh_mapping_reply_t * mp)
4405 {
4406   vat_main_t *vam = &vat_main;
4407   vat_json_node_t node;
4408   u8 *status = 0;
4409
4410   status = format (0, "%s", mp->is_set ? "yes" : "no");
4411   vec_add1 (status, 0);
4412
4413   vat_json_init_object (&node);
4414   vat_json_object_add_string_copy (&node, "is_set", status);
4415   if (mp->is_set)
4416     {
4417       vat_json_object_add_string_copy (&node, "locator_set",
4418                                        mp->locator_set_name);
4419     }
4420
4421   vec_free (status);
4422
4423   vat_json_print (vam->ofp, &node);
4424   vat_json_free (&node);
4425
4426   vam->retval = ntohl (mp->retval);
4427   vam->result_ready = 1;
4428 }
4429
4430 static void
4431   vl_api_show_one_map_register_ttl_reply_t_handler
4432   (vl_api_show_one_map_register_ttl_reply_t * mp)
4433 {
4434   vat_main_t *vam = &vat_main;
4435   i32 retval = ntohl (mp->retval);
4436
4437   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4438
4439   if (0 <= retval)
4440     {
4441       print (vam->ofp, "ttl: %u", mp->ttl);
4442     }
4443
4444   vam->retval = retval;
4445   vam->result_ready = 1;
4446 }
4447
4448 static void
4449   vl_api_show_one_map_register_ttl_reply_t_handler_json
4450   (vl_api_show_one_map_register_ttl_reply_t * mp)
4451 {
4452   vat_main_t *vam = &vat_main;
4453   vat_json_node_t node;
4454
4455   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4456   vat_json_init_object (&node);
4457   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4458
4459   vat_json_print (vam->ofp, &node);
4460   vat_json_free (&node);
4461
4462   vam->retval = ntohl (mp->retval);
4463   vam->result_ready = 1;
4464 }
4465
4466 static void
4467 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4468 {
4469   vat_main_t *vam = &vat_main;
4470   i32 retval = ntohl (mp->retval);
4471
4472   if (0 <= retval)
4473     {
4474       print (vam->ofp, "%-20s%-16s",
4475              mp->status ? "enabled" : "disabled",
4476              mp->status ? (char *) mp->locator_set_name : "");
4477     }
4478
4479   vam->retval = retval;
4480   vam->result_ready = 1;
4481 }
4482
4483 static void
4484 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4485 {
4486   vat_main_t *vam = &vat_main;
4487   vat_json_node_t node;
4488   u8 *status = 0;
4489
4490   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4491   vec_add1 (status, 0);
4492
4493   vat_json_init_object (&node);
4494   vat_json_object_add_string_copy (&node, "status", status);
4495   if (mp->status)
4496     {
4497       vat_json_object_add_string_copy (&node, "locator_set",
4498                                        mp->locator_set_name);
4499     }
4500
4501   vec_free (status);
4502
4503   vat_json_print (vam->ofp, &node);
4504   vat_json_free (&node);
4505
4506   vam->retval = ntohl (mp->retval);
4507   vam->result_ready = 1;
4508 }
4509
4510 static u8 *
4511 format_policer_type (u8 * s, va_list * va)
4512 {
4513   u32 i = va_arg (*va, u32);
4514
4515   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4516     s = format (s, "1r2c");
4517   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4518     s = format (s, "1r3c");
4519   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4520     s = format (s, "2r3c-2698");
4521   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4522     s = format (s, "2r3c-4115");
4523   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4524     s = format (s, "2r3c-mef5cf1");
4525   else
4526     s = format (s, "ILLEGAL");
4527   return s;
4528 }
4529
4530 static u8 *
4531 format_policer_rate_type (u8 * s, va_list * va)
4532 {
4533   u32 i = va_arg (*va, u32);
4534
4535   if (i == SSE2_QOS_RATE_KBPS)
4536     s = format (s, "kbps");
4537   else if (i == SSE2_QOS_RATE_PPS)
4538     s = format (s, "pps");
4539   else
4540     s = format (s, "ILLEGAL");
4541   return s;
4542 }
4543
4544 static u8 *
4545 format_policer_round_type (u8 * s, va_list * va)
4546 {
4547   u32 i = va_arg (*va, u32);
4548
4549   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4550     s = format (s, "closest");
4551   else if (i == SSE2_QOS_ROUND_TO_UP)
4552     s = format (s, "up");
4553   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4554     s = format (s, "down");
4555   else
4556     s = format (s, "ILLEGAL");
4557   return s;
4558 }
4559
4560 static u8 *
4561 format_policer_action_type (u8 * s, va_list * va)
4562 {
4563   u32 i = va_arg (*va, u32);
4564
4565   if (i == SSE2_QOS_ACTION_DROP)
4566     s = format (s, "drop");
4567   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4568     s = format (s, "transmit");
4569   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4570     s = format (s, "mark-and-transmit");
4571   else
4572     s = format (s, "ILLEGAL");
4573   return s;
4574 }
4575
4576 static u8 *
4577 format_dscp (u8 * s, va_list * va)
4578 {
4579   u32 i = va_arg (*va, u32);
4580   char *t = 0;
4581
4582   switch (i)
4583     {
4584 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4585       foreach_vnet_dscp
4586 #undef _
4587     default:
4588       return format (s, "ILLEGAL");
4589     }
4590   s = format (s, "%s", t);
4591   return s;
4592 }
4593
4594 static void
4595 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4596 {
4597   vat_main_t *vam = &vat_main;
4598   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4599
4600   if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4601     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp);
4602   else
4603     conform_dscp_str = format (0, "");
4604
4605   if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4606     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp);
4607   else
4608     exceed_dscp_str = format (0, "");
4609
4610   if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4611     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp);
4612   else
4613     violate_dscp_str = format (0, "");
4614
4615   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4616          "rate type %U, round type %U, %s rate, %s color-aware, "
4617          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4618          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4619          "conform action %U%s, exceed action %U%s, violate action %U%s",
4620          mp->name,
4621          format_policer_type, mp->type,
4622          ntohl (mp->cir),
4623          ntohl (mp->eir),
4624          clib_net_to_host_u64 (mp->cb),
4625          clib_net_to_host_u64 (mp->eb),
4626          format_policer_rate_type, mp->rate_type,
4627          format_policer_round_type, mp->round_type,
4628          mp->single_rate ? "single" : "dual",
4629          mp->color_aware ? "is" : "not",
4630          ntohl (mp->cir_tokens_per_period),
4631          ntohl (mp->pir_tokens_per_period),
4632          ntohl (mp->scale),
4633          ntohl (mp->current_limit),
4634          ntohl (mp->current_bucket),
4635          ntohl (mp->extended_limit),
4636          ntohl (mp->extended_bucket),
4637          clib_net_to_host_u64 (mp->last_update_time),
4638          format_policer_action_type, mp->conform_action.type,
4639          conform_dscp_str,
4640          format_policer_action_type, mp->exceed_action.type,
4641          exceed_dscp_str,
4642          format_policer_action_type, mp->violate_action.type,
4643          violate_dscp_str);
4644
4645   vec_free (conform_dscp_str);
4646   vec_free (exceed_dscp_str);
4647   vec_free (violate_dscp_str);
4648 }
4649
4650 static void vl_api_policer_details_t_handler_json
4651   (vl_api_policer_details_t * mp)
4652 {
4653   vat_main_t *vam = &vat_main;
4654   vat_json_node_t *node;
4655   u8 *rate_type_str, *round_type_str, *type_str;
4656   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4657
4658   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4659   round_type_str =
4660     format (0, "%U", format_policer_round_type, mp->round_type);
4661   type_str = format (0, "%U", format_policer_type, mp->type);
4662   conform_action_str = format (0, "%U", format_policer_action_type,
4663                                mp->conform_action.type);
4664   exceed_action_str = format (0, "%U", format_policer_action_type,
4665                               mp->exceed_action.type);
4666   violate_action_str = format (0, "%U", format_policer_action_type,
4667                                mp->violate_action.type);
4668
4669   if (VAT_JSON_ARRAY != vam->json_tree.type)
4670     {
4671       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4672       vat_json_init_array (&vam->json_tree);
4673     }
4674   node = vat_json_array_add (&vam->json_tree);
4675
4676   vat_json_init_object (node);
4677   vat_json_object_add_string_copy (node, "name", mp->name);
4678   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4679   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4680   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4681   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4682   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4683   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4684   vat_json_object_add_string_copy (node, "type", type_str);
4685   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4686   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4687   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4688   vat_json_object_add_uint (node, "cir_tokens_per_period",
4689                             ntohl (mp->cir_tokens_per_period));
4690   vat_json_object_add_uint (node, "eir_tokens_per_period",
4691                             ntohl (mp->pir_tokens_per_period));
4692   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4693   vat_json_object_add_uint (node, "current_bucket",
4694                             ntohl (mp->current_bucket));
4695   vat_json_object_add_uint (node, "extended_limit",
4696                             ntohl (mp->extended_limit));
4697   vat_json_object_add_uint (node, "extended_bucket",
4698                             ntohl (mp->extended_bucket));
4699   vat_json_object_add_uint (node, "last_update_time",
4700                             ntohl (mp->last_update_time));
4701   vat_json_object_add_string_copy (node, "conform_action",
4702                                    conform_action_str);
4703   if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4704     {
4705       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp);
4706       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4707       vec_free (dscp_str);
4708     }
4709   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4710   if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4711     {
4712       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp);
4713       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4714       vec_free (dscp_str);
4715     }
4716   vat_json_object_add_string_copy (node, "violate_action",
4717                                    violate_action_str);
4718   if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4719     {
4720       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp);
4721       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4722       vec_free (dscp_str);
4723     }
4724
4725   vec_free (rate_type_str);
4726   vec_free (round_type_str);
4727   vec_free (type_str);
4728   vec_free (conform_action_str);
4729   vec_free (exceed_action_str);
4730   vec_free (violate_action_str);
4731 }
4732
4733 static void
4734 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4735                                            mp)
4736 {
4737   vat_main_t *vam = &vat_main;
4738   int i, count = ntohl (mp->count);
4739
4740   if (count > 0)
4741     print (vam->ofp, "classify table ids (%d) : ", count);
4742   for (i = 0; i < count; i++)
4743     {
4744       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4745       print (vam->ofp, (i < count - 1) ? "," : "");
4746     }
4747   vam->retval = ntohl (mp->retval);
4748   vam->result_ready = 1;
4749 }
4750
4751 static void
4752   vl_api_classify_table_ids_reply_t_handler_json
4753   (vl_api_classify_table_ids_reply_t * mp)
4754 {
4755   vat_main_t *vam = &vat_main;
4756   int i, count = ntohl (mp->count);
4757
4758   if (count > 0)
4759     {
4760       vat_json_node_t node;
4761
4762       vat_json_init_object (&node);
4763       for (i = 0; i < count; i++)
4764         {
4765           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4766         }
4767       vat_json_print (vam->ofp, &node);
4768       vat_json_free (&node);
4769     }
4770   vam->retval = ntohl (mp->retval);
4771   vam->result_ready = 1;
4772 }
4773
4774 static void
4775   vl_api_classify_table_by_interface_reply_t_handler
4776   (vl_api_classify_table_by_interface_reply_t * mp)
4777 {
4778   vat_main_t *vam = &vat_main;
4779   u32 table_id;
4780
4781   table_id = ntohl (mp->l2_table_id);
4782   if (table_id != ~0)
4783     print (vam->ofp, "l2 table id : %d", table_id);
4784   else
4785     print (vam->ofp, "l2 table id : No input ACL tables configured");
4786   table_id = ntohl (mp->ip4_table_id);
4787   if (table_id != ~0)
4788     print (vam->ofp, "ip4 table id : %d", table_id);
4789   else
4790     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4791   table_id = ntohl (mp->ip6_table_id);
4792   if (table_id != ~0)
4793     print (vam->ofp, "ip6 table id : %d", table_id);
4794   else
4795     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4796   vam->retval = ntohl (mp->retval);
4797   vam->result_ready = 1;
4798 }
4799
4800 static void
4801   vl_api_classify_table_by_interface_reply_t_handler_json
4802   (vl_api_classify_table_by_interface_reply_t * mp)
4803 {
4804   vat_main_t *vam = &vat_main;
4805   vat_json_node_t node;
4806
4807   vat_json_init_object (&node);
4808
4809   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4810   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4811   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4812
4813   vat_json_print (vam->ofp, &node);
4814   vat_json_free (&node);
4815
4816   vam->retval = ntohl (mp->retval);
4817   vam->result_ready = 1;
4818 }
4819
4820 static void vl_api_policer_add_del_reply_t_handler
4821   (vl_api_policer_add_del_reply_t * mp)
4822 {
4823   vat_main_t *vam = &vat_main;
4824   i32 retval = ntohl (mp->retval);
4825   if (vam->async_mode)
4826     {
4827       vam->async_errors += (retval < 0);
4828     }
4829   else
4830     {
4831       vam->retval = retval;
4832       vam->result_ready = 1;
4833       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4834         /*
4835          * Note: this is just barely thread-safe, depends on
4836          * the main thread spinning waiting for an answer...
4837          */
4838         errmsg ("policer index %d", ntohl (mp->policer_index));
4839     }
4840 }
4841
4842 static void vl_api_policer_add_del_reply_t_handler_json
4843   (vl_api_policer_add_del_reply_t * mp)
4844 {
4845   vat_main_t *vam = &vat_main;
4846   vat_json_node_t node;
4847
4848   vat_json_init_object (&node);
4849   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4850   vat_json_object_add_uint (&node, "policer_index",
4851                             ntohl (mp->policer_index));
4852
4853   vat_json_print (vam->ofp, &node);
4854   vat_json_free (&node);
4855
4856   vam->retval = ntohl (mp->retval);
4857   vam->result_ready = 1;
4858 }
4859
4860 /* Format hex dump. */
4861 u8 *
4862 format_hex_bytes (u8 * s, va_list * va)
4863 {
4864   u8 *bytes = va_arg (*va, u8 *);
4865   int n_bytes = va_arg (*va, int);
4866   uword i;
4867
4868   /* Print short or long form depending on byte count. */
4869   uword short_form = n_bytes <= 32;
4870   u32 indent = format_get_indent (s);
4871
4872   if (n_bytes == 0)
4873     return s;
4874
4875   for (i = 0; i < n_bytes; i++)
4876     {
4877       if (!short_form && (i % 32) == 0)
4878         s = format (s, "%08x: ", i);
4879       s = format (s, "%02x", bytes[i]);
4880       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4881         s = format (s, "\n%U", format_white_space, indent);
4882     }
4883
4884   return s;
4885 }
4886
4887 static void
4888 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4889                                             * mp)
4890 {
4891   vat_main_t *vam = &vat_main;
4892   i32 retval = ntohl (mp->retval);
4893   if (retval == 0)
4894     {
4895       print (vam->ofp, "classify table info :");
4896       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4897              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4898              ntohl (mp->miss_next_index));
4899       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4900              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4901              ntohl (mp->match_n_vectors));
4902       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4903              ntohl (mp->mask_length));
4904     }
4905   vam->retval = retval;
4906   vam->result_ready = 1;
4907 }
4908
4909 static void
4910   vl_api_classify_table_info_reply_t_handler_json
4911   (vl_api_classify_table_info_reply_t * mp)
4912 {
4913   vat_main_t *vam = &vat_main;
4914   vat_json_node_t node;
4915
4916   i32 retval = ntohl (mp->retval);
4917   if (retval == 0)
4918     {
4919       vat_json_init_object (&node);
4920
4921       vat_json_object_add_int (&node, "sessions",
4922                                ntohl (mp->active_sessions));
4923       vat_json_object_add_int (&node, "nexttbl",
4924                                ntohl (mp->next_table_index));
4925       vat_json_object_add_int (&node, "nextnode",
4926                                ntohl (mp->miss_next_index));
4927       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4928       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4929       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4930       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4931                       ntohl (mp->mask_length), 0);
4932       vat_json_object_add_string_copy (&node, "mask", s);
4933
4934       vat_json_print (vam->ofp, &node);
4935       vat_json_free (&node);
4936     }
4937   vam->retval = ntohl (mp->retval);
4938   vam->result_ready = 1;
4939 }
4940
4941 static void
4942 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4943                                            mp)
4944 {
4945   vat_main_t *vam = &vat_main;
4946
4947   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4948          ntohl (mp->hit_next_index), ntohl (mp->advance),
4949          ntohl (mp->opaque_index));
4950   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4951          ntohl (mp->match_length));
4952 }
4953
4954 static void
4955   vl_api_classify_session_details_t_handler_json
4956   (vl_api_classify_session_details_t * mp)
4957 {
4958   vat_main_t *vam = &vat_main;
4959   vat_json_node_t *node = NULL;
4960
4961   if (VAT_JSON_ARRAY != vam->json_tree.type)
4962     {
4963       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4964       vat_json_init_array (&vam->json_tree);
4965     }
4966   node = vat_json_array_add (&vam->json_tree);
4967
4968   vat_json_init_object (node);
4969   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4970   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4971   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4972   u8 *s =
4973     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4974             0);
4975   vat_json_object_add_string_copy (node, "match", s);
4976 }
4977
4978 static void vl_api_pg_create_interface_reply_t_handler
4979   (vl_api_pg_create_interface_reply_t * mp)
4980 {
4981   vat_main_t *vam = &vat_main;
4982
4983   vam->retval = ntohl (mp->retval);
4984   vam->result_ready = 1;
4985 }
4986
4987 static void vl_api_pg_create_interface_reply_t_handler_json
4988   (vl_api_pg_create_interface_reply_t * mp)
4989 {
4990   vat_main_t *vam = &vat_main;
4991   vat_json_node_t node;
4992
4993   i32 retval = ntohl (mp->retval);
4994   if (retval == 0)
4995     {
4996       vat_json_init_object (&node);
4997
4998       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4999
5000       vat_json_print (vam->ofp, &node);
5001       vat_json_free (&node);
5002     }
5003   vam->retval = ntohl (mp->retval);
5004   vam->result_ready = 1;
5005 }
5006
5007 static void vl_api_policer_classify_details_t_handler
5008   (vl_api_policer_classify_details_t * mp)
5009 {
5010   vat_main_t *vam = &vat_main;
5011
5012   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5013          ntohl (mp->table_index));
5014 }
5015
5016 static void vl_api_policer_classify_details_t_handler_json
5017   (vl_api_policer_classify_details_t * mp)
5018 {
5019   vat_main_t *vam = &vat_main;
5020   vat_json_node_t *node;
5021
5022   if (VAT_JSON_ARRAY != vam->json_tree.type)
5023     {
5024       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5025       vat_json_init_array (&vam->json_tree);
5026     }
5027   node = vat_json_array_add (&vam->json_tree);
5028
5029   vat_json_init_object (node);
5030   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5031   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5032 }
5033
5034 static void vl_api_flow_classify_details_t_handler
5035   (vl_api_flow_classify_details_t * mp)
5036 {
5037   vat_main_t *vam = &vat_main;
5038
5039   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5040          ntohl (mp->table_index));
5041 }
5042
5043 static void vl_api_flow_classify_details_t_handler_json
5044   (vl_api_flow_classify_details_t * mp)
5045 {
5046   vat_main_t *vam = &vat_main;
5047   vat_json_node_t *node;
5048
5049   if (VAT_JSON_ARRAY != vam->json_tree.type)
5050     {
5051       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5052       vat_json_init_array (&vam->json_tree);
5053     }
5054   node = vat_json_array_add (&vam->json_tree);
5055
5056   vat_json_init_object (node);
5057   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5058   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5059 }
5060
5061 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5062 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5063 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5064 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5065 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5066 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5067 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5068 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5069 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5070 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5071
5072 /*
5073  * Generate boilerplate reply handlers, which
5074  * dig the return value out of the xxx_reply_t API message,
5075  * stick it into vam->retval, and set vam->result_ready
5076  *
5077  * Could also do this by pointing N message decode slots at
5078  * a single function, but that could break in subtle ways.
5079  */
5080
5081 #define foreach_standard_reply_retval_handler           \
5082 _(sw_interface_set_flags_reply)                         \
5083 _(sw_interface_add_del_address_reply)                   \
5084 _(sw_interface_set_rx_mode_reply)                       \
5085 _(sw_interface_set_rx_placement_reply)                  \
5086 _(sw_interface_set_table_reply)                         \
5087 _(sw_interface_set_mpls_enable_reply)                   \
5088 _(sw_interface_set_vpath_reply)                         \
5089 _(sw_interface_set_vxlan_bypass_reply)                  \
5090 _(sw_interface_set_geneve_bypass_reply)                 \
5091 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5092 _(sw_interface_set_l2_bridge_reply)                     \
5093 _(sw_interface_set_bond_weight_reply)                   \
5094 _(bridge_domain_add_del_reply)                          \
5095 _(sw_interface_set_l2_xconnect_reply)                   \
5096 _(l2fib_add_del_reply)                                  \
5097 _(l2fib_flush_int_reply)                                \
5098 _(l2fib_flush_bd_reply)                                 \
5099 _(ip_route_add_del_reply)                               \
5100 _(ip_table_add_del_reply)                               \
5101 _(ip_table_replace_begin_reply)                         \
5102 _(ip_table_flush_reply)                                 \
5103 _(ip_table_replace_end_reply)                           \
5104 _(ip_mroute_add_del_reply)                              \
5105 _(mpls_route_add_del_reply)                             \
5106 _(mpls_table_add_del_reply)                             \
5107 _(mpls_ip_bind_unbind_reply)                            \
5108 _(bier_route_add_del_reply)                             \
5109 _(bier_table_add_del_reply)                             \
5110 _(sw_interface_set_unnumbered_reply)                    \
5111 _(set_ip_flow_hash_reply)                               \
5112 _(sw_interface_ip6_enable_disable_reply)                \
5113 _(l2_patch_add_del_reply)                               \
5114 _(sr_mpls_policy_add_reply)                             \
5115 _(sr_mpls_policy_mod_reply)                             \
5116 _(sr_mpls_policy_del_reply)                             \
5117 _(sr_policy_add_reply)                                  \
5118 _(sr_policy_mod_reply)                                  \
5119 _(sr_policy_del_reply)                                  \
5120 _(sr_localsid_add_del_reply)                            \
5121 _(sr_steering_add_del_reply)                            \
5122 _(classify_add_del_session_reply)                       \
5123 _(classify_set_interface_ip_table_reply)                \
5124 _(classify_set_interface_l2_tables_reply)               \
5125 _(l2tpv3_set_tunnel_cookies_reply)                      \
5126 _(l2tpv3_interface_enable_disable_reply)                \
5127 _(l2tpv3_set_lookup_key_reply)                          \
5128 _(l2_fib_clear_table_reply)                             \
5129 _(l2_interface_efp_filter_reply)                        \
5130 _(l2_interface_vlan_tag_rewrite_reply)                  \
5131 _(modify_vhost_user_if_reply)                           \
5132 _(delete_vhost_user_if_reply)                           \
5133 _(want_l2_macs_events_reply)                            \
5134 _(input_acl_set_interface_reply)                        \
5135 _(ipsec_spd_add_del_reply)                              \
5136 _(ipsec_interface_add_del_spd_reply)                    \
5137 _(ipsec_spd_entry_add_del_reply)                        \
5138 _(ipsec_sad_entry_add_del_reply)                        \
5139 _(ipsec_tunnel_if_add_del_reply)                        \
5140 _(ipsec_tunnel_if_set_sa_reply)                         \
5141 _(delete_loopback_reply)                                \
5142 _(bd_ip_mac_add_del_reply)                              \
5143 _(bd_ip_mac_flush_reply)                                \
5144 _(want_interface_events_reply)                          \
5145 _(cop_interface_enable_disable_reply)                   \
5146 _(cop_whitelist_enable_disable_reply)                   \
5147 _(sw_interface_clear_stats_reply)                       \
5148 _(ioam_enable_reply)                                    \
5149 _(ioam_disable_reply)                                   \
5150 _(one_add_del_locator_reply)                            \
5151 _(one_add_del_local_eid_reply)                          \
5152 _(one_add_del_remote_mapping_reply)                     \
5153 _(one_add_del_adjacency_reply)                          \
5154 _(one_add_del_map_resolver_reply)                       \
5155 _(one_add_del_map_server_reply)                         \
5156 _(one_enable_disable_reply)                             \
5157 _(one_rloc_probe_enable_disable_reply)                  \
5158 _(one_map_register_enable_disable_reply)                \
5159 _(one_map_register_set_ttl_reply)                       \
5160 _(one_set_transport_protocol_reply)                     \
5161 _(one_map_register_fallback_threshold_reply)            \
5162 _(one_pitr_set_locator_set_reply)                       \
5163 _(one_map_request_mode_reply)                           \
5164 _(one_add_del_map_request_itr_rlocs_reply)              \
5165 _(one_eid_table_add_del_map_reply)                      \
5166 _(one_use_petr_reply)                                   \
5167 _(one_stats_enable_disable_reply)                       \
5168 _(one_add_del_l2_arp_entry_reply)                       \
5169 _(one_add_del_ndp_entry_reply)                          \
5170 _(one_stats_flush_reply)                                \
5171 _(one_enable_disable_xtr_mode_reply)                    \
5172 _(one_enable_disable_pitr_mode_reply)                   \
5173 _(one_enable_disable_petr_mode_reply)                   \
5174 _(gpe_enable_disable_reply)                             \
5175 _(gpe_set_encap_mode_reply)                             \
5176 _(gpe_add_del_iface_reply)                              \
5177 _(gpe_add_del_native_fwd_rpath_reply)                   \
5178 _(af_packet_delete_reply)                               \
5179 _(policer_classify_set_interface_reply)                 \
5180 _(set_ipfix_exporter_reply)                             \
5181 _(set_ipfix_classify_stream_reply)                      \
5182 _(ipfix_classify_table_add_del_reply)                   \
5183 _(flow_classify_set_interface_reply)                    \
5184 _(sw_interface_span_enable_disable_reply)               \
5185 _(pg_capture_reply)                                     \
5186 _(pg_enable_disable_reply)                              \
5187 _(pg_interface_enable_disable_coalesce_reply)           \
5188 _(ip_source_and_port_range_check_add_del_reply)         \
5189 _(ip_source_and_port_range_check_interface_add_del_reply)\
5190 _(delete_subif_reply)                                   \
5191 _(l2_interface_pbb_tag_rewrite_reply)                   \
5192 _(set_punt_reply)                                       \
5193 _(feature_enable_disable_reply)                         \
5194 _(feature_gso_enable_disable_reply)                     \
5195 _(sw_interface_tag_add_del_reply)                       \
5196 _(sw_interface_add_del_mac_address_reply)               \
5197 _(hw_interface_set_mtu_reply)                           \
5198 _(p2p_ethernet_add_reply)                               \
5199 _(p2p_ethernet_del_reply)                               \
5200 _(lldp_config_reply)                                    \
5201 _(sw_interface_set_lldp_reply)                          \
5202 _(tcp_configure_src_addresses_reply)                    \
5203 _(session_rule_add_del_reply)                           \
5204 _(ip_container_proxy_add_del_reply)                     \
5205 _(output_acl_set_interface_reply)                       \
5206 _(qos_record_enable_disable_reply)                      \
5207 _(flow_add_reply)
5208
5209 #define _(n)                                    \
5210     static void vl_api_##n##_t_handler          \
5211     (vl_api_##n##_t * mp)                       \
5212     {                                           \
5213         vat_main_t * vam = &vat_main;           \
5214         i32 retval = ntohl(mp->retval);         \
5215         if (vam->async_mode) {                  \
5216             vam->async_errors += (retval < 0);  \
5217         } else {                                \
5218             vam->retval = retval;               \
5219             vam->result_ready = 1;              \
5220         }                                       \
5221     }
5222 foreach_standard_reply_retval_handler;
5223 #undef _
5224
5225 #define _(n)                                    \
5226     static void vl_api_##n##_t_handler_json     \
5227     (vl_api_##n##_t * mp)                       \
5228     {                                           \
5229         vat_main_t * vam = &vat_main;           \
5230         vat_json_node_t node;                   \
5231         vat_json_init_object(&node);            \
5232         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5233         vat_json_print(vam->ofp, &node);        \
5234         vam->retval = ntohl(mp->retval);        \
5235         vam->result_ready = 1;                  \
5236     }
5237 foreach_standard_reply_retval_handler;
5238 #undef _
5239
5240 /*
5241  * Table of message reply handlers, must include boilerplate handlers
5242  * we just generated
5243  */
5244
5245 #define foreach_vpe_api_reply_msg                                       \
5246 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5247 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5248 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5249 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5250 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5251 _(CLI_REPLY, cli_reply)                                                 \
5252 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5253 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5254   sw_interface_add_del_address_reply)                                   \
5255 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5256 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5257 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5258 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5259 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5260 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5261 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5262 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5263 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5264 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5265   sw_interface_set_l2_xconnect_reply)                                   \
5266 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5267   sw_interface_set_l2_bridge_reply)                                     \
5268 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5269 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5270 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5271 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5272 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5273 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5274 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5275 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5276 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5277 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5278 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5279 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5280 _(VIRTIO_PCI_CREATE_V2_REPLY, virtio_pci_create_v2_reply)               \
5281 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5282 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5283 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5284 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5285 _(BOND_ADD_MEMBER_REPLY, bond_add_member_reply)                         \
5286 _(BOND_DETACH_MEMBER_REPLY, bond_detach_member_reply)                   \
5287 _(SW_INTERFACE_SET_BOND_WEIGHT_REPLY, sw_interface_set_bond_weight_reply) \
5288 _(SW_BOND_INTERFACE_DETAILS, sw_bond_interface_details)                 \
5289 _(SW_MEMBER_INTERFACE_DETAILS, sw_member_interface_details)               \
5290 _(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply)                       \
5291 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5292 _(IP_TABLE_REPLACE_BEGIN_REPLY, ip_table_replace_begin_reply)           \
5293 _(IP_TABLE_FLUSH_REPLY, ip_table_flush_reply)                           \
5294 _(IP_TABLE_REPLACE_END_REPLY, ip_table_replace_end_reply)               \
5295 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5296 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5297 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5298 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5299 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5300 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5301 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5302 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5303   sw_interface_set_unnumbered_reply)                                    \
5304 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5305 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5306 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5307 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5308   sw_interface_ip6_enable_disable_reply)                                \
5309 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5310 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5311 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5312 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5313 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5314 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5315 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5316 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5317 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5318 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5319 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5320 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5321 classify_set_interface_ip_table_reply)                                  \
5322 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5323   classify_set_interface_l2_tables_reply)                               \
5324 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5325 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5326 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5327 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5328 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5329   l2tpv3_interface_enable_disable_reply)                                \
5330 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5331 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5332 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5333 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5334 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5335 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5336 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5337 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5338 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5339 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5340 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5341 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5342 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5343 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5344 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5345 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5346 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5347 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5348 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5349 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5350 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5351 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5352 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5353 _(L2_MACS_EVENT, l2_macs_event)                                         \
5354 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5355 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5356 _(IP_DETAILS, ip_details)                                               \
5357 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5358 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5359 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5360 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5361 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5362 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5363 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5364 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5365 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5366 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5367 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5368 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5369 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5370 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5371 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5372 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5373 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5374 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5375 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5376 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5377 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5378 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5379 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5380 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5381 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5382 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5383 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5384 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5385   one_map_register_enable_disable_reply)                                \
5386 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5387 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5388 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5389 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5390   one_map_register_fallback_threshold_reply)                            \
5391 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5392   one_rloc_probe_enable_disable_reply)                                  \
5393 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5394 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5395 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5396 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5397 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5398 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5399 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5400 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5401 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5402 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5403 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5404 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5405 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5406 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5407 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5408 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5409   show_one_stats_enable_disable_reply)                                  \
5410 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5411 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5412 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5413 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5414 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5415 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5416 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5417 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5418   one_enable_disable_pitr_mode_reply)                                   \
5419 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5420   one_enable_disable_petr_mode_reply)                                   \
5421 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5422 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5423 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5424 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5425 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5426 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5427 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5428 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5429 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5430 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5431 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5432 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5433   gpe_add_del_native_fwd_rpath_reply)                                   \
5434 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5435   gpe_fwd_entry_path_details)                                           \
5436 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5437 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5438   one_add_del_map_request_itr_rlocs_reply)                              \
5439 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5440   one_get_map_request_itr_rlocs_reply)                                  \
5441 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5442 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5443 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5444 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5445 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5446 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5447   show_one_map_register_state_reply)                                    \
5448 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5449 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5450   show_one_map_register_fallback_threshold_reply)                       \
5451 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5452 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5453 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5454 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5455 _(POLICER_DETAILS, policer_details)                                     \
5456 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5457 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5458 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5459 _(MPLS_TABLE_DETAILS, mpls_table_details)                               \
5460 _(MPLS_ROUTE_DETAILS, mpls_route_details)                               \
5461 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5462 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5463 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5464 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5465 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5466 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5467 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5468 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5469 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5470 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5471 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5472 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5473 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5474 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5475 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5476 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5477 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5478 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5479 _(PG_INTERFACE_ENABLE_DISABLE_COALESCE_REPLY, pg_interface_enable_disable_coalesce_reply) \
5480 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5481  ip_source_and_port_range_check_add_del_reply)                          \
5482 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5483  ip_source_and_port_range_check_interface_add_del_reply)                \
5484 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5485 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5486 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5487 _(IP_TABLE_DETAILS, ip_table_details)                                   \
5488 _(IP_ROUTE_DETAILS, ip_route_details)                                   \
5489 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5490 _(FEATURE_GSO_ENABLE_DISABLE_REPLY, feature_gso_enable_disable_reply)   \
5491 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5492 _(SW_INTERFACE_ADD_DEL_MAC_ADDRESS_REPLY, sw_interface_add_del_mac_address_reply) \
5493 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5494 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5495 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5496 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5497 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5498 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5499 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5500 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5501 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5502 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5503 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5504 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5505 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5506 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)             \
5507 _(FLOW_ADD_REPLY, flow_add_reply)   \
5508
5509 #define foreach_standalone_reply_msg                                    \
5510 _(SW_INTERFACE_EVENT, sw_interface_event)
5511
5512 typedef struct
5513 {
5514   u8 *name;
5515   u32 value;
5516 } name_sort_t;
5517
5518 #define STR_VTR_OP_CASE(op)     \
5519     case L2_VTR_ ## op:         \
5520         return "" # op;
5521
5522 static const char *
5523 str_vtr_op (u32 vtr_op)
5524 {
5525   switch (vtr_op)
5526     {
5527       STR_VTR_OP_CASE (DISABLED);
5528       STR_VTR_OP_CASE (PUSH_1);
5529       STR_VTR_OP_CASE (PUSH_2);
5530       STR_VTR_OP_CASE (POP_1);
5531       STR_VTR_OP_CASE (POP_2);
5532       STR_VTR_OP_CASE (TRANSLATE_1_1);
5533       STR_VTR_OP_CASE (TRANSLATE_1_2);
5534       STR_VTR_OP_CASE (TRANSLATE_2_1);
5535       STR_VTR_OP_CASE (TRANSLATE_2_2);
5536     }
5537
5538   return "UNKNOWN";
5539 }
5540
5541 static int
5542 dump_sub_interface_table (vat_main_t * vam)
5543 {
5544   const sw_interface_subif_t *sub = NULL;
5545
5546   if (vam->json_output)
5547     {
5548       clib_warning
5549         ("JSON output supported only for VPE API calls and dump_stats_table");
5550       return -99;
5551     }
5552
5553   print (vam->ofp,
5554          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5555          "Interface", "sw_if_index",
5556          "sub id", "dot1ad", "tags", "outer id",
5557          "inner id", "exact", "default", "outer any", "inner any");
5558
5559   vec_foreach (sub, vam->sw_if_subif_table)
5560   {
5561     print (vam->ofp,
5562            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5563            sub->interface_name,
5564            sub->sw_if_index,
5565            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5566            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5567            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5568            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5569     if (sub->vtr_op != L2_VTR_DISABLED)
5570       {
5571         print (vam->ofp,
5572                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5573                "tag1: %d tag2: %d ]",
5574                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5575                sub->vtr_tag1, sub->vtr_tag2);
5576       }
5577   }
5578
5579   return 0;
5580 }
5581
5582 static int
5583 name_sort_cmp (void *a1, void *a2)
5584 {
5585   name_sort_t *n1 = a1;
5586   name_sort_t *n2 = a2;
5587
5588   return strcmp ((char *) n1->name, (char *) n2->name);
5589 }
5590
5591 static int
5592 dump_interface_table (vat_main_t * vam)
5593 {
5594   hash_pair_t *p;
5595   name_sort_t *nses = 0, *ns;
5596
5597   if (vam->json_output)
5598     {
5599       clib_warning
5600         ("JSON output supported only for VPE API calls and dump_stats_table");
5601       return -99;
5602     }
5603
5604   /* *INDENT-OFF* */
5605   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5606   ({
5607     vec_add2 (nses, ns, 1);
5608     ns->name = (u8 *)(p->key);
5609     ns->value = (u32) p->value[0];
5610   }));
5611   /* *INDENT-ON* */
5612
5613   vec_sort_with_function (nses, name_sort_cmp);
5614
5615   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5616   vec_foreach (ns, nses)
5617   {
5618     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5619   }
5620   vec_free (nses);
5621   return 0;
5622 }
5623
5624 static int
5625 dump_ip_table (vat_main_t * vam, int is_ipv6)
5626 {
5627   const ip_details_t *det = NULL;
5628   const ip_address_details_t *address = NULL;
5629   u32 i = ~0;
5630
5631   print (vam->ofp, "%-12s", "sw_if_index");
5632
5633   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5634   {
5635     i++;
5636     if (!det->present)
5637       {
5638         continue;
5639       }
5640     print (vam->ofp, "%-12d", i);
5641     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5642     if (!det->addr)
5643       {
5644         continue;
5645       }
5646     vec_foreach (address, det->addr)
5647     {
5648       print (vam->ofp,
5649              "            %-30U%-13d",
5650              is_ipv6 ? format_ip6_address : format_ip4_address,
5651              address->ip, address->prefix_length);
5652     }
5653   }
5654
5655   return 0;
5656 }
5657
5658 static int
5659 dump_ipv4_table (vat_main_t * vam)
5660 {
5661   if (vam->json_output)
5662     {
5663       clib_warning
5664         ("JSON output supported only for VPE API calls and dump_stats_table");
5665       return -99;
5666     }
5667
5668   return dump_ip_table (vam, 0);
5669 }
5670
5671 static int
5672 dump_ipv6_table (vat_main_t * vam)
5673 {
5674   if (vam->json_output)
5675     {
5676       clib_warning
5677         ("JSON output supported only for VPE API calls and dump_stats_table");
5678       return -99;
5679     }
5680
5681   return dump_ip_table (vam, 1);
5682 }
5683
5684 /*
5685  * Pass CLI buffers directly in the CLI_INBAND API message,
5686  * instead of an additional shared memory area.
5687  */
5688 static int
5689 exec_inband (vat_main_t * vam)
5690 {
5691   vl_api_cli_inband_t *mp;
5692   unformat_input_t *i = vam->input;
5693   int ret;
5694
5695   if (vec_len (i->buffer) == 0)
5696     return -1;
5697
5698   if (vam->exec_mode == 0 && unformat (i, "mode"))
5699     {
5700       vam->exec_mode = 1;
5701       return 0;
5702     }
5703   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5704     {
5705       vam->exec_mode = 0;
5706       return 0;
5707     }
5708
5709   /*
5710    * In order for the CLI command to work, it
5711    * must be a vector ending in \n, not a C-string ending
5712    * in \n\0.
5713    */
5714   M2 (CLI_INBAND, mp, vec_len (vam->input->buffer));
5715   vl_api_vec_to_api_string (vam->input->buffer, &mp->cmd);
5716
5717   S (mp);
5718   W (ret);
5719   /* json responses may or may not include a useful reply... */
5720   if (vec_len (vam->cmd_reply))
5721     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5722   return ret;
5723 }
5724
5725 int
5726 exec (vat_main_t * vam)
5727 {
5728   return exec_inband (vam);
5729 }
5730
5731 static int
5732 api_create_loopback (vat_main_t * vam)
5733 {
5734   unformat_input_t *i = vam->input;
5735   vl_api_create_loopback_t *mp;
5736   vl_api_create_loopback_instance_t *mp_lbi;
5737   u8 mac_address[6];
5738   u8 mac_set = 0;
5739   u8 is_specified = 0;
5740   u32 user_instance = 0;
5741   int ret;
5742
5743   clib_memset (mac_address, 0, sizeof (mac_address));
5744
5745   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5746     {
5747       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5748         mac_set = 1;
5749       if (unformat (i, "instance %d", &user_instance))
5750         is_specified = 1;
5751       else
5752         break;
5753     }
5754
5755   if (is_specified)
5756     {
5757       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5758       mp_lbi->is_specified = is_specified;
5759       if (is_specified)
5760         mp_lbi->user_instance = htonl (user_instance);
5761       if (mac_set)
5762         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5763       S (mp_lbi);
5764     }
5765   else
5766     {
5767       /* Construct the API message */
5768       M (CREATE_LOOPBACK, mp);
5769       if (mac_set)
5770         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5771       S (mp);
5772     }
5773
5774   W (ret);
5775   return ret;
5776 }
5777
5778 static int
5779 api_delete_loopback (vat_main_t * vam)
5780 {
5781   unformat_input_t *i = vam->input;
5782   vl_api_delete_loopback_t *mp;
5783   u32 sw_if_index = ~0;
5784   int ret;
5785
5786   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5787     {
5788       if (unformat (i, "sw_if_index %d", &sw_if_index))
5789         ;
5790       else
5791         break;
5792     }
5793
5794   if (sw_if_index == ~0)
5795     {
5796       errmsg ("missing sw_if_index");
5797       return -99;
5798     }
5799
5800   /* Construct the API message */
5801   M (DELETE_LOOPBACK, mp);
5802   mp->sw_if_index = ntohl (sw_if_index);
5803
5804   S (mp);
5805   W (ret);
5806   return ret;
5807 }
5808
5809 static int
5810 api_want_interface_events (vat_main_t * vam)
5811 {
5812   unformat_input_t *i = vam->input;
5813   vl_api_want_interface_events_t *mp;
5814   int enable = -1;
5815   int ret;
5816
5817   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5818     {
5819       if (unformat (i, "enable"))
5820         enable = 1;
5821       else if (unformat (i, "disable"))
5822         enable = 0;
5823       else
5824         break;
5825     }
5826
5827   if (enable == -1)
5828     {
5829       errmsg ("missing enable|disable");
5830       return -99;
5831     }
5832
5833   M (WANT_INTERFACE_EVENTS, mp);
5834   mp->enable_disable = enable;
5835
5836   vam->interface_event_display = enable;
5837
5838   S (mp);
5839   W (ret);
5840   return ret;
5841 }
5842
5843
5844 /* Note: non-static, called once to set up the initial intfc table */
5845 int
5846 api_sw_interface_dump (vat_main_t * vam)
5847 {
5848   vl_api_sw_interface_dump_t *mp;
5849   vl_api_control_ping_t *mp_ping;
5850   hash_pair_t *p;
5851   name_sort_t *nses = 0, *ns;
5852   sw_interface_subif_t *sub = NULL;
5853   int ret;
5854
5855   /* Toss the old name table */
5856   /* *INDENT-OFF* */
5857   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5858   ({
5859     vec_add2 (nses, ns, 1);
5860     ns->name = (u8 *)(p->key);
5861     ns->value = (u32) p->value[0];
5862   }));
5863   /* *INDENT-ON* */
5864
5865   hash_free (vam->sw_if_index_by_interface_name);
5866
5867   vec_foreach (ns, nses) vec_free (ns->name);
5868
5869   vec_free (nses);
5870
5871   vec_foreach (sub, vam->sw_if_subif_table)
5872   {
5873     vec_free (sub->interface_name);
5874   }
5875   vec_free (vam->sw_if_subif_table);
5876
5877   /* recreate the interface name hash table */
5878   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5879
5880   /*
5881    * Ask for all interface names. Otherwise, the epic catalog of
5882    * name filters becomes ridiculously long, and vat ends up needing
5883    * to be taught about new interface types.
5884    */
5885   M (SW_INTERFACE_DUMP, mp);
5886   S (mp);
5887
5888   /* Use a control ping for synchronization */
5889   MPING (CONTROL_PING, mp_ping);
5890   S (mp_ping);
5891
5892   W (ret);
5893   return ret;
5894 }
5895
5896 static int
5897 api_sw_interface_set_flags (vat_main_t * vam)
5898 {
5899   unformat_input_t *i = vam->input;
5900   vl_api_sw_interface_set_flags_t *mp;
5901   u32 sw_if_index;
5902   u8 sw_if_index_set = 0;
5903   u8 admin_up = 0;
5904   int ret;
5905
5906   /* Parse args required to build the message */
5907   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5908     {
5909       if (unformat (i, "admin-up"))
5910         admin_up = 1;
5911       else if (unformat (i, "admin-down"))
5912         admin_up = 0;
5913       else
5914         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5915         sw_if_index_set = 1;
5916       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5917         sw_if_index_set = 1;
5918       else
5919         break;
5920     }
5921
5922   if (sw_if_index_set == 0)
5923     {
5924       errmsg ("missing interface name or sw_if_index");
5925       return -99;
5926     }
5927
5928   /* Construct the API message */
5929   M (SW_INTERFACE_SET_FLAGS, mp);
5930   mp->sw_if_index = ntohl (sw_if_index);
5931   mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
5932
5933   /* send it... */
5934   S (mp);
5935
5936   /* Wait for a reply, return the good/bad news... */
5937   W (ret);
5938   return ret;
5939 }
5940
5941 static int
5942 api_sw_interface_set_rx_mode (vat_main_t * vam)
5943 {
5944   unformat_input_t *i = vam->input;
5945   vl_api_sw_interface_set_rx_mode_t *mp;
5946   u32 sw_if_index;
5947   u8 sw_if_index_set = 0;
5948   int ret;
5949   u8 queue_id_valid = 0;
5950   u32 queue_id;
5951   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
5952
5953   /* Parse args required to build the message */
5954   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5955     {
5956       if (unformat (i, "queue %d", &queue_id))
5957         queue_id_valid = 1;
5958       else if (unformat (i, "polling"))
5959         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
5960       else if (unformat (i, "interrupt"))
5961         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
5962       else if (unformat (i, "adaptive"))
5963         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
5964       else
5965         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5966         sw_if_index_set = 1;
5967       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5968         sw_if_index_set = 1;
5969       else
5970         break;
5971     }
5972
5973   if (sw_if_index_set == 0)
5974     {
5975       errmsg ("missing interface name or sw_if_index");
5976       return -99;
5977     }
5978   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
5979     {
5980       errmsg ("missing rx-mode");
5981       return -99;
5982     }
5983
5984   /* Construct the API message */
5985   M (SW_INTERFACE_SET_RX_MODE, mp);
5986   mp->sw_if_index = ntohl (sw_if_index);
5987   mp->mode = (vl_api_rx_mode_t) mode;
5988   mp->queue_id_valid = queue_id_valid;
5989   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
5990
5991   /* send it... */
5992   S (mp);
5993
5994   /* Wait for a reply, return the good/bad news... */
5995   W (ret);
5996   return ret;
5997 }
5998
5999 static int
6000 api_sw_interface_set_rx_placement (vat_main_t * vam)
6001 {
6002   unformat_input_t *i = vam->input;
6003   vl_api_sw_interface_set_rx_placement_t *mp;
6004   u32 sw_if_index;
6005   u8 sw_if_index_set = 0;
6006   int ret;
6007   u8 is_main = 0;
6008   u32 queue_id, thread_index;
6009
6010   /* Parse args required to build the message */
6011   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6012     {
6013       if (unformat (i, "queue %d", &queue_id))
6014         ;
6015       else if (unformat (i, "main"))
6016         is_main = 1;
6017       else if (unformat (i, "worker %d", &thread_index))
6018         ;
6019       else
6020         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6021         sw_if_index_set = 1;
6022       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6023         sw_if_index_set = 1;
6024       else
6025         break;
6026     }
6027
6028   if (sw_if_index_set == 0)
6029     {
6030       errmsg ("missing interface name or sw_if_index");
6031       return -99;
6032     }
6033
6034   if (is_main)
6035     thread_index = 0;
6036   /* Construct the API message */
6037   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6038   mp->sw_if_index = ntohl (sw_if_index);
6039   mp->worker_id = ntohl (thread_index);
6040   mp->queue_id = ntohl (queue_id);
6041   mp->is_main = is_main;
6042
6043   /* send it... */
6044   S (mp);
6045   /* Wait for a reply, return the good/bad news... */
6046   W (ret);
6047   return ret;
6048 }
6049
6050 static void vl_api_sw_interface_rx_placement_details_t_handler
6051   (vl_api_sw_interface_rx_placement_details_t * mp)
6052 {
6053   vat_main_t *vam = &vat_main;
6054   u32 worker_id = ntohl (mp->worker_id);
6055
6056   print (vam->ofp,
6057          "\n%-11d %-11s %-6d %-5d %-9s",
6058          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6059          worker_id, ntohl (mp->queue_id),
6060          (mp->mode ==
6061           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6062 }
6063
6064 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6065   (vl_api_sw_interface_rx_placement_details_t * mp)
6066 {
6067   vat_main_t *vam = &vat_main;
6068   vat_json_node_t *node = NULL;
6069
6070   if (VAT_JSON_ARRAY != vam->json_tree.type)
6071     {
6072       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6073       vat_json_init_array (&vam->json_tree);
6074     }
6075   node = vat_json_array_add (&vam->json_tree);
6076
6077   vat_json_init_object (node);
6078   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6079   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6080   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6081   vat_json_object_add_uint (node, "mode", mp->mode);
6082 }
6083
6084 static int
6085 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6086 {
6087   unformat_input_t *i = vam->input;
6088   vl_api_sw_interface_rx_placement_dump_t *mp;
6089   vl_api_control_ping_t *mp_ping;
6090   int ret;
6091   u32 sw_if_index;
6092   u8 sw_if_index_set = 0;
6093
6094   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6095     {
6096       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6097         sw_if_index_set++;
6098       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6099         sw_if_index_set++;
6100       else
6101         break;
6102     }
6103
6104   print (vam->ofp,
6105          "\n%-11s %-11s %-6s %-5s %-4s",
6106          "sw_if_index", "main/worker", "thread", "queue", "mode");
6107
6108   /* Dump Interface rx placement */
6109   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6110
6111   if (sw_if_index_set)
6112     mp->sw_if_index = htonl (sw_if_index);
6113   else
6114     mp->sw_if_index = ~0;
6115
6116   S (mp);
6117
6118   /* Use a control ping for synchronization */
6119   MPING (CONTROL_PING, mp_ping);
6120   S (mp_ping);
6121
6122   W (ret);
6123   return ret;
6124 }
6125
6126 static int
6127 api_sw_interface_clear_stats (vat_main_t * vam)
6128 {
6129   unformat_input_t *i = vam->input;
6130   vl_api_sw_interface_clear_stats_t *mp;
6131   u32 sw_if_index;
6132   u8 sw_if_index_set = 0;
6133   int ret;
6134
6135   /* Parse args required to build the message */
6136   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6137     {
6138       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6139         sw_if_index_set = 1;
6140       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6141         sw_if_index_set = 1;
6142       else
6143         break;
6144     }
6145
6146   /* Construct the API message */
6147   M (SW_INTERFACE_CLEAR_STATS, mp);
6148
6149   if (sw_if_index_set == 1)
6150     mp->sw_if_index = ntohl (sw_if_index);
6151   else
6152     mp->sw_if_index = ~0;
6153
6154   /* send it... */
6155   S (mp);
6156
6157   /* Wait for a reply, return the good/bad news... */
6158   W (ret);
6159   return ret;
6160 }
6161
6162 static int
6163 api_sw_interface_add_del_address (vat_main_t * vam)
6164 {
6165   unformat_input_t *i = vam->input;
6166   vl_api_sw_interface_add_del_address_t *mp;
6167   u32 sw_if_index;
6168   u8 sw_if_index_set = 0;
6169   u8 is_add = 1, del_all = 0;
6170   u32 address_length = 0;
6171   u8 v4_address_set = 0;
6172   u8 v6_address_set = 0;
6173   ip4_address_t v4address;
6174   ip6_address_t v6address;
6175   int ret;
6176
6177   /* Parse args required to build the message */
6178   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6179     {
6180       if (unformat (i, "del-all"))
6181         del_all = 1;
6182       else if (unformat (i, "del"))
6183         is_add = 0;
6184       else
6185         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6186         sw_if_index_set = 1;
6187       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6188         sw_if_index_set = 1;
6189       else if (unformat (i, "%U/%d",
6190                          unformat_ip4_address, &v4address, &address_length))
6191         v4_address_set = 1;
6192       else if (unformat (i, "%U/%d",
6193                          unformat_ip6_address, &v6address, &address_length))
6194         v6_address_set = 1;
6195       else
6196         break;
6197     }
6198
6199   if (sw_if_index_set == 0)
6200     {
6201       errmsg ("missing interface name or sw_if_index");
6202       return -99;
6203     }
6204   if (v4_address_set && v6_address_set)
6205     {
6206       errmsg ("both v4 and v6 addresses set");
6207       return -99;
6208     }
6209   if (!v4_address_set && !v6_address_set && !del_all)
6210     {
6211       errmsg ("no addresses set");
6212       return -99;
6213     }
6214
6215   /* Construct the API message */
6216   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6217
6218   mp->sw_if_index = ntohl (sw_if_index);
6219   mp->is_add = is_add;
6220   mp->del_all = del_all;
6221   if (v6_address_set)
6222     {
6223       mp->prefix.address.af = ADDRESS_IP6;
6224       clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
6225     }
6226   else
6227     {
6228       mp->prefix.address.af = ADDRESS_IP4;
6229       clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
6230     }
6231   mp->prefix.len = address_length;
6232
6233   /* send it... */
6234   S (mp);
6235
6236   /* Wait for a reply, return good/bad news  */
6237   W (ret);
6238   return ret;
6239 }
6240
6241 static int
6242 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6243 {
6244   unformat_input_t *i = vam->input;
6245   vl_api_sw_interface_set_mpls_enable_t *mp;
6246   u32 sw_if_index;
6247   u8 sw_if_index_set = 0;
6248   u8 enable = 1;
6249   int ret;
6250
6251   /* Parse args required to build the message */
6252   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6253     {
6254       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6255         sw_if_index_set = 1;
6256       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6257         sw_if_index_set = 1;
6258       else if (unformat (i, "disable"))
6259         enable = 0;
6260       else if (unformat (i, "dis"))
6261         enable = 0;
6262       else
6263         break;
6264     }
6265
6266   if (sw_if_index_set == 0)
6267     {
6268       errmsg ("missing interface name or sw_if_index");
6269       return -99;
6270     }
6271
6272   /* Construct the API message */
6273   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6274
6275   mp->sw_if_index = ntohl (sw_if_index);
6276   mp->enable = enable;
6277
6278   /* send it... */
6279   S (mp);
6280
6281   /* Wait for a reply... */
6282   W (ret);
6283   return ret;
6284 }
6285
6286 static int
6287 api_sw_interface_set_table (vat_main_t * vam)
6288 {
6289   unformat_input_t *i = vam->input;
6290   vl_api_sw_interface_set_table_t *mp;
6291   u32 sw_if_index, vrf_id = 0;
6292   u8 sw_if_index_set = 0;
6293   u8 is_ipv6 = 0;
6294   int ret;
6295
6296   /* Parse args required to build the message */
6297   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6298     {
6299       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6300         sw_if_index_set = 1;
6301       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6302         sw_if_index_set = 1;
6303       else if (unformat (i, "vrf %d", &vrf_id))
6304         ;
6305       else if (unformat (i, "ipv6"))
6306         is_ipv6 = 1;
6307       else
6308         break;
6309     }
6310
6311   if (sw_if_index_set == 0)
6312     {
6313       errmsg ("missing interface name or sw_if_index");
6314       return -99;
6315     }
6316
6317   /* Construct the API message */
6318   M (SW_INTERFACE_SET_TABLE, mp);
6319
6320   mp->sw_if_index = ntohl (sw_if_index);
6321   mp->is_ipv6 = is_ipv6;
6322   mp->vrf_id = ntohl (vrf_id);
6323
6324   /* send it... */
6325   S (mp);
6326
6327   /* Wait for a reply... */
6328   W (ret);
6329   return ret;
6330 }
6331
6332 static void vl_api_sw_interface_get_table_reply_t_handler
6333   (vl_api_sw_interface_get_table_reply_t * mp)
6334 {
6335   vat_main_t *vam = &vat_main;
6336
6337   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6338
6339   vam->retval = ntohl (mp->retval);
6340   vam->result_ready = 1;
6341
6342 }
6343
6344 static void vl_api_sw_interface_get_table_reply_t_handler_json
6345   (vl_api_sw_interface_get_table_reply_t * mp)
6346 {
6347   vat_main_t *vam = &vat_main;
6348   vat_json_node_t node;
6349
6350   vat_json_init_object (&node);
6351   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6352   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6353
6354   vat_json_print (vam->ofp, &node);
6355   vat_json_free (&node);
6356
6357   vam->retval = ntohl (mp->retval);
6358   vam->result_ready = 1;
6359 }
6360
6361 static int
6362 api_sw_interface_get_table (vat_main_t * vam)
6363 {
6364   unformat_input_t *i = vam->input;
6365   vl_api_sw_interface_get_table_t *mp;
6366   u32 sw_if_index;
6367   u8 sw_if_index_set = 0;
6368   u8 is_ipv6 = 0;
6369   int ret;
6370
6371   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6372     {
6373       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6374         sw_if_index_set = 1;
6375       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6376         sw_if_index_set = 1;
6377       else if (unformat (i, "ipv6"))
6378         is_ipv6 = 1;
6379       else
6380         break;
6381     }
6382
6383   if (sw_if_index_set == 0)
6384     {
6385       errmsg ("missing interface name or sw_if_index");
6386       return -99;
6387     }
6388
6389   M (SW_INTERFACE_GET_TABLE, mp);
6390   mp->sw_if_index = htonl (sw_if_index);
6391   mp->is_ipv6 = is_ipv6;
6392
6393   S (mp);
6394   W (ret);
6395   return ret;
6396 }
6397
6398 static int
6399 api_sw_interface_set_vpath (vat_main_t * vam)
6400 {
6401   unformat_input_t *i = vam->input;
6402   vl_api_sw_interface_set_vpath_t *mp;
6403   u32 sw_if_index = 0;
6404   u8 sw_if_index_set = 0;
6405   u8 is_enable = 0;
6406   int ret;
6407
6408   /* Parse args required to build the message */
6409   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6410     {
6411       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6412         sw_if_index_set = 1;
6413       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6414         sw_if_index_set = 1;
6415       else if (unformat (i, "enable"))
6416         is_enable = 1;
6417       else if (unformat (i, "disable"))
6418         is_enable = 0;
6419       else
6420         break;
6421     }
6422
6423   if (sw_if_index_set == 0)
6424     {
6425       errmsg ("missing interface name or sw_if_index");
6426       return -99;
6427     }
6428
6429   /* Construct the API message */
6430   M (SW_INTERFACE_SET_VPATH, mp);
6431
6432   mp->sw_if_index = ntohl (sw_if_index);
6433   mp->enable = is_enable;
6434
6435   /* send it... */
6436   S (mp);
6437
6438   /* Wait for a reply... */
6439   W (ret);
6440   return ret;
6441 }
6442
6443 static int
6444 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6445 {
6446   unformat_input_t *i = vam->input;
6447   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6448   u32 sw_if_index = 0;
6449   u8 sw_if_index_set = 0;
6450   u8 is_enable = 1;
6451   u8 is_ipv6 = 0;
6452   int ret;
6453
6454   /* Parse args required to build the message */
6455   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6456     {
6457       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6458         sw_if_index_set = 1;
6459       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6460         sw_if_index_set = 1;
6461       else if (unformat (i, "enable"))
6462         is_enable = 1;
6463       else if (unformat (i, "disable"))
6464         is_enable = 0;
6465       else if (unformat (i, "ip4"))
6466         is_ipv6 = 0;
6467       else if (unformat (i, "ip6"))
6468         is_ipv6 = 1;
6469       else
6470         break;
6471     }
6472
6473   if (sw_if_index_set == 0)
6474     {
6475       errmsg ("missing interface name or sw_if_index");
6476       return -99;
6477     }
6478
6479   /* Construct the API message */
6480   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6481
6482   mp->sw_if_index = ntohl (sw_if_index);
6483   mp->enable = is_enable;
6484   mp->is_ipv6 = is_ipv6;
6485
6486   /* send it... */
6487   S (mp);
6488
6489   /* Wait for a reply... */
6490   W (ret);
6491   return ret;
6492 }
6493
6494 static int
6495 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6496 {
6497   unformat_input_t *i = vam->input;
6498   vl_api_sw_interface_set_geneve_bypass_t *mp;
6499   u32 sw_if_index = 0;
6500   u8 sw_if_index_set = 0;
6501   u8 is_enable = 1;
6502   u8 is_ipv6 = 0;
6503   int ret;
6504
6505   /* Parse args required to build the message */
6506   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6507     {
6508       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6509         sw_if_index_set = 1;
6510       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6511         sw_if_index_set = 1;
6512       else if (unformat (i, "enable"))
6513         is_enable = 1;
6514       else if (unformat (i, "disable"))
6515         is_enable = 0;
6516       else if (unformat (i, "ip4"))
6517         is_ipv6 = 0;
6518       else if (unformat (i, "ip6"))
6519         is_ipv6 = 1;
6520       else
6521         break;
6522     }
6523
6524   if (sw_if_index_set == 0)
6525     {
6526       errmsg ("missing interface name or sw_if_index");
6527       return -99;
6528     }
6529
6530   /* Construct the API message */
6531   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6532
6533   mp->sw_if_index = ntohl (sw_if_index);
6534   mp->enable = is_enable;
6535   mp->is_ipv6 = is_ipv6;
6536
6537   /* send it... */
6538   S (mp);
6539
6540   /* Wait for a reply... */
6541   W (ret);
6542   return ret;
6543 }
6544
6545 static int
6546 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6547 {
6548   unformat_input_t *i = vam->input;
6549   vl_api_sw_interface_set_l2_xconnect_t *mp;
6550   u32 rx_sw_if_index;
6551   u8 rx_sw_if_index_set = 0;
6552   u32 tx_sw_if_index;
6553   u8 tx_sw_if_index_set = 0;
6554   u8 enable = 1;
6555   int ret;
6556
6557   /* Parse args required to build the message */
6558   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6559     {
6560       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6561         rx_sw_if_index_set = 1;
6562       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6563         tx_sw_if_index_set = 1;
6564       else if (unformat (i, "rx"))
6565         {
6566           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6567             {
6568               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6569                             &rx_sw_if_index))
6570                 rx_sw_if_index_set = 1;
6571             }
6572           else
6573             break;
6574         }
6575       else if (unformat (i, "tx"))
6576         {
6577           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6578             {
6579               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6580                             &tx_sw_if_index))
6581                 tx_sw_if_index_set = 1;
6582             }
6583           else
6584             break;
6585         }
6586       else if (unformat (i, "enable"))
6587         enable = 1;
6588       else if (unformat (i, "disable"))
6589         enable = 0;
6590       else
6591         break;
6592     }
6593
6594   if (rx_sw_if_index_set == 0)
6595     {
6596       errmsg ("missing rx interface name or rx_sw_if_index");
6597       return -99;
6598     }
6599
6600   if (enable && (tx_sw_if_index_set == 0))
6601     {
6602       errmsg ("missing tx interface name or tx_sw_if_index");
6603       return -99;
6604     }
6605
6606   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6607
6608   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6609   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6610   mp->enable = enable;
6611
6612   S (mp);
6613   W (ret);
6614   return ret;
6615 }
6616
6617 static int
6618 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6619 {
6620   unformat_input_t *i = vam->input;
6621   vl_api_sw_interface_set_l2_bridge_t *mp;
6622   vl_api_l2_port_type_t port_type;
6623   u32 rx_sw_if_index;
6624   u8 rx_sw_if_index_set = 0;
6625   u32 bd_id;
6626   u8 bd_id_set = 0;
6627   u32 shg = 0;
6628   u8 enable = 1;
6629   int ret;
6630
6631   port_type = L2_API_PORT_TYPE_NORMAL;
6632
6633   /* Parse args required to build the message */
6634   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6635     {
6636       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6637         rx_sw_if_index_set = 1;
6638       else if (unformat (i, "bd_id %d", &bd_id))
6639         bd_id_set = 1;
6640       else
6641         if (unformat
6642             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6643         rx_sw_if_index_set = 1;
6644       else if (unformat (i, "shg %d", &shg))
6645         ;
6646       else if (unformat (i, "bvi"))
6647         port_type = L2_API_PORT_TYPE_BVI;
6648       else if (unformat (i, "uu-fwd"))
6649         port_type = L2_API_PORT_TYPE_UU_FWD;
6650       else if (unformat (i, "enable"))
6651         enable = 1;
6652       else if (unformat (i, "disable"))
6653         enable = 0;
6654       else
6655         break;
6656     }
6657
6658   if (rx_sw_if_index_set == 0)
6659     {
6660       errmsg ("missing rx interface name or sw_if_index");
6661       return -99;
6662     }
6663
6664   if (enable && (bd_id_set == 0))
6665     {
6666       errmsg ("missing bridge domain");
6667       return -99;
6668     }
6669
6670   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6671
6672   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6673   mp->bd_id = ntohl (bd_id);
6674   mp->shg = (u8) shg;
6675   mp->port_type = ntohl (port_type);
6676   mp->enable = enable;
6677
6678   S (mp);
6679   W (ret);
6680   return ret;
6681 }
6682
6683 static int
6684 api_bridge_domain_dump (vat_main_t * vam)
6685 {
6686   unformat_input_t *i = vam->input;
6687   vl_api_bridge_domain_dump_t *mp;
6688   vl_api_control_ping_t *mp_ping;
6689   u32 bd_id = ~0;
6690   int ret;
6691
6692   /* Parse args required to build the message */
6693   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6694     {
6695       if (unformat (i, "bd_id %d", &bd_id))
6696         ;
6697       else
6698         break;
6699     }
6700
6701   M (BRIDGE_DOMAIN_DUMP, mp);
6702   mp->bd_id = ntohl (bd_id);
6703   S (mp);
6704
6705   /* Use a control ping for synchronization */
6706   MPING (CONTROL_PING, mp_ping);
6707   S (mp_ping);
6708
6709   W (ret);
6710   return ret;
6711 }
6712
6713 static int
6714 api_bridge_domain_add_del (vat_main_t * vam)
6715 {
6716   unformat_input_t *i = vam->input;
6717   vl_api_bridge_domain_add_del_t *mp;
6718   u32 bd_id = ~0;
6719   u8 is_add = 1;
6720   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6721   u8 *bd_tag = NULL;
6722   u32 mac_age = 0;
6723   int ret;
6724
6725   /* Parse args required to build the message */
6726   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6727     {
6728       if (unformat (i, "bd_id %d", &bd_id))
6729         ;
6730       else if (unformat (i, "flood %d", &flood))
6731         ;
6732       else if (unformat (i, "uu-flood %d", &uu_flood))
6733         ;
6734       else if (unformat (i, "forward %d", &forward))
6735         ;
6736       else if (unformat (i, "learn %d", &learn))
6737         ;
6738       else if (unformat (i, "arp-term %d", &arp_term))
6739         ;
6740       else if (unformat (i, "mac-age %d", &mac_age))
6741         ;
6742       else if (unformat (i, "bd-tag %s", &bd_tag))
6743         ;
6744       else if (unformat (i, "del"))
6745         {
6746           is_add = 0;
6747           flood = uu_flood = forward = learn = 0;
6748         }
6749       else
6750         break;
6751     }
6752
6753   if (bd_id == ~0)
6754     {
6755       errmsg ("missing bridge domain");
6756       ret = -99;
6757       goto done;
6758     }
6759
6760   if (mac_age > 255)
6761     {
6762       errmsg ("mac age must be less than 256 ");
6763       ret = -99;
6764       goto done;
6765     }
6766
6767   if ((bd_tag) && (vec_len (bd_tag) > 63))
6768     {
6769       errmsg ("bd-tag cannot be longer than 63");
6770       ret = -99;
6771       goto done;
6772     }
6773
6774   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6775
6776   mp->bd_id = ntohl (bd_id);
6777   mp->flood = flood;
6778   mp->uu_flood = uu_flood;
6779   mp->forward = forward;
6780   mp->learn = learn;
6781   mp->arp_term = arp_term;
6782   mp->is_add = is_add;
6783   mp->mac_age = (u8) mac_age;
6784   if (bd_tag)
6785     {
6786       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6787       mp->bd_tag[vec_len (bd_tag)] = 0;
6788     }
6789   S (mp);
6790   W (ret);
6791
6792 done:
6793   vec_free (bd_tag);
6794   return ret;
6795 }
6796
6797 static int
6798 api_l2fib_flush_bd (vat_main_t * vam)
6799 {
6800   unformat_input_t *i = vam->input;
6801   vl_api_l2fib_flush_bd_t *mp;
6802   u32 bd_id = ~0;
6803   int ret;
6804
6805   /* Parse args required to build the message */
6806   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6807     {
6808       if (unformat (i, "bd_id %d", &bd_id));
6809       else
6810         break;
6811     }
6812
6813   if (bd_id == ~0)
6814     {
6815       errmsg ("missing bridge domain");
6816       return -99;
6817     }
6818
6819   M (L2FIB_FLUSH_BD, mp);
6820
6821   mp->bd_id = htonl (bd_id);
6822
6823   S (mp);
6824   W (ret);
6825   return ret;
6826 }
6827
6828 static int
6829 api_l2fib_flush_int (vat_main_t * vam)
6830 {
6831   unformat_input_t *i = vam->input;
6832   vl_api_l2fib_flush_int_t *mp;
6833   u32 sw_if_index = ~0;
6834   int ret;
6835
6836   /* Parse args required to build the message */
6837   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6838     {
6839       if (unformat (i, "sw_if_index %d", &sw_if_index));
6840       else
6841         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6842       else
6843         break;
6844     }
6845
6846   if (sw_if_index == ~0)
6847     {
6848       errmsg ("missing interface name or sw_if_index");
6849       return -99;
6850     }
6851
6852   M (L2FIB_FLUSH_INT, mp);
6853
6854   mp->sw_if_index = ntohl (sw_if_index);
6855
6856   S (mp);
6857   W (ret);
6858   return ret;
6859 }
6860
6861 static int
6862 api_l2fib_add_del (vat_main_t * vam)
6863 {
6864   unformat_input_t *i = vam->input;
6865   vl_api_l2fib_add_del_t *mp;
6866   f64 timeout;
6867   u8 mac[6] = { 0 };
6868   u8 mac_set = 0;
6869   u32 bd_id;
6870   u8 bd_id_set = 0;
6871   u32 sw_if_index = 0;
6872   u8 sw_if_index_set = 0;
6873   u8 is_add = 1;
6874   u8 static_mac = 0;
6875   u8 filter_mac = 0;
6876   u8 bvi_mac = 0;
6877   int count = 1;
6878   f64 before = 0;
6879   int j;
6880
6881   /* Parse args required to build the message */
6882   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6883     {
6884       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6885         mac_set = 1;
6886       else if (unformat (i, "bd_id %d", &bd_id))
6887         bd_id_set = 1;
6888       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6889         sw_if_index_set = 1;
6890       else if (unformat (i, "sw_if"))
6891         {
6892           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6893             {
6894               if (unformat
6895                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6896                 sw_if_index_set = 1;
6897             }
6898           else
6899             break;
6900         }
6901       else if (unformat (i, "static"))
6902         static_mac = 1;
6903       else if (unformat (i, "filter"))
6904         {
6905           filter_mac = 1;
6906           static_mac = 1;
6907         }
6908       else if (unformat (i, "bvi"))
6909         {
6910           bvi_mac = 1;
6911           static_mac = 1;
6912         }
6913       else if (unformat (i, "del"))
6914         is_add = 0;
6915       else if (unformat (i, "count %d", &count))
6916         ;
6917       else
6918         break;
6919     }
6920
6921   if (mac_set == 0)
6922     {
6923       errmsg ("missing mac address");
6924       return -99;
6925     }
6926
6927   if (bd_id_set == 0)
6928     {
6929       errmsg ("missing bridge domain");
6930       return -99;
6931     }
6932
6933   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6934     {
6935       errmsg ("missing interface name or sw_if_index");
6936       return -99;
6937     }
6938
6939   if (count > 1)
6940     {
6941       /* Turn on async mode */
6942       vam->async_mode = 1;
6943       vam->async_errors = 0;
6944       before = vat_time_now (vam);
6945     }
6946
6947   for (j = 0; j < count; j++)
6948     {
6949       M (L2FIB_ADD_DEL, mp);
6950
6951       clib_memcpy (mp->mac, mac, 6);
6952       mp->bd_id = ntohl (bd_id);
6953       mp->is_add = is_add;
6954       mp->sw_if_index = ntohl (sw_if_index);
6955
6956       if (is_add)
6957         {
6958           mp->static_mac = static_mac;
6959           mp->filter_mac = filter_mac;
6960           mp->bvi_mac = bvi_mac;
6961         }
6962       increment_mac_address (mac);
6963       /* send it... */
6964       S (mp);
6965     }
6966
6967   if (count > 1)
6968     {
6969       vl_api_control_ping_t *mp_ping;
6970       f64 after;
6971
6972       /* Shut off async mode */
6973       vam->async_mode = 0;
6974
6975       MPING (CONTROL_PING, mp_ping);
6976       S (mp_ping);
6977
6978       timeout = vat_time_now (vam) + 1.0;
6979       while (vat_time_now (vam) < timeout)
6980         if (vam->result_ready == 1)
6981           goto out;
6982       vam->retval = -99;
6983
6984     out:
6985       if (vam->retval == -99)
6986         errmsg ("timeout");
6987
6988       if (vam->async_errors > 0)
6989         {
6990           errmsg ("%d asynchronous errors", vam->async_errors);
6991           vam->retval = -98;
6992         }
6993       vam->async_errors = 0;
6994       after = vat_time_now (vam);
6995
6996       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6997              count, after - before, count / (after - before));
6998     }
6999   else
7000     {
7001       int ret;
7002
7003       /* Wait for a reply... */
7004       W (ret);
7005       return ret;
7006     }
7007   /* Return the good/bad news */
7008   return (vam->retval);
7009 }
7010
7011 static int
7012 api_bridge_domain_set_mac_age (vat_main_t * vam)
7013 {
7014   unformat_input_t *i = vam->input;
7015   vl_api_bridge_domain_set_mac_age_t *mp;
7016   u32 bd_id = ~0;
7017   u32 mac_age = 0;
7018   int ret;
7019
7020   /* Parse args required to build the message */
7021   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7022     {
7023       if (unformat (i, "bd_id %d", &bd_id));
7024       else if (unformat (i, "mac-age %d", &mac_age));
7025       else
7026         break;
7027     }
7028
7029   if (bd_id == ~0)
7030     {
7031       errmsg ("missing bridge domain");
7032       return -99;
7033     }
7034
7035   if (mac_age > 255)
7036     {
7037       errmsg ("mac age must be less than 256 ");
7038       return -99;
7039     }
7040
7041   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7042
7043   mp->bd_id = htonl (bd_id);
7044   mp->mac_age = (u8) mac_age;
7045
7046   S (mp);
7047   W (ret);
7048   return ret;
7049 }
7050
7051 static int
7052 api_l2_flags (vat_main_t * vam)
7053 {
7054   unformat_input_t *i = vam->input;
7055   vl_api_l2_flags_t *mp;
7056   u32 sw_if_index;
7057   u32 flags = 0;
7058   u8 sw_if_index_set = 0;
7059   u8 is_set = 0;
7060   int ret;
7061
7062   /* Parse args required to build the message */
7063   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7064     {
7065       if (unformat (i, "sw_if_index %d", &sw_if_index))
7066         sw_if_index_set = 1;
7067       else if (unformat (i, "sw_if"))
7068         {
7069           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7070             {
7071               if (unformat
7072                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7073                 sw_if_index_set = 1;
7074             }
7075           else
7076             break;
7077         }
7078       else if (unformat (i, "learn"))
7079         flags |= L2_LEARN;
7080       else if (unformat (i, "forward"))
7081         flags |= L2_FWD;
7082       else if (unformat (i, "flood"))
7083         flags |= L2_FLOOD;
7084       else if (unformat (i, "uu-flood"))
7085         flags |= L2_UU_FLOOD;
7086       else if (unformat (i, "arp-term"))
7087         flags |= L2_ARP_TERM;
7088       else if (unformat (i, "off"))
7089         is_set = 0;
7090       else if (unformat (i, "disable"))
7091         is_set = 0;
7092       else
7093         break;
7094     }
7095
7096   if (sw_if_index_set == 0)
7097     {
7098       errmsg ("missing interface name or sw_if_index");
7099       return -99;
7100     }
7101
7102   M (L2_FLAGS, mp);
7103
7104   mp->sw_if_index = ntohl (sw_if_index);
7105   mp->feature_bitmap = ntohl (flags);
7106   mp->is_set = is_set;
7107
7108   S (mp);
7109   W (ret);
7110   return ret;
7111 }
7112
7113 static int
7114 api_bridge_flags (vat_main_t * vam)
7115 {
7116   unformat_input_t *i = vam->input;
7117   vl_api_bridge_flags_t *mp;
7118   u32 bd_id;
7119   u8 bd_id_set = 0;
7120   u8 is_set = 1;
7121   bd_flags_t flags = 0;
7122   int ret;
7123
7124   /* Parse args required to build the message */
7125   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7126     {
7127       if (unformat (i, "bd_id %d", &bd_id))
7128         bd_id_set = 1;
7129       else if (unformat (i, "learn"))
7130         flags |= BRIDGE_API_FLAG_LEARN;
7131       else if (unformat (i, "forward"))
7132         flags |= BRIDGE_API_FLAG_FWD;
7133       else if (unformat (i, "flood"))
7134         flags |= BRIDGE_API_FLAG_FLOOD;
7135       else if (unformat (i, "uu-flood"))
7136         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7137       else if (unformat (i, "arp-term"))
7138         flags |= BRIDGE_API_FLAG_ARP_TERM;
7139       else if (unformat (i, "off"))
7140         is_set = 0;
7141       else if (unformat (i, "disable"))
7142         is_set = 0;
7143       else
7144         break;
7145     }
7146
7147   if (bd_id_set == 0)
7148     {
7149       errmsg ("missing bridge domain");
7150       return -99;
7151     }
7152
7153   M (BRIDGE_FLAGS, mp);
7154
7155   mp->bd_id = ntohl (bd_id);
7156   mp->flags = ntohl (flags);
7157   mp->is_set = is_set;
7158
7159   S (mp);
7160   W (ret);
7161   return ret;
7162 }
7163
7164 static int
7165 api_bd_ip_mac_add_del (vat_main_t * vam)
7166 {
7167   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7168   vl_api_mac_address_t mac = { 0 };
7169   unformat_input_t *i = vam->input;
7170   vl_api_bd_ip_mac_add_del_t *mp;
7171   u32 bd_id;
7172   u8 is_add = 1;
7173   u8 bd_id_set = 0;
7174   u8 ip_set = 0;
7175   u8 mac_set = 0;
7176   int ret;
7177
7178
7179   /* Parse args required to build the message */
7180   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7181     {
7182       if (unformat (i, "bd_id %d", &bd_id))
7183         {
7184           bd_id_set++;
7185         }
7186       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7187         {
7188           ip_set++;
7189         }
7190       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7191         {
7192           mac_set++;
7193         }
7194       else if (unformat (i, "del"))
7195         is_add = 0;
7196       else
7197         break;
7198     }
7199
7200   if (bd_id_set == 0)
7201     {
7202       errmsg ("missing bridge domain");
7203       return -99;
7204     }
7205   else if (ip_set == 0)
7206     {
7207       errmsg ("missing IP address");
7208       return -99;
7209     }
7210   else if (mac_set == 0)
7211     {
7212       errmsg ("missing MAC address");
7213       return -99;
7214     }
7215
7216   M (BD_IP_MAC_ADD_DEL, mp);
7217
7218   mp->entry.bd_id = ntohl (bd_id);
7219   mp->is_add = is_add;
7220
7221   clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
7222   clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
7223
7224   S (mp);
7225   W (ret);
7226   return ret;
7227 }
7228
7229 static int
7230 api_bd_ip_mac_flush (vat_main_t * vam)
7231 {
7232   unformat_input_t *i = vam->input;
7233   vl_api_bd_ip_mac_flush_t *mp;
7234   u32 bd_id;
7235   u8 bd_id_set = 0;
7236   int ret;
7237
7238   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7239     {
7240       if (unformat (i, "bd_id %d", &bd_id))
7241         {
7242           bd_id_set++;
7243         }
7244       else
7245         break;
7246     }
7247
7248   if (bd_id_set == 0)
7249     {
7250       errmsg ("missing bridge domain");
7251       return -99;
7252     }
7253
7254   M (BD_IP_MAC_FLUSH, mp);
7255
7256   mp->bd_id = ntohl (bd_id);
7257
7258   S (mp);
7259   W (ret);
7260   return ret;
7261 }
7262
7263 static void vl_api_bd_ip_mac_details_t_handler
7264   (vl_api_bd_ip_mac_details_t * mp)
7265 {
7266   vat_main_t *vam = &vat_main;
7267
7268   print (vam->ofp,
7269          "\n%-5d %U %U",
7270          ntohl (mp->entry.bd_id),
7271          format_vl_api_mac_address, mp->entry.mac,
7272          format_vl_api_address, &mp->entry.ip);
7273 }
7274
7275 static void vl_api_bd_ip_mac_details_t_handler_json
7276   (vl_api_bd_ip_mac_details_t * mp)
7277 {
7278   vat_main_t *vam = &vat_main;
7279   vat_json_node_t *node = NULL;
7280
7281   if (VAT_JSON_ARRAY != vam->json_tree.type)
7282     {
7283       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7284       vat_json_init_array (&vam->json_tree);
7285     }
7286   node = vat_json_array_add (&vam->json_tree);
7287
7288   vat_json_init_object (node);
7289   vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
7290   vat_json_object_add_string_copy (node, "mac_address",
7291                                    format (0, "%U", format_vl_api_mac_address,
7292                                            &mp->entry.mac));
7293   u8 *ip = 0;
7294
7295   ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
7296   vat_json_object_add_string_copy (node, "ip_address", ip);
7297   vec_free (ip);
7298 }
7299
7300 static int
7301 api_bd_ip_mac_dump (vat_main_t * vam)
7302 {
7303   unformat_input_t *i = vam->input;
7304   vl_api_bd_ip_mac_dump_t *mp;
7305   vl_api_control_ping_t *mp_ping;
7306   int ret;
7307   u32 bd_id;
7308   u8 bd_id_set = 0;
7309
7310   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7311     {
7312       if (unformat (i, "bd_id %d", &bd_id))
7313         {
7314           bd_id_set++;
7315         }
7316       else
7317         break;
7318     }
7319
7320   print (vam->ofp,
7321          "\n%-5s %-7s %-20s %-30s",
7322          "bd_id", "is_ipv6", "mac_address", "ip_address");
7323
7324   /* Dump Bridge Domain Ip to Mac entries */
7325   M (BD_IP_MAC_DUMP, mp);
7326
7327   if (bd_id_set)
7328     mp->bd_id = htonl (bd_id);
7329   else
7330     mp->bd_id = ~0;
7331
7332   S (mp);
7333
7334   /* Use a control ping for synchronization */
7335   MPING (CONTROL_PING, mp_ping);
7336   S (mp_ping);
7337
7338   W (ret);
7339   return ret;
7340 }
7341
7342 static int
7343 api_tap_create_v2 (vat_main_t * vam)
7344 {
7345   unformat_input_t *i = vam->input;
7346   vl_api_tap_create_v2_t *mp;
7347   u8 mac_address[6];
7348   u8 random_mac = 1;
7349   u32 id = ~0;
7350   u32 num_rx_queues = 0;
7351   u8 *host_if_name = 0;
7352   u8 host_if_name_set = 0;
7353   u8 *host_ns = 0;
7354   u8 host_ns_set = 0;
7355   u8 host_mac_addr[6];
7356   u8 host_mac_addr_set = 0;
7357   u8 *host_bridge = 0;
7358   u8 host_bridge_set = 0;
7359   u8 host_ip4_prefix_set = 0;
7360   u8 host_ip6_prefix_set = 0;
7361   ip4_address_t host_ip4_addr;
7362   ip4_address_t host_ip4_gw;
7363   u8 host_ip4_gw_set = 0;
7364   u32 host_ip4_prefix_len = 0;
7365   ip6_address_t host_ip6_addr;
7366   ip6_address_t host_ip6_gw;
7367   u8 host_ip6_gw_set = 0;
7368   u32 host_ip6_prefix_len = 0;
7369   u32 host_mtu_size = 0;
7370   u8 host_mtu_set = 0;
7371   u32 tap_flags = 0;
7372   int ret;
7373   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7374
7375   clib_memset (mac_address, 0, sizeof (mac_address));
7376
7377   /* Parse args required to build the message */
7378   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7379     {
7380       if (unformat (i, "id %u", &id))
7381         ;
7382       else
7383         if (unformat
7384             (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7385         random_mac = 0;
7386       else if (unformat (i, "host-if-name %s", &host_if_name))
7387         host_if_name_set = 1;
7388       else if (unformat (i, "num-rx-queues %u", &num_rx_queues))
7389         ;
7390       else if (unformat (i, "host-ns %s", &host_ns))
7391         host_ns_set = 1;
7392       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7393                          host_mac_addr))
7394         host_mac_addr_set = 1;
7395       else if (unformat (i, "host-bridge %s", &host_bridge))
7396         host_bridge_set = 1;
7397       else if (unformat (i, "host-ip4-addr %U/%u", unformat_ip4_address,
7398                          &host_ip4_addr, &host_ip4_prefix_len))
7399         host_ip4_prefix_set = 1;
7400       else if (unformat (i, "host-ip6-addr %U/%u", unformat_ip6_address,
7401                          &host_ip6_addr, &host_ip6_prefix_len))
7402         host_ip6_prefix_set = 1;
7403       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7404                          &host_ip4_gw))
7405         host_ip4_gw_set = 1;
7406       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7407                          &host_ip6_gw))
7408         host_ip6_gw_set = 1;
7409       else if (unformat (i, "rx-ring-size %u", &rx_ring_sz))
7410         ;
7411       else if (unformat (i, "tx-ring-size %u", &tx_ring_sz))
7412         ;
7413       else if (unformat (i, "host-mtu-size %u", &host_mtu_size))
7414         host_mtu_set = 1;
7415       else if (unformat (i, "no-gso"))
7416         tap_flags &= ~TAP_API_FLAG_GSO;
7417       else if (unformat (i, "gso"))
7418         tap_flags |= TAP_API_FLAG_GSO;
7419       else if (unformat (i, "csum-offload"))
7420         tap_flags |= TAP_API_FLAG_CSUM_OFFLOAD;
7421       else if (unformat (i, "persist"))
7422         tap_flags |= TAP_API_FLAG_PERSIST;
7423       else if (unformat (i, "attach"))
7424         tap_flags |= TAP_API_FLAG_ATTACH;
7425       else if (unformat (i, "tun"))
7426         tap_flags |= TAP_API_FLAG_TUN;
7427       else if (unformat (i, "gro-coalesce"))
7428         tap_flags |= TAP_API_FLAG_GRO_COALESCE;
7429       else if (unformat (i, "packed"))
7430         tap_flags |= TAP_API_FLAG_PACKED;
7431       else if (unformat (i, "in-order"))
7432         tap_flags |= TAP_API_FLAG_IN_ORDER;
7433       else
7434         break;
7435     }
7436
7437   if (vec_len (host_if_name) > 63)
7438     {
7439       errmsg ("tap name too long. ");
7440       return -99;
7441     }
7442   if (vec_len (host_ns) > 63)
7443     {
7444       errmsg ("host name space too long. ");
7445       return -99;
7446     }
7447   if (vec_len (host_bridge) > 63)
7448     {
7449       errmsg ("host bridge name too long. ");
7450       return -99;
7451     }
7452   if (host_ip4_prefix_len > 32)
7453     {
7454       errmsg ("host ip4 prefix length not valid. ");
7455       return -99;
7456     }
7457   if (host_ip6_prefix_len > 128)
7458     {
7459       errmsg ("host ip6 prefix length not valid. ");
7460       return -99;
7461     }
7462   if (!is_pow2 (rx_ring_sz))
7463     {
7464       errmsg ("rx ring size must be power of 2. ");
7465       return -99;
7466     }
7467   if (rx_ring_sz > 32768)
7468     {
7469       errmsg ("rx ring size must be 32768 or lower. ");
7470       return -99;
7471     }
7472   if (!is_pow2 (tx_ring_sz))
7473     {
7474       errmsg ("tx ring size must be power of 2. ");
7475       return -99;
7476     }
7477   if (tx_ring_sz > 32768)
7478     {
7479       errmsg ("tx ring size must be 32768 or lower. ");
7480       return -99;
7481     }
7482   if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
7483     {
7484       errmsg ("host MTU size must be in between 64 and 65355. ");
7485       return -99;
7486     }
7487
7488   /* Construct the API message */
7489   M (TAP_CREATE_V2, mp);
7490
7491   mp->id = ntohl (id);
7492   mp->use_random_mac = random_mac;
7493   mp->num_rx_queues = (u8) num_rx_queues;
7494   mp->tx_ring_sz = ntohs (tx_ring_sz);
7495   mp->rx_ring_sz = ntohs (rx_ring_sz);
7496   mp->host_mtu_set = host_mtu_set;
7497   mp->host_mtu_size = ntohl (host_mtu_size);
7498   mp->host_mac_addr_set = host_mac_addr_set;
7499   mp->host_ip4_prefix_set = host_ip4_prefix_set;
7500   mp->host_ip6_prefix_set = host_ip6_prefix_set;
7501   mp->host_ip4_gw_set = host_ip4_gw_set;
7502   mp->host_ip6_gw_set = host_ip6_gw_set;
7503   mp->tap_flags = ntohl (tap_flags);
7504   mp->host_namespace_set = host_ns_set;
7505   mp->host_if_name_set = host_if_name_set;
7506   mp->host_bridge_set = host_bridge_set;
7507
7508   if (random_mac == 0)
7509     clib_memcpy (mp->mac_address, mac_address, 6);
7510   if (host_mac_addr_set)
7511     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7512   if (host_if_name_set)
7513     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7514   if (host_ns_set)
7515     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7516   if (host_bridge_set)
7517     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7518   if (host_ip4_prefix_set)
7519     {
7520       clib_memcpy (mp->host_ip4_prefix.address, &host_ip4_addr, 4);
7521       mp->host_ip4_prefix.len = (u8) host_ip4_prefix_len;
7522     }
7523   if (host_ip6_prefix_set)
7524     {
7525       clib_memcpy (mp->host_ip6_prefix.address, &host_ip6_addr, 16);
7526       mp->host_ip6_prefix.len = (u8) host_ip6_prefix_len;
7527     }
7528   if (host_ip4_gw_set)
7529     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7530   if (host_ip6_gw_set)
7531     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7532
7533   vec_free (host_ns);
7534   vec_free (host_if_name);
7535   vec_free (host_bridge);
7536
7537   /* send it... */
7538   S (mp);
7539
7540   /* Wait for a reply... */
7541   W (ret);
7542   return ret;
7543 }
7544
7545 static int
7546 api_tap_delete_v2 (vat_main_t * vam)
7547 {
7548   unformat_input_t *i = vam->input;
7549   vl_api_tap_delete_v2_t *mp;
7550   u32 sw_if_index = ~0;
7551   u8 sw_if_index_set = 0;
7552   int ret;
7553
7554   /* Parse args required to build the message */
7555   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7556     {
7557       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7558         sw_if_index_set = 1;
7559       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7560         sw_if_index_set = 1;
7561       else
7562         break;
7563     }
7564
7565   if (sw_if_index_set == 0)
7566     {
7567       errmsg ("missing vpp interface name. ");
7568       return -99;
7569     }
7570
7571   /* Construct the API message */
7572   M (TAP_DELETE_V2, mp);
7573
7574   mp->sw_if_index = ntohl (sw_if_index);
7575
7576   /* send it... */
7577   S (mp);
7578
7579   /* Wait for a reply... */
7580   W (ret);
7581   return ret;
7582 }
7583
7584 uword
7585 unformat_vlib_pci_addr (unformat_input_t * input, va_list * args)
7586 {
7587   vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
7588   u32 x[4];
7589
7590   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7591     return 0;
7592
7593   addr->domain = x[0];
7594   addr->bus = x[1];
7595   addr->slot = x[2];
7596   addr->function = x[3];
7597
7598   return 1;
7599 }
7600
7601 static int
7602 api_virtio_pci_create_v2 (vat_main_t * vam)
7603 {
7604   unformat_input_t *i = vam->input;
7605   vl_api_virtio_pci_create_v2_t *mp;
7606   u8 mac_address[6];
7607   u8 random_mac = 1;
7608   u32 pci_addr = 0;
7609   u64 features = (u64) ~ (0ULL);
7610   u32 virtio_flags = 0;
7611   int ret;
7612
7613   clib_memset (mac_address, 0, sizeof (mac_address));
7614
7615   /* Parse args required to build the message */
7616   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7617     {
7618       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7619         {
7620           random_mac = 0;
7621         }
7622       else if (unformat (i, "pci-addr %U", unformat_vlib_pci_addr, &pci_addr))
7623         ;
7624       else if (unformat (i, "features 0x%llx", &features))
7625         ;
7626       else if (unformat (i, "gso-enabled"))
7627         virtio_flags |= VIRTIO_API_FLAG_GSO;
7628       else if (unformat (i, "csum-offload-enabled"))
7629         virtio_flags |= VIRTIO_API_FLAG_CSUM_OFFLOAD;
7630       else if (unformat (i, "gro-coalesce"))
7631         virtio_flags |= VIRTIO_API_FLAG_GRO_COALESCE;
7632       else if (unformat (i, "packed"))
7633         virtio_flags |= VIRTIO_API_FLAG_PACKED;
7634       else if (unformat (i, "in-order"))
7635         virtio_flags |= VIRTIO_API_FLAG_IN_ORDER;
7636       else
7637         break;
7638     }
7639
7640   if (pci_addr == 0)
7641     {
7642       errmsg ("pci address must be non zero. ");
7643       return -99;
7644     }
7645
7646   /* Construct the API message */
7647   M (VIRTIO_PCI_CREATE_V2, mp);
7648
7649   mp->use_random_mac = random_mac;
7650
7651   mp->pci_addr.domain = htons (((vlib_pci_addr_t) pci_addr).domain);
7652   mp->pci_addr.bus = ((vlib_pci_addr_t) pci_addr).bus;
7653   mp->pci_addr.slot = ((vlib_pci_addr_t) pci_addr).slot;
7654   mp->pci_addr.function = ((vlib_pci_addr_t) pci_addr).function;
7655
7656   mp->features = clib_host_to_net_u64 (features);
7657   mp->virtio_flags = clib_host_to_net_u32 (virtio_flags);
7658
7659   if (random_mac == 0)
7660     clib_memcpy (mp->mac_address, mac_address, 6);
7661
7662   /* send it... */
7663   S (mp);
7664
7665   /* Wait for a reply... */
7666   W (ret);
7667   return ret;
7668 }
7669
7670 static int
7671 api_virtio_pci_delete (vat_main_t * vam)
7672 {
7673   unformat_input_t *i = vam->input;
7674   vl_api_virtio_pci_delete_t *mp;
7675   u32 sw_if_index = ~0;
7676   u8 sw_if_index_set = 0;
7677   int ret;
7678
7679   /* Parse args required to build the message */
7680   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7681     {
7682       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7683         sw_if_index_set = 1;
7684       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7685         sw_if_index_set = 1;
7686       else
7687         break;
7688     }
7689
7690   if (sw_if_index_set == 0)
7691     {
7692       errmsg ("missing vpp interface name. ");
7693       return -99;
7694     }
7695
7696   /* Construct the API message */
7697   M (VIRTIO_PCI_DELETE, mp);
7698
7699   mp->sw_if_index = htonl (sw_if_index);
7700
7701   /* send it... */
7702   S (mp);
7703
7704   /* Wait for a reply... */
7705   W (ret);
7706   return ret;
7707 }
7708
7709 static int
7710 api_bond_create (vat_main_t * vam)
7711 {
7712   unformat_input_t *i = vam->input;
7713   vl_api_bond_create_t *mp;
7714   u8 mac_address[6];
7715   u8 custom_mac = 0;
7716   int ret;
7717   u8 mode;
7718   u8 lb;
7719   u8 mode_is_set = 0;
7720   u32 id = ~0;
7721   u8 numa_only = 0;
7722
7723   clib_memset (mac_address, 0, sizeof (mac_address));
7724   lb = BOND_LB_L2;
7725
7726   /* Parse args required to build the message */
7727   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7728     {
7729       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7730         mode_is_set = 1;
7731       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7732                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7733         ;
7734       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7735                          mac_address))
7736         custom_mac = 1;
7737       else if (unformat (i, "numa-only"))
7738         numa_only = 1;
7739       else if (unformat (i, "id %u", &id))
7740         ;
7741       else
7742         break;
7743     }
7744
7745   if (mode_is_set == 0)
7746     {
7747       errmsg ("Missing bond mode. ");
7748       return -99;
7749     }
7750
7751   /* Construct the API message */
7752   M (BOND_CREATE, mp);
7753
7754   mp->use_custom_mac = custom_mac;
7755
7756   mp->mode = htonl (mode);
7757   mp->lb = htonl (lb);
7758   mp->id = htonl (id);
7759   mp->numa_only = numa_only;
7760
7761   if (custom_mac)
7762     clib_memcpy (mp->mac_address, mac_address, 6);
7763
7764   /* send it... */
7765   S (mp);
7766
7767   /* Wait for a reply... */
7768   W (ret);
7769   return ret;
7770 }
7771
7772 static int
7773 api_bond_delete (vat_main_t * vam)
7774 {
7775   unformat_input_t *i = vam->input;
7776   vl_api_bond_delete_t *mp;
7777   u32 sw_if_index = ~0;
7778   u8 sw_if_index_set = 0;
7779   int ret;
7780
7781   /* Parse args required to build the message */
7782   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7783     {
7784       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7785         sw_if_index_set = 1;
7786       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7787         sw_if_index_set = 1;
7788       else
7789         break;
7790     }
7791
7792   if (sw_if_index_set == 0)
7793     {
7794       errmsg ("missing vpp interface name. ");
7795       return -99;
7796     }
7797
7798   /* Construct the API message */
7799   M (BOND_DELETE, mp);
7800
7801   mp->sw_if_index = ntohl (sw_if_index);
7802
7803   /* send it... */
7804   S (mp);
7805
7806   /* Wait for a reply... */
7807   W (ret);
7808   return ret;
7809 }
7810
7811 static int
7812 api_bond_add_member (vat_main_t * vam)
7813 {
7814   unformat_input_t *i = vam->input;
7815   vl_api_bond_add_member_t *mp;
7816   u32 bond_sw_if_index;
7817   int ret;
7818   u8 is_passive;
7819   u8 is_long_timeout;
7820   u32 bond_sw_if_index_is_set = 0;
7821   u32 sw_if_index;
7822   u8 sw_if_index_is_set = 0;
7823
7824   /* Parse args required to build the message */
7825   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7826     {
7827       if (unformat (i, "sw_if_index %d", &sw_if_index))
7828         sw_if_index_is_set = 1;
7829       else if (unformat (i, "bond %u", &bond_sw_if_index))
7830         bond_sw_if_index_is_set = 1;
7831       else if (unformat (i, "passive %d", &is_passive))
7832         ;
7833       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7834         ;
7835       else
7836         break;
7837     }
7838
7839   if (bond_sw_if_index_is_set == 0)
7840     {
7841       errmsg ("Missing bond sw_if_index. ");
7842       return -99;
7843     }
7844   if (sw_if_index_is_set == 0)
7845     {
7846       errmsg ("Missing member sw_if_index. ");
7847       return -99;
7848     }
7849
7850   /* Construct the API message */
7851   M (BOND_ADD_MEMBER, mp);
7852
7853   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7854   mp->sw_if_index = ntohl (sw_if_index);
7855   mp->is_long_timeout = is_long_timeout;
7856   mp->is_passive = is_passive;
7857
7858   /* send it... */
7859   S (mp);
7860
7861   /* Wait for a reply... */
7862   W (ret);
7863   return ret;
7864 }
7865
7866 static int
7867 api_bond_detach_member (vat_main_t * vam)
7868 {
7869   unformat_input_t *i = vam->input;
7870   vl_api_bond_detach_member_t *mp;
7871   u32 sw_if_index = ~0;
7872   u8 sw_if_index_set = 0;
7873   int ret;
7874
7875   /* Parse args required to build the message */
7876   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7877     {
7878       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7879         sw_if_index_set = 1;
7880       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7881         sw_if_index_set = 1;
7882       else
7883         break;
7884     }
7885
7886   if (sw_if_index_set == 0)
7887     {
7888       errmsg ("missing vpp interface name. ");
7889       return -99;
7890     }
7891
7892   /* Construct the API message */
7893   M (BOND_DETACH_MEMBER, mp);
7894
7895   mp->sw_if_index = ntohl (sw_if_index);
7896
7897   /* send it... */
7898   S (mp);
7899
7900   /* Wait for a reply... */
7901   W (ret);
7902   return ret;
7903 }
7904
7905 static int
7906 api_ip_table_add_del (vat_main_t * vam)
7907 {
7908   unformat_input_t *i = vam->input;
7909   vl_api_ip_table_add_del_t *mp;
7910   u32 table_id = ~0;
7911   u8 is_ipv6 = 0;
7912   u8 is_add = 1;
7913   int ret = 0;
7914
7915   /* Parse args required to build the message */
7916   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7917     {
7918       if (unformat (i, "ipv6"))
7919         is_ipv6 = 1;
7920       else if (unformat (i, "del"))
7921         is_add = 0;
7922       else if (unformat (i, "add"))
7923         is_add = 1;
7924       else if (unformat (i, "table %d", &table_id))
7925         ;
7926       else
7927         {
7928           clib_warning ("parse error '%U'", format_unformat_error, i);
7929           return -99;
7930         }
7931     }
7932
7933   if (~0 == table_id)
7934     {
7935       errmsg ("missing table-ID");
7936       return -99;
7937     }
7938
7939   /* Construct the API message */
7940   M (IP_TABLE_ADD_DEL, mp);
7941
7942   mp->table.table_id = ntohl (table_id);
7943   mp->table.is_ip6 = is_ipv6;
7944   mp->is_add = is_add;
7945
7946   /* send it... */
7947   S (mp);
7948
7949   /* Wait for a reply... */
7950   W (ret);
7951
7952   return ret;
7953 }
7954
7955 uword
7956 unformat_fib_path (unformat_input_t * input, va_list * args)
7957 {
7958   vat_main_t *vam = va_arg (*args, vat_main_t *);
7959   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
7960   u32 weight, preference;
7961   mpls_label_t out_label;
7962
7963   clib_memset (path, 0, sizeof (*path));
7964   path->weight = 1;
7965   path->sw_if_index = ~0;
7966   path->rpf_id = ~0;
7967   path->n_labels = 0;
7968
7969   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7970     {
7971       if (unformat (input, "%U %U",
7972                     unformat_vl_api_ip4_address,
7973                     &path->nh.address.ip4,
7974                     api_unformat_sw_if_index, vam, &path->sw_if_index))
7975         {
7976           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7977         }
7978       else if (unformat (input, "%U %U",
7979                          unformat_vl_api_ip6_address,
7980                          &path->nh.address.ip6,
7981                          api_unformat_sw_if_index, vam, &path->sw_if_index))
7982         {
7983           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7984         }
7985       else if (unformat (input, "weight %u", &weight))
7986         {
7987           path->weight = weight;
7988         }
7989       else if (unformat (input, "preference %u", &preference))
7990         {
7991           path->preference = preference;
7992         }
7993       else if (unformat (input, "%U next-hop-table %d",
7994                          unformat_vl_api_ip4_address,
7995                          &path->nh.address.ip4, &path->table_id))
7996         {
7997           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7998         }
7999       else if (unformat (input, "%U next-hop-table %d",
8000                          unformat_vl_api_ip6_address,
8001                          &path->nh.address.ip6, &path->table_id))
8002         {
8003           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8004         }
8005       else if (unformat (input, "%U",
8006                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
8007         {
8008           /*
8009            * the recursive next-hops are by default in the default table
8010            */
8011           path->table_id = 0;
8012           path->sw_if_index = ~0;
8013           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8014         }
8015       else if (unformat (input, "%U",
8016                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
8017         {
8018           /*
8019            * the recursive next-hops are by default in the default table
8020            */
8021           path->table_id = 0;
8022           path->sw_if_index = ~0;
8023           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8024         }
8025       else if (unformat (input, "resolve-via-host"))
8026         {
8027           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
8028         }
8029       else if (unformat (input, "resolve-via-attached"))
8030         {
8031           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
8032         }
8033       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
8034         {
8035           path->type = FIB_API_PATH_TYPE_LOCAL;
8036           path->sw_if_index = ~0;
8037           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8038         }
8039       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
8040         {
8041           path->type = FIB_API_PATH_TYPE_LOCAL;
8042           path->sw_if_index = ~0;
8043           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8044         }
8045       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
8046         ;
8047       else if (unformat (input, "via-label %d", &path->nh.via_label))
8048         {
8049           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
8050           path->sw_if_index = ~0;
8051         }
8052       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
8053         {
8054           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
8055           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
8056         }
8057       else if (unformat (input, "local"))
8058         {
8059           path->type = FIB_API_PATH_TYPE_LOCAL;
8060         }
8061       else if (unformat (input, "out-labels"))
8062         {
8063           while (unformat (input, "%d", &out_label))
8064             {
8065               path->label_stack[path->n_labels].label = out_label;
8066               path->label_stack[path->n_labels].is_uniform = 0;
8067               path->label_stack[path->n_labels].ttl = 64;
8068               path->n_labels++;
8069             }
8070         }
8071       else if (unformat (input, "via"))
8072         {
8073           /* new path, back up and return */
8074           unformat_put_input (input);
8075           unformat_put_input (input);
8076           unformat_put_input (input);
8077           unformat_put_input (input);
8078           break;
8079         }
8080       else
8081         {
8082           return (0);
8083         }
8084     }
8085
8086   path->proto = ntohl (path->proto);
8087   path->type = ntohl (path->type);
8088   path->flags = ntohl (path->flags);
8089   path->table_id = ntohl (path->table_id);
8090   path->sw_if_index = ntohl (path->sw_if_index);
8091
8092   return (1);
8093 }
8094
8095 static int
8096 api_ip_route_add_del (vat_main_t * vam)
8097 {
8098   unformat_input_t *i = vam->input;
8099   vl_api_ip_route_add_del_t *mp;
8100   u32 vrf_id = 0;
8101   u8 is_add = 1;
8102   u8 is_multipath = 0;
8103   u8 prefix_set = 0;
8104   u8 path_count = 0;
8105   vl_api_prefix_t pfx = { };
8106   vl_api_fib_path_t paths[8];
8107   int count = 1;
8108   int j;
8109   f64 before = 0;
8110   u32 random_add_del = 0;
8111   u32 *random_vector = 0;
8112   u32 random_seed = 0xdeaddabe;
8113
8114   /* Parse args required to build the message */
8115   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8116     {
8117       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8118         prefix_set = 1;
8119       else if (unformat (i, "del"))
8120         is_add = 0;
8121       else if (unformat (i, "add"))
8122         is_add = 1;
8123       else if (unformat (i, "vrf %d", &vrf_id))
8124         ;
8125       else if (unformat (i, "count %d", &count))
8126         ;
8127       else if (unformat (i, "random"))
8128         random_add_del = 1;
8129       else if (unformat (i, "multipath"))
8130         is_multipath = 1;
8131       else if (unformat (i, "seed %d", &random_seed))
8132         ;
8133       else
8134         if (unformat
8135             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8136         {
8137           path_count++;
8138           if (8 == path_count)
8139             {
8140               errmsg ("max 8 paths");
8141               return -99;
8142             }
8143         }
8144       else
8145         {
8146           clib_warning ("parse error '%U'", format_unformat_error, i);
8147           return -99;
8148         }
8149     }
8150
8151   if (!path_count)
8152     {
8153       errmsg ("specify a path; via ...");
8154       return -99;
8155     }
8156   if (prefix_set == 0)
8157     {
8158       errmsg ("missing prefix");
8159       return -99;
8160     }
8161
8162   /* Generate a pile of unique, random routes */
8163   if (random_add_del)
8164     {
8165       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
8166       u32 this_random_address;
8167       uword *random_hash;
8168
8169       random_hash = hash_create (count, sizeof (uword));
8170
8171       hash_set (random_hash, i->as_u32, 1);
8172       for (j = 0; j <= count; j++)
8173         {
8174           do
8175             {
8176               this_random_address = random_u32 (&random_seed);
8177               this_random_address =
8178                 clib_host_to_net_u32 (this_random_address);
8179             }
8180           while (hash_get (random_hash, this_random_address));
8181           vec_add1 (random_vector, this_random_address);
8182           hash_set (random_hash, this_random_address, 1);
8183         }
8184       hash_free (random_hash);
8185       set_ip4_address (&pfx.address, random_vector[0]);
8186     }
8187
8188   if (count > 1)
8189     {
8190       /* Turn on async mode */
8191       vam->async_mode = 1;
8192       vam->async_errors = 0;
8193       before = vat_time_now (vam);
8194     }
8195
8196   for (j = 0; j < count; j++)
8197     {
8198       /* Construct the API message */
8199       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8200
8201       mp->is_add = is_add;
8202       mp->is_multipath = is_multipath;
8203
8204       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8205       mp->route.table_id = ntohl (vrf_id);
8206       mp->route.n_paths = path_count;
8207
8208       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
8209
8210       if (random_add_del)
8211         set_ip4_address (&pfx.address, random_vector[j + 1]);
8212       else
8213         increment_address (&pfx.address);
8214       /* send it... */
8215       S (mp);
8216       /* If we receive SIGTERM, stop now... */
8217       if (vam->do_exit)
8218         break;
8219     }
8220
8221   /* When testing multiple add/del ops, use a control-ping to sync */
8222   if (count > 1)
8223     {
8224       vl_api_control_ping_t *mp_ping;
8225       f64 after;
8226       f64 timeout;
8227
8228       /* Shut off async mode */
8229       vam->async_mode = 0;
8230
8231       MPING (CONTROL_PING, mp_ping);
8232       S (mp_ping);
8233
8234       timeout = vat_time_now (vam) + 1.0;
8235       while (vat_time_now (vam) < timeout)
8236         if (vam->result_ready == 1)
8237           goto out;
8238       vam->retval = -99;
8239
8240     out:
8241       if (vam->retval == -99)
8242         errmsg ("timeout");
8243
8244       if (vam->async_errors > 0)
8245         {
8246           errmsg ("%d asynchronous errors", vam->async_errors);
8247           vam->retval = -98;
8248         }
8249       vam->async_errors = 0;
8250       after = vat_time_now (vam);
8251
8252       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8253       if (j > 0)
8254         count = j;
8255
8256       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8257              count, after - before, count / (after - before));
8258     }
8259   else
8260     {
8261       int ret;
8262
8263       /* Wait for a reply... */
8264       W (ret);
8265       return ret;
8266     }
8267
8268   /* Return the good/bad news */
8269   return (vam->retval);
8270 }
8271
8272 static int
8273 api_ip_mroute_add_del (vat_main_t * vam)
8274 {
8275   unformat_input_t *i = vam->input;
8276   u8 path_set = 0, prefix_set = 0, is_add = 1;
8277   vl_api_ip_mroute_add_del_t *mp;
8278   mfib_entry_flags_t eflags = 0;
8279   vl_api_mfib_path_t path;
8280   vl_api_mprefix_t pfx = { };
8281   u32 vrf_id = 0;
8282   int ret;
8283
8284   /* Parse args required to build the message */
8285   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8286     {
8287       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
8288         {
8289           prefix_set = 1;
8290           pfx.grp_address_length = htons (pfx.grp_address_length);
8291         }
8292       else if (unformat (i, "del"))
8293         is_add = 0;
8294       else if (unformat (i, "add"))
8295         is_add = 1;
8296       else if (unformat (i, "vrf %d", &vrf_id))
8297         ;
8298       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
8299         path.itf_flags = htonl (path.itf_flags);
8300       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8301         ;
8302       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
8303         path_set = 1;
8304       else
8305         {
8306           clib_warning ("parse error '%U'", format_unformat_error, i);
8307           return -99;
8308         }
8309     }
8310
8311   if (prefix_set == 0)
8312     {
8313       errmsg ("missing addresses\n");
8314       return -99;
8315     }
8316   if (path_set == 0)
8317     {
8318       errmsg ("missing path\n");
8319       return -99;
8320     }
8321
8322   /* Construct the API message */
8323   M (IP_MROUTE_ADD_DEL, mp);
8324
8325   mp->is_add = is_add;
8326   mp->is_multipath = 1;
8327
8328   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8329   mp->route.table_id = htonl (vrf_id);
8330   mp->route.n_paths = 1;
8331   mp->route.entry_flags = htonl (eflags);
8332
8333   clib_memcpy (&mp->route.paths, &path, sizeof (path));
8334
8335   /* send it... */
8336   S (mp);
8337   /* Wait for a reply... */
8338   W (ret);
8339   return ret;
8340 }
8341
8342 static int
8343 api_mpls_table_add_del (vat_main_t * vam)
8344 {
8345   unformat_input_t *i = vam->input;
8346   vl_api_mpls_table_add_del_t *mp;
8347   u32 table_id = ~0;
8348   u8 is_add = 1;
8349   int ret = 0;
8350
8351   /* Parse args required to build the message */
8352   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8353     {
8354       if (unformat (i, "table %d", &table_id))
8355         ;
8356       else if (unformat (i, "del"))
8357         is_add = 0;
8358       else if (unformat (i, "add"))
8359         is_add = 1;
8360       else
8361         {
8362           clib_warning ("parse error '%U'", format_unformat_error, i);
8363           return -99;
8364         }
8365     }
8366
8367   if (~0 == table_id)
8368     {
8369       errmsg ("missing table-ID");
8370       return -99;
8371     }
8372
8373   /* Construct the API message */
8374   M (MPLS_TABLE_ADD_DEL, mp);
8375
8376   mp->mt_table.mt_table_id = ntohl (table_id);
8377   mp->mt_is_add = is_add;
8378
8379   /* send it... */
8380   S (mp);
8381
8382   /* Wait for a reply... */
8383   W (ret);
8384
8385   return ret;
8386 }
8387
8388 static int
8389 api_mpls_route_add_del (vat_main_t * vam)
8390 {
8391   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
8392   mpls_label_t local_label = MPLS_LABEL_INVALID;
8393   unformat_input_t *i = vam->input;
8394   vl_api_mpls_route_add_del_t *mp;
8395   vl_api_fib_path_t paths[8];
8396   int count = 1, j;
8397   f64 before = 0;
8398
8399   /* Parse args required to build the message */
8400   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8401     {
8402       if (unformat (i, "%d", &local_label))
8403         ;
8404       else if (unformat (i, "eos"))
8405         is_eos = 1;
8406       else if (unformat (i, "non-eos"))
8407         is_eos = 0;
8408       else if (unformat (i, "del"))
8409         is_add = 0;
8410       else if (unformat (i, "add"))
8411         is_add = 1;
8412       else if (unformat (i, "multipath"))
8413         is_multipath = 1;
8414       else if (unformat (i, "count %d", &count))
8415         ;
8416       else
8417         if (unformat
8418             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8419         {
8420           path_count++;
8421           if (8 == path_count)
8422             {
8423               errmsg ("max 8 paths");
8424               return -99;
8425             }
8426         }
8427       else
8428         {
8429           clib_warning ("parse error '%U'", format_unformat_error, i);
8430           return -99;
8431         }
8432     }
8433
8434   if (!path_count)
8435     {
8436       errmsg ("specify a path; via ...");
8437       return -99;
8438     }
8439
8440   if (MPLS_LABEL_INVALID == local_label)
8441     {
8442       errmsg ("missing label");
8443       return -99;
8444     }
8445
8446   if (count > 1)
8447     {
8448       /* Turn on async mode */
8449       vam->async_mode = 1;
8450       vam->async_errors = 0;
8451       before = vat_time_now (vam);
8452     }
8453
8454   for (j = 0; j < count; j++)
8455     {
8456       /* Construct the API message */
8457       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8458
8459       mp->mr_is_add = is_add;
8460       mp->mr_is_multipath = is_multipath;
8461
8462       mp->mr_route.mr_label = local_label;
8463       mp->mr_route.mr_eos = is_eos;
8464       mp->mr_route.mr_table_id = 0;
8465       mp->mr_route.mr_n_paths = path_count;
8466
8467       clib_memcpy (&mp->mr_route.mr_paths, paths,
8468                    sizeof (paths[0]) * path_count);
8469
8470       local_label++;
8471
8472       /* send it... */
8473       S (mp);
8474       /* If we receive SIGTERM, stop now... */
8475       if (vam->do_exit)
8476         break;
8477     }
8478
8479   /* When testing multiple add/del ops, use a control-ping to sync */
8480   if (count > 1)
8481     {
8482       vl_api_control_ping_t *mp_ping;
8483       f64 after;
8484       f64 timeout;
8485
8486       /* Shut off async mode */
8487       vam->async_mode = 0;
8488
8489       MPING (CONTROL_PING, mp_ping);
8490       S (mp_ping);
8491
8492       timeout = vat_time_now (vam) + 1.0;
8493       while (vat_time_now (vam) < timeout)
8494         if (vam->result_ready == 1)
8495           goto out;
8496       vam->retval = -99;
8497
8498     out:
8499       if (vam->retval == -99)
8500         errmsg ("timeout");
8501
8502       if (vam->async_errors > 0)
8503         {
8504           errmsg ("%d asynchronous errors", vam->async_errors);
8505           vam->retval = -98;
8506         }
8507       vam->async_errors = 0;
8508       after = vat_time_now (vam);
8509
8510       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8511       if (j > 0)
8512         count = j;
8513
8514       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8515              count, after - before, count / (after - before));
8516     }
8517   else
8518     {
8519       int ret;
8520
8521       /* Wait for a reply... */
8522       W (ret);
8523       return ret;
8524     }
8525
8526   /* Return the good/bad news */
8527   return (vam->retval);
8528   return (0);
8529 }
8530
8531 static int
8532 api_mpls_ip_bind_unbind (vat_main_t * vam)
8533 {
8534   unformat_input_t *i = vam->input;
8535   vl_api_mpls_ip_bind_unbind_t *mp;
8536   u32 ip_table_id = 0;
8537   u8 is_bind = 1;
8538   vl_api_prefix_t pfx;
8539   u8 prefix_set = 0;
8540   mpls_label_t local_label = MPLS_LABEL_INVALID;
8541   int ret;
8542
8543   /* Parse args required to build the message */
8544   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8545     {
8546       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8547         prefix_set = 1;
8548       else if (unformat (i, "%d", &local_label))
8549         ;
8550       else if (unformat (i, "table-id %d", &ip_table_id))
8551         ;
8552       else if (unformat (i, "unbind"))
8553         is_bind = 0;
8554       else if (unformat (i, "bind"))
8555         is_bind = 1;
8556       else
8557         {
8558           clib_warning ("parse error '%U'", format_unformat_error, i);
8559           return -99;
8560         }
8561     }
8562
8563   if (!prefix_set)
8564     {
8565       errmsg ("IP prefix not set");
8566       return -99;
8567     }
8568
8569   if (MPLS_LABEL_INVALID == local_label)
8570     {
8571       errmsg ("missing label");
8572       return -99;
8573     }
8574
8575   /* Construct the API message */
8576   M (MPLS_IP_BIND_UNBIND, mp);
8577
8578   mp->mb_is_bind = is_bind;
8579   mp->mb_ip_table_id = ntohl (ip_table_id);
8580   mp->mb_mpls_table_id = 0;
8581   mp->mb_label = ntohl (local_label);
8582   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
8583
8584   /* send it... */
8585   S (mp);
8586
8587   /* Wait for a reply... */
8588   W (ret);
8589   return ret;
8590   return (0);
8591 }
8592
8593 static int
8594 api_sr_mpls_policy_add (vat_main_t * vam)
8595 {
8596   unformat_input_t *i = vam->input;
8597   vl_api_sr_mpls_policy_add_t *mp;
8598   u32 bsid = 0;
8599   u32 weight = 1;
8600   u8 type = 0;
8601   u8 n_segments = 0;
8602   u32 sid;
8603   u32 *segments = NULL;
8604   int ret;
8605
8606   /* Parse args required to build the message */
8607   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8608     {
8609       if (unformat (i, "bsid %d", &bsid))
8610         ;
8611       else if (unformat (i, "weight %d", &weight))
8612         ;
8613       else if (unformat (i, "spray"))
8614         type = 1;
8615       else if (unformat (i, "next %d", &sid))
8616         {
8617           n_segments += 1;
8618           vec_add1 (segments, htonl (sid));
8619         }
8620       else
8621         {
8622           clib_warning ("parse error '%U'", format_unformat_error, i);
8623           return -99;
8624         }
8625     }
8626
8627   if (bsid == 0)
8628     {
8629       errmsg ("bsid not set");
8630       return -99;
8631     }
8632
8633   if (n_segments == 0)
8634     {
8635       errmsg ("no sid in segment stack");
8636       return -99;
8637     }
8638
8639   /* Construct the API message */
8640   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8641
8642   mp->bsid = htonl (bsid);
8643   mp->weight = htonl (weight);
8644   mp->is_spray = type;
8645   mp->n_segments = n_segments;
8646   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8647   vec_free (segments);
8648
8649   /* send it... */
8650   S (mp);
8651
8652   /* Wait for a reply... */
8653   W (ret);
8654   return ret;
8655 }
8656
8657 static int
8658 api_sr_mpls_policy_del (vat_main_t * vam)
8659 {
8660   unformat_input_t *i = vam->input;
8661   vl_api_sr_mpls_policy_del_t *mp;
8662   u32 bsid = 0;
8663   int ret;
8664
8665   /* Parse args required to build the message */
8666   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8667     {
8668       if (unformat (i, "bsid %d", &bsid))
8669         ;
8670       else
8671         {
8672           clib_warning ("parse error '%U'", format_unformat_error, i);
8673           return -99;
8674         }
8675     }
8676
8677   if (bsid == 0)
8678     {
8679       errmsg ("bsid not set");
8680       return -99;
8681     }
8682
8683   /* Construct the API message */
8684   M (SR_MPLS_POLICY_DEL, mp);
8685
8686   mp->bsid = htonl (bsid);
8687
8688   /* send it... */
8689   S (mp);
8690
8691   /* Wait for a reply... */
8692   W (ret);
8693   return ret;
8694 }
8695
8696 static int
8697 api_bier_table_add_del (vat_main_t * vam)
8698 {
8699   unformat_input_t *i = vam->input;
8700   vl_api_bier_table_add_del_t *mp;
8701   u8 is_add = 1;
8702   u32 set = 0, sub_domain = 0, hdr_len = 3;
8703   mpls_label_t local_label = MPLS_LABEL_INVALID;
8704   int ret;
8705
8706   /* Parse args required to build the message */
8707   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8708     {
8709       if (unformat (i, "sub-domain %d", &sub_domain))
8710         ;
8711       else if (unformat (i, "set %d", &set))
8712         ;
8713       else if (unformat (i, "label %d", &local_label))
8714         ;
8715       else if (unformat (i, "hdr-len %d", &hdr_len))
8716         ;
8717       else if (unformat (i, "add"))
8718         is_add = 1;
8719       else if (unformat (i, "del"))
8720         is_add = 0;
8721       else
8722         {
8723           clib_warning ("parse error '%U'", format_unformat_error, i);
8724           return -99;
8725         }
8726     }
8727
8728   if (MPLS_LABEL_INVALID == local_label)
8729     {
8730       errmsg ("missing label\n");
8731       return -99;
8732     }
8733
8734   /* Construct the API message */
8735   M (BIER_TABLE_ADD_DEL, mp);
8736
8737   mp->bt_is_add = is_add;
8738   mp->bt_label = ntohl (local_label);
8739   mp->bt_tbl_id.bt_set = set;
8740   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8741   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8742
8743   /* send it... */
8744   S (mp);
8745
8746   /* Wait for a reply... */
8747   W (ret);
8748
8749   return (ret);
8750 }
8751
8752 static int
8753 api_bier_route_add_del (vat_main_t * vam)
8754 {
8755   unformat_input_t *i = vam->input;
8756   vl_api_bier_route_add_del_t *mp;
8757   u8 is_add = 1;
8758   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8759   ip4_address_t v4_next_hop_address;
8760   ip6_address_t v6_next_hop_address;
8761   u8 next_hop_set = 0;
8762   u8 next_hop_proto_is_ip4 = 1;
8763   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8764   int ret;
8765
8766   /* Parse args required to build the message */
8767   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8768     {
8769       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8770         {
8771           next_hop_proto_is_ip4 = 1;
8772           next_hop_set = 1;
8773         }
8774       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8775         {
8776           next_hop_proto_is_ip4 = 0;
8777           next_hop_set = 1;
8778         }
8779       if (unformat (i, "sub-domain %d", &sub_domain))
8780         ;
8781       else if (unformat (i, "set %d", &set))
8782         ;
8783       else if (unformat (i, "hdr-len %d", &hdr_len))
8784         ;
8785       else if (unformat (i, "bp %d", &bp))
8786         ;
8787       else if (unformat (i, "add"))
8788         is_add = 1;
8789       else if (unformat (i, "del"))
8790         is_add = 0;
8791       else if (unformat (i, "out-label %d", &next_hop_out_label))
8792         ;
8793       else
8794         {
8795           clib_warning ("parse error '%U'", format_unformat_error, i);
8796           return -99;
8797         }
8798     }
8799
8800   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8801     {
8802       errmsg ("next hop / label set\n");
8803       return -99;
8804     }
8805   if (0 == bp)
8806     {
8807       errmsg ("bit=position not set\n");
8808       return -99;
8809     }
8810
8811   /* Construct the API message */
8812   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
8813
8814   mp->br_is_add = is_add;
8815   mp->br_route.br_tbl_id.bt_set = set;
8816   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
8817   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
8818   mp->br_route.br_bp = ntohs (bp);
8819   mp->br_route.br_n_paths = 1;
8820   mp->br_route.br_paths[0].n_labels = 1;
8821   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
8822   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
8823                                     FIB_API_PATH_NH_PROTO_IP4 :
8824                                     FIB_API_PATH_NH_PROTO_IP6);
8825
8826   if (next_hop_proto_is_ip4)
8827     {
8828       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
8829                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8830     }
8831   else
8832     {
8833       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
8834                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8835     }
8836
8837   /* send it... */
8838   S (mp);
8839
8840   /* Wait for a reply... */
8841   W (ret);
8842
8843   return (ret);
8844 }
8845
8846 static int
8847 api_mpls_tunnel_add_del (vat_main_t * vam)
8848 {
8849   unformat_input_t *i = vam->input;
8850   vl_api_mpls_tunnel_add_del_t *mp;
8851
8852   vl_api_fib_path_t paths[8];
8853   u32 sw_if_index = ~0;
8854   u8 path_count = 0;
8855   u8 l2_only = 0;
8856   u8 is_add = 1;
8857   int ret;
8858
8859   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8860     {
8861       if (unformat (i, "add"))
8862         is_add = 1;
8863       else
8864         if (unformat
8865             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
8866         is_add = 0;
8867       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8868         is_add = 0;
8869       else if (unformat (i, "l2-only"))
8870         l2_only = 1;
8871       else
8872         if (unformat
8873             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8874         {
8875           path_count++;
8876           if (8 == path_count)
8877             {
8878               errmsg ("max 8 paths");
8879               return -99;
8880             }
8881         }
8882       else
8883         {
8884           clib_warning ("parse error '%U'", format_unformat_error, i);
8885           return -99;
8886         }
8887     }
8888
8889   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8890
8891   mp->mt_is_add = is_add;
8892   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
8893   mp->mt_tunnel.mt_l2_only = l2_only;
8894   mp->mt_tunnel.mt_is_multicast = 0;
8895   mp->mt_tunnel.mt_n_paths = path_count;
8896
8897   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
8898                sizeof (paths[0]) * path_count);
8899
8900   S (mp);
8901   W (ret);
8902   return ret;
8903 }
8904
8905 static int
8906 api_sw_interface_set_unnumbered (vat_main_t * vam)
8907 {
8908   unformat_input_t *i = vam->input;
8909   vl_api_sw_interface_set_unnumbered_t *mp;
8910   u32 sw_if_index;
8911   u32 unnum_sw_index = ~0;
8912   u8 is_add = 1;
8913   u8 sw_if_index_set = 0;
8914   int ret;
8915
8916   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8917     {
8918       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8919         sw_if_index_set = 1;
8920       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8921         sw_if_index_set = 1;
8922       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8923         ;
8924       else if (unformat (i, "del"))
8925         is_add = 0;
8926       else
8927         {
8928           clib_warning ("parse error '%U'", format_unformat_error, i);
8929           return -99;
8930         }
8931     }
8932
8933   if (sw_if_index_set == 0)
8934     {
8935       errmsg ("missing interface name or sw_if_index");
8936       return -99;
8937     }
8938
8939   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8940
8941   mp->sw_if_index = ntohl (sw_if_index);
8942   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8943   mp->is_add = is_add;
8944
8945   S (mp);
8946   W (ret);
8947   return ret;
8948 }
8949
8950
8951 static int
8952 api_create_vlan_subif (vat_main_t * vam)
8953 {
8954   unformat_input_t *i = vam->input;
8955   vl_api_create_vlan_subif_t *mp;
8956   u32 sw_if_index;
8957   u8 sw_if_index_set = 0;
8958   u32 vlan_id;
8959   u8 vlan_id_set = 0;
8960   int ret;
8961
8962   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8963     {
8964       if (unformat (i, "sw_if_index %d", &sw_if_index))
8965         sw_if_index_set = 1;
8966       else
8967         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8968         sw_if_index_set = 1;
8969       else if (unformat (i, "vlan %d", &vlan_id))
8970         vlan_id_set = 1;
8971       else
8972         {
8973           clib_warning ("parse error '%U'", format_unformat_error, i);
8974           return -99;
8975         }
8976     }
8977
8978   if (sw_if_index_set == 0)
8979     {
8980       errmsg ("missing interface name or sw_if_index");
8981       return -99;
8982     }
8983
8984   if (vlan_id_set == 0)
8985     {
8986       errmsg ("missing vlan_id");
8987       return -99;
8988     }
8989   M (CREATE_VLAN_SUBIF, mp);
8990
8991   mp->sw_if_index = ntohl (sw_if_index);
8992   mp->vlan_id = ntohl (vlan_id);
8993
8994   S (mp);
8995   W (ret);
8996   return ret;
8997 }
8998
8999 #define foreach_create_subif_bit                \
9000 _(no_tags)                                      \
9001 _(one_tag)                                      \
9002 _(two_tags)                                     \
9003 _(dot1ad)                                       \
9004 _(exact_match)                                  \
9005 _(default_sub)                                  \
9006 _(outer_vlan_id_any)                            \
9007 _(inner_vlan_id_any)
9008
9009 #define foreach_create_subif_flag               \
9010 _(0, "no_tags")                                 \
9011 _(1, "one_tag")                                 \
9012 _(2, "two_tags")                                \
9013 _(3, "dot1ad")                                  \
9014 _(4, "exact_match")                             \
9015 _(5, "default_sub")                             \
9016 _(6, "outer_vlan_id_any")                       \
9017 _(7, "inner_vlan_id_any")
9018
9019 static int
9020 api_create_subif (vat_main_t * vam)
9021 {
9022   unformat_input_t *i = vam->input;
9023   vl_api_create_subif_t *mp;
9024   u32 sw_if_index;
9025   u8 sw_if_index_set = 0;
9026   u32 sub_id;
9027   u8 sub_id_set = 0;
9028   u32 __attribute__ ((unused)) no_tags = 0;
9029   u32 __attribute__ ((unused)) one_tag = 0;
9030   u32 __attribute__ ((unused)) two_tags = 0;
9031   u32 __attribute__ ((unused)) dot1ad = 0;
9032   u32 __attribute__ ((unused)) exact_match = 0;
9033   u32 __attribute__ ((unused)) default_sub = 0;
9034   u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
9035   u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
9036   u32 tmp;
9037   u16 outer_vlan_id = 0;
9038   u16 inner_vlan_id = 0;
9039   int ret;
9040
9041   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9042     {
9043       if (unformat (i, "sw_if_index %d", &sw_if_index))
9044         sw_if_index_set = 1;
9045       else
9046         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9047         sw_if_index_set = 1;
9048       else if (unformat (i, "sub_id %d", &sub_id))
9049         sub_id_set = 1;
9050       else if (unformat (i, "outer_vlan_id %d", &tmp))
9051         outer_vlan_id = tmp;
9052       else if (unformat (i, "inner_vlan_id %d", &tmp))
9053         inner_vlan_id = tmp;
9054
9055 #define _(a) else if (unformat (i, #a)) a = 1 ;
9056       foreach_create_subif_bit
9057 #undef _
9058         else
9059         {
9060           clib_warning ("parse error '%U'", format_unformat_error, i);
9061           return -99;
9062         }
9063     }
9064
9065   if (sw_if_index_set == 0)
9066     {
9067       errmsg ("missing interface name or sw_if_index");
9068       return -99;
9069     }
9070
9071   if (sub_id_set == 0)
9072     {
9073       errmsg ("missing sub_id");
9074       return -99;
9075     }
9076   M (CREATE_SUBIF, mp);
9077
9078   mp->sw_if_index = ntohl (sw_if_index);
9079   mp->sub_id = ntohl (sub_id);
9080
9081 #define _(a,b) mp->sub_if_flags |= (1 << a);
9082   foreach_create_subif_flag;
9083 #undef _
9084
9085   mp->outer_vlan_id = ntohs (outer_vlan_id);
9086   mp->inner_vlan_id = ntohs (inner_vlan_id);
9087
9088   S (mp);
9089   W (ret);
9090   return ret;
9091 }
9092
9093 static int
9094 api_ip_table_replace_begin (vat_main_t * vam)
9095 {
9096   unformat_input_t *i = vam->input;
9097   vl_api_ip_table_replace_begin_t *mp;
9098   u32 table_id = 0;
9099   u8 is_ipv6 = 0;
9100
9101   int ret;
9102   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9103     {
9104       if (unformat (i, "table %d", &table_id))
9105         ;
9106       else if (unformat (i, "ipv6"))
9107         is_ipv6 = 1;
9108       else
9109         {
9110           clib_warning ("parse error '%U'", format_unformat_error, i);
9111           return -99;
9112         }
9113     }
9114
9115   M (IP_TABLE_REPLACE_BEGIN, mp);
9116
9117   mp->table.table_id = ntohl (table_id);
9118   mp->table.is_ip6 = is_ipv6;
9119
9120   S (mp);
9121   W (ret);
9122   return ret;
9123 }
9124
9125 static int
9126 api_ip_table_flush (vat_main_t * vam)
9127 {
9128   unformat_input_t *i = vam->input;
9129   vl_api_ip_table_flush_t *mp;
9130   u32 table_id = 0;
9131   u8 is_ipv6 = 0;
9132
9133   int ret;
9134   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9135     {
9136       if (unformat (i, "table %d", &table_id))
9137         ;
9138       else if (unformat (i, "ipv6"))
9139         is_ipv6 = 1;
9140       else
9141         {
9142           clib_warning ("parse error '%U'", format_unformat_error, i);
9143           return -99;
9144         }
9145     }
9146
9147   M (IP_TABLE_FLUSH, mp);
9148
9149   mp->table.table_id = ntohl (table_id);
9150   mp->table.is_ip6 = is_ipv6;
9151
9152   S (mp);
9153   W (ret);
9154   return ret;
9155 }
9156
9157 static int
9158 api_ip_table_replace_end (vat_main_t * vam)
9159 {
9160   unformat_input_t *i = vam->input;
9161   vl_api_ip_table_replace_end_t *mp;
9162   u32 table_id = 0;
9163   u8 is_ipv6 = 0;
9164
9165   int ret;
9166   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9167     {
9168       if (unformat (i, "table %d", &table_id))
9169         ;
9170       else if (unformat (i, "ipv6"))
9171         is_ipv6 = 1;
9172       else
9173         {
9174           clib_warning ("parse error '%U'", format_unformat_error, i);
9175           return -99;
9176         }
9177     }
9178
9179   M (IP_TABLE_REPLACE_END, mp);
9180
9181   mp->table.table_id = ntohl (table_id);
9182   mp->table.is_ip6 = is_ipv6;
9183
9184   S (mp);
9185   W (ret);
9186   return ret;
9187 }
9188
9189 static int
9190 api_set_ip_flow_hash (vat_main_t * vam)
9191 {
9192   unformat_input_t *i = vam->input;
9193   vl_api_set_ip_flow_hash_t *mp;
9194   u32 vrf_id = 0;
9195   u8 is_ipv6 = 0;
9196   u8 vrf_id_set = 0;
9197   u8 src = 0;
9198   u8 dst = 0;
9199   u8 sport = 0;
9200   u8 dport = 0;
9201   u8 proto = 0;
9202   u8 reverse = 0;
9203   int ret;
9204
9205   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9206     {
9207       if (unformat (i, "vrf %d", &vrf_id))
9208         vrf_id_set = 1;
9209       else if (unformat (i, "ipv6"))
9210         is_ipv6 = 1;
9211       else if (unformat (i, "src"))
9212         src = 1;
9213       else if (unformat (i, "dst"))
9214         dst = 1;
9215       else if (unformat (i, "sport"))
9216         sport = 1;
9217       else if (unformat (i, "dport"))
9218         dport = 1;
9219       else if (unformat (i, "proto"))
9220         proto = 1;
9221       else if (unformat (i, "reverse"))
9222         reverse = 1;
9223
9224       else
9225         {
9226           clib_warning ("parse error '%U'", format_unformat_error, i);
9227           return -99;
9228         }
9229     }
9230
9231   if (vrf_id_set == 0)
9232     {
9233       errmsg ("missing vrf id");
9234       return -99;
9235     }
9236
9237   M (SET_IP_FLOW_HASH, mp);
9238   mp->src = src;
9239   mp->dst = dst;
9240   mp->sport = sport;
9241   mp->dport = dport;
9242   mp->proto = proto;
9243   mp->reverse = reverse;
9244   mp->vrf_id = ntohl (vrf_id);
9245   mp->is_ipv6 = is_ipv6;
9246
9247   S (mp);
9248   W (ret);
9249   return ret;
9250 }
9251
9252 static int
9253 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9254 {
9255   unformat_input_t *i = vam->input;
9256   vl_api_sw_interface_ip6_enable_disable_t *mp;
9257   u32 sw_if_index;
9258   u8 sw_if_index_set = 0;
9259   u8 enable = 0;
9260   int ret;
9261
9262   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9263     {
9264       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9265         sw_if_index_set = 1;
9266       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9267         sw_if_index_set = 1;
9268       else if (unformat (i, "enable"))
9269         enable = 1;
9270       else if (unformat (i, "disable"))
9271         enable = 0;
9272       else
9273         {
9274           clib_warning ("parse error '%U'", format_unformat_error, i);
9275           return -99;
9276         }
9277     }
9278
9279   if (sw_if_index_set == 0)
9280     {
9281       errmsg ("missing interface name or sw_if_index");
9282       return -99;
9283     }
9284
9285   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9286
9287   mp->sw_if_index = ntohl (sw_if_index);
9288   mp->enable = enable;
9289
9290   S (mp);
9291   W (ret);
9292   return ret;
9293 }
9294
9295
9296 static int
9297 api_l2_patch_add_del (vat_main_t * vam)
9298 {
9299   unformat_input_t *i = vam->input;
9300   vl_api_l2_patch_add_del_t *mp;
9301   u32 rx_sw_if_index;
9302   u8 rx_sw_if_index_set = 0;
9303   u32 tx_sw_if_index;
9304   u8 tx_sw_if_index_set = 0;
9305   u8 is_add = 1;
9306   int ret;
9307
9308   /* Parse args required to build the message */
9309   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9310     {
9311       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9312         rx_sw_if_index_set = 1;
9313       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9314         tx_sw_if_index_set = 1;
9315       else if (unformat (i, "rx"))
9316         {
9317           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9318             {
9319               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9320                             &rx_sw_if_index))
9321                 rx_sw_if_index_set = 1;
9322             }
9323           else
9324             break;
9325         }
9326       else if (unformat (i, "tx"))
9327         {
9328           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9329             {
9330               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9331                             &tx_sw_if_index))
9332                 tx_sw_if_index_set = 1;
9333             }
9334           else
9335             break;
9336         }
9337       else if (unformat (i, "del"))
9338         is_add = 0;
9339       else
9340         break;
9341     }
9342
9343   if (rx_sw_if_index_set == 0)
9344     {
9345       errmsg ("missing rx interface name or rx_sw_if_index");
9346       return -99;
9347     }
9348
9349   if (tx_sw_if_index_set == 0)
9350     {
9351       errmsg ("missing tx interface name or tx_sw_if_index");
9352       return -99;
9353     }
9354
9355   M (L2_PATCH_ADD_DEL, mp);
9356
9357   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9358   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9359   mp->is_add = is_add;
9360
9361   S (mp);
9362   W (ret);
9363   return ret;
9364 }
9365
9366 u8 is_del;
9367 u8 localsid_addr[16];
9368 u8 end_psp;
9369 u8 behavior;
9370 u32 sw_if_index;
9371 u32 vlan_index;
9372 u32 fib_table;
9373 u8 nh_addr[16];
9374
9375 static int
9376 api_sr_localsid_add_del (vat_main_t * vam)
9377 {
9378   unformat_input_t *i = vam->input;
9379   vl_api_sr_localsid_add_del_t *mp;
9380
9381   u8 is_del;
9382   ip6_address_t localsid;
9383   u8 end_psp = 0;
9384   u8 behavior = ~0;
9385   u32 sw_if_index;
9386   u32 fib_table = ~(u32) 0;
9387   ip46_address_t nh_addr;
9388   clib_memset (&nh_addr, 0, sizeof (ip46_address_t));
9389
9390   bool nexthop_set = 0;
9391
9392   int ret;
9393
9394   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9395     {
9396       if (unformat (i, "del"))
9397         is_del = 1;
9398       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9399       else if (unformat (i, "next-hop %U", unformat_ip46_address, &nh_addr))
9400         nexthop_set = 1;
9401       else if (unformat (i, "behavior %u", &behavior));
9402       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9403       else if (unformat (i, "fib-table %u", &fib_table));
9404       else if (unformat (i, "end.psp %u", &behavior));
9405       else
9406         break;
9407     }
9408
9409   M (SR_LOCALSID_ADD_DEL, mp);
9410
9411   clib_memcpy (mp->localsid, &localsid, sizeof (mp->localsid));
9412
9413   if (nexthop_set)
9414     {
9415       clib_memcpy (&mp->nh_addr.un, &nh_addr, sizeof (mp->nh_addr.un));
9416     }
9417   mp->behavior = behavior;
9418   mp->sw_if_index = ntohl (sw_if_index);
9419   mp->fib_table = ntohl (fib_table);
9420   mp->end_psp = end_psp;
9421   mp->is_del = is_del;
9422
9423   S (mp);
9424   W (ret);
9425   return ret;
9426 }
9427
9428 static int
9429 api_ioam_enable (vat_main_t * vam)
9430 {
9431   unformat_input_t *input = vam->input;
9432   vl_api_ioam_enable_t *mp;
9433   u32 id = 0;
9434   int has_trace_option = 0;
9435   int has_pot_option = 0;
9436   int has_seqno_option = 0;
9437   int has_analyse_option = 0;
9438   int ret;
9439
9440   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9441     {
9442       if (unformat (input, "trace"))
9443         has_trace_option = 1;
9444       else if (unformat (input, "pot"))
9445         has_pot_option = 1;
9446       else if (unformat (input, "seqno"))
9447         has_seqno_option = 1;
9448       else if (unformat (input, "analyse"))
9449         has_analyse_option = 1;
9450       else
9451         break;
9452     }
9453   M (IOAM_ENABLE, mp);
9454   mp->id = htons (id);
9455   mp->seqno = has_seqno_option;
9456   mp->analyse = has_analyse_option;
9457   mp->pot_enable = has_pot_option;
9458   mp->trace_enable = has_trace_option;
9459
9460   S (mp);
9461   W (ret);
9462   return ret;
9463 }
9464
9465
9466 static int
9467 api_ioam_disable (vat_main_t * vam)
9468 {
9469   vl_api_ioam_disable_t *mp;
9470   int ret;
9471
9472   M (IOAM_DISABLE, mp);
9473   S (mp);
9474   W (ret);
9475   return ret;
9476 }
9477
9478 #define foreach_tcp_proto_field                 \
9479 _(src_port)                                     \
9480 _(dst_port)
9481
9482 #define foreach_udp_proto_field                 \
9483 _(src_port)                                     \
9484 _(dst_port)
9485
9486 #define foreach_ip4_proto_field                 \
9487 _(src_address)                                  \
9488 _(dst_address)                                  \
9489 _(tos)                                          \
9490 _(length)                                       \
9491 _(fragment_id)                                  \
9492 _(ttl)                                          \
9493 _(protocol)                                     \
9494 _(checksum)
9495
9496 typedef struct
9497 {
9498   u16 src_port, dst_port;
9499 } tcpudp_header_t;
9500
9501 #if VPP_API_TEST_BUILTIN == 0
9502 uword
9503 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9504 {
9505   u8 **maskp = va_arg (*args, u8 **);
9506   u8 *mask = 0;
9507   u8 found_something = 0;
9508   tcp_header_t *tcp;
9509
9510 #define _(a) u8 a=0;
9511   foreach_tcp_proto_field;
9512 #undef _
9513
9514   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9515     {
9516       if (0);
9517 #define _(a) else if (unformat (input, #a)) a=1;
9518       foreach_tcp_proto_field
9519 #undef _
9520         else
9521         break;
9522     }
9523
9524 #define _(a) found_something += a;
9525   foreach_tcp_proto_field;
9526 #undef _
9527
9528   if (found_something == 0)
9529     return 0;
9530
9531   vec_validate (mask, sizeof (*tcp) - 1);
9532
9533   tcp = (tcp_header_t *) mask;
9534
9535 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
9536   foreach_tcp_proto_field;
9537 #undef _
9538
9539   *maskp = mask;
9540   return 1;
9541 }
9542
9543 uword
9544 unformat_udp_mask (unformat_input_t * input, va_list * args)
9545 {
9546   u8 **maskp = va_arg (*args, u8 **);
9547   u8 *mask = 0;
9548   u8 found_something = 0;
9549   udp_header_t *udp;
9550
9551 #define _(a) u8 a=0;
9552   foreach_udp_proto_field;
9553 #undef _
9554
9555   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9556     {
9557       if (0);
9558 #define _(a) else if (unformat (input, #a)) a=1;
9559       foreach_udp_proto_field
9560 #undef _
9561         else
9562         break;
9563     }
9564
9565 #define _(a) found_something += a;
9566   foreach_udp_proto_field;
9567 #undef _
9568
9569   if (found_something == 0)
9570     return 0;
9571
9572   vec_validate (mask, sizeof (*udp) - 1);
9573
9574   udp = (udp_header_t *) mask;
9575
9576 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
9577   foreach_udp_proto_field;
9578 #undef _
9579
9580   *maskp = mask;
9581   return 1;
9582 }
9583
9584 uword
9585 unformat_l4_mask (unformat_input_t * input, va_list * args)
9586 {
9587   u8 **maskp = va_arg (*args, u8 **);
9588   u16 src_port = 0, dst_port = 0;
9589   tcpudp_header_t *tcpudp;
9590
9591   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9592     {
9593       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9594         return 1;
9595       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9596         return 1;
9597       else if (unformat (input, "src_port"))
9598         src_port = 0xFFFF;
9599       else if (unformat (input, "dst_port"))
9600         dst_port = 0xFFFF;
9601       else
9602         return 0;
9603     }
9604
9605   if (!src_port && !dst_port)
9606     return 0;
9607
9608   u8 *mask = 0;
9609   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9610
9611   tcpudp = (tcpudp_header_t *) mask;
9612   tcpudp->src_port = src_port;
9613   tcpudp->dst_port = dst_port;
9614
9615   *maskp = mask;
9616
9617   return 1;
9618 }
9619
9620 uword
9621 unformat_ip4_mask (unformat_input_t * input, va_list * args)
9622 {
9623   u8 **maskp = va_arg (*args, u8 **);
9624   u8 *mask = 0;
9625   u8 found_something = 0;
9626   ip4_header_t *ip;
9627
9628 #define _(a) u8 a=0;
9629   foreach_ip4_proto_field;
9630 #undef _
9631   u8 version = 0;
9632   u8 hdr_length = 0;
9633
9634
9635   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9636     {
9637       if (unformat (input, "version"))
9638         version = 1;
9639       else if (unformat (input, "hdr_length"))
9640         hdr_length = 1;
9641       else if (unformat (input, "src"))
9642         src_address = 1;
9643       else if (unformat (input, "dst"))
9644         dst_address = 1;
9645       else if (unformat (input, "proto"))
9646         protocol = 1;
9647
9648 #define _(a) else if (unformat (input, #a)) a=1;
9649       foreach_ip4_proto_field
9650 #undef _
9651         else
9652         break;
9653     }
9654
9655 #define _(a) found_something += a;
9656   foreach_ip4_proto_field;
9657 #undef _
9658
9659   if (found_something == 0)
9660     return 0;
9661
9662   vec_validate (mask, sizeof (*ip) - 1);
9663
9664   ip = (ip4_header_t *) mask;
9665
9666 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
9667   foreach_ip4_proto_field;
9668 #undef _
9669
9670   ip->ip_version_and_header_length = 0;
9671
9672   if (version)
9673     ip->ip_version_and_header_length |= 0xF0;
9674
9675   if (hdr_length)
9676     ip->ip_version_and_header_length |= 0x0F;
9677
9678   *maskp = mask;
9679   return 1;
9680 }
9681
9682 #define foreach_ip6_proto_field                 \
9683 _(src_address)                                  \
9684 _(dst_address)                                  \
9685 _(payload_length)                               \
9686 _(hop_limit)                                    \
9687 _(protocol)
9688
9689 uword
9690 unformat_ip6_mask (unformat_input_t * input, va_list * args)
9691 {
9692   u8 **maskp = va_arg (*args, u8 **);
9693   u8 *mask = 0;
9694   u8 found_something = 0;
9695   ip6_header_t *ip;
9696   u32 ip_version_traffic_class_and_flow_label;
9697
9698 #define _(a) u8 a=0;
9699   foreach_ip6_proto_field;
9700 #undef _
9701   u8 version = 0;
9702   u8 traffic_class = 0;
9703   u8 flow_label = 0;
9704
9705   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9706     {
9707       if (unformat (input, "version"))
9708         version = 1;
9709       else if (unformat (input, "traffic-class"))
9710         traffic_class = 1;
9711       else if (unformat (input, "flow-label"))
9712         flow_label = 1;
9713       else if (unformat (input, "src"))
9714         src_address = 1;
9715       else if (unformat (input, "dst"))
9716         dst_address = 1;
9717       else if (unformat (input, "proto"))
9718         protocol = 1;
9719
9720 #define _(a) else if (unformat (input, #a)) a=1;
9721       foreach_ip6_proto_field
9722 #undef _
9723         else
9724         break;
9725     }
9726
9727 #define _(a) found_something += a;
9728   foreach_ip6_proto_field;
9729 #undef _
9730
9731   if (found_something == 0)
9732     return 0;
9733
9734   vec_validate (mask, sizeof (*ip) - 1);
9735
9736   ip = (ip6_header_t *) mask;
9737
9738 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
9739   foreach_ip6_proto_field;
9740 #undef _
9741
9742   ip_version_traffic_class_and_flow_label = 0;
9743
9744   if (version)
9745     ip_version_traffic_class_and_flow_label |= 0xF0000000;
9746
9747   if (traffic_class)
9748     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9749
9750   if (flow_label)
9751     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9752
9753   ip->ip_version_traffic_class_and_flow_label =
9754     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9755
9756   *maskp = mask;
9757   return 1;
9758 }
9759
9760 uword
9761 unformat_l3_mask (unformat_input_t * input, va_list * args)
9762 {
9763   u8 **maskp = va_arg (*args, u8 **);
9764
9765   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9766     {
9767       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9768         return 1;
9769       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9770         return 1;
9771       else
9772         break;
9773     }
9774   return 0;
9775 }
9776
9777 uword
9778 unformat_l2_mask (unformat_input_t * input, va_list * args)
9779 {
9780   u8 **maskp = va_arg (*args, u8 **);
9781   u8 *mask = 0;
9782   u8 src = 0;
9783   u8 dst = 0;
9784   u8 proto = 0;
9785   u8 tag1 = 0;
9786   u8 tag2 = 0;
9787   u8 ignore_tag1 = 0;
9788   u8 ignore_tag2 = 0;
9789   u8 cos1 = 0;
9790   u8 cos2 = 0;
9791   u8 dot1q = 0;
9792   u8 dot1ad = 0;
9793   int len = 14;
9794
9795   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9796     {
9797       if (unformat (input, "src"))
9798         src = 1;
9799       else if (unformat (input, "dst"))
9800         dst = 1;
9801       else if (unformat (input, "proto"))
9802         proto = 1;
9803       else if (unformat (input, "tag1"))
9804         tag1 = 1;
9805       else if (unformat (input, "tag2"))
9806         tag2 = 1;
9807       else if (unformat (input, "ignore-tag1"))
9808         ignore_tag1 = 1;
9809       else if (unformat (input, "ignore-tag2"))
9810         ignore_tag2 = 1;
9811       else if (unformat (input, "cos1"))
9812         cos1 = 1;
9813       else if (unformat (input, "cos2"))
9814         cos2 = 1;
9815       else if (unformat (input, "dot1q"))
9816         dot1q = 1;
9817       else if (unformat (input, "dot1ad"))
9818         dot1ad = 1;
9819       else
9820         break;
9821     }
9822   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9823        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9824     return 0;
9825
9826   if (tag1 || ignore_tag1 || cos1 || dot1q)
9827     len = 18;
9828   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9829     len = 22;
9830
9831   vec_validate (mask, len - 1);
9832
9833   if (dst)
9834     clib_memset (mask, 0xff, 6);
9835
9836   if (src)
9837     clib_memset (mask + 6, 0xff, 6);
9838
9839   if (tag2 || dot1ad)
9840     {
9841       /* inner vlan tag */
9842       if (tag2)
9843         {
9844           mask[19] = 0xff;
9845           mask[18] = 0x0f;
9846         }
9847       if (cos2)
9848         mask[18] |= 0xe0;
9849       if (proto)
9850         mask[21] = mask[20] = 0xff;
9851       if (tag1)
9852         {
9853           mask[15] = 0xff;
9854           mask[14] = 0x0f;
9855         }
9856       if (cos1)
9857         mask[14] |= 0xe0;
9858       *maskp = mask;
9859       return 1;
9860     }
9861   if (tag1 | dot1q)
9862     {
9863       if (tag1)
9864         {
9865           mask[15] = 0xff;
9866           mask[14] = 0x0f;
9867         }
9868       if (cos1)
9869         mask[14] |= 0xe0;
9870       if (proto)
9871         mask[16] = mask[17] = 0xff;
9872
9873       *maskp = mask;
9874       return 1;
9875     }
9876   if (cos2)
9877     mask[18] |= 0xe0;
9878   if (cos1)
9879     mask[14] |= 0xe0;
9880   if (proto)
9881     mask[12] = mask[13] = 0xff;
9882
9883   *maskp = mask;
9884   return 1;
9885 }
9886
9887 uword
9888 unformat_classify_mask (unformat_input_t * input, va_list * args)
9889 {
9890   u8 **maskp = va_arg (*args, u8 **);
9891   u32 *skipp = va_arg (*args, u32 *);
9892   u32 *matchp = va_arg (*args, u32 *);
9893   u32 match;
9894   u8 *mask = 0;
9895   u8 *l2 = 0;
9896   u8 *l3 = 0;
9897   u8 *l4 = 0;
9898   int i;
9899
9900   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9901     {
9902       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9903         ;
9904       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9905         ;
9906       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9907         ;
9908       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9909         ;
9910       else
9911         break;
9912     }
9913
9914   if (l4 && !l3)
9915     {
9916       vec_free (mask);
9917       vec_free (l2);
9918       vec_free (l4);
9919       return 0;
9920     }
9921
9922   if (mask || l2 || l3 || l4)
9923     {
9924       if (l2 || l3 || l4)
9925         {
9926           /* "With a free Ethernet header in every package" */
9927           if (l2 == 0)
9928             vec_validate (l2, 13);
9929           mask = l2;
9930           if (vec_len (l3))
9931             {
9932               vec_append (mask, l3);
9933               vec_free (l3);
9934             }
9935           if (vec_len (l4))
9936             {
9937               vec_append (mask, l4);
9938               vec_free (l4);
9939             }
9940         }
9941
9942       /* Scan forward looking for the first significant mask octet */
9943       for (i = 0; i < vec_len (mask); i++)
9944         if (mask[i])
9945           break;
9946
9947       /* compute (skip, match) params */
9948       *skipp = i / sizeof (u32x4);
9949       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9950
9951       /* Pad mask to an even multiple of the vector size */
9952       while (vec_len (mask) % sizeof (u32x4))
9953         vec_add1 (mask, 0);
9954
9955       match = vec_len (mask) / sizeof (u32x4);
9956
9957       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9958         {
9959           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9960           if (*tmp || *(tmp + 1))
9961             break;
9962           match--;
9963         }
9964       if (match == 0)
9965         clib_warning ("BUG: match 0");
9966
9967       _vec_len (mask) = match * sizeof (u32x4);
9968
9969       *matchp = match;
9970       *maskp = mask;
9971
9972       return 1;
9973     }
9974
9975   return 0;
9976 }
9977 #endif /* VPP_API_TEST_BUILTIN */
9978
9979 #define foreach_l2_next                         \
9980 _(drop, DROP)                                   \
9981 _(ethernet, ETHERNET_INPUT)                     \
9982 _(ip4, IP4_INPUT)                               \
9983 _(ip6, IP6_INPUT)
9984
9985 uword
9986 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9987 {
9988   u32 *miss_next_indexp = va_arg (*args, u32 *);
9989   u32 next_index = 0;
9990   u32 tmp;
9991
9992 #define _(n,N) \
9993   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9994   foreach_l2_next;
9995 #undef _
9996
9997   if (unformat (input, "%d", &tmp))
9998     {
9999       next_index = tmp;
10000       goto out;
10001     }
10002
10003   return 0;
10004
10005 out:
10006   *miss_next_indexp = next_index;
10007   return 1;
10008 }
10009
10010 #define foreach_ip_next                         \
10011 _(drop, DROP)                                   \
10012 _(local, LOCAL)                                 \
10013 _(rewrite, REWRITE)
10014
10015 uword
10016 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10017 {
10018   u32 *miss_next_indexp = va_arg (*args, u32 *);
10019   u32 next_index = 0;
10020   u32 tmp;
10021
10022 #define _(n,N) \
10023   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10024   foreach_ip_next;
10025 #undef _
10026
10027   if (unformat (input, "%d", &tmp))
10028     {
10029       next_index = tmp;
10030       goto out;
10031     }
10032
10033   return 0;
10034
10035 out:
10036   *miss_next_indexp = next_index;
10037   return 1;
10038 }
10039
10040 #define foreach_acl_next                        \
10041 _(deny, DENY)
10042
10043 uword
10044 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10045 {
10046   u32 *miss_next_indexp = va_arg (*args, u32 *);
10047   u32 next_index = 0;
10048   u32 tmp;
10049
10050 #define _(n,N) \
10051   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10052   foreach_acl_next;
10053 #undef _
10054
10055   if (unformat (input, "permit"))
10056     {
10057       next_index = ~0;
10058       goto out;
10059     }
10060   else if (unformat (input, "%d", &tmp))
10061     {
10062       next_index = tmp;
10063       goto out;
10064     }
10065
10066   return 0;
10067
10068 out:
10069   *miss_next_indexp = next_index;
10070   return 1;
10071 }
10072
10073 uword
10074 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10075 {
10076   u32 *r = va_arg (*args, u32 *);
10077
10078   if (unformat (input, "conform-color"))
10079     *r = POLICE_CONFORM;
10080   else if (unformat (input, "exceed-color"))
10081     *r = POLICE_EXCEED;
10082   else
10083     return 0;
10084
10085   return 1;
10086 }
10087
10088 static int
10089 api_classify_add_del_table (vat_main_t * vam)
10090 {
10091   unformat_input_t *i = vam->input;
10092   vl_api_classify_add_del_table_t *mp;
10093
10094   u32 nbuckets = 2;
10095   u32 skip = ~0;
10096   u32 match = ~0;
10097   int is_add = 1;
10098   int del_chain = 0;
10099   u32 table_index = ~0;
10100   u32 next_table_index = ~0;
10101   u32 miss_next_index = ~0;
10102   u32 memory_size = 32 << 20;
10103   u8 *mask = 0;
10104   u32 current_data_flag = 0;
10105   int current_data_offset = 0;
10106   int ret;
10107
10108   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10109     {
10110       if (unformat (i, "del"))
10111         is_add = 0;
10112       else if (unformat (i, "del-chain"))
10113         {
10114           is_add = 0;
10115           del_chain = 1;
10116         }
10117       else if (unformat (i, "buckets %d", &nbuckets))
10118         ;
10119       else if (unformat (i, "memory_size %d", &memory_size))
10120         ;
10121       else if (unformat (i, "skip %d", &skip))
10122         ;
10123       else if (unformat (i, "match %d", &match))
10124         ;
10125       else if (unformat (i, "table %d", &table_index))
10126         ;
10127       else if (unformat (i, "mask %U", unformat_classify_mask,
10128                          &mask, &skip, &match))
10129         ;
10130       else if (unformat (i, "next-table %d", &next_table_index))
10131         ;
10132       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10133                          &miss_next_index))
10134         ;
10135       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10136                          &miss_next_index))
10137         ;
10138       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10139                          &miss_next_index))
10140         ;
10141       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10142         ;
10143       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10144         ;
10145       else
10146         break;
10147     }
10148
10149   if (is_add && mask == 0)
10150     {
10151       errmsg ("Mask required");
10152       return -99;
10153     }
10154
10155   if (is_add && skip == ~0)
10156     {
10157       errmsg ("skip count required");
10158       return -99;
10159     }
10160
10161   if (is_add && match == ~0)
10162     {
10163       errmsg ("match count required");
10164       return -99;
10165     }
10166
10167   if (!is_add && table_index == ~0)
10168     {
10169       errmsg ("table index required for delete");
10170       return -99;
10171     }
10172
10173   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10174
10175   mp->is_add = is_add;
10176   mp->del_chain = del_chain;
10177   mp->table_index = ntohl (table_index);
10178   mp->nbuckets = ntohl (nbuckets);
10179   mp->memory_size = ntohl (memory_size);
10180   mp->skip_n_vectors = ntohl (skip);
10181   mp->match_n_vectors = ntohl (match);
10182   mp->next_table_index = ntohl (next_table_index);
10183   mp->miss_next_index = ntohl (miss_next_index);
10184   mp->current_data_flag = ntohl (current_data_flag);
10185   mp->current_data_offset = ntohl (current_data_offset);
10186   mp->mask_len = ntohl (vec_len (mask));
10187   clib_memcpy (mp->mask, mask, vec_len (mask));
10188
10189   vec_free (mask);
10190
10191   S (mp);
10192   W (ret);
10193   return ret;
10194 }
10195
10196 #if VPP_API_TEST_BUILTIN == 0
10197 uword
10198 unformat_l4_match (unformat_input_t * input, va_list * args)
10199 {
10200   u8 **matchp = va_arg (*args, u8 **);
10201
10202   u8 *proto_header = 0;
10203   int src_port = 0;
10204   int dst_port = 0;
10205
10206   tcpudp_header_t h;
10207
10208   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10209     {
10210       if (unformat (input, "src_port %d", &src_port))
10211         ;
10212       else if (unformat (input, "dst_port %d", &dst_port))
10213         ;
10214       else
10215         return 0;
10216     }
10217
10218   h.src_port = clib_host_to_net_u16 (src_port);
10219   h.dst_port = clib_host_to_net_u16 (dst_port);
10220   vec_validate (proto_header, sizeof (h) - 1);
10221   memcpy (proto_header, &h, sizeof (h));
10222
10223   *matchp = proto_header;
10224
10225   return 1;
10226 }
10227
10228 uword
10229 unformat_ip4_match (unformat_input_t * input, va_list * args)
10230 {
10231   u8 **matchp = va_arg (*args, u8 **);
10232   u8 *match = 0;
10233   ip4_header_t *ip;
10234   int version = 0;
10235   u32 version_val;
10236   int hdr_length = 0;
10237   u32 hdr_length_val;
10238   int src = 0, dst = 0;
10239   ip4_address_t src_val, dst_val;
10240   int proto = 0;
10241   u32 proto_val;
10242   int tos = 0;
10243   u32 tos_val;
10244   int length = 0;
10245   u32 length_val;
10246   int fragment_id = 0;
10247   u32 fragment_id_val;
10248   int ttl = 0;
10249   int ttl_val;
10250   int checksum = 0;
10251   u32 checksum_val;
10252
10253   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10254     {
10255       if (unformat (input, "version %d", &version_val))
10256         version = 1;
10257       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10258         hdr_length = 1;
10259       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10260         src = 1;
10261       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10262         dst = 1;
10263       else if (unformat (input, "proto %d", &proto_val))
10264         proto = 1;
10265       else if (unformat (input, "tos %d", &tos_val))
10266         tos = 1;
10267       else if (unformat (input, "length %d", &length_val))
10268         length = 1;
10269       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10270         fragment_id = 1;
10271       else if (unformat (input, "ttl %d", &ttl_val))
10272         ttl = 1;
10273       else if (unformat (input, "checksum %d", &checksum_val))
10274         checksum = 1;
10275       else
10276         break;
10277     }
10278
10279   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10280       + ttl + checksum == 0)
10281     return 0;
10282
10283   /*
10284    * Aligned because we use the real comparison functions
10285    */
10286   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10287
10288   ip = (ip4_header_t *) match;
10289
10290   /* These are realistically matched in practice */
10291   if (src)
10292     ip->src_address.as_u32 = src_val.as_u32;
10293
10294   if (dst)
10295     ip->dst_address.as_u32 = dst_val.as_u32;
10296
10297   if (proto)
10298     ip->protocol = proto_val;
10299
10300
10301   /* These are not, but they're included for completeness */
10302   if (version)
10303     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10304
10305   if (hdr_length)
10306     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10307
10308   if (tos)
10309     ip->tos = tos_val;
10310
10311   if (length)
10312     ip->length = clib_host_to_net_u16 (length_val);
10313
10314   if (ttl)
10315     ip->ttl = ttl_val;
10316
10317   if (checksum)
10318     ip->checksum = clib_host_to_net_u16 (checksum_val);
10319
10320   *matchp = match;
10321   return 1;
10322 }
10323
10324 uword
10325 unformat_ip6_match (unformat_input_t * input, va_list * args)
10326 {
10327   u8 **matchp = va_arg (*args, u8 **);
10328   u8 *match = 0;
10329   ip6_header_t *ip;
10330   int version = 0;
10331   u32 version_val;
10332   u8 traffic_class = 0;
10333   u32 traffic_class_val = 0;
10334   u8 flow_label = 0;
10335   u8 flow_label_val;
10336   int src = 0, dst = 0;
10337   ip6_address_t src_val, dst_val;
10338   int proto = 0;
10339   u32 proto_val;
10340   int payload_length = 0;
10341   u32 payload_length_val;
10342   int hop_limit = 0;
10343   int hop_limit_val;
10344   u32 ip_version_traffic_class_and_flow_label;
10345
10346   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10347     {
10348       if (unformat (input, "version %d", &version_val))
10349         version = 1;
10350       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10351         traffic_class = 1;
10352       else if (unformat (input, "flow_label %d", &flow_label_val))
10353         flow_label = 1;
10354       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10355         src = 1;
10356       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10357         dst = 1;
10358       else if (unformat (input, "proto %d", &proto_val))
10359         proto = 1;
10360       else if (unformat (input, "payload_length %d", &payload_length_val))
10361         payload_length = 1;
10362       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10363         hop_limit = 1;
10364       else
10365         break;
10366     }
10367
10368   if (version + traffic_class + flow_label + src + dst + proto +
10369       payload_length + hop_limit == 0)
10370     return 0;
10371
10372   /*
10373    * Aligned because we use the real comparison functions
10374    */
10375   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10376
10377   ip = (ip6_header_t *) match;
10378
10379   if (src)
10380     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10381
10382   if (dst)
10383     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10384
10385   if (proto)
10386     ip->protocol = proto_val;
10387
10388   ip_version_traffic_class_and_flow_label = 0;
10389
10390   if (version)
10391     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10392
10393   if (traffic_class)
10394     ip_version_traffic_class_and_flow_label |=
10395       (traffic_class_val & 0xFF) << 20;
10396
10397   if (flow_label)
10398     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10399
10400   ip->ip_version_traffic_class_and_flow_label =
10401     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10402
10403   if (payload_length)
10404     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10405
10406   if (hop_limit)
10407     ip->hop_limit = hop_limit_val;
10408
10409   *matchp = match;
10410   return 1;
10411 }
10412
10413 uword
10414 unformat_l3_match (unformat_input_t * input, va_list * args)
10415 {
10416   u8 **matchp = va_arg (*args, u8 **);
10417
10418   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10419     {
10420       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10421         return 1;
10422       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10423         return 1;
10424       else
10425         break;
10426     }
10427   return 0;
10428 }
10429
10430 uword
10431 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10432 {
10433   u8 *tagp = va_arg (*args, u8 *);
10434   u32 tag;
10435
10436   if (unformat (input, "%d", &tag))
10437     {
10438       tagp[0] = (tag >> 8) & 0x0F;
10439       tagp[1] = tag & 0xFF;
10440       return 1;
10441     }
10442
10443   return 0;
10444 }
10445
10446 uword
10447 unformat_l2_match (unformat_input_t * input, va_list * args)
10448 {
10449   u8 **matchp = va_arg (*args, u8 **);
10450   u8 *match = 0;
10451   u8 src = 0;
10452   u8 src_val[6];
10453   u8 dst = 0;
10454   u8 dst_val[6];
10455   u8 proto = 0;
10456   u16 proto_val;
10457   u8 tag1 = 0;
10458   u8 tag1_val[2];
10459   u8 tag2 = 0;
10460   u8 tag2_val[2];
10461   int len = 14;
10462   u8 ignore_tag1 = 0;
10463   u8 ignore_tag2 = 0;
10464   u8 cos1 = 0;
10465   u8 cos2 = 0;
10466   u32 cos1_val = 0;
10467   u32 cos2_val = 0;
10468
10469   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10470     {
10471       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10472         src = 1;
10473       else
10474         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10475         dst = 1;
10476       else if (unformat (input, "proto %U",
10477                          unformat_ethernet_type_host_byte_order, &proto_val))
10478         proto = 1;
10479       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10480         tag1 = 1;
10481       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10482         tag2 = 1;
10483       else if (unformat (input, "ignore-tag1"))
10484         ignore_tag1 = 1;
10485       else if (unformat (input, "ignore-tag2"))
10486         ignore_tag2 = 1;
10487       else if (unformat (input, "cos1 %d", &cos1_val))
10488         cos1 = 1;
10489       else if (unformat (input, "cos2 %d", &cos2_val))
10490         cos2 = 1;
10491       else
10492         break;
10493     }
10494   if ((src + dst + proto + tag1 + tag2 +
10495        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10496     return 0;
10497
10498   if (tag1 || ignore_tag1 || cos1)
10499     len = 18;
10500   if (tag2 || ignore_tag2 || cos2)
10501     len = 22;
10502
10503   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10504
10505   if (dst)
10506     clib_memcpy (match, dst_val, 6);
10507
10508   if (src)
10509     clib_memcpy (match + 6, src_val, 6);
10510
10511   if (tag2)
10512     {
10513       /* inner vlan tag */
10514       match[19] = tag2_val[1];
10515       match[18] = tag2_val[0];
10516       if (cos2)
10517         match[18] |= (cos2_val & 0x7) << 5;
10518       if (proto)
10519         {
10520           match[21] = proto_val & 0xff;
10521           match[20] = proto_val >> 8;
10522         }
10523       if (tag1)
10524         {
10525           match[15] = tag1_val[1];
10526           match[14] = tag1_val[0];
10527         }
10528       if (cos1)
10529         match[14] |= (cos1_val & 0x7) << 5;
10530       *matchp = match;
10531       return 1;
10532     }
10533   if (tag1)
10534     {
10535       match[15] = tag1_val[1];
10536       match[14] = tag1_val[0];
10537       if (proto)
10538         {
10539           match[17] = proto_val & 0xff;
10540           match[16] = proto_val >> 8;
10541         }
10542       if (cos1)
10543         match[14] |= (cos1_val & 0x7) << 5;
10544
10545       *matchp = match;
10546       return 1;
10547     }
10548   if (cos2)
10549     match[18] |= (cos2_val & 0x7) << 5;
10550   if (cos1)
10551     match[14] |= (cos1_val & 0x7) << 5;
10552   if (proto)
10553     {
10554       match[13] = proto_val & 0xff;
10555       match[12] = proto_val >> 8;
10556     }
10557
10558   *matchp = match;
10559   return 1;
10560 }
10561
10562 uword
10563 unformat_qos_source (unformat_input_t * input, va_list * args)
10564 {
10565   int *qs = va_arg (*args, int *);
10566
10567   if (unformat (input, "ip"))
10568     *qs = QOS_SOURCE_IP;
10569   else if (unformat (input, "mpls"))
10570     *qs = QOS_SOURCE_MPLS;
10571   else if (unformat (input, "ext"))
10572     *qs = QOS_SOURCE_EXT;
10573   else if (unformat (input, "vlan"))
10574     *qs = QOS_SOURCE_VLAN;
10575   else
10576     return 0;
10577
10578   return 1;
10579 }
10580 #endif
10581
10582 uword
10583 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10584 {
10585   u8 **matchp = va_arg (*args, u8 **);
10586   u32 skip_n_vectors = va_arg (*args, u32);
10587   u32 match_n_vectors = va_arg (*args, u32);
10588
10589   u8 *match = 0;
10590   u8 *l2 = 0;
10591   u8 *l3 = 0;
10592   u8 *l4 = 0;
10593
10594   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10595     {
10596       if (unformat (input, "hex %U", unformat_hex_string, &match))
10597         ;
10598       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10599         ;
10600       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10601         ;
10602       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10603         ;
10604       else
10605         break;
10606     }
10607
10608   if (l4 && !l3)
10609     {
10610       vec_free (match);
10611       vec_free (l2);
10612       vec_free (l4);
10613       return 0;
10614     }
10615
10616   if (match || l2 || l3 || l4)
10617     {
10618       if (l2 || l3 || l4)
10619         {
10620           /* "Win a free Ethernet header in every packet" */
10621           if (l2 == 0)
10622             vec_validate_aligned (l2, 13, sizeof (u32x4));
10623           match = l2;
10624           if (vec_len (l3))
10625             {
10626               vec_append_aligned (match, l3, sizeof (u32x4));
10627               vec_free (l3);
10628             }
10629           if (vec_len (l4))
10630             {
10631               vec_append_aligned (match, l4, sizeof (u32x4));
10632               vec_free (l4);
10633             }
10634         }
10635
10636       /* Make sure the vector is big enough even if key is all 0's */
10637       vec_validate_aligned
10638         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
10639          sizeof (u32x4));
10640
10641       /* Set size, include skipped vectors */
10642       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
10643
10644       *matchp = match;
10645
10646       return 1;
10647     }
10648
10649   return 0;
10650 }
10651
10652 static int
10653 api_classify_add_del_session (vat_main_t * vam)
10654 {
10655   unformat_input_t *i = vam->input;
10656   vl_api_classify_add_del_session_t *mp;
10657   int is_add = 1;
10658   u32 table_index = ~0;
10659   u32 hit_next_index = ~0;
10660   u32 opaque_index = ~0;
10661   u8 *match = 0;
10662   i32 advance = 0;
10663   u32 skip_n_vectors = 0;
10664   u32 match_n_vectors = 0;
10665   u32 action = 0;
10666   u32 metadata = 0;
10667   int ret;
10668
10669   /*
10670    * Warning: you have to supply skip_n and match_n
10671    * because the API client cant simply look at the classify
10672    * table object.
10673    */
10674
10675   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10676     {
10677       if (unformat (i, "del"))
10678         is_add = 0;
10679       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
10680                          &hit_next_index))
10681         ;
10682       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10683                          &hit_next_index))
10684         ;
10685       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
10686                          &hit_next_index))
10687         ;
10688       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10689         ;
10690       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10691         ;
10692       else if (unformat (i, "opaque-index %d", &opaque_index))
10693         ;
10694       else if (unformat (i, "skip_n %d", &skip_n_vectors))
10695         ;
10696       else if (unformat (i, "match_n %d", &match_n_vectors))
10697         ;
10698       else if (unformat (i, "match %U", api_unformat_classify_match,
10699                          &match, skip_n_vectors, match_n_vectors))
10700         ;
10701       else if (unformat (i, "advance %d", &advance))
10702         ;
10703       else if (unformat (i, "table-index %d", &table_index))
10704         ;
10705       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10706         action = 1;
10707       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10708         action = 2;
10709       else if (unformat (i, "action %d", &action))
10710         ;
10711       else if (unformat (i, "metadata %d", &metadata))
10712         ;
10713       else
10714         break;
10715     }
10716
10717   if (table_index == ~0)
10718     {
10719       errmsg ("Table index required");
10720       return -99;
10721     }
10722
10723   if (is_add && match == 0)
10724     {
10725       errmsg ("Match value required");
10726       return -99;
10727     }
10728
10729   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10730
10731   mp->is_add = is_add;
10732   mp->table_index = ntohl (table_index);
10733   mp->hit_next_index = ntohl (hit_next_index);
10734   mp->opaque_index = ntohl (opaque_index);
10735   mp->advance = ntohl (advance);
10736   mp->action = action;
10737   mp->metadata = ntohl (metadata);
10738   mp->match_len = ntohl (vec_len (match));
10739   clib_memcpy (mp->match, match, vec_len (match));
10740   vec_free (match);
10741
10742   S (mp);
10743   W (ret);
10744   return ret;
10745 }
10746
10747 static int
10748 api_classify_set_interface_ip_table (vat_main_t * vam)
10749 {
10750   unformat_input_t *i = vam->input;
10751   vl_api_classify_set_interface_ip_table_t *mp;
10752   u32 sw_if_index;
10753   int sw_if_index_set;
10754   u32 table_index = ~0;
10755   u8 is_ipv6 = 0;
10756   int ret;
10757
10758   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10759     {
10760       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10761         sw_if_index_set = 1;
10762       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10763         sw_if_index_set = 1;
10764       else if (unformat (i, "table %d", &table_index))
10765         ;
10766       else
10767         {
10768           clib_warning ("parse error '%U'", format_unformat_error, i);
10769           return -99;
10770         }
10771     }
10772
10773   if (sw_if_index_set == 0)
10774     {
10775       errmsg ("missing interface name or sw_if_index");
10776       return -99;
10777     }
10778
10779
10780   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10781
10782   mp->sw_if_index = ntohl (sw_if_index);
10783   mp->table_index = ntohl (table_index);
10784   mp->is_ipv6 = is_ipv6;
10785
10786   S (mp);
10787   W (ret);
10788   return ret;
10789 }
10790
10791 static int
10792 api_classify_set_interface_l2_tables (vat_main_t * vam)
10793 {
10794   unformat_input_t *i = vam->input;
10795   vl_api_classify_set_interface_l2_tables_t *mp;
10796   u32 sw_if_index;
10797   int sw_if_index_set;
10798   u32 ip4_table_index = ~0;
10799   u32 ip6_table_index = ~0;
10800   u32 other_table_index = ~0;
10801   u32 is_input = 1;
10802   int ret;
10803
10804   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10805     {
10806       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10807         sw_if_index_set = 1;
10808       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10809         sw_if_index_set = 1;
10810       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10811         ;
10812       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10813         ;
10814       else if (unformat (i, "other-table %d", &other_table_index))
10815         ;
10816       else if (unformat (i, "is-input %d", &is_input))
10817         ;
10818       else
10819         {
10820           clib_warning ("parse error '%U'", format_unformat_error, i);
10821           return -99;
10822         }
10823     }
10824
10825   if (sw_if_index_set == 0)
10826     {
10827       errmsg ("missing interface name or sw_if_index");
10828       return -99;
10829     }
10830
10831
10832   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10833
10834   mp->sw_if_index = ntohl (sw_if_index);
10835   mp->ip4_table_index = ntohl (ip4_table_index);
10836   mp->ip6_table_index = ntohl (ip6_table_index);
10837   mp->other_table_index = ntohl (other_table_index);
10838   mp->is_input = (u8) is_input;
10839
10840   S (mp);
10841   W (ret);
10842   return ret;
10843 }
10844
10845 static int
10846 api_set_ipfix_exporter (vat_main_t * vam)
10847 {
10848   unformat_input_t *i = vam->input;
10849   vl_api_set_ipfix_exporter_t *mp;
10850   ip4_address_t collector_address;
10851   u8 collector_address_set = 0;
10852   u32 collector_port = ~0;
10853   ip4_address_t src_address;
10854   u8 src_address_set = 0;
10855   u32 vrf_id = ~0;
10856   u32 path_mtu = ~0;
10857   u32 template_interval = ~0;
10858   u8 udp_checksum = 0;
10859   int ret;
10860
10861   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10862     {
10863       if (unformat (i, "collector_address %U", unformat_ip4_address,
10864                     &collector_address))
10865         collector_address_set = 1;
10866       else if (unformat (i, "collector_port %d", &collector_port))
10867         ;
10868       else if (unformat (i, "src_address %U", unformat_ip4_address,
10869                          &src_address))
10870         src_address_set = 1;
10871       else if (unformat (i, "vrf_id %d", &vrf_id))
10872         ;
10873       else if (unformat (i, "path_mtu %d", &path_mtu))
10874         ;
10875       else if (unformat (i, "template_interval %d", &template_interval))
10876         ;
10877       else if (unformat (i, "udp_checksum"))
10878         udp_checksum = 1;
10879       else
10880         break;
10881     }
10882
10883   if (collector_address_set == 0)
10884     {
10885       errmsg ("collector_address required");
10886       return -99;
10887     }
10888
10889   if (src_address_set == 0)
10890     {
10891       errmsg ("src_address required");
10892       return -99;
10893     }
10894
10895   M (SET_IPFIX_EXPORTER, mp);
10896
10897   memcpy (mp->collector_address.un.ip4, collector_address.data,
10898           sizeof (collector_address.data));
10899   mp->collector_port = htons ((u16) collector_port);
10900   memcpy (mp->src_address.un.ip4, src_address.data,
10901           sizeof (src_address.data));
10902   mp->vrf_id = htonl (vrf_id);
10903   mp->path_mtu = htonl (path_mtu);
10904   mp->template_interval = htonl (template_interval);
10905   mp->udp_checksum = udp_checksum;
10906
10907   S (mp);
10908   W (ret);
10909   return ret;
10910 }
10911
10912 static int
10913 api_set_ipfix_classify_stream (vat_main_t * vam)
10914 {
10915   unformat_input_t *i = vam->input;
10916   vl_api_set_ipfix_classify_stream_t *mp;
10917   u32 domain_id = 0;
10918   u32 src_port = UDP_DST_PORT_ipfix;
10919   int ret;
10920
10921   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10922     {
10923       if (unformat (i, "domain %d", &domain_id))
10924         ;
10925       else if (unformat (i, "src_port %d", &src_port))
10926         ;
10927       else
10928         {
10929           errmsg ("unknown input `%U'", format_unformat_error, i);
10930           return -99;
10931         }
10932     }
10933
10934   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10935
10936   mp->domain_id = htonl (domain_id);
10937   mp->src_port = htons ((u16) src_port);
10938
10939   S (mp);
10940   W (ret);
10941   return ret;
10942 }
10943
10944 static int
10945 api_ipfix_classify_table_add_del (vat_main_t * vam)
10946 {
10947   unformat_input_t *i = vam->input;
10948   vl_api_ipfix_classify_table_add_del_t *mp;
10949   int is_add = -1;
10950   u32 classify_table_index = ~0;
10951   u8 ip_version = 0;
10952   u8 transport_protocol = 255;
10953   int ret;
10954
10955   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10956     {
10957       if (unformat (i, "add"))
10958         is_add = 1;
10959       else if (unformat (i, "del"))
10960         is_add = 0;
10961       else if (unformat (i, "table %d", &classify_table_index))
10962         ;
10963       else if (unformat (i, "ip4"))
10964         ip_version = 4;
10965       else if (unformat (i, "ip6"))
10966         ip_version = 6;
10967       else if (unformat (i, "tcp"))
10968         transport_protocol = 6;
10969       else if (unformat (i, "udp"))
10970         transport_protocol = 17;
10971       else
10972         {
10973           errmsg ("unknown input `%U'", format_unformat_error, i);
10974           return -99;
10975         }
10976     }
10977
10978   if (is_add == -1)
10979     {
10980       errmsg ("expecting: add|del");
10981       return -99;
10982     }
10983   if (classify_table_index == ~0)
10984     {
10985       errmsg ("classifier table not specified");
10986       return -99;
10987     }
10988   if (ip_version == 0)
10989     {
10990       errmsg ("IP version not specified");
10991       return -99;
10992     }
10993
10994   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10995
10996   mp->is_add = is_add;
10997   mp->table_id = htonl (classify_table_index);
10998   mp->ip_version = ip_version;
10999   mp->transport_protocol = transport_protocol;
11000
11001   S (mp);
11002   W (ret);
11003   return ret;
11004 }
11005
11006 static int
11007 api_get_node_index (vat_main_t * vam)
11008 {
11009   unformat_input_t *i = vam->input;
11010   vl_api_get_node_index_t *mp;
11011   u8 *name = 0;
11012   int ret;
11013
11014   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11015     {
11016       if (unformat (i, "node %s", &name))
11017         ;
11018       else
11019         break;
11020     }
11021   if (name == 0)
11022     {
11023       errmsg ("node name required");
11024       return -99;
11025     }
11026   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11027     {
11028       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11029       return -99;
11030     }
11031
11032   M (GET_NODE_INDEX, mp);
11033   clib_memcpy (mp->node_name, name, vec_len (name));
11034   vec_free (name);
11035
11036   S (mp);
11037   W (ret);
11038   return ret;
11039 }
11040
11041 static int
11042 api_get_next_index (vat_main_t * vam)
11043 {
11044   unformat_input_t *i = vam->input;
11045   vl_api_get_next_index_t *mp;
11046   u8 *node_name = 0, *next_node_name = 0;
11047   int ret;
11048
11049   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11050     {
11051       if (unformat (i, "node-name %s", &node_name))
11052         ;
11053       else if (unformat (i, "next-node-name %s", &next_node_name))
11054         break;
11055     }
11056
11057   if (node_name == 0)
11058     {
11059       errmsg ("node name required");
11060       return -99;
11061     }
11062   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11063     {
11064       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11065       return -99;
11066     }
11067
11068   if (next_node_name == 0)
11069     {
11070       errmsg ("next node name required");
11071       return -99;
11072     }
11073   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11074     {
11075       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11076       return -99;
11077     }
11078
11079   M (GET_NEXT_INDEX, mp);
11080   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11081   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11082   vec_free (node_name);
11083   vec_free (next_node_name);
11084
11085   S (mp);
11086   W (ret);
11087   return ret;
11088 }
11089
11090 static int
11091 api_add_node_next (vat_main_t * vam)
11092 {
11093   unformat_input_t *i = vam->input;
11094   vl_api_add_node_next_t *mp;
11095   u8 *name = 0;
11096   u8 *next = 0;
11097   int ret;
11098
11099   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11100     {
11101       if (unformat (i, "node %s", &name))
11102         ;
11103       else if (unformat (i, "next %s", &next))
11104         ;
11105       else
11106         break;
11107     }
11108   if (name == 0)
11109     {
11110       errmsg ("node name required");
11111       return -99;
11112     }
11113   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11114     {
11115       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11116       return -99;
11117     }
11118   if (next == 0)
11119     {
11120       errmsg ("next node required");
11121       return -99;
11122     }
11123   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11124     {
11125       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11126       return -99;
11127     }
11128
11129   M (ADD_NODE_NEXT, mp);
11130   clib_memcpy (mp->node_name, name, vec_len (name));
11131   clib_memcpy (mp->next_name, next, vec_len (next));
11132   vec_free (name);
11133   vec_free (next);
11134
11135   S (mp);
11136   W (ret);
11137   return ret;
11138 }
11139
11140 static int
11141 api_l2tpv3_create_tunnel (vat_main_t * vam)
11142 {
11143   unformat_input_t *i = vam->input;
11144   ip6_address_t client_address, our_address;
11145   int client_address_set = 0;
11146   int our_address_set = 0;
11147   u32 local_session_id = 0;
11148   u32 remote_session_id = 0;
11149   u64 local_cookie = 0;
11150   u64 remote_cookie = 0;
11151   u8 l2_sublayer_present = 0;
11152   vl_api_l2tpv3_create_tunnel_t *mp;
11153   int ret;
11154
11155   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11156     {
11157       if (unformat (i, "client_address %U", unformat_ip6_address,
11158                     &client_address))
11159         client_address_set = 1;
11160       else if (unformat (i, "our_address %U", unformat_ip6_address,
11161                          &our_address))
11162         our_address_set = 1;
11163       else if (unformat (i, "local_session_id %d", &local_session_id))
11164         ;
11165       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11166         ;
11167       else if (unformat (i, "local_cookie %lld", &local_cookie))
11168         ;
11169       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11170         ;
11171       else if (unformat (i, "l2-sublayer-present"))
11172         l2_sublayer_present = 1;
11173       else
11174         break;
11175     }
11176
11177   if (client_address_set == 0)
11178     {
11179       errmsg ("client_address required");
11180       return -99;
11181     }
11182
11183   if (our_address_set == 0)
11184     {
11185       errmsg ("our_address required");
11186       return -99;
11187     }
11188
11189   M (L2TPV3_CREATE_TUNNEL, mp);
11190
11191   clib_memcpy (mp->client_address.un.ip6, client_address.as_u8,
11192                sizeof (ip6_address_t));
11193
11194   clib_memcpy (mp->our_address.un.ip6, our_address.as_u8,
11195                sizeof (ip6_address_t));
11196
11197   mp->local_session_id = ntohl (local_session_id);
11198   mp->remote_session_id = ntohl (remote_session_id);
11199   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11200   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11201   mp->l2_sublayer_present = l2_sublayer_present;
11202
11203   S (mp);
11204   W (ret);
11205   return ret;
11206 }
11207
11208 static int
11209 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11210 {
11211   unformat_input_t *i = vam->input;
11212   u32 sw_if_index;
11213   u8 sw_if_index_set = 0;
11214   u64 new_local_cookie = 0;
11215   u64 new_remote_cookie = 0;
11216   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11217   int ret;
11218
11219   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11220     {
11221       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11222         sw_if_index_set = 1;
11223       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11224         sw_if_index_set = 1;
11225       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11226         ;
11227       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11228         ;
11229       else
11230         break;
11231     }
11232
11233   if (sw_if_index_set == 0)
11234     {
11235       errmsg ("missing interface name or sw_if_index");
11236       return -99;
11237     }
11238
11239   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11240
11241   mp->sw_if_index = ntohl (sw_if_index);
11242   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11243   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11244
11245   S (mp);
11246   W (ret);
11247   return ret;
11248 }
11249
11250 static int
11251 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11252 {
11253   unformat_input_t *i = vam->input;
11254   vl_api_l2tpv3_interface_enable_disable_t *mp;
11255   u32 sw_if_index;
11256   u8 sw_if_index_set = 0;
11257   u8 enable_disable = 1;
11258   int ret;
11259
11260   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11261     {
11262       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11263         sw_if_index_set = 1;
11264       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11265         sw_if_index_set = 1;
11266       else if (unformat (i, "enable"))
11267         enable_disable = 1;
11268       else if (unformat (i, "disable"))
11269         enable_disable = 0;
11270       else
11271         break;
11272     }
11273
11274   if (sw_if_index_set == 0)
11275     {
11276       errmsg ("missing interface name or sw_if_index");
11277       return -99;
11278     }
11279
11280   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11281
11282   mp->sw_if_index = ntohl (sw_if_index);
11283   mp->enable_disable = enable_disable;
11284
11285   S (mp);
11286   W (ret);
11287   return ret;
11288 }
11289
11290 static int
11291 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11292 {
11293   unformat_input_t *i = vam->input;
11294   vl_api_l2tpv3_set_lookup_key_t *mp;
11295   u8 key = ~0;
11296   int ret;
11297
11298   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11299     {
11300       if (unformat (i, "lookup_v6_src"))
11301         key = L2T_LOOKUP_SRC_ADDRESS;
11302       else if (unformat (i, "lookup_v6_dst"))
11303         key = L2T_LOOKUP_DST_ADDRESS;
11304       else if (unformat (i, "lookup_session_id"))
11305         key = L2T_LOOKUP_SESSION_ID;
11306       else
11307         break;
11308     }
11309
11310   if (key == (u8) ~ 0)
11311     {
11312       errmsg ("l2tp session lookup key unset");
11313       return -99;
11314     }
11315
11316   M (L2TPV3_SET_LOOKUP_KEY, mp);
11317
11318   mp->key = key;
11319
11320   S (mp);
11321   W (ret);
11322   return ret;
11323 }
11324
11325 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11326   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11327 {
11328   vat_main_t *vam = &vat_main;
11329
11330   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11331          format_ip6_address, mp->our_address,
11332          format_ip6_address, mp->client_address,
11333          clib_net_to_host_u32 (mp->sw_if_index));
11334
11335   print (vam->ofp,
11336          "   local cookies %016llx %016llx remote cookie %016llx",
11337          clib_net_to_host_u64 (mp->local_cookie[0]),
11338          clib_net_to_host_u64 (mp->local_cookie[1]),
11339          clib_net_to_host_u64 (mp->remote_cookie));
11340
11341   print (vam->ofp, "   local session-id %d remote session-id %d",
11342          clib_net_to_host_u32 (mp->local_session_id),
11343          clib_net_to_host_u32 (mp->remote_session_id));
11344
11345   print (vam->ofp, "   l2 specific sublayer %s\n",
11346          mp->l2_sublayer_present ? "preset" : "absent");
11347
11348 }
11349
11350 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11351   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11352 {
11353   vat_main_t *vam = &vat_main;
11354   vat_json_node_t *node = NULL;
11355   struct in6_addr addr;
11356
11357   if (VAT_JSON_ARRAY != vam->json_tree.type)
11358     {
11359       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11360       vat_json_init_array (&vam->json_tree);
11361     }
11362   node = vat_json_array_add (&vam->json_tree);
11363
11364   vat_json_init_object (node);
11365
11366   clib_memcpy (&addr, mp->our_address.un.ip6, sizeof (addr));
11367   vat_json_object_add_ip6 (node, "our_address", addr);
11368   clib_memcpy (&addr, mp->client_address.un.ip6, sizeof (addr));
11369   vat_json_object_add_ip6 (node, "client_address", addr);
11370
11371   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11372   vat_json_init_array (lc);
11373   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11374   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11375   vat_json_object_add_uint (node, "remote_cookie",
11376                             clib_net_to_host_u64 (mp->remote_cookie));
11377
11378   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11379   vat_json_object_add_uint (node, "local_session_id",
11380                             clib_net_to_host_u32 (mp->local_session_id));
11381   vat_json_object_add_uint (node, "remote_session_id",
11382                             clib_net_to_host_u32 (mp->remote_session_id));
11383   vat_json_object_add_string_copy (node, "l2_sublayer",
11384                                    mp->l2_sublayer_present ? (u8 *) "present"
11385                                    : (u8 *) "absent");
11386 }
11387
11388 static int
11389 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11390 {
11391   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11392   vl_api_control_ping_t *mp_ping;
11393   int ret;
11394
11395   /* Get list of l2tpv3-tunnel interfaces */
11396   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11397   S (mp);
11398
11399   /* Use a control ping for synchronization */
11400   MPING (CONTROL_PING, mp_ping);
11401   S (mp_ping);
11402
11403   W (ret);
11404   return ret;
11405 }
11406
11407
11408 static void vl_api_sw_interface_tap_v2_details_t_handler
11409   (vl_api_sw_interface_tap_v2_details_t * mp)
11410 {
11411   vat_main_t *vam = &vat_main;
11412
11413   u8 *ip4 =
11414     format (0, "%U/%d", format_ip4_address, mp->host_ip4_prefix.address,
11415             mp->host_ip4_prefix.len);
11416   u8 *ip6 =
11417     format (0, "%U/%d", format_ip6_address, mp->host_ip6_prefix.address,
11418             mp->host_ip6_prefix.len);
11419
11420   print (vam->ofp,
11421          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
11422          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
11423          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11424          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
11425          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
11426
11427   vec_free (ip4);
11428   vec_free (ip6);
11429 }
11430
11431 static void vl_api_sw_interface_tap_v2_details_t_handler_json
11432   (vl_api_sw_interface_tap_v2_details_t * mp)
11433 {
11434   vat_main_t *vam = &vat_main;
11435   vat_json_node_t *node = NULL;
11436
11437   if (VAT_JSON_ARRAY != vam->json_tree.type)
11438     {
11439       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11440       vat_json_init_array (&vam->json_tree);
11441     }
11442   node = vat_json_array_add (&vam->json_tree);
11443
11444   vat_json_init_object (node);
11445   vat_json_object_add_uint (node, "id", ntohl (mp->id));
11446   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11447   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
11448   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11449   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11450   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11451   vat_json_object_add_string_copy (node, "host_mac_addr",
11452                                    format (0, "%U", format_ethernet_address,
11453                                            &mp->host_mac_addr));
11454   vat_json_object_add_string_copy (node, "host_namespace",
11455                                    mp->host_namespace);
11456   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
11457   vat_json_object_add_string_copy (node, "host_ip4_addr",
11458                                    format (0, "%U/%d", format_ip4_address,
11459                                            mp->host_ip4_prefix.address,
11460                                            mp->host_ip4_prefix.len));
11461   vat_json_object_add_string_copy (node, "host_ip6_prefix",
11462                                    format (0, "%U/%d", format_ip6_address,
11463                                            mp->host_ip6_prefix.address,
11464                                            mp->host_ip6_prefix.len));
11465
11466 }
11467
11468 static int
11469 api_sw_interface_tap_v2_dump (vat_main_t * vam)
11470 {
11471   vl_api_sw_interface_tap_v2_dump_t *mp;
11472   vl_api_control_ping_t *mp_ping;
11473   int ret;
11474
11475   print (vam->ofp,
11476          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
11477          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
11478          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
11479          "host_ip6_addr");
11480
11481   /* Get list of tap interfaces */
11482   M (SW_INTERFACE_TAP_V2_DUMP, mp);
11483   S (mp);
11484
11485   /* Use a control ping for synchronization */
11486   MPING (CONTROL_PING, mp_ping);
11487   S (mp_ping);
11488
11489   W (ret);
11490   return ret;
11491 }
11492
11493 static void vl_api_sw_interface_virtio_pci_details_t_handler
11494   (vl_api_sw_interface_virtio_pci_details_t * mp)
11495 {
11496   vat_main_t *vam = &vat_main;
11497
11498   typedef union
11499   {
11500     struct
11501     {
11502       u16 domain;
11503       u8 bus;
11504       u8 slot:5;
11505       u8 function:3;
11506     };
11507     u32 as_u32;
11508   } pci_addr_t;
11509   pci_addr_t addr;
11510
11511   addr.domain = ntohs (mp->pci_addr.domain);
11512   addr.bus = mp->pci_addr.bus;
11513   addr.slot = mp->pci_addr.slot;
11514   addr.function = mp->pci_addr.function;
11515
11516   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
11517                          addr.slot, addr.function);
11518
11519   print (vam->ofp,
11520          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
11521          pci_addr, ntohl (mp->sw_if_index),
11522          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11523          format_ethernet_address, mp->mac_addr,
11524          clib_net_to_host_u64 (mp->features));
11525   vec_free (pci_addr);
11526 }
11527
11528 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
11529   (vl_api_sw_interface_virtio_pci_details_t * mp)
11530 {
11531   vat_main_t *vam = &vat_main;
11532   vat_json_node_t *node = NULL;
11533   vlib_pci_addr_t pci_addr;
11534
11535   if (VAT_JSON_ARRAY != vam->json_tree.type)
11536     {
11537       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11538       vat_json_init_array (&vam->json_tree);
11539     }
11540   node = vat_json_array_add (&vam->json_tree);
11541
11542   pci_addr.domain = ntohs (mp->pci_addr.domain);
11543   pci_addr.bus = mp->pci_addr.bus;
11544   pci_addr.slot = mp->pci_addr.slot;
11545   pci_addr.function = mp->pci_addr.function;
11546
11547   vat_json_init_object (node);
11548   vat_json_object_add_uint (node, "pci-addr", pci_addr.as_u32);
11549   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11550   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11551   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11552   vat_json_object_add_uint (node, "features",
11553                             clib_net_to_host_u64 (mp->features));
11554   vat_json_object_add_string_copy (node, "mac_addr",
11555                                    format (0, "%U", format_ethernet_address,
11556                                            &mp->mac_addr));
11557 }
11558
11559 static int
11560 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
11561 {
11562   vl_api_sw_interface_virtio_pci_dump_t *mp;
11563   vl_api_control_ping_t *mp_ping;
11564   int ret;
11565
11566   print (vam->ofp,
11567          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
11568          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
11569          "mac_addr", "features");
11570
11571   /* Get list of tap interfaces */
11572   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
11573   S (mp);
11574
11575   /* Use a control ping for synchronization */
11576   MPING (CONTROL_PING, mp_ping);
11577   S (mp_ping);
11578
11579   W (ret);
11580   return ret;
11581 }
11582
11583 static int
11584 api_vxlan_offload_rx (vat_main_t * vam)
11585 {
11586   unformat_input_t *line_input = vam->input;
11587   vl_api_vxlan_offload_rx_t *mp;
11588   u32 hw_if_index = ~0, rx_if_index = ~0;
11589   u8 is_add = 1;
11590   int ret;
11591
11592   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11593     {
11594       if (unformat (line_input, "del"))
11595         is_add = 0;
11596       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
11597                          &hw_if_index))
11598         ;
11599       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
11600         ;
11601       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
11602                          &rx_if_index))
11603         ;
11604       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
11605         ;
11606       else
11607         {
11608           errmsg ("parse error '%U'", format_unformat_error, line_input);
11609           return -99;
11610         }
11611     }
11612
11613   if (hw_if_index == ~0)
11614     {
11615       errmsg ("no hw interface");
11616       return -99;
11617     }
11618
11619   if (rx_if_index == ~0)
11620     {
11621       errmsg ("no rx tunnel");
11622       return -99;
11623     }
11624
11625   M (VXLAN_OFFLOAD_RX, mp);
11626
11627   mp->hw_if_index = ntohl (hw_if_index);
11628   mp->sw_if_index = ntohl (rx_if_index);
11629   mp->enable = is_add;
11630
11631   S (mp);
11632   W (ret);
11633   return ret;
11634 }
11635
11636 static uword unformat_vxlan_decap_next
11637   (unformat_input_t * input, va_list * args)
11638 {
11639   u32 *result = va_arg (*args, u32 *);
11640   u32 tmp;
11641
11642   if (unformat (input, "l2"))
11643     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11644   else if (unformat (input, "%d", &tmp))
11645     *result = tmp;
11646   else
11647     return 0;
11648   return 1;
11649 }
11650
11651 static int
11652 api_vxlan_add_del_tunnel (vat_main_t * vam)
11653 {
11654   unformat_input_t *line_input = vam->input;
11655   vl_api_vxlan_add_del_tunnel_t *mp;
11656   ip46_address_t src, dst;
11657   u8 is_add = 1;
11658   u8 ipv4_set = 0, ipv6_set = 0;
11659   u8 src_set = 0;
11660   u8 dst_set = 0;
11661   u8 grp_set = 0;
11662   u32 instance = ~0;
11663   u32 mcast_sw_if_index = ~0;
11664   u32 encap_vrf_id = 0;
11665   u32 decap_next_index = ~0;
11666   u32 vni = 0;
11667   int ret;
11668
11669   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11670   clib_memset (&src, 0, sizeof src);
11671   clib_memset (&dst, 0, sizeof dst);
11672
11673   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11674     {
11675       if (unformat (line_input, "del"))
11676         is_add = 0;
11677       else if (unformat (line_input, "instance %d", &instance))
11678         ;
11679       else
11680         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11681         {
11682           ipv4_set = 1;
11683           src_set = 1;
11684         }
11685       else
11686         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11687         {
11688           ipv4_set = 1;
11689           dst_set = 1;
11690         }
11691       else
11692         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11693         {
11694           ipv6_set = 1;
11695           src_set = 1;
11696         }
11697       else
11698         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11699         {
11700           ipv6_set = 1;
11701           dst_set = 1;
11702         }
11703       else if (unformat (line_input, "group %U %U",
11704                          unformat_ip4_address, &dst.ip4,
11705                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11706         {
11707           grp_set = dst_set = 1;
11708           ipv4_set = 1;
11709         }
11710       else if (unformat (line_input, "group %U",
11711                          unformat_ip4_address, &dst.ip4))
11712         {
11713           grp_set = dst_set = 1;
11714           ipv4_set = 1;
11715         }
11716       else if (unformat (line_input, "group %U %U",
11717                          unformat_ip6_address, &dst.ip6,
11718                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11719         {
11720           grp_set = dst_set = 1;
11721           ipv6_set = 1;
11722         }
11723       else if (unformat (line_input, "group %U",
11724                          unformat_ip6_address, &dst.ip6))
11725         {
11726           grp_set = dst_set = 1;
11727           ipv6_set = 1;
11728         }
11729       else
11730         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11731         ;
11732       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11733         ;
11734       else if (unformat (line_input, "decap-next %U",
11735                          unformat_vxlan_decap_next, &decap_next_index))
11736         ;
11737       else if (unformat (line_input, "vni %d", &vni))
11738         ;
11739       else
11740         {
11741           errmsg ("parse error '%U'", format_unformat_error, line_input);
11742           return -99;
11743         }
11744     }
11745
11746   if (src_set == 0)
11747     {
11748       errmsg ("tunnel src address not specified");
11749       return -99;
11750     }
11751   if (dst_set == 0)
11752     {
11753       errmsg ("tunnel dst address not specified");
11754       return -99;
11755     }
11756
11757   if (grp_set && !ip46_address_is_multicast (&dst))
11758     {
11759       errmsg ("tunnel group address not multicast");
11760       return -99;
11761     }
11762   if (grp_set && mcast_sw_if_index == ~0)
11763     {
11764       errmsg ("tunnel nonexistent multicast device");
11765       return -99;
11766     }
11767   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11768     {
11769       errmsg ("tunnel dst address must be unicast");
11770       return -99;
11771     }
11772
11773
11774   if (ipv4_set && ipv6_set)
11775     {
11776       errmsg ("both IPv4 and IPv6 addresses specified");
11777       return -99;
11778     }
11779
11780   if ((vni == 0) || (vni >> 24))
11781     {
11782       errmsg ("vni not specified or out of range");
11783       return -99;
11784     }
11785
11786   M (VXLAN_ADD_DEL_TUNNEL, mp);
11787
11788   if (ipv6_set)
11789     {
11790       clib_memcpy (mp->src_address.un.ip6, &src.ip6, sizeof (src.ip6));
11791       clib_memcpy (mp->dst_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
11792     }
11793   else
11794     {
11795       clib_memcpy (mp->src_address.un.ip4, &src.ip4, sizeof (src.ip4));
11796       clib_memcpy (mp->dst_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
11797     }
11798   mp->src_address.af = ipv6_set;
11799   mp->dst_address.af = ipv6_set;
11800
11801   mp->instance = htonl (instance);
11802   mp->encap_vrf_id = ntohl (encap_vrf_id);
11803   mp->decap_next_index = ntohl (decap_next_index);
11804   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11805   mp->vni = ntohl (vni);
11806   mp->is_add = is_add;
11807
11808   S (mp);
11809   W (ret);
11810   return ret;
11811 }
11812
11813 static void vl_api_vxlan_tunnel_details_t_handler
11814   (vl_api_vxlan_tunnel_details_t * mp)
11815 {
11816   vat_main_t *vam = &vat_main;
11817   ip46_address_t src =
11818     to_ip46 (mp->dst_address.af, (u8 *) & mp->dst_address.un);
11819   ip46_address_t dst =
11820     to_ip46 (mp->dst_address.af, (u8 *) & mp->src_address.un);
11821
11822   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
11823          ntohl (mp->sw_if_index),
11824          ntohl (mp->instance),
11825          format_ip46_address, &src, IP46_TYPE_ANY,
11826          format_ip46_address, &dst, IP46_TYPE_ANY,
11827          ntohl (mp->encap_vrf_id),
11828          ntohl (mp->decap_next_index), ntohl (mp->vni),
11829          ntohl (mp->mcast_sw_if_index));
11830 }
11831
11832 static void vl_api_vxlan_tunnel_details_t_handler_json
11833   (vl_api_vxlan_tunnel_details_t * mp)
11834 {
11835   vat_main_t *vam = &vat_main;
11836   vat_json_node_t *node = NULL;
11837
11838   if (VAT_JSON_ARRAY != vam->json_tree.type)
11839     {
11840       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11841       vat_json_init_array (&vam->json_tree);
11842     }
11843   node = vat_json_array_add (&vam->json_tree);
11844
11845   vat_json_init_object (node);
11846   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11847
11848   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
11849
11850   if (mp->src_address.af)
11851     {
11852       struct in6_addr ip6;
11853
11854       clib_memcpy (&ip6, mp->src_address.un.ip6, sizeof (ip6));
11855       vat_json_object_add_ip6 (node, "src_address", ip6);
11856       clib_memcpy (&ip6, mp->dst_address.un.ip6, sizeof (ip6));
11857       vat_json_object_add_ip6 (node, "dst_address", ip6);
11858     }
11859   else
11860     {
11861       struct in_addr ip4;
11862
11863       clib_memcpy (&ip4, mp->src_address.un.ip4, sizeof (ip4));
11864       vat_json_object_add_ip4 (node, "src_address", ip4);
11865       clib_memcpy (&ip4, mp->dst_address.un.ip4, sizeof (ip4));
11866       vat_json_object_add_ip4 (node, "dst_address", ip4);
11867     }
11868   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11869   vat_json_object_add_uint (node, "decap_next_index",
11870                             ntohl (mp->decap_next_index));
11871   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11872   vat_json_object_add_uint (node, "mcast_sw_if_index",
11873                             ntohl (mp->mcast_sw_if_index));
11874 }
11875
11876 static int
11877 api_vxlan_tunnel_dump (vat_main_t * vam)
11878 {
11879   unformat_input_t *i = vam->input;
11880   vl_api_vxlan_tunnel_dump_t *mp;
11881   vl_api_control_ping_t *mp_ping;
11882   u32 sw_if_index;
11883   u8 sw_if_index_set = 0;
11884   int ret;
11885
11886   /* Parse args required to build the message */
11887   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11888     {
11889       if (unformat (i, "sw_if_index %d", &sw_if_index))
11890         sw_if_index_set = 1;
11891       else
11892         break;
11893     }
11894
11895   if (sw_if_index_set == 0)
11896     {
11897       sw_if_index = ~0;
11898     }
11899
11900   if (!vam->json_output)
11901     {
11902       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
11903              "sw_if_index", "instance", "src_address", "dst_address",
11904              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
11905     }
11906
11907   /* Get list of vxlan-tunnel interfaces */
11908   M (VXLAN_TUNNEL_DUMP, mp);
11909
11910   mp->sw_if_index = htonl (sw_if_index);
11911
11912   S (mp);
11913
11914   /* Use a control ping for synchronization */
11915   MPING (CONTROL_PING, mp_ping);
11916   S (mp_ping);
11917
11918   W (ret);
11919   return ret;
11920 }
11921
11922 static uword unformat_geneve_decap_next
11923   (unformat_input_t * input, va_list * args)
11924 {
11925   u32 *result = va_arg (*args, u32 *);
11926   u32 tmp;
11927
11928   if (unformat (input, "l2"))
11929     *result = GENEVE_INPUT_NEXT_L2_INPUT;
11930   else if (unformat (input, "%d", &tmp))
11931     *result = tmp;
11932   else
11933     return 0;
11934   return 1;
11935 }
11936
11937 static int
11938 api_geneve_add_del_tunnel (vat_main_t * vam)
11939 {
11940   unformat_input_t *line_input = vam->input;
11941   vl_api_geneve_add_del_tunnel_t *mp;
11942   ip46_address_t src, dst;
11943   u8 is_add = 1;
11944   u8 ipv4_set = 0, ipv6_set = 0;
11945   u8 src_set = 0;
11946   u8 dst_set = 0;
11947   u8 grp_set = 0;
11948   u32 mcast_sw_if_index = ~0;
11949   u32 encap_vrf_id = 0;
11950   u32 decap_next_index = ~0;
11951   u32 vni = 0;
11952   int ret;
11953
11954   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11955   clib_memset (&src, 0, sizeof src);
11956   clib_memset (&dst, 0, sizeof dst);
11957
11958   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11959     {
11960       if (unformat (line_input, "del"))
11961         is_add = 0;
11962       else
11963         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11964         {
11965           ipv4_set = 1;
11966           src_set = 1;
11967         }
11968       else
11969         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11970         {
11971           ipv4_set = 1;
11972           dst_set = 1;
11973         }
11974       else
11975         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11976         {
11977           ipv6_set = 1;
11978           src_set = 1;
11979         }
11980       else
11981         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11982         {
11983           ipv6_set = 1;
11984           dst_set = 1;
11985         }
11986       else if (unformat (line_input, "group %U %U",
11987                          unformat_ip4_address, &dst.ip4,
11988                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11989         {
11990           grp_set = dst_set = 1;
11991           ipv4_set = 1;
11992         }
11993       else if (unformat (line_input, "group %U",
11994                          unformat_ip4_address, &dst.ip4))
11995         {
11996           grp_set = dst_set = 1;
11997           ipv4_set = 1;
11998         }
11999       else if (unformat (line_input, "group %U %U",
12000                          unformat_ip6_address, &dst.ip6,
12001                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12002         {
12003           grp_set = dst_set = 1;
12004           ipv6_set = 1;
12005         }
12006       else if (unformat (line_input, "group %U",
12007                          unformat_ip6_address, &dst.ip6))
12008         {
12009           grp_set = dst_set = 1;
12010           ipv6_set = 1;
12011         }
12012       else
12013         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12014         ;
12015       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12016         ;
12017       else if (unformat (line_input, "decap-next %U",
12018                          unformat_geneve_decap_next, &decap_next_index))
12019         ;
12020       else if (unformat (line_input, "vni %d", &vni))
12021         ;
12022       else
12023         {
12024           errmsg ("parse error '%U'", format_unformat_error, line_input);
12025           return -99;
12026         }
12027     }
12028
12029   if (src_set == 0)
12030     {
12031       errmsg ("tunnel src address not specified");
12032       return -99;
12033     }
12034   if (dst_set == 0)
12035     {
12036       errmsg ("tunnel dst address not specified");
12037       return -99;
12038     }
12039
12040   if (grp_set && !ip46_address_is_multicast (&dst))
12041     {
12042       errmsg ("tunnel group address not multicast");
12043       return -99;
12044     }
12045   if (grp_set && mcast_sw_if_index == ~0)
12046     {
12047       errmsg ("tunnel nonexistent multicast device");
12048       return -99;
12049     }
12050   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12051     {
12052       errmsg ("tunnel dst address must be unicast");
12053       return -99;
12054     }
12055
12056
12057   if (ipv4_set && ipv6_set)
12058     {
12059       errmsg ("both IPv4 and IPv6 addresses specified");
12060       return -99;
12061     }
12062
12063   if ((vni == 0) || (vni >> 24))
12064     {
12065       errmsg ("vni not specified or out of range");
12066       return -99;
12067     }
12068
12069   M (GENEVE_ADD_DEL_TUNNEL, mp);
12070
12071   if (ipv6_set)
12072     {
12073       clib_memcpy (&mp->local_address.un.ip6, &src.ip6, sizeof (src.ip6));
12074       clib_memcpy (&mp->remote_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
12075     }
12076   else
12077     {
12078       clib_memcpy (&mp->local_address.un.ip4, &src.ip4, sizeof (src.ip4));
12079       clib_memcpy (&mp->remote_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
12080     }
12081   mp->encap_vrf_id = ntohl (encap_vrf_id);
12082   mp->decap_next_index = ntohl (decap_next_index);
12083   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12084   mp->vni = ntohl (vni);
12085   mp->is_add = is_add;
12086
12087   S (mp);
12088   W (ret);
12089   return ret;
12090 }
12091
12092 static void vl_api_geneve_tunnel_details_t_handler
12093   (vl_api_geneve_tunnel_details_t * mp)
12094 {
12095   vat_main_t *vam = &vat_main;
12096   ip46_address_t src = {.as_u64[0] = 0,.as_u64[1] = 0 };
12097   ip46_address_t dst = {.as_u64[0] = 0,.as_u64[1] = 0 };
12098
12099   if (mp->src_address.af == ADDRESS_IP6)
12100     {
12101       clib_memcpy (&src.ip6, &mp->src_address.un.ip6, sizeof (ip6_address_t));
12102       clib_memcpy (&dst.ip6, &mp->dst_address.un.ip6, sizeof (ip6_address_t));
12103     }
12104   else
12105     {
12106       clib_memcpy (&src.ip4, &mp->src_address.un.ip4, sizeof (ip4_address_t));
12107       clib_memcpy (&dst.ip4, &mp->dst_address.un.ip4, sizeof (ip4_address_t));
12108     }
12109
12110   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12111          ntohl (mp->sw_if_index),
12112          format_ip46_address, &src, IP46_TYPE_ANY,
12113          format_ip46_address, &dst, IP46_TYPE_ANY,
12114          ntohl (mp->encap_vrf_id),
12115          ntohl (mp->decap_next_index), ntohl (mp->vni),
12116          ntohl (mp->mcast_sw_if_index));
12117 }
12118
12119 static void vl_api_geneve_tunnel_details_t_handler_json
12120   (vl_api_geneve_tunnel_details_t * mp)
12121 {
12122   vat_main_t *vam = &vat_main;
12123   vat_json_node_t *node = NULL;
12124   bool is_ipv6;
12125
12126   if (VAT_JSON_ARRAY != vam->json_tree.type)
12127     {
12128       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12129       vat_json_init_array (&vam->json_tree);
12130     }
12131   node = vat_json_array_add (&vam->json_tree);
12132
12133   vat_json_init_object (node);
12134   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12135   is_ipv6 = mp->src_address.af == ADDRESS_IP6;
12136   if (is_ipv6)
12137     {
12138       struct in6_addr ip6;
12139
12140       clib_memcpy (&ip6, &mp->src_address.un.ip6, sizeof (ip6));
12141       vat_json_object_add_ip6 (node, "src_address", ip6);
12142       clib_memcpy (&ip6, &mp->dst_address.un.ip6, sizeof (ip6));
12143       vat_json_object_add_ip6 (node, "dst_address", ip6);
12144     }
12145   else
12146     {
12147       struct in_addr ip4;
12148
12149       clib_memcpy (&ip4, &mp->src_address.un.ip4, sizeof (ip4));
12150       vat_json_object_add_ip4 (node, "src_address", ip4);
12151       clib_memcpy (&ip4, &mp->dst_address.un.ip4, sizeof (ip4));
12152       vat_json_object_add_ip4 (node, "dst_address", ip4);
12153     }
12154   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12155   vat_json_object_add_uint (node, "decap_next_index",
12156                             ntohl (mp->decap_next_index));
12157   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12158   vat_json_object_add_uint (node, "mcast_sw_if_index",
12159                             ntohl (mp->mcast_sw_if_index));
12160 }
12161
12162 static int
12163 api_geneve_tunnel_dump (vat_main_t * vam)
12164 {
12165   unformat_input_t *i = vam->input;
12166   vl_api_geneve_tunnel_dump_t *mp;
12167   vl_api_control_ping_t *mp_ping;
12168   u32 sw_if_index;
12169   u8 sw_if_index_set = 0;
12170   int ret;
12171
12172   /* Parse args required to build the message */
12173   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12174     {
12175       if (unformat (i, "sw_if_index %d", &sw_if_index))
12176         sw_if_index_set = 1;
12177       else
12178         break;
12179     }
12180
12181   if (sw_if_index_set == 0)
12182     {
12183       sw_if_index = ~0;
12184     }
12185
12186   if (!vam->json_output)
12187     {
12188       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12189              "sw_if_index", "local_address", "remote_address",
12190              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12191     }
12192
12193   /* Get list of geneve-tunnel interfaces */
12194   M (GENEVE_TUNNEL_DUMP, mp);
12195
12196   mp->sw_if_index = htonl (sw_if_index);
12197
12198   S (mp);
12199
12200   /* Use a control ping for synchronization */
12201   M (CONTROL_PING, mp_ping);
12202   S (mp_ping);
12203
12204   W (ret);
12205   return ret;
12206 }
12207
12208 static int
12209 api_gre_tunnel_add_del (vat_main_t * vam)
12210 {
12211   unformat_input_t *line_input = vam->input;
12212   vl_api_address_t src = { }, dst =
12213   {
12214   };
12215   vl_api_gre_tunnel_add_del_t *mp;
12216   vl_api_gre_tunnel_type_t t_type;
12217   u8 is_add = 1;
12218   u8 src_set = 0;
12219   u8 dst_set = 0;
12220   u32 outer_table_id = 0;
12221   u32 session_id = 0;
12222   u32 instance = ~0;
12223   int ret;
12224
12225   t_type = GRE_API_TUNNEL_TYPE_L3;
12226
12227   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12228     {
12229       if (unformat (line_input, "del"))
12230         is_add = 0;
12231       else if (unformat (line_input, "instance %d", &instance))
12232         ;
12233       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
12234         {
12235           src_set = 1;
12236         }
12237       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
12238         {
12239           dst_set = 1;
12240         }
12241       else if (unformat (line_input, "outer-table-id %d", &outer_table_id))
12242         ;
12243       else if (unformat (line_input, "teb"))
12244         t_type = GRE_API_TUNNEL_TYPE_TEB;
12245       else if (unformat (line_input, "erspan %d", &session_id))
12246         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
12247       else
12248         {
12249           errmsg ("parse error '%U'", format_unformat_error, line_input);
12250           return -99;
12251         }
12252     }
12253
12254   if (src_set == 0)
12255     {
12256       errmsg ("tunnel src address not specified");
12257       return -99;
12258     }
12259   if (dst_set == 0)
12260     {
12261       errmsg ("tunnel dst address not specified");
12262       return -99;
12263     }
12264
12265   M (GRE_TUNNEL_ADD_DEL, mp);
12266
12267   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
12268   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
12269
12270   mp->tunnel.instance = htonl (instance);
12271   mp->tunnel.outer_table_id = htonl (outer_table_id);
12272   mp->is_add = is_add;
12273   mp->tunnel.session_id = htons ((u16) session_id);
12274   mp->tunnel.type = htonl (t_type);
12275
12276   S (mp);
12277   W (ret);
12278   return ret;
12279 }
12280
12281 static void vl_api_gre_tunnel_details_t_handler
12282   (vl_api_gre_tunnel_details_t * mp)
12283 {
12284   vat_main_t *vam = &vat_main;
12285
12286   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
12287          ntohl (mp->tunnel.sw_if_index),
12288          ntohl (mp->tunnel.instance),
12289          format_vl_api_address, &mp->tunnel.src,
12290          format_vl_api_address, &mp->tunnel.dst,
12291          mp->tunnel.type, ntohl (mp->tunnel.outer_table_id),
12292          ntohl (mp->tunnel.session_id));
12293 }
12294
12295 static void vl_api_gre_tunnel_details_t_handler_json
12296   (vl_api_gre_tunnel_details_t * mp)
12297 {
12298   vat_main_t *vam = &vat_main;
12299   vat_json_node_t *node = NULL;
12300
12301   if (VAT_JSON_ARRAY != vam->json_tree.type)
12302     {
12303       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12304       vat_json_init_array (&vam->json_tree);
12305     }
12306   node = vat_json_array_add (&vam->json_tree);
12307
12308   vat_json_init_object (node);
12309   vat_json_object_add_uint (node, "sw_if_index",
12310                             ntohl (mp->tunnel.sw_if_index));
12311   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
12312
12313   vat_json_object_add_address (node, "src", &mp->tunnel.src);
12314   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
12315   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
12316   vat_json_object_add_uint (node, "outer_table_id",
12317                             ntohl (mp->tunnel.outer_table_id));
12318   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
12319 }
12320
12321 static int
12322 api_gre_tunnel_dump (vat_main_t * vam)
12323 {
12324   unformat_input_t *i = vam->input;
12325   vl_api_gre_tunnel_dump_t *mp;
12326   vl_api_control_ping_t *mp_ping;
12327   u32 sw_if_index;
12328   u8 sw_if_index_set = 0;
12329   int ret;
12330
12331   /* Parse args required to build the message */
12332   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12333     {
12334       if (unformat (i, "sw_if_index %d", &sw_if_index))
12335         sw_if_index_set = 1;
12336       else
12337         break;
12338     }
12339
12340   if (sw_if_index_set == 0)
12341     {
12342       sw_if_index = ~0;
12343     }
12344
12345   if (!vam->json_output)
12346     {
12347       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
12348              "sw_if_index", "instance", "src_address", "dst_address",
12349              "tunnel_type", "outer_fib_id", "session_id");
12350     }
12351
12352   /* Get list of gre-tunnel interfaces */
12353   M (GRE_TUNNEL_DUMP, mp);
12354
12355   mp->sw_if_index = htonl (sw_if_index);
12356
12357   S (mp);
12358
12359   /* Use a control ping for synchronization */
12360   MPING (CONTROL_PING, mp_ping);
12361   S (mp_ping);
12362
12363   W (ret);
12364   return ret;
12365 }
12366
12367 static int
12368 api_l2_fib_clear_table (vat_main_t * vam)
12369 {
12370 //  unformat_input_t * i = vam->input;
12371   vl_api_l2_fib_clear_table_t *mp;
12372   int ret;
12373
12374   M (L2_FIB_CLEAR_TABLE, mp);
12375
12376   S (mp);
12377   W (ret);
12378   return ret;
12379 }
12380
12381 static int
12382 api_l2_interface_efp_filter (vat_main_t * vam)
12383 {
12384   unformat_input_t *i = vam->input;
12385   vl_api_l2_interface_efp_filter_t *mp;
12386   u32 sw_if_index;
12387   u8 enable = 1;
12388   u8 sw_if_index_set = 0;
12389   int ret;
12390
12391   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12392     {
12393       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12394         sw_if_index_set = 1;
12395       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12396         sw_if_index_set = 1;
12397       else if (unformat (i, "enable"))
12398         enable = 1;
12399       else if (unformat (i, "disable"))
12400         enable = 0;
12401       else
12402         {
12403           clib_warning ("parse error '%U'", format_unformat_error, i);
12404           return -99;
12405         }
12406     }
12407
12408   if (sw_if_index_set == 0)
12409     {
12410       errmsg ("missing sw_if_index");
12411       return -99;
12412     }
12413
12414   M (L2_INTERFACE_EFP_FILTER, mp);
12415
12416   mp->sw_if_index = ntohl (sw_if_index);
12417   mp->enable_disable = enable;
12418
12419   S (mp);
12420   W (ret);
12421   return ret;
12422 }
12423
12424 #define foreach_vtr_op                          \
12425 _("disable",  L2_VTR_DISABLED)                  \
12426 _("push-1",  L2_VTR_PUSH_1)                     \
12427 _("push-2",  L2_VTR_PUSH_2)                     \
12428 _("pop-1",  L2_VTR_POP_1)                       \
12429 _("pop-2",  L2_VTR_POP_2)                       \
12430 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12431 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12432 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12433 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12434
12435 static int
12436 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12437 {
12438   unformat_input_t *i = vam->input;
12439   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12440   u32 sw_if_index;
12441   u8 sw_if_index_set = 0;
12442   u8 vtr_op_set = 0;
12443   u32 vtr_op = 0;
12444   u32 push_dot1q = 1;
12445   u32 tag1 = ~0;
12446   u32 tag2 = ~0;
12447   int ret;
12448
12449   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12450     {
12451       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12452         sw_if_index_set = 1;
12453       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12454         sw_if_index_set = 1;
12455       else if (unformat (i, "vtr_op %d", &vtr_op))
12456         vtr_op_set = 1;
12457 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12458       foreach_vtr_op
12459 #undef _
12460         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12461         ;
12462       else if (unformat (i, "tag1 %d", &tag1))
12463         ;
12464       else if (unformat (i, "tag2 %d", &tag2))
12465         ;
12466       else
12467         {
12468           clib_warning ("parse error '%U'", format_unformat_error, i);
12469           return -99;
12470         }
12471     }
12472
12473   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12474     {
12475       errmsg ("missing vtr operation or sw_if_index");
12476       return -99;
12477     }
12478
12479   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12480   mp->sw_if_index = ntohl (sw_if_index);
12481   mp->vtr_op = ntohl (vtr_op);
12482   mp->push_dot1q = ntohl (push_dot1q);
12483   mp->tag1 = ntohl (tag1);
12484   mp->tag2 = ntohl (tag2);
12485
12486   S (mp);
12487   W (ret);
12488   return ret;
12489 }
12490
12491 static int
12492 api_create_vhost_user_if (vat_main_t * vam)
12493 {
12494   unformat_input_t *i = vam->input;
12495   vl_api_create_vhost_user_if_t *mp;
12496   u8 *file_name;
12497   u8 is_server = 0;
12498   u8 file_name_set = 0;
12499   u32 custom_dev_instance = ~0;
12500   u8 hwaddr[6];
12501   u8 use_custom_mac = 0;
12502   u8 disable_mrg_rxbuf = 0;
12503   u8 disable_indirect_desc = 0;
12504   u8 *tag = 0;
12505   u8 enable_gso = 0;
12506   u8 enable_packed = 0;
12507   int ret;
12508
12509   /* Shut up coverity */
12510   clib_memset (hwaddr, 0, sizeof (hwaddr));
12511
12512   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12513     {
12514       if (unformat (i, "socket %s", &file_name))
12515         {
12516           file_name_set = 1;
12517         }
12518       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12519         ;
12520       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12521         use_custom_mac = 1;
12522       else if (unformat (i, "server"))
12523         is_server = 1;
12524       else if (unformat (i, "disable_mrg_rxbuf"))
12525         disable_mrg_rxbuf = 1;
12526       else if (unformat (i, "disable_indirect_desc"))
12527         disable_indirect_desc = 1;
12528       else if (unformat (i, "gso"))
12529         enable_gso = 1;
12530       else if (unformat (i, "packed"))
12531         enable_packed = 1;
12532       else if (unformat (i, "tag %s", &tag))
12533         ;
12534       else
12535         break;
12536     }
12537
12538   if (file_name_set == 0)
12539     {
12540       errmsg ("missing socket file name");
12541       return -99;
12542     }
12543
12544   if (vec_len (file_name) > 255)
12545     {
12546       errmsg ("socket file name too long");
12547       return -99;
12548     }
12549   vec_add1 (file_name, 0);
12550
12551   M (CREATE_VHOST_USER_IF, mp);
12552
12553   mp->is_server = is_server;
12554   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
12555   mp->disable_indirect_desc = disable_indirect_desc;
12556   mp->enable_gso = enable_gso;
12557   mp->enable_packed = enable_packed;
12558   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12559   vec_free (file_name);
12560   if (custom_dev_instance != ~0)
12561     {
12562       mp->renumber = 1;
12563       mp->custom_dev_instance = ntohl (custom_dev_instance);
12564     }
12565
12566   mp->use_custom_mac = use_custom_mac;
12567   clib_memcpy (mp->mac_address, hwaddr, 6);
12568   if (tag)
12569     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
12570   vec_free (tag);
12571
12572   S (mp);
12573   W (ret);
12574   return ret;
12575 }
12576
12577 static int
12578 api_modify_vhost_user_if (vat_main_t * vam)
12579 {
12580   unformat_input_t *i = vam->input;
12581   vl_api_modify_vhost_user_if_t *mp;
12582   u8 *file_name;
12583   u8 is_server = 0;
12584   u8 file_name_set = 0;
12585   u32 custom_dev_instance = ~0;
12586   u8 sw_if_index_set = 0;
12587   u32 sw_if_index = (u32) ~ 0;
12588   u8 enable_gso = 0;
12589   u8 enable_packed = 0;
12590   int ret;
12591
12592   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12593     {
12594       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12595         sw_if_index_set = 1;
12596       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12597         sw_if_index_set = 1;
12598       else if (unformat (i, "socket %s", &file_name))
12599         {
12600           file_name_set = 1;
12601         }
12602       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12603         ;
12604       else if (unformat (i, "server"))
12605         is_server = 1;
12606       else if (unformat (i, "gso"))
12607         enable_gso = 1;
12608       else if (unformat (i, "packed"))
12609         enable_packed = 1;
12610       else
12611         break;
12612     }
12613
12614   if (sw_if_index_set == 0)
12615     {
12616       errmsg ("missing sw_if_index or interface name");
12617       return -99;
12618     }
12619
12620   if (file_name_set == 0)
12621     {
12622       errmsg ("missing socket file name");
12623       return -99;
12624     }
12625
12626   if (vec_len (file_name) > 255)
12627     {
12628       errmsg ("socket file name too long");
12629       return -99;
12630     }
12631   vec_add1 (file_name, 0);
12632
12633   M (MODIFY_VHOST_USER_IF, mp);
12634
12635   mp->sw_if_index = ntohl (sw_if_index);
12636   mp->is_server = is_server;
12637   mp->enable_gso = enable_gso;
12638   mp->enable_packed = enable_packed;
12639   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12640   vec_free (file_name);
12641   if (custom_dev_instance != ~0)
12642     {
12643       mp->renumber = 1;
12644       mp->custom_dev_instance = ntohl (custom_dev_instance);
12645     }
12646
12647   S (mp);
12648   W (ret);
12649   return ret;
12650 }
12651
12652 static int
12653 api_delete_vhost_user_if (vat_main_t * vam)
12654 {
12655   unformat_input_t *i = vam->input;
12656   vl_api_delete_vhost_user_if_t *mp;
12657   u32 sw_if_index = ~0;
12658   u8 sw_if_index_set = 0;
12659   int ret;
12660
12661   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12662     {
12663       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12664         sw_if_index_set = 1;
12665       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12666         sw_if_index_set = 1;
12667       else
12668         break;
12669     }
12670
12671   if (sw_if_index_set == 0)
12672     {
12673       errmsg ("missing sw_if_index or interface name");
12674       return -99;
12675     }
12676
12677
12678   M (DELETE_VHOST_USER_IF, mp);
12679
12680   mp->sw_if_index = ntohl (sw_if_index);
12681
12682   S (mp);
12683   W (ret);
12684   return ret;
12685 }
12686
12687 static void vl_api_sw_interface_vhost_user_details_t_handler
12688   (vl_api_sw_interface_vhost_user_details_t * mp)
12689 {
12690   vat_main_t *vam = &vat_main;
12691   u64 features;
12692
12693   features =
12694     clib_net_to_host_u32 (mp->features_first_32) | ((u64)
12695                                                     clib_net_to_host_u32
12696                                                     (mp->features_last_32) <<
12697                                                     32);
12698
12699   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
12700          (char *) mp->interface_name,
12701          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
12702          features, mp->is_server,
12703          ntohl (mp->num_regions), (char *) mp->sock_filename);
12704   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
12705 }
12706
12707 static void vl_api_sw_interface_vhost_user_details_t_handler_json
12708   (vl_api_sw_interface_vhost_user_details_t * mp)
12709 {
12710   vat_main_t *vam = &vat_main;
12711   vat_json_node_t *node = NULL;
12712
12713   if (VAT_JSON_ARRAY != vam->json_tree.type)
12714     {
12715       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12716       vat_json_init_array (&vam->json_tree);
12717     }
12718   node = vat_json_array_add (&vam->json_tree);
12719
12720   vat_json_init_object (node);
12721   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12722   vat_json_object_add_string_copy (node, "interface_name",
12723                                    mp->interface_name);
12724   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
12725                             ntohl (mp->virtio_net_hdr_sz));
12726   vat_json_object_add_uint (node, "features_first_32",
12727                             clib_net_to_host_u32 (mp->features_first_32));
12728   vat_json_object_add_uint (node, "features_last_32",
12729                             clib_net_to_host_u32 (mp->features_last_32));
12730   vat_json_object_add_uint (node, "is_server", mp->is_server);
12731   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
12732   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
12733   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
12734 }
12735
12736 static int
12737 api_sw_interface_vhost_user_dump (vat_main_t * vam)
12738 {
12739   unformat_input_t *i = vam->input;
12740   vl_api_sw_interface_vhost_user_dump_t *mp;
12741   vl_api_control_ping_t *mp_ping;
12742   int ret;
12743   u32 sw_if_index = ~0;
12744
12745   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12746     {
12747       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12748         ;
12749       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12750         ;
12751       else
12752         break;
12753     }
12754
12755   print (vam->ofp,
12756          "Interface name            idx hdr_sz features server regions filename");
12757
12758   /* Get list of vhost-user interfaces */
12759   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
12760   mp->sw_if_index = ntohl (sw_if_index);
12761   S (mp);
12762
12763   /* Use a control ping for synchronization */
12764   MPING (CONTROL_PING, mp_ping);
12765   S (mp_ping);
12766
12767   W (ret);
12768   return ret;
12769 }
12770
12771 static int
12772 api_show_version (vat_main_t * vam)
12773 {
12774   vl_api_show_version_t *mp;
12775   int ret;
12776
12777   M (SHOW_VERSION, mp);
12778
12779   S (mp);
12780   W (ret);
12781   return ret;
12782 }
12783
12784
12785 static int
12786 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
12787 {
12788   unformat_input_t *line_input = vam->input;
12789   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
12790   ip46_address_t local, remote;
12791   u8 is_add = 1;
12792   u8 local_set = 0;
12793   u8 remote_set = 0;
12794   u8 grp_set = 0;
12795   u32 mcast_sw_if_index = ~0;
12796   u32 encap_vrf_id = 0;
12797   u32 decap_vrf_id = 0;
12798   u8 protocol = ~0;
12799   u32 vni;
12800   u8 vni_set = 0;
12801   int ret;
12802
12803   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12804     {
12805       if (unformat (line_input, "del"))
12806         is_add = 0;
12807       else if (unformat (line_input, "local %U",
12808                          unformat_ip46_address, &local))
12809         {
12810           local_set = 1;
12811         }
12812       else if (unformat (line_input, "remote %U",
12813                          unformat_ip46_address, &remote))
12814         {
12815           remote_set = 1;
12816         }
12817       else if (unformat (line_input, "group %U %U",
12818                          unformat_ip46_address, &remote,
12819                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12820         {
12821           grp_set = remote_set = 1;
12822         }
12823       else if (unformat (line_input, "group %U",
12824                          unformat_ip46_address, &remote))
12825         {
12826           grp_set = remote_set = 1;
12827         }
12828       else
12829         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12830         ;
12831       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12832         ;
12833       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
12834         ;
12835       else if (unformat (line_input, "vni %d", &vni))
12836         vni_set = 1;
12837       else if (unformat (line_input, "next-ip4"))
12838         protocol = 1;
12839       else if (unformat (line_input, "next-ip6"))
12840         protocol = 2;
12841       else if (unformat (line_input, "next-ethernet"))
12842         protocol = 3;
12843       else if (unformat (line_input, "next-nsh"))
12844         protocol = 4;
12845       else
12846         {
12847           errmsg ("parse error '%U'", format_unformat_error, line_input);
12848           return -99;
12849         }
12850     }
12851
12852   if (local_set == 0)
12853     {
12854       errmsg ("tunnel local address not specified");
12855       return -99;
12856     }
12857   if (remote_set == 0)
12858     {
12859       errmsg ("tunnel remote address not specified");
12860       return -99;
12861     }
12862   if (grp_set && mcast_sw_if_index == ~0)
12863     {
12864       errmsg ("tunnel nonexistent multicast device");
12865       return -99;
12866     }
12867   if (ip46_address_is_ip4 (&local) != ip46_address_is_ip4 (&remote))
12868     {
12869       errmsg ("both IPv4 and IPv6 addresses specified");
12870       return -99;
12871     }
12872
12873   if (vni_set == 0)
12874     {
12875       errmsg ("vni not specified");
12876       return -99;
12877     }
12878
12879   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
12880
12881   ip_address_encode (&local,
12882                      ip46_address_is_ip4 (&local) ? IP46_TYPE_IP4 :
12883                      IP46_TYPE_IP6, &mp->local);
12884   ip_address_encode (&remote,
12885                      ip46_address_is_ip4 (&remote) ? IP46_TYPE_IP4 :
12886                      IP46_TYPE_IP6, &mp->remote);
12887
12888   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12889   mp->encap_vrf_id = ntohl (encap_vrf_id);
12890   mp->decap_vrf_id = ntohl (decap_vrf_id);
12891   mp->protocol = protocol;
12892   mp->vni = ntohl (vni);
12893   mp->is_add = is_add;
12894
12895   S (mp);
12896   W (ret);
12897   return ret;
12898 }
12899
12900 static void vl_api_vxlan_gpe_tunnel_details_t_handler
12901   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12902 {
12903   vat_main_t *vam = &vat_main;
12904   ip46_address_t local, remote;
12905
12906   ip_address_decode (&mp->local, &local);
12907   ip_address_decode (&mp->remote, &remote);
12908
12909   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
12910          ntohl (mp->sw_if_index),
12911          format_ip46_address, &local, IP46_TYPE_ANY,
12912          format_ip46_address, &remote, IP46_TYPE_ANY,
12913          ntohl (mp->vni), mp->protocol,
12914          ntohl (mp->mcast_sw_if_index),
12915          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
12916 }
12917
12918
12919 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
12920   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12921 {
12922   vat_main_t *vam = &vat_main;
12923   vat_json_node_t *node = NULL;
12924   struct in_addr ip4;
12925   struct in6_addr ip6;
12926   ip46_address_t local, remote;
12927
12928   ip_address_decode (&mp->local, &local);
12929   ip_address_decode (&mp->remote, &remote);
12930
12931   if (VAT_JSON_ARRAY != vam->json_tree.type)
12932     {
12933       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12934       vat_json_init_array (&vam->json_tree);
12935     }
12936   node = vat_json_array_add (&vam->json_tree);
12937
12938   vat_json_init_object (node);
12939   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12940   if (ip46_address_is_ip4 (&local))
12941     {
12942       clib_memcpy (&ip4, &local.ip4, sizeof (ip4));
12943       vat_json_object_add_ip4 (node, "local", ip4);
12944       clib_memcpy (&ip4, &remote.ip4, sizeof (ip4));
12945       vat_json_object_add_ip4 (node, "remote", ip4);
12946     }
12947   else
12948     {
12949       clib_memcpy (&ip6, &local.ip6, sizeof (ip6));
12950       vat_json_object_add_ip6 (node, "local", ip6);
12951       clib_memcpy (&ip6, &remote.ip6, sizeof (ip6));
12952       vat_json_object_add_ip6 (node, "remote", ip6);
12953     }
12954   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12955   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
12956   vat_json_object_add_uint (node, "mcast_sw_if_index",
12957                             ntohl (mp->mcast_sw_if_index));
12958   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12959   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
12960   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12961 }
12962
12963 static int
12964 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
12965 {
12966   unformat_input_t *i = vam->input;
12967   vl_api_vxlan_gpe_tunnel_dump_t *mp;
12968   vl_api_control_ping_t *mp_ping;
12969   u32 sw_if_index;
12970   u8 sw_if_index_set = 0;
12971   int ret;
12972
12973   /* Parse args required to build the message */
12974   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12975     {
12976       if (unformat (i, "sw_if_index %d", &sw_if_index))
12977         sw_if_index_set = 1;
12978       else
12979         break;
12980     }
12981
12982   if (sw_if_index_set == 0)
12983     {
12984       sw_if_index = ~0;
12985     }
12986
12987   if (!vam->json_output)
12988     {
12989       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
12990              "sw_if_index", "local", "remote", "vni",
12991              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
12992     }
12993
12994   /* Get list of vxlan-tunnel interfaces */
12995   M (VXLAN_GPE_TUNNEL_DUMP, mp);
12996
12997   mp->sw_if_index = htonl (sw_if_index);
12998
12999   S (mp);
13000
13001   /* Use a control ping for synchronization */
13002   MPING (CONTROL_PING, mp_ping);
13003   S (mp_ping);
13004
13005   W (ret);
13006   return ret;
13007 }
13008
13009 static void vl_api_l2_fib_table_details_t_handler
13010   (vl_api_l2_fib_table_details_t * mp)
13011 {
13012   vat_main_t *vam = &vat_main;
13013
13014   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13015          "       %d       %d     %d",
13016          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
13017          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13018          mp->bvi_mac);
13019 }
13020
13021 static void vl_api_l2_fib_table_details_t_handler_json
13022   (vl_api_l2_fib_table_details_t * mp)
13023 {
13024   vat_main_t *vam = &vat_main;
13025   vat_json_node_t *node = NULL;
13026
13027   if (VAT_JSON_ARRAY != vam->json_tree.type)
13028     {
13029       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13030       vat_json_init_array (&vam->json_tree);
13031     }
13032   node = vat_json_array_add (&vam->json_tree);
13033
13034   vat_json_init_object (node);
13035   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13036   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
13037   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13038   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13039   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13040   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13041 }
13042
13043 static int
13044 api_l2_fib_table_dump (vat_main_t * vam)
13045 {
13046   unformat_input_t *i = vam->input;
13047   vl_api_l2_fib_table_dump_t *mp;
13048   vl_api_control_ping_t *mp_ping;
13049   u32 bd_id;
13050   u8 bd_id_set = 0;
13051   int ret;
13052
13053   /* Parse args required to build the message */
13054   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13055     {
13056       if (unformat (i, "bd_id %d", &bd_id))
13057         bd_id_set = 1;
13058       else
13059         break;
13060     }
13061
13062   if (bd_id_set == 0)
13063     {
13064       errmsg ("missing bridge domain");
13065       return -99;
13066     }
13067
13068   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13069
13070   /* Get list of l2 fib entries */
13071   M (L2_FIB_TABLE_DUMP, mp);
13072
13073   mp->bd_id = ntohl (bd_id);
13074   S (mp);
13075
13076   /* Use a control ping for synchronization */
13077   MPING (CONTROL_PING, mp_ping);
13078   S (mp_ping);
13079
13080   W (ret);
13081   return ret;
13082 }
13083
13084
13085 static int
13086 api_interface_name_renumber (vat_main_t * vam)
13087 {
13088   unformat_input_t *line_input = vam->input;
13089   vl_api_interface_name_renumber_t *mp;
13090   u32 sw_if_index = ~0;
13091   u32 new_show_dev_instance = ~0;
13092   int ret;
13093
13094   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13095     {
13096       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13097                     &sw_if_index))
13098         ;
13099       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13100         ;
13101       else if (unformat (line_input, "new_show_dev_instance %d",
13102                          &new_show_dev_instance))
13103         ;
13104       else
13105         break;
13106     }
13107
13108   if (sw_if_index == ~0)
13109     {
13110       errmsg ("missing interface name or sw_if_index");
13111       return -99;
13112     }
13113
13114   if (new_show_dev_instance == ~0)
13115     {
13116       errmsg ("missing new_show_dev_instance");
13117       return -99;
13118     }
13119
13120   M (INTERFACE_NAME_RENUMBER, mp);
13121
13122   mp->sw_if_index = ntohl (sw_if_index);
13123   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13124
13125   S (mp);
13126   W (ret);
13127   return ret;
13128 }
13129
13130 static int
13131 api_want_l2_macs_events (vat_main_t * vam)
13132 {
13133   unformat_input_t *line_input = vam->input;
13134   vl_api_want_l2_macs_events_t *mp;
13135   u8 enable_disable = 1;
13136   u32 scan_delay = 0;
13137   u32 max_macs_in_event = 0;
13138   u32 learn_limit = 0;
13139   int ret;
13140
13141   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13142     {
13143       if (unformat (line_input, "learn-limit %d", &learn_limit))
13144         ;
13145       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13146         ;
13147       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13148         ;
13149       else if (unformat (line_input, "disable"))
13150         enable_disable = 0;
13151       else
13152         break;
13153     }
13154
13155   M (WANT_L2_MACS_EVENTS, mp);
13156   mp->enable_disable = enable_disable;
13157   mp->pid = htonl (getpid ());
13158   mp->learn_limit = htonl (learn_limit);
13159   mp->scan_delay = (u8) scan_delay;
13160   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13161   S (mp);
13162   W (ret);
13163   return ret;
13164 }
13165
13166 static int
13167 api_input_acl_set_interface (vat_main_t * vam)
13168 {
13169   unformat_input_t *i = vam->input;
13170   vl_api_input_acl_set_interface_t *mp;
13171   u32 sw_if_index;
13172   int sw_if_index_set;
13173   u32 ip4_table_index = ~0;
13174   u32 ip6_table_index = ~0;
13175   u32 l2_table_index = ~0;
13176   u8 is_add = 1;
13177   int ret;
13178
13179   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13180     {
13181       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13182         sw_if_index_set = 1;
13183       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13184         sw_if_index_set = 1;
13185       else if (unformat (i, "del"))
13186         is_add = 0;
13187       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13188         ;
13189       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13190         ;
13191       else if (unformat (i, "l2-table %d", &l2_table_index))
13192         ;
13193       else
13194         {
13195           clib_warning ("parse error '%U'", format_unformat_error, i);
13196           return -99;
13197         }
13198     }
13199
13200   if (sw_if_index_set == 0)
13201     {
13202       errmsg ("missing interface name or sw_if_index");
13203       return -99;
13204     }
13205
13206   M (INPUT_ACL_SET_INTERFACE, mp);
13207
13208   mp->sw_if_index = ntohl (sw_if_index);
13209   mp->ip4_table_index = ntohl (ip4_table_index);
13210   mp->ip6_table_index = ntohl (ip6_table_index);
13211   mp->l2_table_index = ntohl (l2_table_index);
13212   mp->is_add = is_add;
13213
13214   S (mp);
13215   W (ret);
13216   return ret;
13217 }
13218
13219 static int
13220 api_output_acl_set_interface (vat_main_t * vam)
13221 {
13222   unformat_input_t *i = vam->input;
13223   vl_api_output_acl_set_interface_t *mp;
13224   u32 sw_if_index;
13225   int sw_if_index_set;
13226   u32 ip4_table_index = ~0;
13227   u32 ip6_table_index = ~0;
13228   u32 l2_table_index = ~0;
13229   u8 is_add = 1;
13230   int ret;
13231
13232   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13233     {
13234       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13235         sw_if_index_set = 1;
13236       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13237         sw_if_index_set = 1;
13238       else if (unformat (i, "del"))
13239         is_add = 0;
13240       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13241         ;
13242       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13243         ;
13244       else if (unformat (i, "l2-table %d", &l2_table_index))
13245         ;
13246       else
13247         {
13248           clib_warning ("parse error '%U'", format_unformat_error, i);
13249           return -99;
13250         }
13251     }
13252
13253   if (sw_if_index_set == 0)
13254     {
13255       errmsg ("missing interface name or sw_if_index");
13256       return -99;
13257     }
13258
13259   M (OUTPUT_ACL_SET_INTERFACE, mp);
13260
13261   mp->sw_if_index = ntohl (sw_if_index);
13262   mp->ip4_table_index = ntohl (ip4_table_index);
13263   mp->ip6_table_index = ntohl (ip6_table_index);
13264   mp->l2_table_index = ntohl (l2_table_index);
13265   mp->is_add = is_add;
13266
13267   S (mp);
13268   W (ret);
13269   return ret;
13270 }
13271
13272 static int
13273 api_ip_address_dump (vat_main_t * vam)
13274 {
13275   unformat_input_t *i = vam->input;
13276   vl_api_ip_address_dump_t *mp;
13277   vl_api_control_ping_t *mp_ping;
13278   u32 sw_if_index = ~0;
13279   u8 sw_if_index_set = 0;
13280   u8 ipv4_set = 0;
13281   u8 ipv6_set = 0;
13282   int ret;
13283
13284   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13285     {
13286       if (unformat (i, "sw_if_index %d", &sw_if_index))
13287         sw_if_index_set = 1;
13288       else
13289         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13290         sw_if_index_set = 1;
13291       else if (unformat (i, "ipv4"))
13292         ipv4_set = 1;
13293       else if (unformat (i, "ipv6"))
13294         ipv6_set = 1;
13295       else
13296         break;
13297     }
13298
13299   if (ipv4_set && ipv6_set)
13300     {
13301       errmsg ("ipv4 and ipv6 flags cannot be both set");
13302       return -99;
13303     }
13304
13305   if ((!ipv4_set) && (!ipv6_set))
13306     {
13307       errmsg ("no ipv4 nor ipv6 flag set");
13308       return -99;
13309     }
13310
13311   if (sw_if_index_set == 0)
13312     {
13313       errmsg ("missing interface name or sw_if_index");
13314       return -99;
13315     }
13316
13317   vam->current_sw_if_index = sw_if_index;
13318   vam->is_ipv6 = ipv6_set;
13319
13320   M (IP_ADDRESS_DUMP, mp);
13321   mp->sw_if_index = ntohl (sw_if_index);
13322   mp->is_ipv6 = ipv6_set;
13323   S (mp);
13324
13325   /* Use a control ping for synchronization */
13326   MPING (CONTROL_PING, mp_ping);
13327   S (mp_ping);
13328
13329   W (ret);
13330   return ret;
13331 }
13332
13333 static int
13334 api_ip_dump (vat_main_t * vam)
13335 {
13336   vl_api_ip_dump_t *mp;
13337   vl_api_control_ping_t *mp_ping;
13338   unformat_input_t *in = vam->input;
13339   int ipv4_set = 0;
13340   int ipv6_set = 0;
13341   int is_ipv6;
13342   int i;
13343   int ret;
13344
13345   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13346     {
13347       if (unformat (in, "ipv4"))
13348         ipv4_set = 1;
13349       else if (unformat (in, "ipv6"))
13350         ipv6_set = 1;
13351       else
13352         break;
13353     }
13354
13355   if (ipv4_set && ipv6_set)
13356     {
13357       errmsg ("ipv4 and ipv6 flags cannot be both set");
13358       return -99;
13359     }
13360
13361   if ((!ipv4_set) && (!ipv6_set))
13362     {
13363       errmsg ("no ipv4 nor ipv6 flag set");
13364       return -99;
13365     }
13366
13367   is_ipv6 = ipv6_set;
13368   vam->is_ipv6 = is_ipv6;
13369
13370   /* free old data */
13371   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13372     {
13373       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13374     }
13375   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13376
13377   M (IP_DUMP, mp);
13378   mp->is_ipv6 = ipv6_set;
13379   S (mp);
13380
13381   /* Use a control ping for synchronization */
13382   MPING (CONTROL_PING, mp_ping);
13383   S (mp_ping);
13384
13385   W (ret);
13386   return ret;
13387 }
13388
13389 static int
13390 api_ipsec_spd_add_del (vat_main_t * vam)
13391 {
13392   unformat_input_t *i = vam->input;
13393   vl_api_ipsec_spd_add_del_t *mp;
13394   u32 spd_id = ~0;
13395   u8 is_add = 1;
13396   int ret;
13397
13398   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13399     {
13400       if (unformat (i, "spd_id %d", &spd_id))
13401         ;
13402       else if (unformat (i, "del"))
13403         is_add = 0;
13404       else
13405         {
13406           clib_warning ("parse error '%U'", format_unformat_error, i);
13407           return -99;
13408         }
13409     }
13410   if (spd_id == ~0)
13411     {
13412       errmsg ("spd_id must be set");
13413       return -99;
13414     }
13415
13416   M (IPSEC_SPD_ADD_DEL, mp);
13417
13418   mp->spd_id = ntohl (spd_id);
13419   mp->is_add = is_add;
13420
13421   S (mp);
13422   W (ret);
13423   return ret;
13424 }
13425
13426 static int
13427 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13428 {
13429   unformat_input_t *i = vam->input;
13430   vl_api_ipsec_interface_add_del_spd_t *mp;
13431   u32 sw_if_index;
13432   u8 sw_if_index_set = 0;
13433   u32 spd_id = (u32) ~ 0;
13434   u8 is_add = 1;
13435   int ret;
13436
13437   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13438     {
13439       if (unformat (i, "del"))
13440         is_add = 0;
13441       else if (unformat (i, "spd_id %d", &spd_id))
13442         ;
13443       else
13444         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13445         sw_if_index_set = 1;
13446       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13447         sw_if_index_set = 1;
13448       else
13449         {
13450           clib_warning ("parse error '%U'", format_unformat_error, i);
13451           return -99;
13452         }
13453
13454     }
13455
13456   if (spd_id == (u32) ~ 0)
13457     {
13458       errmsg ("spd_id must be set");
13459       return -99;
13460     }
13461
13462   if (sw_if_index_set == 0)
13463     {
13464       errmsg ("missing interface name or sw_if_index");
13465       return -99;
13466     }
13467
13468   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
13469
13470   mp->spd_id = ntohl (spd_id);
13471   mp->sw_if_index = ntohl (sw_if_index);
13472   mp->is_add = is_add;
13473
13474   S (mp);
13475   W (ret);
13476   return ret;
13477 }
13478
13479 static int
13480 api_ipsec_spd_entry_add_del (vat_main_t * vam)
13481 {
13482   unformat_input_t *i = vam->input;
13483   vl_api_ipsec_spd_entry_add_del_t *mp;
13484   u8 is_add = 1, is_outbound = 0;
13485   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
13486   i32 priority = 0;
13487   u32 rport_start = 0, rport_stop = (u32) ~ 0;
13488   u32 lport_start = 0, lport_stop = (u32) ~ 0;
13489   vl_api_address_t laddr_start = { }, laddr_stop =
13490   {
13491   }, raddr_start =
13492   {
13493   }, raddr_stop =
13494   {
13495   };
13496   int ret;
13497
13498   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13499     {
13500       if (unformat (i, "del"))
13501         is_add = 0;
13502       if (unformat (i, "outbound"))
13503         is_outbound = 1;
13504       if (unformat (i, "inbound"))
13505         is_outbound = 0;
13506       else if (unformat (i, "spd_id %d", &spd_id))
13507         ;
13508       else if (unformat (i, "sa_id %d", &sa_id))
13509         ;
13510       else if (unformat (i, "priority %d", &priority))
13511         ;
13512       else if (unformat (i, "protocol %d", &protocol))
13513         ;
13514       else if (unformat (i, "lport_start %d", &lport_start))
13515         ;
13516       else if (unformat (i, "lport_stop %d", &lport_stop))
13517         ;
13518       else if (unformat (i, "rport_start %d", &rport_start))
13519         ;
13520       else if (unformat (i, "rport_stop %d", &rport_stop))
13521         ;
13522       else if (unformat (i, "laddr_start %U",
13523                          unformat_vl_api_address, &laddr_start))
13524         ;
13525       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
13526                          &laddr_stop))
13527         ;
13528       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
13529                          &raddr_start))
13530         ;
13531       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
13532                          &raddr_stop))
13533         ;
13534       else
13535         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
13536         {
13537           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
13538             {
13539               clib_warning ("unsupported action: 'resolve'");
13540               return -99;
13541             }
13542         }
13543       else
13544         {
13545           clib_warning ("parse error '%U'", format_unformat_error, i);
13546           return -99;
13547         }
13548
13549     }
13550
13551   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
13552
13553   mp->is_add = is_add;
13554
13555   mp->entry.spd_id = ntohl (spd_id);
13556   mp->entry.priority = ntohl (priority);
13557   mp->entry.is_outbound = is_outbound;
13558
13559   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
13560                sizeof (vl_api_address_t));
13561   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
13562                sizeof (vl_api_address_t));
13563   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
13564                sizeof (vl_api_address_t));
13565   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
13566                sizeof (vl_api_address_t));
13567
13568   mp->entry.protocol = (u8) protocol;
13569   mp->entry.local_port_start = ntohs ((u16) lport_start);
13570   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
13571   mp->entry.remote_port_start = ntohs ((u16) rport_start);
13572   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
13573   mp->entry.policy = (u8) policy;
13574   mp->entry.sa_id = ntohl (sa_id);
13575
13576   S (mp);
13577   W (ret);
13578   return ret;
13579 }
13580
13581 static int
13582 api_ipsec_sad_entry_add_del (vat_main_t * vam)
13583 {
13584   unformat_input_t *i = vam->input;
13585   vl_api_ipsec_sad_entry_add_del_t *mp;
13586   u32 sad_id = 0, spi = 0;
13587   u8 *ck = 0, *ik = 0;
13588   u8 is_add = 1;
13589
13590   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
13591   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
13592   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
13593   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
13594   vl_api_address_t tun_src, tun_dst;
13595   int ret;
13596
13597   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13598     {
13599       if (unformat (i, "del"))
13600         is_add = 0;
13601       else if (unformat (i, "sad_id %d", &sad_id))
13602         ;
13603       else if (unformat (i, "spi %d", &spi))
13604         ;
13605       else if (unformat (i, "esp"))
13606         protocol = IPSEC_API_PROTO_ESP;
13607       else
13608         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
13609         {
13610           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13611           if (ADDRESS_IP6 == tun_src.af)
13612             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13613         }
13614       else
13615         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
13616         {
13617           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13618           if (ADDRESS_IP6 == tun_src.af)
13619             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13620         }
13621       else
13622         if (unformat (i, "crypto_alg %U",
13623                       unformat_ipsec_api_crypto_alg, &crypto_alg))
13624         ;
13625       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13626         ;
13627       else if (unformat (i, "integ_alg %U",
13628                          unformat_ipsec_api_integ_alg, &integ_alg))
13629         ;
13630       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13631         ;
13632       else
13633         {
13634           clib_warning ("parse error '%U'", format_unformat_error, i);
13635           return -99;
13636         }
13637
13638     }
13639
13640   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
13641
13642   mp->is_add = is_add;
13643   mp->entry.sad_id = ntohl (sad_id);
13644   mp->entry.protocol = protocol;
13645   mp->entry.spi = ntohl (spi);
13646   mp->entry.flags = flags;
13647
13648   mp->entry.crypto_algorithm = crypto_alg;
13649   mp->entry.integrity_algorithm = integ_alg;
13650   mp->entry.crypto_key.length = vec_len (ck);
13651   mp->entry.integrity_key.length = vec_len (ik);
13652
13653   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
13654     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
13655
13656   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
13657     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
13658
13659   if (ck)
13660     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
13661   if (ik)
13662     clib_memcpy (mp->entry.integrity_key.data, ik,
13663                  mp->entry.integrity_key.length);
13664
13665   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
13666     {
13667       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
13668                    sizeof (mp->entry.tunnel_src));
13669       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
13670                    sizeof (mp->entry.tunnel_dst));
13671     }
13672
13673   S (mp);
13674   W (ret);
13675   return ret;
13676 }
13677
13678 static int
13679 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
13680 {
13681   unformat_input_t *i = vam->input;
13682   vl_api_ipsec_tunnel_if_add_del_t *mp;
13683   u32 local_spi = 0, remote_spi = 0;
13684   u32 crypto_alg = 0, integ_alg = 0;
13685   u8 *lck = NULL, *rck = NULL;
13686   u8 *lik = NULL, *rik = NULL;
13687   vl_api_address_t local_ip = { 0 };
13688   vl_api_address_t remote_ip = { 0 };
13689   f64 before = 0;
13690   u8 is_add = 1;
13691   u8 esn = 0;
13692   u8 anti_replay = 0;
13693   u8 renumber = 0;
13694   u32 instance = ~0;
13695   u32 count = 1, jj;
13696   int ret = -1;
13697
13698   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13699     {
13700       if (unformat (i, "del"))
13701         is_add = 0;
13702       else if (unformat (i, "esn"))
13703         esn = 1;
13704       else if (unformat (i, "anti-replay"))
13705         anti_replay = 1;
13706       else if (unformat (i, "count %d", &count))
13707         ;
13708       else if (unformat (i, "local_spi %d", &local_spi))
13709         ;
13710       else if (unformat (i, "remote_spi %d", &remote_spi))
13711         ;
13712       else
13713         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
13714         ;
13715       else
13716         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
13717         ;
13718       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
13719         ;
13720       else
13721         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
13722         ;
13723       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
13724         ;
13725       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
13726         ;
13727       else
13728         if (unformat
13729             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
13730         {
13731           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
13732             {
13733               errmsg ("unsupported crypto-alg: '%U'\n",
13734                       format_ipsec_crypto_alg, crypto_alg);
13735               return -99;
13736             }
13737         }
13738       else
13739         if (unformat
13740             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
13741         {
13742           if (integ_alg >= IPSEC_INTEG_N_ALG)
13743             {
13744               errmsg ("unsupported integ-alg: '%U'\n",
13745                       format_ipsec_integ_alg, integ_alg);
13746               return -99;
13747             }
13748         }
13749       else if (unformat (i, "instance %u", &instance))
13750         renumber = 1;
13751       else
13752         {
13753           errmsg ("parse error '%U'\n", format_unformat_error, i);
13754           return -99;
13755         }
13756     }
13757
13758   if (count > 1)
13759     {
13760       /* Turn on async mode */
13761       vam->async_mode = 1;
13762       vam->async_errors = 0;
13763       before = vat_time_now (vam);
13764     }
13765
13766   for (jj = 0; jj < count; jj++)
13767     {
13768       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
13769
13770       mp->is_add = is_add;
13771       mp->esn = esn;
13772       mp->anti_replay = anti_replay;
13773
13774       if (jj > 0)
13775         increment_address (&remote_ip);
13776
13777       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
13778       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
13779
13780       mp->local_spi = htonl (local_spi + jj);
13781       mp->remote_spi = htonl (remote_spi + jj);
13782       mp->crypto_alg = (u8) crypto_alg;
13783
13784       mp->local_crypto_key_len = 0;
13785       if (lck)
13786         {
13787           mp->local_crypto_key_len = vec_len (lck);
13788           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
13789             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
13790           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
13791         }
13792
13793       mp->remote_crypto_key_len = 0;
13794       if (rck)
13795         {
13796           mp->remote_crypto_key_len = vec_len (rck);
13797           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
13798             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
13799           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
13800         }
13801
13802       mp->integ_alg = (u8) integ_alg;
13803
13804       mp->local_integ_key_len = 0;
13805       if (lik)
13806         {
13807           mp->local_integ_key_len = vec_len (lik);
13808           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
13809             mp->local_integ_key_len = sizeof (mp->local_integ_key);
13810           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
13811         }
13812
13813       mp->remote_integ_key_len = 0;
13814       if (rik)
13815         {
13816           mp->remote_integ_key_len = vec_len (rik);
13817           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
13818             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
13819           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
13820         }
13821
13822       if (renumber)
13823         {
13824           mp->renumber = renumber;
13825           mp->show_instance = ntohl (instance);
13826         }
13827       S (mp);
13828     }
13829
13830   /* When testing multiple add/del ops, use a control-ping to sync */
13831   if (count > 1)
13832     {
13833       vl_api_control_ping_t *mp_ping;
13834       f64 after;
13835       f64 timeout;
13836
13837       /* Shut off async mode */
13838       vam->async_mode = 0;
13839
13840       MPING (CONTROL_PING, mp_ping);
13841       S (mp_ping);
13842
13843       timeout = vat_time_now (vam) + 1.0;
13844       while (vat_time_now (vam) < timeout)
13845         if (vam->result_ready == 1)
13846           goto out;
13847       vam->retval = -99;
13848
13849     out:
13850       if (vam->retval == -99)
13851         errmsg ("timeout");
13852
13853       if (vam->async_errors > 0)
13854         {
13855           errmsg ("%d asynchronous errors", vam->async_errors);
13856           vam->retval = -98;
13857         }
13858       vam->async_errors = 0;
13859       after = vat_time_now (vam);
13860
13861       /* slim chance, but we might have eaten SIGTERM on the first iteration */
13862       if (jj > 0)
13863         count = jj;
13864
13865       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
13866              count, after - before, count / (after - before));
13867     }
13868   else
13869     {
13870       /* Wait for a reply... */
13871       W (ret);
13872       return ret;
13873     }
13874
13875   return ret;
13876 }
13877
13878 static void
13879 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
13880 {
13881   vat_main_t *vam = &vat_main;
13882
13883   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
13884          "crypto_key %U integ_alg %u integ_key %U flags %x "
13885          "tunnel_src_addr %U tunnel_dst_addr %U "
13886          "salt %u seq_outbound %lu last_seq_inbound %lu "
13887          "replay_window %lu stat_index %u\n",
13888          ntohl (mp->entry.sad_id),
13889          ntohl (mp->sw_if_index),
13890          ntohl (mp->entry.spi),
13891          ntohl (mp->entry.protocol),
13892          ntohl (mp->entry.crypto_algorithm),
13893          format_hex_bytes, mp->entry.crypto_key.data,
13894          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
13895          format_hex_bytes, mp->entry.integrity_key.data,
13896          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
13897          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
13898          &mp->entry.tunnel_dst, ntohl (mp->salt),
13899          clib_net_to_host_u64 (mp->seq_outbound),
13900          clib_net_to_host_u64 (mp->last_seq_inbound),
13901          clib_net_to_host_u64 (mp->replay_window), ntohl (mp->stat_index));
13902 }
13903
13904 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
13905 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
13906
13907 static void vl_api_ipsec_sa_details_t_handler_json
13908   (vl_api_ipsec_sa_details_t * mp)
13909 {
13910   vat_main_t *vam = &vat_main;
13911   vat_json_node_t *node = NULL;
13912   vl_api_ipsec_sad_flags_t flags;
13913
13914   if (VAT_JSON_ARRAY != vam->json_tree.type)
13915     {
13916       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13917       vat_json_init_array (&vam->json_tree);
13918     }
13919   node = vat_json_array_add (&vam->json_tree);
13920
13921   vat_json_init_object (node);
13922   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
13923   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13924   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
13925   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
13926   vat_json_object_add_uint (node, "crypto_alg",
13927                             ntohl (mp->entry.crypto_algorithm));
13928   vat_json_object_add_uint (node, "integ_alg",
13929                             ntohl (mp->entry.integrity_algorithm));
13930   flags = ntohl (mp->entry.flags);
13931   vat_json_object_add_uint (node, "use_esn",
13932                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
13933   vat_json_object_add_uint (node, "use_anti_replay",
13934                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
13935   vat_json_object_add_uint (node, "is_tunnel",
13936                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
13937   vat_json_object_add_uint (node, "is_tunnel_ip6",
13938                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
13939   vat_json_object_add_uint (node, "udp_encap",
13940                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
13941   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
13942                              mp->entry.crypto_key.length);
13943   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
13944                              mp->entry.integrity_key.length);
13945   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
13946   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
13947   vat_json_object_add_uint (node, "replay_window",
13948                             clib_net_to_host_u64 (mp->replay_window));
13949   vat_json_object_add_uint (node, "stat_index", ntohl (mp->stat_index));
13950 }
13951
13952 static int
13953 api_ipsec_sa_dump (vat_main_t * vam)
13954 {
13955   unformat_input_t *i = vam->input;
13956   vl_api_ipsec_sa_dump_t *mp;
13957   vl_api_control_ping_t *mp_ping;
13958   u32 sa_id = ~0;
13959   int ret;
13960
13961   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13962     {
13963       if (unformat (i, "sa_id %d", &sa_id))
13964         ;
13965       else
13966         {
13967           clib_warning ("parse error '%U'", format_unformat_error, i);
13968           return -99;
13969         }
13970     }
13971
13972   M (IPSEC_SA_DUMP, mp);
13973
13974   mp->sa_id = ntohl (sa_id);
13975
13976   S (mp);
13977
13978   /* Use a control ping for synchronization */
13979   M (CONTROL_PING, mp_ping);
13980   S (mp_ping);
13981
13982   W (ret);
13983   return ret;
13984 }
13985
13986 static int
13987 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
13988 {
13989   unformat_input_t *i = vam->input;
13990   vl_api_ipsec_tunnel_if_set_sa_t *mp;
13991   u32 sw_if_index = ~0;
13992   u32 sa_id = ~0;
13993   u8 is_outbound = (u8) ~ 0;
13994   int ret;
13995
13996   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13997     {
13998       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13999         ;
14000       else if (unformat (i, "sa_id %d", &sa_id))
14001         ;
14002       else if (unformat (i, "outbound"))
14003         is_outbound = 1;
14004       else if (unformat (i, "inbound"))
14005         is_outbound = 0;
14006       else
14007         {
14008           clib_warning ("parse error '%U'", format_unformat_error, i);
14009           return -99;
14010         }
14011     }
14012
14013   if (sw_if_index == ~0)
14014     {
14015       errmsg ("interface must be specified");
14016       return -99;
14017     }
14018
14019   if (sa_id == ~0)
14020     {
14021       errmsg ("SA ID must be specified");
14022       return -99;
14023     }
14024
14025   M (IPSEC_TUNNEL_IF_SET_SA, mp);
14026
14027   mp->sw_if_index = htonl (sw_if_index);
14028   mp->sa_id = htonl (sa_id);
14029   mp->is_outbound = is_outbound;
14030
14031   S (mp);
14032   W (ret);
14033
14034   return ret;
14035 }
14036
14037 static int
14038 api_get_first_msg_id (vat_main_t * vam)
14039 {
14040   vl_api_get_first_msg_id_t *mp;
14041   unformat_input_t *i = vam->input;
14042   u8 *name;
14043   u8 name_set = 0;
14044   int ret;
14045
14046   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14047     {
14048       if (unformat (i, "client %s", &name))
14049         name_set = 1;
14050       else
14051         break;
14052     }
14053
14054   if (name_set == 0)
14055     {
14056       errmsg ("missing client name");
14057       return -99;
14058     }
14059   vec_add1 (name, 0);
14060
14061   if (vec_len (name) > 63)
14062     {
14063       errmsg ("client name too long");
14064       return -99;
14065     }
14066
14067   M (GET_FIRST_MSG_ID, mp);
14068   clib_memcpy (mp->name, name, vec_len (name));
14069   S (mp);
14070   W (ret);
14071   return ret;
14072 }
14073
14074 static int
14075 api_cop_interface_enable_disable (vat_main_t * vam)
14076 {
14077   unformat_input_t *line_input = vam->input;
14078   vl_api_cop_interface_enable_disable_t *mp;
14079   u32 sw_if_index = ~0;
14080   u8 enable_disable = 1;
14081   int ret;
14082
14083   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14084     {
14085       if (unformat (line_input, "disable"))
14086         enable_disable = 0;
14087       if (unformat (line_input, "enable"))
14088         enable_disable = 1;
14089       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14090                          vam, &sw_if_index))
14091         ;
14092       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14093         ;
14094       else
14095         break;
14096     }
14097
14098   if (sw_if_index == ~0)
14099     {
14100       errmsg ("missing interface name or sw_if_index");
14101       return -99;
14102     }
14103
14104   /* Construct the API message */
14105   M (COP_INTERFACE_ENABLE_DISABLE, mp);
14106   mp->sw_if_index = ntohl (sw_if_index);
14107   mp->enable_disable = enable_disable;
14108
14109   /* send it... */
14110   S (mp);
14111   /* Wait for the reply */
14112   W (ret);
14113   return ret;
14114 }
14115
14116 static int
14117 api_cop_whitelist_enable_disable (vat_main_t * vam)
14118 {
14119   unformat_input_t *line_input = vam->input;
14120   vl_api_cop_whitelist_enable_disable_t *mp;
14121   u32 sw_if_index = ~0;
14122   u8 ip4 = 0, ip6 = 0, default_cop = 0;
14123   u32 fib_id = 0;
14124   int ret;
14125
14126   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14127     {
14128       if (unformat (line_input, "ip4"))
14129         ip4 = 1;
14130       else if (unformat (line_input, "ip6"))
14131         ip6 = 1;
14132       else if (unformat (line_input, "default"))
14133         default_cop = 1;
14134       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14135                          vam, &sw_if_index))
14136         ;
14137       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14138         ;
14139       else if (unformat (line_input, "fib-id %d", &fib_id))
14140         ;
14141       else
14142         break;
14143     }
14144
14145   if (sw_if_index == ~0)
14146     {
14147       errmsg ("missing interface name or sw_if_index");
14148       return -99;
14149     }
14150
14151   /* Construct the API message */
14152   M (COP_WHITELIST_ENABLE_DISABLE, mp);
14153   mp->sw_if_index = ntohl (sw_if_index);
14154   mp->fib_id = ntohl (fib_id);
14155   mp->ip4 = ip4;
14156   mp->ip6 = ip6;
14157   mp->default_cop = default_cop;
14158
14159   /* send it... */
14160   S (mp);
14161   /* Wait for the reply */
14162   W (ret);
14163   return ret;
14164 }
14165
14166 static int
14167 api_get_node_graph (vat_main_t * vam)
14168 {
14169   vl_api_get_node_graph_t *mp;
14170   int ret;
14171
14172   M (GET_NODE_GRAPH, mp);
14173
14174   /* send it... */
14175   S (mp);
14176   /* Wait for the reply */
14177   W (ret);
14178   return ret;
14179 }
14180
14181 /* *INDENT-OFF* */
14182 /** Used for parsing LISP eids */
14183 typedef CLIB_PACKED(struct{
14184   union {
14185           ip46_address_t ip;
14186           mac_address_t mac;
14187           lisp_nsh_api_t nsh;
14188   } addr;
14189   u32 len;       /**< prefix length if IP */
14190   u8 type;      /**< type of eid */
14191 }) lisp_eid_vat_t;
14192 /* *INDENT-ON* */
14193
14194 static uword
14195 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
14196 {
14197   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
14198
14199   clib_memset (a, 0, sizeof (a[0]));
14200
14201   if (unformat (input, "%U/%d", unformat_ip46_address, a->addr.ip, &a->len))
14202     {
14203       a->type = 0;              /* ip prefix type */
14204     }
14205   else if (unformat (input, "%U", unformat_ethernet_address, a->addr.mac))
14206     {
14207       a->type = 1;              /* mac type */
14208     }
14209   else if (unformat (input, "%U", unformat_nsh_address, a->addr.nsh))
14210     {
14211       a->type = 2;              /* NSH type */
14212       a->addr.nsh.spi = clib_host_to_net_u32 (a->addr.nsh.spi);
14213     }
14214   else
14215     {
14216       return 0;
14217     }
14218
14219   if (a->type == 0)
14220     {
14221       if (ip46_address_is_ip4 (&a->addr.ip))
14222         return a->len > 32 ? 1 : 0;
14223       else
14224         return a->len > 128 ? 1 : 0;
14225     }
14226
14227   return 1;
14228 }
14229
14230 static void
14231 lisp_eid_put_vat (vl_api_eid_t * eid, const lisp_eid_vat_t * vat_eid)
14232 {
14233   eid->type = vat_eid->type;
14234   switch (eid->type)
14235     {
14236     case EID_TYPE_API_PREFIX:
14237       if (ip46_address_is_ip4 (&vat_eid->addr.ip))
14238         {
14239           clib_memcpy (&eid->address.prefix.address.un.ip4,
14240                        &vat_eid->addr.ip.ip4, 4);
14241           eid->address.prefix.address.af = ADDRESS_IP4;
14242           eid->address.prefix.len = vat_eid->len;
14243         }
14244       else
14245         {
14246           clib_memcpy (&eid->address.prefix.address.un.ip6,
14247                        &vat_eid->addr.ip.ip6, 16);
14248           eid->address.prefix.address.af = ADDRESS_IP6;
14249           eid->address.prefix.len = vat_eid->len;
14250         }
14251       return;
14252     case EID_TYPE_API_MAC:
14253       clib_memcpy (&eid->address.mac, &vat_eid->addr.mac,
14254                    sizeof (eid->address.mac));
14255       return;
14256     case EID_TYPE_API_NSH:
14257       clib_memcpy (&eid->address.nsh, &vat_eid->addr.nsh,
14258                    sizeof (eid->address.nsh));
14259       return;
14260     default:
14261       ASSERT (0);
14262       return;
14263     }
14264 }
14265
14266 static int
14267 api_one_add_del_locator_set (vat_main_t * vam)
14268 {
14269   unformat_input_t *input = vam->input;
14270   vl_api_one_add_del_locator_set_t *mp;
14271   u8 is_add = 1;
14272   u8 *locator_set_name = NULL;
14273   u8 locator_set_name_set = 0;
14274   vl_api_local_locator_t locator, *locators = 0;
14275   u32 sw_if_index, priority, weight;
14276   u32 data_len = 0;
14277
14278   int ret;
14279   /* Parse args required to build the message */
14280   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14281     {
14282       if (unformat (input, "del"))
14283         {
14284           is_add = 0;
14285         }
14286       else if (unformat (input, "locator-set %s", &locator_set_name))
14287         {
14288           locator_set_name_set = 1;
14289         }
14290       else if (unformat (input, "sw_if_index %u p %u w %u",
14291                          &sw_if_index, &priority, &weight))
14292         {
14293           locator.sw_if_index = htonl (sw_if_index);
14294           locator.priority = priority;
14295           locator.weight = weight;
14296           vec_add1 (locators, locator);
14297         }
14298       else
14299         if (unformat
14300             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14301              &sw_if_index, &priority, &weight))
14302         {
14303           locator.sw_if_index = htonl (sw_if_index);
14304           locator.priority = priority;
14305           locator.weight = weight;
14306           vec_add1 (locators, locator);
14307         }
14308       else
14309         break;
14310     }
14311
14312   if (locator_set_name_set == 0)
14313     {
14314       errmsg ("missing locator-set name");
14315       vec_free (locators);
14316       return -99;
14317     }
14318
14319   if (vec_len (locator_set_name) > 64)
14320     {
14321       errmsg ("locator-set name too long");
14322       vec_free (locator_set_name);
14323       vec_free (locators);
14324       return -99;
14325     }
14326   vec_add1 (locator_set_name, 0);
14327
14328   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14329
14330   /* Construct the API message */
14331   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14332
14333   mp->is_add = is_add;
14334   clib_memcpy (mp->locator_set_name, locator_set_name,
14335                vec_len (locator_set_name));
14336   vec_free (locator_set_name);
14337
14338   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14339   if (locators)
14340     clib_memcpy (mp->locators, locators, data_len);
14341   vec_free (locators);
14342
14343   /* send it... */
14344   S (mp);
14345
14346   /* Wait for a reply... */
14347   W (ret);
14348   return ret;
14349 }
14350
14351 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14352
14353 static int
14354 api_one_add_del_locator (vat_main_t * vam)
14355 {
14356   unformat_input_t *input = vam->input;
14357   vl_api_one_add_del_locator_t *mp;
14358   u32 tmp_if_index = ~0;
14359   u32 sw_if_index = ~0;
14360   u8 sw_if_index_set = 0;
14361   u8 sw_if_index_if_name_set = 0;
14362   u32 priority = ~0;
14363   u8 priority_set = 0;
14364   u32 weight = ~0;
14365   u8 weight_set = 0;
14366   u8 is_add = 1;
14367   u8 *locator_set_name = NULL;
14368   u8 locator_set_name_set = 0;
14369   int ret;
14370
14371   /* Parse args required to build the message */
14372   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14373     {
14374       if (unformat (input, "del"))
14375         {
14376           is_add = 0;
14377         }
14378       else if (unformat (input, "locator-set %s", &locator_set_name))
14379         {
14380           locator_set_name_set = 1;
14381         }
14382       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14383                          &tmp_if_index))
14384         {
14385           sw_if_index_if_name_set = 1;
14386           sw_if_index = tmp_if_index;
14387         }
14388       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14389         {
14390           sw_if_index_set = 1;
14391           sw_if_index = tmp_if_index;
14392         }
14393       else if (unformat (input, "p %d", &priority))
14394         {
14395           priority_set = 1;
14396         }
14397       else if (unformat (input, "w %d", &weight))
14398         {
14399           weight_set = 1;
14400         }
14401       else
14402         break;
14403     }
14404
14405   if (locator_set_name_set == 0)
14406     {
14407       errmsg ("missing locator-set name");
14408       return -99;
14409     }
14410
14411   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14412     {
14413       errmsg ("missing sw_if_index");
14414       vec_free (locator_set_name);
14415       return -99;
14416     }
14417
14418   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14419     {
14420       errmsg ("cannot use both params interface name and sw_if_index");
14421       vec_free (locator_set_name);
14422       return -99;
14423     }
14424
14425   if (priority_set == 0)
14426     {
14427       errmsg ("missing locator-set priority");
14428       vec_free (locator_set_name);
14429       return -99;
14430     }
14431
14432   if (weight_set == 0)
14433     {
14434       errmsg ("missing locator-set weight");
14435       vec_free (locator_set_name);
14436       return -99;
14437     }
14438
14439   if (vec_len (locator_set_name) > 64)
14440     {
14441       errmsg ("locator-set name too long");
14442       vec_free (locator_set_name);
14443       return -99;
14444     }
14445   vec_add1 (locator_set_name, 0);
14446
14447   /* Construct the API message */
14448   M (ONE_ADD_DEL_LOCATOR, mp);
14449
14450   mp->is_add = is_add;
14451   mp->sw_if_index = ntohl (sw_if_index);
14452   mp->priority = priority;
14453   mp->weight = weight;
14454   clib_memcpy (mp->locator_set_name, locator_set_name,
14455                vec_len (locator_set_name));
14456   vec_free (locator_set_name);
14457
14458   /* send it... */
14459   S (mp);
14460
14461   /* Wait for a reply... */
14462   W (ret);
14463   return ret;
14464 }
14465
14466 #define api_lisp_add_del_locator api_one_add_del_locator
14467
14468 uword
14469 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
14470 {
14471   u32 *key_id = va_arg (*args, u32 *);
14472   u8 *s = 0;
14473
14474   if (unformat (input, "%s", &s))
14475     {
14476       if (!strcmp ((char *) s, "sha1"))
14477         key_id[0] = HMAC_SHA_1_96;
14478       else if (!strcmp ((char *) s, "sha256"))
14479         key_id[0] = HMAC_SHA_256_128;
14480       else
14481         {
14482           clib_warning ("invalid key_id: '%s'", s);
14483           key_id[0] = HMAC_NO_KEY;
14484         }
14485     }
14486   else
14487     return 0;
14488
14489   vec_free (s);
14490   return 1;
14491 }
14492
14493 static int
14494 api_one_add_del_local_eid (vat_main_t * vam)
14495 {
14496   unformat_input_t *input = vam->input;
14497   vl_api_one_add_del_local_eid_t *mp;
14498   u8 is_add = 1;
14499   u8 eid_set = 0;
14500   lisp_eid_vat_t _eid, *eid = &_eid;
14501   u8 *locator_set_name = 0;
14502   u8 locator_set_name_set = 0;
14503   u32 vni = 0;
14504   u16 key_id = 0;
14505   u8 *key = 0;
14506   int ret;
14507
14508   /* Parse args required to build the message */
14509   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14510     {
14511       if (unformat (input, "del"))
14512         {
14513           is_add = 0;
14514         }
14515       else if (unformat (input, "vni %d", &vni))
14516         {
14517           ;
14518         }
14519       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14520         {
14521           eid_set = 1;
14522         }
14523       else if (unformat (input, "locator-set %s", &locator_set_name))
14524         {
14525           locator_set_name_set = 1;
14526         }
14527       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
14528         ;
14529       else if (unformat (input, "secret-key %_%v%_", &key))
14530         ;
14531       else
14532         break;
14533     }
14534
14535   if (locator_set_name_set == 0)
14536     {
14537       errmsg ("missing locator-set name");
14538       return -99;
14539     }
14540
14541   if (0 == eid_set)
14542     {
14543       errmsg ("EID address not set!");
14544       vec_free (locator_set_name);
14545       return -99;
14546     }
14547
14548   if (key && (0 == key_id))
14549     {
14550       errmsg ("invalid key_id!");
14551       return -99;
14552     }
14553
14554   if (vec_len (key) > 64)
14555     {
14556       errmsg ("key too long");
14557       vec_free (key);
14558       return -99;
14559     }
14560
14561   if (vec_len (locator_set_name) > 64)
14562     {
14563       errmsg ("locator-set name too long");
14564       vec_free (locator_set_name);
14565       return -99;
14566     }
14567   vec_add1 (locator_set_name, 0);
14568
14569   /* Construct the API message */
14570   M (ONE_ADD_DEL_LOCAL_EID, mp);
14571
14572   mp->is_add = is_add;
14573   lisp_eid_put_vat (&mp->eid, eid);
14574   mp->vni = clib_host_to_net_u32 (vni);
14575   mp->key.id = key_id;
14576   clib_memcpy (mp->locator_set_name, locator_set_name,
14577                vec_len (locator_set_name));
14578   clib_memcpy (mp->key.key, key, vec_len (key));
14579
14580   vec_free (locator_set_name);
14581   vec_free (key);
14582
14583   /* send it... */
14584   S (mp);
14585
14586   /* Wait for a reply... */
14587   W (ret);
14588   return ret;
14589 }
14590
14591 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
14592
14593 static int
14594 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
14595 {
14596   u32 dp_table = 0, vni = 0;;
14597   unformat_input_t *input = vam->input;
14598   vl_api_gpe_add_del_fwd_entry_t *mp;
14599   u8 is_add = 1;
14600   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
14601   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
14602   u8 rmt_eid_set = 0, lcl_eid_set = 0;
14603   u32 action = ~0, w;
14604   ip4_address_t rmt_rloc4, lcl_rloc4;
14605   ip6_address_t rmt_rloc6, lcl_rloc6;
14606   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
14607   int ret;
14608
14609   clib_memset (&rloc, 0, sizeof (rloc));
14610
14611   /* Parse args required to build the message */
14612   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14613     {
14614       if (unformat (input, "del"))
14615         is_add = 0;
14616       else if (unformat (input, "add"))
14617         is_add = 1;
14618       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
14619         {
14620           rmt_eid_set = 1;
14621         }
14622       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
14623         {
14624           lcl_eid_set = 1;
14625         }
14626       else if (unformat (input, "vrf %d", &dp_table))
14627         ;
14628       else if (unformat (input, "bd %d", &dp_table))
14629         ;
14630       else if (unformat (input, "vni %d", &vni))
14631         ;
14632       else if (unformat (input, "w %d", &w))
14633         {
14634           if (!curr_rloc)
14635             {
14636               errmsg ("No RLOC configured for setting priority/weight!");
14637               return -99;
14638             }
14639           curr_rloc->weight = w;
14640         }
14641       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14642                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14643         {
14644           rloc.addr.af = 0;
14645           clib_memcpy (&rloc.addr.un.ip4, &lcl_rloc4, sizeof (lcl_rloc4));
14646           rloc.weight = 0;
14647           vec_add1 (lcl_locs, rloc);
14648
14649           clib_memcpy (&rloc.addr.un.ip4, &rmt_rloc4, sizeof (rmt_rloc4));
14650           vec_add1 (rmt_locs, rloc);
14651           /* weight saved in rmt loc */
14652           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14653         }
14654       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14655                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14656         {
14657           rloc.addr.af = 1;
14658           clib_memcpy (&rloc.addr.un.ip6, &lcl_rloc6, sizeof (lcl_rloc6));
14659           rloc.weight = 0;
14660           vec_add1 (lcl_locs, rloc);
14661
14662           clib_memcpy (&rloc.addr.un.ip6, &rmt_rloc6, sizeof (rmt_rloc6));
14663           vec_add1 (rmt_locs, rloc);
14664           /* weight saved in rmt loc */
14665           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14666         }
14667       else if (unformat (input, "action %d", &action))
14668         {
14669           ;
14670         }
14671       else
14672         {
14673           clib_warning ("parse error '%U'", format_unformat_error, input);
14674           return -99;
14675         }
14676     }
14677
14678   if (!rmt_eid_set)
14679     {
14680       errmsg ("remote eid addresses not set");
14681       return -99;
14682     }
14683
14684   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14685     {
14686       errmsg ("eid types don't match");
14687       return -99;
14688     }
14689
14690   if (0 == rmt_locs && (u32) ~ 0 == action)
14691     {
14692       errmsg ("action not set for negative mapping");
14693       return -99;
14694     }
14695
14696   /* Construct the API message */
14697   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14698       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
14699
14700   mp->is_add = is_add;
14701   lisp_eid_put_vat (&mp->rmt_eid, rmt_eid);
14702   lisp_eid_put_vat (&mp->lcl_eid, lcl_eid);
14703   mp->dp_table = clib_host_to_net_u32 (dp_table);
14704   mp->vni = clib_host_to_net_u32 (vni);
14705   mp->action = action;
14706
14707   if (0 != rmt_locs && 0 != lcl_locs)
14708     {
14709       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14710       clib_memcpy (mp->locs, lcl_locs,
14711                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
14712
14713       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14714       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14715                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
14716     }
14717   vec_free (lcl_locs);
14718   vec_free (rmt_locs);
14719
14720   /* send it... */
14721   S (mp);
14722
14723   /* Wait for a reply... */
14724   W (ret);
14725   return ret;
14726 }
14727
14728 static int
14729 api_one_add_del_map_server (vat_main_t * vam)
14730 {
14731   unformat_input_t *input = vam->input;
14732   vl_api_one_add_del_map_server_t *mp;
14733   u8 is_add = 1;
14734   u8 ipv4_set = 0;
14735   u8 ipv6_set = 0;
14736   ip4_address_t ipv4;
14737   ip6_address_t ipv6;
14738   int ret;
14739
14740   /* Parse args required to build the message */
14741   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14742     {
14743       if (unformat (input, "del"))
14744         {
14745           is_add = 0;
14746         }
14747       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14748         {
14749           ipv4_set = 1;
14750         }
14751       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14752         {
14753           ipv6_set = 1;
14754         }
14755       else
14756         break;
14757     }
14758
14759   if (ipv4_set && ipv6_set)
14760     {
14761       errmsg ("both eid v4 and v6 addresses set");
14762       return -99;
14763     }
14764
14765   if (!ipv4_set && !ipv6_set)
14766     {
14767       errmsg ("eid addresses not set");
14768       return -99;
14769     }
14770
14771   /* Construct the API message */
14772   M (ONE_ADD_DEL_MAP_SERVER, mp);
14773
14774   mp->is_add = is_add;
14775   if (ipv6_set)
14776     {
14777       mp->ip_address.af = 1;
14778       clib_memcpy (mp->ip_address.un.ip6, &ipv6, sizeof (ipv6));
14779     }
14780   else
14781     {
14782       mp->ip_address.af = 0;
14783       clib_memcpy (mp->ip_address.un.ip4, &ipv4, sizeof (ipv4));
14784     }
14785
14786   /* send it... */
14787   S (mp);
14788
14789   /* Wait for a reply... */
14790   W (ret);
14791   return ret;
14792 }
14793
14794 #define api_lisp_add_del_map_server api_one_add_del_map_server
14795
14796 static int
14797 api_one_add_del_map_resolver (vat_main_t * vam)
14798 {
14799   unformat_input_t *input = vam->input;
14800   vl_api_one_add_del_map_resolver_t *mp;
14801   u8 is_add = 1;
14802   u8 ipv4_set = 0;
14803   u8 ipv6_set = 0;
14804   ip4_address_t ipv4;
14805   ip6_address_t ipv6;
14806   int ret;
14807
14808   /* Parse args required to build the message */
14809   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14810     {
14811       if (unformat (input, "del"))
14812         {
14813           is_add = 0;
14814         }
14815       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14816         {
14817           ipv4_set = 1;
14818         }
14819       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14820         {
14821           ipv6_set = 1;
14822         }
14823       else
14824         break;
14825     }
14826
14827   if (ipv4_set && ipv6_set)
14828     {
14829       errmsg ("both eid v4 and v6 addresses set");
14830       return -99;
14831     }
14832
14833   if (!ipv4_set && !ipv6_set)
14834     {
14835       errmsg ("eid addresses not set");
14836       return -99;
14837     }
14838
14839   /* Construct the API message */
14840   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
14841
14842   mp->is_add = is_add;
14843   if (ipv6_set)
14844     {
14845       mp->ip_address.af = 1;
14846       clib_memcpy (mp->ip_address.un.ip6, &ipv6, sizeof (ipv6));
14847     }
14848   else
14849     {
14850       mp->ip_address.af = 0;
14851       clib_memcpy (mp->ip_address.un.ip6, &ipv4, sizeof (ipv4));
14852     }
14853
14854   /* send it... */
14855   S (mp);
14856
14857   /* Wait for a reply... */
14858   W (ret);
14859   return ret;
14860 }
14861
14862 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14863
14864 static int
14865 api_lisp_gpe_enable_disable (vat_main_t * vam)
14866 {
14867   unformat_input_t *input = vam->input;
14868   vl_api_gpe_enable_disable_t *mp;
14869   u8 is_set = 0;
14870   u8 is_enable = 1;
14871   int ret;
14872
14873   /* Parse args required to build the message */
14874   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14875     {
14876       if (unformat (input, "enable"))
14877         {
14878           is_set = 1;
14879           is_enable = 1;
14880         }
14881       else if (unformat (input, "disable"))
14882         {
14883           is_set = 1;
14884           is_enable = 0;
14885         }
14886       else
14887         break;
14888     }
14889
14890   if (is_set == 0)
14891     {
14892       errmsg ("Value not set");
14893       return -99;
14894     }
14895
14896   /* Construct the API message */
14897   M (GPE_ENABLE_DISABLE, mp);
14898
14899   mp->is_enable = is_enable;
14900
14901   /* send it... */
14902   S (mp);
14903
14904   /* Wait for a reply... */
14905   W (ret);
14906   return ret;
14907 }
14908
14909 static int
14910 api_one_rloc_probe_enable_disable (vat_main_t * vam)
14911 {
14912   unformat_input_t *input = vam->input;
14913   vl_api_one_rloc_probe_enable_disable_t *mp;
14914   u8 is_set = 0;
14915   u8 is_enable = 0;
14916   int ret;
14917
14918   /* Parse args required to build the message */
14919   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14920     {
14921       if (unformat (input, "enable"))
14922         {
14923           is_set = 1;
14924           is_enable = 1;
14925         }
14926       else if (unformat (input, "disable"))
14927         is_set = 1;
14928       else
14929         break;
14930     }
14931
14932   if (!is_set)
14933     {
14934       errmsg ("Value not set");
14935       return -99;
14936     }
14937
14938   /* Construct the API message */
14939   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
14940
14941   mp->is_enable = is_enable;
14942
14943   /* send it... */
14944   S (mp);
14945
14946   /* Wait for a reply... */
14947   W (ret);
14948   return ret;
14949 }
14950
14951 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14952
14953 static int
14954 api_one_map_register_enable_disable (vat_main_t * vam)
14955 {
14956   unformat_input_t *input = vam->input;
14957   vl_api_one_map_register_enable_disable_t *mp;
14958   u8 is_set = 0;
14959   u8 is_enable = 0;
14960   int ret;
14961
14962   /* Parse args required to build the message */
14963   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14964     {
14965       if (unformat (input, "enable"))
14966         {
14967           is_set = 1;
14968           is_enable = 1;
14969         }
14970       else if (unformat (input, "disable"))
14971         is_set = 1;
14972       else
14973         break;
14974     }
14975
14976   if (!is_set)
14977     {
14978       errmsg ("Value not set");
14979       return -99;
14980     }
14981
14982   /* Construct the API message */
14983   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
14984
14985   mp->is_enable = is_enable;
14986
14987   /* send it... */
14988   S (mp);
14989
14990   /* Wait for a reply... */
14991   W (ret);
14992   return ret;
14993 }
14994
14995 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14996
14997 static int
14998 api_one_enable_disable (vat_main_t * vam)
14999 {
15000   unformat_input_t *input = vam->input;
15001   vl_api_one_enable_disable_t *mp;
15002   u8 is_set = 0;
15003   u8 is_enable = 0;
15004   int ret;
15005
15006   /* Parse args required to build the message */
15007   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15008     {
15009       if (unformat (input, "enable"))
15010         {
15011           is_set = 1;
15012           is_enable = 1;
15013         }
15014       else if (unformat (input, "disable"))
15015         {
15016           is_set = 1;
15017         }
15018       else
15019         break;
15020     }
15021
15022   if (!is_set)
15023     {
15024       errmsg ("Value not set");
15025       return -99;
15026     }
15027
15028   /* Construct the API message */
15029   M (ONE_ENABLE_DISABLE, mp);
15030
15031   mp->is_enable = is_enable;
15032
15033   /* send it... */
15034   S (mp);
15035
15036   /* Wait for a reply... */
15037   W (ret);
15038   return ret;
15039 }
15040
15041 #define api_lisp_enable_disable api_one_enable_disable
15042
15043 static int
15044 api_one_enable_disable_xtr_mode (vat_main_t * vam)
15045 {
15046   unformat_input_t *input = vam->input;
15047   vl_api_one_enable_disable_xtr_mode_t *mp;
15048   u8 is_set = 0;
15049   u8 is_enable = 0;
15050   int ret;
15051
15052   /* Parse args required to build the message */
15053   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15054     {
15055       if (unformat (input, "enable"))
15056         {
15057           is_set = 1;
15058           is_enable = 1;
15059         }
15060       else if (unformat (input, "disable"))
15061         {
15062           is_set = 1;
15063         }
15064       else
15065         break;
15066     }
15067
15068   if (!is_set)
15069     {
15070       errmsg ("Value not set");
15071       return -99;
15072     }
15073
15074   /* Construct the API message */
15075   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
15076
15077   mp->is_enable = is_enable;
15078
15079   /* send it... */
15080   S (mp);
15081
15082   /* Wait for a reply... */
15083   W (ret);
15084   return ret;
15085 }
15086
15087 static int
15088 api_one_show_xtr_mode (vat_main_t * vam)
15089 {
15090   vl_api_one_show_xtr_mode_t *mp;
15091   int ret;
15092
15093   /* Construct the API message */
15094   M (ONE_SHOW_XTR_MODE, mp);
15095
15096   /* send it... */
15097   S (mp);
15098
15099   /* Wait for a reply... */
15100   W (ret);
15101   return ret;
15102 }
15103
15104 static int
15105 api_one_enable_disable_pitr_mode (vat_main_t * vam)
15106 {
15107   unformat_input_t *input = vam->input;
15108   vl_api_one_enable_disable_pitr_mode_t *mp;
15109   u8 is_set = 0;
15110   u8 is_enable = 0;
15111   int ret;
15112
15113   /* Parse args required to build the message */
15114   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15115     {
15116       if (unformat (input, "enable"))
15117         {
15118           is_set = 1;
15119           is_enable = 1;
15120         }
15121       else if (unformat (input, "disable"))
15122         {
15123           is_set = 1;
15124         }
15125       else
15126         break;
15127     }
15128
15129   if (!is_set)
15130     {
15131       errmsg ("Value not set");
15132       return -99;
15133     }
15134
15135   /* Construct the API message */
15136   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
15137
15138   mp->is_enable = is_enable;
15139
15140   /* send it... */
15141   S (mp);
15142
15143   /* Wait for a reply... */
15144   W (ret);
15145   return ret;
15146 }
15147
15148 static int
15149 api_one_show_pitr_mode (vat_main_t * vam)
15150 {
15151   vl_api_one_show_pitr_mode_t *mp;
15152   int ret;
15153
15154   /* Construct the API message */
15155   M (ONE_SHOW_PITR_MODE, mp);
15156
15157   /* send it... */
15158   S (mp);
15159
15160   /* Wait for a reply... */
15161   W (ret);
15162   return ret;
15163 }
15164
15165 static int
15166 api_one_enable_disable_petr_mode (vat_main_t * vam)
15167 {
15168   unformat_input_t *input = vam->input;
15169   vl_api_one_enable_disable_petr_mode_t *mp;
15170   u8 is_set = 0;
15171   u8 is_enable = 0;
15172   int ret;
15173
15174   /* Parse args required to build the message */
15175   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15176     {
15177       if (unformat (input, "enable"))
15178         {
15179           is_set = 1;
15180           is_enable = 1;
15181         }
15182       else if (unformat (input, "disable"))
15183         {
15184           is_set = 1;
15185         }
15186       else
15187         break;
15188     }
15189
15190   if (!is_set)
15191     {
15192       errmsg ("Value not set");
15193       return -99;
15194     }
15195
15196   /* Construct the API message */
15197   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
15198
15199   mp->is_enable = is_enable;
15200
15201   /* send it... */
15202   S (mp);
15203
15204   /* Wait for a reply... */
15205   W (ret);
15206   return ret;
15207 }
15208
15209 static int
15210 api_one_show_petr_mode (vat_main_t * vam)
15211 {
15212   vl_api_one_show_petr_mode_t *mp;
15213   int ret;
15214
15215   /* Construct the API message */
15216   M (ONE_SHOW_PETR_MODE, mp);
15217
15218   /* send it... */
15219   S (mp);
15220
15221   /* Wait for a reply... */
15222   W (ret);
15223   return ret;
15224 }
15225
15226 static int
15227 api_show_one_map_register_state (vat_main_t * vam)
15228 {
15229   vl_api_show_one_map_register_state_t *mp;
15230   int ret;
15231
15232   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
15233
15234   /* send */
15235   S (mp);
15236
15237   /* wait for reply */
15238   W (ret);
15239   return ret;
15240 }
15241
15242 #define api_show_lisp_map_register_state api_show_one_map_register_state
15243
15244 static int
15245 api_show_one_rloc_probe_state (vat_main_t * vam)
15246 {
15247   vl_api_show_one_rloc_probe_state_t *mp;
15248   int ret;
15249
15250   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
15251
15252   /* send */
15253   S (mp);
15254
15255   /* wait for reply */
15256   W (ret);
15257   return ret;
15258 }
15259
15260 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
15261
15262 static int
15263 api_one_add_del_ndp_entry (vat_main_t * vam)
15264 {
15265   vl_api_one_add_del_ndp_entry_t *mp;
15266   unformat_input_t *input = vam->input;
15267   u8 is_add = 1;
15268   u8 mac_set = 0;
15269   u8 bd_set = 0;
15270   u8 ip_set = 0;
15271   u8 mac[6] = { 0, };
15272   u8 ip6[16] = { 0, };
15273   u32 bd = ~0;
15274   int ret;
15275
15276   /* Parse args required to build the message */
15277   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15278     {
15279       if (unformat (input, "del"))
15280         is_add = 0;
15281       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15282         mac_set = 1;
15283       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
15284         ip_set = 1;
15285       else if (unformat (input, "bd %d", &bd))
15286         bd_set = 1;
15287       else
15288         {
15289           errmsg ("parse error '%U'", format_unformat_error, input);
15290           return -99;
15291         }
15292     }
15293
15294   if (!bd_set || !ip_set || (!mac_set && is_add))
15295     {
15296       errmsg ("Missing BD, IP or MAC!");
15297       return -99;
15298     }
15299
15300   M (ONE_ADD_DEL_NDP_ENTRY, mp);
15301   mp->is_add = is_add;
15302   clib_memcpy (&mp->entry.mac, mac, 6);
15303   mp->bd = clib_host_to_net_u32 (bd);
15304   clib_memcpy (&mp->entry.ip6, ip6, sizeof (mp->entry.ip6));
15305
15306   /* send */
15307   S (mp);
15308
15309   /* wait for reply */
15310   W (ret);
15311   return ret;
15312 }
15313
15314 static int
15315 api_one_add_del_l2_arp_entry (vat_main_t * vam)
15316 {
15317   vl_api_one_add_del_l2_arp_entry_t *mp;
15318   unformat_input_t *input = vam->input;
15319   u8 is_add = 1;
15320   u8 mac_set = 0;
15321   u8 bd_set = 0;
15322   u8 ip_set = 0;
15323   u8 mac[6] = { 0, };
15324   u32 ip4 = 0, bd = ~0;
15325   int ret;
15326
15327   /* Parse args required to build the message */
15328   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15329     {
15330       if (unformat (input, "del"))
15331         is_add = 0;
15332       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15333         mac_set = 1;
15334       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
15335         ip_set = 1;
15336       else if (unformat (input, "bd %d", &bd))
15337         bd_set = 1;
15338       else
15339         {
15340           errmsg ("parse error '%U'", format_unformat_error, input);
15341           return -99;
15342         }
15343     }
15344
15345   if (!bd_set || !ip_set || (!mac_set && is_add))
15346     {
15347       errmsg ("Missing BD, IP or MAC!");
15348       return -99;
15349     }
15350
15351   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
15352   mp->is_add = is_add;
15353   clib_memcpy (&mp->entry.mac, mac, 6);
15354   mp->bd = clib_host_to_net_u32 (bd);
15355   clib_memcpy (mp->entry.ip4, &ip4, sizeof (mp->entry.ip4));
15356
15357   /* send */
15358   S (mp);
15359
15360   /* wait for reply */
15361   W (ret);
15362   return ret;
15363 }
15364
15365 static int
15366 api_one_ndp_bd_get (vat_main_t * vam)
15367 {
15368   vl_api_one_ndp_bd_get_t *mp;
15369   int ret;
15370
15371   M (ONE_NDP_BD_GET, mp);
15372
15373   /* send */
15374   S (mp);
15375
15376   /* wait for reply */
15377   W (ret);
15378   return ret;
15379 }
15380
15381 static int
15382 api_one_ndp_entries_get (vat_main_t * vam)
15383 {
15384   vl_api_one_ndp_entries_get_t *mp;
15385   unformat_input_t *input = vam->input;
15386   u8 bd_set = 0;
15387   u32 bd = ~0;
15388   int ret;
15389
15390   /* Parse args required to build the message */
15391   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15392     {
15393       if (unformat (input, "bd %d", &bd))
15394         bd_set = 1;
15395       else
15396         {
15397           errmsg ("parse error '%U'", format_unformat_error, input);
15398           return -99;
15399         }
15400     }
15401
15402   if (!bd_set)
15403     {
15404       errmsg ("Expected bridge domain!");
15405       return -99;
15406     }
15407
15408   M (ONE_NDP_ENTRIES_GET, mp);
15409   mp->bd = clib_host_to_net_u32 (bd);
15410
15411   /* send */
15412   S (mp);
15413
15414   /* wait for reply */
15415   W (ret);
15416   return ret;
15417 }
15418
15419 static int
15420 api_one_l2_arp_bd_get (vat_main_t * vam)
15421 {
15422   vl_api_one_l2_arp_bd_get_t *mp;
15423   int ret;
15424
15425   M (ONE_L2_ARP_BD_GET, mp);
15426
15427   /* send */
15428   S (mp);
15429
15430   /* wait for reply */
15431   W (ret);
15432   return ret;
15433 }
15434
15435 static int
15436 api_one_l2_arp_entries_get (vat_main_t * vam)
15437 {
15438   vl_api_one_l2_arp_entries_get_t *mp;
15439   unformat_input_t *input = vam->input;
15440   u8 bd_set = 0;
15441   u32 bd = ~0;
15442   int ret;
15443
15444   /* Parse args required to build the message */
15445   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15446     {
15447       if (unformat (input, "bd %d", &bd))
15448         bd_set = 1;
15449       else
15450         {
15451           errmsg ("parse error '%U'", format_unformat_error, input);
15452           return -99;
15453         }
15454     }
15455
15456   if (!bd_set)
15457     {
15458       errmsg ("Expected bridge domain!");
15459       return -99;
15460     }
15461
15462   M (ONE_L2_ARP_ENTRIES_GET, mp);
15463   mp->bd = clib_host_to_net_u32 (bd);
15464
15465   /* send */
15466   S (mp);
15467
15468   /* wait for reply */
15469   W (ret);
15470   return ret;
15471 }
15472
15473 static int
15474 api_one_stats_enable_disable (vat_main_t * vam)
15475 {
15476   vl_api_one_stats_enable_disable_t *mp;
15477   unformat_input_t *input = vam->input;
15478   u8 is_set = 0;
15479   u8 is_enable = 0;
15480   int ret;
15481
15482   /* Parse args required to build the message */
15483   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15484     {
15485       if (unformat (input, "enable"))
15486         {
15487           is_set = 1;
15488           is_enable = 1;
15489         }
15490       else if (unformat (input, "disable"))
15491         {
15492           is_set = 1;
15493         }
15494       else
15495         break;
15496     }
15497
15498   if (!is_set)
15499     {
15500       errmsg ("Value not set");
15501       return -99;
15502     }
15503
15504   M (ONE_STATS_ENABLE_DISABLE, mp);
15505   mp->is_enable = is_enable;
15506
15507   /* send */
15508   S (mp);
15509
15510   /* wait for reply */
15511   W (ret);
15512   return ret;
15513 }
15514
15515 static int
15516 api_show_one_stats_enable_disable (vat_main_t * vam)
15517 {
15518   vl_api_show_one_stats_enable_disable_t *mp;
15519   int ret;
15520
15521   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
15522
15523   /* send */
15524   S (mp);
15525
15526   /* wait for reply */
15527   W (ret);
15528   return ret;
15529 }
15530
15531 static int
15532 api_show_one_map_request_mode (vat_main_t * vam)
15533 {
15534   vl_api_show_one_map_request_mode_t *mp;
15535   int ret;
15536
15537   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
15538
15539   /* send */
15540   S (mp);
15541
15542   /* wait for reply */
15543   W (ret);
15544   return ret;
15545 }
15546
15547 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
15548
15549 static int
15550 api_one_map_request_mode (vat_main_t * vam)
15551 {
15552   unformat_input_t *input = vam->input;
15553   vl_api_one_map_request_mode_t *mp;
15554   u8 mode = 0;
15555   int ret;
15556
15557   /* Parse args required to build the message */
15558   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15559     {
15560       if (unformat (input, "dst-only"))
15561         mode = 0;
15562       else if (unformat (input, "src-dst"))
15563         mode = 1;
15564       else
15565         {
15566           errmsg ("parse error '%U'", format_unformat_error, input);
15567           return -99;
15568         }
15569     }
15570
15571   M (ONE_MAP_REQUEST_MODE, mp);
15572
15573   mp->mode = mode;
15574
15575   /* send */
15576   S (mp);
15577
15578   /* wait for reply */
15579   W (ret);
15580   return ret;
15581 }
15582
15583 #define api_lisp_map_request_mode api_one_map_request_mode
15584
15585 /**
15586  * Enable/disable ONE proxy ITR.
15587  *
15588  * @param vam vpp API test context
15589  * @return return code
15590  */
15591 static int
15592 api_one_pitr_set_locator_set (vat_main_t * vam)
15593 {
15594   u8 ls_name_set = 0;
15595   unformat_input_t *input = vam->input;
15596   vl_api_one_pitr_set_locator_set_t *mp;
15597   u8 is_add = 1;
15598   u8 *ls_name = 0;
15599   int ret;
15600
15601   /* Parse args required to build the message */
15602   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15603     {
15604       if (unformat (input, "del"))
15605         is_add = 0;
15606       else if (unformat (input, "locator-set %s", &ls_name))
15607         ls_name_set = 1;
15608       else
15609         {
15610           errmsg ("parse error '%U'", format_unformat_error, input);
15611           return -99;
15612         }
15613     }
15614
15615   if (!ls_name_set)
15616     {
15617       errmsg ("locator-set name not set!");
15618       return -99;
15619     }
15620
15621   M (ONE_PITR_SET_LOCATOR_SET, mp);
15622
15623   mp->is_add = is_add;
15624   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15625   vec_free (ls_name);
15626
15627   /* send */
15628   S (mp);
15629
15630   /* wait for reply */
15631   W (ret);
15632   return ret;
15633 }
15634
15635 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
15636
15637 static int
15638 api_one_nsh_set_locator_set (vat_main_t * vam)
15639 {
15640   u8 ls_name_set = 0;
15641   unformat_input_t *input = vam->input;
15642   vl_api_one_nsh_set_locator_set_t *mp;
15643   u8 is_add = 1;
15644   u8 *ls_name = 0;
15645   int ret;
15646
15647   /* Parse args required to build the message */
15648   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15649     {
15650       if (unformat (input, "del"))
15651         is_add = 0;
15652       else if (unformat (input, "ls %s", &ls_name))
15653         ls_name_set = 1;
15654       else
15655         {
15656           errmsg ("parse error '%U'", format_unformat_error, input);
15657           return -99;
15658         }
15659     }
15660
15661   if (!ls_name_set && is_add)
15662     {
15663       errmsg ("locator-set name not set!");
15664       return -99;
15665     }
15666
15667   M (ONE_NSH_SET_LOCATOR_SET, mp);
15668
15669   mp->is_add = is_add;
15670   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15671   vec_free (ls_name);
15672
15673   /* send */
15674   S (mp);
15675
15676   /* wait for reply */
15677   W (ret);
15678   return ret;
15679 }
15680
15681 static int
15682 api_show_one_pitr (vat_main_t * vam)
15683 {
15684   vl_api_show_one_pitr_t *mp;
15685   int ret;
15686
15687   if (!vam->json_output)
15688     {
15689       print (vam->ofp, "%=20s", "lisp status:");
15690     }
15691
15692   M (SHOW_ONE_PITR, mp);
15693   /* send it... */
15694   S (mp);
15695
15696   /* Wait for a reply... */
15697   W (ret);
15698   return ret;
15699 }
15700
15701 #define api_show_lisp_pitr api_show_one_pitr
15702
15703 static int
15704 api_one_use_petr (vat_main_t * vam)
15705 {
15706   unformat_input_t *input = vam->input;
15707   vl_api_one_use_petr_t *mp;
15708   u8 is_add = 0;
15709   ip_address_t ip;
15710   int ret;
15711
15712   clib_memset (&ip, 0, sizeof (ip));
15713
15714   /* Parse args required to build the message */
15715   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15716     {
15717       if (unformat (input, "disable"))
15718         is_add = 0;
15719       else
15720         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
15721         {
15722           is_add = 1;
15723           ip_addr_version (&ip) = AF_IP4;
15724         }
15725       else
15726         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
15727         {
15728           is_add = 1;
15729           ip_addr_version (&ip) = AF_IP6;
15730         }
15731       else
15732         {
15733           errmsg ("parse error '%U'", format_unformat_error, input);
15734           return -99;
15735         }
15736     }
15737
15738   M (ONE_USE_PETR, mp);
15739
15740   mp->is_add = is_add;
15741   if (is_add)
15742     {
15743       mp->ip_address.af = ip_addr_version (&ip) == AF_IP4 ? 0 : 1;
15744       if (mp->ip_address.af)
15745         clib_memcpy (mp->ip_address.un.ip6, &ip, 16);
15746       else
15747         clib_memcpy (mp->ip_address.un.ip4, &ip, 4);
15748     }
15749
15750   /* send */
15751   S (mp);
15752
15753   /* wait for reply */
15754   W (ret);
15755   return ret;
15756 }
15757
15758 #define api_lisp_use_petr api_one_use_petr
15759
15760 static int
15761 api_show_one_nsh_mapping (vat_main_t * vam)
15762 {
15763   vl_api_show_one_use_petr_t *mp;
15764   int ret;
15765
15766   if (!vam->json_output)
15767     {
15768       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
15769     }
15770
15771   M (SHOW_ONE_NSH_MAPPING, mp);
15772   /* send it... */
15773   S (mp);
15774
15775   /* Wait for a reply... */
15776   W (ret);
15777   return ret;
15778 }
15779
15780 static int
15781 api_show_one_use_petr (vat_main_t * vam)
15782 {
15783   vl_api_show_one_use_petr_t *mp;
15784   int ret;
15785
15786   if (!vam->json_output)
15787     {
15788       print (vam->ofp, "%=20s", "Proxy-ETR status:");
15789     }
15790
15791   M (SHOW_ONE_USE_PETR, mp);
15792   /* send it... */
15793   S (mp);
15794
15795   /* Wait for a reply... */
15796   W (ret);
15797   return ret;
15798 }
15799
15800 #define api_show_lisp_use_petr api_show_one_use_petr
15801
15802 /**
15803  * Add/delete mapping between vni and vrf
15804  */
15805 static int
15806 api_one_eid_table_add_del_map (vat_main_t * vam)
15807 {
15808   unformat_input_t *input = vam->input;
15809   vl_api_one_eid_table_add_del_map_t *mp;
15810   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
15811   u32 vni, vrf, bd_index;
15812   int ret;
15813
15814   /* Parse args required to build the message */
15815   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15816     {
15817       if (unformat (input, "del"))
15818         is_add = 0;
15819       else if (unformat (input, "vrf %d", &vrf))
15820         vrf_set = 1;
15821       else if (unformat (input, "bd_index %d", &bd_index))
15822         bd_index_set = 1;
15823       else if (unformat (input, "vni %d", &vni))
15824         vni_set = 1;
15825       else
15826         break;
15827     }
15828
15829   if (!vni_set || (!vrf_set && !bd_index_set))
15830     {
15831       errmsg ("missing arguments!");
15832       return -99;
15833     }
15834
15835   if (vrf_set && bd_index_set)
15836     {
15837       errmsg ("error: both vrf and bd entered!");
15838       return -99;
15839     }
15840
15841   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
15842
15843   mp->is_add = is_add;
15844   mp->vni = htonl (vni);
15845   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
15846   mp->is_l2 = bd_index_set;
15847
15848   /* send */
15849   S (mp);
15850
15851   /* wait for reply */
15852   W (ret);
15853   return ret;
15854 }
15855
15856 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
15857
15858 uword
15859 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
15860 {
15861   u32 *action = va_arg (*args, u32 *);
15862   u8 *s = 0;
15863
15864   if (unformat (input, "%s", &s))
15865     {
15866       if (!strcmp ((char *) s, "no-action"))
15867         action[0] = 0;
15868       else if (!strcmp ((char *) s, "natively-forward"))
15869         action[0] = 1;
15870       else if (!strcmp ((char *) s, "send-map-request"))
15871         action[0] = 2;
15872       else if (!strcmp ((char *) s, "drop"))
15873         action[0] = 3;
15874       else
15875         {
15876           clib_warning ("invalid action: '%s'", s);
15877           action[0] = 3;
15878         }
15879     }
15880   else
15881     return 0;
15882
15883   vec_free (s);
15884   return 1;
15885 }
15886
15887 /**
15888  * Add/del remote mapping to/from ONE control plane
15889  *
15890  * @param vam vpp API test context
15891  * @return return code
15892  */
15893 static int
15894 api_one_add_del_remote_mapping (vat_main_t * vam)
15895 {
15896   unformat_input_t *input = vam->input;
15897   vl_api_one_add_del_remote_mapping_t *mp;
15898   u32 vni = 0;
15899   lisp_eid_vat_t _eid, *eid = &_eid;
15900   lisp_eid_vat_t _seid, *seid = &_seid;
15901   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
15902   u32 action = ~0, p, w, data_len;
15903   ip4_address_t rloc4;
15904   ip6_address_t rloc6;
15905   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
15906   int ret;
15907
15908   clib_memset (&rloc, 0, sizeof (rloc));
15909
15910   /* Parse args required to build the message */
15911   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15912     {
15913       if (unformat (input, "del-all"))
15914         {
15915           del_all = 1;
15916         }
15917       else if (unformat (input, "del"))
15918         {
15919           is_add = 0;
15920         }
15921       else if (unformat (input, "add"))
15922         {
15923           is_add = 1;
15924         }
15925       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15926         {
15927           eid_set = 1;
15928         }
15929       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
15930         {
15931           seid_set = 1;
15932         }
15933       else if (unformat (input, "vni %d", &vni))
15934         {
15935           ;
15936         }
15937       else if (unformat (input, "p %d w %d", &p, &w))
15938         {
15939           if (!curr_rloc)
15940             {
15941               errmsg ("No RLOC configured for setting priority/weight!");
15942               return -99;
15943             }
15944           curr_rloc->priority = p;
15945           curr_rloc->weight = w;
15946         }
15947       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
15948         {
15949           rloc.ip_address.af = 0;
15950           clib_memcpy (&rloc.ip_address.un.ip6, &rloc6, sizeof (rloc6));
15951           vec_add1 (rlocs, rloc);
15952           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15953         }
15954       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
15955         {
15956           rloc.ip_address.af = 1;
15957           clib_memcpy (&rloc.ip_address.un.ip4, &rloc4, sizeof (rloc4));
15958           vec_add1 (rlocs, rloc);
15959           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15960         }
15961       else if (unformat (input, "action %U",
15962                          unformat_negative_mapping_action, &action))
15963         {
15964           ;
15965         }
15966       else
15967         {
15968           clib_warning ("parse error '%U'", format_unformat_error, input);
15969           return -99;
15970         }
15971     }
15972
15973   if (0 == eid_set)
15974     {
15975       errmsg ("missing params!");
15976       return -99;
15977     }
15978
15979   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
15980     {
15981       errmsg ("no action set for negative map-reply!");
15982       return -99;
15983     }
15984
15985   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
15986
15987   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
15988   mp->is_add = is_add;
15989   mp->vni = htonl (vni);
15990   mp->action = (u8) action;
15991   mp->is_src_dst = seid_set;
15992   mp->del_all = del_all;
15993   lisp_eid_put_vat (&mp->deid, eid);
15994   lisp_eid_put_vat (&mp->seid, seid);
15995
15996   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
15997   clib_memcpy (mp->rlocs, rlocs, data_len);
15998   vec_free (rlocs);
15999
16000   /* send it... */
16001   S (mp);
16002
16003   /* Wait for a reply... */
16004   W (ret);
16005   return ret;
16006 }
16007
16008 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
16009
16010 /**
16011  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
16012  * forwarding entries in data-plane accordingly.
16013  *
16014  * @param vam vpp API test context
16015  * @return return code
16016  */
16017 static int
16018 api_one_add_del_adjacency (vat_main_t * vam)
16019 {
16020   unformat_input_t *input = vam->input;
16021   vl_api_one_add_del_adjacency_t *mp;
16022   u32 vni = 0;
16023   u8 is_add = 1;
16024   int ret;
16025   lisp_eid_vat_t leid, reid;
16026
16027   leid.type = reid.type = (u8) ~ 0;
16028
16029   /* Parse args required to build the message */
16030   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16031     {
16032       if (unformat (input, "del"))
16033         {
16034           is_add = 0;
16035         }
16036       else if (unformat (input, "add"))
16037         {
16038           is_add = 1;
16039         }
16040       else if (unformat (input, "reid %U/%d", unformat_ip46_address,
16041                          &reid.addr.ip, &reid.len))
16042         {
16043           reid.type = 0;        /* ipv4 */
16044         }
16045       else if (unformat (input, "reid %U", unformat_ethernet_address,
16046                          &reid.addr.mac))
16047         {
16048           reid.type = 1;        /* mac */
16049         }
16050       else if (unformat (input, "leid %U/%d", unformat_ip46_address,
16051                          &leid.addr.ip, &leid.len))
16052         {
16053           leid.type = 0;        /* ipv4 */
16054         }
16055       else if (unformat (input, "leid %U", unformat_ethernet_address,
16056                          &leid.addr.mac))
16057         {
16058           leid.type = 1;        /* mac */
16059         }
16060       else if (unformat (input, "vni %d", &vni))
16061         {
16062           ;
16063         }
16064       else
16065         {
16066           errmsg ("parse error '%U'", format_unformat_error, input);
16067           return -99;
16068         }
16069     }
16070
16071   if ((u8) ~ 0 == reid.type)
16072     {
16073       errmsg ("missing params!");
16074       return -99;
16075     }
16076
16077   if (leid.type != reid.type)
16078     {
16079       errmsg ("remote and local EIDs are of different types!");
16080       return -99;
16081     }
16082
16083   M (ONE_ADD_DEL_ADJACENCY, mp);
16084   mp->is_add = is_add;
16085   mp->vni = htonl (vni);
16086   lisp_eid_put_vat (&mp->leid, &leid);
16087   lisp_eid_put_vat (&mp->reid, &reid);
16088
16089   /* send it... */
16090   S (mp);
16091
16092   /* Wait for a reply... */
16093   W (ret);
16094   return ret;
16095 }
16096
16097 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
16098
16099 uword
16100 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
16101 {
16102   u32 *mode = va_arg (*args, u32 *);
16103
16104   if (unformat (input, "lisp"))
16105     *mode = 0;
16106   else if (unformat (input, "vxlan"))
16107     *mode = 1;
16108   else
16109     return 0;
16110
16111   return 1;
16112 }
16113
16114 static int
16115 api_gpe_get_encap_mode (vat_main_t * vam)
16116 {
16117   vl_api_gpe_get_encap_mode_t *mp;
16118   int ret;
16119
16120   /* Construct the API message */
16121   M (GPE_GET_ENCAP_MODE, mp);
16122
16123   /* send it... */
16124   S (mp);
16125
16126   /* Wait for a reply... */
16127   W (ret);
16128   return ret;
16129 }
16130
16131 static int
16132 api_gpe_set_encap_mode (vat_main_t * vam)
16133 {
16134   unformat_input_t *input = vam->input;
16135   vl_api_gpe_set_encap_mode_t *mp;
16136   int ret;
16137   u32 mode = 0;
16138
16139   /* Parse args required to build the message */
16140   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16141     {
16142       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
16143         ;
16144       else
16145         break;
16146     }
16147
16148   /* Construct the API message */
16149   M (GPE_SET_ENCAP_MODE, mp);
16150
16151   mp->is_vxlan = mode;
16152
16153   /* send it... */
16154   S (mp);
16155
16156   /* Wait for a reply... */
16157   W (ret);
16158   return ret;
16159 }
16160
16161 static int
16162 api_lisp_gpe_add_del_iface (vat_main_t * vam)
16163 {
16164   unformat_input_t *input = vam->input;
16165   vl_api_gpe_add_del_iface_t *mp;
16166   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
16167   u32 dp_table = 0, vni = 0;
16168   int ret;
16169
16170   /* Parse args required to build the message */
16171   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16172     {
16173       if (unformat (input, "up"))
16174         {
16175           action_set = 1;
16176           is_add = 1;
16177         }
16178       else if (unformat (input, "down"))
16179         {
16180           action_set = 1;
16181           is_add = 0;
16182         }
16183       else if (unformat (input, "table_id %d", &dp_table))
16184         {
16185           dp_table_set = 1;
16186         }
16187       else if (unformat (input, "bd_id %d", &dp_table))
16188         {
16189           dp_table_set = 1;
16190           is_l2 = 1;
16191         }
16192       else if (unformat (input, "vni %d", &vni))
16193         {
16194           vni_set = 1;
16195         }
16196       else
16197         break;
16198     }
16199
16200   if (action_set == 0)
16201     {
16202       errmsg ("Action not set");
16203       return -99;
16204     }
16205   if (dp_table_set == 0 || vni_set == 0)
16206     {
16207       errmsg ("vni and dp_table must be set");
16208       return -99;
16209     }
16210
16211   /* Construct the API message */
16212   M (GPE_ADD_DEL_IFACE, mp);
16213
16214   mp->is_add = is_add;
16215   mp->dp_table = clib_host_to_net_u32 (dp_table);
16216   mp->is_l2 = is_l2;
16217   mp->vni = clib_host_to_net_u32 (vni);
16218
16219   /* send it... */
16220   S (mp);
16221
16222   /* Wait for a reply... */
16223   W (ret);
16224   return ret;
16225 }
16226
16227 static int
16228 api_one_map_register_fallback_threshold (vat_main_t * vam)
16229 {
16230   unformat_input_t *input = vam->input;
16231   vl_api_one_map_register_fallback_threshold_t *mp;
16232   u32 value = 0;
16233   u8 is_set = 0;
16234   int ret;
16235
16236   /* Parse args required to build the message */
16237   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16238     {
16239       if (unformat (input, "%u", &value))
16240         is_set = 1;
16241       else
16242         {
16243           clib_warning ("parse error '%U'", format_unformat_error, input);
16244           return -99;
16245         }
16246     }
16247
16248   if (!is_set)
16249     {
16250       errmsg ("fallback threshold value is missing!");
16251       return -99;
16252     }
16253
16254   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16255   mp->value = clib_host_to_net_u32 (value);
16256
16257   /* send it... */
16258   S (mp);
16259
16260   /* Wait for a reply... */
16261   W (ret);
16262   return ret;
16263 }
16264
16265 static int
16266 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
16267 {
16268   vl_api_show_one_map_register_fallback_threshold_t *mp;
16269   int ret;
16270
16271   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16272
16273   /* send it... */
16274   S (mp);
16275
16276   /* Wait for a reply... */
16277   W (ret);
16278   return ret;
16279 }
16280
16281 uword
16282 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
16283 {
16284   u32 *proto = va_arg (*args, u32 *);
16285
16286   if (unformat (input, "udp"))
16287     *proto = 1;
16288   else if (unformat (input, "api"))
16289     *proto = 2;
16290   else
16291     return 0;
16292
16293   return 1;
16294 }
16295
16296 static int
16297 api_one_set_transport_protocol (vat_main_t * vam)
16298 {
16299   unformat_input_t *input = vam->input;
16300   vl_api_one_set_transport_protocol_t *mp;
16301   u8 is_set = 0;
16302   u32 protocol = 0;
16303   int ret;
16304
16305   /* Parse args required to build the message */
16306   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16307     {
16308       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
16309         is_set = 1;
16310       else
16311         {
16312           clib_warning ("parse error '%U'", format_unformat_error, input);
16313           return -99;
16314         }
16315     }
16316
16317   if (!is_set)
16318     {
16319       errmsg ("Transport protocol missing!");
16320       return -99;
16321     }
16322
16323   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
16324   mp->protocol = (u8) protocol;
16325
16326   /* send it... */
16327   S (mp);
16328
16329   /* Wait for a reply... */
16330   W (ret);
16331   return ret;
16332 }
16333
16334 static int
16335 api_one_get_transport_protocol (vat_main_t * vam)
16336 {
16337   vl_api_one_get_transport_protocol_t *mp;
16338   int ret;
16339
16340   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
16341
16342   /* send it... */
16343   S (mp);
16344
16345   /* Wait for a reply... */
16346   W (ret);
16347   return ret;
16348 }
16349
16350 static int
16351 api_one_map_register_set_ttl (vat_main_t * vam)
16352 {
16353   unformat_input_t *input = vam->input;
16354   vl_api_one_map_register_set_ttl_t *mp;
16355   u32 ttl = 0;
16356   u8 is_set = 0;
16357   int ret;
16358
16359   /* Parse args required to build the message */
16360   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16361     {
16362       if (unformat (input, "%u", &ttl))
16363         is_set = 1;
16364       else
16365         {
16366           clib_warning ("parse error '%U'", format_unformat_error, input);
16367           return -99;
16368         }
16369     }
16370
16371   if (!is_set)
16372     {
16373       errmsg ("TTL value missing!");
16374       return -99;
16375     }
16376
16377   M (ONE_MAP_REGISTER_SET_TTL, mp);
16378   mp->ttl = clib_host_to_net_u32 (ttl);
16379
16380   /* send it... */
16381   S (mp);
16382
16383   /* Wait for a reply... */
16384   W (ret);
16385   return ret;
16386 }
16387
16388 static int
16389 api_show_one_map_register_ttl (vat_main_t * vam)
16390 {
16391   vl_api_show_one_map_register_ttl_t *mp;
16392   int ret;
16393
16394   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
16395
16396   /* send it... */
16397   S (mp);
16398
16399   /* Wait for a reply... */
16400   W (ret);
16401   return ret;
16402 }
16403
16404 /**
16405  * Add/del map request itr rlocs from ONE control plane and updates
16406  *
16407  * @param vam vpp API test context
16408  * @return return code
16409  */
16410 static int
16411 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
16412 {
16413   unformat_input_t *input = vam->input;
16414   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
16415   u8 *locator_set_name = 0;
16416   u8 locator_set_name_set = 0;
16417   u8 is_add = 1;
16418   int ret;
16419
16420   /* Parse args required to build the message */
16421   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16422     {
16423       if (unformat (input, "del"))
16424         {
16425           is_add = 0;
16426         }
16427       else if (unformat (input, "%_%v%_", &locator_set_name))
16428         {
16429           locator_set_name_set = 1;
16430         }
16431       else
16432         {
16433           clib_warning ("parse error '%U'", format_unformat_error, input);
16434           return -99;
16435         }
16436     }
16437
16438   if (is_add && !locator_set_name_set)
16439     {
16440       errmsg ("itr-rloc is not set!");
16441       return -99;
16442     }
16443
16444   if (is_add && vec_len (locator_set_name) > 64)
16445     {
16446       errmsg ("itr-rloc locator-set name too long");
16447       vec_free (locator_set_name);
16448       return -99;
16449     }
16450
16451   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
16452   mp->is_add = is_add;
16453   if (is_add)
16454     {
16455       clib_memcpy (mp->locator_set_name, locator_set_name,
16456                    vec_len (locator_set_name));
16457     }
16458   else
16459     {
16460       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
16461     }
16462   vec_free (locator_set_name);
16463
16464   /* send it... */
16465   S (mp);
16466
16467   /* Wait for a reply... */
16468   W (ret);
16469   return ret;
16470 }
16471
16472 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
16473
16474 static int
16475 api_one_locator_dump (vat_main_t * vam)
16476 {
16477   unformat_input_t *input = vam->input;
16478   vl_api_one_locator_dump_t *mp;
16479   vl_api_control_ping_t *mp_ping;
16480   u8 is_index_set = 0, is_name_set = 0;
16481   u8 *ls_name = 0;
16482   u32 ls_index = ~0;
16483   int ret;
16484
16485   /* Parse args required to build the message */
16486   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16487     {
16488       if (unformat (input, "ls_name %_%v%_", &ls_name))
16489         {
16490           is_name_set = 1;
16491         }
16492       else if (unformat (input, "ls_index %d", &ls_index))
16493         {
16494           is_index_set = 1;
16495         }
16496       else
16497         {
16498           errmsg ("parse error '%U'", format_unformat_error, input);
16499           return -99;
16500         }
16501     }
16502
16503   if (!is_index_set && !is_name_set)
16504     {
16505       errmsg ("error: expected one of index or name!");
16506       return -99;
16507     }
16508
16509   if (is_index_set && is_name_set)
16510     {
16511       errmsg ("error: only one param expected!");
16512       return -99;
16513     }
16514
16515   if (vec_len (ls_name) > 62)
16516     {
16517       errmsg ("error: locator set name too long!");
16518       return -99;
16519     }
16520
16521   if (!vam->json_output)
16522     {
16523       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
16524     }
16525
16526   M (ONE_LOCATOR_DUMP, mp);
16527   mp->is_index_set = is_index_set;
16528
16529   if (is_index_set)
16530     mp->ls_index = clib_host_to_net_u32 (ls_index);
16531   else
16532     {
16533       vec_add1 (ls_name, 0);
16534       strncpy ((char *) mp->ls_name, (char *) ls_name,
16535                sizeof (mp->ls_name) - 1);
16536     }
16537
16538   /* send it... */
16539   S (mp);
16540
16541   /* Use a control ping for synchronization */
16542   MPING (CONTROL_PING, mp_ping);
16543   S (mp_ping);
16544
16545   /* Wait for a reply... */
16546   W (ret);
16547   return ret;
16548 }
16549
16550 #define api_lisp_locator_dump api_one_locator_dump
16551
16552 static int
16553 api_one_locator_set_dump (vat_main_t * vam)
16554 {
16555   vl_api_one_locator_set_dump_t *mp;
16556   vl_api_control_ping_t *mp_ping;
16557   unformat_input_t *input = vam->input;
16558   u8 filter = 0;
16559   int ret;
16560
16561   /* Parse args required to build the message */
16562   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16563     {
16564       if (unformat (input, "local"))
16565         {
16566           filter = 1;
16567         }
16568       else if (unformat (input, "remote"))
16569         {
16570           filter = 2;
16571         }
16572       else
16573         {
16574           errmsg ("parse error '%U'", format_unformat_error, input);
16575           return -99;
16576         }
16577     }
16578
16579   if (!vam->json_output)
16580     {
16581       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
16582     }
16583
16584   M (ONE_LOCATOR_SET_DUMP, mp);
16585
16586   mp->filter = filter;
16587
16588   /* send it... */
16589   S (mp);
16590
16591   /* Use a control ping for synchronization */
16592   MPING (CONTROL_PING, mp_ping);
16593   S (mp_ping);
16594
16595   /* Wait for a reply... */
16596   W (ret);
16597   return ret;
16598 }
16599
16600 #define api_lisp_locator_set_dump api_one_locator_set_dump
16601
16602 static int
16603 api_one_eid_table_map_dump (vat_main_t * vam)
16604 {
16605   u8 is_l2 = 0;
16606   u8 mode_set = 0;
16607   unformat_input_t *input = vam->input;
16608   vl_api_one_eid_table_map_dump_t *mp;
16609   vl_api_control_ping_t *mp_ping;
16610   int ret;
16611
16612   /* Parse args required to build the message */
16613   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16614     {
16615       if (unformat (input, "l2"))
16616         {
16617           is_l2 = 1;
16618           mode_set = 1;
16619         }
16620       else if (unformat (input, "l3"))
16621         {
16622           is_l2 = 0;
16623           mode_set = 1;
16624         }
16625       else
16626         {
16627           errmsg ("parse error '%U'", format_unformat_error, input);
16628           return -99;
16629         }
16630     }
16631
16632   if (!mode_set)
16633     {
16634       errmsg ("expected one of 'l2' or 'l3' parameter!");
16635       return -99;
16636     }
16637
16638   if (!vam->json_output)
16639     {
16640       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
16641     }
16642
16643   M (ONE_EID_TABLE_MAP_DUMP, mp);
16644   mp->is_l2 = is_l2;
16645
16646   /* send it... */
16647   S (mp);
16648
16649   /* Use a control ping for synchronization */
16650   MPING (CONTROL_PING, mp_ping);
16651   S (mp_ping);
16652
16653   /* Wait for a reply... */
16654   W (ret);
16655   return ret;
16656 }
16657
16658 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
16659
16660 static int
16661 api_one_eid_table_vni_dump (vat_main_t * vam)
16662 {
16663   vl_api_one_eid_table_vni_dump_t *mp;
16664   vl_api_control_ping_t *mp_ping;
16665   int ret;
16666
16667   if (!vam->json_output)
16668     {
16669       print (vam->ofp, "VNI");
16670     }
16671
16672   M (ONE_EID_TABLE_VNI_DUMP, mp);
16673
16674   /* send it... */
16675   S (mp);
16676
16677   /* Use a control ping for synchronization */
16678   MPING (CONTROL_PING, mp_ping);
16679   S (mp_ping);
16680
16681   /* Wait for a reply... */
16682   W (ret);
16683   return ret;
16684 }
16685
16686 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
16687
16688 static int
16689 api_one_eid_table_dump (vat_main_t * vam)
16690 {
16691   unformat_input_t *i = vam->input;
16692   vl_api_one_eid_table_dump_t *mp;
16693   vl_api_control_ping_t *mp_ping;
16694   u8 filter = 0;
16695   int ret;
16696   u32 vni, t = 0;
16697   lisp_eid_vat_t eid;
16698   u8 eid_set = 0;
16699
16700   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16701     {
16702       if (unformat
16703           (i, "eid %U/%d", unformat_ip46_address, &eid.addr.ip, &eid.len))
16704         {
16705           eid_set = 1;
16706           eid.type = 0;
16707         }
16708       else
16709         if (unformat (i, "eid %U", unformat_ethernet_address, &eid.addr.mac))
16710         {
16711           eid_set = 1;
16712           eid.type = 1;
16713         }
16714       else if (unformat (i, "eid %U", unformat_nsh_address, &eid.addr.nsh))
16715         {
16716           eid_set = 1;
16717           eid.type = 2;
16718         }
16719       else if (unformat (i, "vni %d", &t))
16720         {
16721           vni = t;
16722         }
16723       else if (unformat (i, "local"))
16724         {
16725           filter = 1;
16726         }
16727       else if (unformat (i, "remote"))
16728         {
16729           filter = 2;
16730         }
16731       else
16732         {
16733           errmsg ("parse error '%U'", format_unformat_error, i);
16734           return -99;
16735         }
16736     }
16737
16738   if (!vam->json_output)
16739     {
16740       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
16741              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
16742     }
16743
16744   M (ONE_EID_TABLE_DUMP, mp);
16745
16746   mp->filter = filter;
16747   if (eid_set)
16748     {
16749       mp->eid_set = 1;
16750       mp->vni = htonl (vni);
16751       lisp_eid_put_vat (&mp->eid, &eid);
16752     }
16753
16754   /* send it... */
16755   S (mp);
16756
16757   /* Use a control ping for synchronization */
16758   MPING (CONTROL_PING, mp_ping);
16759   S (mp_ping);
16760
16761   /* Wait for a reply... */
16762   W (ret);
16763   return ret;
16764 }
16765
16766 #define api_lisp_eid_table_dump api_one_eid_table_dump
16767
16768 static int
16769 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
16770 {
16771   unformat_input_t *i = vam->input;
16772   vl_api_gpe_fwd_entries_get_t *mp;
16773   u8 vni_set = 0;
16774   u32 vni = ~0;
16775   int ret;
16776
16777   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16778     {
16779       if (unformat (i, "vni %d", &vni))
16780         {
16781           vni_set = 1;
16782         }
16783       else
16784         {
16785           errmsg ("parse error '%U'", format_unformat_error, i);
16786           return -99;
16787         }
16788     }
16789
16790   if (!vni_set)
16791     {
16792       errmsg ("vni not set!");
16793       return -99;
16794     }
16795
16796   if (!vam->json_output)
16797     {
16798       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
16799              "leid", "reid");
16800     }
16801
16802   M (GPE_FWD_ENTRIES_GET, mp);
16803   mp->vni = clib_host_to_net_u32 (vni);
16804
16805   /* send it... */
16806   S (mp);
16807
16808   /* Wait for a reply... */
16809   W (ret);
16810   return ret;
16811 }
16812
16813 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
16814 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
16815 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
16816 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
16817 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
16818 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
16819 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
16820 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
16821
16822 static int
16823 api_one_adjacencies_get (vat_main_t * vam)
16824 {
16825   unformat_input_t *i = vam->input;
16826   vl_api_one_adjacencies_get_t *mp;
16827   u8 vni_set = 0;
16828   u32 vni = ~0;
16829   int ret;
16830
16831   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16832     {
16833       if (unformat (i, "vni %d", &vni))
16834         {
16835           vni_set = 1;
16836         }
16837       else
16838         {
16839           errmsg ("parse error '%U'", format_unformat_error, i);
16840           return -99;
16841         }
16842     }
16843
16844   if (!vni_set)
16845     {
16846       errmsg ("vni not set!");
16847       return -99;
16848     }
16849
16850   if (!vam->json_output)
16851     {
16852       print (vam->ofp, "%s %40s", "leid", "reid");
16853     }
16854
16855   M (ONE_ADJACENCIES_GET, mp);
16856   mp->vni = clib_host_to_net_u32 (vni);
16857
16858   /* send it... */
16859   S (mp);
16860
16861   /* Wait for a reply... */
16862   W (ret);
16863   return ret;
16864 }
16865
16866 #define api_lisp_adjacencies_get api_one_adjacencies_get
16867
16868 static int
16869 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
16870 {
16871   unformat_input_t *i = vam->input;
16872   vl_api_gpe_native_fwd_rpaths_get_t *mp;
16873   int ret;
16874   u8 ip_family_set = 0, is_ip4 = 1;
16875
16876   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16877     {
16878       if (unformat (i, "ip4"))
16879         {
16880           ip_family_set = 1;
16881           is_ip4 = 1;
16882         }
16883       else if (unformat (i, "ip6"))
16884         {
16885           ip_family_set = 1;
16886           is_ip4 = 0;
16887         }
16888       else
16889         {
16890           errmsg ("parse error '%U'", format_unformat_error, i);
16891           return -99;
16892         }
16893     }
16894
16895   if (!ip_family_set)
16896     {
16897       errmsg ("ip family not set!");
16898       return -99;
16899     }
16900
16901   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
16902   mp->is_ip4 = is_ip4;
16903
16904   /* send it... */
16905   S (mp);
16906
16907   /* Wait for a reply... */
16908   W (ret);
16909   return ret;
16910 }
16911
16912 static int
16913 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
16914 {
16915   vl_api_gpe_fwd_entry_vnis_get_t *mp;
16916   int ret;
16917
16918   if (!vam->json_output)
16919     {
16920       print (vam->ofp, "VNIs");
16921     }
16922
16923   M (GPE_FWD_ENTRY_VNIS_GET, mp);
16924
16925   /* send it... */
16926   S (mp);
16927
16928   /* Wait for a reply... */
16929   W (ret);
16930   return ret;
16931 }
16932
16933 static int
16934 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
16935 {
16936   unformat_input_t *i = vam->input;
16937   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
16938   int ret = 0;
16939   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
16940   struct in_addr ip4;
16941   struct in6_addr ip6;
16942   u32 table_id = 0, nh_sw_if_index = ~0;
16943
16944   clib_memset (&ip4, 0, sizeof (ip4));
16945   clib_memset (&ip6, 0, sizeof (ip6));
16946
16947   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16948     {
16949       if (unformat (i, "del"))
16950         is_add = 0;
16951       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
16952                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16953         {
16954           ip_set = 1;
16955           is_ip4 = 1;
16956         }
16957       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
16958                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16959         {
16960           ip_set = 1;
16961           is_ip4 = 0;
16962         }
16963       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
16964         {
16965           ip_set = 1;
16966           is_ip4 = 1;
16967           nh_sw_if_index = ~0;
16968         }
16969       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
16970         {
16971           ip_set = 1;
16972           is_ip4 = 0;
16973           nh_sw_if_index = ~0;
16974         }
16975       else if (unformat (i, "table %d", &table_id))
16976         ;
16977       else
16978         {
16979           errmsg ("parse error '%U'", format_unformat_error, i);
16980           return -99;
16981         }
16982     }
16983
16984   if (!ip_set)
16985     {
16986       errmsg ("nh addr not set!");
16987       return -99;
16988     }
16989
16990   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
16991   mp->is_add = is_add;
16992   mp->table_id = clib_host_to_net_u32 (table_id);
16993   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
16994   mp->nh_addr.af = is_ip4 ? 0 : 1;
16995   if (is_ip4)
16996     clib_memcpy (mp->nh_addr.un.ip4, &ip4, sizeof (ip4));
16997   else
16998     clib_memcpy (mp->nh_addr.un.ip6, &ip6, sizeof (ip6));
16999
17000   /* send it... */
17001   S (mp);
17002
17003   /* Wait for a reply... */
17004   W (ret);
17005   return ret;
17006 }
17007
17008 static int
17009 api_one_map_server_dump (vat_main_t * vam)
17010 {
17011   vl_api_one_map_server_dump_t *mp;
17012   vl_api_control_ping_t *mp_ping;
17013   int ret;
17014
17015   if (!vam->json_output)
17016     {
17017       print (vam->ofp, "%=20s", "Map server");
17018     }
17019
17020   M (ONE_MAP_SERVER_DUMP, mp);
17021   /* send it... */
17022   S (mp);
17023
17024   /* Use a control ping for synchronization */
17025   MPING (CONTROL_PING, mp_ping);
17026   S (mp_ping);
17027
17028   /* Wait for a reply... */
17029   W (ret);
17030   return ret;
17031 }
17032
17033 #define api_lisp_map_server_dump api_one_map_server_dump
17034
17035 static int
17036 api_one_map_resolver_dump (vat_main_t * vam)
17037 {
17038   vl_api_one_map_resolver_dump_t *mp;
17039   vl_api_control_ping_t *mp_ping;
17040   int ret;
17041
17042   if (!vam->json_output)
17043     {
17044       print (vam->ofp, "%=20s", "Map resolver");
17045     }
17046
17047   M (ONE_MAP_RESOLVER_DUMP, mp);
17048   /* send it... */
17049   S (mp);
17050
17051   /* Use a control ping for synchronization */
17052   MPING (CONTROL_PING, mp_ping);
17053   S (mp_ping);
17054
17055   /* Wait for a reply... */
17056   W (ret);
17057   return ret;
17058 }
17059
17060 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
17061
17062 static int
17063 api_one_stats_flush (vat_main_t * vam)
17064 {
17065   vl_api_one_stats_flush_t *mp;
17066   int ret = 0;
17067
17068   M (ONE_STATS_FLUSH, mp);
17069   S (mp);
17070   W (ret);
17071   return ret;
17072 }
17073
17074 static int
17075 api_one_stats_dump (vat_main_t * vam)
17076 {
17077   vl_api_one_stats_dump_t *mp;
17078   vl_api_control_ping_t *mp_ping;
17079   int ret;
17080
17081   M (ONE_STATS_DUMP, mp);
17082   /* send it... */
17083   S (mp);
17084
17085   /* Use a control ping for synchronization */
17086   MPING (CONTROL_PING, mp_ping);
17087   S (mp_ping);
17088
17089   /* Wait for a reply... */
17090   W (ret);
17091   return ret;
17092 }
17093
17094 static int
17095 api_show_one_status (vat_main_t * vam)
17096 {
17097   vl_api_show_one_status_t *mp;
17098   int ret;
17099
17100   if (!vam->json_output)
17101     {
17102       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
17103     }
17104
17105   M (SHOW_ONE_STATUS, mp);
17106   /* send it... */
17107   S (mp);
17108   /* Wait for a reply... */
17109   W (ret);
17110   return ret;
17111 }
17112
17113 #define api_show_lisp_status api_show_one_status
17114
17115 static int
17116 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
17117 {
17118   vl_api_gpe_fwd_entry_path_dump_t *mp;
17119   vl_api_control_ping_t *mp_ping;
17120   unformat_input_t *i = vam->input;
17121   u32 fwd_entry_index = ~0;
17122   int ret;
17123
17124   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17125     {
17126       if (unformat (i, "index %d", &fwd_entry_index))
17127         ;
17128       else
17129         break;
17130     }
17131
17132   if (~0 == fwd_entry_index)
17133     {
17134       errmsg ("no index specified!");
17135       return -99;
17136     }
17137
17138   if (!vam->json_output)
17139     {
17140       print (vam->ofp, "first line");
17141     }
17142
17143   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
17144
17145   /* send it... */
17146   S (mp);
17147   /* Use a control ping for synchronization */
17148   MPING (CONTROL_PING, mp_ping);
17149   S (mp_ping);
17150
17151   /* Wait for a reply... */
17152   W (ret);
17153   return ret;
17154 }
17155
17156 static int
17157 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
17158 {
17159   vl_api_one_get_map_request_itr_rlocs_t *mp;
17160   int ret;
17161
17162   if (!vam->json_output)
17163     {
17164       print (vam->ofp, "%=20s", "itr-rlocs:");
17165     }
17166
17167   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
17168   /* send it... */
17169   S (mp);
17170   /* Wait for a reply... */
17171   W (ret);
17172   return ret;
17173 }
17174
17175 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
17176
17177 static int
17178 api_af_packet_create (vat_main_t * vam)
17179 {
17180   unformat_input_t *i = vam->input;
17181   vl_api_af_packet_create_t *mp;
17182   u8 *host_if_name = 0;
17183   u8 hw_addr[6];
17184   u8 random_hw_addr = 1;
17185   int ret;
17186
17187   clib_memset (hw_addr, 0, sizeof (hw_addr));
17188
17189   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17190     {
17191       if (unformat (i, "name %s", &host_if_name))
17192         vec_add1 (host_if_name, 0);
17193       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17194         random_hw_addr = 0;
17195       else
17196         break;
17197     }
17198
17199   if (!vec_len (host_if_name))
17200     {
17201       errmsg ("host-interface name must be specified");
17202       return -99;
17203     }
17204
17205   if (vec_len (host_if_name) > 64)
17206     {
17207       errmsg ("host-interface name too long");
17208       return -99;
17209     }
17210
17211   M (AF_PACKET_CREATE, mp);
17212
17213   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17214   clib_memcpy (mp->hw_addr, hw_addr, 6);
17215   mp->use_random_hw_addr = random_hw_addr;
17216   vec_free (host_if_name);
17217
17218   S (mp);
17219
17220   /* *INDENT-OFF* */
17221   W2 (ret,
17222       ({
17223         if (ret == 0)
17224           fprintf (vam->ofp ? vam->ofp : stderr,
17225                    " new sw_if_index = %d\n", vam->sw_if_index);
17226       }));
17227   /* *INDENT-ON* */
17228   return ret;
17229 }
17230
17231 static int
17232 api_af_packet_delete (vat_main_t * vam)
17233 {
17234   unformat_input_t *i = vam->input;
17235   vl_api_af_packet_delete_t *mp;
17236   u8 *host_if_name = 0;
17237   int ret;
17238
17239   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17240     {
17241       if (unformat (i, "name %s", &host_if_name))
17242         vec_add1 (host_if_name, 0);
17243       else
17244         break;
17245     }
17246
17247   if (!vec_len (host_if_name))
17248     {
17249       errmsg ("host-interface name must be specified");
17250       return -99;
17251     }
17252
17253   if (vec_len (host_if_name) > 64)
17254     {
17255       errmsg ("host-interface name too long");
17256       return -99;
17257     }
17258
17259   M (AF_PACKET_DELETE, mp);
17260
17261   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17262   vec_free (host_if_name);
17263
17264   S (mp);
17265   W (ret);
17266   return ret;
17267 }
17268
17269 static void vl_api_af_packet_details_t_handler
17270   (vl_api_af_packet_details_t * mp)
17271 {
17272   vat_main_t *vam = &vat_main;
17273
17274   print (vam->ofp, "%-16s %d",
17275          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
17276 }
17277
17278 static void vl_api_af_packet_details_t_handler_json
17279   (vl_api_af_packet_details_t * mp)
17280 {
17281   vat_main_t *vam = &vat_main;
17282   vat_json_node_t *node = NULL;
17283
17284   if (VAT_JSON_ARRAY != vam->json_tree.type)
17285     {
17286       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17287       vat_json_init_array (&vam->json_tree);
17288     }
17289   node = vat_json_array_add (&vam->json_tree);
17290
17291   vat_json_init_object (node);
17292   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17293   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
17294 }
17295
17296 static int
17297 api_af_packet_dump (vat_main_t * vam)
17298 {
17299   vl_api_af_packet_dump_t *mp;
17300   vl_api_control_ping_t *mp_ping;
17301   int ret;
17302
17303   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
17304   /* Get list of tap interfaces */
17305   M (AF_PACKET_DUMP, mp);
17306   S (mp);
17307
17308   /* Use a control ping for synchronization */
17309   MPING (CONTROL_PING, mp_ping);
17310   S (mp_ping);
17311
17312   W (ret);
17313   return ret;
17314 }
17315
17316 static int
17317 api_policer_add_del (vat_main_t * vam)
17318 {
17319   unformat_input_t *i = vam->input;
17320   vl_api_policer_add_del_t *mp;
17321   u8 is_add = 1;
17322   u8 *name = 0;
17323   u32 cir = 0;
17324   u32 eir = 0;
17325   u64 cb = 0;
17326   u64 eb = 0;
17327   u8 rate_type = 0;
17328   u8 round_type = 0;
17329   u8 type = 0;
17330   u8 color_aware = 0;
17331   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
17332   int ret;
17333
17334   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
17335   conform_action.dscp = 0;
17336   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
17337   exceed_action.dscp = 0;
17338   violate_action.action_type = SSE2_QOS_ACTION_DROP;
17339   violate_action.dscp = 0;
17340
17341   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17342     {
17343       if (unformat (i, "del"))
17344         is_add = 0;
17345       else if (unformat (i, "name %s", &name))
17346         vec_add1 (name, 0);
17347       else if (unformat (i, "cir %u", &cir))
17348         ;
17349       else if (unformat (i, "eir %u", &eir))
17350         ;
17351       else if (unformat (i, "cb %u", &cb))
17352         ;
17353       else if (unformat (i, "eb %u", &eb))
17354         ;
17355       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
17356                          &rate_type))
17357         ;
17358       else if (unformat (i, "round_type %U", unformat_policer_round_type,
17359                          &round_type))
17360         ;
17361       else if (unformat (i, "type %U", unformat_policer_type, &type))
17362         ;
17363       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
17364                          &conform_action))
17365         ;
17366       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
17367                          &exceed_action))
17368         ;
17369       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
17370                          &violate_action))
17371         ;
17372       else if (unformat (i, "color-aware"))
17373         color_aware = 1;
17374       else
17375         break;
17376     }
17377
17378   if (!vec_len (name))
17379     {
17380       errmsg ("policer name must be specified");
17381       return -99;
17382     }
17383
17384   if (vec_len (name) > 64)
17385     {
17386       errmsg ("policer name too long");
17387       return -99;
17388     }
17389
17390   M (POLICER_ADD_DEL, mp);
17391
17392   clib_memcpy (mp->name, name, vec_len (name));
17393   vec_free (name);
17394   mp->is_add = is_add;
17395   mp->cir = ntohl (cir);
17396   mp->eir = ntohl (eir);
17397   mp->cb = clib_net_to_host_u64 (cb);
17398   mp->eb = clib_net_to_host_u64 (eb);
17399   mp->rate_type = rate_type;
17400   mp->round_type = round_type;
17401   mp->type = type;
17402   mp->conform_action.type = conform_action.action_type;
17403   mp->conform_action.dscp = conform_action.dscp;
17404   mp->exceed_action.type = exceed_action.action_type;
17405   mp->exceed_action.dscp = exceed_action.dscp;
17406   mp->violate_action.type = violate_action.action_type;
17407   mp->violate_action.dscp = violate_action.dscp;
17408   mp->color_aware = color_aware;
17409
17410   S (mp);
17411   W (ret);
17412   return ret;
17413 }
17414
17415 static int
17416 api_policer_dump (vat_main_t * vam)
17417 {
17418   unformat_input_t *i = vam->input;
17419   vl_api_policer_dump_t *mp;
17420   vl_api_control_ping_t *mp_ping;
17421   u8 *match_name = 0;
17422   u8 match_name_valid = 0;
17423   int ret;
17424
17425   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17426     {
17427       if (unformat (i, "name %s", &match_name))
17428         {
17429           vec_add1 (match_name, 0);
17430           match_name_valid = 1;
17431         }
17432       else
17433         break;
17434     }
17435
17436   M (POLICER_DUMP, mp);
17437   mp->match_name_valid = match_name_valid;
17438   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
17439   vec_free (match_name);
17440   /* send it... */
17441   S (mp);
17442
17443   /* Use a control ping for synchronization */
17444   MPING (CONTROL_PING, mp_ping);
17445   S (mp_ping);
17446
17447   /* Wait for a reply... */
17448   W (ret);
17449   return ret;
17450 }
17451
17452 static int
17453 api_policer_classify_set_interface (vat_main_t * vam)
17454 {
17455   unformat_input_t *i = vam->input;
17456   vl_api_policer_classify_set_interface_t *mp;
17457   u32 sw_if_index;
17458   int sw_if_index_set;
17459   u32 ip4_table_index = ~0;
17460   u32 ip6_table_index = ~0;
17461   u32 l2_table_index = ~0;
17462   u8 is_add = 1;
17463   int ret;
17464
17465   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17466     {
17467       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17468         sw_if_index_set = 1;
17469       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17470         sw_if_index_set = 1;
17471       else if (unformat (i, "del"))
17472         is_add = 0;
17473       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17474         ;
17475       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17476         ;
17477       else if (unformat (i, "l2-table %d", &l2_table_index))
17478         ;
17479       else
17480         {
17481           clib_warning ("parse error '%U'", format_unformat_error, i);
17482           return -99;
17483         }
17484     }
17485
17486   if (sw_if_index_set == 0)
17487     {
17488       errmsg ("missing interface name or sw_if_index");
17489       return -99;
17490     }
17491
17492   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
17493
17494   mp->sw_if_index = ntohl (sw_if_index);
17495   mp->ip4_table_index = ntohl (ip4_table_index);
17496   mp->ip6_table_index = ntohl (ip6_table_index);
17497   mp->l2_table_index = ntohl (l2_table_index);
17498   mp->is_add = is_add;
17499
17500   S (mp);
17501   W (ret);
17502   return ret;
17503 }
17504
17505 static int
17506 api_policer_classify_dump (vat_main_t * vam)
17507 {
17508   unformat_input_t *i = vam->input;
17509   vl_api_policer_classify_dump_t *mp;
17510   vl_api_control_ping_t *mp_ping;
17511   u8 type = POLICER_CLASSIFY_N_TABLES;
17512   int ret;
17513
17514   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
17515     ;
17516   else
17517     {
17518       errmsg ("classify table type must be specified");
17519       return -99;
17520     }
17521
17522   if (!vam->json_output)
17523     {
17524       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17525     }
17526
17527   M (POLICER_CLASSIFY_DUMP, mp);
17528   mp->type = type;
17529   /* send it... */
17530   S (mp);
17531
17532   /* Use a control ping for synchronization */
17533   MPING (CONTROL_PING, mp_ping);
17534   S (mp_ping);
17535
17536   /* Wait for a reply... */
17537   W (ret);
17538   return ret;
17539 }
17540
17541 static u8 *
17542 format_fib_api_path_nh_proto (u8 * s, va_list * args)
17543 {
17544   vl_api_fib_path_nh_proto_t proto =
17545     va_arg (*args, vl_api_fib_path_nh_proto_t);
17546
17547   switch (proto)
17548     {
17549     case FIB_API_PATH_NH_PROTO_IP4:
17550       s = format (s, "ip4");
17551       break;
17552     case FIB_API_PATH_NH_PROTO_IP6:
17553       s = format (s, "ip6");
17554       break;
17555     case FIB_API_PATH_NH_PROTO_MPLS:
17556       s = format (s, "mpls");
17557       break;
17558     case FIB_API_PATH_NH_PROTO_BIER:
17559       s = format (s, "bier");
17560       break;
17561     case FIB_API_PATH_NH_PROTO_ETHERNET:
17562       s = format (s, "ethernet");
17563       break;
17564     }
17565
17566   return (s);
17567 }
17568
17569 static u8 *
17570 format_vl_api_ip_address_union (u8 * s, va_list * args)
17571 {
17572   vl_api_address_family_t af = va_arg (*args, int);
17573   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
17574
17575   switch (af)
17576     {
17577     case ADDRESS_IP4:
17578       s = format (s, "%U", format_ip4_address, u->ip4);
17579       break;
17580     case ADDRESS_IP6:
17581       s = format (s, "%U", format_ip6_address, u->ip6);
17582       break;
17583     }
17584   return (s);
17585 }
17586
17587 static u8 *
17588 format_vl_api_fib_path_type (u8 * s, va_list * args)
17589 {
17590   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
17591
17592   switch (t)
17593     {
17594     case FIB_API_PATH_TYPE_NORMAL:
17595       s = format (s, "normal");
17596       break;
17597     case FIB_API_PATH_TYPE_LOCAL:
17598       s = format (s, "local");
17599       break;
17600     case FIB_API_PATH_TYPE_DROP:
17601       s = format (s, "drop");
17602       break;
17603     case FIB_API_PATH_TYPE_UDP_ENCAP:
17604       s = format (s, "udp-encap");
17605       break;
17606     case FIB_API_PATH_TYPE_BIER_IMP:
17607       s = format (s, "bier-imp");
17608       break;
17609     case FIB_API_PATH_TYPE_ICMP_UNREACH:
17610       s = format (s, "unreach");
17611       break;
17612     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
17613       s = format (s, "prohibit");
17614       break;
17615     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
17616       s = format (s, "src-lookup");
17617       break;
17618     case FIB_API_PATH_TYPE_DVR:
17619       s = format (s, "dvr");
17620       break;
17621     case FIB_API_PATH_TYPE_INTERFACE_RX:
17622       s = format (s, "interface-rx");
17623       break;
17624     case FIB_API_PATH_TYPE_CLASSIFY:
17625       s = format (s, "classify");
17626       break;
17627     }
17628
17629   return (s);
17630 }
17631
17632 static void
17633 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
17634 {
17635   print (vam->ofp,
17636          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
17637          ntohl (fp->weight), ntohl (fp->sw_if_index),
17638          format_vl_api_fib_path_type, fp->type,
17639          format_fib_api_path_nh_proto, fp->proto,
17640          format_vl_api_ip_address_union, &fp->nh.address);
17641 }
17642
17643 static void
17644 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
17645                                  vl_api_fib_path_t * fp)
17646 {
17647   struct in_addr ip4;
17648   struct in6_addr ip6;
17649
17650   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17651   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17652   vat_json_object_add_uint (node, "type", fp->type);
17653   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
17654   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
17655     {
17656       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
17657       vat_json_object_add_ip4 (node, "next_hop", ip4);
17658     }
17659   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP6)
17660     {
17661       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
17662       vat_json_object_add_ip6 (node, "next_hop", ip6);
17663     }
17664 }
17665
17666 static void
17667 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
17668 {
17669   vat_main_t *vam = &vat_main;
17670   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17671   vl_api_fib_path_t *fp;
17672   i32 i;
17673
17674   print (vam->ofp, "sw_if_index %d via:",
17675          ntohl (mp->mt_tunnel.mt_sw_if_index));
17676   fp = mp->mt_tunnel.mt_paths;
17677   for (i = 0; i < count; i++)
17678     {
17679       vl_api_fib_path_print (vam, fp);
17680       fp++;
17681     }
17682
17683   print (vam->ofp, "");
17684 }
17685
17686 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
17687 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
17688
17689 static void
17690 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
17691 {
17692   vat_main_t *vam = &vat_main;
17693   vat_json_node_t *node = NULL;
17694   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17695   vl_api_fib_path_t *fp;
17696   i32 i;
17697
17698   if (VAT_JSON_ARRAY != vam->json_tree.type)
17699     {
17700       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17701       vat_json_init_array (&vam->json_tree);
17702     }
17703   node = vat_json_array_add (&vam->json_tree);
17704
17705   vat_json_init_object (node);
17706   vat_json_object_add_uint (node, "sw_if_index",
17707                             ntohl (mp->mt_tunnel.mt_sw_if_index));
17708
17709   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
17710
17711   fp = mp->mt_tunnel.mt_paths;
17712   for (i = 0; i < count; i++)
17713     {
17714       vl_api_mpls_fib_path_json_print (node, fp);
17715       fp++;
17716     }
17717 }
17718
17719 static int
17720 api_mpls_tunnel_dump (vat_main_t * vam)
17721 {
17722   vl_api_mpls_tunnel_dump_t *mp;
17723   vl_api_control_ping_t *mp_ping;
17724   int ret;
17725
17726   M (MPLS_TUNNEL_DUMP, mp);
17727
17728   S (mp);
17729
17730   /* Use a control ping for synchronization */
17731   MPING (CONTROL_PING, mp_ping);
17732   S (mp_ping);
17733
17734   W (ret);
17735   return ret;
17736 }
17737
17738 #define vl_api_mpls_table_details_t_endian vl_noop_handler
17739 #define vl_api_mpls_table_details_t_print vl_noop_handler
17740
17741
17742 static void
17743 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
17744 {
17745   vat_main_t *vam = &vat_main;
17746
17747   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
17748 }
17749
17750 static void vl_api_mpls_table_details_t_handler_json
17751   (vl_api_mpls_table_details_t * mp)
17752 {
17753   vat_main_t *vam = &vat_main;
17754   vat_json_node_t *node = NULL;
17755
17756   if (VAT_JSON_ARRAY != vam->json_tree.type)
17757     {
17758       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17759       vat_json_init_array (&vam->json_tree);
17760     }
17761   node = vat_json_array_add (&vam->json_tree);
17762
17763   vat_json_init_object (node);
17764   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
17765 }
17766
17767 static int
17768 api_mpls_table_dump (vat_main_t * vam)
17769 {
17770   vl_api_mpls_table_dump_t *mp;
17771   vl_api_control_ping_t *mp_ping;
17772   int ret;
17773
17774   M (MPLS_TABLE_DUMP, mp);
17775   S (mp);
17776
17777   /* Use a control ping for synchronization */
17778   MPING (CONTROL_PING, mp_ping);
17779   S (mp_ping);
17780
17781   W (ret);
17782   return ret;
17783 }
17784
17785 #define vl_api_mpls_route_details_t_endian vl_noop_handler
17786 #define vl_api_mpls_route_details_t_print vl_noop_handler
17787
17788 static void
17789 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
17790 {
17791   vat_main_t *vam = &vat_main;
17792   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
17793   vl_api_fib_path_t *fp;
17794   int i;
17795
17796   print (vam->ofp,
17797          "table-id %d, label %u, ess_bit %u",
17798          ntohl (mp->mr_route.mr_table_id),
17799          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
17800   fp = mp->mr_route.mr_paths;
17801   for (i = 0; i < count; i++)
17802     {
17803       vl_api_fib_path_print (vam, fp);
17804       fp++;
17805     }
17806 }
17807
17808 static void vl_api_mpls_route_details_t_handler_json
17809   (vl_api_mpls_route_details_t * mp)
17810 {
17811   vat_main_t *vam = &vat_main;
17812   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
17813   vat_json_node_t *node = NULL;
17814   vl_api_fib_path_t *fp;
17815   int i;
17816
17817   if (VAT_JSON_ARRAY != vam->json_tree.type)
17818     {
17819       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17820       vat_json_init_array (&vam->json_tree);
17821     }
17822   node = vat_json_array_add (&vam->json_tree);
17823
17824   vat_json_init_object (node);
17825   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
17826   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
17827   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
17828   vat_json_object_add_uint (node, "path_count", count);
17829   fp = mp->mr_route.mr_paths;
17830   for (i = 0; i < count; i++)
17831     {
17832       vl_api_mpls_fib_path_json_print (node, fp);
17833       fp++;
17834     }
17835 }
17836
17837 static int
17838 api_mpls_route_dump (vat_main_t * vam)
17839 {
17840   unformat_input_t *input = vam->input;
17841   vl_api_mpls_route_dump_t *mp;
17842   vl_api_control_ping_t *mp_ping;
17843   u32 table_id;
17844   int ret;
17845
17846   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17847     {
17848       if (unformat (input, "table_id %d", &table_id))
17849         ;
17850       else
17851         break;
17852     }
17853   if (table_id == ~0)
17854     {
17855       errmsg ("missing table id");
17856       return -99;
17857     }
17858
17859   M (MPLS_ROUTE_DUMP, mp);
17860
17861   mp->table.mt_table_id = ntohl (table_id);
17862   S (mp);
17863
17864   /* Use a control ping for synchronization */
17865   MPING (CONTROL_PING, mp_ping);
17866   S (mp_ping);
17867
17868   W (ret);
17869   return ret;
17870 }
17871
17872 #define vl_api_ip_table_details_t_endian vl_noop_handler
17873 #define vl_api_ip_table_details_t_print vl_noop_handler
17874
17875 static void
17876 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
17877 {
17878   vat_main_t *vam = &vat_main;
17879
17880   print (vam->ofp,
17881          "%s; table-id %d, prefix %U/%d",
17882          mp->table.name, ntohl (mp->table.table_id));
17883 }
17884
17885
17886 static void vl_api_ip_table_details_t_handler_json
17887   (vl_api_ip_table_details_t * mp)
17888 {
17889   vat_main_t *vam = &vat_main;
17890   vat_json_node_t *node = NULL;
17891
17892   if (VAT_JSON_ARRAY != vam->json_tree.type)
17893     {
17894       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17895       vat_json_init_array (&vam->json_tree);
17896     }
17897   node = vat_json_array_add (&vam->json_tree);
17898
17899   vat_json_init_object (node);
17900   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
17901 }
17902
17903 static int
17904 api_ip_table_dump (vat_main_t * vam)
17905 {
17906   vl_api_ip_table_dump_t *mp;
17907   vl_api_control_ping_t *mp_ping;
17908   int ret;
17909
17910   M (IP_TABLE_DUMP, mp);
17911   S (mp);
17912
17913   /* Use a control ping for synchronization */
17914   MPING (CONTROL_PING, mp_ping);
17915   S (mp_ping);
17916
17917   W (ret);
17918   return ret;
17919 }
17920
17921 static int
17922 api_ip_mtable_dump (vat_main_t * vam)
17923 {
17924   vl_api_ip_mtable_dump_t *mp;
17925   vl_api_control_ping_t *mp_ping;
17926   int ret;
17927
17928   M (IP_MTABLE_DUMP, mp);
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 static int
17940 api_ip_mroute_dump (vat_main_t * vam)
17941 {
17942   unformat_input_t *input = vam->input;
17943   vl_api_control_ping_t *mp_ping;
17944   vl_api_ip_mroute_dump_t *mp;
17945   int ret, is_ip6;
17946   u32 table_id;
17947
17948   is_ip6 = 0;
17949   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17950     {
17951       if (unformat (input, "table_id %d", &table_id))
17952         ;
17953       else if (unformat (input, "ip6"))
17954         is_ip6 = 1;
17955       else if (unformat (input, "ip4"))
17956         is_ip6 = 0;
17957       else
17958         break;
17959     }
17960   if (table_id == ~0)
17961     {
17962       errmsg ("missing table id");
17963       return -99;
17964     }
17965
17966   M (IP_MROUTE_DUMP, mp);
17967   mp->table.table_id = table_id;
17968   mp->table.is_ip6 = is_ip6;
17969   S (mp);
17970
17971   /* Use a control ping for synchronization */
17972   MPING (CONTROL_PING, mp_ping);
17973   S (mp_ping);
17974
17975   W (ret);
17976   return ret;
17977 }
17978
17979 #define vl_api_ip_route_details_t_endian vl_noop_handler
17980 #define vl_api_ip_route_details_t_print vl_noop_handler
17981
17982 static void
17983 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
17984 {
17985   vat_main_t *vam = &vat_main;
17986   u8 count = mp->route.n_paths;
17987   vl_api_fib_path_t *fp;
17988   int i;
17989
17990   print (vam->ofp,
17991          "table-id %d, prefix %U/%d",
17992          ntohl (mp->route.table_id),
17993          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
17994   for (i = 0; i < count; i++)
17995     {
17996       fp = &mp->route.paths[i];
17997
17998       vl_api_fib_path_print (vam, fp);
17999       fp++;
18000     }
18001 }
18002
18003 static void vl_api_ip_route_details_t_handler_json
18004   (vl_api_ip_route_details_t * mp)
18005 {
18006   vat_main_t *vam = &vat_main;
18007   u8 count = mp->route.n_paths;
18008   vat_json_node_t *node = NULL;
18009   struct in_addr ip4;
18010   struct in6_addr ip6;
18011   vl_api_fib_path_t *fp;
18012   int i;
18013
18014   if (VAT_JSON_ARRAY != vam->json_tree.type)
18015     {
18016       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18017       vat_json_init_array (&vam->json_tree);
18018     }
18019   node = vat_json_array_add (&vam->json_tree);
18020
18021   vat_json_init_object (node);
18022   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
18023   if (ADDRESS_IP6 == mp->route.prefix.address.af)
18024     {
18025       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
18026       vat_json_object_add_ip6 (node, "prefix", ip6);
18027     }
18028   else
18029     {
18030       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
18031       vat_json_object_add_ip4 (node, "prefix", ip4);
18032     }
18033   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
18034   vat_json_object_add_uint (node, "path_count", count);
18035   for (i = 0; i < count; i++)
18036     {
18037       fp = &mp->route.paths[i];
18038       vl_api_mpls_fib_path_json_print (node, fp);
18039     }
18040 }
18041
18042 static int
18043 api_ip_route_dump (vat_main_t * vam)
18044 {
18045   unformat_input_t *input = vam->input;
18046   vl_api_ip_route_dump_t *mp;
18047   vl_api_control_ping_t *mp_ping;
18048   u32 table_id;
18049   u8 is_ip6;
18050   int ret;
18051
18052   is_ip6 = 0;
18053   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18054     {
18055       if (unformat (input, "table_id %d", &table_id))
18056         ;
18057       else if (unformat (input, "ip6"))
18058         is_ip6 = 1;
18059       else if (unformat (input, "ip4"))
18060         is_ip6 = 0;
18061       else
18062         break;
18063     }
18064   if (table_id == ~0)
18065     {
18066       errmsg ("missing table id");
18067       return -99;
18068     }
18069
18070   M (IP_ROUTE_DUMP, mp);
18071
18072   mp->table.table_id = table_id;
18073   mp->table.is_ip6 = is_ip6;
18074
18075   S (mp);
18076
18077   /* Use a control ping for synchronization */
18078   MPING (CONTROL_PING, mp_ping);
18079   S (mp_ping);
18080
18081   W (ret);
18082   return ret;
18083 }
18084
18085 int
18086 api_classify_table_ids (vat_main_t * vam)
18087 {
18088   vl_api_classify_table_ids_t *mp;
18089   int ret;
18090
18091   /* Construct the API message */
18092   M (CLASSIFY_TABLE_IDS, mp);
18093   mp->context = 0;
18094
18095   S (mp);
18096   W (ret);
18097   return ret;
18098 }
18099
18100 int
18101 api_classify_table_by_interface (vat_main_t * vam)
18102 {
18103   unformat_input_t *input = vam->input;
18104   vl_api_classify_table_by_interface_t *mp;
18105
18106   u32 sw_if_index = ~0;
18107   int ret;
18108   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18109     {
18110       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18111         ;
18112       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18113         ;
18114       else
18115         break;
18116     }
18117   if (sw_if_index == ~0)
18118     {
18119       errmsg ("missing interface name or sw_if_index");
18120       return -99;
18121     }
18122
18123   /* Construct the API message */
18124   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
18125   mp->context = 0;
18126   mp->sw_if_index = ntohl (sw_if_index);
18127
18128   S (mp);
18129   W (ret);
18130   return ret;
18131 }
18132
18133 int
18134 api_classify_table_info (vat_main_t * vam)
18135 {
18136   unformat_input_t *input = vam->input;
18137   vl_api_classify_table_info_t *mp;
18138
18139   u32 table_id = ~0;
18140   int ret;
18141   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18142     {
18143       if (unformat (input, "table_id %d", &table_id))
18144         ;
18145       else
18146         break;
18147     }
18148   if (table_id == ~0)
18149     {
18150       errmsg ("missing table id");
18151       return -99;
18152     }
18153
18154   /* Construct the API message */
18155   M (CLASSIFY_TABLE_INFO, mp);
18156   mp->context = 0;
18157   mp->table_id = ntohl (table_id);
18158
18159   S (mp);
18160   W (ret);
18161   return ret;
18162 }
18163
18164 int
18165 api_classify_session_dump (vat_main_t * vam)
18166 {
18167   unformat_input_t *input = vam->input;
18168   vl_api_classify_session_dump_t *mp;
18169   vl_api_control_ping_t *mp_ping;
18170
18171   u32 table_id = ~0;
18172   int ret;
18173   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18174     {
18175       if (unformat (input, "table_id %d", &table_id))
18176         ;
18177       else
18178         break;
18179     }
18180   if (table_id == ~0)
18181     {
18182       errmsg ("missing table id");
18183       return -99;
18184     }
18185
18186   /* Construct the API message */
18187   M (CLASSIFY_SESSION_DUMP, mp);
18188   mp->context = 0;
18189   mp->table_id = ntohl (table_id);
18190   S (mp);
18191
18192   /* Use a control ping for synchronization */
18193   MPING (CONTROL_PING, mp_ping);
18194   S (mp_ping);
18195
18196   W (ret);
18197   return ret;
18198 }
18199
18200 static void
18201 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
18202 {
18203   vat_main_t *vam = &vat_main;
18204
18205   print (vam->ofp, "collector_address %U, collector_port %d, "
18206          "src_address %U, vrf_id %d, path_mtu %u, "
18207          "template_interval %u, udp_checksum %d",
18208          format_ip4_address, mp->collector_address,
18209          ntohs (mp->collector_port),
18210          format_ip4_address, mp->src_address,
18211          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
18212          ntohl (mp->template_interval), mp->udp_checksum);
18213
18214   vam->retval = 0;
18215   vam->result_ready = 1;
18216 }
18217
18218 static void
18219   vl_api_ipfix_exporter_details_t_handler_json
18220   (vl_api_ipfix_exporter_details_t * mp)
18221 {
18222   vat_main_t *vam = &vat_main;
18223   vat_json_node_t node;
18224   struct in_addr collector_address;
18225   struct in_addr src_address;
18226
18227   vat_json_init_object (&node);
18228   clib_memcpy (&collector_address, &mp->collector_address,
18229                sizeof (collector_address));
18230   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
18231   vat_json_object_add_uint (&node, "collector_port",
18232                             ntohs (mp->collector_port));
18233   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
18234   vat_json_object_add_ip4 (&node, "src_address", src_address);
18235   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
18236   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
18237   vat_json_object_add_uint (&node, "template_interval",
18238                             ntohl (mp->template_interval));
18239   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
18240
18241   vat_json_print (vam->ofp, &node);
18242   vat_json_free (&node);
18243   vam->retval = 0;
18244   vam->result_ready = 1;
18245 }
18246
18247 int
18248 api_ipfix_exporter_dump (vat_main_t * vam)
18249 {
18250   vl_api_ipfix_exporter_dump_t *mp;
18251   int ret;
18252
18253   /* Construct the API message */
18254   M (IPFIX_EXPORTER_DUMP, mp);
18255   mp->context = 0;
18256
18257   S (mp);
18258   W (ret);
18259   return ret;
18260 }
18261
18262 static int
18263 api_ipfix_classify_stream_dump (vat_main_t * vam)
18264 {
18265   vl_api_ipfix_classify_stream_dump_t *mp;
18266   int ret;
18267
18268   /* Construct the API message */
18269   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
18270   mp->context = 0;
18271
18272   S (mp);
18273   W (ret);
18274   return ret;
18275   /* NOTREACHED */
18276   return 0;
18277 }
18278
18279 static void
18280   vl_api_ipfix_classify_stream_details_t_handler
18281   (vl_api_ipfix_classify_stream_details_t * mp)
18282 {
18283   vat_main_t *vam = &vat_main;
18284   print (vam->ofp, "domain_id %d, src_port %d",
18285          ntohl (mp->domain_id), ntohs (mp->src_port));
18286   vam->retval = 0;
18287   vam->result_ready = 1;
18288 }
18289
18290 static void
18291   vl_api_ipfix_classify_stream_details_t_handler_json
18292   (vl_api_ipfix_classify_stream_details_t * mp)
18293 {
18294   vat_main_t *vam = &vat_main;
18295   vat_json_node_t node;
18296
18297   vat_json_init_object (&node);
18298   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
18299   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
18300
18301   vat_json_print (vam->ofp, &node);
18302   vat_json_free (&node);
18303   vam->retval = 0;
18304   vam->result_ready = 1;
18305 }
18306
18307 static int
18308 api_ipfix_classify_table_dump (vat_main_t * vam)
18309 {
18310   vl_api_ipfix_classify_table_dump_t *mp;
18311   vl_api_control_ping_t *mp_ping;
18312   int ret;
18313
18314   if (!vam->json_output)
18315     {
18316       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
18317              "transport_protocol");
18318     }
18319
18320   /* Construct the API message */
18321   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
18322
18323   /* send it... */
18324   S (mp);
18325
18326   /* Use a control ping for synchronization */
18327   MPING (CONTROL_PING, mp_ping);
18328   S (mp_ping);
18329
18330   W (ret);
18331   return ret;
18332 }
18333
18334 static void
18335   vl_api_ipfix_classify_table_details_t_handler
18336   (vl_api_ipfix_classify_table_details_t * mp)
18337 {
18338   vat_main_t *vam = &vat_main;
18339   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
18340          mp->transport_protocol);
18341 }
18342
18343 static void
18344   vl_api_ipfix_classify_table_details_t_handler_json
18345   (vl_api_ipfix_classify_table_details_t * mp)
18346 {
18347   vat_json_node_t *node = NULL;
18348   vat_main_t *vam = &vat_main;
18349
18350   if (VAT_JSON_ARRAY != vam->json_tree.type)
18351     {
18352       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18353       vat_json_init_array (&vam->json_tree);
18354     }
18355
18356   node = vat_json_array_add (&vam->json_tree);
18357   vat_json_init_object (node);
18358
18359   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
18360   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
18361   vat_json_object_add_uint (node, "transport_protocol",
18362                             mp->transport_protocol);
18363 }
18364
18365 static int
18366 api_sw_interface_span_enable_disable (vat_main_t * vam)
18367 {
18368   unformat_input_t *i = vam->input;
18369   vl_api_sw_interface_span_enable_disable_t *mp;
18370   u32 src_sw_if_index = ~0;
18371   u32 dst_sw_if_index = ~0;
18372   u8 state = 3;
18373   int ret;
18374   u8 is_l2 = 0;
18375
18376   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18377     {
18378       if (unformat
18379           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
18380         ;
18381       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
18382         ;
18383       else
18384         if (unformat
18385             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
18386         ;
18387       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
18388         ;
18389       else if (unformat (i, "disable"))
18390         state = 0;
18391       else if (unformat (i, "rx"))
18392         state = 1;
18393       else if (unformat (i, "tx"))
18394         state = 2;
18395       else if (unformat (i, "both"))
18396         state = 3;
18397       else if (unformat (i, "l2"))
18398         is_l2 = 1;
18399       else
18400         break;
18401     }
18402
18403   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
18404
18405   mp->sw_if_index_from = htonl (src_sw_if_index);
18406   mp->sw_if_index_to = htonl (dst_sw_if_index);
18407   mp->state = state;
18408   mp->is_l2 = is_l2;
18409
18410   S (mp);
18411   W (ret);
18412   return ret;
18413 }
18414
18415 static void
18416 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
18417                                             * mp)
18418 {
18419   vat_main_t *vam = &vat_main;
18420   u8 *sw_if_from_name = 0;
18421   u8 *sw_if_to_name = 0;
18422   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18423   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18424   char *states[] = { "none", "rx", "tx", "both" };
18425   hash_pair_t *p;
18426
18427   /* *INDENT-OFF* */
18428   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18429   ({
18430     if ((u32) p->value[0] == sw_if_index_from)
18431       {
18432         sw_if_from_name = (u8 *)(p->key);
18433         if (sw_if_to_name)
18434           break;
18435       }
18436     if ((u32) p->value[0] == sw_if_index_to)
18437       {
18438         sw_if_to_name = (u8 *)(p->key);
18439         if (sw_if_from_name)
18440           break;
18441       }
18442   }));
18443   /* *INDENT-ON* */
18444   print (vam->ofp, "%20s => %20s (%s) %s",
18445          sw_if_from_name, sw_if_to_name, states[mp->state],
18446          mp->is_l2 ? "l2" : "device");
18447 }
18448
18449 static void
18450   vl_api_sw_interface_span_details_t_handler_json
18451   (vl_api_sw_interface_span_details_t * mp)
18452 {
18453   vat_main_t *vam = &vat_main;
18454   vat_json_node_t *node = NULL;
18455   u8 *sw_if_from_name = 0;
18456   u8 *sw_if_to_name = 0;
18457   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18458   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18459   hash_pair_t *p;
18460
18461   /* *INDENT-OFF* */
18462   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18463   ({
18464     if ((u32) p->value[0] == sw_if_index_from)
18465       {
18466         sw_if_from_name = (u8 *)(p->key);
18467         if (sw_if_to_name)
18468           break;
18469       }
18470     if ((u32) p->value[0] == sw_if_index_to)
18471       {
18472         sw_if_to_name = (u8 *)(p->key);
18473         if (sw_if_from_name)
18474           break;
18475       }
18476   }));
18477   /* *INDENT-ON* */
18478
18479   if (VAT_JSON_ARRAY != vam->json_tree.type)
18480     {
18481       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18482       vat_json_init_array (&vam->json_tree);
18483     }
18484   node = vat_json_array_add (&vam->json_tree);
18485
18486   vat_json_init_object (node);
18487   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
18488   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
18489   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
18490   if (0 != sw_if_to_name)
18491     {
18492       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
18493     }
18494   vat_json_object_add_uint (node, "state", mp->state);
18495   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
18496 }
18497
18498 static int
18499 api_sw_interface_span_dump (vat_main_t * vam)
18500 {
18501   unformat_input_t *input = vam->input;
18502   vl_api_sw_interface_span_dump_t *mp;
18503   vl_api_control_ping_t *mp_ping;
18504   u8 is_l2 = 0;
18505   int ret;
18506
18507   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18508     {
18509       if (unformat (input, "l2"))
18510         is_l2 = 1;
18511       else
18512         break;
18513     }
18514
18515   M (SW_INTERFACE_SPAN_DUMP, mp);
18516   mp->is_l2 = is_l2;
18517   S (mp);
18518
18519   /* Use a control ping for synchronization */
18520   MPING (CONTROL_PING, mp_ping);
18521   S (mp_ping);
18522
18523   W (ret);
18524   return ret;
18525 }
18526
18527 int
18528 api_pg_create_interface (vat_main_t * vam)
18529 {
18530   unformat_input_t *input = vam->input;
18531   vl_api_pg_create_interface_t *mp;
18532
18533   u32 if_id = ~0, gso_size = 0;
18534   u8 gso_enabled = 0;
18535   int ret;
18536   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18537     {
18538       if (unformat (input, "if_id %d", &if_id))
18539         ;
18540       else if (unformat (input, "gso-enabled"))
18541         {
18542           gso_enabled = 1;
18543           if (unformat (input, "gso-size %u", &gso_size))
18544             ;
18545           else
18546             {
18547               errmsg ("missing gso-size");
18548               return -99;
18549             }
18550         }
18551       else
18552         break;
18553     }
18554   if (if_id == ~0)
18555     {
18556       errmsg ("missing pg interface index");
18557       return -99;
18558     }
18559
18560   /* Construct the API message */
18561   M (PG_CREATE_INTERFACE, mp);
18562   mp->context = 0;
18563   mp->interface_id = ntohl (if_id);
18564   mp->gso_enabled = gso_enabled;
18565
18566   S (mp);
18567   W (ret);
18568   return ret;
18569 }
18570
18571 int
18572 api_pg_capture (vat_main_t * vam)
18573 {
18574   unformat_input_t *input = vam->input;
18575   vl_api_pg_capture_t *mp;
18576
18577   u32 if_id = ~0;
18578   u8 enable = 1;
18579   u32 count = 1;
18580   u8 pcap_file_set = 0;
18581   u8 *pcap_file = 0;
18582   int ret;
18583   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18584     {
18585       if (unformat (input, "if_id %d", &if_id))
18586         ;
18587       else if (unformat (input, "pcap %s", &pcap_file))
18588         pcap_file_set = 1;
18589       else if (unformat (input, "count %d", &count))
18590         ;
18591       else if (unformat (input, "disable"))
18592         enable = 0;
18593       else
18594         break;
18595     }
18596   if (if_id == ~0)
18597     {
18598       errmsg ("missing pg interface index");
18599       return -99;
18600     }
18601   if (pcap_file_set > 0)
18602     {
18603       if (vec_len (pcap_file) > 255)
18604         {
18605           errmsg ("pcap file name is too long");
18606           return -99;
18607         }
18608     }
18609
18610   /* Construct the API message */
18611   M (PG_CAPTURE, mp);
18612   mp->context = 0;
18613   mp->interface_id = ntohl (if_id);
18614   mp->is_enabled = enable;
18615   mp->count = ntohl (count);
18616   if (pcap_file_set != 0)
18617     {
18618       vl_api_vec_to_api_string (pcap_file, &mp->pcap_file_name);
18619     }
18620   vec_free (pcap_file);
18621
18622   S (mp);
18623   W (ret);
18624   return ret;
18625 }
18626
18627 int
18628 api_pg_enable_disable (vat_main_t * vam)
18629 {
18630   unformat_input_t *input = vam->input;
18631   vl_api_pg_enable_disable_t *mp;
18632
18633   u8 enable = 1;
18634   u8 stream_name_set = 0;
18635   u8 *stream_name = 0;
18636   int ret;
18637   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18638     {
18639       if (unformat (input, "stream %s", &stream_name))
18640         stream_name_set = 1;
18641       else if (unformat (input, "disable"))
18642         enable = 0;
18643       else
18644         break;
18645     }
18646
18647   if (stream_name_set > 0)
18648     {
18649       if (vec_len (stream_name) > 255)
18650         {
18651           errmsg ("stream name too long");
18652           return -99;
18653         }
18654     }
18655
18656   /* Construct the API message */
18657   M (PG_ENABLE_DISABLE, mp);
18658   mp->context = 0;
18659   mp->is_enabled = enable;
18660   if (stream_name_set != 0)
18661     {
18662       vl_api_vec_to_api_string (stream_name, &mp->stream_name);
18663     }
18664   vec_free (stream_name);
18665
18666   S (mp);
18667   W (ret);
18668   return ret;
18669 }
18670
18671 int
18672 api_pg_interface_enable_disable_coalesce (vat_main_t * vam)
18673 {
18674   unformat_input_t *input = vam->input;
18675   vl_api_pg_interface_enable_disable_coalesce_t *mp;
18676
18677   u32 sw_if_index = ~0;
18678   u8 enable = 1;
18679   int ret;
18680   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18681     {
18682       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18683         ;
18684       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18685         ;
18686       else if (unformat (input, "disable"))
18687         enable = 0;
18688       else
18689         break;
18690     }
18691
18692   if (sw_if_index == ~0)
18693     {
18694       errmsg ("Interface required but not specified");
18695       return -99;
18696     }
18697
18698   /* Construct the API message */
18699   M (PG_INTERFACE_ENABLE_DISABLE_COALESCE, mp);
18700   mp->context = 0;
18701   mp->coalesce_enabled = enable;
18702   mp->sw_if_index = htonl (sw_if_index);
18703
18704   S (mp);
18705   W (ret);
18706   return ret;
18707 }
18708
18709 int
18710 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
18711 {
18712   unformat_input_t *input = vam->input;
18713   vl_api_ip_source_and_port_range_check_add_del_t *mp;
18714
18715   u16 *low_ports = 0;
18716   u16 *high_ports = 0;
18717   u16 this_low;
18718   u16 this_hi;
18719   vl_api_prefix_t prefix;
18720   u32 tmp, tmp2;
18721   u8 prefix_set = 0;
18722   u32 vrf_id = ~0;
18723   u8 is_add = 1;
18724   int ret;
18725
18726   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18727     {
18728       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
18729         prefix_set = 1;
18730       else if (unformat (input, "vrf %d", &vrf_id))
18731         ;
18732       else if (unformat (input, "del"))
18733         is_add = 0;
18734       else if (unformat (input, "port %d", &tmp))
18735         {
18736           if (tmp == 0 || tmp > 65535)
18737             {
18738               errmsg ("port %d out of range", tmp);
18739               return -99;
18740             }
18741           this_low = tmp;
18742           this_hi = this_low + 1;
18743           vec_add1 (low_ports, this_low);
18744           vec_add1 (high_ports, this_hi);
18745         }
18746       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
18747         {
18748           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
18749             {
18750               errmsg ("incorrect range parameters");
18751               return -99;
18752             }
18753           this_low = tmp;
18754           /* Note: in debug CLI +1 is added to high before
18755              passing to real fn that does "the work"
18756              (ip_source_and_port_range_check_add_del).
18757              This fn is a wrapper around the binary API fn a
18758              control plane will call, which expects this increment
18759              to have occurred. Hence letting the binary API control
18760              plane fn do the increment for consistency between VAT
18761              and other control planes.
18762            */
18763           this_hi = tmp2;
18764           vec_add1 (low_ports, this_low);
18765           vec_add1 (high_ports, this_hi);
18766         }
18767       else
18768         break;
18769     }
18770
18771   if (prefix_set == 0)
18772     {
18773       errmsg ("<address>/<mask> not specified");
18774       return -99;
18775     }
18776
18777   if (vrf_id == ~0)
18778     {
18779       errmsg ("VRF ID required, not specified");
18780       return -99;
18781     }
18782
18783   if (vrf_id == 0)
18784     {
18785       errmsg
18786         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18787       return -99;
18788     }
18789
18790   if (vec_len (low_ports) == 0)
18791     {
18792       errmsg ("At least one port or port range required");
18793       return -99;
18794     }
18795
18796   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
18797
18798   mp->is_add = is_add;
18799
18800   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
18801
18802   mp->number_of_ranges = vec_len (low_ports);
18803
18804   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
18805   vec_free (low_ports);
18806
18807   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
18808   vec_free (high_ports);
18809
18810   mp->vrf_id = ntohl (vrf_id);
18811
18812   S (mp);
18813   W (ret);
18814   return ret;
18815 }
18816
18817 int
18818 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
18819 {
18820   unformat_input_t *input = vam->input;
18821   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
18822   u32 sw_if_index = ~0;
18823   int vrf_set = 0;
18824   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
18825   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
18826   u8 is_add = 1;
18827   int ret;
18828
18829   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18830     {
18831       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18832         ;
18833       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18834         ;
18835       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
18836         vrf_set = 1;
18837       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
18838         vrf_set = 1;
18839       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
18840         vrf_set = 1;
18841       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
18842         vrf_set = 1;
18843       else if (unformat (input, "del"))
18844         is_add = 0;
18845       else
18846         break;
18847     }
18848
18849   if (sw_if_index == ~0)
18850     {
18851       errmsg ("Interface required but not specified");
18852       return -99;
18853     }
18854
18855   if (vrf_set == 0)
18856     {
18857       errmsg ("VRF ID required but not specified");
18858       return -99;
18859     }
18860
18861   if (tcp_out_vrf_id == 0
18862       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
18863     {
18864       errmsg
18865         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18866       return -99;
18867     }
18868
18869   /* Construct the API message */
18870   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
18871
18872   mp->sw_if_index = ntohl (sw_if_index);
18873   mp->is_add = is_add;
18874   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
18875   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
18876   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
18877   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
18878
18879   /* send it... */
18880   S (mp);
18881
18882   /* Wait for a reply... */
18883   W (ret);
18884   return ret;
18885 }
18886
18887 static int
18888 api_set_punt (vat_main_t * vam)
18889 {
18890   unformat_input_t *i = vam->input;
18891   vl_api_address_family_t af;
18892   vl_api_set_punt_t *mp;
18893   u32 protocol = ~0;
18894   u32 port = ~0;
18895   int is_add = 1;
18896   int ret;
18897
18898   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18899     {
18900       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
18901         ;
18902       else if (unformat (i, "protocol %d", &protocol))
18903         ;
18904       else if (unformat (i, "port %d", &port))
18905         ;
18906       else if (unformat (i, "del"))
18907         is_add = 0;
18908       else
18909         {
18910           clib_warning ("parse error '%U'", format_unformat_error, i);
18911           return -99;
18912         }
18913     }
18914
18915   M (SET_PUNT, mp);
18916
18917   mp->is_add = (u8) is_add;
18918   mp->punt.type = PUNT_API_TYPE_L4;
18919   mp->punt.punt.l4.af = af;
18920   mp->punt.punt.l4.protocol = (u8) protocol;
18921   mp->punt.punt.l4.port = htons ((u16) port);
18922
18923   S (mp);
18924   W (ret);
18925   return ret;
18926 }
18927
18928 static int
18929 api_delete_subif (vat_main_t * vam)
18930 {
18931   unformat_input_t *i = vam->input;
18932   vl_api_delete_subif_t *mp;
18933   u32 sw_if_index = ~0;
18934   int ret;
18935
18936   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18937     {
18938       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18939         ;
18940       if (unformat (i, "sw_if_index %d", &sw_if_index))
18941         ;
18942       else
18943         break;
18944     }
18945
18946   if (sw_if_index == ~0)
18947     {
18948       errmsg ("missing sw_if_index");
18949       return -99;
18950     }
18951
18952   /* Construct the API message */
18953   M (DELETE_SUBIF, mp);
18954   mp->sw_if_index = ntohl (sw_if_index);
18955
18956   S (mp);
18957   W (ret);
18958   return ret;
18959 }
18960
18961 #define foreach_pbb_vtr_op      \
18962 _("disable",  L2_VTR_DISABLED)  \
18963 _("pop",  L2_VTR_POP_2)         \
18964 _("push",  L2_VTR_PUSH_2)
18965
18966 static int
18967 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
18968 {
18969   unformat_input_t *i = vam->input;
18970   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
18971   u32 sw_if_index = ~0, vtr_op = ~0;
18972   u16 outer_tag = ~0;
18973   u8 dmac[6], smac[6];
18974   u8 dmac_set = 0, smac_set = 0;
18975   u16 vlanid = 0;
18976   u32 sid = ~0;
18977   u32 tmp;
18978   int ret;
18979
18980   /* Shut up coverity */
18981   clib_memset (dmac, 0, sizeof (dmac));
18982   clib_memset (smac, 0, sizeof (smac));
18983
18984   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18985     {
18986       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18987         ;
18988       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18989         ;
18990       else if (unformat (i, "vtr_op %d", &vtr_op))
18991         ;
18992 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
18993       foreach_pbb_vtr_op
18994 #undef _
18995         else if (unformat (i, "translate_pbb_stag"))
18996         {
18997           if (unformat (i, "%d", &tmp))
18998             {
18999               vtr_op = L2_VTR_TRANSLATE_2_1;
19000               outer_tag = tmp;
19001             }
19002           else
19003             {
19004               errmsg
19005                 ("translate_pbb_stag operation requires outer tag definition");
19006               return -99;
19007             }
19008         }
19009       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
19010         dmac_set++;
19011       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
19012         smac_set++;
19013       else if (unformat (i, "sid %d", &sid))
19014         ;
19015       else if (unformat (i, "vlanid %d", &tmp))
19016         vlanid = tmp;
19017       else
19018         {
19019           clib_warning ("parse error '%U'", format_unformat_error, i);
19020           return -99;
19021         }
19022     }
19023
19024   if ((sw_if_index == ~0) || (vtr_op == ~0))
19025     {
19026       errmsg ("missing sw_if_index or vtr operation");
19027       return -99;
19028     }
19029   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
19030       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
19031     {
19032       errmsg
19033         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
19034       return -99;
19035     }
19036
19037   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
19038   mp->sw_if_index = ntohl (sw_if_index);
19039   mp->vtr_op = ntohl (vtr_op);
19040   mp->outer_tag = ntohs (outer_tag);
19041   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
19042   clib_memcpy (mp->b_smac, smac, sizeof (smac));
19043   mp->b_vlanid = ntohs (vlanid);
19044   mp->i_sid = ntohl (sid);
19045
19046   S (mp);
19047   W (ret);
19048   return ret;
19049 }
19050
19051 static int
19052 api_flow_classify_set_interface (vat_main_t * vam)
19053 {
19054   unformat_input_t *i = vam->input;
19055   vl_api_flow_classify_set_interface_t *mp;
19056   u32 sw_if_index;
19057   int sw_if_index_set;
19058   u32 ip4_table_index = ~0;
19059   u32 ip6_table_index = ~0;
19060   u8 is_add = 1;
19061   int ret;
19062
19063   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19064     {
19065       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19066         sw_if_index_set = 1;
19067       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19068         sw_if_index_set = 1;
19069       else if (unformat (i, "del"))
19070         is_add = 0;
19071       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19072         ;
19073       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19074         ;
19075       else
19076         {
19077           clib_warning ("parse error '%U'", format_unformat_error, i);
19078           return -99;
19079         }
19080     }
19081
19082   if (sw_if_index_set == 0)
19083     {
19084       errmsg ("missing interface name or sw_if_index");
19085       return -99;
19086     }
19087
19088   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
19089
19090   mp->sw_if_index = ntohl (sw_if_index);
19091   mp->ip4_table_index = ntohl (ip4_table_index);
19092   mp->ip6_table_index = ntohl (ip6_table_index);
19093   mp->is_add = is_add;
19094
19095   S (mp);
19096   W (ret);
19097   return ret;
19098 }
19099
19100 static int
19101 api_flow_classify_dump (vat_main_t * vam)
19102 {
19103   unformat_input_t *i = vam->input;
19104   vl_api_flow_classify_dump_t *mp;
19105   vl_api_control_ping_t *mp_ping;
19106   u8 type = FLOW_CLASSIFY_N_TABLES;
19107   int ret;
19108
19109   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
19110     ;
19111   else
19112     {
19113       errmsg ("classify table type must be specified");
19114       return -99;
19115     }
19116
19117   if (!vam->json_output)
19118     {
19119       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19120     }
19121
19122   M (FLOW_CLASSIFY_DUMP, mp);
19123   mp->type = type;
19124   /* send it... */
19125   S (mp);
19126
19127   /* Use a control ping for synchronization */
19128   MPING (CONTROL_PING, mp_ping);
19129   S (mp_ping);
19130
19131   /* Wait for a reply... */
19132   W (ret);
19133   return ret;
19134 }
19135
19136 static int
19137 api_feature_enable_disable (vat_main_t * vam)
19138 {
19139   unformat_input_t *i = vam->input;
19140   vl_api_feature_enable_disable_t *mp;
19141   u8 *arc_name = 0;
19142   u8 *feature_name = 0;
19143   u32 sw_if_index = ~0;
19144   u8 enable = 1;
19145   int ret;
19146
19147   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19148     {
19149       if (unformat (i, "arc_name %s", &arc_name))
19150         ;
19151       else if (unformat (i, "feature_name %s", &feature_name))
19152         ;
19153       else
19154         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19155         ;
19156       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19157         ;
19158       else if (unformat (i, "disable"))
19159         enable = 0;
19160       else
19161         break;
19162     }
19163
19164   if (arc_name == 0)
19165     {
19166       errmsg ("missing arc name");
19167       return -99;
19168     }
19169   if (vec_len (arc_name) > 63)
19170     {
19171       errmsg ("arc name too long");
19172     }
19173
19174   if (feature_name == 0)
19175     {
19176       errmsg ("missing feature name");
19177       return -99;
19178     }
19179   if (vec_len (feature_name) > 63)
19180     {
19181       errmsg ("feature name too long");
19182     }
19183
19184   if (sw_if_index == ~0)
19185     {
19186       errmsg ("missing interface name or sw_if_index");
19187       return -99;
19188     }
19189
19190   /* Construct the API message */
19191   M (FEATURE_ENABLE_DISABLE, mp);
19192   mp->sw_if_index = ntohl (sw_if_index);
19193   mp->enable = enable;
19194   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
19195   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
19196   vec_free (arc_name);
19197   vec_free (feature_name);
19198
19199   S (mp);
19200   W (ret);
19201   return ret;
19202 }
19203
19204 static int
19205 api_feature_gso_enable_disable (vat_main_t * vam)
19206 {
19207   unformat_input_t *i = vam->input;
19208   vl_api_feature_gso_enable_disable_t *mp;
19209   u32 sw_if_index = ~0;
19210   u8 enable = 1;
19211   int ret;
19212
19213   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19214     {
19215       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19216         ;
19217       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19218         ;
19219       else if (unformat (i, "enable"))
19220         enable = 1;
19221       else if (unformat (i, "disable"))
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   /* Construct the API message */
19234   M (FEATURE_GSO_ENABLE_DISABLE, mp);
19235   mp->sw_if_index = ntohl (sw_if_index);
19236   mp->enable_disable = enable;
19237
19238   S (mp);
19239   W (ret);
19240   return ret;
19241 }
19242
19243 static int
19244 api_sw_interface_tag_add_del (vat_main_t * vam)
19245 {
19246   unformat_input_t *i = vam->input;
19247   vl_api_sw_interface_tag_add_del_t *mp;
19248   u32 sw_if_index = ~0;
19249   u8 *tag = 0;
19250   u8 enable = 1;
19251   int ret;
19252
19253   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19254     {
19255       if (unformat (i, "tag %s", &tag))
19256         ;
19257       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19258         ;
19259       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19260         ;
19261       else if (unformat (i, "del"))
19262         enable = 0;
19263       else
19264         break;
19265     }
19266
19267   if (sw_if_index == ~0)
19268     {
19269       errmsg ("missing interface name or sw_if_index");
19270       return -99;
19271     }
19272
19273   if (enable && (tag == 0))
19274     {
19275       errmsg ("no tag specified");
19276       return -99;
19277     }
19278
19279   /* Construct the API message */
19280   M (SW_INTERFACE_TAG_ADD_DEL, mp);
19281   mp->sw_if_index = ntohl (sw_if_index);
19282   mp->is_add = enable;
19283   if (enable)
19284     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
19285   vec_free (tag);
19286
19287   S (mp);
19288   W (ret);
19289   return ret;
19290 }
19291
19292 static int
19293 api_sw_interface_add_del_mac_address (vat_main_t * vam)
19294 {
19295   unformat_input_t *i = vam->input;
19296   vl_api_mac_address_t mac = { 0 };
19297   vl_api_sw_interface_add_del_mac_address_t *mp;
19298   u32 sw_if_index = ~0;
19299   u8 is_add = 1;
19300   u8 mac_set = 0;
19301   int ret;
19302
19303   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19304     {
19305       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19306         ;
19307       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19308         ;
19309       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
19310         mac_set++;
19311       else if (unformat (i, "del"))
19312         is_add = 0;
19313       else
19314         break;
19315     }
19316
19317   if (sw_if_index == ~0)
19318     {
19319       errmsg ("missing interface name or sw_if_index");
19320       return -99;
19321     }
19322
19323   if (!mac_set)
19324     {
19325       errmsg ("missing MAC address");
19326       return -99;
19327     }
19328
19329   /* Construct the API message */
19330   M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
19331   mp->sw_if_index = ntohl (sw_if_index);
19332   mp->is_add = is_add;
19333   clib_memcpy (&mp->addr, &mac, sizeof (mac));
19334
19335   S (mp);
19336   W (ret);
19337   return ret;
19338 }
19339
19340 static void vl_api_l2_xconnect_details_t_handler
19341   (vl_api_l2_xconnect_details_t * mp)
19342 {
19343   vat_main_t *vam = &vat_main;
19344
19345   print (vam->ofp, "%15d%15d",
19346          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
19347 }
19348
19349 static void vl_api_l2_xconnect_details_t_handler_json
19350   (vl_api_l2_xconnect_details_t * mp)
19351 {
19352   vat_main_t *vam = &vat_main;
19353   vat_json_node_t *node = NULL;
19354
19355   if (VAT_JSON_ARRAY != vam->json_tree.type)
19356     {
19357       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19358       vat_json_init_array (&vam->json_tree);
19359     }
19360   node = vat_json_array_add (&vam->json_tree);
19361
19362   vat_json_init_object (node);
19363   vat_json_object_add_uint (node, "rx_sw_if_index",
19364                             ntohl (mp->rx_sw_if_index));
19365   vat_json_object_add_uint (node, "tx_sw_if_index",
19366                             ntohl (mp->tx_sw_if_index));
19367 }
19368
19369 static int
19370 api_l2_xconnect_dump (vat_main_t * vam)
19371 {
19372   vl_api_l2_xconnect_dump_t *mp;
19373   vl_api_control_ping_t *mp_ping;
19374   int ret;
19375
19376   if (!vam->json_output)
19377     {
19378       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
19379     }
19380
19381   M (L2_XCONNECT_DUMP, mp);
19382
19383   S (mp);
19384
19385   /* Use a control ping for synchronization */
19386   MPING (CONTROL_PING, mp_ping);
19387   S (mp_ping);
19388
19389   W (ret);
19390   return ret;
19391 }
19392
19393 static int
19394 api_hw_interface_set_mtu (vat_main_t * vam)
19395 {
19396   unformat_input_t *i = vam->input;
19397   vl_api_hw_interface_set_mtu_t *mp;
19398   u32 sw_if_index = ~0;
19399   u32 mtu = 0;
19400   int ret;
19401
19402   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19403     {
19404       if (unformat (i, "mtu %d", &mtu))
19405         ;
19406       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19407         ;
19408       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19409         ;
19410       else
19411         break;
19412     }
19413
19414   if (sw_if_index == ~0)
19415     {
19416       errmsg ("missing interface name or sw_if_index");
19417       return -99;
19418     }
19419
19420   if (mtu == 0)
19421     {
19422       errmsg ("no mtu specified");
19423       return -99;
19424     }
19425
19426   /* Construct the API message */
19427   M (HW_INTERFACE_SET_MTU, mp);
19428   mp->sw_if_index = ntohl (sw_if_index);
19429   mp->mtu = ntohs ((u16) mtu);
19430
19431   S (mp);
19432   W (ret);
19433   return ret;
19434 }
19435
19436 static int
19437 api_p2p_ethernet_add (vat_main_t * vam)
19438 {
19439   unformat_input_t *i = vam->input;
19440   vl_api_p2p_ethernet_add_t *mp;
19441   u32 parent_if_index = ~0;
19442   u32 sub_id = ~0;
19443   u8 remote_mac[6];
19444   u8 mac_set = 0;
19445   int ret;
19446
19447   clib_memset (remote_mac, 0, sizeof (remote_mac));
19448   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19449     {
19450       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19451         ;
19452       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19453         ;
19454       else
19455         if (unformat
19456             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19457         mac_set++;
19458       else if (unformat (i, "sub_id %d", &sub_id))
19459         ;
19460       else
19461         {
19462           clib_warning ("parse error '%U'", format_unformat_error, i);
19463           return -99;
19464         }
19465     }
19466
19467   if (parent_if_index == ~0)
19468     {
19469       errmsg ("missing interface name or sw_if_index");
19470       return -99;
19471     }
19472   if (mac_set == 0)
19473     {
19474       errmsg ("missing remote mac address");
19475       return -99;
19476     }
19477   if (sub_id == ~0)
19478     {
19479       errmsg ("missing sub-interface id");
19480       return -99;
19481     }
19482
19483   M (P2P_ETHERNET_ADD, mp);
19484   mp->parent_if_index = ntohl (parent_if_index);
19485   mp->subif_id = ntohl (sub_id);
19486   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19487
19488   S (mp);
19489   W (ret);
19490   return ret;
19491 }
19492
19493 static int
19494 api_p2p_ethernet_del (vat_main_t * vam)
19495 {
19496   unformat_input_t *i = vam->input;
19497   vl_api_p2p_ethernet_del_t *mp;
19498   u32 parent_if_index = ~0;
19499   u8 remote_mac[6];
19500   u8 mac_set = 0;
19501   int ret;
19502
19503   clib_memset (remote_mac, 0, sizeof (remote_mac));
19504   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19505     {
19506       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19507         ;
19508       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19509         ;
19510       else
19511         if (unformat
19512             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19513         mac_set++;
19514       else
19515         {
19516           clib_warning ("parse error '%U'", format_unformat_error, i);
19517           return -99;
19518         }
19519     }
19520
19521   if (parent_if_index == ~0)
19522     {
19523       errmsg ("missing interface name or sw_if_index");
19524       return -99;
19525     }
19526   if (mac_set == 0)
19527     {
19528       errmsg ("missing remote mac address");
19529       return -99;
19530     }
19531
19532   M (P2P_ETHERNET_DEL, mp);
19533   mp->parent_if_index = ntohl (parent_if_index);
19534   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19535
19536   S (mp);
19537   W (ret);
19538   return ret;
19539 }
19540
19541 static int
19542 api_lldp_config (vat_main_t * vam)
19543 {
19544   unformat_input_t *i = vam->input;
19545   vl_api_lldp_config_t *mp;
19546   int tx_hold = 0;
19547   int tx_interval = 0;
19548   u8 *sys_name = NULL;
19549   int ret;
19550
19551   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19552     {
19553       if (unformat (i, "system-name %s", &sys_name))
19554         ;
19555       else if (unformat (i, "tx-hold %d", &tx_hold))
19556         ;
19557       else if (unformat (i, "tx-interval %d", &tx_interval))
19558         ;
19559       else
19560         {
19561           clib_warning ("parse error '%U'", format_unformat_error, i);
19562           return -99;
19563         }
19564     }
19565
19566   vec_add1 (sys_name, 0);
19567
19568   M (LLDP_CONFIG, mp);
19569   mp->tx_hold = htonl (tx_hold);
19570   mp->tx_interval = htonl (tx_interval);
19571   vl_api_vec_to_api_string (sys_name, &mp->system_name);
19572   vec_free (sys_name);
19573
19574   S (mp);
19575   W (ret);
19576   return ret;
19577 }
19578
19579 static int
19580 api_sw_interface_set_lldp (vat_main_t * vam)
19581 {
19582   unformat_input_t *i = vam->input;
19583   vl_api_sw_interface_set_lldp_t *mp;
19584   u32 sw_if_index = ~0;
19585   u32 enable = 1;
19586   u8 *port_desc = NULL, *mgmt_oid = NULL;
19587   ip4_address_t ip4_addr;
19588   ip6_address_t ip6_addr;
19589   int ret;
19590
19591   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
19592   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
19593
19594   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19595     {
19596       if (unformat (i, "disable"))
19597         enable = 0;
19598       else
19599         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19600         ;
19601       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19602         ;
19603       else if (unformat (i, "port-desc %s", &port_desc))
19604         ;
19605       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
19606         ;
19607       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
19608         ;
19609       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
19610         ;
19611       else
19612         break;
19613     }
19614
19615   if (sw_if_index == ~0)
19616     {
19617       errmsg ("missing interface name or sw_if_index");
19618       return -99;
19619     }
19620
19621   /* Construct the API message */
19622   vec_add1 (port_desc, 0);
19623   vec_add1 (mgmt_oid, 0);
19624   M (SW_INTERFACE_SET_LLDP, mp);
19625   mp->sw_if_index = ntohl (sw_if_index);
19626   mp->enable = enable;
19627   vl_api_vec_to_api_string (port_desc, &mp->port_desc);
19628   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
19629   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
19630   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
19631   vec_free (port_desc);
19632   vec_free (mgmt_oid);
19633
19634   S (mp);
19635   W (ret);
19636   return ret;
19637 }
19638
19639 static int
19640 api_tcp_configure_src_addresses (vat_main_t * vam)
19641 {
19642   vl_api_tcp_configure_src_addresses_t *mp;
19643   unformat_input_t *i = vam->input;
19644   vl_api_address_t first, last;
19645   u8 range_set = 0;
19646   u32 vrf_id = 0;
19647   int ret;
19648
19649   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19650     {
19651       if (unformat (i, "%U - %U",
19652                     unformat_vl_api_address, &first,
19653                     unformat_vl_api_address, &last))
19654         {
19655           if (range_set)
19656             {
19657               errmsg ("one range per message (range already set)");
19658               return -99;
19659             }
19660           range_set = 1;
19661         }
19662       else if (unformat (i, "vrf %d", &vrf_id))
19663         ;
19664       else
19665         break;
19666     }
19667
19668   if (range_set == 0)
19669     {
19670       errmsg ("address range not set");
19671       return -99;
19672     }
19673
19674   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
19675
19676   mp->vrf_id = ntohl (vrf_id);
19677   clib_memcpy (&mp->first_address, &first, sizeof (first));
19678   clib_memcpy (&mp->last_address, &last, sizeof (last));
19679
19680   S (mp);
19681   W (ret);
19682   return ret;
19683 }
19684
19685 static void vl_api_app_namespace_add_del_reply_t_handler
19686   (vl_api_app_namespace_add_del_reply_t * mp)
19687 {
19688   vat_main_t *vam = &vat_main;
19689   i32 retval = ntohl (mp->retval);
19690   if (vam->async_mode)
19691     {
19692       vam->async_errors += (retval < 0);
19693     }
19694   else
19695     {
19696       vam->retval = retval;
19697       if (retval == 0)
19698         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
19699       vam->result_ready = 1;
19700     }
19701 }
19702
19703 static void vl_api_app_namespace_add_del_reply_t_handler_json
19704   (vl_api_app_namespace_add_del_reply_t * mp)
19705 {
19706   vat_main_t *vam = &vat_main;
19707   vat_json_node_t node;
19708
19709   vat_json_init_object (&node);
19710   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
19711   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
19712
19713   vat_json_print (vam->ofp, &node);
19714   vat_json_free (&node);
19715
19716   vam->retval = ntohl (mp->retval);
19717   vam->result_ready = 1;
19718 }
19719
19720 static int
19721 api_app_namespace_add_del (vat_main_t * vam)
19722 {
19723   vl_api_app_namespace_add_del_t *mp;
19724   unformat_input_t *i = vam->input;
19725   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
19726   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
19727   u64 secret;
19728   int ret;
19729
19730   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19731     {
19732       if (unformat (i, "id %_%v%_", &ns_id))
19733         ;
19734       else if (unformat (i, "secret %lu", &secret))
19735         secret_set = 1;
19736       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19737         sw_if_index_set = 1;
19738       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
19739         ;
19740       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
19741         ;
19742       else
19743         break;
19744     }
19745   if (!ns_id || !secret_set || !sw_if_index_set)
19746     {
19747       errmsg ("namespace id, secret and sw_if_index must be set");
19748       return -99;
19749     }
19750   if (vec_len (ns_id) > 64)
19751     {
19752       errmsg ("namespace id too long");
19753       return -99;
19754     }
19755   M (APP_NAMESPACE_ADD_DEL, mp);
19756
19757   vl_api_vec_to_api_string (ns_id, &mp->namespace_id);
19758   mp->secret = clib_host_to_net_u64 (secret);
19759   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
19760   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
19761   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
19762   vec_free (ns_id);
19763   S (mp);
19764   W (ret);
19765   return ret;
19766 }
19767
19768 static int
19769 api_sock_init_shm (vat_main_t * vam)
19770 {
19771 #if VPP_API_TEST_BUILTIN == 0
19772   unformat_input_t *i = vam->input;
19773   vl_api_shm_elem_config_t *config = 0;
19774   u64 size = 64 << 20;
19775   int rv;
19776
19777   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19778     {
19779       if (unformat (i, "size %U", unformat_memory_size, &size))
19780         ;
19781       else
19782         break;
19783     }
19784
19785   /*
19786    * Canned custom ring allocator config.
19787    * Should probably parse all of this
19788    */
19789   vec_validate (config, 6);
19790   config[0].type = VL_API_VLIB_RING;
19791   config[0].size = 256;
19792   config[0].count = 32;
19793
19794   config[1].type = VL_API_VLIB_RING;
19795   config[1].size = 1024;
19796   config[1].count = 16;
19797
19798   config[2].type = VL_API_VLIB_RING;
19799   config[2].size = 4096;
19800   config[2].count = 2;
19801
19802   config[3].type = VL_API_CLIENT_RING;
19803   config[3].size = 256;
19804   config[3].count = 32;
19805
19806   config[4].type = VL_API_CLIENT_RING;
19807   config[4].size = 1024;
19808   config[4].count = 16;
19809
19810   config[5].type = VL_API_CLIENT_RING;
19811   config[5].size = 4096;
19812   config[5].count = 2;
19813
19814   config[6].type = VL_API_QUEUE;
19815   config[6].count = 128;
19816   config[6].size = sizeof (uword);
19817
19818   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
19819   if (!rv)
19820     vam->client_index_invalid = 1;
19821   return rv;
19822 #else
19823   return -99;
19824 #endif
19825 }
19826
19827 static void
19828 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
19829 {
19830   vat_main_t *vam = &vat_main;
19831   fib_prefix_t lcl, rmt;
19832
19833   ip_prefix_decode (&mp->lcl, &lcl);
19834   ip_prefix_decode (&mp->rmt, &rmt);
19835
19836   if (lcl.fp_proto == FIB_PROTOCOL_IP4)
19837     {
19838       print (vam->ofp,
19839              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19840              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19841              mp->scope, format_ip4_address, &lcl.fp_addr.ip4, lcl.fp_len,
19842              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
19843              &rmt.fp_addr.ip4, rmt.fp_len,
19844              clib_net_to_host_u16 (mp->rmt_port),
19845              clib_net_to_host_u32 (mp->action_index), mp->tag);
19846     }
19847   else
19848     {
19849       print (vam->ofp,
19850              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19851              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19852              mp->scope, format_ip6_address, &lcl.fp_addr.ip6, lcl.fp_len,
19853              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
19854              &rmt.fp_addr.ip6, rmt.fp_len,
19855              clib_net_to_host_u16 (mp->rmt_port),
19856              clib_net_to_host_u32 (mp->action_index), mp->tag);
19857     }
19858 }
19859
19860 static void
19861 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
19862                                              mp)
19863 {
19864   vat_main_t *vam = &vat_main;
19865   vat_json_node_t *node = NULL;
19866   struct in6_addr ip6;
19867   struct in_addr ip4;
19868
19869   fib_prefix_t lcl, rmt;
19870
19871   ip_prefix_decode (&mp->lcl, &lcl);
19872   ip_prefix_decode (&mp->rmt, &rmt);
19873
19874   if (VAT_JSON_ARRAY != vam->json_tree.type)
19875     {
19876       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19877       vat_json_init_array (&vam->json_tree);
19878     }
19879   node = vat_json_array_add (&vam->json_tree);
19880   vat_json_init_object (node);
19881
19882   vat_json_object_add_uint (node, "appns_index",
19883                             clib_net_to_host_u32 (mp->appns_index));
19884   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
19885   vat_json_object_add_uint (node, "scope", mp->scope);
19886   vat_json_object_add_uint (node, "action_index",
19887                             clib_net_to_host_u32 (mp->action_index));
19888   vat_json_object_add_uint (node, "lcl_port",
19889                             clib_net_to_host_u16 (mp->lcl_port));
19890   vat_json_object_add_uint (node, "rmt_port",
19891                             clib_net_to_host_u16 (mp->rmt_port));
19892   vat_json_object_add_uint (node, "lcl_plen", lcl.fp_len);
19893   vat_json_object_add_uint (node, "rmt_plen", rmt.fp_len);
19894   vat_json_object_add_string_copy (node, "tag", mp->tag);
19895   if (lcl.fp_proto == FIB_PROTOCOL_IP4)
19896     {
19897       clib_memcpy (&ip4, &lcl.fp_addr.ip4, sizeof (ip4));
19898       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
19899       clib_memcpy (&ip4, &rmt.fp_addr.ip4, sizeof (ip4));
19900       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
19901     }
19902   else
19903     {
19904       clib_memcpy (&ip6, &lcl.fp_addr.ip6, sizeof (ip6));
19905       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
19906       clib_memcpy (&ip6, &rmt.fp_addr.ip6, sizeof (ip6));
19907       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
19908     }
19909 }
19910
19911 static int
19912 api_session_rule_add_del (vat_main_t * vam)
19913 {
19914   vl_api_session_rule_add_del_t *mp;
19915   unformat_input_t *i = vam->input;
19916   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
19917   u32 appns_index = 0, scope = 0;
19918   ip4_address_t lcl_ip4, rmt_ip4;
19919   ip6_address_t lcl_ip6, rmt_ip6;
19920   u8 is_ip4 = 1, conn_set = 0;
19921   u8 is_add = 1, *tag = 0;
19922   int ret;
19923   fib_prefix_t lcl, rmt;
19924
19925   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19926     {
19927       if (unformat (i, "del"))
19928         is_add = 0;
19929       else if (unformat (i, "add"))
19930         ;
19931       else if (unformat (i, "proto tcp"))
19932         proto = 0;
19933       else if (unformat (i, "proto udp"))
19934         proto = 1;
19935       else if (unformat (i, "appns %d", &appns_index))
19936         ;
19937       else if (unformat (i, "scope %d", &scope))
19938         ;
19939       else if (unformat (i, "tag %_%v%_", &tag))
19940         ;
19941       else
19942         if (unformat
19943             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
19944              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
19945              &rmt_port))
19946         {
19947           is_ip4 = 1;
19948           conn_set = 1;
19949         }
19950       else
19951         if (unformat
19952             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
19953              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
19954              &rmt_port))
19955         {
19956           is_ip4 = 0;
19957           conn_set = 1;
19958         }
19959       else if (unformat (i, "action %d", &action))
19960         ;
19961       else
19962         break;
19963     }
19964   if (proto == ~0 || !conn_set || action == ~0)
19965     {
19966       errmsg ("transport proto, connection and action must be set");
19967       return -99;
19968     }
19969
19970   if (scope > 3)
19971     {
19972       errmsg ("scope should be 0-3");
19973       return -99;
19974     }
19975
19976   M (SESSION_RULE_ADD_DEL, mp);
19977
19978   clib_memset (&lcl, 0, sizeof (lcl));
19979   clib_memset (&rmt, 0, sizeof (rmt));
19980   if (is_ip4)
19981     {
19982       ip_set (&lcl.fp_addr, &lcl_ip4, 1);
19983       ip_set (&rmt.fp_addr, &rmt_ip4, 1);
19984       lcl.fp_len = lcl_plen;
19985       rmt.fp_len = rmt_plen;
19986     }
19987   else
19988     {
19989       ip_set (&lcl.fp_addr, &lcl_ip6, 0);
19990       ip_set (&rmt.fp_addr, &rmt_ip6, 0);
19991       lcl.fp_len = lcl_plen;
19992       rmt.fp_len = rmt_plen;
19993     }
19994
19995
19996   ip_prefix_encode (&lcl, &mp->lcl);
19997   ip_prefix_encode (&rmt, &mp->rmt);
19998   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
19999   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
20000   mp->transport_proto =
20001     proto ? TRANSPORT_PROTO_API_UDP : TRANSPORT_PROTO_API_TCP;
20002   mp->action_index = clib_host_to_net_u32 (action);
20003   mp->appns_index = clib_host_to_net_u32 (appns_index);
20004   mp->scope = scope;
20005   mp->is_add = is_add;
20006   if (tag)
20007     {
20008       clib_memcpy (mp->tag, tag, vec_len (tag));
20009       vec_free (tag);
20010     }
20011
20012   S (mp);
20013   W (ret);
20014   return ret;
20015 }
20016
20017 static int
20018 api_session_rules_dump (vat_main_t * vam)
20019 {
20020   vl_api_session_rules_dump_t *mp;
20021   vl_api_control_ping_t *mp_ping;
20022   int ret;
20023
20024   if (!vam->json_output)
20025     {
20026       print (vam->ofp, "%=20s", "Session Rules");
20027     }
20028
20029   M (SESSION_RULES_DUMP, mp);
20030   /* send it... */
20031   S (mp);
20032
20033   /* Use a control ping for synchronization */
20034   MPING (CONTROL_PING, mp_ping);
20035   S (mp_ping);
20036
20037   /* Wait for a reply... */
20038   W (ret);
20039   return ret;
20040 }
20041
20042 static int
20043 api_ip_container_proxy_add_del (vat_main_t * vam)
20044 {
20045   vl_api_ip_container_proxy_add_del_t *mp;
20046   unformat_input_t *i = vam->input;
20047   u32 sw_if_index = ~0;
20048   vl_api_prefix_t pfx = { };
20049   u8 is_add = 1;
20050   int ret;
20051
20052   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20053     {
20054       if (unformat (i, "del"))
20055         is_add = 0;
20056       else if (unformat (i, "add"))
20057         ;
20058       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
20059         ;
20060       else if (unformat (i, "sw_if_index %u", &sw_if_index))
20061         ;
20062       else
20063         break;
20064     }
20065   if (sw_if_index == ~0 || pfx.len == 0)
20066     {
20067       errmsg ("address and sw_if_index must be set");
20068       return -99;
20069     }
20070
20071   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
20072
20073   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20074   mp->is_add = is_add;
20075   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
20076
20077   S (mp);
20078   W (ret);
20079   return ret;
20080 }
20081
20082 static int
20083 api_qos_record_enable_disable (vat_main_t * vam)
20084 {
20085   unformat_input_t *i = vam->input;
20086   vl_api_qos_record_enable_disable_t *mp;
20087   u32 sw_if_index, qs = 0xff;
20088   u8 sw_if_index_set = 0;
20089   u8 enable = 1;
20090   int ret;
20091
20092   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20093     {
20094       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20095         sw_if_index_set = 1;
20096       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20097         sw_if_index_set = 1;
20098       else if (unformat (i, "%U", unformat_qos_source, &qs))
20099         ;
20100       else if (unformat (i, "disable"))
20101         enable = 0;
20102       else
20103         {
20104           clib_warning ("parse error '%U'", format_unformat_error, i);
20105           return -99;
20106         }
20107     }
20108
20109   if (sw_if_index_set == 0)
20110     {
20111       errmsg ("missing interface name or sw_if_index");
20112       return -99;
20113     }
20114   if (qs == 0xff)
20115     {
20116       errmsg ("input location must be specified");
20117       return -99;
20118     }
20119
20120   M (QOS_RECORD_ENABLE_DISABLE, mp);
20121
20122   mp->record.sw_if_index = ntohl (sw_if_index);
20123   mp->record.input_source = qs;
20124   mp->enable = enable;
20125
20126   S (mp);
20127   W (ret);
20128   return ret;
20129 }
20130
20131
20132 static int
20133 q_or_quit (vat_main_t * vam)
20134 {
20135 #if VPP_API_TEST_BUILTIN == 0
20136   longjmp (vam->jump_buf, 1);
20137 #endif
20138   return 0;                     /* not so much */
20139 }
20140
20141 static int
20142 q (vat_main_t * vam)
20143 {
20144   return q_or_quit (vam);
20145 }
20146
20147 static int
20148 quit (vat_main_t * vam)
20149 {
20150   return q_or_quit (vam);
20151 }
20152
20153 static int
20154 comment (vat_main_t * vam)
20155 {
20156   return 0;
20157 }
20158
20159 static int
20160 elog_save (vat_main_t * vam)
20161 {
20162 #if VPP_API_TEST_BUILTIN == 0
20163   elog_main_t *em = &vam->elog_main;
20164   unformat_input_t *i = vam->input;
20165   char *file, *chroot_file;
20166   clib_error_t *error;
20167
20168   if (!unformat (i, "%s", &file))
20169     {
20170       errmsg ("expected file name, got `%U'", format_unformat_error, i);
20171       return 0;
20172     }
20173
20174   /* It's fairly hard to get "../oopsie" through unformat; just in case */
20175   if (strstr (file, "..") || index (file, '/'))
20176     {
20177       errmsg ("illegal characters in filename '%s'", file);
20178       return 0;
20179     }
20180
20181   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
20182
20183   vec_free (file);
20184
20185   errmsg ("Saving %wd of %wd events to %s",
20186           elog_n_events_in_buffer (em),
20187           elog_buffer_capacity (em), chroot_file);
20188
20189   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
20190   vec_free (chroot_file);
20191
20192   if (error)
20193     clib_error_report (error);
20194 #else
20195   errmsg ("Use the vpp event loger...");
20196 #endif
20197
20198   return 0;
20199 }
20200
20201 static int
20202 elog_setup (vat_main_t * vam)
20203 {
20204 #if VPP_API_TEST_BUILTIN == 0
20205   elog_main_t *em = &vam->elog_main;
20206   unformat_input_t *i = vam->input;
20207   u32 nevents = 128 << 10;
20208
20209   (void) unformat (i, "nevents %d", &nevents);
20210
20211   elog_init (em, nevents);
20212   vl_api_set_elog_main (em);
20213   vl_api_set_elog_trace_api_messages (1);
20214   errmsg ("Event logger initialized with %u events", nevents);
20215 #else
20216   errmsg ("Use the vpp event loger...");
20217 #endif
20218   return 0;
20219 }
20220
20221 static int
20222 elog_enable (vat_main_t * vam)
20223 {
20224 #if VPP_API_TEST_BUILTIN == 0
20225   elog_main_t *em = &vam->elog_main;
20226
20227   elog_enable_disable (em, 1 /* enable */ );
20228   vl_api_set_elog_trace_api_messages (1);
20229   errmsg ("Event logger enabled...");
20230 #else
20231   errmsg ("Use the vpp event loger...");
20232 #endif
20233   return 0;
20234 }
20235
20236 static int
20237 elog_disable (vat_main_t * vam)
20238 {
20239 #if VPP_API_TEST_BUILTIN == 0
20240   elog_main_t *em = &vam->elog_main;
20241
20242   elog_enable_disable (em, 0 /* enable */ );
20243   vl_api_set_elog_trace_api_messages (1);
20244   errmsg ("Event logger disabled...");
20245 #else
20246   errmsg ("Use the vpp event loger...");
20247 #endif
20248   return 0;
20249 }
20250
20251 static int
20252 statseg (vat_main_t * vam)
20253 {
20254   ssvm_private_t *ssvmp = &vam->stat_segment;
20255   ssvm_shared_header_t *shared_header = ssvmp->sh;
20256   vlib_counter_t **counters;
20257   u64 thread0_index1_packets;
20258   u64 thread0_index1_bytes;
20259   f64 vector_rate, input_rate;
20260   uword *p;
20261
20262   uword *counter_vector_by_name;
20263   if (vam->stat_segment_lockp == 0)
20264     {
20265       errmsg ("Stat segment not mapped...");
20266       return -99;
20267     }
20268
20269   /* look up "/if/rx for sw_if_index 1 as a test */
20270
20271   clib_spinlock_lock (vam->stat_segment_lockp);
20272
20273   counter_vector_by_name = (uword *) shared_header->opaque[1];
20274
20275   p = hash_get_mem (counter_vector_by_name, "/if/rx");
20276   if (p == 0)
20277     {
20278       clib_spinlock_unlock (vam->stat_segment_lockp);
20279       errmsg ("/if/tx not found?");
20280       return -99;
20281     }
20282
20283   /* Fish per-thread vector of combined counters from shared memory */
20284   counters = (vlib_counter_t **) p[0];
20285
20286   if (vec_len (counters[0]) < 2)
20287     {
20288       clib_spinlock_unlock (vam->stat_segment_lockp);
20289       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
20290       return -99;
20291     }
20292
20293   /* Read thread 0 sw_if_index 1 counter */
20294   thread0_index1_packets = counters[0][1].packets;
20295   thread0_index1_bytes = counters[0][1].bytes;
20296
20297   p = hash_get_mem (counter_vector_by_name, "vector_rate");
20298   if (p == 0)
20299     {
20300       clib_spinlock_unlock (vam->stat_segment_lockp);
20301       errmsg ("vector_rate not found?");
20302       return -99;
20303     }
20304
20305   vector_rate = *(f64 *) (p[0]);
20306   p = hash_get_mem (counter_vector_by_name, "input_rate");
20307   if (p == 0)
20308     {
20309       clib_spinlock_unlock (vam->stat_segment_lockp);
20310       errmsg ("input_rate not found?");
20311       return -99;
20312     }
20313   input_rate = *(f64 *) (p[0]);
20314
20315   clib_spinlock_unlock (vam->stat_segment_lockp);
20316
20317   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
20318          vector_rate, input_rate);
20319   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
20320          thread0_index1_packets, thread0_index1_bytes);
20321
20322   return 0;
20323 }
20324
20325 static int
20326 cmd_cmp (void *a1, void *a2)
20327 {
20328   u8 **c1 = a1;
20329   u8 **c2 = a2;
20330
20331   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
20332 }
20333
20334 static int
20335 help (vat_main_t * vam)
20336 {
20337   u8 **cmds = 0;
20338   u8 *name = 0;
20339   hash_pair_t *p;
20340   unformat_input_t *i = vam->input;
20341   int j;
20342
20343   if (unformat (i, "%s", &name))
20344     {
20345       uword *hs;
20346
20347       vec_add1 (name, 0);
20348
20349       hs = hash_get_mem (vam->help_by_name, name);
20350       if (hs)
20351         print (vam->ofp, "usage: %s %s", name, hs[0]);
20352       else
20353         print (vam->ofp, "No such msg / command '%s'", name);
20354       vec_free (name);
20355       return 0;
20356     }
20357
20358   print (vam->ofp, "Help is available for the following:");
20359
20360     /* *INDENT-OFF* */
20361     hash_foreach_pair (p, vam->function_by_name,
20362     ({
20363       vec_add1 (cmds, (u8 *)(p->key));
20364     }));
20365     /* *INDENT-ON* */
20366
20367   vec_sort_with_function (cmds, cmd_cmp);
20368
20369   for (j = 0; j < vec_len (cmds); j++)
20370     print (vam->ofp, "%s", cmds[j]);
20371
20372   vec_free (cmds);
20373   return 0;
20374 }
20375
20376 static int
20377 set (vat_main_t * vam)
20378 {
20379   u8 *name = 0, *value = 0;
20380   unformat_input_t *i = vam->input;
20381
20382   if (unformat (i, "%s", &name))
20383     {
20384       /* The input buffer is a vector, not a string. */
20385       value = vec_dup (i->buffer);
20386       vec_delete (value, i->index, 0);
20387       /* Almost certainly has a trailing newline */
20388       if (value[vec_len (value) - 1] == '\n')
20389         value[vec_len (value) - 1] = 0;
20390       /* Make sure it's a proper string, one way or the other */
20391       vec_add1 (value, 0);
20392       (void) clib_macro_set_value (&vam->macro_main,
20393                                    (char *) name, (char *) value);
20394     }
20395   else
20396     errmsg ("usage: set <name> <value>");
20397
20398   vec_free (name);
20399   vec_free (value);
20400   return 0;
20401 }
20402
20403 static int
20404 unset (vat_main_t * vam)
20405 {
20406   u8 *name = 0;
20407
20408   if (unformat (vam->input, "%s", &name))
20409     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
20410       errmsg ("unset: %s wasn't set", name);
20411   vec_free (name);
20412   return 0;
20413 }
20414
20415 typedef struct
20416 {
20417   u8 *name;
20418   u8 *value;
20419 } macro_sort_t;
20420
20421
20422 static int
20423 macro_sort_cmp (void *a1, void *a2)
20424 {
20425   macro_sort_t *s1 = a1;
20426   macro_sort_t *s2 = a2;
20427
20428   return strcmp ((char *) (s1->name), (char *) (s2->name));
20429 }
20430
20431 static int
20432 dump_macro_table (vat_main_t * vam)
20433 {
20434   macro_sort_t *sort_me = 0, *sm;
20435   int i;
20436   hash_pair_t *p;
20437
20438     /* *INDENT-OFF* */
20439     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
20440     ({
20441       vec_add2 (sort_me, sm, 1);
20442       sm->name = (u8 *)(p->key);
20443       sm->value = (u8 *) (p->value[0]);
20444     }));
20445     /* *INDENT-ON* */
20446
20447   vec_sort_with_function (sort_me, macro_sort_cmp);
20448
20449   if (vec_len (sort_me))
20450     print (vam->ofp, "%-15s%s", "Name", "Value");
20451   else
20452     print (vam->ofp, "The macro table is empty...");
20453
20454   for (i = 0; i < vec_len (sort_me); i++)
20455     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
20456   return 0;
20457 }
20458
20459 static int
20460 dump_node_table (vat_main_t * vam)
20461 {
20462   int i, j;
20463   vlib_node_t *node, *next_node;
20464
20465   if (vec_len (vam->graph_nodes) == 0)
20466     {
20467       print (vam->ofp, "Node table empty, issue get_node_graph...");
20468       return 0;
20469     }
20470
20471   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
20472     {
20473       node = vam->graph_nodes[0][i];
20474       print (vam->ofp, "[%d] %s", i, node->name);
20475       for (j = 0; j < vec_len (node->next_nodes); j++)
20476         {
20477           if (node->next_nodes[j] != ~0)
20478             {
20479               next_node = vam->graph_nodes[0][node->next_nodes[j]];
20480               print (vam->ofp, "  [%d] %s", j, next_node->name);
20481             }
20482         }
20483     }
20484   return 0;
20485 }
20486
20487 static int
20488 value_sort_cmp (void *a1, void *a2)
20489 {
20490   name_sort_t *n1 = a1;
20491   name_sort_t *n2 = a2;
20492
20493   if (n1->value < n2->value)
20494     return -1;
20495   if (n1->value > n2->value)
20496     return 1;
20497   return 0;
20498 }
20499
20500
20501 static int
20502 dump_msg_api_table (vat_main_t * vam)
20503 {
20504   api_main_t *am = vlibapi_get_main ();
20505   name_sort_t *nses = 0, *ns;
20506   hash_pair_t *hp;
20507   int i;
20508
20509   /* *INDENT-OFF* */
20510   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
20511   ({
20512     vec_add2 (nses, ns, 1);
20513     ns->name = (u8 *)(hp->key);
20514     ns->value = (u32) hp->value[0];
20515   }));
20516   /* *INDENT-ON* */
20517
20518   vec_sort_with_function (nses, value_sort_cmp);
20519
20520   for (i = 0; i < vec_len (nses); i++)
20521     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
20522   vec_free (nses);
20523   return 0;
20524 }
20525
20526 static int
20527 get_msg_id (vat_main_t * vam)
20528 {
20529   u8 *name_and_crc;
20530   u32 message_index;
20531
20532   if (unformat (vam->input, "%s", &name_and_crc))
20533     {
20534       message_index = vl_msg_api_get_msg_index (name_and_crc);
20535       if (message_index == ~0)
20536         {
20537           print (vam->ofp, " '%s' not found", name_and_crc);
20538           return 0;
20539         }
20540       print (vam->ofp, " '%s' has message index %d",
20541              name_and_crc, message_index);
20542       return 0;
20543     }
20544   errmsg ("name_and_crc required...");
20545   return 0;
20546 }
20547
20548 static int
20549 search_node_table (vat_main_t * vam)
20550 {
20551   unformat_input_t *line_input = vam->input;
20552   u8 *node_to_find;
20553   int j;
20554   vlib_node_t *node, *next_node;
20555   uword *p;
20556
20557   if (vam->graph_node_index_by_name == 0)
20558     {
20559       print (vam->ofp, "Node table empty, issue get_node_graph...");
20560       return 0;
20561     }
20562
20563   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20564     {
20565       if (unformat (line_input, "%s", &node_to_find))
20566         {
20567           vec_add1 (node_to_find, 0);
20568           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
20569           if (p == 0)
20570             {
20571               print (vam->ofp, "%s not found...", node_to_find);
20572               goto out;
20573             }
20574           node = vam->graph_nodes[0][p[0]];
20575           print (vam->ofp, "[%d] %s", p[0], node->name);
20576           for (j = 0; j < vec_len (node->next_nodes); j++)
20577             {
20578               if (node->next_nodes[j] != ~0)
20579                 {
20580                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
20581                   print (vam->ofp, "  [%d] %s", j, next_node->name);
20582                 }
20583             }
20584         }
20585
20586       else
20587         {
20588           clib_warning ("parse error '%U'", format_unformat_error,
20589                         line_input);
20590           return -99;
20591         }
20592
20593     out:
20594       vec_free (node_to_find);
20595
20596     }
20597
20598   return 0;
20599 }
20600
20601
20602 static int
20603 script (vat_main_t * vam)
20604 {
20605 #if (VPP_API_TEST_BUILTIN==0)
20606   u8 *s = 0;
20607   char *save_current_file;
20608   unformat_input_t save_input;
20609   jmp_buf save_jump_buf;
20610   u32 save_line_number;
20611
20612   FILE *new_fp, *save_ifp;
20613
20614   if (unformat (vam->input, "%s", &s))
20615     {
20616       new_fp = fopen ((char *) s, "r");
20617       if (new_fp == 0)
20618         {
20619           errmsg ("Couldn't open script file %s", s);
20620           vec_free (s);
20621           return -99;
20622         }
20623     }
20624   else
20625     {
20626       errmsg ("Missing script name");
20627       return -99;
20628     }
20629
20630   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
20631   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
20632   save_ifp = vam->ifp;
20633   save_line_number = vam->input_line_number;
20634   save_current_file = (char *) vam->current_file;
20635
20636   vam->input_line_number = 0;
20637   vam->ifp = new_fp;
20638   vam->current_file = s;
20639   do_one_file (vam);
20640
20641   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
20642   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
20643   vam->ifp = save_ifp;
20644   vam->input_line_number = save_line_number;
20645   vam->current_file = (u8 *) save_current_file;
20646   vec_free (s);
20647
20648   return 0;
20649 #else
20650   clib_warning ("use the exec command...");
20651   return -99;
20652 #endif
20653 }
20654
20655 static int
20656 echo (vat_main_t * vam)
20657 {
20658   print (vam->ofp, "%v", vam->input->buffer);
20659   return 0;
20660 }
20661
20662 /* List of API message constructors, CLI names map to api_xxx */
20663 #define foreach_vpe_api_msg                                             \
20664 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
20665 _(sw_interface_dump,"")                                                 \
20666 _(sw_interface_set_flags,                                               \
20667   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
20668 _(sw_interface_add_del_address,                                         \
20669   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
20670 _(sw_interface_set_rx_mode,                                             \
20671   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
20672 _(sw_interface_set_rx_placement,                                        \
20673   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
20674 _(sw_interface_rx_placement_dump,                                       \
20675   "[<intfc> | sw_if_index <id>]")                                         \
20676 _(sw_interface_set_table,                                               \
20677   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
20678 _(sw_interface_set_mpls_enable,                                         \
20679   "<intfc> | sw_if_index [disable | dis]")                              \
20680 _(sw_interface_set_vpath,                                               \
20681   "<intfc> | sw_if_index <id> enable | disable")                        \
20682 _(sw_interface_set_vxlan_bypass,                                        \
20683   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20684 _(sw_interface_set_geneve_bypass,                                       \
20685   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20686 _(sw_interface_set_l2_xconnect,                                         \
20687   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20688   "enable | disable")                                                   \
20689 _(sw_interface_set_l2_bridge,                                           \
20690   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
20691   "[shg <split-horizon-group>] [bvi]\n"                                 \
20692   "enable | disable")                                                   \
20693 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
20694 _(bridge_domain_add_del,                                                \
20695   "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") \
20696 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
20697 _(l2fib_add_del,                                                        \
20698   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
20699 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
20700 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
20701 _(l2_flags,                                                             \
20702   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20703 _(bridge_flags,                                                         \
20704   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20705 _(tap_create_v2,                                                        \
20706   "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]") \
20707 _(tap_delete_v2,                                                        \
20708   "<vpp-if-name> | sw_if_index <id>")                                   \
20709 _(sw_interface_tap_v2_dump, "")                                         \
20710 _(virtio_pci_create_v2,                                                    \
20711   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled [gro-coalesce] | csum-offload-enabled] [packed] [in-order]") \
20712 _(virtio_pci_delete,                                                    \
20713   "<vpp-if-name> | sw_if_index <id>")                                   \
20714 _(sw_interface_virtio_pci_dump, "")                                     \
20715 _(bond_create,                                                          \
20716   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
20717   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
20718   "[id <if-id>]")                                                       \
20719 _(bond_delete,                                                          \
20720   "<vpp-if-name> | sw_if_index <id>")                                   \
20721 _(bond_add_member,                                                      \
20722   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
20723 _(bond_detach_member,                                                   \
20724   "sw_if_index <n>")                                                    \
20725  _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
20726  _(sw_bond_interface_dump, "<intfc> | sw_if_index <nn>")                \
20727  _(sw_member_interface_dump,                                            \
20728   "<vpp-if-name> | sw_if_index <id>")                                   \
20729 _(ip_table_add_del,                                                     \
20730   "table <n> [ipv6] [add | del]\n")                                     \
20731 _(ip_route_add_del,                                                     \
20732   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
20733   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
20734   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
20735   "[multipath] [count <n>] [del]")                                      \
20736 _(ip_mroute_add_del,                                                    \
20737   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
20738   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
20739 _(mpls_table_add_del,                                                   \
20740   "table <n> [add | del]\n")                                            \
20741 _(mpls_route_add_del,                                                   \
20742   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
20743   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
20744   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
20745   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
20746   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
20747   "[count <n>] [del]")                                                  \
20748 _(mpls_ip_bind_unbind,                                                  \
20749   "<label> <addr/len>")                                                 \
20750 _(mpls_tunnel_add_del,                                                  \
20751   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
20752   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
20753   "[l2-only]  [out-label <n>]")                                         \
20754 _(sr_mpls_policy_add,                                                   \
20755   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
20756 _(sr_mpls_policy_del,                                                   \
20757   "bsid <id>")                                                          \
20758 _(bier_table_add_del,                                                   \
20759   "<label> <sub-domain> <set> <bsl> [del]")                             \
20760 _(bier_route_add_del,                                                   \
20761   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
20762   "[<intfc> | sw_if_index <id>]"                                        \
20763   "[weight <n>] [del] [multipath]")                                     \
20764 _(sw_interface_set_unnumbered,                                          \
20765   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
20766 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
20767 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
20768   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
20769   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
20770   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
20771 _(ip_table_replace_begin, "table <n> [ipv6]")                           \
20772 _(ip_table_flush, "table <n> [ipv6]")                                   \
20773 _(ip_table_replace_end, "table <n> [ipv6]")                             \
20774 _(set_ip_flow_hash,                                                     \
20775   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
20776 _(sw_interface_ip6_enable_disable,                                      \
20777   "<intfc> | sw_if_index <id> enable | disable")                        \
20778 _(l2_patch_add_del,                                                     \
20779   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20780   "enable | disable")                                                   \
20781 _(sr_localsid_add_del,                                                  \
20782   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
20783   "fib-table <num> (end.psp) sw_if_index <num>")                        \
20784 _(classify_add_del_table,                                               \
20785   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
20786   " [del] [del-chain] mask <mask-value>\n"                              \
20787   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
20788   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
20789 _(classify_add_del_session,                                             \
20790   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
20791   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
20792   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
20793   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
20794 _(classify_set_interface_ip_table,                                      \
20795   "<intfc> | sw_if_index <nn> table <nn>")                              \
20796 _(classify_set_interface_l2_tables,                                     \
20797   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20798   "  [other-table <nn>]")                                               \
20799 _(get_node_index, "node <node-name")                                    \
20800 _(add_node_next, "node <node-name> next <next-node-name>")              \
20801 _(l2tpv3_create_tunnel,                                                 \
20802   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
20803   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
20804   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
20805 _(l2tpv3_set_tunnel_cookies,                                            \
20806   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
20807   "[new_remote_cookie <nn>]\n")                                         \
20808 _(l2tpv3_interface_enable_disable,                                      \
20809   "<intfc> | sw_if_index <nn> enable | disable")                        \
20810 _(l2tpv3_set_lookup_key,                                                \
20811   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
20812 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
20813 _(vxlan_offload_rx,                                                     \
20814   "hw { <interface name> | hw_if_index <nn>} "                          \
20815   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
20816 _(vxlan_add_del_tunnel,                                                 \
20817   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20818   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
20819   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20820 _(geneve_add_del_tunnel,                                                \
20821   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20822   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20823   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20824 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
20825 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
20826 _(gre_tunnel_add_del,                                                   \
20827   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
20828   "[teb | erspan <session-id>] [del]")                                  \
20829 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
20830 _(l2_fib_clear_table, "")                                               \
20831 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
20832 _(l2_interface_vlan_tag_rewrite,                                        \
20833   "<intfc> | sw_if_index <nn> \n"                                       \
20834   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
20835   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
20836 _(create_vhost_user_if,                                                 \
20837         "socket <filename> [server] [renumber <dev_instance>] "         \
20838         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
20839         "[mac <mac_address>] [packed]")                                 \
20840 _(modify_vhost_user_if,                                                 \
20841         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
20842         "[server] [renumber <dev_instance>] [gso] [packed]")            \
20843 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
20844 _(sw_interface_vhost_user_dump, "<intfc> | sw_if_index <nn>")           \
20845 _(show_version, "")                                                     \
20846 _(show_threads, "")                                                     \
20847 _(vxlan_gpe_add_del_tunnel,                                             \
20848   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
20849   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20850   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
20851   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
20852 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
20853 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
20854 _(interface_name_renumber,                                              \
20855   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
20856 _(input_acl_set_interface,                                              \
20857   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20858   "  [l2-table <nn>] [del]")                                            \
20859 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
20860 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
20861 _(ip_dump, "ipv4 | ipv6")                                               \
20862 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
20863 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
20864   "  spid_id <n> ")                                                     \
20865 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
20866   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
20867   "  integ_alg <alg> integ_key <hex>")                                  \
20868 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
20869   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
20870   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
20871   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
20872 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
20873   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
20874   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
20875   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
20876   "  [instance <n>]")     \
20877 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
20878 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
20879 _(delete_loopback,"sw_if_index <nn>")                                   \
20880 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
20881 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
20882 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
20883 _(want_interface_events,  "enable|disable")                             \
20884 _(get_first_msg_id, "client <name>")                                    \
20885 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
20886 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
20887   "fib-id <nn> [ip4][ip6][default]")                                    \
20888 _(get_node_graph, " ")                                                  \
20889 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
20890 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
20891 _(ioam_disable, "")                                                     \
20892 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
20893                             " sw_if_index <sw_if_index> p <priority> "  \
20894                             "w <weight>] [del]")                        \
20895 _(one_add_del_locator, "locator-set <locator_name> "                    \
20896                         "iface <intf> | sw_if_index <sw_if_index> "     \
20897                         "p <priority> w <weight> [del]")                \
20898 _(one_add_del_local_eid,"vni <vni> eid "                                \
20899                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20900                          "locator-set <locator_name> [del]"             \
20901                          "[key-id sha1|sha256 secret-key <secret-key>]")\
20902 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
20903 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
20904 _(one_enable_disable, "enable|disable")                                 \
20905 _(one_map_register_enable_disable, "enable|disable")                    \
20906 _(one_map_register_fallback_threshold, "<value>")                       \
20907 _(one_rloc_probe_enable_disable, "enable|disable")                      \
20908 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
20909                                "[seid <seid>] "                         \
20910                                "rloc <locator> p <prio> "               \
20911                                "w <weight> [rloc <loc> ... ] "          \
20912                                "action <action> [del-all]")             \
20913 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
20914                           "<local-eid>")                                \
20915 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
20916 _(one_use_petr, "ip-address> | disable")                                \
20917 _(one_map_request_mode, "src-dst|dst-only")                             \
20918 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
20919 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
20920 _(one_locator_set_dump, "[local | remote]")                             \
20921 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
20922 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
20923                        "[local] | [remote]")                            \
20924 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
20925 _(one_ndp_bd_get, "")                                                   \
20926 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
20927 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
20928 _(one_l2_arp_bd_get, "")                                                \
20929 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
20930 _(one_stats_enable_disable, "enable|disable")                           \
20931 _(show_one_stats_enable_disable, "")                                    \
20932 _(one_eid_table_vni_dump, "")                                           \
20933 _(one_eid_table_map_dump, "l2|l3")                                      \
20934 _(one_map_resolver_dump, "")                                            \
20935 _(one_map_server_dump, "")                                              \
20936 _(one_adjacencies_get, "vni <vni>")                                     \
20937 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
20938 _(show_one_rloc_probe_state, "")                                        \
20939 _(show_one_map_register_state, "")                                      \
20940 _(show_one_status, "")                                                  \
20941 _(one_stats_dump, "")                                                   \
20942 _(one_stats_flush, "")                                                  \
20943 _(one_get_map_request_itr_rlocs, "")                                    \
20944 _(one_map_register_set_ttl, "<ttl>")                                    \
20945 _(one_set_transport_protocol, "udp|api")                                \
20946 _(one_get_transport_protocol, "")                                       \
20947 _(one_enable_disable_xtr_mode, "enable|disable")                        \
20948 _(one_show_xtr_mode, "")                                                \
20949 _(one_enable_disable_pitr_mode, "enable|disable")                       \
20950 _(one_show_pitr_mode, "")                                               \
20951 _(one_enable_disable_petr_mode, "enable|disable")                       \
20952 _(one_show_petr_mode, "")                                               \
20953 _(show_one_nsh_mapping, "")                                             \
20954 _(show_one_pitr, "")                                                    \
20955 _(show_one_use_petr, "")                                                \
20956 _(show_one_map_request_mode, "")                                        \
20957 _(show_one_map_register_ttl, "")                                        \
20958 _(show_one_map_register_fallback_threshold, "")                         \
20959 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
20960                             " sw_if_index <sw_if_index> p <priority> "  \
20961                             "w <weight>] [del]")                        \
20962 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
20963                         "iface <intf> | sw_if_index <sw_if_index> "     \
20964                         "p <priority> w <weight> [del]")                \
20965 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
20966                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20967                          "locator-set <locator_name> [del]"             \
20968                          "[key-id sha1|sha256 secret-key <secret-key>]") \
20969 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
20970 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
20971 _(lisp_enable_disable, "enable|disable")                                \
20972 _(lisp_map_register_enable_disable, "enable|disable")                   \
20973 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
20974 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
20975                                "[seid <seid>] "                         \
20976                                "rloc <locator> p <prio> "               \
20977                                "w <weight> [rloc <loc> ... ] "          \
20978                                "action <action> [del-all]")             \
20979 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
20980                           "<local-eid>")                                \
20981 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
20982 _(lisp_use_petr, "<ip-address> | disable")                              \
20983 _(lisp_map_request_mode, "src-dst|dst-only")                            \
20984 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
20985 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
20986 _(lisp_locator_set_dump, "[local | remote]")                            \
20987 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
20988 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
20989                        "[local] | [remote]")                            \
20990 _(lisp_eid_table_vni_dump, "")                                          \
20991 _(lisp_eid_table_map_dump, "l2|l3")                                     \
20992 _(lisp_map_resolver_dump, "")                                           \
20993 _(lisp_map_server_dump, "")                                             \
20994 _(lisp_adjacencies_get, "vni <vni>")                                    \
20995 _(gpe_fwd_entry_vnis_get, "")                                           \
20996 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
20997 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
20998                                 "[table <table-id>]")                   \
20999 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
21000 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
21001 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
21002 _(gpe_get_encap_mode, "")                                               \
21003 _(lisp_gpe_add_del_iface, "up|down")                                    \
21004 _(lisp_gpe_enable_disable, "enable|disable")                            \
21005 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
21006   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
21007 _(show_lisp_rloc_probe_state, "")                                       \
21008 _(show_lisp_map_register_state, "")                                     \
21009 _(show_lisp_status, "")                                                 \
21010 _(lisp_get_map_request_itr_rlocs, "")                                   \
21011 _(show_lisp_pitr, "")                                                   \
21012 _(show_lisp_use_petr, "")                                               \
21013 _(show_lisp_map_request_mode, "")                                       \
21014 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
21015 _(af_packet_delete, "name <host interface name>")                       \
21016 _(af_packet_dump, "")                                                   \
21017 _(policer_add_del, "name <policer name> <params> [del]")                \
21018 _(policer_dump, "[name <policer name>]")                                \
21019 _(policer_classify_set_interface,                                       \
21020   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21021   "  [l2-table <nn>] [del]")                                            \
21022 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
21023 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
21024 _(mpls_table_dump, "")                                                  \
21025 _(mpls_route_dump, "table-id <ID>")                                     \
21026 _(classify_table_ids, "")                                               \
21027 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
21028 _(classify_table_info, "table_id <nn>")                                 \
21029 _(classify_session_dump, "table_id <nn>")                               \
21030 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
21031     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
21032     "[template_interval <nn>] [udp_checksum]")                          \
21033 _(ipfix_exporter_dump, "")                                              \
21034 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
21035 _(ipfix_classify_stream_dump, "")                                       \
21036 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
21037 _(ipfix_classify_table_dump, "")                                        \
21038 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
21039 _(sw_interface_span_dump, "[l2]")                                           \
21040 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
21041 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
21042 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
21043 _(pg_enable_disable, "[stream <id>] disable")                           \
21044 _(pg_interface_enable_disable_coalesce, "<intf> | sw_if_index <nn> enable | disable")  \
21045 _(ip_source_and_port_range_check_add_del,                               \
21046   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
21047 _(ip_source_and_port_range_check_interface_add_del,                     \
21048   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
21049   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
21050 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
21051 _(l2_interface_pbb_tag_rewrite,                                         \
21052   "<intfc> | sw_if_index <nn> \n"                                       \
21053   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
21054   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
21055 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
21056 _(flow_classify_set_interface,                                          \
21057   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
21058 _(flow_classify_dump, "type [ip4|ip6]")                                 \
21059 _(ip_table_dump, "")                                                    \
21060 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
21061 _(ip_mtable_dump, "")                                                   \
21062 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
21063 _(feature_enable_disable, "arc_name <arc_name> "                        \
21064   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
21065 _(feature_gso_enable_disable, "<intfc> | sw_if_index <nn> "             \
21066   "[enable | disable] ")                                                \
21067 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
21068 "[disable]")                                                            \
21069 _(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> "       \
21070   "mac <mac-address> [del]")                                            \
21071 _(l2_xconnect_dump, "")                                                 \
21072 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
21073 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
21074 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
21075 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
21076 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
21077 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
21078   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
21079 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
21080 _(sock_init_shm, "size <nnn>")                                          \
21081 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
21082 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
21083   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
21084 _(session_rules_dump, "")                                               \
21085 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
21086 _(output_acl_set_interface,                                             \
21087   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21088   "  [l2-table <nn>] [del]")                                            \
21089 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
21090
21091 /* List of command functions, CLI names map directly to functions */
21092 #define foreach_cli_function                                    \
21093 _(comment, "usage: comment <ignore-rest-of-line>")              \
21094 _(dump_interface_table, "usage: dump_interface_table")          \
21095 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
21096 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
21097 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
21098 _(dump_macro_table, "usage: dump_macro_table ")                 \
21099 _(dump_node_table, "usage: dump_node_table")                    \
21100 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
21101 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
21102 _(elog_disable, "usage: elog_disable")                          \
21103 _(elog_enable, "usage: elog_enable")                            \
21104 _(elog_save, "usage: elog_save <filename>")                     \
21105 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
21106 _(echo, "usage: echo <message>")                                \
21107 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
21108 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
21109 _(help, "usage: help")                                          \
21110 _(q, "usage: quit")                                             \
21111 _(quit, "usage: quit")                                          \
21112 _(search_node_table, "usage: search_node_table <name>...")      \
21113 _(set, "usage: set <variable-name> <value>")                    \
21114 _(script, "usage: script <file-name>")                          \
21115 _(statseg, "usage: statseg")                                    \
21116 _(unset, "usage: unset <variable-name>")
21117
21118 #define _(N,n)                                  \
21119     static void vl_api_##n##_t_handler_uni      \
21120     (vl_api_##n##_t * mp)                       \
21121     {                                           \
21122         vat_main_t * vam = &vat_main;           \
21123         if (vam->json_output) {                 \
21124             vl_api_##n##_t_handler_json(mp);    \
21125         } else {                                \
21126             vl_api_##n##_t_handler(mp);         \
21127         }                                       \
21128     }
21129 foreach_vpe_api_reply_msg;
21130 #if VPP_API_TEST_BUILTIN == 0
21131 foreach_standalone_reply_msg;
21132 #endif
21133 #undef _
21134
21135 void
21136 vat_api_hookup (vat_main_t * vam)
21137 {
21138 #define _(N,n)                                                  \
21139     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
21140                            vl_api_##n##_t_handler_uni,          \
21141                            vl_noop_handler,                     \
21142                            vl_api_##n##_t_endian,               \
21143                            vl_api_##n##_t_print,                \
21144                            sizeof(vl_api_##n##_t), 1);
21145   foreach_vpe_api_reply_msg;
21146 #if VPP_API_TEST_BUILTIN == 0
21147   foreach_standalone_reply_msg;
21148 #endif
21149 #undef _
21150
21151 #if (VPP_API_TEST_BUILTIN==0)
21152   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
21153
21154   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
21155
21156   vam->function_by_name = hash_create_string (0, sizeof (uword));
21157
21158   vam->help_by_name = hash_create_string (0, sizeof (uword));
21159 #endif
21160
21161   /* API messages we can send */
21162 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
21163   foreach_vpe_api_msg;
21164 #undef _
21165
21166   /* Help strings */
21167 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21168   foreach_vpe_api_msg;
21169 #undef _
21170
21171   /* CLI functions */
21172 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
21173   foreach_cli_function;
21174 #undef _
21175
21176   /* Help strings */
21177 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21178   foreach_cli_function;
21179 #undef _
21180 }
21181
21182 #if VPP_API_TEST_BUILTIN
21183 static clib_error_t *
21184 vat_api_hookup_shim (vlib_main_t * vm)
21185 {
21186   vat_api_hookup (&vat_main);
21187   return 0;
21188 }
21189
21190 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
21191 #endif
21192
21193 /*
21194  * fd.io coding-style-patch-verification: ON
21195  *
21196  * Local Variables:
21197  * eval: (c-set-style "gnu")
21198  * End:
21199  */