vat: add infrastructure to align vnet test code and plugin test code
[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/gre/gre.h>
33 #include <vnet/vxlan-gpe/vxlan_gpe.h>
34 #include <vnet/lisp-gpe/lisp_gpe.h>
35
36 #include <vpp/api/vpe_msg_enum.h>
37 #include <vnet/l2/l2_classify.h>
38 #include <vnet/l2/l2_vtr.h>
39 #include <vnet/classify/in_out_acl.h>
40 #include <vnet/classify/policer_classify.h>
41 #include <vnet/classify/flow_classify.h>
42 #include <vnet/mpls/mpls.h>
43 #include <vnet/ipsec/ipsec.h>
44 #include <inttypes.h>
45 #include <vnet/ip/ip6_hop_by_hop.h>
46 #include <vnet/ip/ip_source_and_port_range_check.h>
47 #include <vnet/policer/xlate.h>
48 #include <vnet/span/span.h>
49 #include <vnet/policer/policer.h>
50 #include <vnet/policer/police.h>
51 #include <vnet/mfib/mfib_types.h>
52 #include <vnet/bonding/node.h>
53 #include <vnet/qos/qos_types.h>
54 #include <vnet/ethernet/ethernet_types_api.h>
55 #include <vnet/ip/ip_types_api.h>
56 #include "vat/json_format.h"
57 #include <vnet/ip/ip_types_api.h>
58 #include <vnet/ethernet/ethernet_types_api.h>
59
60 #include <inttypes.h>
61 #include <sys/stat.h>
62
63 #define vl_typedefs             /* define message structures */
64 #include <vpp/api/vpe_all_api_h.h>
65 #undef vl_typedefs
66
67 /* declare message handlers for each api */
68
69 #define vl_endianfun            /* define message structures */
70 #include <vpp/api/vpe_all_api_h.h>
71 #undef vl_endianfun
72
73 /* instantiate all the print functions we know about */
74 #if VPP_API_TEST_BUILTIN == 0
75 #define vl_print(handle, ...)
76 #else
77 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
78 #endif
79 #define vl_printfun
80 #include <vpp/api/vpe_all_api_h.h>
81 #undef vl_printfun
82
83 #define __plugin_msg_base 0
84 #include <vlibapi/vat_helper_macros.h>
85
86 #include <vnet/format_fns.h>
87
88 void vl_api_set_elog_main (elog_main_t * m);
89 int vl_api_set_elog_trace_api_messages (int enable);
90
91 #if VPP_API_TEST_BUILTIN == 0
92 #include <netdb.h>
93
94 u32
95 vl (void *p)
96 {
97   return vec_len (p);
98 }
99
100 int
101 vat_socket_connect (vat_main_t * vam)
102 {
103   int rv;
104   api_main_t *am = vlibapi_get_main ();
105   vam->socket_client_main = &socket_client_main;
106   if ((rv = vl_socket_client_connect ((char *) vam->socket_name,
107                                       "vpp_api_test",
108                                       0 /* default socket rx, tx buffer */ )))
109     return rv;
110
111   /* vpp expects the client index in network order */
112   vam->my_client_index = htonl (socket_client_main.client_index);
113   am->my_client_index = vam->my_client_index;
114   return 0;
115 }
116 #else /* vpp built-in case, we don't do sockets... */
117 int
118 vat_socket_connect (vat_main_t * vam)
119 {
120   return 0;
121 }
122
123 int
124 vl_socket_client_read (int wait)
125 {
126   return -1;
127 };
128
129 int
130 vl_socket_client_write ()
131 {
132   return -1;
133 };
134
135 void *
136 vl_socket_client_msg_alloc (int nbytes)
137 {
138   return 0;
139 }
140 #endif
141
142
143 f64
144 vat_time_now (vat_main_t * vam)
145 {
146 #if VPP_API_TEST_BUILTIN
147   return vlib_time_now (vam->vlib_main);
148 #else
149   return clib_time_now (&vam->clib_time);
150 #endif
151 }
152
153 void
154 errmsg (char *fmt, ...)
155 {
156   vat_main_t *vam = &vat_main;
157   va_list va;
158   u8 *s;
159
160   va_start (va, fmt);
161   s = va_format (0, fmt, &va);
162   va_end (va);
163
164   vec_add1 (s, 0);
165
166 #if VPP_API_TEST_BUILTIN
167   vlib_cli_output (vam->vlib_main, (char *) s);
168 #else
169   {
170     if (vam->ifp != stdin)
171       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
172                vam->input_line_number);
173     else
174       fformat (vam->ofp, "%s\n", (char *) s);
175     fflush (vam->ofp);
176   }
177 #endif
178
179   vec_free (s);
180 }
181
182 #if VPP_API_TEST_BUILTIN == 0
183 static uword
184 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
185 {
186   vat_main_t *vam = va_arg (*args, vat_main_t *);
187   u32 *result = va_arg (*args, u32 *);
188   u8 *if_name;
189   uword *p;
190
191   if (!unformat (input, "%s", &if_name))
192     return 0;
193
194   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
195   if (p == 0)
196     return 0;
197   *result = p[0];
198   return 1;
199 }
200
201 static uword
202 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
203 {
204   return 0;
205 }
206
207 /* Parse an IP4 address %d.%d.%d.%d. */
208 uword
209 unformat_ip4_address (unformat_input_t * input, va_list * args)
210 {
211   u8 *result = va_arg (*args, u8 *);
212   unsigned a[4];
213
214   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
215     return 0;
216
217   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
218     return 0;
219
220   result[0] = a[0];
221   result[1] = a[1];
222   result[2] = a[2];
223   result[3] = a[3];
224
225   return 1;
226 }
227
228 uword
229 unformat_ethernet_address (unformat_input_t * input, va_list * args)
230 {
231   u8 *result = va_arg (*args, u8 *);
232   u32 i, a[6];
233
234   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
235                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
236     return 0;
237
238   /* Check range. */
239   for (i = 0; i < 6; i++)
240     if (a[i] >= (1 << 8))
241       return 0;
242
243   for (i = 0; i < 6; i++)
244     result[i] = a[i];
245
246   return 1;
247 }
248
249 /* Returns ethernet type as an int in host byte order. */
250 uword
251 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
252                                         va_list * args)
253 {
254   u16 *result = va_arg (*args, u16 *);
255   int type;
256
257   /* Numeric type. */
258   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
259     {
260       if (type >= (1 << 16))
261         return 0;
262       *result = type;
263       return 1;
264     }
265   return 0;
266 }
267
268 /* Parse an IP46 address. */
269 uword
270 unformat_ip46_address (unformat_input_t * input, va_list * args)
271 {
272   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
273   ip46_type_t type = va_arg (*args, ip46_type_t);
274   if ((type != IP46_TYPE_IP6) &&
275       unformat (input, "%U", unformat_ip4_address, &ip46->ip4))
276     {
277       ip46_address_mask_ip4 (ip46);
278       return 1;
279     }
280   else if ((type != IP46_TYPE_IP4) &&
281            unformat (input, "%U", unformat_ip6_address, &ip46->ip6))
282     {
283       return 1;
284     }
285   return 0;
286 }
287
288 /* Parse an IP6 address. */
289 uword
290 unformat_ip6_address (unformat_input_t * input, va_list * args)
291 {
292   ip6_address_t *result = va_arg (*args, ip6_address_t *);
293   u16 hex_quads[8];
294   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
295   uword c, n_colon, double_colon_index;
296
297   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
298   double_colon_index = ARRAY_LEN (hex_quads);
299   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
300     {
301       hex_digit = 16;
302       if (c >= '0' && c <= '9')
303         hex_digit = c - '0';
304       else if (c >= 'a' && c <= 'f')
305         hex_digit = c + 10 - 'a';
306       else if (c >= 'A' && c <= 'F')
307         hex_digit = c + 10 - 'A';
308       else if (c == ':' && n_colon < 2)
309         n_colon++;
310       else
311         {
312           unformat_put_input (input);
313           break;
314         }
315
316       /* Too many hex quads. */
317       if (n_hex_quads >= ARRAY_LEN (hex_quads))
318         return 0;
319
320       if (hex_digit < 16)
321         {
322           hex_quad = (hex_quad << 4) | hex_digit;
323
324           /* Hex quad must fit in 16 bits. */
325           if (n_hex_digits >= 4)
326             return 0;
327
328           n_colon = 0;
329           n_hex_digits++;
330         }
331
332       /* Save position of :: */
333       if (n_colon == 2)
334         {
335           /* More than one :: ? */
336           if (double_colon_index < ARRAY_LEN (hex_quads))
337             return 0;
338           double_colon_index = n_hex_quads;
339         }
340
341       if (n_colon > 0 && n_hex_digits > 0)
342         {
343           hex_quads[n_hex_quads++] = hex_quad;
344           hex_quad = 0;
345           n_hex_digits = 0;
346         }
347     }
348
349   if (n_hex_digits > 0)
350     hex_quads[n_hex_quads++] = hex_quad;
351
352   {
353     word i;
354
355     /* Expand :: to appropriate number of zero hex quads. */
356     if (double_colon_index < ARRAY_LEN (hex_quads))
357       {
358         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
359
360         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
361           hex_quads[n_zero + i] = hex_quads[i];
362
363         for (i = 0; i < n_zero; i++)
364           hex_quads[double_colon_index + i] = 0;
365
366         n_hex_quads = ARRAY_LEN (hex_quads);
367       }
368
369     /* Too few hex quads given. */
370     if (n_hex_quads < ARRAY_LEN (hex_quads))
371       return 0;
372
373     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
374       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
375
376     return 1;
377   }
378 }
379
380 uword
381 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
382 {
383   u32 *r = va_arg (*args, u32 *);
384
385   if (0);
386 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
387   foreach_ipsec_policy_action
388 #undef _
389     else
390     return 0;
391   return 1;
392 }
393
394 u8 *
395 format_ipsec_crypto_alg (u8 * s, va_list * args)
396 {
397   u32 i = va_arg (*args, u32);
398   u8 *t = 0;
399
400   switch (i)
401     {
402 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
403       foreach_ipsec_crypto_alg
404 #undef _
405     default:
406       return format (s, "unknown");
407     }
408   return format (s, "%s", t);
409 }
410
411 u8 *
412 format_ipsec_integ_alg (u8 * s, va_list * args)
413 {
414   u32 i = va_arg (*args, u32);
415   u8 *t = 0;
416
417   switch (i)
418     {
419 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
420       foreach_ipsec_integ_alg
421 #undef _
422     default:
423       return format (s, "unknown");
424     }
425   return format (s, "%s", t);
426 }
427
428 #else /* VPP_API_TEST_BUILTIN == 1 */
429 static uword
430 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
431 {
432   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
433   vnet_main_t *vnm = vnet_get_main ();
434   u32 *result = va_arg (*args, u32 *);
435
436   return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
437 }
438
439 static uword
440 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
441 {
442   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
443   vnet_main_t *vnm = vnet_get_main ();
444   u32 *result = va_arg (*args, u32 *);
445
446   return unformat (input, "%U", unformat_vnet_hw_interface, vnm, result);
447 }
448
449 #endif /* VPP_API_TEST_BUILTIN */
450
451 uword
452 unformat_ipsec_api_crypto_alg (unformat_input_t * input, va_list * args)
453 {
454   u32 *r = va_arg (*args, u32 *);
455
456   if (0);
457 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_CRYPTO_ALG_##f;
458   foreach_ipsec_crypto_alg
459 #undef _
460     else
461     return 0;
462   return 1;
463 }
464
465 uword
466 unformat_ipsec_api_integ_alg (unformat_input_t * input, va_list * args)
467 {
468   u32 *r = va_arg (*args, u32 *);
469
470   if (0);
471 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_INTEG_ALG_##f;
472   foreach_ipsec_integ_alg
473 #undef _
474     else
475     return 0;
476   return 1;
477 }
478
479 static uword
480 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
481 {
482   u8 *r = va_arg (*args, u8 *);
483
484   if (unformat (input, "kbps"))
485     *r = SSE2_QOS_RATE_KBPS;
486   else if (unformat (input, "pps"))
487     *r = SSE2_QOS_RATE_PPS;
488   else
489     return 0;
490   return 1;
491 }
492
493 static uword
494 unformat_policer_round_type (unformat_input_t * input, va_list * args)
495 {
496   u8 *r = va_arg (*args, u8 *);
497
498   if (unformat (input, "closest"))
499     *r = SSE2_QOS_ROUND_TO_CLOSEST;
500   else if (unformat (input, "up"))
501     *r = SSE2_QOS_ROUND_TO_UP;
502   else if (unformat (input, "down"))
503     *r = SSE2_QOS_ROUND_TO_DOWN;
504   else
505     return 0;
506   return 1;
507 }
508
509 static uword
510 unformat_policer_type (unformat_input_t * input, va_list * args)
511 {
512   u8 *r = va_arg (*args, u8 *);
513
514   if (unformat (input, "1r2c"))
515     *r = SSE2_QOS_POLICER_TYPE_1R2C;
516   else if (unformat (input, "1r3c"))
517     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
518   else if (unformat (input, "2r3c-2698"))
519     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
520   else if (unformat (input, "2r3c-4115"))
521     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
522   else if (unformat (input, "2r3c-mef5cf1"))
523     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
524   else
525     return 0;
526   return 1;
527 }
528
529 static uword
530 unformat_dscp (unformat_input_t * input, va_list * va)
531 {
532   u8 *r = va_arg (*va, u8 *);
533
534   if (0);
535 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
536   foreach_vnet_dscp
537 #undef _
538     else
539     return 0;
540   return 1;
541 }
542
543 static uword
544 unformat_policer_action_type (unformat_input_t * input, va_list * va)
545 {
546   sse2_qos_pol_action_params_st *a
547     = va_arg (*va, sse2_qos_pol_action_params_st *);
548
549   if (unformat (input, "drop"))
550     a->action_type = SSE2_QOS_ACTION_DROP;
551   else if (unformat (input, "transmit"))
552     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
553   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
554     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
555   else
556     return 0;
557   return 1;
558 }
559
560 static uword
561 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
562 {
563   u32 *r = va_arg (*va, u32 *);
564   u32 tid;
565
566   if (unformat (input, "ip4"))
567     tid = POLICER_CLASSIFY_TABLE_IP4;
568   else if (unformat (input, "ip6"))
569     tid = POLICER_CLASSIFY_TABLE_IP6;
570   else if (unformat (input, "l2"))
571     tid = POLICER_CLASSIFY_TABLE_L2;
572   else
573     return 0;
574
575   *r = tid;
576   return 1;
577 }
578
579 static uword
580 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
581 {
582   u32 *r = va_arg (*va, u32 *);
583   u32 tid;
584
585   if (unformat (input, "ip4"))
586     tid = FLOW_CLASSIFY_TABLE_IP4;
587   else if (unformat (input, "ip6"))
588     tid = FLOW_CLASSIFY_TABLE_IP6;
589   else
590     return 0;
591
592   *r = tid;
593   return 1;
594 }
595
596 #if (VPP_API_TEST_BUILTIN==0)
597
598 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
599 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
600 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
601 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
602
603 uword
604 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
605 {
606   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
607   mfib_itf_attribute_t attr;
608
609   old = *iflags;
610   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
611   {
612     if (unformat (input, mfib_itf_flag_long_names[attr]))
613       *iflags |= (1 << attr);
614   }
615   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
616   {
617     if (unformat (input, mfib_itf_flag_names[attr]))
618       *iflags |= (1 << attr);
619   }
620
621   return (old == *iflags ? 0 : 1);
622 }
623
624 uword
625 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
626 {
627   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
628   mfib_entry_attribute_t attr;
629
630   old = *eflags;
631   FOR_EACH_MFIB_ATTRIBUTE (attr)
632   {
633     if (unformat (input, mfib_flag_long_names[attr]))
634       *eflags |= (1 << attr);
635   }
636   FOR_EACH_MFIB_ATTRIBUTE (attr)
637   {
638     if (unformat (input, mfib_flag_names[attr]))
639       *eflags |= (1 << attr);
640   }
641
642   return (old == *eflags ? 0 : 1);
643 }
644
645 u8 *
646 format_ip4_address (u8 * s, va_list * args)
647 {
648   u8 *a = va_arg (*args, u8 *);
649   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
650 }
651
652 u8 *
653 format_ip6_address (u8 * s, va_list * args)
654 {
655   ip6_address_t *a = va_arg (*args, ip6_address_t *);
656   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
657
658   i_max_n_zero = ARRAY_LEN (a->as_u16);
659   max_n_zeros = 0;
660   i_first_zero = i_max_n_zero;
661   n_zeros = 0;
662   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
663     {
664       u32 is_zero = a->as_u16[i] == 0;
665       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
666         {
667           i_first_zero = i;
668           n_zeros = 0;
669         }
670       n_zeros += is_zero;
671       if ((!is_zero && n_zeros > max_n_zeros)
672           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
673         {
674           i_max_n_zero = i_first_zero;
675           max_n_zeros = n_zeros;
676           i_first_zero = ARRAY_LEN (a->as_u16);
677           n_zeros = 0;
678         }
679     }
680
681   last_double_colon = 0;
682   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
683     {
684       if (i == i_max_n_zero && max_n_zeros > 1)
685         {
686           s = format (s, "::");
687           i += max_n_zeros - 1;
688           last_double_colon = 1;
689         }
690       else
691         {
692           s = format (s, "%s%x",
693                       (last_double_colon || i == 0) ? "" : ":",
694                       clib_net_to_host_u16 (a->as_u16[i]));
695           last_double_colon = 0;
696         }
697     }
698
699   return s;
700 }
701
702 /* Format an IP46 address. */
703 u8 *
704 format_ip46_address (u8 * s, va_list * args)
705 {
706   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
707   ip46_type_t type = va_arg (*args, ip46_type_t);
708   int is_ip4 = 1;
709
710   switch (type)
711     {
712     case IP46_TYPE_ANY:
713       is_ip4 = ip46_address_is_ip4 (ip46);
714       break;
715     case IP46_TYPE_IP4:
716       is_ip4 = 1;
717       break;
718     case IP46_TYPE_IP6:
719       is_ip4 = 0;
720       break;
721     }
722
723   return is_ip4 ?
724     format (s, "%U", format_ip4_address, &ip46->ip4) :
725     format (s, "%U", format_ip6_address, &ip46->ip6);
726 }
727
728 u8 *
729 format_ethernet_address (u8 * s, va_list * args)
730 {
731   u8 *a = va_arg (*args, u8 *);
732
733   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
734                  a[0], a[1], a[2], a[3], a[4], a[5]);
735 }
736 #endif
737
738 static void
739 increment_v4_address (vl_api_ip4_address_t * i)
740 {
741   ip4_address_t *a = (ip4_address_t *) i;
742   u32 v;
743
744   v = ntohl (a->as_u32) + 1;
745   a->as_u32 = ntohl (v);
746 }
747
748 static void
749 increment_v6_address (vl_api_ip6_address_t * i)
750 {
751   ip6_address_t *a = (ip6_address_t *) i;
752   u64 v0, v1;
753
754   v0 = clib_net_to_host_u64 (a->as_u64[0]);
755   v1 = clib_net_to_host_u64 (a->as_u64[1]);
756
757   v1 += 1;
758   if (v1 == 0)
759     v0 += 1;
760   a->as_u64[0] = clib_net_to_host_u64 (v0);
761   a->as_u64[1] = clib_net_to_host_u64 (v1);
762 }
763
764 static void
765 increment_address (vl_api_address_t * a)
766 {
767   if (a->af == ADDRESS_IP4)
768     increment_v4_address (&a->un.ip4);
769   else if (a->af == ADDRESS_IP6)
770     increment_v6_address (&a->un.ip6);
771 }
772
773 static void
774 set_ip4_address (vl_api_address_t * a, u32 v)
775 {
776   if (a->af == ADDRESS_IP4)
777     {
778       ip4_address_t *i = (ip4_address_t *) & a->un.ip4;
779       i->as_u32 = v;
780     }
781 }
782
783 void
784 ip_set (ip46_address_t * dst, void *src, u8 is_ip4)
785 {
786   if (is_ip4)
787     dst->ip4.as_u32 = ((ip4_address_t *) src)->as_u32;
788   else
789     clib_memcpy_fast (&dst->ip6, (ip6_address_t *) src,
790                       sizeof (ip6_address_t));
791 }
792
793 static void
794 increment_mac_address (u8 * mac)
795 {
796   u64 tmp = *((u64 *) mac);
797   tmp = clib_net_to_host_u64 (tmp);
798   tmp += 1 << 16;               /* skip unused (least significant) octets */
799   tmp = clib_host_to_net_u64 (tmp);
800
801   clib_memcpy (mac, &tmp, 6);
802 }
803
804 static void
805 vat_json_object_add_address (vat_json_node_t * node,
806                              const char *str, const vl_api_address_t * addr)
807 {
808   if (ADDRESS_IP6 == addr->af)
809     {
810       struct in6_addr ip6;
811
812       clib_memcpy (&ip6, &addr->un.ip6, sizeof (ip6));
813       vat_json_object_add_ip6 (node, str, ip6);
814     }
815   else
816     {
817       struct in_addr ip4;
818
819       clib_memcpy (&ip4, &addr->un.ip4, sizeof (ip4));
820       vat_json_object_add_ip4 (node, str, ip4);
821     }
822 }
823
824 static void
825 vat_json_object_add_prefix (vat_json_node_t * node,
826                             const vl_api_prefix_t * prefix)
827 {
828   vat_json_object_add_uint (node, "len", prefix->len);
829   vat_json_object_add_address (node, "address", &prefix->address);
830 }
831
832 static void vl_api_create_loopback_reply_t_handler
833   (vl_api_create_loopback_reply_t * mp)
834 {
835   vat_main_t *vam = &vat_main;
836   i32 retval = ntohl (mp->retval);
837
838   vam->retval = retval;
839   vam->regenerate_interface_table = 1;
840   vam->sw_if_index = ntohl (mp->sw_if_index);
841   vam->result_ready = 1;
842 }
843
844 static void vl_api_create_loopback_reply_t_handler_json
845   (vl_api_create_loopback_reply_t * mp)
846 {
847   vat_main_t *vam = &vat_main;
848   vat_json_node_t node;
849
850   vat_json_init_object (&node);
851   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
852   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
853
854   vat_json_print (vam->ofp, &node);
855   vat_json_free (&node);
856   vam->retval = ntohl (mp->retval);
857   vam->result_ready = 1;
858 }
859
860 static void vl_api_create_loopback_instance_reply_t_handler
861   (vl_api_create_loopback_instance_reply_t * mp)
862 {
863   vat_main_t *vam = &vat_main;
864   i32 retval = ntohl (mp->retval);
865
866   vam->retval = retval;
867   vam->regenerate_interface_table = 1;
868   vam->sw_if_index = ntohl (mp->sw_if_index);
869   vam->result_ready = 1;
870 }
871
872 static void vl_api_create_loopback_instance_reply_t_handler_json
873   (vl_api_create_loopback_instance_reply_t * mp)
874 {
875   vat_main_t *vam = &vat_main;
876   vat_json_node_t node;
877
878   vat_json_init_object (&node);
879   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
880   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
881
882   vat_json_print (vam->ofp, &node);
883   vat_json_free (&node);
884   vam->retval = ntohl (mp->retval);
885   vam->result_ready = 1;
886 }
887
888 static void vl_api_af_packet_create_reply_t_handler
889   (vl_api_af_packet_create_reply_t * mp)
890 {
891   vat_main_t *vam = &vat_main;
892   i32 retval = ntohl (mp->retval);
893
894   vam->retval = retval;
895   vam->regenerate_interface_table = 1;
896   vam->sw_if_index = ntohl (mp->sw_if_index);
897   vam->result_ready = 1;
898 }
899
900 static void vl_api_af_packet_create_reply_t_handler_json
901   (vl_api_af_packet_create_reply_t * mp)
902 {
903   vat_main_t *vam = &vat_main;
904   vat_json_node_t node;
905
906   vat_json_init_object (&node);
907   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
908   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
909
910   vat_json_print (vam->ofp, &node);
911   vat_json_free (&node);
912
913   vam->retval = ntohl (mp->retval);
914   vam->result_ready = 1;
915 }
916
917 static void vl_api_create_vlan_subif_reply_t_handler
918   (vl_api_create_vlan_subif_reply_t * mp)
919 {
920   vat_main_t *vam = &vat_main;
921   i32 retval = ntohl (mp->retval);
922
923   vam->retval = retval;
924   vam->regenerate_interface_table = 1;
925   vam->sw_if_index = ntohl (mp->sw_if_index);
926   vam->result_ready = 1;
927 }
928
929 static void vl_api_create_vlan_subif_reply_t_handler_json
930   (vl_api_create_vlan_subif_reply_t * mp)
931 {
932   vat_main_t *vam = &vat_main;
933   vat_json_node_t node;
934
935   vat_json_init_object (&node);
936   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
937   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
938
939   vat_json_print (vam->ofp, &node);
940   vat_json_free (&node);
941
942   vam->retval = ntohl (mp->retval);
943   vam->result_ready = 1;
944 }
945
946 static void vl_api_create_subif_reply_t_handler
947   (vl_api_create_subif_reply_t * mp)
948 {
949   vat_main_t *vam = &vat_main;
950   i32 retval = ntohl (mp->retval);
951
952   vam->retval = retval;
953   vam->regenerate_interface_table = 1;
954   vam->sw_if_index = ntohl (mp->sw_if_index);
955   vam->result_ready = 1;
956 }
957
958 static void vl_api_create_subif_reply_t_handler_json
959   (vl_api_create_subif_reply_t * mp)
960 {
961   vat_main_t *vam = &vat_main;
962   vat_json_node_t node;
963
964   vat_json_init_object (&node);
965   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
966   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
967
968   vat_json_print (vam->ofp, &node);
969   vat_json_free (&node);
970
971   vam->retval = ntohl (mp->retval);
972   vam->result_ready = 1;
973 }
974
975 static void vl_api_interface_name_renumber_reply_t_handler
976   (vl_api_interface_name_renumber_reply_t * mp)
977 {
978   vat_main_t *vam = &vat_main;
979   i32 retval = ntohl (mp->retval);
980
981   vam->retval = retval;
982   vam->regenerate_interface_table = 1;
983   vam->result_ready = 1;
984 }
985
986 static void vl_api_interface_name_renumber_reply_t_handler_json
987   (vl_api_interface_name_renumber_reply_t * mp)
988 {
989   vat_main_t *vam = &vat_main;
990   vat_json_node_t node;
991
992   vat_json_init_object (&node);
993   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
994
995   vat_json_print (vam->ofp, &node);
996   vat_json_free (&node);
997
998   vam->retval = ntohl (mp->retval);
999   vam->result_ready = 1;
1000 }
1001
1002 /*
1003  * Special-case: build the interface table, maintain
1004  * the next loopback sw_if_index vbl.
1005  */
1006 static void vl_api_sw_interface_details_t_handler
1007   (vl_api_sw_interface_details_t * mp)
1008 {
1009   vat_main_t *vam = &vat_main;
1010   u8 *s = format (0, "%s%c", mp->interface_name, 0);
1011
1012   hash_set_mem (vam->sw_if_index_by_interface_name, s,
1013                 ntohl (mp->sw_if_index));
1014
1015   /* In sub interface case, fill the sub interface table entry */
1016   if (mp->sw_if_index != mp->sup_sw_if_index)
1017     {
1018       sw_interface_subif_t *sub = NULL;
1019
1020       vec_add2 (vam->sw_if_subif_table, sub, 1);
1021
1022       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
1023       strncpy ((char *) sub->interface_name, (char *) s,
1024                vec_len (sub->interface_name));
1025       sub->sw_if_index = ntohl (mp->sw_if_index);
1026       sub->sub_id = ntohl (mp->sub_id);
1027
1028       sub->raw_flags = ntohl (mp->sub_if_flags & SUB_IF_API_FLAG_MASK_VNET);
1029
1030       sub->sub_number_of_tags = mp->sub_number_of_tags;
1031       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
1032       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
1033
1034       /* vlan tag rewrite */
1035       sub->vtr_op = ntohl (mp->vtr_op);
1036       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
1037       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
1038       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
1039     }
1040 }
1041
1042 static void vl_api_sw_interface_details_t_handler_json
1043   (vl_api_sw_interface_details_t * mp)
1044 {
1045   vat_main_t *vam = &vat_main;
1046   vat_json_node_t *node = NULL;
1047
1048   if (VAT_JSON_ARRAY != vam->json_tree.type)
1049     {
1050       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1051       vat_json_init_array (&vam->json_tree);
1052     }
1053   node = vat_json_array_add (&vam->json_tree);
1054
1055   vat_json_init_object (node);
1056   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1057   vat_json_object_add_uint (node, "sup_sw_if_index",
1058                             ntohl (mp->sup_sw_if_index));
1059   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
1060                              sizeof (mp->l2_address));
1061   vat_json_object_add_string_copy (node, "interface_name",
1062                                    mp->interface_name);
1063   vat_json_object_add_string_copy (node, "interface_dev_type",
1064                                    mp->interface_dev_type);
1065   vat_json_object_add_uint (node, "flags", mp->flags);
1066   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
1067   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
1068   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
1069   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
1070   vat_json_object_add_uint (node, "sub_number_of_tags",
1071                             mp->sub_number_of_tags);
1072   vat_json_object_add_uint (node, "sub_outer_vlan_id",
1073                             ntohs (mp->sub_outer_vlan_id));
1074   vat_json_object_add_uint (node, "sub_inner_vlan_id",
1075                             ntohs (mp->sub_inner_vlan_id));
1076   vat_json_object_add_uint (node, "sub_if_flags", ntohl (mp->sub_if_flags));
1077   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1078   vat_json_object_add_uint (node, "vtr_push_dot1q",
1079                             ntohl (mp->vtr_push_dot1q));
1080   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1081   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1082   if (ntohl (mp->sub_if_flags) & SUB_IF_API_FLAG_DOT1AH)
1083     {
1084       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1085                                        format (0, "%U",
1086                                                format_ethernet_address,
1087                                                &mp->b_dmac));
1088       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1089                                        format (0, "%U",
1090                                                format_ethernet_address,
1091                                                &mp->b_smac));
1092       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1093       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1094     }
1095 }
1096
1097 #if VPP_API_TEST_BUILTIN == 0
1098 static void vl_api_sw_interface_event_t_handler
1099   (vl_api_sw_interface_event_t * mp)
1100 {
1101   vat_main_t *vam = &vat_main;
1102   if (vam->interface_event_display)
1103     errmsg ("interface flags: sw_if_index %d %s %s",
1104             ntohl (mp->sw_if_index),
1105             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_ADMIN_UP) ?
1106             "admin-up" : "admin-down",
1107             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_LINK_UP) ?
1108             "link-up" : "link-down");
1109 }
1110 #endif
1111
1112 __clib_unused static void
1113 vl_api_sw_interface_event_t_handler_json (vl_api_sw_interface_event_t * mp)
1114 {
1115   /* JSON output not supported */
1116 }
1117
1118 static void
1119 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1120 {
1121   vat_main_t *vam = &vat_main;
1122   i32 retval = ntohl (mp->retval);
1123
1124   vam->retval = retval;
1125   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1126   vam->result_ready = 1;
1127 }
1128
1129 static void
1130 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1131 {
1132   vat_main_t *vam = &vat_main;
1133   vat_json_node_t node;
1134   void *oldheap;
1135   u8 *reply;
1136
1137   vat_json_init_object (&node);
1138   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1139   vat_json_object_add_uint (&node, "reply_in_shmem",
1140                             ntohl (mp->reply_in_shmem));
1141   /* Toss the shared-memory original... */
1142   oldheap = vl_msg_push_heap ();
1143
1144   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1145   vec_free (reply);
1146
1147   vl_msg_pop_heap (oldheap);
1148
1149   vat_json_print (vam->ofp, &node);
1150   vat_json_free (&node);
1151
1152   vam->retval = ntohl (mp->retval);
1153   vam->result_ready = 1;
1154 }
1155
1156 static void
1157 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1158 {
1159   vat_main_t *vam = &vat_main;
1160   i32 retval = ntohl (mp->retval);
1161
1162   vec_reset_length (vam->cmd_reply);
1163
1164   vam->retval = retval;
1165   if (retval == 0)
1166     vam->cmd_reply = vl_api_from_api_to_new_vec (mp, &mp->reply);
1167   vam->result_ready = 1;
1168 }
1169
1170 static void
1171 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1172 {
1173   vat_main_t *vam = &vat_main;
1174   vat_json_node_t node;
1175   u8 *reply = 0;                /* reply vector */
1176
1177   reply = vl_api_from_api_to_new_vec (mp, &mp->reply);
1178   vec_reset_length (vam->cmd_reply);
1179
1180   vat_json_init_object (&node);
1181   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1182   vat_json_object_add_string_copy (&node, "reply", reply);
1183
1184   vat_json_print (vam->ofp, &node);
1185   vat_json_free (&node);
1186   vec_free (reply);
1187
1188   vam->retval = ntohl (mp->retval);
1189   vam->result_ready = 1;
1190 }
1191
1192 static void vl_api_classify_add_del_table_reply_t_handler
1193   (vl_api_classify_add_del_table_reply_t * mp)
1194 {
1195   vat_main_t *vam = &vat_main;
1196   i32 retval = ntohl (mp->retval);
1197   if (vam->async_mode)
1198     {
1199       vam->async_errors += (retval < 0);
1200     }
1201   else
1202     {
1203       vam->retval = retval;
1204       if (retval == 0 &&
1205           ((mp->new_table_index != 0xFFFFFFFF) ||
1206            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1207            (mp->match_n_vectors != 0xFFFFFFFF)))
1208         /*
1209          * Note: this is just barely thread-safe, depends on
1210          * the main thread spinning waiting for an answer...
1211          */
1212         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1213                 ntohl (mp->new_table_index),
1214                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1215       vam->result_ready = 1;
1216     }
1217 }
1218
1219 static void vl_api_classify_add_del_table_reply_t_handler_json
1220   (vl_api_classify_add_del_table_reply_t * mp)
1221 {
1222   vat_main_t *vam = &vat_main;
1223   vat_json_node_t node;
1224
1225   vat_json_init_object (&node);
1226   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1227   vat_json_object_add_uint (&node, "new_table_index",
1228                             ntohl (mp->new_table_index));
1229   vat_json_object_add_uint (&node, "skip_n_vectors",
1230                             ntohl (mp->skip_n_vectors));
1231   vat_json_object_add_uint (&node, "match_n_vectors",
1232                             ntohl (mp->match_n_vectors));
1233
1234   vat_json_print (vam->ofp, &node);
1235   vat_json_free (&node);
1236
1237   vam->retval = ntohl (mp->retval);
1238   vam->result_ready = 1;
1239 }
1240
1241 static void vl_api_get_node_index_reply_t_handler
1242   (vl_api_get_node_index_reply_t * mp)
1243 {
1244   vat_main_t *vam = &vat_main;
1245   i32 retval = ntohl (mp->retval);
1246   if (vam->async_mode)
1247     {
1248       vam->async_errors += (retval < 0);
1249     }
1250   else
1251     {
1252       vam->retval = retval;
1253       if (retval == 0)
1254         errmsg ("node index %d", ntohl (mp->node_index));
1255       vam->result_ready = 1;
1256     }
1257 }
1258
1259 static void vl_api_get_node_index_reply_t_handler_json
1260   (vl_api_get_node_index_reply_t * mp)
1261 {
1262   vat_main_t *vam = &vat_main;
1263   vat_json_node_t node;
1264
1265   vat_json_init_object (&node);
1266   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1267   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1268
1269   vat_json_print (vam->ofp, &node);
1270   vat_json_free (&node);
1271
1272   vam->retval = ntohl (mp->retval);
1273   vam->result_ready = 1;
1274 }
1275
1276 static void vl_api_get_next_index_reply_t_handler
1277   (vl_api_get_next_index_reply_t * mp)
1278 {
1279   vat_main_t *vam = &vat_main;
1280   i32 retval = ntohl (mp->retval);
1281   if (vam->async_mode)
1282     {
1283       vam->async_errors += (retval < 0);
1284     }
1285   else
1286     {
1287       vam->retval = retval;
1288       if (retval == 0)
1289         errmsg ("next node index %d", ntohl (mp->next_index));
1290       vam->result_ready = 1;
1291     }
1292 }
1293
1294 static void vl_api_get_next_index_reply_t_handler_json
1295   (vl_api_get_next_index_reply_t * mp)
1296 {
1297   vat_main_t *vam = &vat_main;
1298   vat_json_node_t node;
1299
1300   vat_json_init_object (&node);
1301   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1302   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1303
1304   vat_json_print (vam->ofp, &node);
1305   vat_json_free (&node);
1306
1307   vam->retval = ntohl (mp->retval);
1308   vam->result_ready = 1;
1309 }
1310
1311 static void vl_api_add_node_next_reply_t_handler
1312   (vl_api_add_node_next_reply_t * mp)
1313 {
1314   vat_main_t *vam = &vat_main;
1315   i32 retval = ntohl (mp->retval);
1316   if (vam->async_mode)
1317     {
1318       vam->async_errors += (retval < 0);
1319     }
1320   else
1321     {
1322       vam->retval = retval;
1323       if (retval == 0)
1324         errmsg ("next index %d", ntohl (mp->next_index));
1325       vam->result_ready = 1;
1326     }
1327 }
1328
1329 static void vl_api_add_node_next_reply_t_handler_json
1330   (vl_api_add_node_next_reply_t * mp)
1331 {
1332   vat_main_t *vam = &vat_main;
1333   vat_json_node_t node;
1334
1335   vat_json_init_object (&node);
1336   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1337   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1338
1339   vat_json_print (vam->ofp, &node);
1340   vat_json_free (&node);
1341
1342   vam->retval = ntohl (mp->retval);
1343   vam->result_ready = 1;
1344 }
1345
1346 static void vl_api_show_version_reply_t_handler
1347   (vl_api_show_version_reply_t * mp)
1348 {
1349   vat_main_t *vam = &vat_main;
1350   i32 retval = ntohl (mp->retval);
1351
1352   if (retval >= 0)
1353     {
1354       errmsg ("        program: %s", mp->program);
1355       errmsg ("        version: %s", mp->version);
1356       errmsg ("     build date: %s", mp->build_date);
1357       errmsg ("build directory: %s", mp->build_directory);
1358     }
1359   vam->retval = retval;
1360   vam->result_ready = 1;
1361 }
1362
1363 static void vl_api_show_version_reply_t_handler_json
1364   (vl_api_show_version_reply_t * mp)
1365 {
1366   vat_main_t *vam = &vat_main;
1367   vat_json_node_t node;
1368
1369   vat_json_init_object (&node);
1370   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1371   vat_json_object_add_string_copy (&node, "program", mp->program);
1372   vat_json_object_add_string_copy (&node, "version", mp->version);
1373   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1374   vat_json_object_add_string_copy (&node, "build_directory",
1375                                    mp->build_directory);
1376
1377   vat_json_print (vam->ofp, &node);
1378   vat_json_free (&node);
1379
1380   vam->retval = ntohl (mp->retval);
1381   vam->result_ready = 1;
1382 }
1383
1384 static void vl_api_show_threads_reply_t_handler
1385   (vl_api_show_threads_reply_t * mp)
1386 {
1387   vat_main_t *vam = &vat_main;
1388   i32 retval = ntohl (mp->retval);
1389   int i, count = 0;
1390
1391   if (retval >= 0)
1392     count = ntohl (mp->count);
1393
1394   for (i = 0; i < count; i++)
1395     print (vam->ofp,
1396            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1397            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1398            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1399            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1400            ntohl (mp->thread_data[i].cpu_socket));
1401
1402   vam->retval = retval;
1403   vam->result_ready = 1;
1404 }
1405
1406 static void vl_api_show_threads_reply_t_handler_json
1407   (vl_api_show_threads_reply_t * mp)
1408 {
1409   vat_main_t *vam = &vat_main;
1410   vat_json_node_t node;
1411   vl_api_thread_data_t *td;
1412   i32 retval = ntohl (mp->retval);
1413   int i, count = 0;
1414
1415   if (retval >= 0)
1416     count = ntohl (mp->count);
1417
1418   vat_json_init_object (&node);
1419   vat_json_object_add_int (&node, "retval", retval);
1420   vat_json_object_add_uint (&node, "count", count);
1421
1422   for (i = 0; i < count; i++)
1423     {
1424       td = &mp->thread_data[i];
1425       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1426       vat_json_object_add_string_copy (&node, "name", td->name);
1427       vat_json_object_add_string_copy (&node, "type", td->type);
1428       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1429       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1430       vat_json_object_add_int (&node, "core", ntohl (td->id));
1431       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1432     }
1433
1434   vat_json_print (vam->ofp, &node);
1435   vat_json_free (&node);
1436
1437   vam->retval = retval;
1438   vam->result_ready = 1;
1439 }
1440
1441 static int
1442 api_show_threads (vat_main_t * vam)
1443 {
1444   vl_api_show_threads_t *mp;
1445   int ret;
1446
1447   print (vam->ofp,
1448          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1449          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1450
1451   M (SHOW_THREADS, mp);
1452
1453   S (mp);
1454   W (ret);
1455   return ret;
1456 }
1457
1458 static void
1459 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1460 {
1461   u32 n_macs = ntohl (mp->n_macs);
1462   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1463           ntohl (mp->pid), mp->client_index, n_macs);
1464   int i;
1465   for (i = 0; i < n_macs; i++)
1466     {
1467       vl_api_mac_entry_t *mac = &mp->mac[i];
1468       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1469               i + 1, ntohl (mac->sw_if_index),
1470               format_ethernet_address, mac->mac_addr, mac->action);
1471       if (i == 1000)
1472         break;
1473     }
1474 }
1475
1476 static void
1477 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1478 {
1479   /* JSON output not supported */
1480 }
1481
1482 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1483 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1484
1485 /*
1486  * Special-case: build the bridge domain table, maintain
1487  * the next bd id vbl.
1488  */
1489 static void vl_api_bridge_domain_details_t_handler
1490   (vl_api_bridge_domain_details_t * mp)
1491 {
1492   vat_main_t *vam = &vat_main;
1493   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1494   int i;
1495
1496   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1497          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1498
1499   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1500          ntohl (mp->bd_id), mp->learn, mp->forward,
1501          mp->flood, ntohl (mp->bvi_sw_if_index),
1502          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1503
1504   if (n_sw_ifs)
1505     {
1506       vl_api_bridge_domain_sw_if_t *sw_ifs;
1507       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1508              "Interface Name");
1509
1510       sw_ifs = mp->sw_if_details;
1511       for (i = 0; i < n_sw_ifs; i++)
1512         {
1513           u8 *sw_if_name = 0;
1514           u32 sw_if_index;
1515           hash_pair_t *p;
1516
1517           sw_if_index = ntohl (sw_ifs->sw_if_index);
1518
1519           /* *INDENT-OFF* */
1520           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1521                              ({
1522                                if ((u32) p->value[0] == sw_if_index)
1523                                  {
1524                                    sw_if_name = (u8 *)(p->key);
1525                                    break;
1526                                  }
1527                              }));
1528           /* *INDENT-ON* */
1529           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1530                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1531                  "sw_if_index not found!");
1532
1533           sw_ifs++;
1534         }
1535     }
1536 }
1537
1538 static void vl_api_bridge_domain_details_t_handler_json
1539   (vl_api_bridge_domain_details_t * mp)
1540 {
1541   vat_main_t *vam = &vat_main;
1542   vat_json_node_t *node, *array = NULL;
1543   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1544
1545   if (VAT_JSON_ARRAY != vam->json_tree.type)
1546     {
1547       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1548       vat_json_init_array (&vam->json_tree);
1549     }
1550   node = vat_json_array_add (&vam->json_tree);
1551
1552   vat_json_init_object (node);
1553   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1554   vat_json_object_add_uint (node, "flood", mp->flood);
1555   vat_json_object_add_uint (node, "forward", mp->forward);
1556   vat_json_object_add_uint (node, "learn", mp->learn);
1557   vat_json_object_add_uint (node, "bvi_sw_if_index",
1558                             ntohl (mp->bvi_sw_if_index));
1559   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1560   array = vat_json_object_add (node, "sw_if");
1561   vat_json_init_array (array);
1562
1563
1564
1565   if (n_sw_ifs)
1566     {
1567       vl_api_bridge_domain_sw_if_t *sw_ifs;
1568       int i;
1569
1570       sw_ifs = mp->sw_if_details;
1571       for (i = 0; i < n_sw_ifs; i++)
1572         {
1573           node = vat_json_array_add (array);
1574           vat_json_init_object (node);
1575           vat_json_object_add_uint (node, "sw_if_index",
1576                                     ntohl (sw_ifs->sw_if_index));
1577           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1578           sw_ifs++;
1579         }
1580     }
1581 }
1582
1583 static void vl_api_control_ping_reply_t_handler
1584   (vl_api_control_ping_reply_t * mp)
1585 {
1586   vat_main_t *vam = &vat_main;
1587   i32 retval = ntohl (mp->retval);
1588   if (vam->async_mode)
1589     {
1590       vam->async_errors += (retval < 0);
1591     }
1592   else
1593     {
1594       vam->retval = retval;
1595       vam->result_ready = 1;
1596     }
1597   if (vam->socket_client_main)
1598     vam->socket_client_main->control_pings_outstanding--;
1599 }
1600
1601 static void vl_api_control_ping_reply_t_handler_json
1602   (vl_api_control_ping_reply_t * mp)
1603 {
1604   vat_main_t *vam = &vat_main;
1605   i32 retval = ntohl (mp->retval);
1606
1607   if (VAT_JSON_NONE != vam->json_tree.type)
1608     {
1609       vat_json_print (vam->ofp, &vam->json_tree);
1610       vat_json_free (&vam->json_tree);
1611       vam->json_tree.type = VAT_JSON_NONE;
1612     }
1613   else
1614     {
1615       /* just print [] */
1616       vat_json_init_array (&vam->json_tree);
1617       vat_json_print (vam->ofp, &vam->json_tree);
1618       vam->json_tree.type = VAT_JSON_NONE;
1619     }
1620
1621   vam->retval = retval;
1622   vam->result_ready = 1;
1623 }
1624
1625 static void
1626   vl_api_bridge_domain_set_mac_age_reply_t_handler
1627   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1628 {
1629   vat_main_t *vam = &vat_main;
1630   i32 retval = ntohl (mp->retval);
1631   if (vam->async_mode)
1632     {
1633       vam->async_errors += (retval < 0);
1634     }
1635   else
1636     {
1637       vam->retval = retval;
1638       vam->result_ready = 1;
1639     }
1640 }
1641
1642 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1643   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1644 {
1645   vat_main_t *vam = &vat_main;
1646   vat_json_node_t node;
1647
1648   vat_json_init_object (&node);
1649   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1650
1651   vat_json_print (vam->ofp, &node);
1652   vat_json_free (&node);
1653
1654   vam->retval = ntohl (mp->retval);
1655   vam->result_ready = 1;
1656 }
1657
1658 static void
1659 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1660 {
1661   vat_main_t *vam = &vat_main;
1662   i32 retval = ntohl (mp->retval);
1663   if (vam->async_mode)
1664     {
1665       vam->async_errors += (retval < 0);
1666     }
1667   else
1668     {
1669       vam->retval = retval;
1670       vam->result_ready = 1;
1671     }
1672 }
1673
1674 static void vl_api_l2_flags_reply_t_handler_json
1675   (vl_api_l2_flags_reply_t * mp)
1676 {
1677   vat_main_t *vam = &vat_main;
1678   vat_json_node_t node;
1679
1680   vat_json_init_object (&node);
1681   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1682   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1683                             ntohl (mp->resulting_feature_bitmap));
1684
1685   vat_json_print (vam->ofp, &node);
1686   vat_json_free (&node);
1687
1688   vam->retval = ntohl (mp->retval);
1689   vam->result_ready = 1;
1690 }
1691
1692 static void vl_api_bridge_flags_reply_t_handler
1693   (vl_api_bridge_flags_reply_t * mp)
1694 {
1695   vat_main_t *vam = &vat_main;
1696   i32 retval = ntohl (mp->retval);
1697   if (vam->async_mode)
1698     {
1699       vam->async_errors += (retval < 0);
1700     }
1701   else
1702     {
1703       vam->retval = retval;
1704       vam->result_ready = 1;
1705     }
1706 }
1707
1708 static void vl_api_bridge_flags_reply_t_handler_json
1709   (vl_api_bridge_flags_reply_t * mp)
1710 {
1711   vat_main_t *vam = &vat_main;
1712   vat_json_node_t node;
1713
1714   vat_json_init_object (&node);
1715   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1716   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1717                             ntohl (mp->resulting_feature_bitmap));
1718
1719   vat_json_print (vam->ofp, &node);
1720   vat_json_free (&node);
1721
1722   vam->retval = ntohl (mp->retval);
1723   vam->result_ready = 1;
1724 }
1725
1726 static void
1727 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1728 {
1729   vat_main_t *vam = &vat_main;
1730   i32 retval = ntohl (mp->retval);
1731   if (vam->async_mode)
1732     {
1733       vam->async_errors += (retval < 0);
1734     }
1735   else
1736     {
1737       vam->retval = retval;
1738       vam->sw_if_index = ntohl (mp->sw_if_index);
1739       vam->result_ready = 1;
1740     }
1741
1742 }
1743
1744 static void vl_api_tap_create_v2_reply_t_handler_json
1745   (vl_api_tap_create_v2_reply_t * mp)
1746 {
1747   vat_main_t *vam = &vat_main;
1748   vat_json_node_t node;
1749
1750   vat_json_init_object (&node);
1751   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1752   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1753
1754   vat_json_print (vam->ofp, &node);
1755   vat_json_free (&node);
1756
1757   vam->retval = ntohl (mp->retval);
1758   vam->result_ready = 1;
1759
1760 }
1761
1762 static void
1763 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1764 {
1765   vat_main_t *vam = &vat_main;
1766   i32 retval = ntohl (mp->retval);
1767   if (vam->async_mode)
1768     {
1769       vam->async_errors += (retval < 0);
1770     }
1771   else
1772     {
1773       vam->retval = retval;
1774       vam->result_ready = 1;
1775     }
1776 }
1777
1778 static void vl_api_tap_delete_v2_reply_t_handler_json
1779   (vl_api_tap_delete_v2_reply_t * mp)
1780 {
1781   vat_main_t *vam = &vat_main;
1782   vat_json_node_t node;
1783
1784   vat_json_init_object (&node);
1785   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1786
1787   vat_json_print (vam->ofp, &node);
1788   vat_json_free (&node);
1789
1790   vam->retval = ntohl (mp->retval);
1791   vam->result_ready = 1;
1792 }
1793
1794 static void
1795 vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1796                                           mp)
1797 {
1798   vat_main_t *vam = &vat_main;
1799   i32 retval = ntohl (mp->retval);
1800   if (vam->async_mode)
1801     {
1802       vam->async_errors += (retval < 0);
1803     }
1804   else
1805     {
1806       vam->retval = retval;
1807       vam->sw_if_index = ntohl (mp->sw_if_index);
1808       vam->result_ready = 1;
1809     }
1810 }
1811
1812 static void vl_api_virtio_pci_create_reply_t_handler_json
1813   (vl_api_virtio_pci_create_reply_t * mp)
1814 {
1815   vat_main_t *vam = &vat_main;
1816   vat_json_node_t node;
1817
1818   vat_json_init_object (&node);
1819   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1820   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1821
1822   vat_json_print (vam->ofp, &node);
1823   vat_json_free (&node);
1824
1825   vam->retval = ntohl (mp->retval);
1826   vam->result_ready = 1;
1827
1828 }
1829
1830 static void
1831   vl_api_virtio_pci_create_v2_reply_t_handler
1832   (vl_api_virtio_pci_create_v2_reply_t * mp)
1833 {
1834   vat_main_t *vam = &vat_main;
1835   i32 retval = ntohl (mp->retval);
1836   if (vam->async_mode)
1837     {
1838       vam->async_errors += (retval < 0);
1839     }
1840   else
1841     {
1842       vam->retval = retval;
1843       vam->sw_if_index = ntohl (mp->sw_if_index);
1844       vam->result_ready = 1;
1845     }
1846 }
1847
1848 static void vl_api_virtio_pci_create_v2_reply_t_handler_json
1849   (vl_api_virtio_pci_create_v2_reply_t * mp)
1850 {
1851   vat_main_t *vam = &vat_main;
1852   vat_json_node_t node;
1853
1854   vat_json_init_object (&node);
1855   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1856   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1857
1858   vat_json_print (vam->ofp, &node);
1859   vat_json_free (&node);
1860
1861   vam->retval = ntohl (mp->retval);
1862   vam->result_ready = 1;
1863 }
1864
1865 static void
1866 vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1867                                           mp)
1868 {
1869   vat_main_t *vam = &vat_main;
1870   i32 retval = ntohl (mp->retval);
1871   if (vam->async_mode)
1872     {
1873       vam->async_errors += (retval < 0);
1874     }
1875   else
1876     {
1877       vam->retval = retval;
1878       vam->result_ready = 1;
1879     }
1880 }
1881
1882 static void vl_api_virtio_pci_delete_reply_t_handler_json
1883   (vl_api_virtio_pci_delete_reply_t * mp)
1884 {
1885   vat_main_t *vam = &vat_main;
1886   vat_json_node_t node;
1887
1888   vat_json_init_object (&node);
1889   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1890
1891   vat_json_print (vam->ofp, &node);
1892   vat_json_free (&node);
1893
1894   vam->retval = ntohl (mp->retval);
1895   vam->result_ready = 1;
1896 }
1897
1898 static void
1899 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1900 {
1901   vat_main_t *vam = &vat_main;
1902   i32 retval = ntohl (mp->retval);
1903
1904   if (vam->async_mode)
1905     {
1906       vam->async_errors += (retval < 0);
1907     }
1908   else
1909     {
1910       vam->retval = retval;
1911       vam->sw_if_index = ntohl (mp->sw_if_index);
1912       vam->result_ready = 1;
1913     }
1914 }
1915
1916 static void vl_api_bond_create_reply_t_handler_json
1917   (vl_api_bond_create_reply_t * mp)
1918 {
1919   vat_main_t *vam = &vat_main;
1920   vat_json_node_t node;
1921
1922   vat_json_init_object (&node);
1923   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1924   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1925
1926   vat_json_print (vam->ofp, &node);
1927   vat_json_free (&node);
1928
1929   vam->retval = ntohl (mp->retval);
1930   vam->result_ready = 1;
1931 }
1932
1933 static void
1934 vl_api_bond_create2_reply_t_handler (vl_api_bond_create2_reply_t * mp)
1935 {
1936   vat_main_t *vam = &vat_main;
1937   i32 retval = ntohl (mp->retval);
1938
1939   if (vam->async_mode)
1940     {
1941       vam->async_errors += (retval < 0);
1942     }
1943   else
1944     {
1945       vam->retval = retval;
1946       vam->sw_if_index = ntohl (mp->sw_if_index);
1947       vam->result_ready = 1;
1948     }
1949 }
1950
1951 static void vl_api_bond_create2_reply_t_handler_json
1952   (vl_api_bond_create2_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   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1960
1961   vat_json_print (vam->ofp, &node);
1962   vat_json_free (&node);
1963
1964   vam->retval = ntohl (mp->retval);
1965   vam->result_ready = 1;
1966 }
1967
1968 static void
1969 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1970 {
1971   vat_main_t *vam = &vat_main;
1972   i32 retval = ntohl (mp->retval);
1973
1974   if (vam->async_mode)
1975     {
1976       vam->async_errors += (retval < 0);
1977     }
1978   else
1979     {
1980       vam->retval = retval;
1981       vam->result_ready = 1;
1982     }
1983 }
1984
1985 static void vl_api_bond_delete_reply_t_handler_json
1986   (vl_api_bond_delete_reply_t * mp)
1987 {
1988   vat_main_t *vam = &vat_main;
1989   vat_json_node_t node;
1990
1991   vat_json_init_object (&node);
1992   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1993
1994   vat_json_print (vam->ofp, &node);
1995   vat_json_free (&node);
1996
1997   vam->retval = ntohl (mp->retval);
1998   vam->result_ready = 1;
1999 }
2000
2001 static void
2002 vl_api_bond_add_member_reply_t_handler (vl_api_bond_add_member_reply_t * 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_add_member_reply_t_handler_json
2019   (vl_api_bond_add_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 void
2035 vl_api_bond_detach_member_reply_t_handler (vl_api_bond_detach_member_reply_t *
2036                                            mp)
2037 {
2038   vat_main_t *vam = &vat_main;
2039   i32 retval = ntohl (mp->retval);
2040
2041   if (vam->async_mode)
2042     {
2043       vam->async_errors += (retval < 0);
2044     }
2045   else
2046     {
2047       vam->retval = retval;
2048       vam->result_ready = 1;
2049     }
2050 }
2051
2052 static void vl_api_bond_detach_member_reply_t_handler_json
2053   (vl_api_bond_detach_member_reply_t * mp)
2054 {
2055   vat_main_t *vam = &vat_main;
2056   vat_json_node_t node;
2057
2058   vat_json_init_object (&node);
2059   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2060
2061   vat_json_print (vam->ofp, &node);
2062   vat_json_free (&node);
2063
2064   vam->retval = ntohl (mp->retval);
2065   vam->result_ready = 1;
2066 }
2067
2068 static int
2069 api_sw_interface_set_bond_weight (vat_main_t * vam)
2070 {
2071   unformat_input_t *i = vam->input;
2072   vl_api_sw_interface_set_bond_weight_t *mp;
2073   u32 sw_if_index = ~0;
2074   u32 weight = 0;
2075   u8 weight_enter = 0;
2076   int ret;
2077
2078   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2079     {
2080       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2081         ;
2082       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2083         ;
2084       else if (unformat (i, "weight %u", &weight))
2085         weight_enter = 1;
2086       else
2087         break;
2088     }
2089
2090   if (sw_if_index == ~0)
2091     {
2092       errmsg ("missing interface name or sw_if_index");
2093       return -99;
2094     }
2095   if (weight_enter == 0)
2096     {
2097       errmsg ("missing valid weight");
2098       return -99;
2099     }
2100
2101   /* Construct the API message */
2102   M (SW_INTERFACE_SET_BOND_WEIGHT, mp);
2103   mp->sw_if_index = ntohl (sw_if_index);
2104   mp->weight = ntohl (weight);
2105
2106   S (mp);
2107   W (ret);
2108   return ret;
2109 }
2110
2111 static void vl_api_sw_bond_interface_details_t_handler
2112   (vl_api_sw_bond_interface_details_t * mp)
2113 {
2114   vat_main_t *vam = &vat_main;
2115
2116   print (vam->ofp,
2117          "%-16s %-12d %-12U %-13U %-14u %-14u",
2118          mp->interface_name, ntohl (mp->sw_if_index),
2119          format_bond_mode, ntohl (mp->mode), format_bond_load_balance,
2120          ntohl (mp->lb), ntohl (mp->active_members), ntohl (mp->members));
2121 }
2122
2123 static void vl_api_sw_bond_interface_details_t_handler_json
2124   (vl_api_sw_bond_interface_details_t * mp)
2125 {
2126   vat_main_t *vam = &vat_main;
2127   vat_json_node_t *node = NULL;
2128
2129   if (VAT_JSON_ARRAY != vam->json_tree.type)
2130     {
2131       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2132       vat_json_init_array (&vam->json_tree);
2133     }
2134   node = vat_json_array_add (&vam->json_tree);
2135
2136   vat_json_init_object (node);
2137   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2138   vat_json_object_add_string_copy (node, "interface_name",
2139                                    mp->interface_name);
2140   vat_json_object_add_uint (node, "mode", ntohl (mp->mode));
2141   vat_json_object_add_uint (node, "load_balance", ntohl (mp->lb));
2142   vat_json_object_add_uint (node, "active_members",
2143                             ntohl (mp->active_members));
2144   vat_json_object_add_uint (node, "members", ntohl (mp->members));
2145 }
2146
2147 static int
2148 api_sw_bond_interface_dump (vat_main_t * vam)
2149 {
2150   unformat_input_t *i = vam->input;
2151   vl_api_sw_bond_interface_dump_t *mp;
2152   vl_api_control_ping_t *mp_ping;
2153   int ret;
2154   u32 sw_if_index = ~0;
2155
2156   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2157     {
2158       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2159         ;
2160       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2161         ;
2162       else
2163         break;
2164     }
2165
2166   print (vam->ofp,
2167          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2168          "interface name", "sw_if_index", "mode", "load balance",
2169          "active members", "members");
2170
2171   /* Get list of bond interfaces */
2172   M (SW_BOND_INTERFACE_DUMP, mp);
2173   mp->sw_if_index = ntohl (sw_if_index);
2174   S (mp);
2175
2176   /* Use a control ping for synchronization */
2177   MPING (CONTROL_PING, mp_ping);
2178   S (mp_ping);
2179
2180   W (ret);
2181   return ret;
2182 }
2183
2184 static void vl_api_sw_member_interface_details_t_handler
2185   (vl_api_sw_member_interface_details_t * mp)
2186 {
2187   vat_main_t *vam = &vat_main;
2188
2189   print (vam->ofp,
2190          "%-25s %-12d %-7d %-12d %-10d %-10d", mp->interface_name,
2191          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout,
2192          ntohl (mp->weight), mp->is_local_numa);
2193 }
2194
2195 static void vl_api_sw_member_interface_details_t_handler_json
2196   (vl_api_sw_member_interface_details_t * mp)
2197 {
2198   vat_main_t *vam = &vat_main;
2199   vat_json_node_t *node = NULL;
2200
2201   if (VAT_JSON_ARRAY != vam->json_tree.type)
2202     {
2203       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2204       vat_json_init_array (&vam->json_tree);
2205     }
2206   node = vat_json_array_add (&vam->json_tree);
2207
2208   vat_json_init_object (node);
2209   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2210   vat_json_object_add_string_copy (node, "interface_name",
2211                                    mp->interface_name);
2212   vat_json_object_add_uint (node, "passive", mp->is_passive);
2213   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2214   vat_json_object_add_uint (node, "weight", ntohl (mp->weight));
2215   vat_json_object_add_uint (node, "is_local_numa", mp->is_local_numa);
2216 }
2217
2218 static int
2219 api_sw_member_interface_dump (vat_main_t * vam)
2220 {
2221   unformat_input_t *i = vam->input;
2222   vl_api_sw_member_interface_dump_t *mp;
2223   vl_api_control_ping_t *mp_ping;
2224   u32 sw_if_index = ~0;
2225   u8 sw_if_index_set = 0;
2226   int ret;
2227
2228   /* Parse args required to build the message */
2229   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2230     {
2231       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2232         sw_if_index_set = 1;
2233       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2234         sw_if_index_set = 1;
2235       else
2236         break;
2237     }
2238
2239   if (sw_if_index_set == 0)
2240     {
2241       errmsg ("missing vpp interface name. ");
2242       return -99;
2243     }
2244
2245   print (vam->ofp,
2246          "\n%-25s %-12s %-7s %-12s %-10s %-10s",
2247          "member interface name", "sw_if_index", "passive", "long_timeout",
2248          "weight", "local numa");
2249
2250   /* Get list of bond interfaces */
2251   M (SW_MEMBER_INTERFACE_DUMP, mp);
2252   mp->sw_if_index = ntohl (sw_if_index);
2253   S (mp);
2254
2255   /* Use a control ping for synchronization */
2256   MPING (CONTROL_PING, mp_ping);
2257   S (mp_ping);
2258
2259   W (ret);
2260   return ret;
2261 }
2262
2263 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2264   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2265 {
2266   vat_main_t *vam = &vat_main;
2267   i32 retval = ntohl (mp->retval);
2268   if (vam->async_mode)
2269     {
2270       vam->async_errors += (retval < 0);
2271     }
2272   else
2273     {
2274       vam->retval = retval;
2275       vam->sw_if_index = ntohl (mp->sw_if_index);
2276       vam->result_ready = 1;
2277     }
2278   vam->regenerate_interface_table = 1;
2279 }
2280
2281 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2282   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2283 {
2284   vat_main_t *vam = &vat_main;
2285   vat_json_node_t node;
2286
2287   vat_json_init_object (&node);
2288   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2289   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2290                             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_l2tpv3_create_tunnel_reply_t_handler
2300   (vl_api_l2tpv3_create_tunnel_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->sw_if_index = ntohl (mp->sw_if_index);
2312       vam->result_ready = 1;
2313     }
2314 }
2315
2316 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2317   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2318 {
2319   vat_main_t *vam = &vat_main;
2320   vat_json_node_t node;
2321
2322   vat_json_init_object (&node);
2323   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2324   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_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 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2334   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2335 {
2336   vat_main_t *vam = &vat_main;
2337   i32 retval = ntohl (mp->retval);
2338   if (vam->async_mode)
2339     {
2340       vam->async_errors += (retval < 0);
2341     }
2342   else
2343     {
2344       vam->retval = retval;
2345       vam->result_ready = 1;
2346     }
2347 }
2348
2349 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2350   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2351 {
2352   vat_main_t *vam = &vat_main;
2353   vat_json_node_t node;
2354
2355   vat_json_init_object (&node);
2356   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2357   vat_json_object_add_uint (&node, "fwd_entry_index",
2358                             clib_net_to_host_u32 (mp->fwd_entry_index));
2359
2360   vat_json_print (vam->ofp, &node);
2361   vat_json_free (&node);
2362
2363   vam->retval = ntohl (mp->retval);
2364   vam->result_ready = 1;
2365 }
2366
2367 u8 *
2368 format_lisp_transport_protocol (u8 * s, va_list * args)
2369 {
2370   u32 proto = va_arg (*args, u32);
2371
2372   switch (proto)
2373     {
2374     case 1:
2375       return format (s, "udp");
2376     case 2:
2377       return format (s, "api");
2378     default:
2379       return 0;
2380     }
2381   return 0;
2382 }
2383
2384 static void vl_api_one_get_transport_protocol_reply_t_handler
2385   (vl_api_one_get_transport_protocol_reply_t * mp)
2386 {
2387   vat_main_t *vam = &vat_main;
2388   i32 retval = ntohl (mp->retval);
2389   if (vam->async_mode)
2390     {
2391       vam->async_errors += (retval < 0);
2392     }
2393   else
2394     {
2395       u32 proto = mp->protocol;
2396       print (vam->ofp, "Transport protocol: %U",
2397              format_lisp_transport_protocol, proto);
2398       vam->retval = retval;
2399       vam->result_ready = 1;
2400     }
2401 }
2402
2403 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2404   (vl_api_one_get_transport_protocol_reply_t * mp)
2405 {
2406   vat_main_t *vam = &vat_main;
2407   vat_json_node_t node;
2408   u8 *s;
2409
2410   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2411   vec_add1 (s, 0);
2412
2413   vat_json_init_object (&node);
2414   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2415   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2416
2417   vec_free (s);
2418   vat_json_print (vam->ofp, &node);
2419   vat_json_free (&node);
2420
2421   vam->retval = ntohl (mp->retval);
2422   vam->result_ready = 1;
2423 }
2424
2425 static void vl_api_one_add_del_locator_set_reply_t_handler
2426   (vl_api_one_add_del_locator_set_reply_t * mp)
2427 {
2428   vat_main_t *vam = &vat_main;
2429   i32 retval = ntohl (mp->retval);
2430   if (vam->async_mode)
2431     {
2432       vam->async_errors += (retval < 0);
2433     }
2434   else
2435     {
2436       vam->retval = retval;
2437       vam->result_ready = 1;
2438     }
2439 }
2440
2441 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2442   (vl_api_one_add_del_locator_set_reply_t * mp)
2443 {
2444   vat_main_t *vam = &vat_main;
2445   vat_json_node_t node;
2446
2447   vat_json_init_object (&node);
2448   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2449   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2450
2451   vat_json_print (vam->ofp, &node);
2452   vat_json_free (&node);
2453
2454   vam->retval = ntohl (mp->retval);
2455   vam->result_ready = 1;
2456 }
2457
2458 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2459   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2460 {
2461   vat_main_t *vam = &vat_main;
2462   i32 retval = ntohl (mp->retval);
2463   if (vam->async_mode)
2464     {
2465       vam->async_errors += (retval < 0);
2466     }
2467   else
2468     {
2469       vam->retval = retval;
2470       vam->sw_if_index = ntohl (mp->sw_if_index);
2471       vam->result_ready = 1;
2472     }
2473   vam->regenerate_interface_table = 1;
2474 }
2475
2476 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2477   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2478 {
2479   vat_main_t *vam = &vat_main;
2480   vat_json_node_t node;
2481
2482   vat_json_init_object (&node);
2483   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2484   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2485
2486   vat_json_print (vam->ofp, &node);
2487   vat_json_free (&node);
2488
2489   vam->retval = ntohl (mp->retval);
2490   vam->result_ready = 1;
2491 }
2492
2493 static void vl_api_vxlan_offload_rx_reply_t_handler
2494   (vl_api_vxlan_offload_rx_reply_t * mp)
2495 {
2496   vat_main_t *vam = &vat_main;
2497   i32 retval = ntohl (mp->retval);
2498   if (vam->async_mode)
2499     {
2500       vam->async_errors += (retval < 0);
2501     }
2502   else
2503     {
2504       vam->retval = retval;
2505       vam->result_ready = 1;
2506     }
2507 }
2508
2509 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2510   (vl_api_vxlan_offload_rx_reply_t * mp)
2511 {
2512   vat_main_t *vam = &vat_main;
2513   vat_json_node_t node;
2514
2515   vat_json_init_object (&node);
2516   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
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_vxlan_gpe_bypass_reply)              \
5091 _(sw_interface_set_l2_bridge_reply)                     \
5092 _(sw_interface_set_bond_weight_reply)                   \
5093 _(bridge_domain_add_del_reply)                          \
5094 _(sw_interface_set_l2_xconnect_reply)                   \
5095 _(l2fib_add_del_reply)                                  \
5096 _(l2fib_flush_int_reply)                                \
5097 _(l2fib_flush_bd_reply)                                 \
5098 _(ip_route_add_del_reply)                               \
5099 _(ip_table_add_del_reply)                               \
5100 _(ip_table_replace_begin_reply)                         \
5101 _(ip_table_flush_reply)                                 \
5102 _(ip_table_replace_end_reply)                           \
5103 _(ip_mroute_add_del_reply)                              \
5104 _(mpls_route_add_del_reply)                             \
5105 _(mpls_table_add_del_reply)                             \
5106 _(mpls_ip_bind_unbind_reply)                            \
5107 _(bier_route_add_del_reply)                             \
5108 _(bier_table_add_del_reply)                             \
5109 _(sw_interface_set_unnumbered_reply)                    \
5110 _(set_ip_flow_hash_reply)                               \
5111 _(sw_interface_ip6_enable_disable_reply)                \
5112 _(l2_patch_add_del_reply)                               \
5113 _(sr_mpls_policy_add_reply)                             \
5114 _(sr_mpls_policy_mod_reply)                             \
5115 _(sr_mpls_policy_del_reply)                             \
5116 _(sr_policy_add_reply)                                  \
5117 _(sr_policy_mod_reply)                                  \
5118 _(sr_policy_del_reply)                                  \
5119 _(sr_localsid_add_del_reply)                            \
5120 _(sr_steering_add_del_reply)                            \
5121 _(classify_add_del_session_reply)                       \
5122 _(classify_set_interface_ip_table_reply)                \
5123 _(classify_set_interface_l2_tables_reply)               \
5124 _(l2tpv3_set_tunnel_cookies_reply)                      \
5125 _(l2tpv3_interface_enable_disable_reply)                \
5126 _(l2tpv3_set_lookup_key_reply)                          \
5127 _(l2_fib_clear_table_reply)                             \
5128 _(l2_interface_efp_filter_reply)                        \
5129 _(l2_interface_vlan_tag_rewrite_reply)                  \
5130 _(modify_vhost_user_if_reply)                           \
5131 _(delete_vhost_user_if_reply)                           \
5132 _(want_l2_macs_events_reply)                            \
5133 _(input_acl_set_interface_reply)                        \
5134 _(ipsec_spd_add_del_reply)                              \
5135 _(ipsec_interface_add_del_spd_reply)                    \
5136 _(ipsec_spd_entry_add_del_reply)                        \
5137 _(ipsec_sad_entry_add_del_reply)                        \
5138 _(ipsec_tunnel_if_add_del_reply)                        \
5139 _(ipsec_tunnel_if_set_sa_reply)                         \
5140 _(delete_loopback_reply)                                \
5141 _(bd_ip_mac_add_del_reply)                              \
5142 _(bd_ip_mac_flush_reply)                                \
5143 _(want_interface_events_reply)                          \
5144 _(cop_interface_enable_disable_reply)                   \
5145 _(cop_whitelist_enable_disable_reply)                   \
5146 _(sw_interface_clear_stats_reply)                       \
5147 _(ioam_enable_reply)                                    \
5148 _(ioam_disable_reply)                                   \
5149 _(one_add_del_locator_reply)                            \
5150 _(one_add_del_local_eid_reply)                          \
5151 _(one_add_del_remote_mapping_reply)                     \
5152 _(one_add_del_adjacency_reply)                          \
5153 _(one_add_del_map_resolver_reply)                       \
5154 _(one_add_del_map_server_reply)                         \
5155 _(one_enable_disable_reply)                             \
5156 _(one_rloc_probe_enable_disable_reply)                  \
5157 _(one_map_register_enable_disable_reply)                \
5158 _(one_map_register_set_ttl_reply)                       \
5159 _(one_set_transport_protocol_reply)                     \
5160 _(one_map_register_fallback_threshold_reply)            \
5161 _(one_pitr_set_locator_set_reply)                       \
5162 _(one_map_request_mode_reply)                           \
5163 _(one_add_del_map_request_itr_rlocs_reply)              \
5164 _(one_eid_table_add_del_map_reply)                      \
5165 _(one_use_petr_reply)                                   \
5166 _(one_stats_enable_disable_reply)                       \
5167 _(one_add_del_l2_arp_entry_reply)                       \
5168 _(one_add_del_ndp_entry_reply)                          \
5169 _(one_stats_flush_reply)                                \
5170 _(one_enable_disable_xtr_mode_reply)                    \
5171 _(one_enable_disable_pitr_mode_reply)                   \
5172 _(one_enable_disable_petr_mode_reply)                   \
5173 _(gpe_enable_disable_reply)                             \
5174 _(gpe_set_encap_mode_reply)                             \
5175 _(gpe_add_del_iface_reply)                              \
5176 _(gpe_add_del_native_fwd_rpath_reply)                   \
5177 _(af_packet_delete_reply)                               \
5178 _(policer_classify_set_interface_reply)                 \
5179 _(set_ipfix_exporter_reply)                             \
5180 _(set_ipfix_classify_stream_reply)                      \
5181 _(ipfix_classify_table_add_del_reply)                   \
5182 _(flow_classify_set_interface_reply)                    \
5183 _(sw_interface_span_enable_disable_reply)               \
5184 _(pg_capture_reply)                                     \
5185 _(pg_enable_disable_reply)                              \
5186 _(pg_interface_enable_disable_coalesce_reply)           \
5187 _(ip_source_and_port_range_check_add_del_reply)         \
5188 _(ip_source_and_port_range_check_interface_add_del_reply)\
5189 _(delete_subif_reply)                                   \
5190 _(l2_interface_pbb_tag_rewrite_reply)                   \
5191 _(set_punt_reply)                                       \
5192 _(feature_enable_disable_reply)                         \
5193 _(feature_gso_enable_disable_reply)                     \
5194 _(sw_interface_tag_add_del_reply)                       \
5195 _(sw_interface_add_del_mac_address_reply)               \
5196 _(hw_interface_set_mtu_reply)                           \
5197 _(p2p_ethernet_add_reply)                               \
5198 _(p2p_ethernet_del_reply)                               \
5199 _(lldp_config_reply)                                    \
5200 _(sw_interface_set_lldp_reply)                          \
5201 _(tcp_configure_src_addresses_reply)                    \
5202 _(session_rule_add_del_reply)                           \
5203 _(ip_container_proxy_add_del_reply)                     \
5204 _(output_acl_set_interface_reply)                       \
5205 _(qos_record_enable_disable_reply)                      \
5206 _(flow_add_reply)
5207
5208 #define _(n)                                    \
5209     static void vl_api_##n##_t_handler          \
5210     (vl_api_##n##_t * mp)                       \
5211     {                                           \
5212         vat_main_t * vam = &vat_main;           \
5213         i32 retval = ntohl(mp->retval);         \
5214         if (vam->async_mode) {                  \
5215             vam->async_errors += (retval < 0);  \
5216         } else {                                \
5217             vam->retval = retval;               \
5218             vam->result_ready = 1;              \
5219         }                                       \
5220     }
5221 foreach_standard_reply_retval_handler;
5222 #undef _
5223
5224 #define _(n)                                    \
5225     static void vl_api_##n##_t_handler_json     \
5226     (vl_api_##n##_t * mp)                       \
5227     {                                           \
5228         vat_main_t * vam = &vat_main;           \
5229         vat_json_node_t node;                   \
5230         vat_json_init_object(&node);            \
5231         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5232         vat_json_print(vam->ofp, &node);        \
5233         vam->retval = ntohl(mp->retval);        \
5234         vam->result_ready = 1;                  \
5235     }
5236 foreach_standard_reply_retval_handler;
5237 #undef _
5238
5239 /*
5240  * Table of message reply handlers, must include boilerplate handlers
5241  * we just generated
5242  */
5243
5244 #define foreach_vpe_api_reply_msg                                       \
5245 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5246 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5247 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5248 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5249 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5250 _(CLI_REPLY, cli_reply)                                                 \
5251 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5252 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5253   sw_interface_add_del_address_reply)                                   \
5254 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5255 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5256 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5257 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5258 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5259 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5260 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5261 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5262 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5263   sw_interface_set_l2_xconnect_reply)                                   \
5264 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5265   sw_interface_set_l2_bridge_reply)                                     \
5266 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5267 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5268 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5269 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5270 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5271 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5272 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5273 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5274 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5275 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5276 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5277 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5278 _(VIRTIO_PCI_CREATE_V2_REPLY, virtio_pci_create_v2_reply)               \
5279 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5280 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5281 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5282 _(BOND_CREATE2_REPLY, bond_create2_reply)                               \
5283 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5284 _(BOND_ADD_MEMBER_REPLY, bond_add_member_reply)                         \
5285 _(BOND_DETACH_MEMBER_REPLY, bond_detach_member_reply)                   \
5286 _(SW_INTERFACE_SET_BOND_WEIGHT_REPLY, sw_interface_set_bond_weight_reply) \
5287 _(SW_BOND_INTERFACE_DETAILS, sw_bond_interface_details)                 \
5288 _(SW_MEMBER_INTERFACE_DETAILS, sw_member_interface_details)               \
5289 _(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply)                       \
5290 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5291 _(IP_TABLE_REPLACE_BEGIN_REPLY, ip_table_replace_begin_reply)           \
5292 _(IP_TABLE_FLUSH_REPLY, ip_table_flush_reply)                           \
5293 _(IP_TABLE_REPLACE_END_REPLY, ip_table_replace_end_reply)               \
5294 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5295 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5296 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5297 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5298 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5299 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5300 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5301 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5302   sw_interface_set_unnumbered_reply)                                    \
5303 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5304 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5305 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5306 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5307   sw_interface_ip6_enable_disable_reply)                                \
5308 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5309 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5310 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5311 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5312 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5313 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5314 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5315 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5316 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5317 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5318 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5319 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5320 classify_set_interface_ip_table_reply)                                  \
5321 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5322   classify_set_interface_l2_tables_reply)                               \
5323 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5324 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5325 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5326 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5327 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5328   l2tpv3_interface_enable_disable_reply)                                \
5329 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5330 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5331 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5332 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5333 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5334 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5335 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5336 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5337 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5338 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5339 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5340 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5341 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5342 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5343 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5344 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5345 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5346 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5347 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5348 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5349 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5350 _(L2_MACS_EVENT, l2_macs_event)                                         \
5351 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5352 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5353 _(IP_DETAILS, ip_details)                                               \
5354 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5355 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5356 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5357 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5358 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5359 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5360 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5361 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5362 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5363 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5364 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5365 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5366 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5367 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5368 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5369 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5370 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5371 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5372 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5373 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5374 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5375 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5376 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5377 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5378 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5379 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5380 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5381 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5382   one_map_register_enable_disable_reply)                                \
5383 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5384 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5385 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5386 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5387   one_map_register_fallback_threshold_reply)                            \
5388 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5389   one_rloc_probe_enable_disable_reply)                                  \
5390 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5391 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5392 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5393 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5394 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5395 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5396 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5397 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5398 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5399 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5400 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5401 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5402 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5403 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5404 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5405 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5406   show_one_stats_enable_disable_reply)                                  \
5407 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5408 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5409 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5410 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5411 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5412 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5413 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5414 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5415   one_enable_disable_pitr_mode_reply)                                   \
5416 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5417   one_enable_disable_petr_mode_reply)                                   \
5418 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5419 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5420 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5421 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5422 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5423 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5424 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5425 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5426 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5427 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5428 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5429 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5430   gpe_add_del_native_fwd_rpath_reply)                                   \
5431 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5432   gpe_fwd_entry_path_details)                                           \
5433 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5434 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5435   one_add_del_map_request_itr_rlocs_reply)                              \
5436 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5437   one_get_map_request_itr_rlocs_reply)                                  \
5438 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5439 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5440 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5441 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5442 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5443 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5444   show_one_map_register_state_reply)                                    \
5445 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5446 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5447   show_one_map_register_fallback_threshold_reply)                       \
5448 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5449 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5450 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5451 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5452 _(POLICER_DETAILS, policer_details)                                     \
5453 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5454 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5455 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5456 _(MPLS_TABLE_DETAILS, mpls_table_details)                               \
5457 _(MPLS_ROUTE_DETAILS, mpls_route_details)                               \
5458 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5459 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5460 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5461 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5462 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5463 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5464 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5465 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5466 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5467 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5468 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5469 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5470 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5471 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5472 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5473 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5474 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5475 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5476 _(PG_INTERFACE_ENABLE_DISABLE_COALESCE_REPLY, pg_interface_enable_disable_coalesce_reply) \
5477 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5478  ip_source_and_port_range_check_add_del_reply)                          \
5479 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5480  ip_source_and_port_range_check_interface_add_del_reply)                \
5481 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5482 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5483 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5484 _(IP_TABLE_DETAILS, ip_table_details)                                   \
5485 _(IP_ROUTE_DETAILS, ip_route_details)                                   \
5486 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5487 _(FEATURE_GSO_ENABLE_DISABLE_REPLY, feature_gso_enable_disable_reply)   \
5488 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5489 _(SW_INTERFACE_ADD_DEL_MAC_ADDRESS_REPLY, sw_interface_add_del_mac_address_reply) \
5490 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5491 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5492 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5493 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5494 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5495 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5496 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5497 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5498 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5499 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5500 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5501 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5502 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5503 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)             \
5504 _(FLOW_ADD_REPLY, flow_add_reply)   \
5505
5506 #define foreach_standalone_reply_msg                                    \
5507 _(SW_INTERFACE_EVENT, sw_interface_event)
5508
5509 typedef struct
5510 {
5511   u8 *name;
5512   u32 value;
5513 } name_sort_t;
5514
5515 #define STR_VTR_OP_CASE(op)     \
5516     case L2_VTR_ ## op:         \
5517         return "" # op;
5518
5519 static const char *
5520 str_vtr_op (u32 vtr_op)
5521 {
5522   switch (vtr_op)
5523     {
5524       STR_VTR_OP_CASE (DISABLED);
5525       STR_VTR_OP_CASE (PUSH_1);
5526       STR_VTR_OP_CASE (PUSH_2);
5527       STR_VTR_OP_CASE (POP_1);
5528       STR_VTR_OP_CASE (POP_2);
5529       STR_VTR_OP_CASE (TRANSLATE_1_1);
5530       STR_VTR_OP_CASE (TRANSLATE_1_2);
5531       STR_VTR_OP_CASE (TRANSLATE_2_1);
5532       STR_VTR_OP_CASE (TRANSLATE_2_2);
5533     }
5534
5535   return "UNKNOWN";
5536 }
5537
5538 static int
5539 dump_sub_interface_table (vat_main_t * vam)
5540 {
5541   const sw_interface_subif_t *sub = NULL;
5542
5543   if (vam->json_output)
5544     {
5545       clib_warning
5546         ("JSON output supported only for VPE API calls and dump_stats_table");
5547       return -99;
5548     }
5549
5550   print (vam->ofp,
5551          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5552          "Interface", "sw_if_index",
5553          "sub id", "dot1ad", "tags", "outer id",
5554          "inner id", "exact", "default", "outer any", "inner any");
5555
5556   vec_foreach (sub, vam->sw_if_subif_table)
5557   {
5558     print (vam->ofp,
5559            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5560            sub->interface_name,
5561            sub->sw_if_index,
5562            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5563            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5564            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5565            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5566     if (sub->vtr_op != L2_VTR_DISABLED)
5567       {
5568         print (vam->ofp,
5569                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5570                "tag1: %d tag2: %d ]",
5571                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5572                sub->vtr_tag1, sub->vtr_tag2);
5573       }
5574   }
5575
5576   return 0;
5577 }
5578
5579 static int
5580 name_sort_cmp (void *a1, void *a2)
5581 {
5582   name_sort_t *n1 = a1;
5583   name_sort_t *n2 = a2;
5584
5585   return strcmp ((char *) n1->name, (char *) n2->name);
5586 }
5587
5588 static int
5589 dump_interface_table (vat_main_t * vam)
5590 {
5591   hash_pair_t *p;
5592   name_sort_t *nses = 0, *ns;
5593
5594   if (vam->json_output)
5595     {
5596       clib_warning
5597         ("JSON output supported only for VPE API calls and dump_stats_table");
5598       return -99;
5599     }
5600
5601   /* *INDENT-OFF* */
5602   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5603   ({
5604     vec_add2 (nses, ns, 1);
5605     ns->name = (u8 *)(p->key);
5606     ns->value = (u32) p->value[0];
5607   }));
5608   /* *INDENT-ON* */
5609
5610   vec_sort_with_function (nses, name_sort_cmp);
5611
5612   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5613   vec_foreach (ns, nses)
5614   {
5615     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5616   }
5617   vec_free (nses);
5618   return 0;
5619 }
5620
5621 static int
5622 dump_ip_table (vat_main_t * vam, int is_ipv6)
5623 {
5624   const ip_details_t *det = NULL;
5625   const ip_address_details_t *address = NULL;
5626   u32 i = ~0;
5627
5628   print (vam->ofp, "%-12s", "sw_if_index");
5629
5630   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5631   {
5632     i++;
5633     if (!det->present)
5634       {
5635         continue;
5636       }
5637     print (vam->ofp, "%-12d", i);
5638     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5639     if (!det->addr)
5640       {
5641         continue;
5642       }
5643     vec_foreach (address, det->addr)
5644     {
5645       print (vam->ofp,
5646              "            %-30U%-13d",
5647              is_ipv6 ? format_ip6_address : format_ip4_address,
5648              address->ip, address->prefix_length);
5649     }
5650   }
5651
5652   return 0;
5653 }
5654
5655 static int
5656 dump_ipv4_table (vat_main_t * vam)
5657 {
5658   if (vam->json_output)
5659     {
5660       clib_warning
5661         ("JSON output supported only for VPE API calls and dump_stats_table");
5662       return -99;
5663     }
5664
5665   return dump_ip_table (vam, 0);
5666 }
5667
5668 static int
5669 dump_ipv6_table (vat_main_t * vam)
5670 {
5671   if (vam->json_output)
5672     {
5673       clib_warning
5674         ("JSON output supported only for VPE API calls and dump_stats_table");
5675       return -99;
5676     }
5677
5678   return dump_ip_table (vam, 1);
5679 }
5680
5681 /*
5682  * Pass CLI buffers directly in the CLI_INBAND API message,
5683  * instead of an additional shared memory area.
5684  */
5685 static int
5686 exec_inband (vat_main_t * vam)
5687 {
5688   vl_api_cli_inband_t *mp;
5689   unformat_input_t *i = vam->input;
5690   int ret;
5691
5692   if (vec_len (i->buffer) == 0)
5693     return -1;
5694
5695   if (vam->exec_mode == 0 && unformat (i, "mode"))
5696     {
5697       vam->exec_mode = 1;
5698       return 0;
5699     }
5700   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5701     {
5702       vam->exec_mode = 0;
5703       return 0;
5704     }
5705
5706   /*
5707    * In order for the CLI command to work, it
5708    * must be a vector ending in \n, not a C-string ending
5709    * in \n\0.
5710    */
5711   M2 (CLI_INBAND, mp, vec_len (vam->input->buffer));
5712   vl_api_vec_to_api_string (vam->input->buffer, &mp->cmd);
5713
5714   S (mp);
5715   W (ret);
5716   /* json responses may or may not include a useful reply... */
5717   if (vec_len (vam->cmd_reply))
5718     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5719   return ret;
5720 }
5721
5722 int
5723 exec (vat_main_t * vam)
5724 {
5725   return exec_inband (vam);
5726 }
5727
5728 static int
5729 api_create_loopback (vat_main_t * vam)
5730 {
5731   unformat_input_t *i = vam->input;
5732   vl_api_create_loopback_t *mp;
5733   vl_api_create_loopback_instance_t *mp_lbi;
5734   u8 mac_address[6];
5735   u8 mac_set = 0;
5736   u8 is_specified = 0;
5737   u32 user_instance = 0;
5738   int ret;
5739
5740   clib_memset (mac_address, 0, sizeof (mac_address));
5741
5742   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5743     {
5744       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5745         mac_set = 1;
5746       if (unformat (i, "instance %d", &user_instance))
5747         is_specified = 1;
5748       else
5749         break;
5750     }
5751
5752   if (is_specified)
5753     {
5754       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5755       mp_lbi->is_specified = is_specified;
5756       if (is_specified)
5757         mp_lbi->user_instance = htonl (user_instance);
5758       if (mac_set)
5759         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5760       S (mp_lbi);
5761     }
5762   else
5763     {
5764       /* Construct the API message */
5765       M (CREATE_LOOPBACK, mp);
5766       if (mac_set)
5767         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5768       S (mp);
5769     }
5770
5771   W (ret);
5772   return ret;
5773 }
5774
5775 static int
5776 api_delete_loopback (vat_main_t * vam)
5777 {
5778   unformat_input_t *i = vam->input;
5779   vl_api_delete_loopback_t *mp;
5780   u32 sw_if_index = ~0;
5781   int ret;
5782
5783   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5784     {
5785       if (unformat (i, "sw_if_index %d", &sw_if_index))
5786         ;
5787       else
5788         break;
5789     }
5790
5791   if (sw_if_index == ~0)
5792     {
5793       errmsg ("missing sw_if_index");
5794       return -99;
5795     }
5796
5797   /* Construct the API message */
5798   M (DELETE_LOOPBACK, mp);
5799   mp->sw_if_index = ntohl (sw_if_index);
5800
5801   S (mp);
5802   W (ret);
5803   return ret;
5804 }
5805
5806 static int
5807 api_want_interface_events (vat_main_t * vam)
5808 {
5809   unformat_input_t *i = vam->input;
5810   vl_api_want_interface_events_t *mp;
5811   int enable = -1;
5812   int ret;
5813
5814   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5815     {
5816       if (unformat (i, "enable"))
5817         enable = 1;
5818       else if (unformat (i, "disable"))
5819         enable = 0;
5820       else
5821         break;
5822     }
5823
5824   if (enable == -1)
5825     {
5826       errmsg ("missing enable|disable");
5827       return -99;
5828     }
5829
5830   M (WANT_INTERFACE_EVENTS, mp);
5831   mp->enable_disable = enable;
5832
5833   vam->interface_event_display = enable;
5834
5835   S (mp);
5836   W (ret);
5837   return ret;
5838 }
5839
5840
5841 /* Note: non-static, called once to set up the initial intfc table */
5842 int
5843 api_sw_interface_dump (vat_main_t * vam)
5844 {
5845   vl_api_sw_interface_dump_t *mp;
5846   vl_api_control_ping_t *mp_ping;
5847   hash_pair_t *p;
5848   name_sort_t *nses = 0, *ns;
5849   sw_interface_subif_t *sub = NULL;
5850   int ret;
5851
5852   /* Toss the old name table */
5853   /* *INDENT-OFF* */
5854   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5855   ({
5856     vec_add2 (nses, ns, 1);
5857     ns->name = (u8 *)(p->key);
5858     ns->value = (u32) p->value[0];
5859   }));
5860   /* *INDENT-ON* */
5861
5862   hash_free (vam->sw_if_index_by_interface_name);
5863
5864   vec_foreach (ns, nses) vec_free (ns->name);
5865
5866   vec_free (nses);
5867
5868   vec_foreach (sub, vam->sw_if_subif_table)
5869   {
5870     vec_free (sub->interface_name);
5871   }
5872   vec_free (vam->sw_if_subif_table);
5873
5874   /* recreate the interface name hash table */
5875   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5876
5877   /*
5878    * Ask for all interface names. Otherwise, the epic catalog of
5879    * name filters becomes ridiculously long, and vat ends up needing
5880    * to be taught about new interface types.
5881    */
5882   M (SW_INTERFACE_DUMP, mp);
5883   S (mp);
5884
5885   /* Use a control ping for synchronization */
5886   MPING (CONTROL_PING, mp_ping);
5887   S (mp_ping);
5888
5889   W (ret);
5890   return ret;
5891 }
5892
5893 static int
5894 api_sw_interface_set_flags (vat_main_t * vam)
5895 {
5896   unformat_input_t *i = vam->input;
5897   vl_api_sw_interface_set_flags_t *mp;
5898   u32 sw_if_index;
5899   u8 sw_if_index_set = 0;
5900   u8 admin_up = 0;
5901   int ret;
5902
5903   /* Parse args required to build the message */
5904   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5905     {
5906       if (unformat (i, "admin-up"))
5907         admin_up = 1;
5908       else if (unformat (i, "admin-down"))
5909         admin_up = 0;
5910       else
5911         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5912         sw_if_index_set = 1;
5913       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5914         sw_if_index_set = 1;
5915       else
5916         break;
5917     }
5918
5919   if (sw_if_index_set == 0)
5920     {
5921       errmsg ("missing interface name or sw_if_index");
5922       return -99;
5923     }
5924
5925   /* Construct the API message */
5926   M (SW_INTERFACE_SET_FLAGS, mp);
5927   mp->sw_if_index = ntohl (sw_if_index);
5928   mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
5929
5930   /* send it... */
5931   S (mp);
5932
5933   /* Wait for a reply, return the good/bad news... */
5934   W (ret);
5935   return ret;
5936 }
5937
5938 static int
5939 api_sw_interface_set_rx_mode (vat_main_t * vam)
5940 {
5941   unformat_input_t *i = vam->input;
5942   vl_api_sw_interface_set_rx_mode_t *mp;
5943   u32 sw_if_index;
5944   u8 sw_if_index_set = 0;
5945   int ret;
5946   u8 queue_id_valid = 0;
5947   u32 queue_id;
5948   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
5949
5950   /* Parse args required to build the message */
5951   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5952     {
5953       if (unformat (i, "queue %d", &queue_id))
5954         queue_id_valid = 1;
5955       else if (unformat (i, "polling"))
5956         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
5957       else if (unformat (i, "interrupt"))
5958         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
5959       else if (unformat (i, "adaptive"))
5960         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
5961       else
5962         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5963         sw_if_index_set = 1;
5964       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5965         sw_if_index_set = 1;
5966       else
5967         break;
5968     }
5969
5970   if (sw_if_index_set == 0)
5971     {
5972       errmsg ("missing interface name or sw_if_index");
5973       return -99;
5974     }
5975   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
5976     {
5977       errmsg ("missing rx-mode");
5978       return -99;
5979     }
5980
5981   /* Construct the API message */
5982   M (SW_INTERFACE_SET_RX_MODE, mp);
5983   mp->sw_if_index = ntohl (sw_if_index);
5984   mp->mode = (vl_api_rx_mode_t) mode;
5985   mp->queue_id_valid = queue_id_valid;
5986   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
5987
5988   /* send it... */
5989   S (mp);
5990
5991   /* Wait for a reply, return the good/bad news... */
5992   W (ret);
5993   return ret;
5994 }
5995
5996 static int
5997 api_sw_interface_set_rx_placement (vat_main_t * vam)
5998 {
5999   unformat_input_t *i = vam->input;
6000   vl_api_sw_interface_set_rx_placement_t *mp;
6001   u32 sw_if_index;
6002   u8 sw_if_index_set = 0;
6003   int ret;
6004   u8 is_main = 0;
6005   u32 queue_id, thread_index;
6006
6007   /* Parse args required to build the message */
6008   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6009     {
6010       if (unformat (i, "queue %d", &queue_id))
6011         ;
6012       else if (unformat (i, "main"))
6013         is_main = 1;
6014       else if (unformat (i, "worker %d", &thread_index))
6015         ;
6016       else
6017         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6018         sw_if_index_set = 1;
6019       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6020         sw_if_index_set = 1;
6021       else
6022         break;
6023     }
6024
6025   if (sw_if_index_set == 0)
6026     {
6027       errmsg ("missing interface name or sw_if_index");
6028       return -99;
6029     }
6030
6031   if (is_main)
6032     thread_index = 0;
6033   /* Construct the API message */
6034   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6035   mp->sw_if_index = ntohl (sw_if_index);
6036   mp->worker_id = ntohl (thread_index);
6037   mp->queue_id = ntohl (queue_id);
6038   mp->is_main = is_main;
6039
6040   /* send it... */
6041   S (mp);
6042   /* Wait for a reply, return the good/bad news... */
6043   W (ret);
6044   return ret;
6045 }
6046
6047 static void vl_api_sw_interface_rx_placement_details_t_handler
6048   (vl_api_sw_interface_rx_placement_details_t * mp)
6049 {
6050   vat_main_t *vam = &vat_main;
6051   u32 worker_id = ntohl (mp->worker_id);
6052
6053   print (vam->ofp,
6054          "\n%-11d %-11s %-6d %-5d %-9s",
6055          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6056          worker_id, ntohl (mp->queue_id),
6057          (mp->mode ==
6058           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6059 }
6060
6061 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6062   (vl_api_sw_interface_rx_placement_details_t * mp)
6063 {
6064   vat_main_t *vam = &vat_main;
6065   vat_json_node_t *node = NULL;
6066
6067   if (VAT_JSON_ARRAY != vam->json_tree.type)
6068     {
6069       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6070       vat_json_init_array (&vam->json_tree);
6071     }
6072   node = vat_json_array_add (&vam->json_tree);
6073
6074   vat_json_init_object (node);
6075   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6076   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6077   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6078   vat_json_object_add_uint (node, "mode", mp->mode);
6079 }
6080
6081 static int
6082 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6083 {
6084   unformat_input_t *i = vam->input;
6085   vl_api_sw_interface_rx_placement_dump_t *mp;
6086   vl_api_control_ping_t *mp_ping;
6087   int ret;
6088   u32 sw_if_index;
6089   u8 sw_if_index_set = 0;
6090
6091   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6092     {
6093       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6094         sw_if_index_set++;
6095       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6096         sw_if_index_set++;
6097       else
6098         break;
6099     }
6100
6101   print (vam->ofp,
6102          "\n%-11s %-11s %-6s %-5s %-4s",
6103          "sw_if_index", "main/worker", "thread", "queue", "mode");
6104
6105   /* Dump Interface rx placement */
6106   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6107
6108   if (sw_if_index_set)
6109     mp->sw_if_index = htonl (sw_if_index);
6110   else
6111     mp->sw_if_index = ~0;
6112
6113   S (mp);
6114
6115   /* Use a control ping for synchronization */
6116   MPING (CONTROL_PING, mp_ping);
6117   S (mp_ping);
6118
6119   W (ret);
6120   return ret;
6121 }
6122
6123 static int
6124 api_sw_interface_clear_stats (vat_main_t * vam)
6125 {
6126   unformat_input_t *i = vam->input;
6127   vl_api_sw_interface_clear_stats_t *mp;
6128   u32 sw_if_index;
6129   u8 sw_if_index_set = 0;
6130   int ret;
6131
6132   /* Parse args required to build the message */
6133   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6134     {
6135       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6136         sw_if_index_set = 1;
6137       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6138         sw_if_index_set = 1;
6139       else
6140         break;
6141     }
6142
6143   /* Construct the API message */
6144   M (SW_INTERFACE_CLEAR_STATS, mp);
6145
6146   if (sw_if_index_set == 1)
6147     mp->sw_if_index = ntohl (sw_if_index);
6148   else
6149     mp->sw_if_index = ~0;
6150
6151   /* send it... */
6152   S (mp);
6153
6154   /* Wait for a reply, return the good/bad news... */
6155   W (ret);
6156   return ret;
6157 }
6158
6159 static int
6160 api_sw_interface_add_del_address (vat_main_t * vam)
6161 {
6162   unformat_input_t *i = vam->input;
6163   vl_api_sw_interface_add_del_address_t *mp;
6164   u32 sw_if_index;
6165   u8 sw_if_index_set = 0;
6166   u8 is_add = 1, del_all = 0;
6167   u32 address_length = 0;
6168   u8 v4_address_set = 0;
6169   u8 v6_address_set = 0;
6170   ip4_address_t v4address;
6171   ip6_address_t v6address;
6172   int ret;
6173
6174   /* Parse args required to build the message */
6175   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6176     {
6177       if (unformat (i, "del-all"))
6178         del_all = 1;
6179       else if (unformat (i, "del"))
6180         is_add = 0;
6181       else
6182         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6183         sw_if_index_set = 1;
6184       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6185         sw_if_index_set = 1;
6186       else if (unformat (i, "%U/%d",
6187                          unformat_ip4_address, &v4address, &address_length))
6188         v4_address_set = 1;
6189       else if (unformat (i, "%U/%d",
6190                          unformat_ip6_address, &v6address, &address_length))
6191         v6_address_set = 1;
6192       else
6193         break;
6194     }
6195
6196   if (sw_if_index_set == 0)
6197     {
6198       errmsg ("missing interface name or sw_if_index");
6199       return -99;
6200     }
6201   if (v4_address_set && v6_address_set)
6202     {
6203       errmsg ("both v4 and v6 addresses set");
6204       return -99;
6205     }
6206   if (!v4_address_set && !v6_address_set && !del_all)
6207     {
6208       errmsg ("no addresses set");
6209       return -99;
6210     }
6211
6212   /* Construct the API message */
6213   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6214
6215   mp->sw_if_index = ntohl (sw_if_index);
6216   mp->is_add = is_add;
6217   mp->del_all = del_all;
6218   if (v6_address_set)
6219     {
6220       mp->prefix.address.af = ADDRESS_IP6;
6221       clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
6222     }
6223   else
6224     {
6225       mp->prefix.address.af = ADDRESS_IP4;
6226       clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
6227     }
6228   mp->prefix.len = address_length;
6229
6230   /* send it... */
6231   S (mp);
6232
6233   /* Wait for a reply, return good/bad news  */
6234   W (ret);
6235   return ret;
6236 }
6237
6238 static int
6239 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6240 {
6241   unformat_input_t *i = vam->input;
6242   vl_api_sw_interface_set_mpls_enable_t *mp;
6243   u32 sw_if_index;
6244   u8 sw_if_index_set = 0;
6245   u8 enable = 1;
6246   int ret;
6247
6248   /* Parse args required to build the message */
6249   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6250     {
6251       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6252         sw_if_index_set = 1;
6253       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6254         sw_if_index_set = 1;
6255       else if (unformat (i, "disable"))
6256         enable = 0;
6257       else if (unformat (i, "dis"))
6258         enable = 0;
6259       else
6260         break;
6261     }
6262
6263   if (sw_if_index_set == 0)
6264     {
6265       errmsg ("missing interface name or sw_if_index");
6266       return -99;
6267     }
6268
6269   /* Construct the API message */
6270   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6271
6272   mp->sw_if_index = ntohl (sw_if_index);
6273   mp->enable = enable;
6274
6275   /* send it... */
6276   S (mp);
6277
6278   /* Wait for a reply... */
6279   W (ret);
6280   return ret;
6281 }
6282
6283 static int
6284 api_sw_interface_set_table (vat_main_t * vam)
6285 {
6286   unformat_input_t *i = vam->input;
6287   vl_api_sw_interface_set_table_t *mp;
6288   u32 sw_if_index, vrf_id = 0;
6289   u8 sw_if_index_set = 0;
6290   u8 is_ipv6 = 0;
6291   int ret;
6292
6293   /* Parse args required to build the message */
6294   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6295     {
6296       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6297         sw_if_index_set = 1;
6298       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6299         sw_if_index_set = 1;
6300       else if (unformat (i, "vrf %d", &vrf_id))
6301         ;
6302       else if (unformat (i, "ipv6"))
6303         is_ipv6 = 1;
6304       else
6305         break;
6306     }
6307
6308   if (sw_if_index_set == 0)
6309     {
6310       errmsg ("missing interface name or sw_if_index");
6311       return -99;
6312     }
6313
6314   /* Construct the API message */
6315   M (SW_INTERFACE_SET_TABLE, mp);
6316
6317   mp->sw_if_index = ntohl (sw_if_index);
6318   mp->is_ipv6 = is_ipv6;
6319   mp->vrf_id = ntohl (vrf_id);
6320
6321   /* send it... */
6322   S (mp);
6323
6324   /* Wait for a reply... */
6325   W (ret);
6326   return ret;
6327 }
6328
6329 static void vl_api_sw_interface_get_table_reply_t_handler
6330   (vl_api_sw_interface_get_table_reply_t * mp)
6331 {
6332   vat_main_t *vam = &vat_main;
6333
6334   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6335
6336   vam->retval = ntohl (mp->retval);
6337   vam->result_ready = 1;
6338
6339 }
6340
6341 static void vl_api_sw_interface_get_table_reply_t_handler_json
6342   (vl_api_sw_interface_get_table_reply_t * mp)
6343 {
6344   vat_main_t *vam = &vat_main;
6345   vat_json_node_t node;
6346
6347   vat_json_init_object (&node);
6348   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6349   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6350
6351   vat_json_print (vam->ofp, &node);
6352   vat_json_free (&node);
6353
6354   vam->retval = ntohl (mp->retval);
6355   vam->result_ready = 1;
6356 }
6357
6358 static int
6359 api_sw_interface_get_table (vat_main_t * vam)
6360 {
6361   unformat_input_t *i = vam->input;
6362   vl_api_sw_interface_get_table_t *mp;
6363   u32 sw_if_index;
6364   u8 sw_if_index_set = 0;
6365   u8 is_ipv6 = 0;
6366   int ret;
6367
6368   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6369     {
6370       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6371         sw_if_index_set = 1;
6372       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6373         sw_if_index_set = 1;
6374       else if (unformat (i, "ipv6"))
6375         is_ipv6 = 1;
6376       else
6377         break;
6378     }
6379
6380   if (sw_if_index_set == 0)
6381     {
6382       errmsg ("missing interface name or sw_if_index");
6383       return -99;
6384     }
6385
6386   M (SW_INTERFACE_GET_TABLE, mp);
6387   mp->sw_if_index = htonl (sw_if_index);
6388   mp->is_ipv6 = is_ipv6;
6389
6390   S (mp);
6391   W (ret);
6392   return ret;
6393 }
6394
6395 static int
6396 api_sw_interface_set_vpath (vat_main_t * vam)
6397 {
6398   unformat_input_t *i = vam->input;
6399   vl_api_sw_interface_set_vpath_t *mp;
6400   u32 sw_if_index = 0;
6401   u8 sw_if_index_set = 0;
6402   u8 is_enable = 0;
6403   int ret;
6404
6405   /* Parse args required to build the message */
6406   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6407     {
6408       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6409         sw_if_index_set = 1;
6410       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6411         sw_if_index_set = 1;
6412       else if (unformat (i, "enable"))
6413         is_enable = 1;
6414       else if (unformat (i, "disable"))
6415         is_enable = 0;
6416       else
6417         break;
6418     }
6419
6420   if (sw_if_index_set == 0)
6421     {
6422       errmsg ("missing interface name or sw_if_index");
6423       return -99;
6424     }
6425
6426   /* Construct the API message */
6427   M (SW_INTERFACE_SET_VPATH, mp);
6428
6429   mp->sw_if_index = ntohl (sw_if_index);
6430   mp->enable = is_enable;
6431
6432   /* send it... */
6433   S (mp);
6434
6435   /* Wait for a reply... */
6436   W (ret);
6437   return ret;
6438 }
6439
6440 static int
6441 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6442 {
6443   unformat_input_t *i = vam->input;
6444   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6445   u32 sw_if_index = 0;
6446   u8 sw_if_index_set = 0;
6447   u8 is_enable = 1;
6448   u8 is_ipv6 = 0;
6449   int ret;
6450
6451   /* Parse args required to build the message */
6452   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6453     {
6454       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6455         sw_if_index_set = 1;
6456       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6457         sw_if_index_set = 1;
6458       else if (unformat (i, "enable"))
6459         is_enable = 1;
6460       else if (unformat (i, "disable"))
6461         is_enable = 0;
6462       else if (unformat (i, "ip4"))
6463         is_ipv6 = 0;
6464       else if (unformat (i, "ip6"))
6465         is_ipv6 = 1;
6466       else
6467         break;
6468     }
6469
6470   if (sw_if_index_set == 0)
6471     {
6472       errmsg ("missing interface name or sw_if_index");
6473       return -99;
6474     }
6475
6476   /* Construct the API message */
6477   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6478
6479   mp->sw_if_index = ntohl (sw_if_index);
6480   mp->enable = is_enable;
6481   mp->is_ipv6 = is_ipv6;
6482
6483   /* send it... */
6484   S (mp);
6485
6486   /* Wait for a reply... */
6487   W (ret);
6488   return ret;
6489 }
6490
6491 static int
6492 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6493 {
6494   unformat_input_t *i = vam->input;
6495   vl_api_sw_interface_set_l2_xconnect_t *mp;
6496   u32 rx_sw_if_index;
6497   u8 rx_sw_if_index_set = 0;
6498   u32 tx_sw_if_index;
6499   u8 tx_sw_if_index_set = 0;
6500   u8 enable = 1;
6501   int ret;
6502
6503   /* Parse args required to build the message */
6504   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6505     {
6506       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6507         rx_sw_if_index_set = 1;
6508       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6509         tx_sw_if_index_set = 1;
6510       else if (unformat (i, "rx"))
6511         {
6512           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6513             {
6514               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6515                             &rx_sw_if_index))
6516                 rx_sw_if_index_set = 1;
6517             }
6518           else
6519             break;
6520         }
6521       else if (unformat (i, "tx"))
6522         {
6523           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6524             {
6525               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6526                             &tx_sw_if_index))
6527                 tx_sw_if_index_set = 1;
6528             }
6529           else
6530             break;
6531         }
6532       else if (unformat (i, "enable"))
6533         enable = 1;
6534       else if (unformat (i, "disable"))
6535         enable = 0;
6536       else
6537         break;
6538     }
6539
6540   if (rx_sw_if_index_set == 0)
6541     {
6542       errmsg ("missing rx interface name or rx_sw_if_index");
6543       return -99;
6544     }
6545
6546   if (enable && (tx_sw_if_index_set == 0))
6547     {
6548       errmsg ("missing tx interface name or tx_sw_if_index");
6549       return -99;
6550     }
6551
6552   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6553
6554   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6555   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6556   mp->enable = enable;
6557
6558   S (mp);
6559   W (ret);
6560   return ret;
6561 }
6562
6563 static int
6564 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6565 {
6566   unformat_input_t *i = vam->input;
6567   vl_api_sw_interface_set_l2_bridge_t *mp;
6568   vl_api_l2_port_type_t port_type;
6569   u32 rx_sw_if_index;
6570   u8 rx_sw_if_index_set = 0;
6571   u32 bd_id;
6572   u8 bd_id_set = 0;
6573   u32 shg = 0;
6574   u8 enable = 1;
6575   int ret;
6576
6577   port_type = L2_API_PORT_TYPE_NORMAL;
6578
6579   /* Parse args required to build the message */
6580   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6581     {
6582       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6583         rx_sw_if_index_set = 1;
6584       else if (unformat (i, "bd_id %d", &bd_id))
6585         bd_id_set = 1;
6586       else
6587         if (unformat
6588             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6589         rx_sw_if_index_set = 1;
6590       else if (unformat (i, "shg %d", &shg))
6591         ;
6592       else if (unformat (i, "bvi"))
6593         port_type = L2_API_PORT_TYPE_BVI;
6594       else if (unformat (i, "uu-fwd"))
6595         port_type = L2_API_PORT_TYPE_UU_FWD;
6596       else if (unformat (i, "enable"))
6597         enable = 1;
6598       else if (unformat (i, "disable"))
6599         enable = 0;
6600       else
6601         break;
6602     }
6603
6604   if (rx_sw_if_index_set == 0)
6605     {
6606       errmsg ("missing rx interface name or sw_if_index");
6607       return -99;
6608     }
6609
6610   if (enable && (bd_id_set == 0))
6611     {
6612       errmsg ("missing bridge domain");
6613       return -99;
6614     }
6615
6616   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6617
6618   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6619   mp->bd_id = ntohl (bd_id);
6620   mp->shg = (u8) shg;
6621   mp->port_type = ntohl (port_type);
6622   mp->enable = enable;
6623
6624   S (mp);
6625   W (ret);
6626   return ret;
6627 }
6628
6629 static int
6630 api_bridge_domain_dump (vat_main_t * vam)
6631 {
6632   unformat_input_t *i = vam->input;
6633   vl_api_bridge_domain_dump_t *mp;
6634   vl_api_control_ping_t *mp_ping;
6635   u32 bd_id = ~0;
6636   int ret;
6637
6638   /* Parse args required to build the message */
6639   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6640     {
6641       if (unformat (i, "bd_id %d", &bd_id))
6642         ;
6643       else
6644         break;
6645     }
6646
6647   M (BRIDGE_DOMAIN_DUMP, mp);
6648   mp->bd_id = ntohl (bd_id);
6649   S (mp);
6650
6651   /* Use a control ping for synchronization */
6652   MPING (CONTROL_PING, mp_ping);
6653   S (mp_ping);
6654
6655   W (ret);
6656   return ret;
6657 }
6658
6659 static int
6660 api_bridge_domain_add_del (vat_main_t * vam)
6661 {
6662   unformat_input_t *i = vam->input;
6663   vl_api_bridge_domain_add_del_t *mp;
6664   u32 bd_id = ~0;
6665   u8 is_add = 1;
6666   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6667   u8 *bd_tag = NULL;
6668   u32 mac_age = 0;
6669   int ret;
6670
6671   /* Parse args required to build the message */
6672   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6673     {
6674       if (unformat (i, "bd_id %d", &bd_id))
6675         ;
6676       else if (unformat (i, "flood %d", &flood))
6677         ;
6678       else if (unformat (i, "uu-flood %d", &uu_flood))
6679         ;
6680       else if (unformat (i, "forward %d", &forward))
6681         ;
6682       else if (unformat (i, "learn %d", &learn))
6683         ;
6684       else if (unformat (i, "arp-term %d", &arp_term))
6685         ;
6686       else if (unformat (i, "mac-age %d", &mac_age))
6687         ;
6688       else if (unformat (i, "bd-tag %s", &bd_tag))
6689         ;
6690       else if (unformat (i, "del"))
6691         {
6692           is_add = 0;
6693           flood = uu_flood = forward = learn = 0;
6694         }
6695       else
6696         break;
6697     }
6698
6699   if (bd_id == ~0)
6700     {
6701       errmsg ("missing bridge domain");
6702       ret = -99;
6703       goto done;
6704     }
6705
6706   if (mac_age > 255)
6707     {
6708       errmsg ("mac age must be less than 256 ");
6709       ret = -99;
6710       goto done;
6711     }
6712
6713   if ((bd_tag) && (vec_len (bd_tag) > 63))
6714     {
6715       errmsg ("bd-tag cannot be longer than 63");
6716       ret = -99;
6717       goto done;
6718     }
6719
6720   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6721
6722   mp->bd_id = ntohl (bd_id);
6723   mp->flood = flood;
6724   mp->uu_flood = uu_flood;
6725   mp->forward = forward;
6726   mp->learn = learn;
6727   mp->arp_term = arp_term;
6728   mp->is_add = is_add;
6729   mp->mac_age = (u8) mac_age;
6730   if (bd_tag)
6731     {
6732       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6733       mp->bd_tag[vec_len (bd_tag)] = 0;
6734     }
6735   S (mp);
6736   W (ret);
6737
6738 done:
6739   vec_free (bd_tag);
6740   return ret;
6741 }
6742
6743 static int
6744 api_l2fib_flush_bd (vat_main_t * vam)
6745 {
6746   unformat_input_t *i = vam->input;
6747   vl_api_l2fib_flush_bd_t *mp;
6748   u32 bd_id = ~0;
6749   int ret;
6750
6751   /* Parse args required to build the message */
6752   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6753     {
6754       if (unformat (i, "bd_id %d", &bd_id));
6755       else
6756         break;
6757     }
6758
6759   if (bd_id == ~0)
6760     {
6761       errmsg ("missing bridge domain");
6762       return -99;
6763     }
6764
6765   M (L2FIB_FLUSH_BD, mp);
6766
6767   mp->bd_id = htonl (bd_id);
6768
6769   S (mp);
6770   W (ret);
6771   return ret;
6772 }
6773
6774 static int
6775 api_l2fib_flush_int (vat_main_t * vam)
6776 {
6777   unformat_input_t *i = vam->input;
6778   vl_api_l2fib_flush_int_t *mp;
6779   u32 sw_if_index = ~0;
6780   int ret;
6781
6782   /* Parse args required to build the message */
6783   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6784     {
6785       if (unformat (i, "sw_if_index %d", &sw_if_index));
6786       else
6787         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6788       else
6789         break;
6790     }
6791
6792   if (sw_if_index == ~0)
6793     {
6794       errmsg ("missing interface name or sw_if_index");
6795       return -99;
6796     }
6797
6798   M (L2FIB_FLUSH_INT, mp);
6799
6800   mp->sw_if_index = ntohl (sw_if_index);
6801
6802   S (mp);
6803   W (ret);
6804   return ret;
6805 }
6806
6807 static int
6808 api_l2fib_add_del (vat_main_t * vam)
6809 {
6810   unformat_input_t *i = vam->input;
6811   vl_api_l2fib_add_del_t *mp;
6812   f64 timeout;
6813   u8 mac[6] = { 0 };
6814   u8 mac_set = 0;
6815   u32 bd_id;
6816   u8 bd_id_set = 0;
6817   u32 sw_if_index = 0;
6818   u8 sw_if_index_set = 0;
6819   u8 is_add = 1;
6820   u8 static_mac = 0;
6821   u8 filter_mac = 0;
6822   u8 bvi_mac = 0;
6823   int count = 1;
6824   f64 before = 0;
6825   int j;
6826
6827   /* Parse args required to build the message */
6828   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6829     {
6830       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6831         mac_set = 1;
6832       else if (unformat (i, "bd_id %d", &bd_id))
6833         bd_id_set = 1;
6834       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6835         sw_if_index_set = 1;
6836       else if (unformat (i, "sw_if"))
6837         {
6838           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6839             {
6840               if (unformat
6841                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6842                 sw_if_index_set = 1;
6843             }
6844           else
6845             break;
6846         }
6847       else if (unformat (i, "static"))
6848         static_mac = 1;
6849       else if (unformat (i, "filter"))
6850         {
6851           filter_mac = 1;
6852           static_mac = 1;
6853         }
6854       else if (unformat (i, "bvi"))
6855         {
6856           bvi_mac = 1;
6857           static_mac = 1;
6858         }
6859       else if (unformat (i, "del"))
6860         is_add = 0;
6861       else if (unformat (i, "count %d", &count))
6862         ;
6863       else
6864         break;
6865     }
6866
6867   if (mac_set == 0)
6868     {
6869       errmsg ("missing mac address");
6870       return -99;
6871     }
6872
6873   if (bd_id_set == 0)
6874     {
6875       errmsg ("missing bridge domain");
6876       return -99;
6877     }
6878
6879   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6880     {
6881       errmsg ("missing interface name or sw_if_index");
6882       return -99;
6883     }
6884
6885   if (count > 1)
6886     {
6887       /* Turn on async mode */
6888       vam->async_mode = 1;
6889       vam->async_errors = 0;
6890       before = vat_time_now (vam);
6891     }
6892
6893   for (j = 0; j < count; j++)
6894     {
6895       M (L2FIB_ADD_DEL, mp);
6896
6897       clib_memcpy (mp->mac, mac, 6);
6898       mp->bd_id = ntohl (bd_id);
6899       mp->is_add = is_add;
6900       mp->sw_if_index = ntohl (sw_if_index);
6901
6902       if (is_add)
6903         {
6904           mp->static_mac = static_mac;
6905           mp->filter_mac = filter_mac;
6906           mp->bvi_mac = bvi_mac;
6907         }
6908       increment_mac_address (mac);
6909       /* send it... */
6910       S (mp);
6911     }
6912
6913   if (count > 1)
6914     {
6915       vl_api_control_ping_t *mp_ping;
6916       f64 after;
6917
6918       /* Shut off async mode */
6919       vam->async_mode = 0;
6920
6921       MPING (CONTROL_PING, mp_ping);
6922       S (mp_ping);
6923
6924       timeout = vat_time_now (vam) + 1.0;
6925       while (vat_time_now (vam) < timeout)
6926         if (vam->result_ready == 1)
6927           goto out;
6928       vam->retval = -99;
6929
6930     out:
6931       if (vam->retval == -99)
6932         errmsg ("timeout");
6933
6934       if (vam->async_errors > 0)
6935         {
6936           errmsg ("%d asynchronous errors", vam->async_errors);
6937           vam->retval = -98;
6938         }
6939       vam->async_errors = 0;
6940       after = vat_time_now (vam);
6941
6942       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6943              count, after - before, count / (after - before));
6944     }
6945   else
6946     {
6947       int ret;
6948
6949       /* Wait for a reply... */
6950       W (ret);
6951       return ret;
6952     }
6953   /* Return the good/bad news */
6954   return (vam->retval);
6955 }
6956
6957 static int
6958 api_bridge_domain_set_mac_age (vat_main_t * vam)
6959 {
6960   unformat_input_t *i = vam->input;
6961   vl_api_bridge_domain_set_mac_age_t *mp;
6962   u32 bd_id = ~0;
6963   u32 mac_age = 0;
6964   int ret;
6965
6966   /* Parse args required to build the message */
6967   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6968     {
6969       if (unformat (i, "bd_id %d", &bd_id));
6970       else if (unformat (i, "mac-age %d", &mac_age));
6971       else
6972         break;
6973     }
6974
6975   if (bd_id == ~0)
6976     {
6977       errmsg ("missing bridge domain");
6978       return -99;
6979     }
6980
6981   if (mac_age > 255)
6982     {
6983       errmsg ("mac age must be less than 256 ");
6984       return -99;
6985     }
6986
6987   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
6988
6989   mp->bd_id = htonl (bd_id);
6990   mp->mac_age = (u8) mac_age;
6991
6992   S (mp);
6993   W (ret);
6994   return ret;
6995 }
6996
6997 static int
6998 api_l2_flags (vat_main_t * vam)
6999 {
7000   unformat_input_t *i = vam->input;
7001   vl_api_l2_flags_t *mp;
7002   u32 sw_if_index;
7003   u32 flags = 0;
7004   u8 sw_if_index_set = 0;
7005   u8 is_set = 0;
7006   int ret;
7007
7008   /* Parse args required to build the message */
7009   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7010     {
7011       if (unformat (i, "sw_if_index %d", &sw_if_index))
7012         sw_if_index_set = 1;
7013       else if (unformat (i, "sw_if"))
7014         {
7015           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7016             {
7017               if (unformat
7018                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7019                 sw_if_index_set = 1;
7020             }
7021           else
7022             break;
7023         }
7024       else if (unformat (i, "learn"))
7025         flags |= L2_LEARN;
7026       else if (unformat (i, "forward"))
7027         flags |= L2_FWD;
7028       else if (unformat (i, "flood"))
7029         flags |= L2_FLOOD;
7030       else if (unformat (i, "uu-flood"))
7031         flags |= L2_UU_FLOOD;
7032       else if (unformat (i, "arp-term"))
7033         flags |= L2_ARP_TERM;
7034       else if (unformat (i, "off"))
7035         is_set = 0;
7036       else if (unformat (i, "disable"))
7037         is_set = 0;
7038       else
7039         break;
7040     }
7041
7042   if (sw_if_index_set == 0)
7043     {
7044       errmsg ("missing interface name or sw_if_index");
7045       return -99;
7046     }
7047
7048   M (L2_FLAGS, mp);
7049
7050   mp->sw_if_index = ntohl (sw_if_index);
7051   mp->feature_bitmap = ntohl (flags);
7052   mp->is_set = is_set;
7053
7054   S (mp);
7055   W (ret);
7056   return ret;
7057 }
7058
7059 static int
7060 api_bridge_flags (vat_main_t * vam)
7061 {
7062   unformat_input_t *i = vam->input;
7063   vl_api_bridge_flags_t *mp;
7064   u32 bd_id;
7065   u8 bd_id_set = 0;
7066   u8 is_set = 1;
7067   bd_flags_t flags = 0;
7068   int ret;
7069
7070   /* Parse args required to build the message */
7071   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7072     {
7073       if (unformat (i, "bd_id %d", &bd_id))
7074         bd_id_set = 1;
7075       else if (unformat (i, "learn"))
7076         flags |= BRIDGE_API_FLAG_LEARN;
7077       else if (unformat (i, "forward"))
7078         flags |= BRIDGE_API_FLAG_FWD;
7079       else if (unformat (i, "flood"))
7080         flags |= BRIDGE_API_FLAG_FLOOD;
7081       else if (unformat (i, "uu-flood"))
7082         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7083       else if (unformat (i, "arp-term"))
7084         flags |= BRIDGE_API_FLAG_ARP_TERM;
7085       else if (unformat (i, "off"))
7086         is_set = 0;
7087       else if (unformat (i, "disable"))
7088         is_set = 0;
7089       else
7090         break;
7091     }
7092
7093   if (bd_id_set == 0)
7094     {
7095       errmsg ("missing bridge domain");
7096       return -99;
7097     }
7098
7099   M (BRIDGE_FLAGS, mp);
7100
7101   mp->bd_id = ntohl (bd_id);
7102   mp->flags = ntohl (flags);
7103   mp->is_set = is_set;
7104
7105   S (mp);
7106   W (ret);
7107   return ret;
7108 }
7109
7110 static int
7111 api_bd_ip_mac_add_del (vat_main_t * vam)
7112 {
7113   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7114   vl_api_mac_address_t mac = { 0 };
7115   unformat_input_t *i = vam->input;
7116   vl_api_bd_ip_mac_add_del_t *mp;
7117   u32 bd_id;
7118   u8 is_add = 1;
7119   u8 bd_id_set = 0;
7120   u8 ip_set = 0;
7121   u8 mac_set = 0;
7122   int ret;
7123
7124
7125   /* Parse args required to build the message */
7126   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7127     {
7128       if (unformat (i, "bd_id %d", &bd_id))
7129         {
7130           bd_id_set++;
7131         }
7132       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7133         {
7134           ip_set++;
7135         }
7136       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7137         {
7138           mac_set++;
7139         }
7140       else if (unformat (i, "del"))
7141         is_add = 0;
7142       else
7143         break;
7144     }
7145
7146   if (bd_id_set == 0)
7147     {
7148       errmsg ("missing bridge domain");
7149       return -99;
7150     }
7151   else if (ip_set == 0)
7152     {
7153       errmsg ("missing IP address");
7154       return -99;
7155     }
7156   else if (mac_set == 0)
7157     {
7158       errmsg ("missing MAC address");
7159       return -99;
7160     }
7161
7162   M (BD_IP_MAC_ADD_DEL, mp);
7163
7164   mp->entry.bd_id = ntohl (bd_id);
7165   mp->is_add = is_add;
7166
7167   clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
7168   clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
7169
7170   S (mp);
7171   W (ret);
7172   return ret;
7173 }
7174
7175 static int
7176 api_bd_ip_mac_flush (vat_main_t * vam)
7177 {
7178   unformat_input_t *i = vam->input;
7179   vl_api_bd_ip_mac_flush_t *mp;
7180   u32 bd_id;
7181   u8 bd_id_set = 0;
7182   int ret;
7183
7184   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7185     {
7186       if (unformat (i, "bd_id %d", &bd_id))
7187         {
7188           bd_id_set++;
7189         }
7190       else
7191         break;
7192     }
7193
7194   if (bd_id_set == 0)
7195     {
7196       errmsg ("missing bridge domain");
7197       return -99;
7198     }
7199
7200   M (BD_IP_MAC_FLUSH, mp);
7201
7202   mp->bd_id = ntohl (bd_id);
7203
7204   S (mp);
7205   W (ret);
7206   return ret;
7207 }
7208
7209 static void vl_api_bd_ip_mac_details_t_handler
7210   (vl_api_bd_ip_mac_details_t * mp)
7211 {
7212   vat_main_t *vam = &vat_main;
7213
7214   print (vam->ofp,
7215          "\n%-5d %U %U",
7216          ntohl (mp->entry.bd_id),
7217          format_vl_api_mac_address, mp->entry.mac,
7218          format_vl_api_address, &mp->entry.ip);
7219 }
7220
7221 static void vl_api_bd_ip_mac_details_t_handler_json
7222   (vl_api_bd_ip_mac_details_t * mp)
7223 {
7224   vat_main_t *vam = &vat_main;
7225   vat_json_node_t *node = NULL;
7226
7227   if (VAT_JSON_ARRAY != vam->json_tree.type)
7228     {
7229       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7230       vat_json_init_array (&vam->json_tree);
7231     }
7232   node = vat_json_array_add (&vam->json_tree);
7233
7234   vat_json_init_object (node);
7235   vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
7236   vat_json_object_add_string_copy (node, "mac_address",
7237                                    format (0, "%U", format_vl_api_mac_address,
7238                                            &mp->entry.mac));
7239   u8 *ip = 0;
7240
7241   ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
7242   vat_json_object_add_string_copy (node, "ip_address", ip);
7243   vec_free (ip);
7244 }
7245
7246 static int
7247 api_bd_ip_mac_dump (vat_main_t * vam)
7248 {
7249   unformat_input_t *i = vam->input;
7250   vl_api_bd_ip_mac_dump_t *mp;
7251   vl_api_control_ping_t *mp_ping;
7252   int ret;
7253   u32 bd_id;
7254   u8 bd_id_set = 0;
7255
7256   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7257     {
7258       if (unformat (i, "bd_id %d", &bd_id))
7259         {
7260           bd_id_set++;
7261         }
7262       else
7263         break;
7264     }
7265
7266   print (vam->ofp,
7267          "\n%-5s %-7s %-20s %-30s",
7268          "bd_id", "is_ipv6", "mac_address", "ip_address");
7269
7270   /* Dump Bridge Domain Ip to Mac entries */
7271   M (BD_IP_MAC_DUMP, mp);
7272
7273   if (bd_id_set)
7274     mp->bd_id = htonl (bd_id);
7275   else
7276     mp->bd_id = ~0;
7277
7278   S (mp);
7279
7280   /* Use a control ping for synchronization */
7281   MPING (CONTROL_PING, mp_ping);
7282   S (mp_ping);
7283
7284   W (ret);
7285   return ret;
7286 }
7287
7288 static int
7289 api_tap_create_v2 (vat_main_t * vam)
7290 {
7291   unformat_input_t *i = vam->input;
7292   vl_api_tap_create_v2_t *mp;
7293   u8 mac_address[6];
7294   u8 random_mac = 1;
7295   u32 id = ~0;
7296   u32 num_rx_queues = 0;
7297   u8 *host_if_name = 0;
7298   u8 host_if_name_set = 0;
7299   u8 *host_ns = 0;
7300   u8 host_ns_set = 0;
7301   u8 host_mac_addr[6];
7302   u8 host_mac_addr_set = 0;
7303   u8 *host_bridge = 0;
7304   u8 host_bridge_set = 0;
7305   u8 host_ip4_prefix_set = 0;
7306   u8 host_ip6_prefix_set = 0;
7307   ip4_address_t host_ip4_addr;
7308   ip4_address_t host_ip4_gw;
7309   u8 host_ip4_gw_set = 0;
7310   u32 host_ip4_prefix_len = 0;
7311   ip6_address_t host_ip6_addr;
7312   ip6_address_t host_ip6_gw;
7313   u8 host_ip6_gw_set = 0;
7314   u32 host_ip6_prefix_len = 0;
7315   u32 host_mtu_size = 0;
7316   u8 host_mtu_set = 0;
7317   u32 tap_flags = 0;
7318   int ret;
7319   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7320
7321   clib_memset (mac_address, 0, sizeof (mac_address));
7322
7323   /* Parse args required to build the message */
7324   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7325     {
7326       if (unformat (i, "id %u", &id))
7327         ;
7328       else
7329         if (unformat
7330             (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7331         random_mac = 0;
7332       else if (unformat (i, "host-if-name %s", &host_if_name))
7333         host_if_name_set = 1;
7334       else if (unformat (i, "num-rx-queues %u", &num_rx_queues))
7335         ;
7336       else if (unformat (i, "host-ns %s", &host_ns))
7337         host_ns_set = 1;
7338       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7339                          host_mac_addr))
7340         host_mac_addr_set = 1;
7341       else if (unformat (i, "host-bridge %s", &host_bridge))
7342         host_bridge_set = 1;
7343       else if (unformat (i, "host-ip4-addr %U/%u", unformat_ip4_address,
7344                          &host_ip4_addr, &host_ip4_prefix_len))
7345         host_ip4_prefix_set = 1;
7346       else if (unformat (i, "host-ip6-addr %U/%u", unformat_ip6_address,
7347                          &host_ip6_addr, &host_ip6_prefix_len))
7348         host_ip6_prefix_set = 1;
7349       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7350                          &host_ip4_gw))
7351         host_ip4_gw_set = 1;
7352       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7353                          &host_ip6_gw))
7354         host_ip6_gw_set = 1;
7355       else if (unformat (i, "rx-ring-size %u", &rx_ring_sz))
7356         ;
7357       else if (unformat (i, "tx-ring-size %u", &tx_ring_sz))
7358         ;
7359       else if (unformat (i, "host-mtu-size %u", &host_mtu_size))
7360         host_mtu_set = 1;
7361       else if (unformat (i, "no-gso"))
7362         tap_flags &= ~TAP_API_FLAG_GSO;
7363       else if (unformat (i, "gso"))
7364         tap_flags |= TAP_API_FLAG_GSO;
7365       else if (unformat (i, "csum-offload"))
7366         tap_flags |= TAP_API_FLAG_CSUM_OFFLOAD;
7367       else if (unformat (i, "persist"))
7368         tap_flags |= TAP_API_FLAG_PERSIST;
7369       else if (unformat (i, "attach"))
7370         tap_flags |= TAP_API_FLAG_ATTACH;
7371       else if (unformat (i, "tun"))
7372         tap_flags |= TAP_API_FLAG_TUN;
7373       else if (unformat (i, "gro-coalesce"))
7374         tap_flags |= TAP_API_FLAG_GRO_COALESCE;
7375       else if (unformat (i, "packed"))
7376         tap_flags |= TAP_API_FLAG_PACKED;
7377       else if (unformat (i, "in-order"))
7378         tap_flags |= TAP_API_FLAG_IN_ORDER;
7379       else
7380         break;
7381     }
7382
7383   if (vec_len (host_if_name) > 63)
7384     {
7385       errmsg ("tap name too long. ");
7386       return -99;
7387     }
7388   if (vec_len (host_ns) > 63)
7389     {
7390       errmsg ("host name space too long. ");
7391       return -99;
7392     }
7393   if (vec_len (host_bridge) > 63)
7394     {
7395       errmsg ("host bridge name too long. ");
7396       return -99;
7397     }
7398   if (host_ip4_prefix_len > 32)
7399     {
7400       errmsg ("host ip4 prefix length not valid. ");
7401       return -99;
7402     }
7403   if (host_ip6_prefix_len > 128)
7404     {
7405       errmsg ("host ip6 prefix length not valid. ");
7406       return -99;
7407     }
7408   if (!is_pow2 (rx_ring_sz))
7409     {
7410       errmsg ("rx ring size must be power of 2. ");
7411       return -99;
7412     }
7413   if (rx_ring_sz > 32768)
7414     {
7415       errmsg ("rx ring size must be 32768 or lower. ");
7416       return -99;
7417     }
7418   if (!is_pow2 (tx_ring_sz))
7419     {
7420       errmsg ("tx ring size must be power of 2. ");
7421       return -99;
7422     }
7423   if (tx_ring_sz > 32768)
7424     {
7425       errmsg ("tx ring size must be 32768 or lower. ");
7426       return -99;
7427     }
7428   if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
7429     {
7430       errmsg ("host MTU size must be in between 64 and 65355. ");
7431       return -99;
7432     }
7433
7434   /* Construct the API message */
7435   M (TAP_CREATE_V2, mp);
7436
7437   mp->id = ntohl (id);
7438   mp->use_random_mac = random_mac;
7439   mp->num_rx_queues = (u8) num_rx_queues;
7440   mp->tx_ring_sz = ntohs (tx_ring_sz);
7441   mp->rx_ring_sz = ntohs (rx_ring_sz);
7442   mp->host_mtu_set = host_mtu_set;
7443   mp->host_mtu_size = ntohl (host_mtu_size);
7444   mp->host_mac_addr_set = host_mac_addr_set;
7445   mp->host_ip4_prefix_set = host_ip4_prefix_set;
7446   mp->host_ip6_prefix_set = host_ip6_prefix_set;
7447   mp->host_ip4_gw_set = host_ip4_gw_set;
7448   mp->host_ip6_gw_set = host_ip6_gw_set;
7449   mp->tap_flags = ntohl (tap_flags);
7450   mp->host_namespace_set = host_ns_set;
7451   mp->host_if_name_set = host_if_name_set;
7452   mp->host_bridge_set = host_bridge_set;
7453
7454   if (random_mac == 0)
7455     clib_memcpy (mp->mac_address, mac_address, 6);
7456   if (host_mac_addr_set)
7457     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7458   if (host_if_name_set)
7459     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7460   if (host_ns_set)
7461     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7462   if (host_bridge_set)
7463     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7464   if (host_ip4_prefix_set)
7465     {
7466       clib_memcpy (mp->host_ip4_prefix.address, &host_ip4_addr, 4);
7467       mp->host_ip4_prefix.len = (u8) host_ip4_prefix_len;
7468     }
7469   if (host_ip6_prefix_set)
7470     {
7471       clib_memcpy (mp->host_ip6_prefix.address, &host_ip6_addr, 16);
7472       mp->host_ip6_prefix.len = (u8) host_ip6_prefix_len;
7473     }
7474   if (host_ip4_gw_set)
7475     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7476   if (host_ip6_gw_set)
7477     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7478
7479   vec_free (host_ns);
7480   vec_free (host_if_name);
7481   vec_free (host_bridge);
7482
7483   /* send it... */
7484   S (mp);
7485
7486   /* Wait for a reply... */
7487   W (ret);
7488   return ret;
7489 }
7490
7491 static int
7492 api_tap_delete_v2 (vat_main_t * vam)
7493 {
7494   unformat_input_t *i = vam->input;
7495   vl_api_tap_delete_v2_t *mp;
7496   u32 sw_if_index = ~0;
7497   u8 sw_if_index_set = 0;
7498   int ret;
7499
7500   /* Parse args required to build the message */
7501   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7502     {
7503       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7504         sw_if_index_set = 1;
7505       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7506         sw_if_index_set = 1;
7507       else
7508         break;
7509     }
7510
7511   if (sw_if_index_set == 0)
7512     {
7513       errmsg ("missing vpp interface name. ");
7514       return -99;
7515     }
7516
7517   /* Construct the API message */
7518   M (TAP_DELETE_V2, mp);
7519
7520   mp->sw_if_index = ntohl (sw_if_index);
7521
7522   /* send it... */
7523   S (mp);
7524
7525   /* Wait for a reply... */
7526   W (ret);
7527   return ret;
7528 }
7529
7530 uword
7531 unformat_vlib_pci_addr (unformat_input_t * input, va_list * args)
7532 {
7533   vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
7534   u32 x[4];
7535
7536   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7537     return 0;
7538
7539   addr->domain = x[0];
7540   addr->bus = x[1];
7541   addr->slot = x[2];
7542   addr->function = x[3];
7543
7544   return 1;
7545 }
7546
7547 static int
7548 api_virtio_pci_create_v2 (vat_main_t * vam)
7549 {
7550   unformat_input_t *i = vam->input;
7551   vl_api_virtio_pci_create_v2_t *mp;
7552   u8 mac_address[6];
7553   u8 random_mac = 1;
7554   u32 pci_addr = 0;
7555   u64 features = (u64) ~ (0ULL);
7556   u32 virtio_flags = 0;
7557   int ret;
7558
7559   clib_memset (mac_address, 0, sizeof (mac_address));
7560
7561   /* Parse args required to build the message */
7562   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7563     {
7564       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7565         {
7566           random_mac = 0;
7567         }
7568       else if (unformat (i, "pci-addr %U", unformat_vlib_pci_addr, &pci_addr))
7569         ;
7570       else if (unformat (i, "features 0x%llx", &features))
7571         ;
7572       else if (unformat (i, "gso-enabled"))
7573         virtio_flags |= VIRTIO_API_FLAG_GSO;
7574       else if (unformat (i, "csum-offload-enabled"))
7575         virtio_flags |= VIRTIO_API_FLAG_CSUM_OFFLOAD;
7576       else if (unformat (i, "gro-coalesce"))
7577         virtio_flags |= VIRTIO_API_FLAG_GRO_COALESCE;
7578       else if (unformat (i, "packed"))
7579         virtio_flags |= VIRTIO_API_FLAG_PACKED;
7580       else if (unformat (i, "in-order"))
7581         virtio_flags |= VIRTIO_API_FLAG_IN_ORDER;
7582       else
7583         break;
7584     }
7585
7586   if (pci_addr == 0)
7587     {
7588       errmsg ("pci address must be non zero. ");
7589       return -99;
7590     }
7591
7592   /* Construct the API message */
7593   M (VIRTIO_PCI_CREATE_V2, mp);
7594
7595   mp->use_random_mac = random_mac;
7596
7597   mp->pci_addr.domain = htons (((vlib_pci_addr_t) pci_addr).domain);
7598   mp->pci_addr.bus = ((vlib_pci_addr_t) pci_addr).bus;
7599   mp->pci_addr.slot = ((vlib_pci_addr_t) pci_addr).slot;
7600   mp->pci_addr.function = ((vlib_pci_addr_t) pci_addr).function;
7601
7602   mp->features = clib_host_to_net_u64 (features);
7603   mp->virtio_flags = clib_host_to_net_u32 (virtio_flags);
7604
7605   if (random_mac == 0)
7606     clib_memcpy (mp->mac_address, mac_address, 6);
7607
7608   /* send it... */
7609   S (mp);
7610
7611   /* Wait for a reply... */
7612   W (ret);
7613   return ret;
7614 }
7615
7616 static int
7617 api_virtio_pci_delete (vat_main_t * vam)
7618 {
7619   unformat_input_t *i = vam->input;
7620   vl_api_virtio_pci_delete_t *mp;
7621   u32 sw_if_index = ~0;
7622   u8 sw_if_index_set = 0;
7623   int ret;
7624
7625   /* Parse args required to build the message */
7626   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7627     {
7628       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7629         sw_if_index_set = 1;
7630       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7631         sw_if_index_set = 1;
7632       else
7633         break;
7634     }
7635
7636   if (sw_if_index_set == 0)
7637     {
7638       errmsg ("missing vpp interface name. ");
7639       return -99;
7640     }
7641
7642   /* Construct the API message */
7643   M (VIRTIO_PCI_DELETE, mp);
7644
7645   mp->sw_if_index = htonl (sw_if_index);
7646
7647   /* send it... */
7648   S (mp);
7649
7650   /* Wait for a reply... */
7651   W (ret);
7652   return ret;
7653 }
7654
7655 static int
7656 api_bond_create (vat_main_t * vam)
7657 {
7658   unformat_input_t *i = vam->input;
7659   vl_api_bond_create_t *mp;
7660   u8 mac_address[6];
7661   u8 custom_mac = 0;
7662   int ret;
7663   u8 mode;
7664   u8 lb;
7665   u8 mode_is_set = 0;
7666   u32 id = ~0;
7667   u8 numa_only = 0;
7668
7669   clib_memset (mac_address, 0, sizeof (mac_address));
7670   lb = BOND_LB_L2;
7671
7672   /* Parse args required to build the message */
7673   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7674     {
7675       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7676         mode_is_set = 1;
7677       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7678                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7679         ;
7680       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7681                          mac_address))
7682         custom_mac = 1;
7683       else if (unformat (i, "numa-only"))
7684         numa_only = 1;
7685       else if (unformat (i, "id %u", &id))
7686         ;
7687       else
7688         break;
7689     }
7690
7691   if (mode_is_set == 0)
7692     {
7693       errmsg ("Missing bond mode. ");
7694       return -99;
7695     }
7696
7697   /* Construct the API message */
7698   M (BOND_CREATE, mp);
7699
7700   mp->use_custom_mac = custom_mac;
7701
7702   mp->mode = htonl (mode);
7703   mp->lb = htonl (lb);
7704   mp->id = htonl (id);
7705   mp->numa_only = numa_only;
7706
7707   if (custom_mac)
7708     clib_memcpy (mp->mac_address, mac_address, 6);
7709
7710   /* send it... */
7711   S (mp);
7712
7713   /* Wait for a reply... */
7714   W (ret);
7715   return ret;
7716 }
7717
7718 static int
7719 api_bond_create2 (vat_main_t * vam)
7720 {
7721   unformat_input_t *i = vam->input;
7722   vl_api_bond_create2_t *mp;
7723   u8 mac_address[6];
7724   u8 custom_mac = 0;
7725   int ret;
7726   u8 mode;
7727   u8 lb;
7728   u8 mode_is_set = 0;
7729   u32 id = ~0;
7730   u8 numa_only = 0;
7731   u8 gso = 0;
7732
7733   clib_memset (mac_address, 0, sizeof (mac_address));
7734   lb = BOND_LB_L2;
7735
7736   /* Parse args required to build the message */
7737   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7738     {
7739       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7740         mode_is_set = 1;
7741       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7742                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7743         ;
7744       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7745                          mac_address))
7746         custom_mac = 1;
7747       else if (unformat (i, "numa-only"))
7748         numa_only = 1;
7749       else if (unformat (i, "gso"))
7750         gso = 1;
7751       else if (unformat (i, "id %u", &id))
7752         ;
7753       else
7754         break;
7755     }
7756
7757   if (mode_is_set == 0)
7758     {
7759       errmsg ("Missing bond mode. ");
7760       return -99;
7761     }
7762
7763   /* Construct the API message */
7764   M (BOND_CREATE2, mp);
7765
7766   mp->use_custom_mac = custom_mac;
7767
7768   mp->mode = htonl (mode);
7769   mp->lb = htonl (lb);
7770   mp->id = htonl (id);
7771   mp->numa_only = numa_only;
7772   mp->enable_gso = gso;
7773
7774   if (custom_mac)
7775     clib_memcpy (mp->mac_address, mac_address, 6);
7776
7777   /* send it... */
7778   S (mp);
7779
7780   /* Wait for a reply... */
7781   W (ret);
7782   return ret;
7783 }
7784
7785 static int
7786 api_bond_delete (vat_main_t * vam)
7787 {
7788   unformat_input_t *i = vam->input;
7789   vl_api_bond_delete_t *mp;
7790   u32 sw_if_index = ~0;
7791   u8 sw_if_index_set = 0;
7792   int ret;
7793
7794   /* Parse args required to build the message */
7795   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7796     {
7797       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7798         sw_if_index_set = 1;
7799       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7800         sw_if_index_set = 1;
7801       else
7802         break;
7803     }
7804
7805   if (sw_if_index_set == 0)
7806     {
7807       errmsg ("missing vpp interface name. ");
7808       return -99;
7809     }
7810
7811   /* Construct the API message */
7812   M (BOND_DELETE, mp);
7813
7814   mp->sw_if_index = ntohl (sw_if_index);
7815
7816   /* send it... */
7817   S (mp);
7818
7819   /* Wait for a reply... */
7820   W (ret);
7821   return ret;
7822 }
7823
7824 static int
7825 api_bond_add_member (vat_main_t * vam)
7826 {
7827   unformat_input_t *i = vam->input;
7828   vl_api_bond_add_member_t *mp;
7829   u32 bond_sw_if_index;
7830   int ret;
7831   u8 is_passive;
7832   u8 is_long_timeout;
7833   u32 bond_sw_if_index_is_set = 0;
7834   u32 sw_if_index;
7835   u8 sw_if_index_is_set = 0;
7836
7837   /* Parse args required to build the message */
7838   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7839     {
7840       if (unformat (i, "sw_if_index %d", &sw_if_index))
7841         sw_if_index_is_set = 1;
7842       else if (unformat (i, "bond %u", &bond_sw_if_index))
7843         bond_sw_if_index_is_set = 1;
7844       else if (unformat (i, "passive %d", &is_passive))
7845         ;
7846       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7847         ;
7848       else
7849         break;
7850     }
7851
7852   if (bond_sw_if_index_is_set == 0)
7853     {
7854       errmsg ("Missing bond sw_if_index. ");
7855       return -99;
7856     }
7857   if (sw_if_index_is_set == 0)
7858     {
7859       errmsg ("Missing member sw_if_index. ");
7860       return -99;
7861     }
7862
7863   /* Construct the API message */
7864   M (BOND_ADD_MEMBER, mp);
7865
7866   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7867   mp->sw_if_index = ntohl (sw_if_index);
7868   mp->is_long_timeout = is_long_timeout;
7869   mp->is_passive = is_passive;
7870
7871   /* send it... */
7872   S (mp);
7873
7874   /* Wait for a reply... */
7875   W (ret);
7876   return ret;
7877 }
7878
7879 static int
7880 api_bond_detach_member (vat_main_t * vam)
7881 {
7882   unformat_input_t *i = vam->input;
7883   vl_api_bond_detach_member_t *mp;
7884   u32 sw_if_index = ~0;
7885   u8 sw_if_index_set = 0;
7886   int ret;
7887
7888   /* Parse args required to build the message */
7889   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7890     {
7891       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7892         sw_if_index_set = 1;
7893       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7894         sw_if_index_set = 1;
7895       else
7896         break;
7897     }
7898
7899   if (sw_if_index_set == 0)
7900     {
7901       errmsg ("missing vpp interface name. ");
7902       return -99;
7903     }
7904
7905   /* Construct the API message */
7906   M (BOND_DETACH_MEMBER, mp);
7907
7908   mp->sw_if_index = ntohl (sw_if_index);
7909
7910   /* send it... */
7911   S (mp);
7912
7913   /* Wait for a reply... */
7914   W (ret);
7915   return ret;
7916 }
7917
7918 static int
7919 api_ip_table_add_del (vat_main_t * vam)
7920 {
7921   unformat_input_t *i = vam->input;
7922   vl_api_ip_table_add_del_t *mp;
7923   u32 table_id = ~0;
7924   u8 is_ipv6 = 0;
7925   u8 is_add = 1;
7926   int ret = 0;
7927
7928   /* Parse args required to build the message */
7929   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7930     {
7931       if (unformat (i, "ipv6"))
7932         is_ipv6 = 1;
7933       else if (unformat (i, "del"))
7934         is_add = 0;
7935       else if (unformat (i, "add"))
7936         is_add = 1;
7937       else if (unformat (i, "table %d", &table_id))
7938         ;
7939       else
7940         {
7941           clib_warning ("parse error '%U'", format_unformat_error, i);
7942           return -99;
7943         }
7944     }
7945
7946   if (~0 == table_id)
7947     {
7948       errmsg ("missing table-ID");
7949       return -99;
7950     }
7951
7952   /* Construct the API message */
7953   M (IP_TABLE_ADD_DEL, mp);
7954
7955   mp->table.table_id = ntohl (table_id);
7956   mp->table.is_ip6 = is_ipv6;
7957   mp->is_add = is_add;
7958
7959   /* send it... */
7960   S (mp);
7961
7962   /* Wait for a reply... */
7963   W (ret);
7964
7965   return ret;
7966 }
7967
7968 uword
7969 unformat_fib_path (unformat_input_t * input, va_list * args)
7970 {
7971   vat_main_t *vam = va_arg (*args, vat_main_t *);
7972   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
7973   u32 weight, preference;
7974   mpls_label_t out_label;
7975
7976   clib_memset (path, 0, sizeof (*path));
7977   path->weight = 1;
7978   path->sw_if_index = ~0;
7979   path->rpf_id = ~0;
7980   path->n_labels = 0;
7981
7982   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7983     {
7984       if (unformat (input, "%U %U",
7985                     unformat_vl_api_ip4_address,
7986                     &path->nh.address.ip4,
7987                     api_unformat_sw_if_index, vam, &path->sw_if_index))
7988         {
7989           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7990         }
7991       else if (unformat (input, "%U %U",
7992                          unformat_vl_api_ip6_address,
7993                          &path->nh.address.ip6,
7994                          api_unformat_sw_if_index, vam, &path->sw_if_index))
7995         {
7996           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7997         }
7998       else if (unformat (input, "weight %u", &weight))
7999         {
8000           path->weight = weight;
8001         }
8002       else if (unformat (input, "preference %u", &preference))
8003         {
8004           path->preference = preference;
8005         }
8006       else if (unformat (input, "%U next-hop-table %d",
8007                          unformat_vl_api_ip4_address,
8008                          &path->nh.address.ip4, &path->table_id))
8009         {
8010           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8011         }
8012       else if (unformat (input, "%U next-hop-table %d",
8013                          unformat_vl_api_ip6_address,
8014                          &path->nh.address.ip6, &path->table_id))
8015         {
8016           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8017         }
8018       else if (unformat (input, "%U",
8019                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
8020         {
8021           /*
8022            * the recursive next-hops are by default in the default table
8023            */
8024           path->table_id = 0;
8025           path->sw_if_index = ~0;
8026           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8027         }
8028       else if (unformat (input, "%U",
8029                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
8030         {
8031           /*
8032            * the recursive next-hops are by default in the default table
8033            */
8034           path->table_id = 0;
8035           path->sw_if_index = ~0;
8036           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8037         }
8038       else if (unformat (input, "resolve-via-host"))
8039         {
8040           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
8041         }
8042       else if (unformat (input, "resolve-via-attached"))
8043         {
8044           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
8045         }
8046       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
8047         {
8048           path->type = FIB_API_PATH_TYPE_LOCAL;
8049           path->sw_if_index = ~0;
8050           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8051         }
8052       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
8053         {
8054           path->type = FIB_API_PATH_TYPE_LOCAL;
8055           path->sw_if_index = ~0;
8056           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8057         }
8058       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
8059         ;
8060       else if (unformat (input, "via-label %d", &path->nh.via_label))
8061         {
8062           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
8063           path->sw_if_index = ~0;
8064         }
8065       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
8066         {
8067           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
8068           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
8069         }
8070       else if (unformat (input, "local"))
8071         {
8072           path->type = FIB_API_PATH_TYPE_LOCAL;
8073         }
8074       else if (unformat (input, "out-labels"))
8075         {
8076           while (unformat (input, "%d", &out_label))
8077             {
8078               path->label_stack[path->n_labels].label = out_label;
8079               path->label_stack[path->n_labels].is_uniform = 0;
8080               path->label_stack[path->n_labels].ttl = 64;
8081               path->n_labels++;
8082             }
8083         }
8084       else if (unformat (input, "via"))
8085         {
8086           /* new path, back up and return */
8087           unformat_put_input (input);
8088           unformat_put_input (input);
8089           unformat_put_input (input);
8090           unformat_put_input (input);
8091           break;
8092         }
8093       else
8094         {
8095           return (0);
8096         }
8097     }
8098
8099   path->proto = ntohl (path->proto);
8100   path->type = ntohl (path->type);
8101   path->flags = ntohl (path->flags);
8102   path->table_id = ntohl (path->table_id);
8103   path->sw_if_index = ntohl (path->sw_if_index);
8104
8105   return (1);
8106 }
8107
8108 static int
8109 api_ip_route_add_del (vat_main_t * vam)
8110 {
8111   unformat_input_t *i = vam->input;
8112   vl_api_ip_route_add_del_t *mp;
8113   u32 vrf_id = 0;
8114   u8 is_add = 1;
8115   u8 is_multipath = 0;
8116   u8 prefix_set = 0;
8117   u8 path_count = 0;
8118   vl_api_prefix_t pfx = { };
8119   vl_api_fib_path_t paths[8];
8120   int count = 1;
8121   int j;
8122   f64 before = 0;
8123   u32 random_add_del = 0;
8124   u32 *random_vector = 0;
8125   u32 random_seed = 0xdeaddabe;
8126
8127   /* Parse args required to build the message */
8128   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8129     {
8130       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8131         prefix_set = 1;
8132       else if (unformat (i, "del"))
8133         is_add = 0;
8134       else if (unformat (i, "add"))
8135         is_add = 1;
8136       else if (unformat (i, "vrf %d", &vrf_id))
8137         ;
8138       else if (unformat (i, "count %d", &count))
8139         ;
8140       else if (unformat (i, "random"))
8141         random_add_del = 1;
8142       else if (unformat (i, "multipath"))
8143         is_multipath = 1;
8144       else if (unformat (i, "seed %d", &random_seed))
8145         ;
8146       else
8147         if (unformat
8148             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8149         {
8150           path_count++;
8151           if (8 == path_count)
8152             {
8153               errmsg ("max 8 paths");
8154               return -99;
8155             }
8156         }
8157       else
8158         {
8159           clib_warning ("parse error '%U'", format_unformat_error, i);
8160           return -99;
8161         }
8162     }
8163
8164   if (!path_count)
8165     {
8166       errmsg ("specify a path; via ...");
8167       return -99;
8168     }
8169   if (prefix_set == 0)
8170     {
8171       errmsg ("missing prefix");
8172       return -99;
8173     }
8174
8175   /* Generate a pile of unique, random routes */
8176   if (random_add_del)
8177     {
8178       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
8179       u32 this_random_address;
8180       uword *random_hash;
8181
8182       random_hash = hash_create (count, sizeof (uword));
8183
8184       hash_set (random_hash, i->as_u32, 1);
8185       for (j = 0; j <= count; j++)
8186         {
8187           do
8188             {
8189               this_random_address = random_u32 (&random_seed);
8190               this_random_address =
8191                 clib_host_to_net_u32 (this_random_address);
8192             }
8193           while (hash_get (random_hash, this_random_address));
8194           vec_add1 (random_vector, this_random_address);
8195           hash_set (random_hash, this_random_address, 1);
8196         }
8197       hash_free (random_hash);
8198       set_ip4_address (&pfx.address, random_vector[0]);
8199     }
8200
8201   if (count > 1)
8202     {
8203       /* Turn on async mode */
8204       vam->async_mode = 1;
8205       vam->async_errors = 0;
8206       before = vat_time_now (vam);
8207     }
8208
8209   for (j = 0; j < count; j++)
8210     {
8211       /* Construct the API message */
8212       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8213
8214       mp->is_add = is_add;
8215       mp->is_multipath = is_multipath;
8216
8217       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8218       mp->route.table_id = ntohl (vrf_id);
8219       mp->route.n_paths = path_count;
8220
8221       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
8222
8223       if (random_add_del)
8224         set_ip4_address (&pfx.address, random_vector[j + 1]);
8225       else
8226         increment_address (&pfx.address);
8227       /* send it... */
8228       S (mp);
8229       /* If we receive SIGTERM, stop now... */
8230       if (vam->do_exit)
8231         break;
8232     }
8233
8234   /* When testing multiple add/del ops, use a control-ping to sync */
8235   if (count > 1)
8236     {
8237       vl_api_control_ping_t *mp_ping;
8238       f64 after;
8239       f64 timeout;
8240
8241       /* Shut off async mode */
8242       vam->async_mode = 0;
8243
8244       MPING (CONTROL_PING, mp_ping);
8245       S (mp_ping);
8246
8247       timeout = vat_time_now (vam) + 1.0;
8248       while (vat_time_now (vam) < timeout)
8249         if (vam->result_ready == 1)
8250           goto out;
8251       vam->retval = -99;
8252
8253     out:
8254       if (vam->retval == -99)
8255         errmsg ("timeout");
8256
8257       if (vam->async_errors > 0)
8258         {
8259           errmsg ("%d asynchronous errors", vam->async_errors);
8260           vam->retval = -98;
8261         }
8262       vam->async_errors = 0;
8263       after = vat_time_now (vam);
8264
8265       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8266       if (j > 0)
8267         count = j;
8268
8269       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8270              count, after - before, count / (after - before));
8271     }
8272   else
8273     {
8274       int ret;
8275
8276       /* Wait for a reply... */
8277       W (ret);
8278       return ret;
8279     }
8280
8281   /* Return the good/bad news */
8282   return (vam->retval);
8283 }
8284
8285 static int
8286 api_ip_mroute_add_del (vat_main_t * vam)
8287 {
8288   unformat_input_t *i = vam->input;
8289   u8 path_set = 0, prefix_set = 0, is_add = 1;
8290   vl_api_ip_mroute_add_del_t *mp;
8291   mfib_entry_flags_t eflags = 0;
8292   vl_api_mfib_path_t path;
8293   vl_api_mprefix_t pfx = { };
8294   u32 vrf_id = 0;
8295   int ret;
8296
8297   /* Parse args required to build the message */
8298   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8299     {
8300       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
8301         {
8302           prefix_set = 1;
8303           pfx.grp_address_length = htons (pfx.grp_address_length);
8304         }
8305       else if (unformat (i, "del"))
8306         is_add = 0;
8307       else if (unformat (i, "add"))
8308         is_add = 1;
8309       else if (unformat (i, "vrf %d", &vrf_id))
8310         ;
8311       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
8312         path.itf_flags = htonl (path.itf_flags);
8313       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8314         ;
8315       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
8316         path_set = 1;
8317       else
8318         {
8319           clib_warning ("parse error '%U'", format_unformat_error, i);
8320           return -99;
8321         }
8322     }
8323
8324   if (prefix_set == 0)
8325     {
8326       errmsg ("missing addresses\n");
8327       return -99;
8328     }
8329   if (path_set == 0)
8330     {
8331       errmsg ("missing path\n");
8332       return -99;
8333     }
8334
8335   /* Construct the API message */
8336   M (IP_MROUTE_ADD_DEL, mp);
8337
8338   mp->is_add = is_add;
8339   mp->is_multipath = 1;
8340
8341   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8342   mp->route.table_id = htonl (vrf_id);
8343   mp->route.n_paths = 1;
8344   mp->route.entry_flags = htonl (eflags);
8345
8346   clib_memcpy (&mp->route.paths, &path, sizeof (path));
8347
8348   /* send it... */
8349   S (mp);
8350   /* Wait for a reply... */
8351   W (ret);
8352   return ret;
8353 }
8354
8355 static int
8356 api_mpls_table_add_del (vat_main_t * vam)
8357 {
8358   unformat_input_t *i = vam->input;
8359   vl_api_mpls_table_add_del_t *mp;
8360   u32 table_id = ~0;
8361   u8 is_add = 1;
8362   int ret = 0;
8363
8364   /* Parse args required to build the message */
8365   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8366     {
8367       if (unformat (i, "table %d", &table_id))
8368         ;
8369       else if (unformat (i, "del"))
8370         is_add = 0;
8371       else if (unformat (i, "add"))
8372         is_add = 1;
8373       else
8374         {
8375           clib_warning ("parse error '%U'", format_unformat_error, i);
8376           return -99;
8377         }
8378     }
8379
8380   if (~0 == table_id)
8381     {
8382       errmsg ("missing table-ID");
8383       return -99;
8384     }
8385
8386   /* Construct the API message */
8387   M (MPLS_TABLE_ADD_DEL, mp);
8388
8389   mp->mt_table.mt_table_id = ntohl (table_id);
8390   mp->mt_is_add = is_add;
8391
8392   /* send it... */
8393   S (mp);
8394
8395   /* Wait for a reply... */
8396   W (ret);
8397
8398   return ret;
8399 }
8400
8401 static int
8402 api_mpls_route_add_del (vat_main_t * vam)
8403 {
8404   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
8405   mpls_label_t local_label = MPLS_LABEL_INVALID;
8406   unformat_input_t *i = vam->input;
8407   vl_api_mpls_route_add_del_t *mp;
8408   vl_api_fib_path_t paths[8];
8409   int count = 1, j;
8410   f64 before = 0;
8411
8412   /* Parse args required to build the message */
8413   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8414     {
8415       if (unformat (i, "%d", &local_label))
8416         ;
8417       else if (unformat (i, "eos"))
8418         is_eos = 1;
8419       else if (unformat (i, "non-eos"))
8420         is_eos = 0;
8421       else if (unformat (i, "del"))
8422         is_add = 0;
8423       else if (unformat (i, "add"))
8424         is_add = 1;
8425       else if (unformat (i, "multipath"))
8426         is_multipath = 1;
8427       else if (unformat (i, "count %d", &count))
8428         ;
8429       else
8430         if (unformat
8431             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8432         {
8433           path_count++;
8434           if (8 == path_count)
8435             {
8436               errmsg ("max 8 paths");
8437               return -99;
8438             }
8439         }
8440       else
8441         {
8442           clib_warning ("parse error '%U'", format_unformat_error, i);
8443           return -99;
8444         }
8445     }
8446
8447   if (!path_count)
8448     {
8449       errmsg ("specify a path; via ...");
8450       return -99;
8451     }
8452
8453   if (MPLS_LABEL_INVALID == local_label)
8454     {
8455       errmsg ("missing label");
8456       return -99;
8457     }
8458
8459   if (count > 1)
8460     {
8461       /* Turn on async mode */
8462       vam->async_mode = 1;
8463       vam->async_errors = 0;
8464       before = vat_time_now (vam);
8465     }
8466
8467   for (j = 0; j < count; j++)
8468     {
8469       /* Construct the API message */
8470       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8471
8472       mp->mr_is_add = is_add;
8473       mp->mr_is_multipath = is_multipath;
8474
8475       mp->mr_route.mr_label = local_label;
8476       mp->mr_route.mr_eos = is_eos;
8477       mp->mr_route.mr_table_id = 0;
8478       mp->mr_route.mr_n_paths = path_count;
8479
8480       clib_memcpy (&mp->mr_route.mr_paths, paths,
8481                    sizeof (paths[0]) * path_count);
8482
8483       local_label++;
8484
8485       /* send it... */
8486       S (mp);
8487       /* If we receive SIGTERM, stop now... */
8488       if (vam->do_exit)
8489         break;
8490     }
8491
8492   /* When testing multiple add/del ops, use a control-ping to sync */
8493   if (count > 1)
8494     {
8495       vl_api_control_ping_t *mp_ping;
8496       f64 after;
8497       f64 timeout;
8498
8499       /* Shut off async mode */
8500       vam->async_mode = 0;
8501
8502       MPING (CONTROL_PING, mp_ping);
8503       S (mp_ping);
8504
8505       timeout = vat_time_now (vam) + 1.0;
8506       while (vat_time_now (vam) < timeout)
8507         if (vam->result_ready == 1)
8508           goto out;
8509       vam->retval = -99;
8510
8511     out:
8512       if (vam->retval == -99)
8513         errmsg ("timeout");
8514
8515       if (vam->async_errors > 0)
8516         {
8517           errmsg ("%d asynchronous errors", vam->async_errors);
8518           vam->retval = -98;
8519         }
8520       vam->async_errors = 0;
8521       after = vat_time_now (vam);
8522
8523       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8524       if (j > 0)
8525         count = j;
8526
8527       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8528              count, after - before, count / (after - before));
8529     }
8530   else
8531     {
8532       int ret;
8533
8534       /* Wait for a reply... */
8535       W (ret);
8536       return ret;
8537     }
8538
8539   /* Return the good/bad news */
8540   return (vam->retval);
8541   return (0);
8542 }
8543
8544 static int
8545 api_mpls_ip_bind_unbind (vat_main_t * vam)
8546 {
8547   unformat_input_t *i = vam->input;
8548   vl_api_mpls_ip_bind_unbind_t *mp;
8549   u32 ip_table_id = 0;
8550   u8 is_bind = 1;
8551   vl_api_prefix_t pfx;
8552   u8 prefix_set = 0;
8553   mpls_label_t local_label = MPLS_LABEL_INVALID;
8554   int ret;
8555
8556   /* Parse args required to build the message */
8557   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8558     {
8559       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8560         prefix_set = 1;
8561       else if (unformat (i, "%d", &local_label))
8562         ;
8563       else if (unformat (i, "table-id %d", &ip_table_id))
8564         ;
8565       else if (unformat (i, "unbind"))
8566         is_bind = 0;
8567       else if (unformat (i, "bind"))
8568         is_bind = 1;
8569       else
8570         {
8571           clib_warning ("parse error '%U'", format_unformat_error, i);
8572           return -99;
8573         }
8574     }
8575
8576   if (!prefix_set)
8577     {
8578       errmsg ("IP prefix not set");
8579       return -99;
8580     }
8581
8582   if (MPLS_LABEL_INVALID == local_label)
8583     {
8584       errmsg ("missing label");
8585       return -99;
8586     }
8587
8588   /* Construct the API message */
8589   M (MPLS_IP_BIND_UNBIND, mp);
8590
8591   mp->mb_is_bind = is_bind;
8592   mp->mb_ip_table_id = ntohl (ip_table_id);
8593   mp->mb_mpls_table_id = 0;
8594   mp->mb_label = ntohl (local_label);
8595   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
8596
8597   /* send it... */
8598   S (mp);
8599
8600   /* Wait for a reply... */
8601   W (ret);
8602   return ret;
8603   return (0);
8604 }
8605
8606 static int
8607 api_sr_mpls_policy_add (vat_main_t * vam)
8608 {
8609   unformat_input_t *i = vam->input;
8610   vl_api_sr_mpls_policy_add_t *mp;
8611   u32 bsid = 0;
8612   u32 weight = 1;
8613   u8 type = 0;
8614   u8 n_segments = 0;
8615   u32 sid;
8616   u32 *segments = NULL;
8617   int ret;
8618
8619   /* Parse args required to build the message */
8620   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8621     {
8622       if (unformat (i, "bsid %d", &bsid))
8623         ;
8624       else if (unformat (i, "weight %d", &weight))
8625         ;
8626       else if (unformat (i, "spray"))
8627         type = 1;
8628       else if (unformat (i, "next %d", &sid))
8629         {
8630           n_segments += 1;
8631           vec_add1 (segments, htonl (sid));
8632         }
8633       else
8634         {
8635           clib_warning ("parse error '%U'", format_unformat_error, i);
8636           return -99;
8637         }
8638     }
8639
8640   if (bsid == 0)
8641     {
8642       errmsg ("bsid not set");
8643       return -99;
8644     }
8645
8646   if (n_segments == 0)
8647     {
8648       errmsg ("no sid in segment stack");
8649       return -99;
8650     }
8651
8652   /* Construct the API message */
8653   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8654
8655   mp->bsid = htonl (bsid);
8656   mp->weight = htonl (weight);
8657   mp->is_spray = type;
8658   mp->n_segments = n_segments;
8659   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8660   vec_free (segments);
8661
8662   /* send it... */
8663   S (mp);
8664
8665   /* Wait for a reply... */
8666   W (ret);
8667   return ret;
8668 }
8669
8670 static int
8671 api_sr_mpls_policy_del (vat_main_t * vam)
8672 {
8673   unformat_input_t *i = vam->input;
8674   vl_api_sr_mpls_policy_del_t *mp;
8675   u32 bsid = 0;
8676   int ret;
8677
8678   /* Parse args required to build the message */
8679   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8680     {
8681       if (unformat (i, "bsid %d", &bsid))
8682         ;
8683       else
8684         {
8685           clib_warning ("parse error '%U'", format_unformat_error, i);
8686           return -99;
8687         }
8688     }
8689
8690   if (bsid == 0)
8691     {
8692       errmsg ("bsid not set");
8693       return -99;
8694     }
8695
8696   /* Construct the API message */
8697   M (SR_MPLS_POLICY_DEL, mp);
8698
8699   mp->bsid = htonl (bsid);
8700
8701   /* send it... */
8702   S (mp);
8703
8704   /* Wait for a reply... */
8705   W (ret);
8706   return ret;
8707 }
8708
8709 static int
8710 api_bier_table_add_del (vat_main_t * vam)
8711 {
8712   unformat_input_t *i = vam->input;
8713   vl_api_bier_table_add_del_t *mp;
8714   u8 is_add = 1;
8715   u32 set = 0, sub_domain = 0, hdr_len = 3;
8716   mpls_label_t local_label = MPLS_LABEL_INVALID;
8717   int ret;
8718
8719   /* Parse args required to build the message */
8720   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8721     {
8722       if (unformat (i, "sub-domain %d", &sub_domain))
8723         ;
8724       else if (unformat (i, "set %d", &set))
8725         ;
8726       else if (unformat (i, "label %d", &local_label))
8727         ;
8728       else if (unformat (i, "hdr-len %d", &hdr_len))
8729         ;
8730       else if (unformat (i, "add"))
8731         is_add = 1;
8732       else if (unformat (i, "del"))
8733         is_add = 0;
8734       else
8735         {
8736           clib_warning ("parse error '%U'", format_unformat_error, i);
8737           return -99;
8738         }
8739     }
8740
8741   if (MPLS_LABEL_INVALID == local_label)
8742     {
8743       errmsg ("missing label\n");
8744       return -99;
8745     }
8746
8747   /* Construct the API message */
8748   M (BIER_TABLE_ADD_DEL, mp);
8749
8750   mp->bt_is_add = is_add;
8751   mp->bt_label = ntohl (local_label);
8752   mp->bt_tbl_id.bt_set = set;
8753   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8754   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8755
8756   /* send it... */
8757   S (mp);
8758
8759   /* Wait for a reply... */
8760   W (ret);
8761
8762   return (ret);
8763 }
8764
8765 static int
8766 api_bier_route_add_del (vat_main_t * vam)
8767 {
8768   unformat_input_t *i = vam->input;
8769   vl_api_bier_route_add_del_t *mp;
8770   u8 is_add = 1;
8771   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8772   ip4_address_t v4_next_hop_address;
8773   ip6_address_t v6_next_hop_address;
8774   u8 next_hop_set = 0;
8775   u8 next_hop_proto_is_ip4 = 1;
8776   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8777   int ret;
8778
8779   /* Parse args required to build the message */
8780   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8781     {
8782       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8783         {
8784           next_hop_proto_is_ip4 = 1;
8785           next_hop_set = 1;
8786         }
8787       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8788         {
8789           next_hop_proto_is_ip4 = 0;
8790           next_hop_set = 1;
8791         }
8792       if (unformat (i, "sub-domain %d", &sub_domain))
8793         ;
8794       else if (unformat (i, "set %d", &set))
8795         ;
8796       else if (unformat (i, "hdr-len %d", &hdr_len))
8797         ;
8798       else if (unformat (i, "bp %d", &bp))
8799         ;
8800       else if (unformat (i, "add"))
8801         is_add = 1;
8802       else if (unformat (i, "del"))
8803         is_add = 0;
8804       else if (unformat (i, "out-label %d", &next_hop_out_label))
8805         ;
8806       else
8807         {
8808           clib_warning ("parse error '%U'", format_unformat_error, i);
8809           return -99;
8810         }
8811     }
8812
8813   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8814     {
8815       errmsg ("next hop / label set\n");
8816       return -99;
8817     }
8818   if (0 == bp)
8819     {
8820       errmsg ("bit=position not set\n");
8821       return -99;
8822     }
8823
8824   /* Construct the API message */
8825   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
8826
8827   mp->br_is_add = is_add;
8828   mp->br_route.br_tbl_id.bt_set = set;
8829   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
8830   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
8831   mp->br_route.br_bp = ntohs (bp);
8832   mp->br_route.br_n_paths = 1;
8833   mp->br_route.br_paths[0].n_labels = 1;
8834   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
8835   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
8836                                     FIB_API_PATH_NH_PROTO_IP4 :
8837                                     FIB_API_PATH_NH_PROTO_IP6);
8838
8839   if (next_hop_proto_is_ip4)
8840     {
8841       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
8842                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8843     }
8844   else
8845     {
8846       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
8847                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8848     }
8849
8850   /* send it... */
8851   S (mp);
8852
8853   /* Wait for a reply... */
8854   W (ret);
8855
8856   return (ret);
8857 }
8858
8859 static int
8860 api_mpls_tunnel_add_del (vat_main_t * vam)
8861 {
8862   unformat_input_t *i = vam->input;
8863   vl_api_mpls_tunnel_add_del_t *mp;
8864
8865   vl_api_fib_path_t paths[8];
8866   u32 sw_if_index = ~0;
8867   u8 path_count = 0;
8868   u8 l2_only = 0;
8869   u8 is_add = 1;
8870   int ret;
8871
8872   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8873     {
8874       if (unformat (i, "add"))
8875         is_add = 1;
8876       else
8877         if (unformat
8878             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
8879         is_add = 0;
8880       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8881         is_add = 0;
8882       else if (unformat (i, "l2-only"))
8883         l2_only = 1;
8884       else
8885         if (unformat
8886             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8887         {
8888           path_count++;
8889           if (8 == path_count)
8890             {
8891               errmsg ("max 8 paths");
8892               return -99;
8893             }
8894         }
8895       else
8896         {
8897           clib_warning ("parse error '%U'", format_unformat_error, i);
8898           return -99;
8899         }
8900     }
8901
8902   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8903
8904   mp->mt_is_add = is_add;
8905   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
8906   mp->mt_tunnel.mt_l2_only = l2_only;
8907   mp->mt_tunnel.mt_is_multicast = 0;
8908   mp->mt_tunnel.mt_n_paths = path_count;
8909
8910   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
8911                sizeof (paths[0]) * path_count);
8912
8913   S (mp);
8914   W (ret);
8915   return ret;
8916 }
8917
8918 static int
8919 api_sw_interface_set_unnumbered (vat_main_t * vam)
8920 {
8921   unformat_input_t *i = vam->input;
8922   vl_api_sw_interface_set_unnumbered_t *mp;
8923   u32 sw_if_index;
8924   u32 unnum_sw_index = ~0;
8925   u8 is_add = 1;
8926   u8 sw_if_index_set = 0;
8927   int ret;
8928
8929   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8930     {
8931       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8932         sw_if_index_set = 1;
8933       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8934         sw_if_index_set = 1;
8935       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8936         ;
8937       else if (unformat (i, "del"))
8938         is_add = 0;
8939       else
8940         {
8941           clib_warning ("parse error '%U'", format_unformat_error, i);
8942           return -99;
8943         }
8944     }
8945
8946   if (sw_if_index_set == 0)
8947     {
8948       errmsg ("missing interface name or sw_if_index");
8949       return -99;
8950     }
8951
8952   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8953
8954   mp->sw_if_index = ntohl (sw_if_index);
8955   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8956   mp->is_add = is_add;
8957
8958   S (mp);
8959   W (ret);
8960   return ret;
8961 }
8962
8963
8964 static int
8965 api_create_vlan_subif (vat_main_t * vam)
8966 {
8967   unformat_input_t *i = vam->input;
8968   vl_api_create_vlan_subif_t *mp;
8969   u32 sw_if_index;
8970   u8 sw_if_index_set = 0;
8971   u32 vlan_id;
8972   u8 vlan_id_set = 0;
8973   int ret;
8974
8975   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8976     {
8977       if (unformat (i, "sw_if_index %d", &sw_if_index))
8978         sw_if_index_set = 1;
8979       else
8980         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8981         sw_if_index_set = 1;
8982       else if (unformat (i, "vlan %d", &vlan_id))
8983         vlan_id_set = 1;
8984       else
8985         {
8986           clib_warning ("parse error '%U'", format_unformat_error, i);
8987           return -99;
8988         }
8989     }
8990
8991   if (sw_if_index_set == 0)
8992     {
8993       errmsg ("missing interface name or sw_if_index");
8994       return -99;
8995     }
8996
8997   if (vlan_id_set == 0)
8998     {
8999       errmsg ("missing vlan_id");
9000       return -99;
9001     }
9002   M (CREATE_VLAN_SUBIF, mp);
9003
9004   mp->sw_if_index = ntohl (sw_if_index);
9005   mp->vlan_id = ntohl (vlan_id);
9006
9007   S (mp);
9008   W (ret);
9009   return ret;
9010 }
9011
9012 #define foreach_create_subif_bit                \
9013 _(no_tags)                                      \
9014 _(one_tag)                                      \
9015 _(two_tags)                                     \
9016 _(dot1ad)                                       \
9017 _(exact_match)                                  \
9018 _(default_sub)                                  \
9019 _(outer_vlan_id_any)                            \
9020 _(inner_vlan_id_any)
9021
9022 #define foreach_create_subif_flag               \
9023 _(0, "no_tags")                                 \
9024 _(1, "one_tag")                                 \
9025 _(2, "two_tags")                                \
9026 _(3, "dot1ad")                                  \
9027 _(4, "exact_match")                             \
9028 _(5, "default_sub")                             \
9029 _(6, "outer_vlan_id_any")                       \
9030 _(7, "inner_vlan_id_any")
9031
9032 static int
9033 api_create_subif (vat_main_t * vam)
9034 {
9035   unformat_input_t *i = vam->input;
9036   vl_api_create_subif_t *mp;
9037   u32 sw_if_index;
9038   u8 sw_if_index_set = 0;
9039   u32 sub_id;
9040   u8 sub_id_set = 0;
9041   u32 __attribute__ ((unused)) no_tags = 0;
9042   u32 __attribute__ ((unused)) one_tag = 0;
9043   u32 __attribute__ ((unused)) two_tags = 0;
9044   u32 __attribute__ ((unused)) dot1ad = 0;
9045   u32 __attribute__ ((unused)) exact_match = 0;
9046   u32 __attribute__ ((unused)) default_sub = 0;
9047   u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
9048   u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
9049   u32 tmp;
9050   u16 outer_vlan_id = 0;
9051   u16 inner_vlan_id = 0;
9052   int ret;
9053
9054   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9055     {
9056       if (unformat (i, "sw_if_index %d", &sw_if_index))
9057         sw_if_index_set = 1;
9058       else
9059         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9060         sw_if_index_set = 1;
9061       else if (unformat (i, "sub_id %d", &sub_id))
9062         sub_id_set = 1;
9063       else if (unformat (i, "outer_vlan_id %d", &tmp))
9064         outer_vlan_id = tmp;
9065       else if (unformat (i, "inner_vlan_id %d", &tmp))
9066         inner_vlan_id = tmp;
9067
9068 #define _(a) else if (unformat (i, #a)) a = 1 ;
9069       foreach_create_subif_bit
9070 #undef _
9071         else
9072         {
9073           clib_warning ("parse error '%U'", format_unformat_error, i);
9074           return -99;
9075         }
9076     }
9077
9078   if (sw_if_index_set == 0)
9079     {
9080       errmsg ("missing interface name or sw_if_index");
9081       return -99;
9082     }
9083
9084   if (sub_id_set == 0)
9085     {
9086       errmsg ("missing sub_id");
9087       return -99;
9088     }
9089   M (CREATE_SUBIF, mp);
9090
9091   mp->sw_if_index = ntohl (sw_if_index);
9092   mp->sub_id = ntohl (sub_id);
9093
9094 #define _(a,b) mp->sub_if_flags |= (1 << a);
9095   foreach_create_subif_flag;
9096 #undef _
9097
9098   mp->outer_vlan_id = ntohs (outer_vlan_id);
9099   mp->inner_vlan_id = ntohs (inner_vlan_id);
9100
9101   S (mp);
9102   W (ret);
9103   return ret;
9104 }
9105
9106 static int
9107 api_ip_table_replace_begin (vat_main_t * vam)
9108 {
9109   unformat_input_t *i = vam->input;
9110   vl_api_ip_table_replace_begin_t *mp;
9111   u32 table_id = 0;
9112   u8 is_ipv6 = 0;
9113
9114   int ret;
9115   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9116     {
9117       if (unformat (i, "table %d", &table_id))
9118         ;
9119       else if (unformat (i, "ipv6"))
9120         is_ipv6 = 1;
9121       else
9122         {
9123           clib_warning ("parse error '%U'", format_unformat_error, i);
9124           return -99;
9125         }
9126     }
9127
9128   M (IP_TABLE_REPLACE_BEGIN, mp);
9129
9130   mp->table.table_id = ntohl (table_id);
9131   mp->table.is_ip6 = is_ipv6;
9132
9133   S (mp);
9134   W (ret);
9135   return ret;
9136 }
9137
9138 static int
9139 api_ip_table_flush (vat_main_t * vam)
9140 {
9141   unformat_input_t *i = vam->input;
9142   vl_api_ip_table_flush_t *mp;
9143   u32 table_id = 0;
9144   u8 is_ipv6 = 0;
9145
9146   int ret;
9147   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9148     {
9149       if (unformat (i, "table %d", &table_id))
9150         ;
9151       else if (unformat (i, "ipv6"))
9152         is_ipv6 = 1;
9153       else
9154         {
9155           clib_warning ("parse error '%U'", format_unformat_error, i);
9156           return -99;
9157         }
9158     }
9159
9160   M (IP_TABLE_FLUSH, mp);
9161
9162   mp->table.table_id = ntohl (table_id);
9163   mp->table.is_ip6 = is_ipv6;
9164
9165   S (mp);
9166   W (ret);
9167   return ret;
9168 }
9169
9170 static int
9171 api_ip_table_replace_end (vat_main_t * vam)
9172 {
9173   unformat_input_t *i = vam->input;
9174   vl_api_ip_table_replace_end_t *mp;
9175   u32 table_id = 0;
9176   u8 is_ipv6 = 0;
9177
9178   int ret;
9179   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9180     {
9181       if (unformat (i, "table %d", &table_id))
9182         ;
9183       else if (unformat (i, "ipv6"))
9184         is_ipv6 = 1;
9185       else
9186         {
9187           clib_warning ("parse error '%U'", format_unformat_error, i);
9188           return -99;
9189         }
9190     }
9191
9192   M (IP_TABLE_REPLACE_END, mp);
9193
9194   mp->table.table_id = ntohl (table_id);
9195   mp->table.is_ip6 = is_ipv6;
9196
9197   S (mp);
9198   W (ret);
9199   return ret;
9200 }
9201
9202 static int
9203 api_set_ip_flow_hash (vat_main_t * vam)
9204 {
9205   unformat_input_t *i = vam->input;
9206   vl_api_set_ip_flow_hash_t *mp;
9207   u32 vrf_id = 0;
9208   u8 is_ipv6 = 0;
9209   u8 vrf_id_set = 0;
9210   u8 src = 0;
9211   u8 dst = 0;
9212   u8 sport = 0;
9213   u8 dport = 0;
9214   u8 proto = 0;
9215   u8 reverse = 0;
9216   int ret;
9217
9218   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9219     {
9220       if (unformat (i, "vrf %d", &vrf_id))
9221         vrf_id_set = 1;
9222       else if (unformat (i, "ipv6"))
9223         is_ipv6 = 1;
9224       else if (unformat (i, "src"))
9225         src = 1;
9226       else if (unformat (i, "dst"))
9227         dst = 1;
9228       else if (unformat (i, "sport"))
9229         sport = 1;
9230       else if (unformat (i, "dport"))
9231         dport = 1;
9232       else if (unformat (i, "proto"))
9233         proto = 1;
9234       else if (unformat (i, "reverse"))
9235         reverse = 1;
9236
9237       else
9238         {
9239           clib_warning ("parse error '%U'", format_unformat_error, i);
9240           return -99;
9241         }
9242     }
9243
9244   if (vrf_id_set == 0)
9245     {
9246       errmsg ("missing vrf id");
9247       return -99;
9248     }
9249
9250   M (SET_IP_FLOW_HASH, mp);
9251   mp->src = src;
9252   mp->dst = dst;
9253   mp->sport = sport;
9254   mp->dport = dport;
9255   mp->proto = proto;
9256   mp->reverse = reverse;
9257   mp->vrf_id = ntohl (vrf_id);
9258   mp->is_ipv6 = is_ipv6;
9259
9260   S (mp);
9261   W (ret);
9262   return ret;
9263 }
9264
9265 static int
9266 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9267 {
9268   unformat_input_t *i = vam->input;
9269   vl_api_sw_interface_ip6_enable_disable_t *mp;
9270   u32 sw_if_index;
9271   u8 sw_if_index_set = 0;
9272   u8 enable = 0;
9273   int ret;
9274
9275   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9276     {
9277       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9278         sw_if_index_set = 1;
9279       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9280         sw_if_index_set = 1;
9281       else if (unformat (i, "enable"))
9282         enable = 1;
9283       else if (unformat (i, "disable"))
9284         enable = 0;
9285       else
9286         {
9287           clib_warning ("parse error '%U'", format_unformat_error, i);
9288           return -99;
9289         }
9290     }
9291
9292   if (sw_if_index_set == 0)
9293     {
9294       errmsg ("missing interface name or sw_if_index");
9295       return -99;
9296     }
9297
9298   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9299
9300   mp->sw_if_index = ntohl (sw_if_index);
9301   mp->enable = enable;
9302
9303   S (mp);
9304   W (ret);
9305   return ret;
9306 }
9307
9308
9309 static int
9310 api_l2_patch_add_del (vat_main_t * vam)
9311 {
9312   unformat_input_t *i = vam->input;
9313   vl_api_l2_patch_add_del_t *mp;
9314   u32 rx_sw_if_index;
9315   u8 rx_sw_if_index_set = 0;
9316   u32 tx_sw_if_index;
9317   u8 tx_sw_if_index_set = 0;
9318   u8 is_add = 1;
9319   int ret;
9320
9321   /* Parse args required to build the message */
9322   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9323     {
9324       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9325         rx_sw_if_index_set = 1;
9326       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9327         tx_sw_if_index_set = 1;
9328       else if (unformat (i, "rx"))
9329         {
9330           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9331             {
9332               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9333                             &rx_sw_if_index))
9334                 rx_sw_if_index_set = 1;
9335             }
9336           else
9337             break;
9338         }
9339       else if (unformat (i, "tx"))
9340         {
9341           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9342             {
9343               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9344                             &tx_sw_if_index))
9345                 tx_sw_if_index_set = 1;
9346             }
9347           else
9348             break;
9349         }
9350       else if (unformat (i, "del"))
9351         is_add = 0;
9352       else
9353         break;
9354     }
9355
9356   if (rx_sw_if_index_set == 0)
9357     {
9358       errmsg ("missing rx interface name or rx_sw_if_index");
9359       return -99;
9360     }
9361
9362   if (tx_sw_if_index_set == 0)
9363     {
9364       errmsg ("missing tx interface name or tx_sw_if_index");
9365       return -99;
9366     }
9367
9368   M (L2_PATCH_ADD_DEL, mp);
9369
9370   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9371   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9372   mp->is_add = is_add;
9373
9374   S (mp);
9375   W (ret);
9376   return ret;
9377 }
9378
9379 u8 is_del;
9380 u8 localsid_addr[16];
9381 u8 end_psp;
9382 u8 behavior;
9383 u32 sw_if_index;
9384 u32 vlan_index;
9385 u32 fib_table;
9386 u8 nh_addr[16];
9387
9388 static int
9389 api_sr_localsid_add_del (vat_main_t * vam)
9390 {
9391   unformat_input_t *i = vam->input;
9392   vl_api_sr_localsid_add_del_t *mp;
9393
9394   u8 is_del;
9395   ip6_address_t localsid;
9396   u8 end_psp = 0;
9397   u8 behavior = ~0;
9398   u32 sw_if_index;
9399   u32 fib_table = ~(u32) 0;
9400   ip46_address_t nh_addr;
9401   clib_memset (&nh_addr, 0, sizeof (ip46_address_t));
9402
9403   bool nexthop_set = 0;
9404
9405   int ret;
9406
9407   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9408     {
9409       if (unformat (i, "del"))
9410         is_del = 1;
9411       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9412       else if (unformat (i, "next-hop %U", unformat_ip46_address, &nh_addr))
9413         nexthop_set = 1;
9414       else if (unformat (i, "behavior %u", &behavior));
9415       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9416       else if (unformat (i, "fib-table %u", &fib_table));
9417       else if (unformat (i, "end.psp %u", &behavior));
9418       else
9419         break;
9420     }
9421
9422   M (SR_LOCALSID_ADD_DEL, mp);
9423
9424   clib_memcpy (mp->localsid, &localsid, sizeof (mp->localsid));
9425
9426   if (nexthop_set)
9427     {
9428       clib_memcpy (&mp->nh_addr.un, &nh_addr, sizeof (mp->nh_addr.un));
9429     }
9430   mp->behavior = behavior;
9431   mp->sw_if_index = ntohl (sw_if_index);
9432   mp->fib_table = ntohl (fib_table);
9433   mp->end_psp = end_psp;
9434   mp->is_del = is_del;
9435
9436   S (mp);
9437   W (ret);
9438   return ret;
9439 }
9440
9441 static int
9442 api_ioam_enable (vat_main_t * vam)
9443 {
9444   unformat_input_t *input = vam->input;
9445   vl_api_ioam_enable_t *mp;
9446   u32 id = 0;
9447   int has_trace_option = 0;
9448   int has_pot_option = 0;
9449   int has_seqno_option = 0;
9450   int has_analyse_option = 0;
9451   int ret;
9452
9453   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9454     {
9455       if (unformat (input, "trace"))
9456         has_trace_option = 1;
9457       else if (unformat (input, "pot"))
9458         has_pot_option = 1;
9459       else if (unformat (input, "seqno"))
9460         has_seqno_option = 1;
9461       else if (unformat (input, "analyse"))
9462         has_analyse_option = 1;
9463       else
9464         break;
9465     }
9466   M (IOAM_ENABLE, mp);
9467   mp->id = htons (id);
9468   mp->seqno = has_seqno_option;
9469   mp->analyse = has_analyse_option;
9470   mp->pot_enable = has_pot_option;
9471   mp->trace_enable = has_trace_option;
9472
9473   S (mp);
9474   W (ret);
9475   return ret;
9476 }
9477
9478
9479 static int
9480 api_ioam_disable (vat_main_t * vam)
9481 {
9482   vl_api_ioam_disable_t *mp;
9483   int ret;
9484
9485   M (IOAM_DISABLE, mp);
9486   S (mp);
9487   W (ret);
9488   return ret;
9489 }
9490
9491 #define foreach_tcp_proto_field                 \
9492 _(src_port)                                     \
9493 _(dst_port)
9494
9495 #define foreach_udp_proto_field                 \
9496 _(src_port)                                     \
9497 _(dst_port)
9498
9499 #define foreach_ip4_proto_field                 \
9500 _(src_address)                                  \
9501 _(dst_address)                                  \
9502 _(tos)                                          \
9503 _(length)                                       \
9504 _(fragment_id)                                  \
9505 _(ttl)                                          \
9506 _(protocol)                                     \
9507 _(checksum)
9508
9509 typedef struct
9510 {
9511   u16 src_port, dst_port;
9512 } tcpudp_header_t;
9513
9514 #if VPP_API_TEST_BUILTIN == 0
9515 uword
9516 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9517 {
9518   u8 **maskp = va_arg (*args, u8 **);
9519   u8 *mask = 0;
9520   u8 found_something = 0;
9521   tcp_header_t *tcp;
9522
9523 #define _(a) u8 a=0;
9524   foreach_tcp_proto_field;
9525 #undef _
9526
9527   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9528     {
9529       if (0);
9530 #define _(a) else if (unformat (input, #a)) a=1;
9531       foreach_tcp_proto_field
9532 #undef _
9533         else
9534         break;
9535     }
9536
9537 #define _(a) found_something += a;
9538   foreach_tcp_proto_field;
9539 #undef _
9540
9541   if (found_something == 0)
9542     return 0;
9543
9544   vec_validate (mask, sizeof (*tcp) - 1);
9545
9546   tcp = (tcp_header_t *) mask;
9547
9548 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
9549   foreach_tcp_proto_field;
9550 #undef _
9551
9552   *maskp = mask;
9553   return 1;
9554 }
9555
9556 uword
9557 unformat_udp_mask (unformat_input_t * input, va_list * args)
9558 {
9559   u8 **maskp = va_arg (*args, u8 **);
9560   u8 *mask = 0;
9561   u8 found_something = 0;
9562   udp_header_t *udp;
9563
9564 #define _(a) u8 a=0;
9565   foreach_udp_proto_field;
9566 #undef _
9567
9568   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9569     {
9570       if (0);
9571 #define _(a) else if (unformat (input, #a)) a=1;
9572       foreach_udp_proto_field
9573 #undef _
9574         else
9575         break;
9576     }
9577
9578 #define _(a) found_something += a;
9579   foreach_udp_proto_field;
9580 #undef _
9581
9582   if (found_something == 0)
9583     return 0;
9584
9585   vec_validate (mask, sizeof (*udp) - 1);
9586
9587   udp = (udp_header_t *) mask;
9588
9589 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
9590   foreach_udp_proto_field;
9591 #undef _
9592
9593   *maskp = mask;
9594   return 1;
9595 }
9596
9597 uword
9598 unformat_l4_mask (unformat_input_t * input, va_list * args)
9599 {
9600   u8 **maskp = va_arg (*args, u8 **);
9601   u16 src_port = 0, dst_port = 0;
9602   tcpudp_header_t *tcpudp;
9603
9604   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9605     {
9606       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9607         return 1;
9608       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9609         return 1;
9610       else if (unformat (input, "src_port"))
9611         src_port = 0xFFFF;
9612       else if (unformat (input, "dst_port"))
9613         dst_port = 0xFFFF;
9614       else
9615         return 0;
9616     }
9617
9618   if (!src_port && !dst_port)
9619     return 0;
9620
9621   u8 *mask = 0;
9622   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9623
9624   tcpudp = (tcpudp_header_t *) mask;
9625   tcpudp->src_port = src_port;
9626   tcpudp->dst_port = dst_port;
9627
9628   *maskp = mask;
9629
9630   return 1;
9631 }
9632
9633 uword
9634 unformat_ip4_mask (unformat_input_t * input, va_list * args)
9635 {
9636   u8 **maskp = va_arg (*args, u8 **);
9637   u8 *mask = 0;
9638   u8 found_something = 0;
9639   ip4_header_t *ip;
9640
9641 #define _(a) u8 a=0;
9642   foreach_ip4_proto_field;
9643 #undef _
9644   u8 version = 0;
9645   u8 hdr_length = 0;
9646
9647
9648   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9649     {
9650       if (unformat (input, "version"))
9651         version = 1;
9652       else if (unformat (input, "hdr_length"))
9653         hdr_length = 1;
9654       else if (unformat (input, "src"))
9655         src_address = 1;
9656       else if (unformat (input, "dst"))
9657         dst_address = 1;
9658       else if (unformat (input, "proto"))
9659         protocol = 1;
9660
9661 #define _(a) else if (unformat (input, #a)) a=1;
9662       foreach_ip4_proto_field
9663 #undef _
9664         else
9665         break;
9666     }
9667
9668 #define _(a) found_something += a;
9669   foreach_ip4_proto_field;
9670 #undef _
9671
9672   if (found_something == 0)
9673     return 0;
9674
9675   vec_validate (mask, sizeof (*ip) - 1);
9676
9677   ip = (ip4_header_t *) mask;
9678
9679 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
9680   foreach_ip4_proto_field;
9681 #undef _
9682
9683   ip->ip_version_and_header_length = 0;
9684
9685   if (version)
9686     ip->ip_version_and_header_length |= 0xF0;
9687
9688   if (hdr_length)
9689     ip->ip_version_and_header_length |= 0x0F;
9690
9691   *maskp = mask;
9692   return 1;
9693 }
9694
9695 #define foreach_ip6_proto_field                 \
9696 _(src_address)                                  \
9697 _(dst_address)                                  \
9698 _(payload_length)                               \
9699 _(hop_limit)                                    \
9700 _(protocol)
9701
9702 uword
9703 unformat_ip6_mask (unformat_input_t * input, va_list * args)
9704 {
9705   u8 **maskp = va_arg (*args, u8 **);
9706   u8 *mask = 0;
9707   u8 found_something = 0;
9708   ip6_header_t *ip;
9709   u32 ip_version_traffic_class_and_flow_label;
9710
9711 #define _(a) u8 a=0;
9712   foreach_ip6_proto_field;
9713 #undef _
9714   u8 version = 0;
9715   u8 traffic_class = 0;
9716   u8 flow_label = 0;
9717
9718   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9719     {
9720       if (unformat (input, "version"))
9721         version = 1;
9722       else if (unformat (input, "traffic-class"))
9723         traffic_class = 1;
9724       else if (unformat (input, "flow-label"))
9725         flow_label = 1;
9726       else if (unformat (input, "src"))
9727         src_address = 1;
9728       else if (unformat (input, "dst"))
9729         dst_address = 1;
9730       else if (unformat (input, "proto"))
9731         protocol = 1;
9732
9733 #define _(a) else if (unformat (input, #a)) a=1;
9734       foreach_ip6_proto_field
9735 #undef _
9736         else
9737         break;
9738     }
9739
9740 #define _(a) found_something += a;
9741   foreach_ip6_proto_field;
9742 #undef _
9743
9744   if (found_something == 0)
9745     return 0;
9746
9747   vec_validate (mask, sizeof (*ip) - 1);
9748
9749   ip = (ip6_header_t *) mask;
9750
9751 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
9752   foreach_ip6_proto_field;
9753 #undef _
9754
9755   ip_version_traffic_class_and_flow_label = 0;
9756
9757   if (version)
9758     ip_version_traffic_class_and_flow_label |= 0xF0000000;
9759
9760   if (traffic_class)
9761     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9762
9763   if (flow_label)
9764     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9765
9766   ip->ip_version_traffic_class_and_flow_label =
9767     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9768
9769   *maskp = mask;
9770   return 1;
9771 }
9772
9773 uword
9774 unformat_l3_mask (unformat_input_t * input, va_list * args)
9775 {
9776   u8 **maskp = va_arg (*args, u8 **);
9777
9778   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9779     {
9780       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9781         return 1;
9782       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9783         return 1;
9784       else
9785         break;
9786     }
9787   return 0;
9788 }
9789
9790 uword
9791 unformat_l2_mask (unformat_input_t * input, va_list * args)
9792 {
9793   u8 **maskp = va_arg (*args, u8 **);
9794   u8 *mask = 0;
9795   u8 src = 0;
9796   u8 dst = 0;
9797   u8 proto = 0;
9798   u8 tag1 = 0;
9799   u8 tag2 = 0;
9800   u8 ignore_tag1 = 0;
9801   u8 ignore_tag2 = 0;
9802   u8 cos1 = 0;
9803   u8 cos2 = 0;
9804   u8 dot1q = 0;
9805   u8 dot1ad = 0;
9806   int len = 14;
9807
9808   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9809     {
9810       if (unformat (input, "src"))
9811         src = 1;
9812       else if (unformat (input, "dst"))
9813         dst = 1;
9814       else if (unformat (input, "proto"))
9815         proto = 1;
9816       else if (unformat (input, "tag1"))
9817         tag1 = 1;
9818       else if (unformat (input, "tag2"))
9819         tag2 = 1;
9820       else if (unformat (input, "ignore-tag1"))
9821         ignore_tag1 = 1;
9822       else if (unformat (input, "ignore-tag2"))
9823         ignore_tag2 = 1;
9824       else if (unformat (input, "cos1"))
9825         cos1 = 1;
9826       else if (unformat (input, "cos2"))
9827         cos2 = 1;
9828       else if (unformat (input, "dot1q"))
9829         dot1q = 1;
9830       else if (unformat (input, "dot1ad"))
9831         dot1ad = 1;
9832       else
9833         break;
9834     }
9835   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9836        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9837     return 0;
9838
9839   if (tag1 || ignore_tag1 || cos1 || dot1q)
9840     len = 18;
9841   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9842     len = 22;
9843
9844   vec_validate (mask, len - 1);
9845
9846   if (dst)
9847     clib_memset (mask, 0xff, 6);
9848
9849   if (src)
9850     clib_memset (mask + 6, 0xff, 6);
9851
9852   if (tag2 || dot1ad)
9853     {
9854       /* inner vlan tag */
9855       if (tag2)
9856         {
9857           mask[19] = 0xff;
9858           mask[18] = 0x0f;
9859         }
9860       if (cos2)
9861         mask[18] |= 0xe0;
9862       if (proto)
9863         mask[21] = mask[20] = 0xff;
9864       if (tag1)
9865         {
9866           mask[15] = 0xff;
9867           mask[14] = 0x0f;
9868         }
9869       if (cos1)
9870         mask[14] |= 0xe0;
9871       *maskp = mask;
9872       return 1;
9873     }
9874   if (tag1 | dot1q)
9875     {
9876       if (tag1)
9877         {
9878           mask[15] = 0xff;
9879           mask[14] = 0x0f;
9880         }
9881       if (cos1)
9882         mask[14] |= 0xe0;
9883       if (proto)
9884         mask[16] = mask[17] = 0xff;
9885
9886       *maskp = mask;
9887       return 1;
9888     }
9889   if (cos2)
9890     mask[18] |= 0xe0;
9891   if (cos1)
9892     mask[14] |= 0xe0;
9893   if (proto)
9894     mask[12] = mask[13] = 0xff;
9895
9896   *maskp = mask;
9897   return 1;
9898 }
9899
9900 uword
9901 unformat_classify_mask (unformat_input_t * input, va_list * args)
9902 {
9903   u8 **maskp = va_arg (*args, u8 **);
9904   u32 *skipp = va_arg (*args, u32 *);
9905   u32 *matchp = va_arg (*args, u32 *);
9906   u32 match;
9907   u8 *mask = 0;
9908   u8 *l2 = 0;
9909   u8 *l3 = 0;
9910   u8 *l4 = 0;
9911   int i;
9912
9913   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9914     {
9915       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9916         ;
9917       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9918         ;
9919       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9920         ;
9921       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9922         ;
9923       else
9924         break;
9925     }
9926
9927   if (l4 && !l3)
9928     {
9929       vec_free (mask);
9930       vec_free (l2);
9931       vec_free (l4);
9932       return 0;
9933     }
9934
9935   if (mask || l2 || l3 || l4)
9936     {
9937       if (l2 || l3 || l4)
9938         {
9939           /* "With a free Ethernet header in every package" */
9940           if (l2 == 0)
9941             vec_validate (l2, 13);
9942           mask = l2;
9943           if (vec_len (l3))
9944             {
9945               vec_append (mask, l3);
9946               vec_free (l3);
9947             }
9948           if (vec_len (l4))
9949             {
9950               vec_append (mask, l4);
9951               vec_free (l4);
9952             }
9953         }
9954
9955       /* Scan forward looking for the first significant mask octet */
9956       for (i = 0; i < vec_len (mask); i++)
9957         if (mask[i])
9958           break;
9959
9960       /* compute (skip, match) params */
9961       *skipp = i / sizeof (u32x4);
9962       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9963
9964       /* Pad mask to an even multiple of the vector size */
9965       while (vec_len (mask) % sizeof (u32x4))
9966         vec_add1 (mask, 0);
9967
9968       match = vec_len (mask) / sizeof (u32x4);
9969
9970       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9971         {
9972           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9973           if (*tmp || *(tmp + 1))
9974             break;
9975           match--;
9976         }
9977       if (match == 0)
9978         clib_warning ("BUG: match 0");
9979
9980       _vec_len (mask) = match * sizeof (u32x4);
9981
9982       *matchp = match;
9983       *maskp = mask;
9984
9985       return 1;
9986     }
9987
9988   return 0;
9989 }
9990 #endif /* VPP_API_TEST_BUILTIN */
9991
9992 #define foreach_l2_next                         \
9993 _(drop, DROP)                                   \
9994 _(ethernet, ETHERNET_INPUT)                     \
9995 _(ip4, IP4_INPUT)                               \
9996 _(ip6, IP6_INPUT)
9997
9998 uword
9999 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10000 {
10001   u32 *miss_next_indexp = va_arg (*args, u32 *);
10002   u32 next_index = 0;
10003   u32 tmp;
10004
10005 #define _(n,N) \
10006   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10007   foreach_l2_next;
10008 #undef _
10009
10010   if (unformat (input, "%d", &tmp))
10011     {
10012       next_index = tmp;
10013       goto out;
10014     }
10015
10016   return 0;
10017
10018 out:
10019   *miss_next_indexp = next_index;
10020   return 1;
10021 }
10022
10023 #define foreach_ip_next                         \
10024 _(drop, DROP)                                   \
10025 _(local, LOCAL)                                 \
10026 _(rewrite, REWRITE)
10027
10028 uword
10029 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10030 {
10031   u32 *miss_next_indexp = va_arg (*args, u32 *);
10032   u32 next_index = 0;
10033   u32 tmp;
10034
10035 #define _(n,N) \
10036   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10037   foreach_ip_next;
10038 #undef _
10039
10040   if (unformat (input, "%d", &tmp))
10041     {
10042       next_index = tmp;
10043       goto out;
10044     }
10045
10046   return 0;
10047
10048 out:
10049   *miss_next_indexp = next_index;
10050   return 1;
10051 }
10052
10053 #define foreach_acl_next                        \
10054 _(deny, DENY)
10055
10056 uword
10057 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10058 {
10059   u32 *miss_next_indexp = va_arg (*args, u32 *);
10060   u32 next_index = 0;
10061   u32 tmp;
10062
10063 #define _(n,N) \
10064   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10065   foreach_acl_next;
10066 #undef _
10067
10068   if (unformat (input, "permit"))
10069     {
10070       next_index = ~0;
10071       goto out;
10072     }
10073   else if (unformat (input, "%d", &tmp))
10074     {
10075       next_index = tmp;
10076       goto out;
10077     }
10078
10079   return 0;
10080
10081 out:
10082   *miss_next_indexp = next_index;
10083   return 1;
10084 }
10085
10086 uword
10087 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10088 {
10089   u32 *r = va_arg (*args, u32 *);
10090
10091   if (unformat (input, "conform-color"))
10092     *r = POLICE_CONFORM;
10093   else if (unformat (input, "exceed-color"))
10094     *r = POLICE_EXCEED;
10095   else
10096     return 0;
10097
10098   return 1;
10099 }
10100
10101 static int
10102 api_classify_add_del_table (vat_main_t * vam)
10103 {
10104   unformat_input_t *i = vam->input;
10105   vl_api_classify_add_del_table_t *mp;
10106
10107   u32 nbuckets = 2;
10108   u32 skip = ~0;
10109   u32 match = ~0;
10110   int is_add = 1;
10111   int del_chain = 0;
10112   u32 table_index = ~0;
10113   u32 next_table_index = ~0;
10114   u32 miss_next_index = ~0;
10115   u32 memory_size = 32 << 20;
10116   u8 *mask = 0;
10117   u32 current_data_flag = 0;
10118   int current_data_offset = 0;
10119   int ret;
10120
10121   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10122     {
10123       if (unformat (i, "del"))
10124         is_add = 0;
10125       else if (unformat (i, "del-chain"))
10126         {
10127           is_add = 0;
10128           del_chain = 1;
10129         }
10130       else if (unformat (i, "buckets %d", &nbuckets))
10131         ;
10132       else if (unformat (i, "memory_size %d", &memory_size))
10133         ;
10134       else if (unformat (i, "skip %d", &skip))
10135         ;
10136       else if (unformat (i, "match %d", &match))
10137         ;
10138       else if (unformat (i, "table %d", &table_index))
10139         ;
10140       else if (unformat (i, "mask %U", unformat_classify_mask,
10141                          &mask, &skip, &match))
10142         ;
10143       else if (unformat (i, "next-table %d", &next_table_index))
10144         ;
10145       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10146                          &miss_next_index))
10147         ;
10148       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10149                          &miss_next_index))
10150         ;
10151       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10152                          &miss_next_index))
10153         ;
10154       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10155         ;
10156       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10157         ;
10158       else
10159         break;
10160     }
10161
10162   if (is_add && mask == 0)
10163     {
10164       errmsg ("Mask required");
10165       return -99;
10166     }
10167
10168   if (is_add && skip == ~0)
10169     {
10170       errmsg ("skip count required");
10171       return -99;
10172     }
10173
10174   if (is_add && match == ~0)
10175     {
10176       errmsg ("match count required");
10177       return -99;
10178     }
10179
10180   if (!is_add && table_index == ~0)
10181     {
10182       errmsg ("table index required for delete");
10183       return -99;
10184     }
10185
10186   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10187
10188   mp->is_add = is_add;
10189   mp->del_chain = del_chain;
10190   mp->table_index = ntohl (table_index);
10191   mp->nbuckets = ntohl (nbuckets);
10192   mp->memory_size = ntohl (memory_size);
10193   mp->skip_n_vectors = ntohl (skip);
10194   mp->match_n_vectors = ntohl (match);
10195   mp->next_table_index = ntohl (next_table_index);
10196   mp->miss_next_index = ntohl (miss_next_index);
10197   mp->current_data_flag = ntohl (current_data_flag);
10198   mp->current_data_offset = ntohl (current_data_offset);
10199   mp->mask_len = ntohl (vec_len (mask));
10200   clib_memcpy (mp->mask, mask, vec_len (mask));
10201
10202   vec_free (mask);
10203
10204   S (mp);
10205   W (ret);
10206   return ret;
10207 }
10208
10209 #if VPP_API_TEST_BUILTIN == 0
10210 uword
10211 unformat_l4_match (unformat_input_t * input, va_list * args)
10212 {
10213   u8 **matchp = va_arg (*args, u8 **);
10214
10215   u8 *proto_header = 0;
10216   int src_port = 0;
10217   int dst_port = 0;
10218
10219   tcpudp_header_t h;
10220
10221   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10222     {
10223       if (unformat (input, "src_port %d", &src_port))
10224         ;
10225       else if (unformat (input, "dst_port %d", &dst_port))
10226         ;
10227       else
10228         return 0;
10229     }
10230
10231   h.src_port = clib_host_to_net_u16 (src_port);
10232   h.dst_port = clib_host_to_net_u16 (dst_port);
10233   vec_validate (proto_header, sizeof (h) - 1);
10234   memcpy (proto_header, &h, sizeof (h));
10235
10236   *matchp = proto_header;
10237
10238   return 1;
10239 }
10240
10241 uword
10242 unformat_ip4_match (unformat_input_t * input, va_list * args)
10243 {
10244   u8 **matchp = va_arg (*args, u8 **);
10245   u8 *match = 0;
10246   ip4_header_t *ip;
10247   int version = 0;
10248   u32 version_val;
10249   int hdr_length = 0;
10250   u32 hdr_length_val;
10251   int src = 0, dst = 0;
10252   ip4_address_t src_val, dst_val;
10253   int proto = 0;
10254   u32 proto_val;
10255   int tos = 0;
10256   u32 tos_val;
10257   int length = 0;
10258   u32 length_val;
10259   int fragment_id = 0;
10260   u32 fragment_id_val;
10261   int ttl = 0;
10262   int ttl_val;
10263   int checksum = 0;
10264   u32 checksum_val;
10265
10266   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10267     {
10268       if (unformat (input, "version %d", &version_val))
10269         version = 1;
10270       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10271         hdr_length = 1;
10272       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10273         src = 1;
10274       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10275         dst = 1;
10276       else if (unformat (input, "proto %d", &proto_val))
10277         proto = 1;
10278       else if (unformat (input, "tos %d", &tos_val))
10279         tos = 1;
10280       else if (unformat (input, "length %d", &length_val))
10281         length = 1;
10282       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10283         fragment_id = 1;
10284       else if (unformat (input, "ttl %d", &ttl_val))
10285         ttl = 1;
10286       else if (unformat (input, "checksum %d", &checksum_val))
10287         checksum = 1;
10288       else
10289         break;
10290     }
10291
10292   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10293       + ttl + checksum == 0)
10294     return 0;
10295
10296   /*
10297    * Aligned because we use the real comparison functions
10298    */
10299   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10300
10301   ip = (ip4_header_t *) match;
10302
10303   /* These are realistically matched in practice */
10304   if (src)
10305     ip->src_address.as_u32 = src_val.as_u32;
10306
10307   if (dst)
10308     ip->dst_address.as_u32 = dst_val.as_u32;
10309
10310   if (proto)
10311     ip->protocol = proto_val;
10312
10313
10314   /* These are not, but they're included for completeness */
10315   if (version)
10316     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10317
10318   if (hdr_length)
10319     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10320
10321   if (tos)
10322     ip->tos = tos_val;
10323
10324   if (length)
10325     ip->length = clib_host_to_net_u16 (length_val);
10326
10327   if (ttl)
10328     ip->ttl = ttl_val;
10329
10330   if (checksum)
10331     ip->checksum = clib_host_to_net_u16 (checksum_val);
10332
10333   *matchp = match;
10334   return 1;
10335 }
10336
10337 uword
10338 unformat_ip6_match (unformat_input_t * input, va_list * args)
10339 {
10340   u8 **matchp = va_arg (*args, u8 **);
10341   u8 *match = 0;
10342   ip6_header_t *ip;
10343   int version = 0;
10344   u32 version_val;
10345   u8 traffic_class = 0;
10346   u32 traffic_class_val = 0;
10347   u8 flow_label = 0;
10348   u8 flow_label_val;
10349   int src = 0, dst = 0;
10350   ip6_address_t src_val, dst_val;
10351   int proto = 0;
10352   u32 proto_val;
10353   int payload_length = 0;
10354   u32 payload_length_val;
10355   int hop_limit = 0;
10356   int hop_limit_val;
10357   u32 ip_version_traffic_class_and_flow_label;
10358
10359   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10360     {
10361       if (unformat (input, "version %d", &version_val))
10362         version = 1;
10363       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10364         traffic_class = 1;
10365       else if (unformat (input, "flow_label %d", &flow_label_val))
10366         flow_label = 1;
10367       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10368         src = 1;
10369       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10370         dst = 1;
10371       else if (unformat (input, "proto %d", &proto_val))
10372         proto = 1;
10373       else if (unformat (input, "payload_length %d", &payload_length_val))
10374         payload_length = 1;
10375       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10376         hop_limit = 1;
10377       else
10378         break;
10379     }
10380
10381   if (version + traffic_class + flow_label + src + dst + proto +
10382       payload_length + hop_limit == 0)
10383     return 0;
10384
10385   /*
10386    * Aligned because we use the real comparison functions
10387    */
10388   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10389
10390   ip = (ip6_header_t *) match;
10391
10392   if (src)
10393     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10394
10395   if (dst)
10396     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10397
10398   if (proto)
10399     ip->protocol = proto_val;
10400
10401   ip_version_traffic_class_and_flow_label = 0;
10402
10403   if (version)
10404     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10405
10406   if (traffic_class)
10407     ip_version_traffic_class_and_flow_label |=
10408       (traffic_class_val & 0xFF) << 20;
10409
10410   if (flow_label)
10411     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10412
10413   ip->ip_version_traffic_class_and_flow_label =
10414     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10415
10416   if (payload_length)
10417     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10418
10419   if (hop_limit)
10420     ip->hop_limit = hop_limit_val;
10421
10422   *matchp = match;
10423   return 1;
10424 }
10425
10426 uword
10427 unformat_l3_match (unformat_input_t * input, va_list * args)
10428 {
10429   u8 **matchp = va_arg (*args, u8 **);
10430
10431   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10432     {
10433       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10434         return 1;
10435       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10436         return 1;
10437       else
10438         break;
10439     }
10440   return 0;
10441 }
10442
10443 uword
10444 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10445 {
10446   u8 *tagp = va_arg (*args, u8 *);
10447   u32 tag;
10448
10449   if (unformat (input, "%d", &tag))
10450     {
10451       tagp[0] = (tag >> 8) & 0x0F;
10452       tagp[1] = tag & 0xFF;
10453       return 1;
10454     }
10455
10456   return 0;
10457 }
10458
10459 uword
10460 unformat_l2_match (unformat_input_t * input, va_list * args)
10461 {
10462   u8 **matchp = va_arg (*args, u8 **);
10463   u8 *match = 0;
10464   u8 src = 0;
10465   u8 src_val[6];
10466   u8 dst = 0;
10467   u8 dst_val[6];
10468   u8 proto = 0;
10469   u16 proto_val;
10470   u8 tag1 = 0;
10471   u8 tag1_val[2];
10472   u8 tag2 = 0;
10473   u8 tag2_val[2];
10474   int len = 14;
10475   u8 ignore_tag1 = 0;
10476   u8 ignore_tag2 = 0;
10477   u8 cos1 = 0;
10478   u8 cos2 = 0;
10479   u32 cos1_val = 0;
10480   u32 cos2_val = 0;
10481
10482   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10483     {
10484       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10485         src = 1;
10486       else
10487         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10488         dst = 1;
10489       else if (unformat (input, "proto %U",
10490                          unformat_ethernet_type_host_byte_order, &proto_val))
10491         proto = 1;
10492       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10493         tag1 = 1;
10494       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10495         tag2 = 1;
10496       else if (unformat (input, "ignore-tag1"))
10497         ignore_tag1 = 1;
10498       else if (unformat (input, "ignore-tag2"))
10499         ignore_tag2 = 1;
10500       else if (unformat (input, "cos1 %d", &cos1_val))
10501         cos1 = 1;
10502       else if (unformat (input, "cos2 %d", &cos2_val))
10503         cos2 = 1;
10504       else
10505         break;
10506     }
10507   if ((src + dst + proto + tag1 + tag2 +
10508        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10509     return 0;
10510
10511   if (tag1 || ignore_tag1 || cos1)
10512     len = 18;
10513   if (tag2 || ignore_tag2 || cos2)
10514     len = 22;
10515
10516   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10517
10518   if (dst)
10519     clib_memcpy (match, dst_val, 6);
10520
10521   if (src)
10522     clib_memcpy (match + 6, src_val, 6);
10523
10524   if (tag2)
10525     {
10526       /* inner vlan tag */
10527       match[19] = tag2_val[1];
10528       match[18] = tag2_val[0];
10529       if (cos2)
10530         match[18] |= (cos2_val & 0x7) << 5;
10531       if (proto)
10532         {
10533           match[21] = proto_val & 0xff;
10534           match[20] = proto_val >> 8;
10535         }
10536       if (tag1)
10537         {
10538           match[15] = tag1_val[1];
10539           match[14] = tag1_val[0];
10540         }
10541       if (cos1)
10542         match[14] |= (cos1_val & 0x7) << 5;
10543       *matchp = match;
10544       return 1;
10545     }
10546   if (tag1)
10547     {
10548       match[15] = tag1_val[1];
10549       match[14] = tag1_val[0];
10550       if (proto)
10551         {
10552           match[17] = proto_val & 0xff;
10553           match[16] = proto_val >> 8;
10554         }
10555       if (cos1)
10556         match[14] |= (cos1_val & 0x7) << 5;
10557
10558       *matchp = match;
10559       return 1;
10560     }
10561   if (cos2)
10562     match[18] |= (cos2_val & 0x7) << 5;
10563   if (cos1)
10564     match[14] |= (cos1_val & 0x7) << 5;
10565   if (proto)
10566     {
10567       match[13] = proto_val & 0xff;
10568       match[12] = proto_val >> 8;
10569     }
10570
10571   *matchp = match;
10572   return 1;
10573 }
10574
10575 uword
10576 unformat_qos_source (unformat_input_t * input, va_list * args)
10577 {
10578   int *qs = va_arg (*args, int *);
10579
10580   if (unformat (input, "ip"))
10581     *qs = QOS_SOURCE_IP;
10582   else if (unformat (input, "mpls"))
10583     *qs = QOS_SOURCE_MPLS;
10584   else if (unformat (input, "ext"))
10585     *qs = QOS_SOURCE_EXT;
10586   else if (unformat (input, "vlan"))
10587     *qs = QOS_SOURCE_VLAN;
10588   else
10589     return 0;
10590
10591   return 1;
10592 }
10593 #endif
10594
10595 uword
10596 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10597 {
10598   u8 **matchp = va_arg (*args, u8 **);
10599   u32 skip_n_vectors = va_arg (*args, u32);
10600   u32 match_n_vectors = va_arg (*args, u32);
10601
10602   u8 *match = 0;
10603   u8 *l2 = 0;
10604   u8 *l3 = 0;
10605   u8 *l4 = 0;
10606
10607   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10608     {
10609       if (unformat (input, "hex %U", unformat_hex_string, &match))
10610         ;
10611       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10612         ;
10613       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10614         ;
10615       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10616         ;
10617       else
10618         break;
10619     }
10620
10621   if (l4 && !l3)
10622     {
10623       vec_free (match);
10624       vec_free (l2);
10625       vec_free (l4);
10626       return 0;
10627     }
10628
10629   if (match || l2 || l3 || l4)
10630     {
10631       if (l2 || l3 || l4)
10632         {
10633           /* "Win a free Ethernet header in every packet" */
10634           if (l2 == 0)
10635             vec_validate_aligned (l2, 13, sizeof (u32x4));
10636           match = l2;
10637           if (vec_len (l3))
10638             {
10639               vec_append_aligned (match, l3, sizeof (u32x4));
10640               vec_free (l3);
10641             }
10642           if (vec_len (l4))
10643             {
10644               vec_append_aligned (match, l4, sizeof (u32x4));
10645               vec_free (l4);
10646             }
10647         }
10648
10649       /* Make sure the vector is big enough even if key is all 0's */
10650       vec_validate_aligned
10651         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
10652          sizeof (u32x4));
10653
10654       /* Set size, include skipped vectors */
10655       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
10656
10657       *matchp = match;
10658
10659       return 1;
10660     }
10661
10662   return 0;
10663 }
10664
10665 static int
10666 api_classify_add_del_session (vat_main_t * vam)
10667 {
10668   unformat_input_t *i = vam->input;
10669   vl_api_classify_add_del_session_t *mp;
10670   int is_add = 1;
10671   u32 table_index = ~0;
10672   u32 hit_next_index = ~0;
10673   u32 opaque_index = ~0;
10674   u8 *match = 0;
10675   i32 advance = 0;
10676   u32 skip_n_vectors = 0;
10677   u32 match_n_vectors = 0;
10678   u32 action = 0;
10679   u32 metadata = 0;
10680   int ret;
10681
10682   /*
10683    * Warning: you have to supply skip_n and match_n
10684    * because the API client cant simply look at the classify
10685    * table object.
10686    */
10687
10688   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10689     {
10690       if (unformat (i, "del"))
10691         is_add = 0;
10692       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
10693                          &hit_next_index))
10694         ;
10695       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10696                          &hit_next_index))
10697         ;
10698       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
10699                          &hit_next_index))
10700         ;
10701       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10702         ;
10703       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10704         ;
10705       else if (unformat (i, "opaque-index %d", &opaque_index))
10706         ;
10707       else if (unformat (i, "skip_n %d", &skip_n_vectors))
10708         ;
10709       else if (unformat (i, "match_n %d", &match_n_vectors))
10710         ;
10711       else if (unformat (i, "match %U", api_unformat_classify_match,
10712                          &match, skip_n_vectors, match_n_vectors))
10713         ;
10714       else if (unformat (i, "advance %d", &advance))
10715         ;
10716       else if (unformat (i, "table-index %d", &table_index))
10717         ;
10718       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10719         action = 1;
10720       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10721         action = 2;
10722       else if (unformat (i, "action %d", &action))
10723         ;
10724       else if (unformat (i, "metadata %d", &metadata))
10725         ;
10726       else
10727         break;
10728     }
10729
10730   if (table_index == ~0)
10731     {
10732       errmsg ("Table index required");
10733       return -99;
10734     }
10735
10736   if (is_add && match == 0)
10737     {
10738       errmsg ("Match value required");
10739       return -99;
10740     }
10741
10742   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10743
10744   mp->is_add = is_add;
10745   mp->table_index = ntohl (table_index);
10746   mp->hit_next_index = ntohl (hit_next_index);
10747   mp->opaque_index = ntohl (opaque_index);
10748   mp->advance = ntohl (advance);
10749   mp->action = action;
10750   mp->metadata = ntohl (metadata);
10751   mp->match_len = ntohl (vec_len (match));
10752   clib_memcpy (mp->match, match, vec_len (match));
10753   vec_free (match);
10754
10755   S (mp);
10756   W (ret);
10757   return ret;
10758 }
10759
10760 static int
10761 api_classify_set_interface_ip_table (vat_main_t * vam)
10762 {
10763   unformat_input_t *i = vam->input;
10764   vl_api_classify_set_interface_ip_table_t *mp;
10765   u32 sw_if_index;
10766   int sw_if_index_set;
10767   u32 table_index = ~0;
10768   u8 is_ipv6 = 0;
10769   int ret;
10770
10771   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10772     {
10773       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10774         sw_if_index_set = 1;
10775       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10776         sw_if_index_set = 1;
10777       else if (unformat (i, "table %d", &table_index))
10778         ;
10779       else
10780         {
10781           clib_warning ("parse error '%U'", format_unformat_error, i);
10782           return -99;
10783         }
10784     }
10785
10786   if (sw_if_index_set == 0)
10787     {
10788       errmsg ("missing interface name or sw_if_index");
10789       return -99;
10790     }
10791
10792
10793   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10794
10795   mp->sw_if_index = ntohl (sw_if_index);
10796   mp->table_index = ntohl (table_index);
10797   mp->is_ipv6 = is_ipv6;
10798
10799   S (mp);
10800   W (ret);
10801   return ret;
10802 }
10803
10804 static int
10805 api_classify_set_interface_l2_tables (vat_main_t * vam)
10806 {
10807   unformat_input_t *i = vam->input;
10808   vl_api_classify_set_interface_l2_tables_t *mp;
10809   u32 sw_if_index;
10810   int sw_if_index_set;
10811   u32 ip4_table_index = ~0;
10812   u32 ip6_table_index = ~0;
10813   u32 other_table_index = ~0;
10814   u32 is_input = 1;
10815   int ret;
10816
10817   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10818     {
10819       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10820         sw_if_index_set = 1;
10821       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10822         sw_if_index_set = 1;
10823       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10824         ;
10825       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10826         ;
10827       else if (unformat (i, "other-table %d", &other_table_index))
10828         ;
10829       else if (unformat (i, "is-input %d", &is_input))
10830         ;
10831       else
10832         {
10833           clib_warning ("parse error '%U'", format_unformat_error, i);
10834           return -99;
10835         }
10836     }
10837
10838   if (sw_if_index_set == 0)
10839     {
10840       errmsg ("missing interface name or sw_if_index");
10841       return -99;
10842     }
10843
10844
10845   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10846
10847   mp->sw_if_index = ntohl (sw_if_index);
10848   mp->ip4_table_index = ntohl (ip4_table_index);
10849   mp->ip6_table_index = ntohl (ip6_table_index);
10850   mp->other_table_index = ntohl (other_table_index);
10851   mp->is_input = (u8) is_input;
10852
10853   S (mp);
10854   W (ret);
10855   return ret;
10856 }
10857
10858 static int
10859 api_set_ipfix_exporter (vat_main_t * vam)
10860 {
10861   unformat_input_t *i = vam->input;
10862   vl_api_set_ipfix_exporter_t *mp;
10863   ip4_address_t collector_address;
10864   u8 collector_address_set = 0;
10865   u32 collector_port = ~0;
10866   ip4_address_t src_address;
10867   u8 src_address_set = 0;
10868   u32 vrf_id = ~0;
10869   u32 path_mtu = ~0;
10870   u32 template_interval = ~0;
10871   u8 udp_checksum = 0;
10872   int ret;
10873
10874   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10875     {
10876       if (unformat (i, "collector_address %U", unformat_ip4_address,
10877                     &collector_address))
10878         collector_address_set = 1;
10879       else if (unformat (i, "collector_port %d", &collector_port))
10880         ;
10881       else if (unformat (i, "src_address %U", unformat_ip4_address,
10882                          &src_address))
10883         src_address_set = 1;
10884       else if (unformat (i, "vrf_id %d", &vrf_id))
10885         ;
10886       else if (unformat (i, "path_mtu %d", &path_mtu))
10887         ;
10888       else if (unformat (i, "template_interval %d", &template_interval))
10889         ;
10890       else if (unformat (i, "udp_checksum"))
10891         udp_checksum = 1;
10892       else
10893         break;
10894     }
10895
10896   if (collector_address_set == 0)
10897     {
10898       errmsg ("collector_address required");
10899       return -99;
10900     }
10901
10902   if (src_address_set == 0)
10903     {
10904       errmsg ("src_address required");
10905       return -99;
10906     }
10907
10908   M (SET_IPFIX_EXPORTER, mp);
10909
10910   memcpy (mp->collector_address.un.ip4, collector_address.data,
10911           sizeof (collector_address.data));
10912   mp->collector_port = htons ((u16) collector_port);
10913   memcpy (mp->src_address.un.ip4, src_address.data,
10914           sizeof (src_address.data));
10915   mp->vrf_id = htonl (vrf_id);
10916   mp->path_mtu = htonl (path_mtu);
10917   mp->template_interval = htonl (template_interval);
10918   mp->udp_checksum = udp_checksum;
10919
10920   S (mp);
10921   W (ret);
10922   return ret;
10923 }
10924
10925 static int
10926 api_set_ipfix_classify_stream (vat_main_t * vam)
10927 {
10928   unformat_input_t *i = vam->input;
10929   vl_api_set_ipfix_classify_stream_t *mp;
10930   u32 domain_id = 0;
10931   u32 src_port = UDP_DST_PORT_ipfix;
10932   int ret;
10933
10934   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10935     {
10936       if (unformat (i, "domain %d", &domain_id))
10937         ;
10938       else if (unformat (i, "src_port %d", &src_port))
10939         ;
10940       else
10941         {
10942           errmsg ("unknown input `%U'", format_unformat_error, i);
10943           return -99;
10944         }
10945     }
10946
10947   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10948
10949   mp->domain_id = htonl (domain_id);
10950   mp->src_port = htons ((u16) src_port);
10951
10952   S (mp);
10953   W (ret);
10954   return ret;
10955 }
10956
10957 static int
10958 api_ipfix_classify_table_add_del (vat_main_t * vam)
10959 {
10960   unformat_input_t *i = vam->input;
10961   vl_api_ipfix_classify_table_add_del_t *mp;
10962   int is_add = -1;
10963   u32 classify_table_index = ~0;
10964   u8 ip_version = 0;
10965   u8 transport_protocol = 255;
10966   int ret;
10967
10968   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10969     {
10970       if (unformat (i, "add"))
10971         is_add = 1;
10972       else if (unformat (i, "del"))
10973         is_add = 0;
10974       else if (unformat (i, "table %d", &classify_table_index))
10975         ;
10976       else if (unformat (i, "ip4"))
10977         ip_version = 4;
10978       else if (unformat (i, "ip6"))
10979         ip_version = 6;
10980       else if (unformat (i, "tcp"))
10981         transport_protocol = 6;
10982       else if (unformat (i, "udp"))
10983         transport_protocol = 17;
10984       else
10985         {
10986           errmsg ("unknown input `%U'", format_unformat_error, i);
10987           return -99;
10988         }
10989     }
10990
10991   if (is_add == -1)
10992     {
10993       errmsg ("expecting: add|del");
10994       return -99;
10995     }
10996   if (classify_table_index == ~0)
10997     {
10998       errmsg ("classifier table not specified");
10999       return -99;
11000     }
11001   if (ip_version == 0)
11002     {
11003       errmsg ("IP version not specified");
11004       return -99;
11005     }
11006
11007   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11008
11009   mp->is_add = is_add;
11010   mp->table_id = htonl (classify_table_index);
11011   mp->ip_version = ip_version;
11012   mp->transport_protocol = transport_protocol;
11013
11014   S (mp);
11015   W (ret);
11016   return ret;
11017 }
11018
11019 static int
11020 api_get_node_index (vat_main_t * vam)
11021 {
11022   unformat_input_t *i = vam->input;
11023   vl_api_get_node_index_t *mp;
11024   u8 *name = 0;
11025   int ret;
11026
11027   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11028     {
11029       if (unformat (i, "node %s", &name))
11030         ;
11031       else
11032         break;
11033     }
11034   if (name == 0)
11035     {
11036       errmsg ("node name required");
11037       return -99;
11038     }
11039   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11040     {
11041       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11042       return -99;
11043     }
11044
11045   M (GET_NODE_INDEX, mp);
11046   clib_memcpy (mp->node_name, name, vec_len (name));
11047   vec_free (name);
11048
11049   S (mp);
11050   W (ret);
11051   return ret;
11052 }
11053
11054 static int
11055 api_get_next_index (vat_main_t * vam)
11056 {
11057   unformat_input_t *i = vam->input;
11058   vl_api_get_next_index_t *mp;
11059   u8 *node_name = 0, *next_node_name = 0;
11060   int ret;
11061
11062   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11063     {
11064       if (unformat (i, "node-name %s", &node_name))
11065         ;
11066       else if (unformat (i, "next-node-name %s", &next_node_name))
11067         break;
11068     }
11069
11070   if (node_name == 0)
11071     {
11072       errmsg ("node name required");
11073       return -99;
11074     }
11075   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11076     {
11077       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11078       return -99;
11079     }
11080
11081   if (next_node_name == 0)
11082     {
11083       errmsg ("next node name required");
11084       return -99;
11085     }
11086   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11087     {
11088       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11089       return -99;
11090     }
11091
11092   M (GET_NEXT_INDEX, mp);
11093   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11094   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11095   vec_free (node_name);
11096   vec_free (next_node_name);
11097
11098   S (mp);
11099   W (ret);
11100   return ret;
11101 }
11102
11103 static int
11104 api_add_node_next (vat_main_t * vam)
11105 {
11106   unformat_input_t *i = vam->input;
11107   vl_api_add_node_next_t *mp;
11108   u8 *name = 0;
11109   u8 *next = 0;
11110   int ret;
11111
11112   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11113     {
11114       if (unformat (i, "node %s", &name))
11115         ;
11116       else if (unformat (i, "next %s", &next))
11117         ;
11118       else
11119         break;
11120     }
11121   if (name == 0)
11122     {
11123       errmsg ("node name required");
11124       return -99;
11125     }
11126   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11127     {
11128       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11129       return -99;
11130     }
11131   if (next == 0)
11132     {
11133       errmsg ("next node required");
11134       return -99;
11135     }
11136   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11137     {
11138       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11139       return -99;
11140     }
11141
11142   M (ADD_NODE_NEXT, mp);
11143   clib_memcpy (mp->node_name, name, vec_len (name));
11144   clib_memcpy (mp->next_name, next, vec_len (next));
11145   vec_free (name);
11146   vec_free (next);
11147
11148   S (mp);
11149   W (ret);
11150   return ret;
11151 }
11152
11153 static int
11154 api_l2tpv3_create_tunnel (vat_main_t * vam)
11155 {
11156   unformat_input_t *i = vam->input;
11157   ip6_address_t client_address, our_address;
11158   int client_address_set = 0;
11159   int our_address_set = 0;
11160   u32 local_session_id = 0;
11161   u32 remote_session_id = 0;
11162   u64 local_cookie = 0;
11163   u64 remote_cookie = 0;
11164   u8 l2_sublayer_present = 0;
11165   vl_api_l2tpv3_create_tunnel_t *mp;
11166   int ret;
11167
11168   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11169     {
11170       if (unformat (i, "client_address %U", unformat_ip6_address,
11171                     &client_address))
11172         client_address_set = 1;
11173       else if (unformat (i, "our_address %U", unformat_ip6_address,
11174                          &our_address))
11175         our_address_set = 1;
11176       else if (unformat (i, "local_session_id %d", &local_session_id))
11177         ;
11178       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11179         ;
11180       else if (unformat (i, "local_cookie %lld", &local_cookie))
11181         ;
11182       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11183         ;
11184       else if (unformat (i, "l2-sublayer-present"))
11185         l2_sublayer_present = 1;
11186       else
11187         break;
11188     }
11189
11190   if (client_address_set == 0)
11191     {
11192       errmsg ("client_address required");
11193       return -99;
11194     }
11195
11196   if (our_address_set == 0)
11197     {
11198       errmsg ("our_address required");
11199       return -99;
11200     }
11201
11202   M (L2TPV3_CREATE_TUNNEL, mp);
11203
11204   clib_memcpy (mp->client_address.un.ip6, client_address.as_u8,
11205                sizeof (ip6_address_t));
11206
11207   clib_memcpy (mp->our_address.un.ip6, our_address.as_u8,
11208                sizeof (ip6_address_t));
11209
11210   mp->local_session_id = ntohl (local_session_id);
11211   mp->remote_session_id = ntohl (remote_session_id);
11212   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11213   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11214   mp->l2_sublayer_present = l2_sublayer_present;
11215
11216   S (mp);
11217   W (ret);
11218   return ret;
11219 }
11220
11221 static int
11222 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11223 {
11224   unformat_input_t *i = vam->input;
11225   u32 sw_if_index;
11226   u8 sw_if_index_set = 0;
11227   u64 new_local_cookie = 0;
11228   u64 new_remote_cookie = 0;
11229   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11230   int ret;
11231
11232   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11233     {
11234       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11235         sw_if_index_set = 1;
11236       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11237         sw_if_index_set = 1;
11238       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11239         ;
11240       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11241         ;
11242       else
11243         break;
11244     }
11245
11246   if (sw_if_index_set == 0)
11247     {
11248       errmsg ("missing interface name or sw_if_index");
11249       return -99;
11250     }
11251
11252   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11253
11254   mp->sw_if_index = ntohl (sw_if_index);
11255   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11256   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11257
11258   S (mp);
11259   W (ret);
11260   return ret;
11261 }
11262
11263 static int
11264 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11265 {
11266   unformat_input_t *i = vam->input;
11267   vl_api_l2tpv3_interface_enable_disable_t *mp;
11268   u32 sw_if_index;
11269   u8 sw_if_index_set = 0;
11270   u8 enable_disable = 1;
11271   int ret;
11272
11273   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11274     {
11275       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11276         sw_if_index_set = 1;
11277       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11278         sw_if_index_set = 1;
11279       else if (unformat (i, "enable"))
11280         enable_disable = 1;
11281       else if (unformat (i, "disable"))
11282         enable_disable = 0;
11283       else
11284         break;
11285     }
11286
11287   if (sw_if_index_set == 0)
11288     {
11289       errmsg ("missing interface name or sw_if_index");
11290       return -99;
11291     }
11292
11293   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11294
11295   mp->sw_if_index = ntohl (sw_if_index);
11296   mp->enable_disable = enable_disable;
11297
11298   S (mp);
11299   W (ret);
11300   return ret;
11301 }
11302
11303 static int
11304 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11305 {
11306   unformat_input_t *i = vam->input;
11307   vl_api_l2tpv3_set_lookup_key_t *mp;
11308   u8 key = ~0;
11309   int ret;
11310
11311   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11312     {
11313       if (unformat (i, "lookup_v6_src"))
11314         key = L2T_LOOKUP_SRC_ADDRESS;
11315       else if (unformat (i, "lookup_v6_dst"))
11316         key = L2T_LOOKUP_DST_ADDRESS;
11317       else if (unformat (i, "lookup_session_id"))
11318         key = L2T_LOOKUP_SESSION_ID;
11319       else
11320         break;
11321     }
11322
11323   if (key == (u8) ~ 0)
11324     {
11325       errmsg ("l2tp session lookup key unset");
11326       return -99;
11327     }
11328
11329   M (L2TPV3_SET_LOOKUP_KEY, mp);
11330
11331   mp->key = key;
11332
11333   S (mp);
11334   W (ret);
11335   return ret;
11336 }
11337
11338 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11339   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11340 {
11341   vat_main_t *vam = &vat_main;
11342
11343   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11344          format_ip6_address, mp->our_address,
11345          format_ip6_address, mp->client_address,
11346          clib_net_to_host_u32 (mp->sw_if_index));
11347
11348   print (vam->ofp,
11349          "   local cookies %016llx %016llx remote cookie %016llx",
11350          clib_net_to_host_u64 (mp->local_cookie[0]),
11351          clib_net_to_host_u64 (mp->local_cookie[1]),
11352          clib_net_to_host_u64 (mp->remote_cookie));
11353
11354   print (vam->ofp, "   local session-id %d remote session-id %d",
11355          clib_net_to_host_u32 (mp->local_session_id),
11356          clib_net_to_host_u32 (mp->remote_session_id));
11357
11358   print (vam->ofp, "   l2 specific sublayer %s\n",
11359          mp->l2_sublayer_present ? "preset" : "absent");
11360
11361 }
11362
11363 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11364   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11365 {
11366   vat_main_t *vam = &vat_main;
11367   vat_json_node_t *node = NULL;
11368   struct in6_addr addr;
11369
11370   if (VAT_JSON_ARRAY != vam->json_tree.type)
11371     {
11372       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11373       vat_json_init_array (&vam->json_tree);
11374     }
11375   node = vat_json_array_add (&vam->json_tree);
11376
11377   vat_json_init_object (node);
11378
11379   clib_memcpy (&addr, mp->our_address.un.ip6, sizeof (addr));
11380   vat_json_object_add_ip6 (node, "our_address", addr);
11381   clib_memcpy (&addr, mp->client_address.un.ip6, sizeof (addr));
11382   vat_json_object_add_ip6 (node, "client_address", addr);
11383
11384   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11385   vat_json_init_array (lc);
11386   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11387   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11388   vat_json_object_add_uint (node, "remote_cookie",
11389                             clib_net_to_host_u64 (mp->remote_cookie));
11390
11391   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11392   vat_json_object_add_uint (node, "local_session_id",
11393                             clib_net_to_host_u32 (mp->local_session_id));
11394   vat_json_object_add_uint (node, "remote_session_id",
11395                             clib_net_to_host_u32 (mp->remote_session_id));
11396   vat_json_object_add_string_copy (node, "l2_sublayer",
11397                                    mp->l2_sublayer_present ? (u8 *) "present"
11398                                    : (u8 *) "absent");
11399 }
11400
11401 static int
11402 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11403 {
11404   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11405   vl_api_control_ping_t *mp_ping;
11406   int ret;
11407
11408   /* Get list of l2tpv3-tunnel interfaces */
11409   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11410   S (mp);
11411
11412   /* Use a control ping for synchronization */
11413   MPING (CONTROL_PING, mp_ping);
11414   S (mp_ping);
11415
11416   W (ret);
11417   return ret;
11418 }
11419
11420
11421 static void vl_api_sw_interface_tap_v2_details_t_handler
11422   (vl_api_sw_interface_tap_v2_details_t * mp)
11423 {
11424   vat_main_t *vam = &vat_main;
11425
11426   u8 *ip4 =
11427     format (0, "%U/%d", format_ip4_address, mp->host_ip4_prefix.address,
11428             mp->host_ip4_prefix.len);
11429   u8 *ip6 =
11430     format (0, "%U/%d", format_ip6_address, mp->host_ip6_prefix.address,
11431             mp->host_ip6_prefix.len);
11432
11433   print (vam->ofp,
11434          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
11435          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
11436          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11437          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
11438          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
11439
11440   vec_free (ip4);
11441   vec_free (ip6);
11442 }
11443
11444 static void vl_api_sw_interface_tap_v2_details_t_handler_json
11445   (vl_api_sw_interface_tap_v2_details_t * mp)
11446 {
11447   vat_main_t *vam = &vat_main;
11448   vat_json_node_t *node = NULL;
11449
11450   if (VAT_JSON_ARRAY != vam->json_tree.type)
11451     {
11452       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11453       vat_json_init_array (&vam->json_tree);
11454     }
11455   node = vat_json_array_add (&vam->json_tree);
11456
11457   vat_json_init_object (node);
11458   vat_json_object_add_uint (node, "id", ntohl (mp->id));
11459   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11460   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
11461   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11462   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11463   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11464   vat_json_object_add_string_copy (node, "host_mac_addr",
11465                                    format (0, "%U", format_ethernet_address,
11466                                            &mp->host_mac_addr));
11467   vat_json_object_add_string_copy (node, "host_namespace",
11468                                    mp->host_namespace);
11469   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
11470   vat_json_object_add_string_copy (node, "host_ip4_addr",
11471                                    format (0, "%U/%d", format_ip4_address,
11472                                            mp->host_ip4_prefix.address,
11473                                            mp->host_ip4_prefix.len));
11474   vat_json_object_add_string_copy (node, "host_ip6_prefix",
11475                                    format (0, "%U/%d", format_ip6_address,
11476                                            mp->host_ip6_prefix.address,
11477                                            mp->host_ip6_prefix.len));
11478
11479 }
11480
11481 static int
11482 api_sw_interface_tap_v2_dump (vat_main_t * vam)
11483 {
11484   vl_api_sw_interface_tap_v2_dump_t *mp;
11485   vl_api_control_ping_t *mp_ping;
11486   int ret;
11487
11488   print (vam->ofp,
11489          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
11490          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
11491          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
11492          "host_ip6_addr");
11493
11494   /* Get list of tap interfaces */
11495   M (SW_INTERFACE_TAP_V2_DUMP, mp);
11496   S (mp);
11497
11498   /* Use a control ping for synchronization */
11499   MPING (CONTROL_PING, mp_ping);
11500   S (mp_ping);
11501
11502   W (ret);
11503   return ret;
11504 }
11505
11506 static void vl_api_sw_interface_virtio_pci_details_t_handler
11507   (vl_api_sw_interface_virtio_pci_details_t * mp)
11508 {
11509   vat_main_t *vam = &vat_main;
11510
11511   typedef union
11512   {
11513     struct
11514     {
11515       u16 domain;
11516       u8 bus;
11517       u8 slot:5;
11518       u8 function:3;
11519     };
11520     u32 as_u32;
11521   } pci_addr_t;
11522   pci_addr_t addr;
11523
11524   addr.domain = ntohs (mp->pci_addr.domain);
11525   addr.bus = mp->pci_addr.bus;
11526   addr.slot = mp->pci_addr.slot;
11527   addr.function = mp->pci_addr.function;
11528
11529   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
11530                          addr.slot, addr.function);
11531
11532   print (vam->ofp,
11533          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
11534          pci_addr, ntohl (mp->sw_if_index),
11535          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11536          format_ethernet_address, mp->mac_addr,
11537          clib_net_to_host_u64 (mp->features));
11538   vec_free (pci_addr);
11539 }
11540
11541 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
11542   (vl_api_sw_interface_virtio_pci_details_t * mp)
11543 {
11544   vat_main_t *vam = &vat_main;
11545   vat_json_node_t *node = NULL;
11546   vlib_pci_addr_t pci_addr;
11547
11548   if (VAT_JSON_ARRAY != vam->json_tree.type)
11549     {
11550       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11551       vat_json_init_array (&vam->json_tree);
11552     }
11553   node = vat_json_array_add (&vam->json_tree);
11554
11555   pci_addr.domain = ntohs (mp->pci_addr.domain);
11556   pci_addr.bus = mp->pci_addr.bus;
11557   pci_addr.slot = mp->pci_addr.slot;
11558   pci_addr.function = mp->pci_addr.function;
11559
11560   vat_json_init_object (node);
11561   vat_json_object_add_uint (node, "pci-addr", pci_addr.as_u32);
11562   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11563   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11564   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11565   vat_json_object_add_uint (node, "features",
11566                             clib_net_to_host_u64 (mp->features));
11567   vat_json_object_add_string_copy (node, "mac_addr",
11568                                    format (0, "%U", format_ethernet_address,
11569                                            &mp->mac_addr));
11570 }
11571
11572 static int
11573 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
11574 {
11575   vl_api_sw_interface_virtio_pci_dump_t *mp;
11576   vl_api_control_ping_t *mp_ping;
11577   int ret;
11578
11579   print (vam->ofp,
11580          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
11581          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
11582          "mac_addr", "features");
11583
11584   /* Get list of tap interfaces */
11585   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
11586   S (mp);
11587
11588   /* Use a control ping for synchronization */
11589   MPING (CONTROL_PING, mp_ping);
11590   S (mp_ping);
11591
11592   W (ret);
11593   return ret;
11594 }
11595
11596 static int
11597 api_vxlan_offload_rx (vat_main_t * vam)
11598 {
11599   unformat_input_t *line_input = vam->input;
11600   vl_api_vxlan_offload_rx_t *mp;
11601   u32 hw_if_index = ~0, rx_if_index = ~0;
11602   u8 is_add = 1;
11603   int ret;
11604
11605   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11606     {
11607       if (unformat (line_input, "del"))
11608         is_add = 0;
11609       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
11610                          &hw_if_index))
11611         ;
11612       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
11613         ;
11614       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
11615                          &rx_if_index))
11616         ;
11617       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
11618         ;
11619       else
11620         {
11621           errmsg ("parse error '%U'", format_unformat_error, line_input);
11622           return -99;
11623         }
11624     }
11625
11626   if (hw_if_index == ~0)
11627     {
11628       errmsg ("no hw interface");
11629       return -99;
11630     }
11631
11632   if (rx_if_index == ~0)
11633     {
11634       errmsg ("no rx tunnel");
11635       return -99;
11636     }
11637
11638   M (VXLAN_OFFLOAD_RX, mp);
11639
11640   mp->hw_if_index = ntohl (hw_if_index);
11641   mp->sw_if_index = ntohl (rx_if_index);
11642   mp->enable = is_add;
11643
11644   S (mp);
11645   W (ret);
11646   return ret;
11647 }
11648
11649 static uword unformat_vxlan_decap_next
11650   (unformat_input_t * input, va_list * args)
11651 {
11652   u32 *result = va_arg (*args, u32 *);
11653   u32 tmp;
11654
11655   if (unformat (input, "l2"))
11656     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11657   else if (unformat (input, "%d", &tmp))
11658     *result = tmp;
11659   else
11660     return 0;
11661   return 1;
11662 }
11663
11664 static int
11665 api_vxlan_add_del_tunnel (vat_main_t * vam)
11666 {
11667   unformat_input_t *line_input = vam->input;
11668   vl_api_vxlan_add_del_tunnel_t *mp;
11669   ip46_address_t src, dst;
11670   u8 is_add = 1;
11671   u8 ipv4_set = 0, ipv6_set = 0;
11672   u8 src_set = 0;
11673   u8 dst_set = 0;
11674   u8 grp_set = 0;
11675   u32 instance = ~0;
11676   u32 mcast_sw_if_index = ~0;
11677   u32 encap_vrf_id = 0;
11678   u32 decap_next_index = ~0;
11679   u32 vni = 0;
11680   int ret;
11681
11682   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11683   clib_memset (&src, 0, sizeof src);
11684   clib_memset (&dst, 0, sizeof dst);
11685
11686   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11687     {
11688       if (unformat (line_input, "del"))
11689         is_add = 0;
11690       else if (unformat (line_input, "instance %d", &instance))
11691         ;
11692       else
11693         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11694         {
11695           ipv4_set = 1;
11696           src_set = 1;
11697         }
11698       else
11699         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11700         {
11701           ipv4_set = 1;
11702           dst_set = 1;
11703         }
11704       else
11705         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11706         {
11707           ipv6_set = 1;
11708           src_set = 1;
11709         }
11710       else
11711         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11712         {
11713           ipv6_set = 1;
11714           dst_set = 1;
11715         }
11716       else if (unformat (line_input, "group %U %U",
11717                          unformat_ip4_address, &dst.ip4,
11718                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11719         {
11720           grp_set = dst_set = 1;
11721           ipv4_set = 1;
11722         }
11723       else if (unformat (line_input, "group %U",
11724                          unformat_ip4_address, &dst.ip4))
11725         {
11726           grp_set = dst_set = 1;
11727           ipv4_set = 1;
11728         }
11729       else if (unformat (line_input, "group %U %U",
11730                          unformat_ip6_address, &dst.ip6,
11731                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11732         {
11733           grp_set = dst_set = 1;
11734           ipv6_set = 1;
11735         }
11736       else if (unformat (line_input, "group %U",
11737                          unformat_ip6_address, &dst.ip6))
11738         {
11739           grp_set = dst_set = 1;
11740           ipv6_set = 1;
11741         }
11742       else
11743         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11744         ;
11745       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11746         ;
11747       else if (unformat (line_input, "decap-next %U",
11748                          unformat_vxlan_decap_next, &decap_next_index))
11749         ;
11750       else if (unformat (line_input, "vni %d", &vni))
11751         ;
11752       else
11753         {
11754           errmsg ("parse error '%U'", format_unformat_error, line_input);
11755           return -99;
11756         }
11757     }
11758
11759   if (src_set == 0)
11760     {
11761       errmsg ("tunnel src address not specified");
11762       return -99;
11763     }
11764   if (dst_set == 0)
11765     {
11766       errmsg ("tunnel dst address not specified");
11767       return -99;
11768     }
11769
11770   if (grp_set && !ip46_address_is_multicast (&dst))
11771     {
11772       errmsg ("tunnel group address not multicast");
11773       return -99;
11774     }
11775   if (grp_set && mcast_sw_if_index == ~0)
11776     {
11777       errmsg ("tunnel nonexistent multicast device");
11778       return -99;
11779     }
11780   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11781     {
11782       errmsg ("tunnel dst address must be unicast");
11783       return -99;
11784     }
11785
11786
11787   if (ipv4_set && ipv6_set)
11788     {
11789       errmsg ("both IPv4 and IPv6 addresses specified");
11790       return -99;
11791     }
11792
11793   if ((vni == 0) || (vni >> 24))
11794     {
11795       errmsg ("vni not specified or out of range");
11796       return -99;
11797     }
11798
11799   M (VXLAN_ADD_DEL_TUNNEL, mp);
11800
11801   if (ipv6_set)
11802     {
11803       clib_memcpy (mp->src_address.un.ip6, &src.ip6, sizeof (src.ip6));
11804       clib_memcpy (mp->dst_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
11805     }
11806   else
11807     {
11808       clib_memcpy (mp->src_address.un.ip4, &src.ip4, sizeof (src.ip4));
11809       clib_memcpy (mp->dst_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
11810     }
11811   mp->src_address.af = ipv6_set;
11812   mp->dst_address.af = ipv6_set;
11813
11814   mp->instance = htonl (instance);
11815   mp->encap_vrf_id = ntohl (encap_vrf_id);
11816   mp->decap_next_index = ntohl (decap_next_index);
11817   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11818   mp->vni = ntohl (vni);
11819   mp->is_add = is_add;
11820
11821   S (mp);
11822   W (ret);
11823   return ret;
11824 }
11825
11826 static void vl_api_vxlan_tunnel_details_t_handler
11827   (vl_api_vxlan_tunnel_details_t * mp)
11828 {
11829   vat_main_t *vam = &vat_main;
11830   ip46_address_t src =
11831     to_ip46 (mp->dst_address.af, (u8 *) & mp->dst_address.un);
11832   ip46_address_t dst =
11833     to_ip46 (mp->dst_address.af, (u8 *) & mp->src_address.un);
11834
11835   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
11836          ntohl (mp->sw_if_index),
11837          ntohl (mp->instance),
11838          format_ip46_address, &src, IP46_TYPE_ANY,
11839          format_ip46_address, &dst, IP46_TYPE_ANY,
11840          ntohl (mp->encap_vrf_id),
11841          ntohl (mp->decap_next_index), ntohl (mp->vni),
11842          ntohl (mp->mcast_sw_if_index));
11843 }
11844
11845 static void vl_api_vxlan_tunnel_details_t_handler_json
11846   (vl_api_vxlan_tunnel_details_t * mp)
11847 {
11848   vat_main_t *vam = &vat_main;
11849   vat_json_node_t *node = NULL;
11850
11851   if (VAT_JSON_ARRAY != vam->json_tree.type)
11852     {
11853       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11854       vat_json_init_array (&vam->json_tree);
11855     }
11856   node = vat_json_array_add (&vam->json_tree);
11857
11858   vat_json_init_object (node);
11859   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11860
11861   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
11862
11863   if (mp->src_address.af)
11864     {
11865       struct in6_addr ip6;
11866
11867       clib_memcpy (&ip6, mp->src_address.un.ip6, sizeof (ip6));
11868       vat_json_object_add_ip6 (node, "src_address", ip6);
11869       clib_memcpy (&ip6, mp->dst_address.un.ip6, sizeof (ip6));
11870       vat_json_object_add_ip6 (node, "dst_address", ip6);
11871     }
11872   else
11873     {
11874       struct in_addr ip4;
11875
11876       clib_memcpy (&ip4, mp->src_address.un.ip4, sizeof (ip4));
11877       vat_json_object_add_ip4 (node, "src_address", ip4);
11878       clib_memcpy (&ip4, mp->dst_address.un.ip4, sizeof (ip4));
11879       vat_json_object_add_ip4 (node, "dst_address", ip4);
11880     }
11881   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11882   vat_json_object_add_uint (node, "decap_next_index",
11883                             ntohl (mp->decap_next_index));
11884   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11885   vat_json_object_add_uint (node, "mcast_sw_if_index",
11886                             ntohl (mp->mcast_sw_if_index));
11887 }
11888
11889 static int
11890 api_vxlan_tunnel_dump (vat_main_t * vam)
11891 {
11892   unformat_input_t *i = vam->input;
11893   vl_api_vxlan_tunnel_dump_t *mp;
11894   vl_api_control_ping_t *mp_ping;
11895   u32 sw_if_index;
11896   u8 sw_if_index_set = 0;
11897   int ret;
11898
11899   /* Parse args required to build the message */
11900   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11901     {
11902       if (unformat (i, "sw_if_index %d", &sw_if_index))
11903         sw_if_index_set = 1;
11904       else
11905         break;
11906     }
11907
11908   if (sw_if_index_set == 0)
11909     {
11910       sw_if_index = ~0;
11911     }
11912
11913   if (!vam->json_output)
11914     {
11915       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
11916              "sw_if_index", "instance", "src_address", "dst_address",
11917              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
11918     }
11919
11920   /* Get list of vxlan-tunnel interfaces */
11921   M (VXLAN_TUNNEL_DUMP, mp);
11922
11923   mp->sw_if_index = htonl (sw_if_index);
11924
11925   S (mp);
11926
11927   /* Use a control ping for synchronization */
11928   MPING (CONTROL_PING, mp_ping);
11929   S (mp_ping);
11930
11931   W (ret);
11932   return ret;
11933 }
11934
11935 static int
11936 api_gre_tunnel_add_del (vat_main_t * vam)
11937 {
11938   unformat_input_t *line_input = vam->input;
11939   vl_api_address_t src = { }, dst =
11940   {
11941   };
11942   vl_api_gre_tunnel_add_del_t *mp;
11943   vl_api_gre_tunnel_type_t t_type;
11944   u8 is_add = 1;
11945   u8 src_set = 0;
11946   u8 dst_set = 0;
11947   u32 outer_table_id = 0;
11948   u32 session_id = 0;
11949   u32 instance = ~0;
11950   int ret;
11951
11952   t_type = GRE_API_TUNNEL_TYPE_L3;
11953
11954   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11955     {
11956       if (unformat (line_input, "del"))
11957         is_add = 0;
11958       else if (unformat (line_input, "instance %d", &instance))
11959         ;
11960       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
11961         {
11962           src_set = 1;
11963         }
11964       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
11965         {
11966           dst_set = 1;
11967         }
11968       else if (unformat (line_input, "outer-table-id %d", &outer_table_id))
11969         ;
11970       else if (unformat (line_input, "teb"))
11971         t_type = GRE_API_TUNNEL_TYPE_TEB;
11972       else if (unformat (line_input, "erspan %d", &session_id))
11973         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
11974       else
11975         {
11976           errmsg ("parse error '%U'", format_unformat_error, line_input);
11977           return -99;
11978         }
11979     }
11980
11981   if (src_set == 0)
11982     {
11983       errmsg ("tunnel src address not specified");
11984       return -99;
11985     }
11986   if (dst_set == 0)
11987     {
11988       errmsg ("tunnel dst address not specified");
11989       return -99;
11990     }
11991
11992   M (GRE_TUNNEL_ADD_DEL, mp);
11993
11994   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
11995   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
11996
11997   mp->tunnel.instance = htonl (instance);
11998   mp->tunnel.outer_table_id = htonl (outer_table_id);
11999   mp->is_add = is_add;
12000   mp->tunnel.session_id = htons ((u16) session_id);
12001   mp->tunnel.type = htonl (t_type);
12002
12003   S (mp);
12004   W (ret);
12005   return ret;
12006 }
12007
12008 static void vl_api_gre_tunnel_details_t_handler
12009   (vl_api_gre_tunnel_details_t * mp)
12010 {
12011   vat_main_t *vam = &vat_main;
12012
12013   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
12014          ntohl (mp->tunnel.sw_if_index),
12015          ntohl (mp->tunnel.instance),
12016          format_vl_api_address, &mp->tunnel.src,
12017          format_vl_api_address, &mp->tunnel.dst,
12018          mp->tunnel.type, ntohl (mp->tunnel.outer_table_id),
12019          ntohl (mp->tunnel.session_id));
12020 }
12021
12022 static void vl_api_gre_tunnel_details_t_handler_json
12023   (vl_api_gre_tunnel_details_t * mp)
12024 {
12025   vat_main_t *vam = &vat_main;
12026   vat_json_node_t *node = NULL;
12027
12028   if (VAT_JSON_ARRAY != vam->json_tree.type)
12029     {
12030       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12031       vat_json_init_array (&vam->json_tree);
12032     }
12033   node = vat_json_array_add (&vam->json_tree);
12034
12035   vat_json_init_object (node);
12036   vat_json_object_add_uint (node, "sw_if_index",
12037                             ntohl (mp->tunnel.sw_if_index));
12038   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
12039
12040   vat_json_object_add_address (node, "src", &mp->tunnel.src);
12041   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
12042   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
12043   vat_json_object_add_uint (node, "outer_table_id",
12044                             ntohl (mp->tunnel.outer_table_id));
12045   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
12046 }
12047
12048 static int
12049 api_gre_tunnel_dump (vat_main_t * vam)
12050 {
12051   unformat_input_t *i = vam->input;
12052   vl_api_gre_tunnel_dump_t *mp;
12053   vl_api_control_ping_t *mp_ping;
12054   u32 sw_if_index;
12055   u8 sw_if_index_set = 0;
12056   int ret;
12057
12058   /* Parse args required to build the message */
12059   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12060     {
12061       if (unformat (i, "sw_if_index %d", &sw_if_index))
12062         sw_if_index_set = 1;
12063       else
12064         break;
12065     }
12066
12067   if (sw_if_index_set == 0)
12068     {
12069       sw_if_index = ~0;
12070     }
12071
12072   if (!vam->json_output)
12073     {
12074       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
12075              "sw_if_index", "instance", "src_address", "dst_address",
12076              "tunnel_type", "outer_fib_id", "session_id");
12077     }
12078
12079   /* Get list of gre-tunnel interfaces */
12080   M (GRE_TUNNEL_DUMP, mp);
12081
12082   mp->sw_if_index = htonl (sw_if_index);
12083
12084   S (mp);
12085
12086   /* Use a control ping for synchronization */
12087   MPING (CONTROL_PING, mp_ping);
12088   S (mp_ping);
12089
12090   W (ret);
12091   return ret;
12092 }
12093
12094 static int
12095 api_l2_fib_clear_table (vat_main_t * vam)
12096 {
12097 //  unformat_input_t * i = vam->input;
12098   vl_api_l2_fib_clear_table_t *mp;
12099   int ret;
12100
12101   M (L2_FIB_CLEAR_TABLE, mp);
12102
12103   S (mp);
12104   W (ret);
12105   return ret;
12106 }
12107
12108 static int
12109 api_l2_interface_efp_filter (vat_main_t * vam)
12110 {
12111   unformat_input_t *i = vam->input;
12112   vl_api_l2_interface_efp_filter_t *mp;
12113   u32 sw_if_index;
12114   u8 enable = 1;
12115   u8 sw_if_index_set = 0;
12116   int ret;
12117
12118   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12119     {
12120       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12121         sw_if_index_set = 1;
12122       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12123         sw_if_index_set = 1;
12124       else if (unformat (i, "enable"))
12125         enable = 1;
12126       else if (unformat (i, "disable"))
12127         enable = 0;
12128       else
12129         {
12130           clib_warning ("parse error '%U'", format_unformat_error, i);
12131           return -99;
12132         }
12133     }
12134
12135   if (sw_if_index_set == 0)
12136     {
12137       errmsg ("missing sw_if_index");
12138       return -99;
12139     }
12140
12141   M (L2_INTERFACE_EFP_FILTER, mp);
12142
12143   mp->sw_if_index = ntohl (sw_if_index);
12144   mp->enable_disable = enable;
12145
12146   S (mp);
12147   W (ret);
12148   return ret;
12149 }
12150
12151 #define foreach_vtr_op                          \
12152 _("disable",  L2_VTR_DISABLED)                  \
12153 _("push-1",  L2_VTR_PUSH_1)                     \
12154 _("push-2",  L2_VTR_PUSH_2)                     \
12155 _("pop-1",  L2_VTR_POP_1)                       \
12156 _("pop-2",  L2_VTR_POP_2)                       \
12157 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12158 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12159 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12160 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12161
12162 static int
12163 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12164 {
12165   unformat_input_t *i = vam->input;
12166   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12167   u32 sw_if_index;
12168   u8 sw_if_index_set = 0;
12169   u8 vtr_op_set = 0;
12170   u32 vtr_op = 0;
12171   u32 push_dot1q = 1;
12172   u32 tag1 = ~0;
12173   u32 tag2 = ~0;
12174   int ret;
12175
12176   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12177     {
12178       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12179         sw_if_index_set = 1;
12180       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12181         sw_if_index_set = 1;
12182       else if (unformat (i, "vtr_op %d", &vtr_op))
12183         vtr_op_set = 1;
12184 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12185       foreach_vtr_op
12186 #undef _
12187         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12188         ;
12189       else if (unformat (i, "tag1 %d", &tag1))
12190         ;
12191       else if (unformat (i, "tag2 %d", &tag2))
12192         ;
12193       else
12194         {
12195           clib_warning ("parse error '%U'", format_unformat_error, i);
12196           return -99;
12197         }
12198     }
12199
12200   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12201     {
12202       errmsg ("missing vtr operation or sw_if_index");
12203       return -99;
12204     }
12205
12206   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12207   mp->sw_if_index = ntohl (sw_if_index);
12208   mp->vtr_op = ntohl (vtr_op);
12209   mp->push_dot1q = ntohl (push_dot1q);
12210   mp->tag1 = ntohl (tag1);
12211   mp->tag2 = ntohl (tag2);
12212
12213   S (mp);
12214   W (ret);
12215   return ret;
12216 }
12217
12218 static int
12219 api_create_vhost_user_if (vat_main_t * vam)
12220 {
12221   unformat_input_t *i = vam->input;
12222   vl_api_create_vhost_user_if_t *mp;
12223   u8 *file_name;
12224   u8 is_server = 0;
12225   u8 file_name_set = 0;
12226   u32 custom_dev_instance = ~0;
12227   u8 hwaddr[6];
12228   u8 use_custom_mac = 0;
12229   u8 disable_mrg_rxbuf = 0;
12230   u8 disable_indirect_desc = 0;
12231   u8 *tag = 0;
12232   u8 enable_gso = 0;
12233   u8 enable_packed = 0;
12234   int ret;
12235
12236   /* Shut up coverity */
12237   clib_memset (hwaddr, 0, sizeof (hwaddr));
12238
12239   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12240     {
12241       if (unformat (i, "socket %s", &file_name))
12242         {
12243           file_name_set = 1;
12244         }
12245       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12246         ;
12247       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12248         use_custom_mac = 1;
12249       else if (unformat (i, "server"))
12250         is_server = 1;
12251       else if (unformat (i, "disable_mrg_rxbuf"))
12252         disable_mrg_rxbuf = 1;
12253       else if (unformat (i, "disable_indirect_desc"))
12254         disable_indirect_desc = 1;
12255       else if (unformat (i, "gso"))
12256         enable_gso = 1;
12257       else if (unformat (i, "packed"))
12258         enable_packed = 1;
12259       else if (unformat (i, "tag %s", &tag))
12260         ;
12261       else
12262         break;
12263     }
12264
12265   if (file_name_set == 0)
12266     {
12267       errmsg ("missing socket file name");
12268       return -99;
12269     }
12270
12271   if (vec_len (file_name) > 255)
12272     {
12273       errmsg ("socket file name too long");
12274       return -99;
12275     }
12276   vec_add1 (file_name, 0);
12277
12278   M (CREATE_VHOST_USER_IF, mp);
12279
12280   mp->is_server = is_server;
12281   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
12282   mp->disable_indirect_desc = disable_indirect_desc;
12283   mp->enable_gso = enable_gso;
12284   mp->enable_packed = enable_packed;
12285   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12286   vec_free (file_name);
12287   if (custom_dev_instance != ~0)
12288     {
12289       mp->renumber = 1;
12290       mp->custom_dev_instance = ntohl (custom_dev_instance);
12291     }
12292
12293   mp->use_custom_mac = use_custom_mac;
12294   clib_memcpy (mp->mac_address, hwaddr, 6);
12295   if (tag)
12296     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
12297   vec_free (tag);
12298
12299   S (mp);
12300   W (ret);
12301   return ret;
12302 }
12303
12304 static int
12305 api_modify_vhost_user_if (vat_main_t * vam)
12306 {
12307   unformat_input_t *i = vam->input;
12308   vl_api_modify_vhost_user_if_t *mp;
12309   u8 *file_name;
12310   u8 is_server = 0;
12311   u8 file_name_set = 0;
12312   u32 custom_dev_instance = ~0;
12313   u8 sw_if_index_set = 0;
12314   u32 sw_if_index = (u32) ~ 0;
12315   u8 enable_gso = 0;
12316   u8 enable_packed = 0;
12317   int ret;
12318
12319   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12320     {
12321       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12322         sw_if_index_set = 1;
12323       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12324         sw_if_index_set = 1;
12325       else if (unformat (i, "socket %s", &file_name))
12326         {
12327           file_name_set = 1;
12328         }
12329       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12330         ;
12331       else if (unformat (i, "server"))
12332         is_server = 1;
12333       else if (unformat (i, "gso"))
12334         enable_gso = 1;
12335       else if (unformat (i, "packed"))
12336         enable_packed = 1;
12337       else
12338         break;
12339     }
12340
12341   if (sw_if_index_set == 0)
12342     {
12343       errmsg ("missing sw_if_index or interface name");
12344       return -99;
12345     }
12346
12347   if (file_name_set == 0)
12348     {
12349       errmsg ("missing socket file name");
12350       return -99;
12351     }
12352
12353   if (vec_len (file_name) > 255)
12354     {
12355       errmsg ("socket file name too long");
12356       return -99;
12357     }
12358   vec_add1 (file_name, 0);
12359
12360   M (MODIFY_VHOST_USER_IF, mp);
12361
12362   mp->sw_if_index = ntohl (sw_if_index);
12363   mp->is_server = is_server;
12364   mp->enable_gso = enable_gso;
12365   mp->enable_packed = enable_packed;
12366   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12367   vec_free (file_name);
12368   if (custom_dev_instance != ~0)
12369     {
12370       mp->renumber = 1;
12371       mp->custom_dev_instance = ntohl (custom_dev_instance);
12372     }
12373
12374   S (mp);
12375   W (ret);
12376   return ret;
12377 }
12378
12379 static int
12380 api_delete_vhost_user_if (vat_main_t * vam)
12381 {
12382   unformat_input_t *i = vam->input;
12383   vl_api_delete_vhost_user_if_t *mp;
12384   u32 sw_if_index = ~0;
12385   u8 sw_if_index_set = 0;
12386   int ret;
12387
12388   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12389     {
12390       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12391         sw_if_index_set = 1;
12392       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12393         sw_if_index_set = 1;
12394       else
12395         break;
12396     }
12397
12398   if (sw_if_index_set == 0)
12399     {
12400       errmsg ("missing sw_if_index or interface name");
12401       return -99;
12402     }
12403
12404
12405   M (DELETE_VHOST_USER_IF, mp);
12406
12407   mp->sw_if_index = ntohl (sw_if_index);
12408
12409   S (mp);
12410   W (ret);
12411   return ret;
12412 }
12413
12414 static void vl_api_sw_interface_vhost_user_details_t_handler
12415   (vl_api_sw_interface_vhost_user_details_t * mp)
12416 {
12417   vat_main_t *vam = &vat_main;
12418   u64 features;
12419
12420   features =
12421     clib_net_to_host_u32 (mp->features_first_32) | ((u64)
12422                                                     clib_net_to_host_u32
12423                                                     (mp->features_last_32) <<
12424                                                     32);
12425
12426   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
12427          (char *) mp->interface_name,
12428          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
12429          features, mp->is_server,
12430          ntohl (mp->num_regions), (char *) mp->sock_filename);
12431   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
12432 }
12433
12434 static void vl_api_sw_interface_vhost_user_details_t_handler_json
12435   (vl_api_sw_interface_vhost_user_details_t * mp)
12436 {
12437   vat_main_t *vam = &vat_main;
12438   vat_json_node_t *node = NULL;
12439
12440   if (VAT_JSON_ARRAY != vam->json_tree.type)
12441     {
12442       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12443       vat_json_init_array (&vam->json_tree);
12444     }
12445   node = vat_json_array_add (&vam->json_tree);
12446
12447   vat_json_init_object (node);
12448   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12449   vat_json_object_add_string_copy (node, "interface_name",
12450                                    mp->interface_name);
12451   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
12452                             ntohl (mp->virtio_net_hdr_sz));
12453   vat_json_object_add_uint (node, "features_first_32",
12454                             clib_net_to_host_u32 (mp->features_first_32));
12455   vat_json_object_add_uint (node, "features_last_32",
12456                             clib_net_to_host_u32 (mp->features_last_32));
12457   vat_json_object_add_uint (node, "is_server", mp->is_server);
12458   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
12459   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
12460   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
12461 }
12462
12463 static int
12464 api_sw_interface_vhost_user_dump (vat_main_t * vam)
12465 {
12466   unformat_input_t *i = vam->input;
12467   vl_api_sw_interface_vhost_user_dump_t *mp;
12468   vl_api_control_ping_t *mp_ping;
12469   int ret;
12470   u32 sw_if_index = ~0;
12471
12472   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12473     {
12474       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12475         ;
12476       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12477         ;
12478       else
12479         break;
12480     }
12481
12482   print (vam->ofp,
12483          "Interface name            idx hdr_sz features server regions filename");
12484
12485   /* Get list of vhost-user interfaces */
12486   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
12487   mp->sw_if_index = ntohl (sw_if_index);
12488   S (mp);
12489
12490   /* Use a control ping for synchronization */
12491   MPING (CONTROL_PING, mp_ping);
12492   S (mp_ping);
12493
12494   W (ret);
12495   return ret;
12496 }
12497
12498 static int
12499 api_show_version (vat_main_t * vam)
12500 {
12501   vl_api_show_version_t *mp;
12502   int ret;
12503
12504   M (SHOW_VERSION, mp);
12505
12506   S (mp);
12507   W (ret);
12508   return ret;
12509 }
12510
12511
12512 static int
12513 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
12514 {
12515   unformat_input_t *line_input = vam->input;
12516   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
12517   ip46_address_t local, remote;
12518   u8 is_add = 1;
12519   u8 local_set = 0;
12520   u8 remote_set = 0;
12521   u8 grp_set = 0;
12522   u32 mcast_sw_if_index = ~0;
12523   u32 encap_vrf_id = 0;
12524   u32 decap_vrf_id = 0;
12525   u8 protocol = ~0;
12526   u32 vni;
12527   u8 vni_set = 0;
12528   int ret;
12529
12530   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12531     {
12532       if (unformat (line_input, "del"))
12533         is_add = 0;
12534       else if (unformat (line_input, "local %U",
12535                          unformat_ip46_address, &local))
12536         {
12537           local_set = 1;
12538         }
12539       else if (unformat (line_input, "remote %U",
12540                          unformat_ip46_address, &remote))
12541         {
12542           remote_set = 1;
12543         }
12544       else if (unformat (line_input, "group %U %U",
12545                          unformat_ip46_address, &remote,
12546                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12547         {
12548           grp_set = remote_set = 1;
12549         }
12550       else if (unformat (line_input, "group %U",
12551                          unformat_ip46_address, &remote))
12552         {
12553           grp_set = remote_set = 1;
12554         }
12555       else
12556         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12557         ;
12558       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12559         ;
12560       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
12561         ;
12562       else if (unformat (line_input, "vni %d", &vni))
12563         vni_set = 1;
12564       else if (unformat (line_input, "next-ip4"))
12565         protocol = 1;
12566       else if (unformat (line_input, "next-ip6"))
12567         protocol = 2;
12568       else if (unformat (line_input, "next-ethernet"))
12569         protocol = 3;
12570       else if (unformat (line_input, "next-nsh"))
12571         protocol = 4;
12572       else
12573         {
12574           errmsg ("parse error '%U'", format_unformat_error, line_input);
12575           return -99;
12576         }
12577     }
12578
12579   if (local_set == 0)
12580     {
12581       errmsg ("tunnel local address not specified");
12582       return -99;
12583     }
12584   if (remote_set == 0)
12585     {
12586       errmsg ("tunnel remote address not specified");
12587       return -99;
12588     }
12589   if (grp_set && mcast_sw_if_index == ~0)
12590     {
12591       errmsg ("tunnel nonexistent multicast device");
12592       return -99;
12593     }
12594   if (ip46_address_is_ip4 (&local) != ip46_address_is_ip4 (&remote))
12595     {
12596       errmsg ("both IPv4 and IPv6 addresses specified");
12597       return -99;
12598     }
12599
12600   if (vni_set == 0)
12601     {
12602       errmsg ("vni not specified");
12603       return -99;
12604     }
12605
12606   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
12607
12608   ip_address_encode (&local,
12609                      ip46_address_is_ip4 (&local) ? IP46_TYPE_IP4 :
12610                      IP46_TYPE_IP6, &mp->local);
12611   ip_address_encode (&remote,
12612                      ip46_address_is_ip4 (&remote) ? IP46_TYPE_IP4 :
12613                      IP46_TYPE_IP6, &mp->remote);
12614
12615   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12616   mp->encap_vrf_id = ntohl (encap_vrf_id);
12617   mp->decap_vrf_id = ntohl (decap_vrf_id);
12618   mp->protocol = protocol;
12619   mp->vni = ntohl (vni);
12620   mp->is_add = is_add;
12621
12622   S (mp);
12623   W (ret);
12624   return ret;
12625 }
12626
12627 static void vl_api_vxlan_gpe_tunnel_details_t_handler
12628   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12629 {
12630   vat_main_t *vam = &vat_main;
12631   ip46_address_t local, remote;
12632
12633   ip_address_decode (&mp->local, &local);
12634   ip_address_decode (&mp->remote, &remote);
12635
12636   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
12637          ntohl (mp->sw_if_index),
12638          format_ip46_address, &local, IP46_TYPE_ANY,
12639          format_ip46_address, &remote, IP46_TYPE_ANY,
12640          ntohl (mp->vni), mp->protocol,
12641          ntohl (mp->mcast_sw_if_index),
12642          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
12643 }
12644
12645
12646 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
12647   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12648 {
12649   vat_main_t *vam = &vat_main;
12650   vat_json_node_t *node = NULL;
12651   struct in_addr ip4;
12652   struct in6_addr ip6;
12653   ip46_address_t local, remote;
12654
12655   ip_address_decode (&mp->local, &local);
12656   ip_address_decode (&mp->remote, &remote);
12657
12658   if (VAT_JSON_ARRAY != vam->json_tree.type)
12659     {
12660       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12661       vat_json_init_array (&vam->json_tree);
12662     }
12663   node = vat_json_array_add (&vam->json_tree);
12664
12665   vat_json_init_object (node);
12666   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12667   if (ip46_address_is_ip4 (&local))
12668     {
12669       clib_memcpy (&ip4, &local.ip4, sizeof (ip4));
12670       vat_json_object_add_ip4 (node, "local", ip4);
12671       clib_memcpy (&ip4, &remote.ip4, sizeof (ip4));
12672       vat_json_object_add_ip4 (node, "remote", ip4);
12673     }
12674   else
12675     {
12676       clib_memcpy (&ip6, &local.ip6, sizeof (ip6));
12677       vat_json_object_add_ip6 (node, "local", ip6);
12678       clib_memcpy (&ip6, &remote.ip6, sizeof (ip6));
12679       vat_json_object_add_ip6 (node, "remote", ip6);
12680     }
12681   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12682   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
12683   vat_json_object_add_uint (node, "mcast_sw_if_index",
12684                             ntohl (mp->mcast_sw_if_index));
12685   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12686   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
12687   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12688 }
12689
12690 static int
12691 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
12692 {
12693   unformat_input_t *i = vam->input;
12694   vl_api_vxlan_gpe_tunnel_dump_t *mp;
12695   vl_api_control_ping_t *mp_ping;
12696   u32 sw_if_index;
12697   u8 sw_if_index_set = 0;
12698   int ret;
12699
12700   /* Parse args required to build the message */
12701   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12702     {
12703       if (unformat (i, "sw_if_index %d", &sw_if_index))
12704         sw_if_index_set = 1;
12705       else
12706         break;
12707     }
12708
12709   if (sw_if_index_set == 0)
12710     {
12711       sw_if_index = ~0;
12712     }
12713
12714   if (!vam->json_output)
12715     {
12716       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
12717              "sw_if_index", "local", "remote", "vni",
12718              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
12719     }
12720
12721   /* Get list of vxlan-tunnel interfaces */
12722   M (VXLAN_GPE_TUNNEL_DUMP, mp);
12723
12724   mp->sw_if_index = htonl (sw_if_index);
12725
12726   S (mp);
12727
12728   /* Use a control ping for synchronization */
12729   MPING (CONTROL_PING, mp_ping);
12730   S (mp_ping);
12731
12732   W (ret);
12733   return ret;
12734 }
12735
12736 static void vl_api_l2_fib_table_details_t_handler
12737   (vl_api_l2_fib_table_details_t * mp)
12738 {
12739   vat_main_t *vam = &vat_main;
12740
12741   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
12742          "       %d       %d     %d",
12743          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
12744          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
12745          mp->bvi_mac);
12746 }
12747
12748 static void vl_api_l2_fib_table_details_t_handler_json
12749   (vl_api_l2_fib_table_details_t * mp)
12750 {
12751   vat_main_t *vam = &vat_main;
12752   vat_json_node_t *node = NULL;
12753
12754   if (VAT_JSON_ARRAY != vam->json_tree.type)
12755     {
12756       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12757       vat_json_init_array (&vam->json_tree);
12758     }
12759   node = vat_json_array_add (&vam->json_tree);
12760
12761   vat_json_init_object (node);
12762   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
12763   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
12764   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12765   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
12766   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
12767   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
12768 }
12769
12770 static int
12771 api_l2_fib_table_dump (vat_main_t * vam)
12772 {
12773   unformat_input_t *i = vam->input;
12774   vl_api_l2_fib_table_dump_t *mp;
12775   vl_api_control_ping_t *mp_ping;
12776   u32 bd_id;
12777   u8 bd_id_set = 0;
12778   int ret;
12779
12780   /* Parse args required to build the message */
12781   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12782     {
12783       if (unformat (i, "bd_id %d", &bd_id))
12784         bd_id_set = 1;
12785       else
12786         break;
12787     }
12788
12789   if (bd_id_set == 0)
12790     {
12791       errmsg ("missing bridge domain");
12792       return -99;
12793     }
12794
12795   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
12796
12797   /* Get list of l2 fib entries */
12798   M (L2_FIB_TABLE_DUMP, mp);
12799
12800   mp->bd_id = ntohl (bd_id);
12801   S (mp);
12802
12803   /* Use a control ping for synchronization */
12804   MPING (CONTROL_PING, mp_ping);
12805   S (mp_ping);
12806
12807   W (ret);
12808   return ret;
12809 }
12810
12811
12812 static int
12813 api_interface_name_renumber (vat_main_t * vam)
12814 {
12815   unformat_input_t *line_input = vam->input;
12816   vl_api_interface_name_renumber_t *mp;
12817   u32 sw_if_index = ~0;
12818   u32 new_show_dev_instance = ~0;
12819   int ret;
12820
12821   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12822     {
12823       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
12824                     &sw_if_index))
12825         ;
12826       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12827         ;
12828       else if (unformat (line_input, "new_show_dev_instance %d",
12829                          &new_show_dev_instance))
12830         ;
12831       else
12832         break;
12833     }
12834
12835   if (sw_if_index == ~0)
12836     {
12837       errmsg ("missing interface name or sw_if_index");
12838       return -99;
12839     }
12840
12841   if (new_show_dev_instance == ~0)
12842     {
12843       errmsg ("missing new_show_dev_instance");
12844       return -99;
12845     }
12846
12847   M (INTERFACE_NAME_RENUMBER, mp);
12848
12849   mp->sw_if_index = ntohl (sw_if_index);
12850   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
12851
12852   S (mp);
12853   W (ret);
12854   return ret;
12855 }
12856
12857 static int
12858 api_want_l2_macs_events (vat_main_t * vam)
12859 {
12860   unformat_input_t *line_input = vam->input;
12861   vl_api_want_l2_macs_events_t *mp;
12862   u8 enable_disable = 1;
12863   u32 scan_delay = 0;
12864   u32 max_macs_in_event = 0;
12865   u32 learn_limit = 0;
12866   int ret;
12867
12868   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12869     {
12870       if (unformat (line_input, "learn-limit %d", &learn_limit))
12871         ;
12872       else if (unformat (line_input, "scan-delay %d", &scan_delay))
12873         ;
12874       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
12875         ;
12876       else if (unformat (line_input, "disable"))
12877         enable_disable = 0;
12878       else
12879         break;
12880     }
12881
12882   M (WANT_L2_MACS_EVENTS, mp);
12883   mp->enable_disable = enable_disable;
12884   mp->pid = htonl (getpid ());
12885   mp->learn_limit = htonl (learn_limit);
12886   mp->scan_delay = (u8) scan_delay;
12887   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
12888   S (mp);
12889   W (ret);
12890   return ret;
12891 }
12892
12893 static int
12894 api_input_acl_set_interface (vat_main_t * vam)
12895 {
12896   unformat_input_t *i = vam->input;
12897   vl_api_input_acl_set_interface_t *mp;
12898   u32 sw_if_index;
12899   int sw_if_index_set;
12900   u32 ip4_table_index = ~0;
12901   u32 ip6_table_index = ~0;
12902   u32 l2_table_index = ~0;
12903   u8 is_add = 1;
12904   int ret;
12905
12906   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12907     {
12908       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12909         sw_if_index_set = 1;
12910       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12911         sw_if_index_set = 1;
12912       else if (unformat (i, "del"))
12913         is_add = 0;
12914       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12915         ;
12916       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12917         ;
12918       else if (unformat (i, "l2-table %d", &l2_table_index))
12919         ;
12920       else
12921         {
12922           clib_warning ("parse error '%U'", format_unformat_error, i);
12923           return -99;
12924         }
12925     }
12926
12927   if (sw_if_index_set == 0)
12928     {
12929       errmsg ("missing interface name or sw_if_index");
12930       return -99;
12931     }
12932
12933   M (INPUT_ACL_SET_INTERFACE, mp);
12934
12935   mp->sw_if_index = ntohl (sw_if_index);
12936   mp->ip4_table_index = ntohl (ip4_table_index);
12937   mp->ip6_table_index = ntohl (ip6_table_index);
12938   mp->l2_table_index = ntohl (l2_table_index);
12939   mp->is_add = is_add;
12940
12941   S (mp);
12942   W (ret);
12943   return ret;
12944 }
12945
12946 static int
12947 api_output_acl_set_interface (vat_main_t * vam)
12948 {
12949   unformat_input_t *i = vam->input;
12950   vl_api_output_acl_set_interface_t *mp;
12951   u32 sw_if_index;
12952   int sw_if_index_set;
12953   u32 ip4_table_index = ~0;
12954   u32 ip6_table_index = ~0;
12955   u32 l2_table_index = ~0;
12956   u8 is_add = 1;
12957   int ret;
12958
12959   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12960     {
12961       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12962         sw_if_index_set = 1;
12963       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12964         sw_if_index_set = 1;
12965       else if (unformat (i, "del"))
12966         is_add = 0;
12967       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12968         ;
12969       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12970         ;
12971       else if (unformat (i, "l2-table %d", &l2_table_index))
12972         ;
12973       else
12974         {
12975           clib_warning ("parse error '%U'", format_unformat_error, i);
12976           return -99;
12977         }
12978     }
12979
12980   if (sw_if_index_set == 0)
12981     {
12982       errmsg ("missing interface name or sw_if_index");
12983       return -99;
12984     }
12985
12986   M (OUTPUT_ACL_SET_INTERFACE, mp);
12987
12988   mp->sw_if_index = ntohl (sw_if_index);
12989   mp->ip4_table_index = ntohl (ip4_table_index);
12990   mp->ip6_table_index = ntohl (ip6_table_index);
12991   mp->l2_table_index = ntohl (l2_table_index);
12992   mp->is_add = is_add;
12993
12994   S (mp);
12995   W (ret);
12996   return ret;
12997 }
12998
12999 static int
13000 api_ip_address_dump (vat_main_t * vam)
13001 {
13002   unformat_input_t *i = vam->input;
13003   vl_api_ip_address_dump_t *mp;
13004   vl_api_control_ping_t *mp_ping;
13005   u32 sw_if_index = ~0;
13006   u8 sw_if_index_set = 0;
13007   u8 ipv4_set = 0;
13008   u8 ipv6_set = 0;
13009   int ret;
13010
13011   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13012     {
13013       if (unformat (i, "sw_if_index %d", &sw_if_index))
13014         sw_if_index_set = 1;
13015       else
13016         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13017         sw_if_index_set = 1;
13018       else if (unformat (i, "ipv4"))
13019         ipv4_set = 1;
13020       else if (unformat (i, "ipv6"))
13021         ipv6_set = 1;
13022       else
13023         break;
13024     }
13025
13026   if (ipv4_set && ipv6_set)
13027     {
13028       errmsg ("ipv4 and ipv6 flags cannot be both set");
13029       return -99;
13030     }
13031
13032   if ((!ipv4_set) && (!ipv6_set))
13033     {
13034       errmsg ("no ipv4 nor ipv6 flag set");
13035       return -99;
13036     }
13037
13038   if (sw_if_index_set == 0)
13039     {
13040       errmsg ("missing interface name or sw_if_index");
13041       return -99;
13042     }
13043
13044   vam->current_sw_if_index = sw_if_index;
13045   vam->is_ipv6 = ipv6_set;
13046
13047   M (IP_ADDRESS_DUMP, mp);
13048   mp->sw_if_index = ntohl (sw_if_index);
13049   mp->is_ipv6 = ipv6_set;
13050   S (mp);
13051
13052   /* Use a control ping for synchronization */
13053   MPING (CONTROL_PING, mp_ping);
13054   S (mp_ping);
13055
13056   W (ret);
13057   return ret;
13058 }
13059
13060 static int
13061 api_ip_dump (vat_main_t * vam)
13062 {
13063   vl_api_ip_dump_t *mp;
13064   vl_api_control_ping_t *mp_ping;
13065   unformat_input_t *in = vam->input;
13066   int ipv4_set = 0;
13067   int ipv6_set = 0;
13068   int is_ipv6;
13069   int i;
13070   int ret;
13071
13072   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13073     {
13074       if (unformat (in, "ipv4"))
13075         ipv4_set = 1;
13076       else if (unformat (in, "ipv6"))
13077         ipv6_set = 1;
13078       else
13079         break;
13080     }
13081
13082   if (ipv4_set && ipv6_set)
13083     {
13084       errmsg ("ipv4 and ipv6 flags cannot be both set");
13085       return -99;
13086     }
13087
13088   if ((!ipv4_set) && (!ipv6_set))
13089     {
13090       errmsg ("no ipv4 nor ipv6 flag set");
13091       return -99;
13092     }
13093
13094   is_ipv6 = ipv6_set;
13095   vam->is_ipv6 = is_ipv6;
13096
13097   /* free old data */
13098   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13099     {
13100       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13101     }
13102   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13103
13104   M (IP_DUMP, mp);
13105   mp->is_ipv6 = ipv6_set;
13106   S (mp);
13107
13108   /* Use a control ping for synchronization */
13109   MPING (CONTROL_PING, mp_ping);
13110   S (mp_ping);
13111
13112   W (ret);
13113   return ret;
13114 }
13115
13116 static int
13117 api_ipsec_spd_add_del (vat_main_t * vam)
13118 {
13119   unformat_input_t *i = vam->input;
13120   vl_api_ipsec_spd_add_del_t *mp;
13121   u32 spd_id = ~0;
13122   u8 is_add = 1;
13123   int ret;
13124
13125   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13126     {
13127       if (unformat (i, "spd_id %d", &spd_id))
13128         ;
13129       else if (unformat (i, "del"))
13130         is_add = 0;
13131       else
13132         {
13133           clib_warning ("parse error '%U'", format_unformat_error, i);
13134           return -99;
13135         }
13136     }
13137   if (spd_id == ~0)
13138     {
13139       errmsg ("spd_id must be set");
13140       return -99;
13141     }
13142
13143   M (IPSEC_SPD_ADD_DEL, mp);
13144
13145   mp->spd_id = ntohl (spd_id);
13146   mp->is_add = is_add;
13147
13148   S (mp);
13149   W (ret);
13150   return ret;
13151 }
13152
13153 static int
13154 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13155 {
13156   unformat_input_t *i = vam->input;
13157   vl_api_ipsec_interface_add_del_spd_t *mp;
13158   u32 sw_if_index;
13159   u8 sw_if_index_set = 0;
13160   u32 spd_id = (u32) ~ 0;
13161   u8 is_add = 1;
13162   int ret;
13163
13164   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13165     {
13166       if (unformat (i, "del"))
13167         is_add = 0;
13168       else if (unformat (i, "spd_id %d", &spd_id))
13169         ;
13170       else
13171         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13172         sw_if_index_set = 1;
13173       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13174         sw_if_index_set = 1;
13175       else
13176         {
13177           clib_warning ("parse error '%U'", format_unformat_error, i);
13178           return -99;
13179         }
13180
13181     }
13182
13183   if (spd_id == (u32) ~ 0)
13184     {
13185       errmsg ("spd_id must be set");
13186       return -99;
13187     }
13188
13189   if (sw_if_index_set == 0)
13190     {
13191       errmsg ("missing interface name or sw_if_index");
13192       return -99;
13193     }
13194
13195   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
13196
13197   mp->spd_id = ntohl (spd_id);
13198   mp->sw_if_index = ntohl (sw_if_index);
13199   mp->is_add = is_add;
13200
13201   S (mp);
13202   W (ret);
13203   return ret;
13204 }
13205
13206 static int
13207 api_ipsec_spd_entry_add_del (vat_main_t * vam)
13208 {
13209   unformat_input_t *i = vam->input;
13210   vl_api_ipsec_spd_entry_add_del_t *mp;
13211   u8 is_add = 1, is_outbound = 0;
13212   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
13213   i32 priority = 0;
13214   u32 rport_start = 0, rport_stop = (u32) ~ 0;
13215   u32 lport_start = 0, lport_stop = (u32) ~ 0;
13216   vl_api_address_t laddr_start = { }, laddr_stop =
13217   {
13218   }, raddr_start =
13219   {
13220   }, raddr_stop =
13221   {
13222   };
13223   int ret;
13224
13225   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13226     {
13227       if (unformat (i, "del"))
13228         is_add = 0;
13229       if (unformat (i, "outbound"))
13230         is_outbound = 1;
13231       if (unformat (i, "inbound"))
13232         is_outbound = 0;
13233       else if (unformat (i, "spd_id %d", &spd_id))
13234         ;
13235       else if (unformat (i, "sa_id %d", &sa_id))
13236         ;
13237       else if (unformat (i, "priority %d", &priority))
13238         ;
13239       else if (unformat (i, "protocol %d", &protocol))
13240         ;
13241       else if (unformat (i, "lport_start %d", &lport_start))
13242         ;
13243       else if (unformat (i, "lport_stop %d", &lport_stop))
13244         ;
13245       else if (unformat (i, "rport_start %d", &rport_start))
13246         ;
13247       else if (unformat (i, "rport_stop %d", &rport_stop))
13248         ;
13249       else if (unformat (i, "laddr_start %U",
13250                          unformat_vl_api_address, &laddr_start))
13251         ;
13252       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
13253                          &laddr_stop))
13254         ;
13255       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
13256                          &raddr_start))
13257         ;
13258       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
13259                          &raddr_stop))
13260         ;
13261       else
13262         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
13263         {
13264           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
13265             {
13266               clib_warning ("unsupported action: 'resolve'");
13267               return -99;
13268             }
13269         }
13270       else
13271         {
13272           clib_warning ("parse error '%U'", format_unformat_error, i);
13273           return -99;
13274         }
13275
13276     }
13277
13278   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
13279
13280   mp->is_add = is_add;
13281
13282   mp->entry.spd_id = ntohl (spd_id);
13283   mp->entry.priority = ntohl (priority);
13284   mp->entry.is_outbound = is_outbound;
13285
13286   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
13287                sizeof (vl_api_address_t));
13288   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
13289                sizeof (vl_api_address_t));
13290   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
13291                sizeof (vl_api_address_t));
13292   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
13293                sizeof (vl_api_address_t));
13294
13295   mp->entry.protocol = (u8) protocol;
13296   mp->entry.local_port_start = ntohs ((u16) lport_start);
13297   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
13298   mp->entry.remote_port_start = ntohs ((u16) rport_start);
13299   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
13300   mp->entry.policy = (u8) policy;
13301   mp->entry.sa_id = ntohl (sa_id);
13302
13303   S (mp);
13304   W (ret);
13305   return ret;
13306 }
13307
13308 static int
13309 api_ipsec_sad_entry_add_del (vat_main_t * vam)
13310 {
13311   unformat_input_t *i = vam->input;
13312   vl_api_ipsec_sad_entry_add_del_t *mp;
13313   u32 sad_id = 0, spi = 0;
13314   u8 *ck = 0, *ik = 0;
13315   u8 is_add = 1;
13316
13317   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
13318   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
13319   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
13320   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
13321   vl_api_address_t tun_src, tun_dst;
13322   int ret;
13323
13324   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13325     {
13326       if (unformat (i, "del"))
13327         is_add = 0;
13328       else if (unformat (i, "sad_id %d", &sad_id))
13329         ;
13330       else if (unformat (i, "spi %d", &spi))
13331         ;
13332       else if (unformat (i, "esp"))
13333         protocol = IPSEC_API_PROTO_ESP;
13334       else
13335         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
13336         {
13337           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13338           if (ADDRESS_IP6 == tun_src.af)
13339             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13340         }
13341       else
13342         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
13343         {
13344           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13345           if (ADDRESS_IP6 == tun_src.af)
13346             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13347         }
13348       else
13349         if (unformat (i, "crypto_alg %U",
13350                       unformat_ipsec_api_crypto_alg, &crypto_alg))
13351         ;
13352       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13353         ;
13354       else if (unformat (i, "integ_alg %U",
13355                          unformat_ipsec_api_integ_alg, &integ_alg))
13356         ;
13357       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13358         ;
13359       else
13360         {
13361           clib_warning ("parse error '%U'", format_unformat_error, i);
13362           return -99;
13363         }
13364
13365     }
13366
13367   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
13368
13369   mp->is_add = is_add;
13370   mp->entry.sad_id = ntohl (sad_id);
13371   mp->entry.protocol = protocol;
13372   mp->entry.spi = ntohl (spi);
13373   mp->entry.flags = flags;
13374
13375   mp->entry.crypto_algorithm = crypto_alg;
13376   mp->entry.integrity_algorithm = integ_alg;
13377   mp->entry.crypto_key.length = vec_len (ck);
13378   mp->entry.integrity_key.length = vec_len (ik);
13379
13380   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
13381     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
13382
13383   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
13384     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
13385
13386   if (ck)
13387     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
13388   if (ik)
13389     clib_memcpy (mp->entry.integrity_key.data, ik,
13390                  mp->entry.integrity_key.length);
13391
13392   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
13393     {
13394       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
13395                    sizeof (mp->entry.tunnel_src));
13396       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
13397                    sizeof (mp->entry.tunnel_dst));
13398     }
13399
13400   S (mp);
13401   W (ret);
13402   return ret;
13403 }
13404
13405 static int
13406 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
13407 {
13408   unformat_input_t *i = vam->input;
13409   vl_api_ipsec_tunnel_if_add_del_t *mp;
13410   u32 local_spi = 0, remote_spi = 0;
13411   u32 crypto_alg = 0, integ_alg = 0;
13412   u8 *lck = NULL, *rck = NULL;
13413   u8 *lik = NULL, *rik = NULL;
13414   vl_api_address_t local_ip = { 0 };
13415   vl_api_address_t remote_ip = { 0 };
13416   f64 before = 0;
13417   u8 is_add = 1;
13418   u8 esn = 0;
13419   u8 anti_replay = 0;
13420   u8 renumber = 0;
13421   u32 instance = ~0;
13422   u32 count = 1, jj;
13423   int ret = -1;
13424
13425   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13426     {
13427       if (unformat (i, "del"))
13428         is_add = 0;
13429       else if (unformat (i, "esn"))
13430         esn = 1;
13431       else if (unformat (i, "anti-replay"))
13432         anti_replay = 1;
13433       else if (unformat (i, "count %d", &count))
13434         ;
13435       else if (unformat (i, "local_spi %d", &local_spi))
13436         ;
13437       else if (unformat (i, "remote_spi %d", &remote_spi))
13438         ;
13439       else
13440         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
13441         ;
13442       else
13443         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
13444         ;
13445       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
13446         ;
13447       else
13448         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
13449         ;
13450       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
13451         ;
13452       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
13453         ;
13454       else
13455         if (unformat
13456             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
13457         {
13458           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
13459             {
13460               errmsg ("unsupported crypto-alg: '%U'\n",
13461                       format_ipsec_crypto_alg, crypto_alg);
13462               return -99;
13463             }
13464         }
13465       else
13466         if (unformat
13467             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
13468         {
13469           if (integ_alg >= IPSEC_INTEG_N_ALG)
13470             {
13471               errmsg ("unsupported integ-alg: '%U'\n",
13472                       format_ipsec_integ_alg, integ_alg);
13473               return -99;
13474             }
13475         }
13476       else if (unformat (i, "instance %u", &instance))
13477         renumber = 1;
13478       else
13479         {
13480           errmsg ("parse error '%U'\n", format_unformat_error, i);
13481           return -99;
13482         }
13483     }
13484
13485   if (count > 1)
13486     {
13487       /* Turn on async mode */
13488       vam->async_mode = 1;
13489       vam->async_errors = 0;
13490       before = vat_time_now (vam);
13491     }
13492
13493   for (jj = 0; jj < count; jj++)
13494     {
13495       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
13496
13497       mp->is_add = is_add;
13498       mp->esn = esn;
13499       mp->anti_replay = anti_replay;
13500
13501       if (jj > 0)
13502         increment_address (&remote_ip);
13503
13504       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
13505       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
13506
13507       mp->local_spi = htonl (local_spi + jj);
13508       mp->remote_spi = htonl (remote_spi + jj);
13509       mp->crypto_alg = (u8) crypto_alg;
13510
13511       mp->local_crypto_key_len = 0;
13512       if (lck)
13513         {
13514           mp->local_crypto_key_len = vec_len (lck);
13515           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
13516             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
13517           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
13518         }
13519
13520       mp->remote_crypto_key_len = 0;
13521       if (rck)
13522         {
13523           mp->remote_crypto_key_len = vec_len (rck);
13524           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
13525             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
13526           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
13527         }
13528
13529       mp->integ_alg = (u8) integ_alg;
13530
13531       mp->local_integ_key_len = 0;
13532       if (lik)
13533         {
13534           mp->local_integ_key_len = vec_len (lik);
13535           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
13536             mp->local_integ_key_len = sizeof (mp->local_integ_key);
13537           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
13538         }
13539
13540       mp->remote_integ_key_len = 0;
13541       if (rik)
13542         {
13543           mp->remote_integ_key_len = vec_len (rik);
13544           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
13545             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
13546           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
13547         }
13548
13549       if (renumber)
13550         {
13551           mp->renumber = renumber;
13552           mp->show_instance = ntohl (instance);
13553         }
13554       S (mp);
13555     }
13556
13557   /* When testing multiple add/del ops, use a control-ping to sync */
13558   if (count > 1)
13559     {
13560       vl_api_control_ping_t *mp_ping;
13561       f64 after;
13562       f64 timeout;
13563
13564       /* Shut off async mode */
13565       vam->async_mode = 0;
13566
13567       MPING (CONTROL_PING, mp_ping);
13568       S (mp_ping);
13569
13570       timeout = vat_time_now (vam) + 1.0;
13571       while (vat_time_now (vam) < timeout)
13572         if (vam->result_ready == 1)
13573           goto out;
13574       vam->retval = -99;
13575
13576     out:
13577       if (vam->retval == -99)
13578         errmsg ("timeout");
13579
13580       if (vam->async_errors > 0)
13581         {
13582           errmsg ("%d asynchronous errors", vam->async_errors);
13583           vam->retval = -98;
13584         }
13585       vam->async_errors = 0;
13586       after = vat_time_now (vam);
13587
13588       /* slim chance, but we might have eaten SIGTERM on the first iteration */
13589       if (jj > 0)
13590         count = jj;
13591
13592       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
13593              count, after - before, count / (after - before));
13594     }
13595   else
13596     {
13597       /* Wait for a reply... */
13598       W (ret);
13599       return ret;
13600     }
13601
13602   return ret;
13603 }
13604
13605 static void
13606 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
13607 {
13608   vat_main_t *vam = &vat_main;
13609
13610   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
13611          "crypto_key %U integ_alg %u integ_key %U flags %x "
13612          "tunnel_src_addr %U tunnel_dst_addr %U "
13613          "salt %u seq_outbound %lu last_seq_inbound %lu "
13614          "replay_window %lu stat_index %u\n",
13615          ntohl (mp->entry.sad_id),
13616          ntohl (mp->sw_if_index),
13617          ntohl (mp->entry.spi),
13618          ntohl (mp->entry.protocol),
13619          ntohl (mp->entry.crypto_algorithm),
13620          format_hex_bytes, mp->entry.crypto_key.data,
13621          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
13622          format_hex_bytes, mp->entry.integrity_key.data,
13623          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
13624          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
13625          &mp->entry.tunnel_dst, ntohl (mp->salt),
13626          clib_net_to_host_u64 (mp->seq_outbound),
13627          clib_net_to_host_u64 (mp->last_seq_inbound),
13628          clib_net_to_host_u64 (mp->replay_window), ntohl (mp->stat_index));
13629 }
13630
13631 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
13632 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
13633
13634 static void vl_api_ipsec_sa_details_t_handler_json
13635   (vl_api_ipsec_sa_details_t * mp)
13636 {
13637   vat_main_t *vam = &vat_main;
13638   vat_json_node_t *node = NULL;
13639   vl_api_ipsec_sad_flags_t flags;
13640
13641   if (VAT_JSON_ARRAY != vam->json_tree.type)
13642     {
13643       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13644       vat_json_init_array (&vam->json_tree);
13645     }
13646   node = vat_json_array_add (&vam->json_tree);
13647
13648   vat_json_init_object (node);
13649   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
13650   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13651   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
13652   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
13653   vat_json_object_add_uint (node, "crypto_alg",
13654                             ntohl (mp->entry.crypto_algorithm));
13655   vat_json_object_add_uint (node, "integ_alg",
13656                             ntohl (mp->entry.integrity_algorithm));
13657   flags = ntohl (mp->entry.flags);
13658   vat_json_object_add_uint (node, "use_esn",
13659                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
13660   vat_json_object_add_uint (node, "use_anti_replay",
13661                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
13662   vat_json_object_add_uint (node, "is_tunnel",
13663                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
13664   vat_json_object_add_uint (node, "is_tunnel_ip6",
13665                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
13666   vat_json_object_add_uint (node, "udp_encap",
13667                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
13668   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
13669                              mp->entry.crypto_key.length);
13670   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
13671                              mp->entry.integrity_key.length);
13672   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
13673   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
13674   vat_json_object_add_uint (node, "replay_window",
13675                             clib_net_to_host_u64 (mp->replay_window));
13676   vat_json_object_add_uint (node, "stat_index", ntohl (mp->stat_index));
13677 }
13678
13679 static int
13680 api_ipsec_sa_dump (vat_main_t * vam)
13681 {
13682   unformat_input_t *i = vam->input;
13683   vl_api_ipsec_sa_dump_t *mp;
13684   vl_api_control_ping_t *mp_ping;
13685   u32 sa_id = ~0;
13686   int ret;
13687
13688   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13689     {
13690       if (unformat (i, "sa_id %d", &sa_id))
13691         ;
13692       else
13693         {
13694           clib_warning ("parse error '%U'", format_unformat_error, i);
13695           return -99;
13696         }
13697     }
13698
13699   M (IPSEC_SA_DUMP, mp);
13700
13701   mp->sa_id = ntohl (sa_id);
13702
13703   S (mp);
13704
13705   /* Use a control ping for synchronization */
13706   M (CONTROL_PING, mp_ping);
13707   S (mp_ping);
13708
13709   W (ret);
13710   return ret;
13711 }
13712
13713 static int
13714 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
13715 {
13716   unformat_input_t *i = vam->input;
13717   vl_api_ipsec_tunnel_if_set_sa_t *mp;
13718   u32 sw_if_index = ~0;
13719   u32 sa_id = ~0;
13720   u8 is_outbound = (u8) ~ 0;
13721   int ret;
13722
13723   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13724     {
13725       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13726         ;
13727       else if (unformat (i, "sa_id %d", &sa_id))
13728         ;
13729       else if (unformat (i, "outbound"))
13730         is_outbound = 1;
13731       else if (unformat (i, "inbound"))
13732         is_outbound = 0;
13733       else
13734         {
13735           clib_warning ("parse error '%U'", format_unformat_error, i);
13736           return -99;
13737         }
13738     }
13739
13740   if (sw_if_index == ~0)
13741     {
13742       errmsg ("interface must be specified");
13743       return -99;
13744     }
13745
13746   if (sa_id == ~0)
13747     {
13748       errmsg ("SA ID must be specified");
13749       return -99;
13750     }
13751
13752   M (IPSEC_TUNNEL_IF_SET_SA, mp);
13753
13754   mp->sw_if_index = htonl (sw_if_index);
13755   mp->sa_id = htonl (sa_id);
13756   mp->is_outbound = is_outbound;
13757
13758   S (mp);
13759   W (ret);
13760
13761   return ret;
13762 }
13763
13764 static int
13765 api_get_first_msg_id (vat_main_t * vam)
13766 {
13767   vl_api_get_first_msg_id_t *mp;
13768   unformat_input_t *i = vam->input;
13769   u8 *name;
13770   u8 name_set = 0;
13771   int ret;
13772
13773   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13774     {
13775       if (unformat (i, "client %s", &name))
13776         name_set = 1;
13777       else
13778         break;
13779     }
13780
13781   if (name_set == 0)
13782     {
13783       errmsg ("missing client name");
13784       return -99;
13785     }
13786   vec_add1 (name, 0);
13787
13788   if (vec_len (name) > 63)
13789     {
13790       errmsg ("client name too long");
13791       return -99;
13792     }
13793
13794   M (GET_FIRST_MSG_ID, mp);
13795   clib_memcpy (mp->name, name, vec_len (name));
13796   S (mp);
13797   W (ret);
13798   return ret;
13799 }
13800
13801 static int
13802 api_cop_interface_enable_disable (vat_main_t * vam)
13803 {
13804   unformat_input_t *line_input = vam->input;
13805   vl_api_cop_interface_enable_disable_t *mp;
13806   u32 sw_if_index = ~0;
13807   u8 enable_disable = 1;
13808   int ret;
13809
13810   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13811     {
13812       if (unformat (line_input, "disable"))
13813         enable_disable = 0;
13814       if (unformat (line_input, "enable"))
13815         enable_disable = 1;
13816       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13817                          vam, &sw_if_index))
13818         ;
13819       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13820         ;
13821       else
13822         break;
13823     }
13824
13825   if (sw_if_index == ~0)
13826     {
13827       errmsg ("missing interface name or sw_if_index");
13828       return -99;
13829     }
13830
13831   /* Construct the API message */
13832   M (COP_INTERFACE_ENABLE_DISABLE, mp);
13833   mp->sw_if_index = ntohl (sw_if_index);
13834   mp->enable_disable = enable_disable;
13835
13836   /* send it... */
13837   S (mp);
13838   /* Wait for the reply */
13839   W (ret);
13840   return ret;
13841 }
13842
13843 static int
13844 api_cop_whitelist_enable_disable (vat_main_t * vam)
13845 {
13846   unformat_input_t *line_input = vam->input;
13847   vl_api_cop_whitelist_enable_disable_t *mp;
13848   u32 sw_if_index = ~0;
13849   u8 ip4 = 0, ip6 = 0, default_cop = 0;
13850   u32 fib_id = 0;
13851   int ret;
13852
13853   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13854     {
13855       if (unformat (line_input, "ip4"))
13856         ip4 = 1;
13857       else if (unformat (line_input, "ip6"))
13858         ip6 = 1;
13859       else if (unformat (line_input, "default"))
13860         default_cop = 1;
13861       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13862                          vam, &sw_if_index))
13863         ;
13864       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13865         ;
13866       else if (unformat (line_input, "fib-id %d", &fib_id))
13867         ;
13868       else
13869         break;
13870     }
13871
13872   if (sw_if_index == ~0)
13873     {
13874       errmsg ("missing interface name or sw_if_index");
13875       return -99;
13876     }
13877
13878   /* Construct the API message */
13879   M (COP_WHITELIST_ENABLE_DISABLE, mp);
13880   mp->sw_if_index = ntohl (sw_if_index);
13881   mp->fib_id = ntohl (fib_id);
13882   mp->ip4 = ip4;
13883   mp->ip6 = ip6;
13884   mp->default_cop = default_cop;
13885
13886   /* send it... */
13887   S (mp);
13888   /* Wait for the reply */
13889   W (ret);
13890   return ret;
13891 }
13892
13893 static int
13894 api_get_node_graph (vat_main_t * vam)
13895 {
13896   vl_api_get_node_graph_t *mp;
13897   int ret;
13898
13899   M (GET_NODE_GRAPH, mp);
13900
13901   /* send it... */
13902   S (mp);
13903   /* Wait for the reply */
13904   W (ret);
13905   return ret;
13906 }
13907
13908 /* *INDENT-OFF* */
13909 /** Used for parsing LISP eids */
13910 typedef CLIB_PACKED(struct{
13911   union {
13912           ip46_address_t ip;
13913           mac_address_t mac;
13914           lisp_nsh_api_t nsh;
13915   } addr;
13916   u32 len;       /**< prefix length if IP */
13917   u8 type;      /**< type of eid */
13918 }) lisp_eid_vat_t;
13919 /* *INDENT-ON* */
13920
13921 static uword
13922 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
13923 {
13924   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
13925
13926   clib_memset (a, 0, sizeof (a[0]));
13927
13928   if (unformat (input, "%U/%d", unformat_ip46_address, a->addr.ip, &a->len))
13929     {
13930       a->type = 0;              /* ip prefix type */
13931     }
13932   else if (unformat (input, "%U", unformat_ethernet_address, &a->addr.mac))
13933     {
13934       a->type = 1;              /* mac type */
13935     }
13936   else if (unformat (input, "%U", unformat_nsh_address, a->addr.nsh))
13937     {
13938       a->type = 2;              /* NSH type */
13939       a->addr.nsh.spi = clib_host_to_net_u32 (a->addr.nsh.spi);
13940     }
13941   else
13942     {
13943       return 0;
13944     }
13945
13946   if (a->type == 0)
13947     {
13948       if (ip46_address_is_ip4 (&a->addr.ip))
13949         return a->len > 32 ? 1 : 0;
13950       else
13951         return a->len > 128 ? 1 : 0;
13952     }
13953
13954   return 1;
13955 }
13956
13957 static void
13958 lisp_eid_put_vat (vl_api_eid_t * eid, const lisp_eid_vat_t * vat_eid)
13959 {
13960   eid->type = vat_eid->type;
13961   switch (eid->type)
13962     {
13963     case EID_TYPE_API_PREFIX:
13964       if (ip46_address_is_ip4 (&vat_eid->addr.ip))
13965         {
13966           clib_memcpy (&eid->address.prefix.address.un.ip4,
13967                        &vat_eid->addr.ip.ip4, 4);
13968           eid->address.prefix.address.af = ADDRESS_IP4;
13969           eid->address.prefix.len = vat_eid->len;
13970         }
13971       else
13972         {
13973           clib_memcpy (&eid->address.prefix.address.un.ip6,
13974                        &vat_eid->addr.ip.ip6, 16);
13975           eid->address.prefix.address.af = ADDRESS_IP6;
13976           eid->address.prefix.len = vat_eid->len;
13977         }
13978       return;
13979     case EID_TYPE_API_MAC:
13980       clib_memcpy (&eid->address.mac, &vat_eid->addr.mac,
13981                    sizeof (eid->address.mac));
13982       return;
13983     case EID_TYPE_API_NSH:
13984       clib_memcpy (&eid->address.nsh, &vat_eid->addr.nsh,
13985                    sizeof (eid->address.nsh));
13986       return;
13987     default:
13988       ASSERT (0);
13989       return;
13990     }
13991 }
13992
13993 static int
13994 api_one_add_del_locator_set (vat_main_t * vam)
13995 {
13996   unformat_input_t *input = vam->input;
13997   vl_api_one_add_del_locator_set_t *mp;
13998   u8 is_add = 1;
13999   u8 *locator_set_name = NULL;
14000   u8 locator_set_name_set = 0;
14001   vl_api_local_locator_t locator, *locators = 0;
14002   u32 sw_if_index, priority, weight;
14003   u32 data_len = 0;
14004
14005   int ret;
14006   /* Parse args required to build the message */
14007   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14008     {
14009       if (unformat (input, "del"))
14010         {
14011           is_add = 0;
14012         }
14013       else if (unformat (input, "locator-set %s", &locator_set_name))
14014         {
14015           locator_set_name_set = 1;
14016         }
14017       else if (unformat (input, "sw_if_index %u p %u w %u",
14018                          &sw_if_index, &priority, &weight))
14019         {
14020           locator.sw_if_index = htonl (sw_if_index);
14021           locator.priority = priority;
14022           locator.weight = weight;
14023           vec_add1 (locators, locator);
14024         }
14025       else
14026         if (unformat
14027             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14028              &sw_if_index, &priority, &weight))
14029         {
14030           locator.sw_if_index = htonl (sw_if_index);
14031           locator.priority = priority;
14032           locator.weight = weight;
14033           vec_add1 (locators, locator);
14034         }
14035       else
14036         break;
14037     }
14038
14039   if (locator_set_name_set == 0)
14040     {
14041       errmsg ("missing locator-set name");
14042       vec_free (locators);
14043       return -99;
14044     }
14045
14046   if (vec_len (locator_set_name) > 64)
14047     {
14048       errmsg ("locator-set name too long");
14049       vec_free (locator_set_name);
14050       vec_free (locators);
14051       return -99;
14052     }
14053   vec_add1 (locator_set_name, 0);
14054
14055   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14056
14057   /* Construct the API message */
14058   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14059
14060   mp->is_add = is_add;
14061   clib_memcpy (mp->locator_set_name, locator_set_name,
14062                vec_len (locator_set_name));
14063   vec_free (locator_set_name);
14064
14065   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14066   if (locators)
14067     clib_memcpy (mp->locators, locators, data_len);
14068   vec_free (locators);
14069
14070   /* send it... */
14071   S (mp);
14072
14073   /* Wait for a reply... */
14074   W (ret);
14075   return ret;
14076 }
14077
14078 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14079
14080 static int
14081 api_one_add_del_locator (vat_main_t * vam)
14082 {
14083   unformat_input_t *input = vam->input;
14084   vl_api_one_add_del_locator_t *mp;
14085   u32 tmp_if_index = ~0;
14086   u32 sw_if_index = ~0;
14087   u8 sw_if_index_set = 0;
14088   u8 sw_if_index_if_name_set = 0;
14089   u32 priority = ~0;
14090   u8 priority_set = 0;
14091   u32 weight = ~0;
14092   u8 weight_set = 0;
14093   u8 is_add = 1;
14094   u8 *locator_set_name = NULL;
14095   u8 locator_set_name_set = 0;
14096   int ret;
14097
14098   /* Parse args required to build the message */
14099   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14100     {
14101       if (unformat (input, "del"))
14102         {
14103           is_add = 0;
14104         }
14105       else if (unformat (input, "locator-set %s", &locator_set_name))
14106         {
14107           locator_set_name_set = 1;
14108         }
14109       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14110                          &tmp_if_index))
14111         {
14112           sw_if_index_if_name_set = 1;
14113           sw_if_index = tmp_if_index;
14114         }
14115       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14116         {
14117           sw_if_index_set = 1;
14118           sw_if_index = tmp_if_index;
14119         }
14120       else if (unformat (input, "p %d", &priority))
14121         {
14122           priority_set = 1;
14123         }
14124       else if (unformat (input, "w %d", &weight))
14125         {
14126           weight_set = 1;
14127         }
14128       else
14129         break;
14130     }
14131
14132   if (locator_set_name_set == 0)
14133     {
14134       errmsg ("missing locator-set name");
14135       return -99;
14136     }
14137
14138   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14139     {
14140       errmsg ("missing sw_if_index");
14141       vec_free (locator_set_name);
14142       return -99;
14143     }
14144
14145   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14146     {
14147       errmsg ("cannot use both params interface name and sw_if_index");
14148       vec_free (locator_set_name);
14149       return -99;
14150     }
14151
14152   if (priority_set == 0)
14153     {
14154       errmsg ("missing locator-set priority");
14155       vec_free (locator_set_name);
14156       return -99;
14157     }
14158
14159   if (weight_set == 0)
14160     {
14161       errmsg ("missing locator-set weight");
14162       vec_free (locator_set_name);
14163       return -99;
14164     }
14165
14166   if (vec_len (locator_set_name) > 64)
14167     {
14168       errmsg ("locator-set name too long");
14169       vec_free (locator_set_name);
14170       return -99;
14171     }
14172   vec_add1 (locator_set_name, 0);
14173
14174   /* Construct the API message */
14175   M (ONE_ADD_DEL_LOCATOR, mp);
14176
14177   mp->is_add = is_add;
14178   mp->sw_if_index = ntohl (sw_if_index);
14179   mp->priority = priority;
14180   mp->weight = weight;
14181   clib_memcpy (mp->locator_set_name, locator_set_name,
14182                vec_len (locator_set_name));
14183   vec_free (locator_set_name);
14184
14185   /* send it... */
14186   S (mp);
14187
14188   /* Wait for a reply... */
14189   W (ret);
14190   return ret;
14191 }
14192
14193 #define api_lisp_add_del_locator api_one_add_del_locator
14194
14195 uword
14196 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
14197 {
14198   u32 *key_id = va_arg (*args, u32 *);
14199   u8 *s = 0;
14200
14201   if (unformat (input, "%s", &s))
14202     {
14203       if (!strcmp ((char *) s, "sha1"))
14204         key_id[0] = HMAC_SHA_1_96;
14205       else if (!strcmp ((char *) s, "sha256"))
14206         key_id[0] = HMAC_SHA_256_128;
14207       else
14208         {
14209           clib_warning ("invalid key_id: '%s'", s);
14210           key_id[0] = HMAC_NO_KEY;
14211         }
14212     }
14213   else
14214     return 0;
14215
14216   vec_free (s);
14217   return 1;
14218 }
14219
14220 static int
14221 api_one_add_del_local_eid (vat_main_t * vam)
14222 {
14223   unformat_input_t *input = vam->input;
14224   vl_api_one_add_del_local_eid_t *mp;
14225   u8 is_add = 1;
14226   u8 eid_set = 0;
14227   lisp_eid_vat_t _eid, *eid = &_eid;
14228   u8 *locator_set_name = 0;
14229   u8 locator_set_name_set = 0;
14230   u32 vni = 0;
14231   u16 key_id = 0;
14232   u8 *key = 0;
14233   int ret;
14234
14235   /* Parse args required to build the message */
14236   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14237     {
14238       if (unformat (input, "del"))
14239         {
14240           is_add = 0;
14241         }
14242       else if (unformat (input, "vni %d", &vni))
14243         {
14244           ;
14245         }
14246       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14247         {
14248           eid_set = 1;
14249         }
14250       else if (unformat (input, "locator-set %s", &locator_set_name))
14251         {
14252           locator_set_name_set = 1;
14253         }
14254       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
14255         ;
14256       else if (unformat (input, "secret-key %_%v%_", &key))
14257         ;
14258       else
14259         break;
14260     }
14261
14262   if (locator_set_name_set == 0)
14263     {
14264       errmsg ("missing locator-set name");
14265       return -99;
14266     }
14267
14268   if (0 == eid_set)
14269     {
14270       errmsg ("EID address not set!");
14271       vec_free (locator_set_name);
14272       return -99;
14273     }
14274
14275   if (key && (0 == key_id))
14276     {
14277       errmsg ("invalid key_id!");
14278       return -99;
14279     }
14280
14281   if (vec_len (key) > 64)
14282     {
14283       errmsg ("key too long");
14284       vec_free (key);
14285       return -99;
14286     }
14287
14288   if (vec_len (locator_set_name) > 64)
14289     {
14290       errmsg ("locator-set name too long");
14291       vec_free (locator_set_name);
14292       return -99;
14293     }
14294   vec_add1 (locator_set_name, 0);
14295
14296   /* Construct the API message */
14297   M (ONE_ADD_DEL_LOCAL_EID, mp);
14298
14299   mp->is_add = is_add;
14300   lisp_eid_put_vat (&mp->eid, eid);
14301   mp->vni = clib_host_to_net_u32 (vni);
14302   mp->key.id = key_id;
14303   clib_memcpy (mp->locator_set_name, locator_set_name,
14304                vec_len (locator_set_name));
14305   clib_memcpy (mp->key.key, key, vec_len (key));
14306
14307   vec_free (locator_set_name);
14308   vec_free (key);
14309
14310   /* send it... */
14311   S (mp);
14312
14313   /* Wait for a reply... */
14314   W (ret);
14315   return ret;
14316 }
14317
14318 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
14319
14320 static int
14321 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
14322 {
14323   u32 dp_table = 0, vni = 0;;
14324   unformat_input_t *input = vam->input;
14325   vl_api_gpe_add_del_fwd_entry_t *mp;
14326   u8 is_add = 1;
14327   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
14328   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
14329   u8 rmt_eid_set = 0, lcl_eid_set = 0;
14330   u32 action = ~0, w;
14331   ip4_address_t rmt_rloc4, lcl_rloc4;
14332   ip6_address_t rmt_rloc6, lcl_rloc6;
14333   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
14334   int ret;
14335
14336   clib_memset (&rloc, 0, sizeof (rloc));
14337
14338   /* Parse args required to build the message */
14339   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14340     {
14341       if (unformat (input, "del"))
14342         is_add = 0;
14343       else if (unformat (input, "add"))
14344         is_add = 1;
14345       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
14346         {
14347           rmt_eid_set = 1;
14348         }
14349       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
14350         {
14351           lcl_eid_set = 1;
14352         }
14353       else if (unformat (input, "vrf %d", &dp_table))
14354         ;
14355       else if (unformat (input, "bd %d", &dp_table))
14356         ;
14357       else if (unformat (input, "vni %d", &vni))
14358         ;
14359       else if (unformat (input, "w %d", &w))
14360         {
14361           if (!curr_rloc)
14362             {
14363               errmsg ("No RLOC configured for setting priority/weight!");
14364               return -99;
14365             }
14366           curr_rloc->weight = w;
14367         }
14368       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14369                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14370         {
14371           rloc.addr.af = 0;
14372           clib_memcpy (&rloc.addr.un.ip4, &lcl_rloc4, sizeof (lcl_rloc4));
14373           rloc.weight = 0;
14374           vec_add1 (lcl_locs, rloc);
14375
14376           clib_memcpy (&rloc.addr.un.ip4, &rmt_rloc4, sizeof (rmt_rloc4));
14377           vec_add1 (rmt_locs, rloc);
14378           /* weight saved in rmt loc */
14379           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14380         }
14381       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14382                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14383         {
14384           rloc.addr.af = 1;
14385           clib_memcpy (&rloc.addr.un.ip6, &lcl_rloc6, sizeof (lcl_rloc6));
14386           rloc.weight = 0;
14387           vec_add1 (lcl_locs, rloc);
14388
14389           clib_memcpy (&rloc.addr.un.ip6, &rmt_rloc6, sizeof (rmt_rloc6));
14390           vec_add1 (rmt_locs, rloc);
14391           /* weight saved in rmt loc */
14392           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14393         }
14394       else if (unformat (input, "action %d", &action))
14395         {
14396           ;
14397         }
14398       else
14399         {
14400           clib_warning ("parse error '%U'", format_unformat_error, input);
14401           return -99;
14402         }
14403     }
14404
14405   if (!rmt_eid_set)
14406     {
14407       errmsg ("remote eid addresses not set");
14408       return -99;
14409     }
14410
14411   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14412     {
14413       errmsg ("eid types don't match");
14414       return -99;
14415     }
14416
14417   if (0 == rmt_locs && (u32) ~ 0 == action)
14418     {
14419       errmsg ("action not set for negative mapping");
14420       return -99;
14421     }
14422
14423   /* Construct the API message */
14424   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14425       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
14426
14427   mp->is_add = is_add;
14428   lisp_eid_put_vat (&mp->rmt_eid, rmt_eid);
14429   lisp_eid_put_vat (&mp->lcl_eid, lcl_eid);
14430   mp->dp_table = clib_host_to_net_u32 (dp_table);
14431   mp->vni = clib_host_to_net_u32 (vni);
14432   mp->action = action;
14433
14434   if (0 != rmt_locs && 0 != lcl_locs)
14435     {
14436       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14437       clib_memcpy (mp->locs, lcl_locs,
14438                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
14439
14440       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14441       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14442                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
14443     }
14444   vec_free (lcl_locs);
14445   vec_free (rmt_locs);
14446
14447   /* send it... */
14448   S (mp);
14449
14450   /* Wait for a reply... */
14451   W (ret);
14452   return ret;
14453 }
14454
14455 static int
14456 api_one_add_del_map_server (vat_main_t * vam)
14457 {
14458   unformat_input_t *input = vam->input;
14459   vl_api_one_add_del_map_server_t *mp;
14460   u8 is_add = 1;
14461   u8 ipv4_set = 0;
14462   u8 ipv6_set = 0;
14463   ip4_address_t ipv4;
14464   ip6_address_t ipv6;
14465   int ret;
14466
14467   /* Parse args required to build the message */
14468   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14469     {
14470       if (unformat (input, "del"))
14471         {
14472           is_add = 0;
14473         }
14474       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14475         {
14476           ipv4_set = 1;
14477         }
14478       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14479         {
14480           ipv6_set = 1;
14481         }
14482       else
14483         break;
14484     }
14485
14486   if (ipv4_set && ipv6_set)
14487     {
14488       errmsg ("both eid v4 and v6 addresses set");
14489       return -99;
14490     }
14491
14492   if (!ipv4_set && !ipv6_set)
14493     {
14494       errmsg ("eid addresses not set");
14495       return -99;
14496     }
14497
14498   /* Construct the API message */
14499   M (ONE_ADD_DEL_MAP_SERVER, mp);
14500
14501   mp->is_add = is_add;
14502   if (ipv6_set)
14503     {
14504       mp->ip_address.af = 1;
14505       clib_memcpy (mp->ip_address.un.ip6, &ipv6, sizeof (ipv6));
14506     }
14507   else
14508     {
14509       mp->ip_address.af = 0;
14510       clib_memcpy (mp->ip_address.un.ip4, &ipv4, sizeof (ipv4));
14511     }
14512
14513   /* send it... */
14514   S (mp);
14515
14516   /* Wait for a reply... */
14517   W (ret);
14518   return ret;
14519 }
14520
14521 #define api_lisp_add_del_map_server api_one_add_del_map_server
14522
14523 static int
14524 api_one_add_del_map_resolver (vat_main_t * vam)
14525 {
14526   unformat_input_t *input = vam->input;
14527   vl_api_one_add_del_map_resolver_t *mp;
14528   u8 is_add = 1;
14529   u8 ipv4_set = 0;
14530   u8 ipv6_set = 0;
14531   ip4_address_t ipv4;
14532   ip6_address_t ipv6;
14533   int ret;
14534
14535   /* Parse args required to build the message */
14536   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14537     {
14538       if (unformat (input, "del"))
14539         {
14540           is_add = 0;
14541         }
14542       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14543         {
14544           ipv4_set = 1;
14545         }
14546       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14547         {
14548           ipv6_set = 1;
14549         }
14550       else
14551         break;
14552     }
14553
14554   if (ipv4_set && ipv6_set)
14555     {
14556       errmsg ("both eid v4 and v6 addresses set");
14557       return -99;
14558     }
14559
14560   if (!ipv4_set && !ipv6_set)
14561     {
14562       errmsg ("eid addresses not set");
14563       return -99;
14564     }
14565
14566   /* Construct the API message */
14567   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
14568
14569   mp->is_add = is_add;
14570   if (ipv6_set)
14571     {
14572       mp->ip_address.af = 1;
14573       clib_memcpy (mp->ip_address.un.ip6, &ipv6, sizeof (ipv6));
14574     }
14575   else
14576     {
14577       mp->ip_address.af = 0;
14578       clib_memcpy (mp->ip_address.un.ip6, &ipv4, sizeof (ipv4));
14579     }
14580
14581   /* send it... */
14582   S (mp);
14583
14584   /* Wait for a reply... */
14585   W (ret);
14586   return ret;
14587 }
14588
14589 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14590
14591 static int
14592 api_lisp_gpe_enable_disable (vat_main_t * vam)
14593 {
14594   unformat_input_t *input = vam->input;
14595   vl_api_gpe_enable_disable_t *mp;
14596   u8 is_set = 0;
14597   u8 is_enable = 1;
14598   int ret;
14599
14600   /* Parse args required to build the message */
14601   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14602     {
14603       if (unformat (input, "enable"))
14604         {
14605           is_set = 1;
14606           is_enable = 1;
14607         }
14608       else if (unformat (input, "disable"))
14609         {
14610           is_set = 1;
14611           is_enable = 0;
14612         }
14613       else
14614         break;
14615     }
14616
14617   if (is_set == 0)
14618     {
14619       errmsg ("Value not set");
14620       return -99;
14621     }
14622
14623   /* Construct the API message */
14624   M (GPE_ENABLE_DISABLE, mp);
14625
14626   mp->is_enable = is_enable;
14627
14628   /* send it... */
14629   S (mp);
14630
14631   /* Wait for a reply... */
14632   W (ret);
14633   return ret;
14634 }
14635
14636 static int
14637 api_one_rloc_probe_enable_disable (vat_main_t * vam)
14638 {
14639   unformat_input_t *input = vam->input;
14640   vl_api_one_rloc_probe_enable_disable_t *mp;
14641   u8 is_set = 0;
14642   u8 is_enable = 0;
14643   int ret;
14644
14645   /* Parse args required to build the message */
14646   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14647     {
14648       if (unformat (input, "enable"))
14649         {
14650           is_set = 1;
14651           is_enable = 1;
14652         }
14653       else if (unformat (input, "disable"))
14654         is_set = 1;
14655       else
14656         break;
14657     }
14658
14659   if (!is_set)
14660     {
14661       errmsg ("Value not set");
14662       return -99;
14663     }
14664
14665   /* Construct the API message */
14666   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
14667
14668   mp->is_enable = is_enable;
14669
14670   /* send it... */
14671   S (mp);
14672
14673   /* Wait for a reply... */
14674   W (ret);
14675   return ret;
14676 }
14677
14678 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14679
14680 static int
14681 api_one_map_register_enable_disable (vat_main_t * vam)
14682 {
14683   unformat_input_t *input = vam->input;
14684   vl_api_one_map_register_enable_disable_t *mp;
14685   u8 is_set = 0;
14686   u8 is_enable = 0;
14687   int ret;
14688
14689   /* Parse args required to build the message */
14690   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14691     {
14692       if (unformat (input, "enable"))
14693         {
14694           is_set = 1;
14695           is_enable = 1;
14696         }
14697       else if (unformat (input, "disable"))
14698         is_set = 1;
14699       else
14700         break;
14701     }
14702
14703   if (!is_set)
14704     {
14705       errmsg ("Value not set");
14706       return -99;
14707     }
14708
14709   /* Construct the API message */
14710   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
14711
14712   mp->is_enable = is_enable;
14713
14714   /* send it... */
14715   S (mp);
14716
14717   /* Wait for a reply... */
14718   W (ret);
14719   return ret;
14720 }
14721
14722 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14723
14724 static int
14725 api_one_enable_disable (vat_main_t * vam)
14726 {
14727   unformat_input_t *input = vam->input;
14728   vl_api_one_enable_disable_t *mp;
14729   u8 is_set = 0;
14730   u8 is_enable = 0;
14731   int ret;
14732
14733   /* Parse args required to build the message */
14734   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14735     {
14736       if (unformat (input, "enable"))
14737         {
14738           is_set = 1;
14739           is_enable = 1;
14740         }
14741       else if (unformat (input, "disable"))
14742         {
14743           is_set = 1;
14744         }
14745       else
14746         break;
14747     }
14748
14749   if (!is_set)
14750     {
14751       errmsg ("Value not set");
14752       return -99;
14753     }
14754
14755   /* Construct the API message */
14756   M (ONE_ENABLE_DISABLE, mp);
14757
14758   mp->is_enable = is_enable;
14759
14760   /* send it... */
14761   S (mp);
14762
14763   /* Wait for a reply... */
14764   W (ret);
14765   return ret;
14766 }
14767
14768 #define api_lisp_enable_disable api_one_enable_disable
14769
14770 static int
14771 api_one_enable_disable_xtr_mode (vat_main_t * vam)
14772 {
14773   unformat_input_t *input = vam->input;
14774   vl_api_one_enable_disable_xtr_mode_t *mp;
14775   u8 is_set = 0;
14776   u8 is_enable = 0;
14777   int ret;
14778
14779   /* Parse args required to build the message */
14780   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14781     {
14782       if (unformat (input, "enable"))
14783         {
14784           is_set = 1;
14785           is_enable = 1;
14786         }
14787       else if (unformat (input, "disable"))
14788         {
14789           is_set = 1;
14790         }
14791       else
14792         break;
14793     }
14794
14795   if (!is_set)
14796     {
14797       errmsg ("Value not set");
14798       return -99;
14799     }
14800
14801   /* Construct the API message */
14802   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
14803
14804   mp->is_enable = is_enable;
14805
14806   /* send it... */
14807   S (mp);
14808
14809   /* Wait for a reply... */
14810   W (ret);
14811   return ret;
14812 }
14813
14814 static int
14815 api_one_show_xtr_mode (vat_main_t * vam)
14816 {
14817   vl_api_one_show_xtr_mode_t *mp;
14818   int ret;
14819
14820   /* Construct the API message */
14821   M (ONE_SHOW_XTR_MODE, mp);
14822
14823   /* send it... */
14824   S (mp);
14825
14826   /* Wait for a reply... */
14827   W (ret);
14828   return ret;
14829 }
14830
14831 static int
14832 api_one_enable_disable_pitr_mode (vat_main_t * vam)
14833 {
14834   unformat_input_t *input = vam->input;
14835   vl_api_one_enable_disable_pitr_mode_t *mp;
14836   u8 is_set = 0;
14837   u8 is_enable = 0;
14838   int ret;
14839
14840   /* Parse args required to build the message */
14841   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14842     {
14843       if (unformat (input, "enable"))
14844         {
14845           is_set = 1;
14846           is_enable = 1;
14847         }
14848       else if (unformat (input, "disable"))
14849         {
14850           is_set = 1;
14851         }
14852       else
14853         break;
14854     }
14855
14856   if (!is_set)
14857     {
14858       errmsg ("Value not set");
14859       return -99;
14860     }
14861
14862   /* Construct the API message */
14863   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
14864
14865   mp->is_enable = is_enable;
14866
14867   /* send it... */
14868   S (mp);
14869
14870   /* Wait for a reply... */
14871   W (ret);
14872   return ret;
14873 }
14874
14875 static int
14876 api_one_show_pitr_mode (vat_main_t * vam)
14877 {
14878   vl_api_one_show_pitr_mode_t *mp;
14879   int ret;
14880
14881   /* Construct the API message */
14882   M (ONE_SHOW_PITR_MODE, mp);
14883
14884   /* send it... */
14885   S (mp);
14886
14887   /* Wait for a reply... */
14888   W (ret);
14889   return ret;
14890 }
14891
14892 static int
14893 api_one_enable_disable_petr_mode (vat_main_t * vam)
14894 {
14895   unformat_input_t *input = vam->input;
14896   vl_api_one_enable_disable_petr_mode_t *mp;
14897   u8 is_set = 0;
14898   u8 is_enable = 0;
14899   int ret;
14900
14901   /* Parse args required to build the message */
14902   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14903     {
14904       if (unformat (input, "enable"))
14905         {
14906           is_set = 1;
14907           is_enable = 1;
14908         }
14909       else if (unformat (input, "disable"))
14910         {
14911           is_set = 1;
14912         }
14913       else
14914         break;
14915     }
14916
14917   if (!is_set)
14918     {
14919       errmsg ("Value not set");
14920       return -99;
14921     }
14922
14923   /* Construct the API message */
14924   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
14925
14926   mp->is_enable = is_enable;
14927
14928   /* send it... */
14929   S (mp);
14930
14931   /* Wait for a reply... */
14932   W (ret);
14933   return ret;
14934 }
14935
14936 static int
14937 api_one_show_petr_mode (vat_main_t * vam)
14938 {
14939   vl_api_one_show_petr_mode_t *mp;
14940   int ret;
14941
14942   /* Construct the API message */
14943   M (ONE_SHOW_PETR_MODE, mp);
14944
14945   /* send it... */
14946   S (mp);
14947
14948   /* Wait for a reply... */
14949   W (ret);
14950   return ret;
14951 }
14952
14953 static int
14954 api_show_one_map_register_state (vat_main_t * vam)
14955 {
14956   vl_api_show_one_map_register_state_t *mp;
14957   int ret;
14958
14959   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
14960
14961   /* send */
14962   S (mp);
14963
14964   /* wait for reply */
14965   W (ret);
14966   return ret;
14967 }
14968
14969 #define api_show_lisp_map_register_state api_show_one_map_register_state
14970
14971 static int
14972 api_show_one_rloc_probe_state (vat_main_t * vam)
14973 {
14974   vl_api_show_one_rloc_probe_state_t *mp;
14975   int ret;
14976
14977   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
14978
14979   /* send */
14980   S (mp);
14981
14982   /* wait for reply */
14983   W (ret);
14984   return ret;
14985 }
14986
14987 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
14988
14989 static int
14990 api_one_add_del_ndp_entry (vat_main_t * vam)
14991 {
14992   vl_api_one_add_del_ndp_entry_t *mp;
14993   unformat_input_t *input = vam->input;
14994   u8 is_add = 1;
14995   u8 mac_set = 0;
14996   u8 bd_set = 0;
14997   u8 ip_set = 0;
14998   u8 mac[6] = { 0, };
14999   u8 ip6[16] = { 0, };
15000   u32 bd = ~0;
15001   int ret;
15002
15003   /* Parse args required to build the message */
15004   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15005     {
15006       if (unformat (input, "del"))
15007         is_add = 0;
15008       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15009         mac_set = 1;
15010       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
15011         ip_set = 1;
15012       else if (unformat (input, "bd %d", &bd))
15013         bd_set = 1;
15014       else
15015         {
15016           errmsg ("parse error '%U'", format_unformat_error, input);
15017           return -99;
15018         }
15019     }
15020
15021   if (!bd_set || !ip_set || (!mac_set && is_add))
15022     {
15023       errmsg ("Missing BD, IP or MAC!");
15024       return -99;
15025     }
15026
15027   M (ONE_ADD_DEL_NDP_ENTRY, mp);
15028   mp->is_add = is_add;
15029   clib_memcpy (&mp->entry.mac, mac, 6);
15030   mp->bd = clib_host_to_net_u32 (bd);
15031   clib_memcpy (&mp->entry.ip6, ip6, sizeof (mp->entry.ip6));
15032
15033   /* send */
15034   S (mp);
15035
15036   /* wait for reply */
15037   W (ret);
15038   return ret;
15039 }
15040
15041 static int
15042 api_one_add_del_l2_arp_entry (vat_main_t * vam)
15043 {
15044   vl_api_one_add_del_l2_arp_entry_t *mp;
15045   unformat_input_t *input = vam->input;
15046   u8 is_add = 1;
15047   u8 mac_set = 0;
15048   u8 bd_set = 0;
15049   u8 ip_set = 0;
15050   u8 mac[6] = { 0, };
15051   u32 ip4 = 0, bd = ~0;
15052   int ret;
15053
15054   /* Parse args required to build the message */
15055   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15056     {
15057       if (unformat (input, "del"))
15058         is_add = 0;
15059       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15060         mac_set = 1;
15061       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
15062         ip_set = 1;
15063       else if (unformat (input, "bd %d", &bd))
15064         bd_set = 1;
15065       else
15066         {
15067           errmsg ("parse error '%U'", format_unformat_error, input);
15068           return -99;
15069         }
15070     }
15071
15072   if (!bd_set || !ip_set || (!mac_set && is_add))
15073     {
15074       errmsg ("Missing BD, IP or MAC!");
15075       return -99;
15076     }
15077
15078   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
15079   mp->is_add = is_add;
15080   clib_memcpy (&mp->entry.mac, mac, 6);
15081   mp->bd = clib_host_to_net_u32 (bd);
15082   clib_memcpy (mp->entry.ip4, &ip4, sizeof (mp->entry.ip4));
15083
15084   /* send */
15085   S (mp);
15086
15087   /* wait for reply */
15088   W (ret);
15089   return ret;
15090 }
15091
15092 static int
15093 api_one_ndp_bd_get (vat_main_t * vam)
15094 {
15095   vl_api_one_ndp_bd_get_t *mp;
15096   int ret;
15097
15098   M (ONE_NDP_BD_GET, mp);
15099
15100   /* send */
15101   S (mp);
15102
15103   /* wait for reply */
15104   W (ret);
15105   return ret;
15106 }
15107
15108 static int
15109 api_one_ndp_entries_get (vat_main_t * vam)
15110 {
15111   vl_api_one_ndp_entries_get_t *mp;
15112   unformat_input_t *input = vam->input;
15113   u8 bd_set = 0;
15114   u32 bd = ~0;
15115   int ret;
15116
15117   /* Parse args required to build the message */
15118   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15119     {
15120       if (unformat (input, "bd %d", &bd))
15121         bd_set = 1;
15122       else
15123         {
15124           errmsg ("parse error '%U'", format_unformat_error, input);
15125           return -99;
15126         }
15127     }
15128
15129   if (!bd_set)
15130     {
15131       errmsg ("Expected bridge domain!");
15132       return -99;
15133     }
15134
15135   M (ONE_NDP_ENTRIES_GET, mp);
15136   mp->bd = clib_host_to_net_u32 (bd);
15137
15138   /* send */
15139   S (mp);
15140
15141   /* wait for reply */
15142   W (ret);
15143   return ret;
15144 }
15145
15146 static int
15147 api_one_l2_arp_bd_get (vat_main_t * vam)
15148 {
15149   vl_api_one_l2_arp_bd_get_t *mp;
15150   int ret;
15151
15152   M (ONE_L2_ARP_BD_GET, mp);
15153
15154   /* send */
15155   S (mp);
15156
15157   /* wait for reply */
15158   W (ret);
15159   return ret;
15160 }
15161
15162 static int
15163 api_one_l2_arp_entries_get (vat_main_t * vam)
15164 {
15165   vl_api_one_l2_arp_entries_get_t *mp;
15166   unformat_input_t *input = vam->input;
15167   u8 bd_set = 0;
15168   u32 bd = ~0;
15169   int ret;
15170
15171   /* Parse args required to build the message */
15172   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15173     {
15174       if (unformat (input, "bd %d", &bd))
15175         bd_set = 1;
15176       else
15177         {
15178           errmsg ("parse error '%U'", format_unformat_error, input);
15179           return -99;
15180         }
15181     }
15182
15183   if (!bd_set)
15184     {
15185       errmsg ("Expected bridge domain!");
15186       return -99;
15187     }
15188
15189   M (ONE_L2_ARP_ENTRIES_GET, mp);
15190   mp->bd = clib_host_to_net_u32 (bd);
15191
15192   /* send */
15193   S (mp);
15194
15195   /* wait for reply */
15196   W (ret);
15197   return ret;
15198 }
15199
15200 static int
15201 api_one_stats_enable_disable (vat_main_t * vam)
15202 {
15203   vl_api_one_stats_enable_disable_t *mp;
15204   unformat_input_t *input = vam->input;
15205   u8 is_set = 0;
15206   u8 is_enable = 0;
15207   int ret;
15208
15209   /* Parse args required to build the message */
15210   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15211     {
15212       if (unformat (input, "enable"))
15213         {
15214           is_set = 1;
15215           is_enable = 1;
15216         }
15217       else if (unformat (input, "disable"))
15218         {
15219           is_set = 1;
15220         }
15221       else
15222         break;
15223     }
15224
15225   if (!is_set)
15226     {
15227       errmsg ("Value not set");
15228       return -99;
15229     }
15230
15231   M (ONE_STATS_ENABLE_DISABLE, mp);
15232   mp->is_enable = is_enable;
15233
15234   /* send */
15235   S (mp);
15236
15237   /* wait for reply */
15238   W (ret);
15239   return ret;
15240 }
15241
15242 static int
15243 api_show_one_stats_enable_disable (vat_main_t * vam)
15244 {
15245   vl_api_show_one_stats_enable_disable_t *mp;
15246   int ret;
15247
15248   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
15249
15250   /* send */
15251   S (mp);
15252
15253   /* wait for reply */
15254   W (ret);
15255   return ret;
15256 }
15257
15258 static int
15259 api_show_one_map_request_mode (vat_main_t * vam)
15260 {
15261   vl_api_show_one_map_request_mode_t *mp;
15262   int ret;
15263
15264   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
15265
15266   /* send */
15267   S (mp);
15268
15269   /* wait for reply */
15270   W (ret);
15271   return ret;
15272 }
15273
15274 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
15275
15276 static int
15277 api_one_map_request_mode (vat_main_t * vam)
15278 {
15279   unformat_input_t *input = vam->input;
15280   vl_api_one_map_request_mode_t *mp;
15281   u8 mode = 0;
15282   int ret;
15283
15284   /* Parse args required to build the message */
15285   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15286     {
15287       if (unformat (input, "dst-only"))
15288         mode = 0;
15289       else if (unformat (input, "src-dst"))
15290         mode = 1;
15291       else
15292         {
15293           errmsg ("parse error '%U'", format_unformat_error, input);
15294           return -99;
15295         }
15296     }
15297
15298   M (ONE_MAP_REQUEST_MODE, mp);
15299
15300   mp->mode = mode;
15301
15302   /* send */
15303   S (mp);
15304
15305   /* wait for reply */
15306   W (ret);
15307   return ret;
15308 }
15309
15310 #define api_lisp_map_request_mode api_one_map_request_mode
15311
15312 /**
15313  * Enable/disable ONE proxy ITR.
15314  *
15315  * @param vam vpp API test context
15316  * @return return code
15317  */
15318 static int
15319 api_one_pitr_set_locator_set (vat_main_t * vam)
15320 {
15321   u8 ls_name_set = 0;
15322   unformat_input_t *input = vam->input;
15323   vl_api_one_pitr_set_locator_set_t *mp;
15324   u8 is_add = 1;
15325   u8 *ls_name = 0;
15326   int ret;
15327
15328   /* Parse args required to build the message */
15329   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15330     {
15331       if (unformat (input, "del"))
15332         is_add = 0;
15333       else if (unformat (input, "locator-set %s", &ls_name))
15334         ls_name_set = 1;
15335       else
15336         {
15337           errmsg ("parse error '%U'", format_unformat_error, input);
15338           return -99;
15339         }
15340     }
15341
15342   if (!ls_name_set)
15343     {
15344       errmsg ("locator-set name not set!");
15345       return -99;
15346     }
15347
15348   M (ONE_PITR_SET_LOCATOR_SET, mp);
15349
15350   mp->is_add = is_add;
15351   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15352   vec_free (ls_name);
15353
15354   /* send */
15355   S (mp);
15356
15357   /* wait for reply */
15358   W (ret);
15359   return ret;
15360 }
15361
15362 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
15363
15364 static int
15365 api_one_nsh_set_locator_set (vat_main_t * vam)
15366 {
15367   u8 ls_name_set = 0;
15368   unformat_input_t *input = vam->input;
15369   vl_api_one_nsh_set_locator_set_t *mp;
15370   u8 is_add = 1;
15371   u8 *ls_name = 0;
15372   int ret;
15373
15374   /* Parse args required to build the message */
15375   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15376     {
15377       if (unformat (input, "del"))
15378         is_add = 0;
15379       else if (unformat (input, "ls %s", &ls_name))
15380         ls_name_set = 1;
15381       else
15382         {
15383           errmsg ("parse error '%U'", format_unformat_error, input);
15384           return -99;
15385         }
15386     }
15387
15388   if (!ls_name_set && is_add)
15389     {
15390       errmsg ("locator-set name not set!");
15391       return -99;
15392     }
15393
15394   M (ONE_NSH_SET_LOCATOR_SET, mp);
15395
15396   mp->is_add = is_add;
15397   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15398   vec_free (ls_name);
15399
15400   /* send */
15401   S (mp);
15402
15403   /* wait for reply */
15404   W (ret);
15405   return ret;
15406 }
15407
15408 static int
15409 api_show_one_pitr (vat_main_t * vam)
15410 {
15411   vl_api_show_one_pitr_t *mp;
15412   int ret;
15413
15414   if (!vam->json_output)
15415     {
15416       print (vam->ofp, "%=20s", "lisp status:");
15417     }
15418
15419   M (SHOW_ONE_PITR, mp);
15420   /* send it... */
15421   S (mp);
15422
15423   /* Wait for a reply... */
15424   W (ret);
15425   return ret;
15426 }
15427
15428 #define api_show_lisp_pitr api_show_one_pitr
15429
15430 static int
15431 api_one_use_petr (vat_main_t * vam)
15432 {
15433   unformat_input_t *input = vam->input;
15434   vl_api_one_use_petr_t *mp;
15435   u8 is_add = 0;
15436   ip_address_t ip;
15437   int ret;
15438
15439   clib_memset (&ip, 0, sizeof (ip));
15440
15441   /* Parse args required to build the message */
15442   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15443     {
15444       if (unformat (input, "disable"))
15445         is_add = 0;
15446       else
15447         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
15448         {
15449           is_add = 1;
15450           ip_addr_version (&ip) = AF_IP4;
15451         }
15452       else
15453         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
15454         {
15455           is_add = 1;
15456           ip_addr_version (&ip) = AF_IP6;
15457         }
15458       else
15459         {
15460           errmsg ("parse error '%U'", format_unformat_error, input);
15461           return -99;
15462         }
15463     }
15464
15465   M (ONE_USE_PETR, mp);
15466
15467   mp->is_add = is_add;
15468   if (is_add)
15469     {
15470       mp->ip_address.af = ip_addr_version (&ip) == AF_IP4 ? 0 : 1;
15471       if (mp->ip_address.af)
15472         clib_memcpy (mp->ip_address.un.ip6, &ip, 16);
15473       else
15474         clib_memcpy (mp->ip_address.un.ip4, &ip, 4);
15475     }
15476
15477   /* send */
15478   S (mp);
15479
15480   /* wait for reply */
15481   W (ret);
15482   return ret;
15483 }
15484
15485 #define api_lisp_use_petr api_one_use_petr
15486
15487 static int
15488 api_show_one_nsh_mapping (vat_main_t * vam)
15489 {
15490   vl_api_show_one_use_petr_t *mp;
15491   int ret;
15492
15493   if (!vam->json_output)
15494     {
15495       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
15496     }
15497
15498   M (SHOW_ONE_NSH_MAPPING, mp);
15499   /* send it... */
15500   S (mp);
15501
15502   /* Wait for a reply... */
15503   W (ret);
15504   return ret;
15505 }
15506
15507 static int
15508 api_show_one_use_petr (vat_main_t * vam)
15509 {
15510   vl_api_show_one_use_petr_t *mp;
15511   int ret;
15512
15513   if (!vam->json_output)
15514     {
15515       print (vam->ofp, "%=20s", "Proxy-ETR status:");
15516     }
15517
15518   M (SHOW_ONE_USE_PETR, mp);
15519   /* send it... */
15520   S (mp);
15521
15522   /* Wait for a reply... */
15523   W (ret);
15524   return ret;
15525 }
15526
15527 #define api_show_lisp_use_petr api_show_one_use_petr
15528
15529 /**
15530  * Add/delete mapping between vni and vrf
15531  */
15532 static int
15533 api_one_eid_table_add_del_map (vat_main_t * vam)
15534 {
15535   unformat_input_t *input = vam->input;
15536   vl_api_one_eid_table_add_del_map_t *mp;
15537   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
15538   u32 vni, vrf, bd_index;
15539   int ret;
15540
15541   /* Parse args required to build the message */
15542   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15543     {
15544       if (unformat (input, "del"))
15545         is_add = 0;
15546       else if (unformat (input, "vrf %d", &vrf))
15547         vrf_set = 1;
15548       else if (unformat (input, "bd_index %d", &bd_index))
15549         bd_index_set = 1;
15550       else if (unformat (input, "vni %d", &vni))
15551         vni_set = 1;
15552       else
15553         break;
15554     }
15555
15556   if (!vni_set || (!vrf_set && !bd_index_set))
15557     {
15558       errmsg ("missing arguments!");
15559       return -99;
15560     }
15561
15562   if (vrf_set && bd_index_set)
15563     {
15564       errmsg ("error: both vrf and bd entered!");
15565       return -99;
15566     }
15567
15568   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
15569
15570   mp->is_add = is_add;
15571   mp->vni = htonl (vni);
15572   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
15573   mp->is_l2 = bd_index_set;
15574
15575   /* send */
15576   S (mp);
15577
15578   /* wait for reply */
15579   W (ret);
15580   return ret;
15581 }
15582
15583 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
15584
15585 uword
15586 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
15587 {
15588   u32 *action = va_arg (*args, u32 *);
15589   u8 *s = 0;
15590
15591   if (unformat (input, "%s", &s))
15592     {
15593       if (!strcmp ((char *) s, "no-action"))
15594         action[0] = 0;
15595       else if (!strcmp ((char *) s, "natively-forward"))
15596         action[0] = 1;
15597       else if (!strcmp ((char *) s, "send-map-request"))
15598         action[0] = 2;
15599       else if (!strcmp ((char *) s, "drop"))
15600         action[0] = 3;
15601       else
15602         {
15603           clib_warning ("invalid action: '%s'", s);
15604           action[0] = 3;
15605         }
15606     }
15607   else
15608     return 0;
15609
15610   vec_free (s);
15611   return 1;
15612 }
15613
15614 /**
15615  * Add/del remote mapping to/from ONE control plane
15616  *
15617  * @param vam vpp API test context
15618  * @return return code
15619  */
15620 static int
15621 api_one_add_del_remote_mapping (vat_main_t * vam)
15622 {
15623   unformat_input_t *input = vam->input;
15624   vl_api_one_add_del_remote_mapping_t *mp;
15625   u32 vni = 0;
15626   lisp_eid_vat_t _eid, *eid = &_eid;
15627   lisp_eid_vat_t _seid, *seid = &_seid;
15628   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
15629   u32 action = ~0, p, w, data_len;
15630   ip4_address_t rloc4;
15631   ip6_address_t rloc6;
15632   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
15633   int ret;
15634
15635   clib_memset (&rloc, 0, sizeof (rloc));
15636
15637   /* Parse args required to build the message */
15638   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15639     {
15640       if (unformat (input, "del-all"))
15641         {
15642           del_all = 1;
15643         }
15644       else if (unformat (input, "del"))
15645         {
15646           is_add = 0;
15647         }
15648       else if (unformat (input, "add"))
15649         {
15650           is_add = 1;
15651         }
15652       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15653         {
15654           eid_set = 1;
15655         }
15656       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
15657         {
15658           seid_set = 1;
15659         }
15660       else if (unformat (input, "vni %d", &vni))
15661         {
15662           ;
15663         }
15664       else if (unformat (input, "p %d w %d", &p, &w))
15665         {
15666           if (!curr_rloc)
15667             {
15668               errmsg ("No RLOC configured for setting priority/weight!");
15669               return -99;
15670             }
15671           curr_rloc->priority = p;
15672           curr_rloc->weight = w;
15673         }
15674       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
15675         {
15676           rloc.ip_address.af = 0;
15677           clib_memcpy (&rloc.ip_address.un.ip6, &rloc6, sizeof (rloc6));
15678           vec_add1 (rlocs, rloc);
15679           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15680         }
15681       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
15682         {
15683           rloc.ip_address.af = 1;
15684           clib_memcpy (&rloc.ip_address.un.ip4, &rloc4, sizeof (rloc4));
15685           vec_add1 (rlocs, rloc);
15686           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15687         }
15688       else if (unformat (input, "action %U",
15689                          unformat_negative_mapping_action, &action))
15690         {
15691           ;
15692         }
15693       else
15694         {
15695           clib_warning ("parse error '%U'", format_unformat_error, input);
15696           return -99;
15697         }
15698     }
15699
15700   if (0 == eid_set)
15701     {
15702       errmsg ("missing params!");
15703       return -99;
15704     }
15705
15706   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
15707     {
15708       errmsg ("no action set for negative map-reply!");
15709       return -99;
15710     }
15711
15712   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
15713
15714   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
15715   mp->is_add = is_add;
15716   mp->vni = htonl (vni);
15717   mp->action = (u8) action;
15718   mp->is_src_dst = seid_set;
15719   mp->del_all = del_all;
15720   lisp_eid_put_vat (&mp->deid, eid);
15721   lisp_eid_put_vat (&mp->seid, seid);
15722
15723   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
15724   clib_memcpy (mp->rlocs, rlocs, data_len);
15725   vec_free (rlocs);
15726
15727   /* send it... */
15728   S (mp);
15729
15730   /* Wait for a reply... */
15731   W (ret);
15732   return ret;
15733 }
15734
15735 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
15736
15737 /**
15738  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
15739  * forwarding entries in data-plane accordingly.
15740  *
15741  * @param vam vpp API test context
15742  * @return return code
15743  */
15744 static int
15745 api_one_add_del_adjacency (vat_main_t * vam)
15746 {
15747   unformat_input_t *input = vam->input;
15748   vl_api_one_add_del_adjacency_t *mp;
15749   u32 vni = 0;
15750   u8 is_add = 1;
15751   int ret;
15752   lisp_eid_vat_t leid, reid;
15753
15754   leid.type = reid.type = (u8) ~ 0;
15755
15756   /* Parse args required to build the message */
15757   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15758     {
15759       if (unformat (input, "del"))
15760         {
15761           is_add = 0;
15762         }
15763       else if (unformat (input, "add"))
15764         {
15765           is_add = 1;
15766         }
15767       else if (unformat (input, "reid %U/%d", unformat_ip46_address,
15768                          &reid.addr.ip, &reid.len))
15769         {
15770           reid.type = 0;        /* ipv4 */
15771         }
15772       else if (unformat (input, "reid %U", unformat_ethernet_address,
15773                          &reid.addr.mac))
15774         {
15775           reid.type = 1;        /* mac */
15776         }
15777       else if (unformat (input, "leid %U/%d", unformat_ip46_address,
15778                          &leid.addr.ip, &leid.len))
15779         {
15780           leid.type = 0;        /* ipv4 */
15781         }
15782       else if (unformat (input, "leid %U", unformat_ethernet_address,
15783                          &leid.addr.mac))
15784         {
15785           leid.type = 1;        /* mac */
15786         }
15787       else if (unformat (input, "vni %d", &vni))
15788         {
15789           ;
15790         }
15791       else
15792         {
15793           errmsg ("parse error '%U'", format_unformat_error, input);
15794           return -99;
15795         }
15796     }
15797
15798   if ((u8) ~ 0 == reid.type)
15799     {
15800       errmsg ("missing params!");
15801       return -99;
15802     }
15803
15804   if (leid.type != reid.type)
15805     {
15806       errmsg ("remote and local EIDs are of different types!");
15807       return -99;
15808     }
15809
15810   M (ONE_ADD_DEL_ADJACENCY, mp);
15811   mp->is_add = is_add;
15812   mp->vni = htonl (vni);
15813   lisp_eid_put_vat (&mp->leid, &leid);
15814   lisp_eid_put_vat (&mp->reid, &reid);
15815
15816   /* send it... */
15817   S (mp);
15818
15819   /* Wait for a reply... */
15820   W (ret);
15821   return ret;
15822 }
15823
15824 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
15825
15826 uword
15827 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
15828 {
15829   u32 *mode = va_arg (*args, u32 *);
15830
15831   if (unformat (input, "lisp"))
15832     *mode = 0;
15833   else if (unformat (input, "vxlan"))
15834     *mode = 1;
15835   else
15836     return 0;
15837
15838   return 1;
15839 }
15840
15841 static int
15842 api_gpe_get_encap_mode (vat_main_t * vam)
15843 {
15844   vl_api_gpe_get_encap_mode_t *mp;
15845   int ret;
15846
15847   /* Construct the API message */
15848   M (GPE_GET_ENCAP_MODE, mp);
15849
15850   /* send it... */
15851   S (mp);
15852
15853   /* Wait for a reply... */
15854   W (ret);
15855   return ret;
15856 }
15857
15858 static int
15859 api_gpe_set_encap_mode (vat_main_t * vam)
15860 {
15861   unformat_input_t *input = vam->input;
15862   vl_api_gpe_set_encap_mode_t *mp;
15863   int ret;
15864   u32 mode = 0;
15865
15866   /* Parse args required to build the message */
15867   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15868     {
15869       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
15870         ;
15871       else
15872         break;
15873     }
15874
15875   /* Construct the API message */
15876   M (GPE_SET_ENCAP_MODE, mp);
15877
15878   mp->is_vxlan = mode;
15879
15880   /* send it... */
15881   S (mp);
15882
15883   /* Wait for a reply... */
15884   W (ret);
15885   return ret;
15886 }
15887
15888 static int
15889 api_lisp_gpe_add_del_iface (vat_main_t * vam)
15890 {
15891   unformat_input_t *input = vam->input;
15892   vl_api_gpe_add_del_iface_t *mp;
15893   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
15894   u32 dp_table = 0, vni = 0;
15895   int ret;
15896
15897   /* Parse args required to build the message */
15898   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15899     {
15900       if (unformat (input, "up"))
15901         {
15902           action_set = 1;
15903           is_add = 1;
15904         }
15905       else if (unformat (input, "down"))
15906         {
15907           action_set = 1;
15908           is_add = 0;
15909         }
15910       else if (unformat (input, "table_id %d", &dp_table))
15911         {
15912           dp_table_set = 1;
15913         }
15914       else if (unformat (input, "bd_id %d", &dp_table))
15915         {
15916           dp_table_set = 1;
15917           is_l2 = 1;
15918         }
15919       else if (unformat (input, "vni %d", &vni))
15920         {
15921           vni_set = 1;
15922         }
15923       else
15924         break;
15925     }
15926
15927   if (action_set == 0)
15928     {
15929       errmsg ("Action not set");
15930       return -99;
15931     }
15932   if (dp_table_set == 0 || vni_set == 0)
15933     {
15934       errmsg ("vni and dp_table must be set");
15935       return -99;
15936     }
15937
15938   /* Construct the API message */
15939   M (GPE_ADD_DEL_IFACE, mp);
15940
15941   mp->is_add = is_add;
15942   mp->dp_table = clib_host_to_net_u32 (dp_table);
15943   mp->is_l2 = is_l2;
15944   mp->vni = clib_host_to_net_u32 (vni);
15945
15946   /* send it... */
15947   S (mp);
15948
15949   /* Wait for a reply... */
15950   W (ret);
15951   return ret;
15952 }
15953
15954 static int
15955 api_one_map_register_fallback_threshold (vat_main_t * vam)
15956 {
15957   unformat_input_t *input = vam->input;
15958   vl_api_one_map_register_fallback_threshold_t *mp;
15959   u32 value = 0;
15960   u8 is_set = 0;
15961   int ret;
15962
15963   /* Parse args required to build the message */
15964   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15965     {
15966       if (unformat (input, "%u", &value))
15967         is_set = 1;
15968       else
15969         {
15970           clib_warning ("parse error '%U'", format_unformat_error, input);
15971           return -99;
15972         }
15973     }
15974
15975   if (!is_set)
15976     {
15977       errmsg ("fallback threshold value is missing!");
15978       return -99;
15979     }
15980
15981   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
15982   mp->value = clib_host_to_net_u32 (value);
15983
15984   /* send it... */
15985   S (mp);
15986
15987   /* Wait for a reply... */
15988   W (ret);
15989   return ret;
15990 }
15991
15992 static int
15993 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
15994 {
15995   vl_api_show_one_map_register_fallback_threshold_t *mp;
15996   int ret;
15997
15998   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
15999
16000   /* send it... */
16001   S (mp);
16002
16003   /* Wait for a reply... */
16004   W (ret);
16005   return ret;
16006 }
16007
16008 uword
16009 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
16010 {
16011   u32 *proto = va_arg (*args, u32 *);
16012
16013   if (unformat (input, "udp"))
16014     *proto = 1;
16015   else if (unformat (input, "api"))
16016     *proto = 2;
16017   else
16018     return 0;
16019
16020   return 1;
16021 }
16022
16023 static int
16024 api_one_set_transport_protocol (vat_main_t * vam)
16025 {
16026   unformat_input_t *input = vam->input;
16027   vl_api_one_set_transport_protocol_t *mp;
16028   u8 is_set = 0;
16029   u32 protocol = 0;
16030   int ret;
16031
16032   /* Parse args required to build the message */
16033   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16034     {
16035       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
16036         is_set = 1;
16037       else
16038         {
16039           clib_warning ("parse error '%U'", format_unformat_error, input);
16040           return -99;
16041         }
16042     }
16043
16044   if (!is_set)
16045     {
16046       errmsg ("Transport protocol missing!");
16047       return -99;
16048     }
16049
16050   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
16051   mp->protocol = (u8) protocol;
16052
16053   /* send it... */
16054   S (mp);
16055
16056   /* Wait for a reply... */
16057   W (ret);
16058   return ret;
16059 }
16060
16061 static int
16062 api_one_get_transport_protocol (vat_main_t * vam)
16063 {
16064   vl_api_one_get_transport_protocol_t *mp;
16065   int ret;
16066
16067   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
16068
16069   /* send it... */
16070   S (mp);
16071
16072   /* Wait for a reply... */
16073   W (ret);
16074   return ret;
16075 }
16076
16077 static int
16078 api_one_map_register_set_ttl (vat_main_t * vam)
16079 {
16080   unformat_input_t *input = vam->input;
16081   vl_api_one_map_register_set_ttl_t *mp;
16082   u32 ttl = 0;
16083   u8 is_set = 0;
16084   int ret;
16085
16086   /* Parse args required to build the message */
16087   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16088     {
16089       if (unformat (input, "%u", &ttl))
16090         is_set = 1;
16091       else
16092         {
16093           clib_warning ("parse error '%U'", format_unformat_error, input);
16094           return -99;
16095         }
16096     }
16097
16098   if (!is_set)
16099     {
16100       errmsg ("TTL value missing!");
16101       return -99;
16102     }
16103
16104   M (ONE_MAP_REGISTER_SET_TTL, mp);
16105   mp->ttl = clib_host_to_net_u32 (ttl);
16106
16107   /* send it... */
16108   S (mp);
16109
16110   /* Wait for a reply... */
16111   W (ret);
16112   return ret;
16113 }
16114
16115 static int
16116 api_show_one_map_register_ttl (vat_main_t * vam)
16117 {
16118   vl_api_show_one_map_register_ttl_t *mp;
16119   int ret;
16120
16121   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
16122
16123   /* send it... */
16124   S (mp);
16125
16126   /* Wait for a reply... */
16127   W (ret);
16128   return ret;
16129 }
16130
16131 /**
16132  * Add/del map request itr rlocs from ONE control plane and updates
16133  *
16134  * @param vam vpp API test context
16135  * @return return code
16136  */
16137 static int
16138 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
16139 {
16140   unformat_input_t *input = vam->input;
16141   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
16142   u8 *locator_set_name = 0;
16143   u8 locator_set_name_set = 0;
16144   u8 is_add = 1;
16145   int ret;
16146
16147   /* Parse args required to build the message */
16148   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16149     {
16150       if (unformat (input, "del"))
16151         {
16152           is_add = 0;
16153         }
16154       else if (unformat (input, "%_%v%_", &locator_set_name))
16155         {
16156           locator_set_name_set = 1;
16157         }
16158       else
16159         {
16160           clib_warning ("parse error '%U'", format_unformat_error, input);
16161           return -99;
16162         }
16163     }
16164
16165   if (is_add && !locator_set_name_set)
16166     {
16167       errmsg ("itr-rloc is not set!");
16168       return -99;
16169     }
16170
16171   if (is_add && vec_len (locator_set_name) > 64)
16172     {
16173       errmsg ("itr-rloc locator-set name too long");
16174       vec_free (locator_set_name);
16175       return -99;
16176     }
16177
16178   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
16179   mp->is_add = is_add;
16180   if (is_add)
16181     {
16182       clib_memcpy (mp->locator_set_name, locator_set_name,
16183                    vec_len (locator_set_name));
16184     }
16185   else
16186     {
16187       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
16188     }
16189   vec_free (locator_set_name);
16190
16191   /* send it... */
16192   S (mp);
16193
16194   /* Wait for a reply... */
16195   W (ret);
16196   return ret;
16197 }
16198
16199 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
16200
16201 static int
16202 api_one_locator_dump (vat_main_t * vam)
16203 {
16204   unformat_input_t *input = vam->input;
16205   vl_api_one_locator_dump_t *mp;
16206   vl_api_control_ping_t *mp_ping;
16207   u8 is_index_set = 0, is_name_set = 0;
16208   u8 *ls_name = 0;
16209   u32 ls_index = ~0;
16210   int ret;
16211
16212   /* Parse args required to build the message */
16213   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16214     {
16215       if (unformat (input, "ls_name %_%v%_", &ls_name))
16216         {
16217           is_name_set = 1;
16218         }
16219       else if (unformat (input, "ls_index %d", &ls_index))
16220         {
16221           is_index_set = 1;
16222         }
16223       else
16224         {
16225           errmsg ("parse error '%U'", format_unformat_error, input);
16226           return -99;
16227         }
16228     }
16229
16230   if (!is_index_set && !is_name_set)
16231     {
16232       errmsg ("error: expected one of index or name!");
16233       return -99;
16234     }
16235
16236   if (is_index_set && is_name_set)
16237     {
16238       errmsg ("error: only one param expected!");
16239       return -99;
16240     }
16241
16242   if (vec_len (ls_name) > 62)
16243     {
16244       errmsg ("error: locator set name too long!");
16245       return -99;
16246     }
16247
16248   if (!vam->json_output)
16249     {
16250       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
16251     }
16252
16253   M (ONE_LOCATOR_DUMP, mp);
16254   mp->is_index_set = is_index_set;
16255
16256   if (is_index_set)
16257     mp->ls_index = clib_host_to_net_u32 (ls_index);
16258   else
16259     {
16260       vec_add1 (ls_name, 0);
16261       strncpy ((char *) mp->ls_name, (char *) ls_name,
16262                sizeof (mp->ls_name) - 1);
16263     }
16264
16265   /* send it... */
16266   S (mp);
16267
16268   /* Use a control ping for synchronization */
16269   MPING (CONTROL_PING, mp_ping);
16270   S (mp_ping);
16271
16272   /* Wait for a reply... */
16273   W (ret);
16274   return ret;
16275 }
16276
16277 #define api_lisp_locator_dump api_one_locator_dump
16278
16279 static int
16280 api_one_locator_set_dump (vat_main_t * vam)
16281 {
16282   vl_api_one_locator_set_dump_t *mp;
16283   vl_api_control_ping_t *mp_ping;
16284   unformat_input_t *input = vam->input;
16285   u8 filter = 0;
16286   int ret;
16287
16288   /* Parse args required to build the message */
16289   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16290     {
16291       if (unformat (input, "local"))
16292         {
16293           filter = 1;
16294         }
16295       else if (unformat (input, "remote"))
16296         {
16297           filter = 2;
16298         }
16299       else
16300         {
16301           errmsg ("parse error '%U'", format_unformat_error, input);
16302           return -99;
16303         }
16304     }
16305
16306   if (!vam->json_output)
16307     {
16308       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
16309     }
16310
16311   M (ONE_LOCATOR_SET_DUMP, mp);
16312
16313   mp->filter = filter;
16314
16315   /* send it... */
16316   S (mp);
16317
16318   /* Use a control ping for synchronization */
16319   MPING (CONTROL_PING, mp_ping);
16320   S (mp_ping);
16321
16322   /* Wait for a reply... */
16323   W (ret);
16324   return ret;
16325 }
16326
16327 #define api_lisp_locator_set_dump api_one_locator_set_dump
16328
16329 static int
16330 api_one_eid_table_map_dump (vat_main_t * vam)
16331 {
16332   u8 is_l2 = 0;
16333   u8 mode_set = 0;
16334   unformat_input_t *input = vam->input;
16335   vl_api_one_eid_table_map_dump_t *mp;
16336   vl_api_control_ping_t *mp_ping;
16337   int ret;
16338
16339   /* Parse args required to build the message */
16340   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16341     {
16342       if (unformat (input, "l2"))
16343         {
16344           is_l2 = 1;
16345           mode_set = 1;
16346         }
16347       else if (unformat (input, "l3"))
16348         {
16349           is_l2 = 0;
16350           mode_set = 1;
16351         }
16352       else
16353         {
16354           errmsg ("parse error '%U'", format_unformat_error, input);
16355           return -99;
16356         }
16357     }
16358
16359   if (!mode_set)
16360     {
16361       errmsg ("expected one of 'l2' or 'l3' parameter!");
16362       return -99;
16363     }
16364
16365   if (!vam->json_output)
16366     {
16367       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
16368     }
16369
16370   M (ONE_EID_TABLE_MAP_DUMP, mp);
16371   mp->is_l2 = is_l2;
16372
16373   /* send it... */
16374   S (mp);
16375
16376   /* Use a control ping for synchronization */
16377   MPING (CONTROL_PING, mp_ping);
16378   S (mp_ping);
16379
16380   /* Wait for a reply... */
16381   W (ret);
16382   return ret;
16383 }
16384
16385 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
16386
16387 static int
16388 api_one_eid_table_vni_dump (vat_main_t * vam)
16389 {
16390   vl_api_one_eid_table_vni_dump_t *mp;
16391   vl_api_control_ping_t *mp_ping;
16392   int ret;
16393
16394   if (!vam->json_output)
16395     {
16396       print (vam->ofp, "VNI");
16397     }
16398
16399   M (ONE_EID_TABLE_VNI_DUMP, mp);
16400
16401   /* send it... */
16402   S (mp);
16403
16404   /* Use a control ping for synchronization */
16405   MPING (CONTROL_PING, mp_ping);
16406   S (mp_ping);
16407
16408   /* Wait for a reply... */
16409   W (ret);
16410   return ret;
16411 }
16412
16413 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
16414
16415 static int
16416 api_one_eid_table_dump (vat_main_t * vam)
16417 {
16418   unformat_input_t *i = vam->input;
16419   vl_api_one_eid_table_dump_t *mp;
16420   vl_api_control_ping_t *mp_ping;
16421   u8 filter = 0;
16422   int ret;
16423   u32 vni, t = 0;
16424   lisp_eid_vat_t eid;
16425   u8 eid_set = 0;
16426
16427   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16428     {
16429       if (unformat
16430           (i, "eid %U/%d", unformat_ip46_address, &eid.addr.ip, &eid.len))
16431         {
16432           eid_set = 1;
16433           eid.type = 0;
16434         }
16435       else
16436         if (unformat (i, "eid %U", unformat_ethernet_address, &eid.addr.mac))
16437         {
16438           eid_set = 1;
16439           eid.type = 1;
16440         }
16441       else if (unformat (i, "eid %U", unformat_nsh_address, &eid.addr.nsh))
16442         {
16443           eid_set = 1;
16444           eid.type = 2;
16445         }
16446       else if (unformat (i, "vni %d", &t))
16447         {
16448           vni = t;
16449         }
16450       else if (unformat (i, "local"))
16451         {
16452           filter = 1;
16453         }
16454       else if (unformat (i, "remote"))
16455         {
16456           filter = 2;
16457         }
16458       else
16459         {
16460           errmsg ("parse error '%U'", format_unformat_error, i);
16461           return -99;
16462         }
16463     }
16464
16465   if (!vam->json_output)
16466     {
16467       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
16468              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
16469     }
16470
16471   M (ONE_EID_TABLE_DUMP, mp);
16472
16473   mp->filter = filter;
16474   if (eid_set)
16475     {
16476       mp->eid_set = 1;
16477       mp->vni = htonl (vni);
16478       lisp_eid_put_vat (&mp->eid, &eid);
16479     }
16480
16481   /* send it... */
16482   S (mp);
16483
16484   /* Use a control ping for synchronization */
16485   MPING (CONTROL_PING, mp_ping);
16486   S (mp_ping);
16487
16488   /* Wait for a reply... */
16489   W (ret);
16490   return ret;
16491 }
16492
16493 #define api_lisp_eid_table_dump api_one_eid_table_dump
16494
16495 static int
16496 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
16497 {
16498   unformat_input_t *i = vam->input;
16499   vl_api_gpe_fwd_entries_get_t *mp;
16500   u8 vni_set = 0;
16501   u32 vni = ~0;
16502   int ret;
16503
16504   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16505     {
16506       if (unformat (i, "vni %d", &vni))
16507         {
16508           vni_set = 1;
16509         }
16510       else
16511         {
16512           errmsg ("parse error '%U'", format_unformat_error, i);
16513           return -99;
16514         }
16515     }
16516
16517   if (!vni_set)
16518     {
16519       errmsg ("vni not set!");
16520       return -99;
16521     }
16522
16523   if (!vam->json_output)
16524     {
16525       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
16526              "leid", "reid");
16527     }
16528
16529   M (GPE_FWD_ENTRIES_GET, mp);
16530   mp->vni = clib_host_to_net_u32 (vni);
16531
16532   /* send it... */
16533   S (mp);
16534
16535   /* Wait for a reply... */
16536   W (ret);
16537   return ret;
16538 }
16539
16540 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
16541 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
16542 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
16543 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
16544 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
16545 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
16546 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
16547 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
16548
16549 static int
16550 api_one_adjacencies_get (vat_main_t * vam)
16551 {
16552   unformat_input_t *i = vam->input;
16553   vl_api_one_adjacencies_get_t *mp;
16554   u8 vni_set = 0;
16555   u32 vni = ~0;
16556   int ret;
16557
16558   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16559     {
16560       if (unformat (i, "vni %d", &vni))
16561         {
16562           vni_set = 1;
16563         }
16564       else
16565         {
16566           errmsg ("parse error '%U'", format_unformat_error, i);
16567           return -99;
16568         }
16569     }
16570
16571   if (!vni_set)
16572     {
16573       errmsg ("vni not set!");
16574       return -99;
16575     }
16576
16577   if (!vam->json_output)
16578     {
16579       print (vam->ofp, "%s %40s", "leid", "reid");
16580     }
16581
16582   M (ONE_ADJACENCIES_GET, mp);
16583   mp->vni = clib_host_to_net_u32 (vni);
16584
16585   /* send it... */
16586   S (mp);
16587
16588   /* Wait for a reply... */
16589   W (ret);
16590   return ret;
16591 }
16592
16593 #define api_lisp_adjacencies_get api_one_adjacencies_get
16594
16595 static int
16596 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
16597 {
16598   unformat_input_t *i = vam->input;
16599   vl_api_gpe_native_fwd_rpaths_get_t *mp;
16600   int ret;
16601   u8 ip_family_set = 0, is_ip4 = 1;
16602
16603   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16604     {
16605       if (unformat (i, "ip4"))
16606         {
16607           ip_family_set = 1;
16608           is_ip4 = 1;
16609         }
16610       else if (unformat (i, "ip6"))
16611         {
16612           ip_family_set = 1;
16613           is_ip4 = 0;
16614         }
16615       else
16616         {
16617           errmsg ("parse error '%U'", format_unformat_error, i);
16618           return -99;
16619         }
16620     }
16621
16622   if (!ip_family_set)
16623     {
16624       errmsg ("ip family not set!");
16625       return -99;
16626     }
16627
16628   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
16629   mp->is_ip4 = is_ip4;
16630
16631   /* send it... */
16632   S (mp);
16633
16634   /* Wait for a reply... */
16635   W (ret);
16636   return ret;
16637 }
16638
16639 static int
16640 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
16641 {
16642   vl_api_gpe_fwd_entry_vnis_get_t *mp;
16643   int ret;
16644
16645   if (!vam->json_output)
16646     {
16647       print (vam->ofp, "VNIs");
16648     }
16649
16650   M (GPE_FWD_ENTRY_VNIS_GET, mp);
16651
16652   /* send it... */
16653   S (mp);
16654
16655   /* Wait for a reply... */
16656   W (ret);
16657   return ret;
16658 }
16659
16660 static int
16661 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
16662 {
16663   unformat_input_t *i = vam->input;
16664   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
16665   int ret = 0;
16666   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
16667   struct in_addr ip4;
16668   struct in6_addr ip6;
16669   u32 table_id = 0, nh_sw_if_index = ~0;
16670
16671   clib_memset (&ip4, 0, sizeof (ip4));
16672   clib_memset (&ip6, 0, sizeof (ip6));
16673
16674   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16675     {
16676       if (unformat (i, "del"))
16677         is_add = 0;
16678       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
16679                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16680         {
16681           ip_set = 1;
16682           is_ip4 = 1;
16683         }
16684       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
16685                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16686         {
16687           ip_set = 1;
16688           is_ip4 = 0;
16689         }
16690       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
16691         {
16692           ip_set = 1;
16693           is_ip4 = 1;
16694           nh_sw_if_index = ~0;
16695         }
16696       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
16697         {
16698           ip_set = 1;
16699           is_ip4 = 0;
16700           nh_sw_if_index = ~0;
16701         }
16702       else if (unformat (i, "table %d", &table_id))
16703         ;
16704       else
16705         {
16706           errmsg ("parse error '%U'", format_unformat_error, i);
16707           return -99;
16708         }
16709     }
16710
16711   if (!ip_set)
16712     {
16713       errmsg ("nh addr not set!");
16714       return -99;
16715     }
16716
16717   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
16718   mp->is_add = is_add;
16719   mp->table_id = clib_host_to_net_u32 (table_id);
16720   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
16721   mp->nh_addr.af = is_ip4 ? 0 : 1;
16722   if (is_ip4)
16723     clib_memcpy (mp->nh_addr.un.ip4, &ip4, sizeof (ip4));
16724   else
16725     clib_memcpy (mp->nh_addr.un.ip6, &ip6, sizeof (ip6));
16726
16727   /* send it... */
16728   S (mp);
16729
16730   /* Wait for a reply... */
16731   W (ret);
16732   return ret;
16733 }
16734
16735 static int
16736 api_one_map_server_dump (vat_main_t * vam)
16737 {
16738   vl_api_one_map_server_dump_t *mp;
16739   vl_api_control_ping_t *mp_ping;
16740   int ret;
16741
16742   if (!vam->json_output)
16743     {
16744       print (vam->ofp, "%=20s", "Map server");
16745     }
16746
16747   M (ONE_MAP_SERVER_DUMP, mp);
16748   /* send it... */
16749   S (mp);
16750
16751   /* Use a control ping for synchronization */
16752   MPING (CONTROL_PING, mp_ping);
16753   S (mp_ping);
16754
16755   /* Wait for a reply... */
16756   W (ret);
16757   return ret;
16758 }
16759
16760 #define api_lisp_map_server_dump api_one_map_server_dump
16761
16762 static int
16763 api_one_map_resolver_dump (vat_main_t * vam)
16764 {
16765   vl_api_one_map_resolver_dump_t *mp;
16766   vl_api_control_ping_t *mp_ping;
16767   int ret;
16768
16769   if (!vam->json_output)
16770     {
16771       print (vam->ofp, "%=20s", "Map resolver");
16772     }
16773
16774   M (ONE_MAP_RESOLVER_DUMP, mp);
16775   /* send it... */
16776   S (mp);
16777
16778   /* Use a control ping for synchronization */
16779   MPING (CONTROL_PING, mp_ping);
16780   S (mp_ping);
16781
16782   /* Wait for a reply... */
16783   W (ret);
16784   return ret;
16785 }
16786
16787 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
16788
16789 static int
16790 api_one_stats_flush (vat_main_t * vam)
16791 {
16792   vl_api_one_stats_flush_t *mp;
16793   int ret = 0;
16794
16795   M (ONE_STATS_FLUSH, mp);
16796   S (mp);
16797   W (ret);
16798   return ret;
16799 }
16800
16801 static int
16802 api_one_stats_dump (vat_main_t * vam)
16803 {
16804   vl_api_one_stats_dump_t *mp;
16805   vl_api_control_ping_t *mp_ping;
16806   int ret;
16807
16808   M (ONE_STATS_DUMP, mp);
16809   /* send it... */
16810   S (mp);
16811
16812   /* Use a control ping for synchronization */
16813   MPING (CONTROL_PING, mp_ping);
16814   S (mp_ping);
16815
16816   /* Wait for a reply... */
16817   W (ret);
16818   return ret;
16819 }
16820
16821 static int
16822 api_show_one_status (vat_main_t * vam)
16823 {
16824   vl_api_show_one_status_t *mp;
16825   int ret;
16826
16827   if (!vam->json_output)
16828     {
16829       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
16830     }
16831
16832   M (SHOW_ONE_STATUS, mp);
16833   /* send it... */
16834   S (mp);
16835   /* Wait for a reply... */
16836   W (ret);
16837   return ret;
16838 }
16839
16840 #define api_show_lisp_status api_show_one_status
16841
16842 static int
16843 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
16844 {
16845   vl_api_gpe_fwd_entry_path_dump_t *mp;
16846   vl_api_control_ping_t *mp_ping;
16847   unformat_input_t *i = vam->input;
16848   u32 fwd_entry_index = ~0;
16849   int ret;
16850
16851   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16852     {
16853       if (unformat (i, "index %d", &fwd_entry_index))
16854         ;
16855       else
16856         break;
16857     }
16858
16859   if (~0 == fwd_entry_index)
16860     {
16861       errmsg ("no index specified!");
16862       return -99;
16863     }
16864
16865   if (!vam->json_output)
16866     {
16867       print (vam->ofp, "first line");
16868     }
16869
16870   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
16871
16872   /* send it... */
16873   S (mp);
16874   /* Use a control ping for synchronization */
16875   MPING (CONTROL_PING, mp_ping);
16876   S (mp_ping);
16877
16878   /* Wait for a reply... */
16879   W (ret);
16880   return ret;
16881 }
16882
16883 static int
16884 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
16885 {
16886   vl_api_one_get_map_request_itr_rlocs_t *mp;
16887   int ret;
16888
16889   if (!vam->json_output)
16890     {
16891       print (vam->ofp, "%=20s", "itr-rlocs:");
16892     }
16893
16894   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
16895   /* send it... */
16896   S (mp);
16897   /* Wait for a reply... */
16898   W (ret);
16899   return ret;
16900 }
16901
16902 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
16903
16904 static int
16905 api_af_packet_create (vat_main_t * vam)
16906 {
16907   unformat_input_t *i = vam->input;
16908   vl_api_af_packet_create_t *mp;
16909   u8 *host_if_name = 0;
16910   u8 hw_addr[6];
16911   u8 random_hw_addr = 1;
16912   int ret;
16913
16914   clib_memset (hw_addr, 0, sizeof (hw_addr));
16915
16916   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16917     {
16918       if (unformat (i, "name %s", &host_if_name))
16919         vec_add1 (host_if_name, 0);
16920       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
16921         random_hw_addr = 0;
16922       else
16923         break;
16924     }
16925
16926   if (!vec_len (host_if_name))
16927     {
16928       errmsg ("host-interface name must be specified");
16929       return -99;
16930     }
16931
16932   if (vec_len (host_if_name) > 64)
16933     {
16934       errmsg ("host-interface name too long");
16935       return -99;
16936     }
16937
16938   M (AF_PACKET_CREATE, mp);
16939
16940   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
16941   clib_memcpy (mp->hw_addr, hw_addr, 6);
16942   mp->use_random_hw_addr = random_hw_addr;
16943   vec_free (host_if_name);
16944
16945   S (mp);
16946
16947   /* *INDENT-OFF* */
16948   W2 (ret,
16949       ({
16950         if (ret == 0)
16951           fprintf (vam->ofp ? vam->ofp : stderr,
16952                    " new sw_if_index = %d\n", vam->sw_if_index);
16953       }));
16954   /* *INDENT-ON* */
16955   return ret;
16956 }
16957
16958 static int
16959 api_af_packet_delete (vat_main_t * vam)
16960 {
16961   unformat_input_t *i = vam->input;
16962   vl_api_af_packet_delete_t *mp;
16963   u8 *host_if_name = 0;
16964   int ret;
16965
16966   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16967     {
16968       if (unformat (i, "name %s", &host_if_name))
16969         vec_add1 (host_if_name, 0);
16970       else
16971         break;
16972     }
16973
16974   if (!vec_len (host_if_name))
16975     {
16976       errmsg ("host-interface name must be specified");
16977       return -99;
16978     }
16979
16980   if (vec_len (host_if_name) > 64)
16981     {
16982       errmsg ("host-interface name too long");
16983       return -99;
16984     }
16985
16986   M (AF_PACKET_DELETE, mp);
16987
16988   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
16989   vec_free (host_if_name);
16990
16991   S (mp);
16992   W (ret);
16993   return ret;
16994 }
16995
16996 static void vl_api_af_packet_details_t_handler
16997   (vl_api_af_packet_details_t * mp)
16998 {
16999   vat_main_t *vam = &vat_main;
17000
17001   print (vam->ofp, "%-16s %d",
17002          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
17003 }
17004
17005 static void vl_api_af_packet_details_t_handler_json
17006   (vl_api_af_packet_details_t * mp)
17007 {
17008   vat_main_t *vam = &vat_main;
17009   vat_json_node_t *node = NULL;
17010
17011   if (VAT_JSON_ARRAY != vam->json_tree.type)
17012     {
17013       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17014       vat_json_init_array (&vam->json_tree);
17015     }
17016   node = vat_json_array_add (&vam->json_tree);
17017
17018   vat_json_init_object (node);
17019   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17020   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
17021 }
17022
17023 static int
17024 api_af_packet_dump (vat_main_t * vam)
17025 {
17026   vl_api_af_packet_dump_t *mp;
17027   vl_api_control_ping_t *mp_ping;
17028   int ret;
17029
17030   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
17031   /* Get list of tap interfaces */
17032   M (AF_PACKET_DUMP, mp);
17033   S (mp);
17034
17035   /* Use a control ping for synchronization */
17036   MPING (CONTROL_PING, mp_ping);
17037   S (mp_ping);
17038
17039   W (ret);
17040   return ret;
17041 }
17042
17043 static int
17044 api_policer_add_del (vat_main_t * vam)
17045 {
17046   unformat_input_t *i = vam->input;
17047   vl_api_policer_add_del_t *mp;
17048   u8 is_add = 1;
17049   u8 *name = 0;
17050   u32 cir = 0;
17051   u32 eir = 0;
17052   u64 cb = 0;
17053   u64 eb = 0;
17054   u8 rate_type = 0;
17055   u8 round_type = 0;
17056   u8 type = 0;
17057   u8 color_aware = 0;
17058   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
17059   int ret;
17060
17061   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
17062   conform_action.dscp = 0;
17063   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
17064   exceed_action.dscp = 0;
17065   violate_action.action_type = SSE2_QOS_ACTION_DROP;
17066   violate_action.dscp = 0;
17067
17068   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17069     {
17070       if (unformat (i, "del"))
17071         is_add = 0;
17072       else if (unformat (i, "name %s", &name))
17073         vec_add1 (name, 0);
17074       else if (unformat (i, "cir %u", &cir))
17075         ;
17076       else if (unformat (i, "eir %u", &eir))
17077         ;
17078       else if (unformat (i, "cb %u", &cb))
17079         ;
17080       else if (unformat (i, "eb %u", &eb))
17081         ;
17082       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
17083                          &rate_type))
17084         ;
17085       else if (unformat (i, "round_type %U", unformat_policer_round_type,
17086                          &round_type))
17087         ;
17088       else if (unformat (i, "type %U", unformat_policer_type, &type))
17089         ;
17090       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
17091                          &conform_action))
17092         ;
17093       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
17094                          &exceed_action))
17095         ;
17096       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
17097                          &violate_action))
17098         ;
17099       else if (unformat (i, "color-aware"))
17100         color_aware = 1;
17101       else
17102         break;
17103     }
17104
17105   if (!vec_len (name))
17106     {
17107       errmsg ("policer name must be specified");
17108       return -99;
17109     }
17110
17111   if (vec_len (name) > 64)
17112     {
17113       errmsg ("policer name too long");
17114       return -99;
17115     }
17116
17117   M (POLICER_ADD_DEL, mp);
17118
17119   clib_memcpy (mp->name, name, vec_len (name));
17120   vec_free (name);
17121   mp->is_add = is_add;
17122   mp->cir = ntohl (cir);
17123   mp->eir = ntohl (eir);
17124   mp->cb = clib_net_to_host_u64 (cb);
17125   mp->eb = clib_net_to_host_u64 (eb);
17126   mp->rate_type = rate_type;
17127   mp->round_type = round_type;
17128   mp->type = type;
17129   mp->conform_action.type = conform_action.action_type;
17130   mp->conform_action.dscp = conform_action.dscp;
17131   mp->exceed_action.type = exceed_action.action_type;
17132   mp->exceed_action.dscp = exceed_action.dscp;
17133   mp->violate_action.type = violate_action.action_type;
17134   mp->violate_action.dscp = violate_action.dscp;
17135   mp->color_aware = color_aware;
17136
17137   S (mp);
17138   W (ret);
17139   return ret;
17140 }
17141
17142 static int
17143 api_policer_dump (vat_main_t * vam)
17144 {
17145   unformat_input_t *i = vam->input;
17146   vl_api_policer_dump_t *mp;
17147   vl_api_control_ping_t *mp_ping;
17148   u8 *match_name = 0;
17149   u8 match_name_valid = 0;
17150   int ret;
17151
17152   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17153     {
17154       if (unformat (i, "name %s", &match_name))
17155         {
17156           vec_add1 (match_name, 0);
17157           match_name_valid = 1;
17158         }
17159       else
17160         break;
17161     }
17162
17163   M (POLICER_DUMP, mp);
17164   mp->match_name_valid = match_name_valid;
17165   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
17166   vec_free (match_name);
17167   /* send it... */
17168   S (mp);
17169
17170   /* Use a control ping for synchronization */
17171   MPING (CONTROL_PING, mp_ping);
17172   S (mp_ping);
17173
17174   /* Wait for a reply... */
17175   W (ret);
17176   return ret;
17177 }
17178
17179 static int
17180 api_policer_classify_set_interface (vat_main_t * vam)
17181 {
17182   unformat_input_t *i = vam->input;
17183   vl_api_policer_classify_set_interface_t *mp;
17184   u32 sw_if_index;
17185   int sw_if_index_set;
17186   u32 ip4_table_index = ~0;
17187   u32 ip6_table_index = ~0;
17188   u32 l2_table_index = ~0;
17189   u8 is_add = 1;
17190   int ret;
17191
17192   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17193     {
17194       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17195         sw_if_index_set = 1;
17196       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17197         sw_if_index_set = 1;
17198       else if (unformat (i, "del"))
17199         is_add = 0;
17200       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17201         ;
17202       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17203         ;
17204       else if (unformat (i, "l2-table %d", &l2_table_index))
17205         ;
17206       else
17207         {
17208           clib_warning ("parse error '%U'", format_unformat_error, i);
17209           return -99;
17210         }
17211     }
17212
17213   if (sw_if_index_set == 0)
17214     {
17215       errmsg ("missing interface name or sw_if_index");
17216       return -99;
17217     }
17218
17219   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
17220
17221   mp->sw_if_index = ntohl (sw_if_index);
17222   mp->ip4_table_index = ntohl (ip4_table_index);
17223   mp->ip6_table_index = ntohl (ip6_table_index);
17224   mp->l2_table_index = ntohl (l2_table_index);
17225   mp->is_add = is_add;
17226
17227   S (mp);
17228   W (ret);
17229   return ret;
17230 }
17231
17232 static int
17233 api_policer_classify_dump (vat_main_t * vam)
17234 {
17235   unformat_input_t *i = vam->input;
17236   vl_api_policer_classify_dump_t *mp;
17237   vl_api_control_ping_t *mp_ping;
17238   u8 type = POLICER_CLASSIFY_N_TABLES;
17239   int ret;
17240
17241   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
17242     ;
17243   else
17244     {
17245       errmsg ("classify table type must be specified");
17246       return -99;
17247     }
17248
17249   if (!vam->json_output)
17250     {
17251       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17252     }
17253
17254   M (POLICER_CLASSIFY_DUMP, mp);
17255   mp->type = type;
17256   /* send it... */
17257   S (mp);
17258
17259   /* Use a control ping for synchronization */
17260   MPING (CONTROL_PING, mp_ping);
17261   S (mp_ping);
17262
17263   /* Wait for a reply... */
17264   W (ret);
17265   return ret;
17266 }
17267
17268 static u8 *
17269 format_fib_api_path_nh_proto (u8 * s, va_list * args)
17270 {
17271   vl_api_fib_path_nh_proto_t proto =
17272     va_arg (*args, vl_api_fib_path_nh_proto_t);
17273
17274   switch (proto)
17275     {
17276     case FIB_API_PATH_NH_PROTO_IP4:
17277       s = format (s, "ip4");
17278       break;
17279     case FIB_API_PATH_NH_PROTO_IP6:
17280       s = format (s, "ip6");
17281       break;
17282     case FIB_API_PATH_NH_PROTO_MPLS:
17283       s = format (s, "mpls");
17284       break;
17285     case FIB_API_PATH_NH_PROTO_BIER:
17286       s = format (s, "bier");
17287       break;
17288     case FIB_API_PATH_NH_PROTO_ETHERNET:
17289       s = format (s, "ethernet");
17290       break;
17291     }
17292
17293   return (s);
17294 }
17295
17296 static u8 *
17297 format_vl_api_ip_address_union (u8 * s, va_list * args)
17298 {
17299   vl_api_address_family_t af = va_arg (*args, int);
17300   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
17301
17302   switch (af)
17303     {
17304     case ADDRESS_IP4:
17305       s = format (s, "%U", format_ip4_address, u->ip4);
17306       break;
17307     case ADDRESS_IP6:
17308       s = format (s, "%U", format_ip6_address, u->ip6);
17309       break;
17310     }
17311   return (s);
17312 }
17313
17314 static u8 *
17315 format_vl_api_fib_path_type (u8 * s, va_list * args)
17316 {
17317   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
17318
17319   switch (t)
17320     {
17321     case FIB_API_PATH_TYPE_NORMAL:
17322       s = format (s, "normal");
17323       break;
17324     case FIB_API_PATH_TYPE_LOCAL:
17325       s = format (s, "local");
17326       break;
17327     case FIB_API_PATH_TYPE_DROP:
17328       s = format (s, "drop");
17329       break;
17330     case FIB_API_PATH_TYPE_UDP_ENCAP:
17331       s = format (s, "udp-encap");
17332       break;
17333     case FIB_API_PATH_TYPE_BIER_IMP:
17334       s = format (s, "bier-imp");
17335       break;
17336     case FIB_API_PATH_TYPE_ICMP_UNREACH:
17337       s = format (s, "unreach");
17338       break;
17339     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
17340       s = format (s, "prohibit");
17341       break;
17342     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
17343       s = format (s, "src-lookup");
17344       break;
17345     case FIB_API_PATH_TYPE_DVR:
17346       s = format (s, "dvr");
17347       break;
17348     case FIB_API_PATH_TYPE_INTERFACE_RX:
17349       s = format (s, "interface-rx");
17350       break;
17351     case FIB_API_PATH_TYPE_CLASSIFY:
17352       s = format (s, "classify");
17353       break;
17354     }
17355
17356   return (s);
17357 }
17358
17359 static void
17360 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
17361 {
17362   print (vam->ofp,
17363          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
17364          ntohl (fp->weight), ntohl (fp->sw_if_index),
17365          format_vl_api_fib_path_type, fp->type,
17366          format_fib_api_path_nh_proto, fp->proto,
17367          format_vl_api_ip_address_union, &fp->nh.address);
17368 }
17369
17370 static void
17371 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
17372                                  vl_api_fib_path_t * fp)
17373 {
17374   struct in_addr ip4;
17375   struct in6_addr ip6;
17376
17377   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17378   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17379   vat_json_object_add_uint (node, "type", fp->type);
17380   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
17381   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
17382     {
17383       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
17384       vat_json_object_add_ip4 (node, "next_hop", ip4);
17385     }
17386   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP6)
17387     {
17388       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
17389       vat_json_object_add_ip6 (node, "next_hop", ip6);
17390     }
17391 }
17392
17393 static void
17394 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
17395 {
17396   vat_main_t *vam = &vat_main;
17397   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17398   vl_api_fib_path_t *fp;
17399   i32 i;
17400
17401   print (vam->ofp, "sw_if_index %d via:",
17402          ntohl (mp->mt_tunnel.mt_sw_if_index));
17403   fp = mp->mt_tunnel.mt_paths;
17404   for (i = 0; i < count; i++)
17405     {
17406       vl_api_fib_path_print (vam, fp);
17407       fp++;
17408     }
17409
17410   print (vam->ofp, "");
17411 }
17412
17413 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
17414 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
17415
17416 static void
17417 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
17418 {
17419   vat_main_t *vam = &vat_main;
17420   vat_json_node_t *node = NULL;
17421   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17422   vl_api_fib_path_t *fp;
17423   i32 i;
17424
17425   if (VAT_JSON_ARRAY != vam->json_tree.type)
17426     {
17427       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17428       vat_json_init_array (&vam->json_tree);
17429     }
17430   node = vat_json_array_add (&vam->json_tree);
17431
17432   vat_json_init_object (node);
17433   vat_json_object_add_uint (node, "sw_if_index",
17434                             ntohl (mp->mt_tunnel.mt_sw_if_index));
17435
17436   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
17437
17438   fp = mp->mt_tunnel.mt_paths;
17439   for (i = 0; i < count; i++)
17440     {
17441       vl_api_mpls_fib_path_json_print (node, fp);
17442       fp++;
17443     }
17444 }
17445
17446 static int
17447 api_mpls_tunnel_dump (vat_main_t * vam)
17448 {
17449   vl_api_mpls_tunnel_dump_t *mp;
17450   vl_api_control_ping_t *mp_ping;
17451   int ret;
17452
17453   M (MPLS_TUNNEL_DUMP, mp);
17454
17455   S (mp);
17456
17457   /* Use a control ping for synchronization */
17458   MPING (CONTROL_PING, mp_ping);
17459   S (mp_ping);
17460
17461   W (ret);
17462   return ret;
17463 }
17464
17465 #define vl_api_mpls_table_details_t_endian vl_noop_handler
17466 #define vl_api_mpls_table_details_t_print vl_noop_handler
17467
17468
17469 static void
17470 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
17471 {
17472   vat_main_t *vam = &vat_main;
17473
17474   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
17475 }
17476
17477 static void vl_api_mpls_table_details_t_handler_json
17478   (vl_api_mpls_table_details_t * mp)
17479 {
17480   vat_main_t *vam = &vat_main;
17481   vat_json_node_t *node = NULL;
17482
17483   if (VAT_JSON_ARRAY != vam->json_tree.type)
17484     {
17485       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17486       vat_json_init_array (&vam->json_tree);
17487     }
17488   node = vat_json_array_add (&vam->json_tree);
17489
17490   vat_json_init_object (node);
17491   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
17492 }
17493
17494 static int
17495 api_mpls_table_dump (vat_main_t * vam)
17496 {
17497   vl_api_mpls_table_dump_t *mp;
17498   vl_api_control_ping_t *mp_ping;
17499   int ret;
17500
17501   M (MPLS_TABLE_DUMP, mp);
17502   S (mp);
17503
17504   /* Use a control ping for synchronization */
17505   MPING (CONTROL_PING, mp_ping);
17506   S (mp_ping);
17507
17508   W (ret);
17509   return ret;
17510 }
17511
17512 #define vl_api_mpls_route_details_t_endian vl_noop_handler
17513 #define vl_api_mpls_route_details_t_print vl_noop_handler
17514
17515 static void
17516 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
17517 {
17518   vat_main_t *vam = &vat_main;
17519   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
17520   vl_api_fib_path_t *fp;
17521   int i;
17522
17523   print (vam->ofp,
17524          "table-id %d, label %u, ess_bit %u",
17525          ntohl (mp->mr_route.mr_table_id),
17526          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
17527   fp = mp->mr_route.mr_paths;
17528   for (i = 0; i < count; i++)
17529     {
17530       vl_api_fib_path_print (vam, fp);
17531       fp++;
17532     }
17533 }
17534
17535 static void vl_api_mpls_route_details_t_handler_json
17536   (vl_api_mpls_route_details_t * mp)
17537 {
17538   vat_main_t *vam = &vat_main;
17539   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
17540   vat_json_node_t *node = NULL;
17541   vl_api_fib_path_t *fp;
17542   int i;
17543
17544   if (VAT_JSON_ARRAY != vam->json_tree.type)
17545     {
17546       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17547       vat_json_init_array (&vam->json_tree);
17548     }
17549   node = vat_json_array_add (&vam->json_tree);
17550
17551   vat_json_init_object (node);
17552   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
17553   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
17554   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
17555   vat_json_object_add_uint (node, "path_count", count);
17556   fp = mp->mr_route.mr_paths;
17557   for (i = 0; i < count; i++)
17558     {
17559       vl_api_mpls_fib_path_json_print (node, fp);
17560       fp++;
17561     }
17562 }
17563
17564 static int
17565 api_mpls_route_dump (vat_main_t * vam)
17566 {
17567   unformat_input_t *input = vam->input;
17568   vl_api_mpls_route_dump_t *mp;
17569   vl_api_control_ping_t *mp_ping;
17570   u32 table_id;
17571   int ret;
17572
17573   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17574     {
17575       if (unformat (input, "table_id %d", &table_id))
17576         ;
17577       else
17578         break;
17579     }
17580   if (table_id == ~0)
17581     {
17582       errmsg ("missing table id");
17583       return -99;
17584     }
17585
17586   M (MPLS_ROUTE_DUMP, mp);
17587
17588   mp->table.mt_table_id = ntohl (table_id);
17589   S (mp);
17590
17591   /* Use a control ping for synchronization */
17592   MPING (CONTROL_PING, mp_ping);
17593   S (mp_ping);
17594
17595   W (ret);
17596   return ret;
17597 }
17598
17599 #define vl_api_ip_table_details_t_endian vl_noop_handler
17600 #define vl_api_ip_table_details_t_print vl_noop_handler
17601
17602 static void
17603 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
17604 {
17605   vat_main_t *vam = &vat_main;
17606
17607   print (vam->ofp,
17608          "%s; table-id %d, prefix %U/%d",
17609          mp->table.name, ntohl (mp->table.table_id));
17610 }
17611
17612
17613 static void vl_api_ip_table_details_t_handler_json
17614   (vl_api_ip_table_details_t * mp)
17615 {
17616   vat_main_t *vam = &vat_main;
17617   vat_json_node_t *node = NULL;
17618
17619   if (VAT_JSON_ARRAY != vam->json_tree.type)
17620     {
17621       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17622       vat_json_init_array (&vam->json_tree);
17623     }
17624   node = vat_json_array_add (&vam->json_tree);
17625
17626   vat_json_init_object (node);
17627   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
17628 }
17629
17630 static int
17631 api_ip_table_dump (vat_main_t * vam)
17632 {
17633   vl_api_ip_table_dump_t *mp;
17634   vl_api_control_ping_t *mp_ping;
17635   int ret;
17636
17637   M (IP_TABLE_DUMP, mp);
17638   S (mp);
17639
17640   /* Use a control ping for synchronization */
17641   MPING (CONTROL_PING, mp_ping);
17642   S (mp_ping);
17643
17644   W (ret);
17645   return ret;
17646 }
17647
17648 static int
17649 api_ip_mtable_dump (vat_main_t * vam)
17650 {
17651   vl_api_ip_mtable_dump_t *mp;
17652   vl_api_control_ping_t *mp_ping;
17653   int ret;
17654
17655   M (IP_MTABLE_DUMP, mp);
17656   S (mp);
17657
17658   /* Use a control ping for synchronization */
17659   MPING (CONTROL_PING, mp_ping);
17660   S (mp_ping);
17661
17662   W (ret);
17663   return ret;
17664 }
17665
17666 static int
17667 api_ip_mroute_dump (vat_main_t * vam)
17668 {
17669   unformat_input_t *input = vam->input;
17670   vl_api_control_ping_t *mp_ping;
17671   vl_api_ip_mroute_dump_t *mp;
17672   int ret, is_ip6;
17673   u32 table_id;
17674
17675   is_ip6 = 0;
17676   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17677     {
17678       if (unformat (input, "table_id %d", &table_id))
17679         ;
17680       else if (unformat (input, "ip6"))
17681         is_ip6 = 1;
17682       else if (unformat (input, "ip4"))
17683         is_ip6 = 0;
17684       else
17685         break;
17686     }
17687   if (table_id == ~0)
17688     {
17689       errmsg ("missing table id");
17690       return -99;
17691     }
17692
17693   M (IP_MROUTE_DUMP, mp);
17694   mp->table.table_id = table_id;
17695   mp->table.is_ip6 = is_ip6;
17696   S (mp);
17697
17698   /* Use a control ping for synchronization */
17699   MPING (CONTROL_PING, mp_ping);
17700   S (mp_ping);
17701
17702   W (ret);
17703   return ret;
17704 }
17705
17706 #define vl_api_ip_route_details_t_endian vl_noop_handler
17707 #define vl_api_ip_route_details_t_print vl_noop_handler
17708
17709 static void
17710 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
17711 {
17712   vat_main_t *vam = &vat_main;
17713   u8 count = mp->route.n_paths;
17714   vl_api_fib_path_t *fp;
17715   int i;
17716
17717   print (vam->ofp,
17718          "table-id %d, prefix %U/%d",
17719          ntohl (mp->route.table_id),
17720          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
17721   for (i = 0; i < count; i++)
17722     {
17723       fp = &mp->route.paths[i];
17724
17725       vl_api_fib_path_print (vam, fp);
17726       fp++;
17727     }
17728 }
17729
17730 static void vl_api_ip_route_details_t_handler_json
17731   (vl_api_ip_route_details_t * mp)
17732 {
17733   vat_main_t *vam = &vat_main;
17734   u8 count = mp->route.n_paths;
17735   vat_json_node_t *node = NULL;
17736   struct in_addr ip4;
17737   struct in6_addr ip6;
17738   vl_api_fib_path_t *fp;
17739   int i;
17740
17741   if (VAT_JSON_ARRAY != vam->json_tree.type)
17742     {
17743       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17744       vat_json_init_array (&vam->json_tree);
17745     }
17746   node = vat_json_array_add (&vam->json_tree);
17747
17748   vat_json_init_object (node);
17749   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
17750   if (ADDRESS_IP6 == mp->route.prefix.address.af)
17751     {
17752       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
17753       vat_json_object_add_ip6 (node, "prefix", ip6);
17754     }
17755   else
17756     {
17757       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
17758       vat_json_object_add_ip4 (node, "prefix", ip4);
17759     }
17760   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
17761   vat_json_object_add_uint (node, "path_count", count);
17762   for (i = 0; i < count; i++)
17763     {
17764       fp = &mp->route.paths[i];
17765       vl_api_mpls_fib_path_json_print (node, fp);
17766     }
17767 }
17768
17769 static int
17770 api_ip_route_dump (vat_main_t * vam)
17771 {
17772   unformat_input_t *input = vam->input;
17773   vl_api_ip_route_dump_t *mp;
17774   vl_api_control_ping_t *mp_ping;
17775   u32 table_id;
17776   u8 is_ip6;
17777   int ret;
17778
17779   is_ip6 = 0;
17780   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17781     {
17782       if (unformat (input, "table_id %d", &table_id))
17783         ;
17784       else if (unformat (input, "ip6"))
17785         is_ip6 = 1;
17786       else if (unformat (input, "ip4"))
17787         is_ip6 = 0;
17788       else
17789         break;
17790     }
17791   if (table_id == ~0)
17792     {
17793       errmsg ("missing table id");
17794       return -99;
17795     }
17796
17797   M (IP_ROUTE_DUMP, mp);
17798
17799   mp->table.table_id = table_id;
17800   mp->table.is_ip6 = is_ip6;
17801
17802   S (mp);
17803
17804   /* Use a control ping for synchronization */
17805   MPING (CONTROL_PING, mp_ping);
17806   S (mp_ping);
17807
17808   W (ret);
17809   return ret;
17810 }
17811
17812 int
17813 api_classify_table_ids (vat_main_t * vam)
17814 {
17815   vl_api_classify_table_ids_t *mp;
17816   int ret;
17817
17818   /* Construct the API message */
17819   M (CLASSIFY_TABLE_IDS, mp);
17820   mp->context = 0;
17821
17822   S (mp);
17823   W (ret);
17824   return ret;
17825 }
17826
17827 int
17828 api_classify_table_by_interface (vat_main_t * vam)
17829 {
17830   unformat_input_t *input = vam->input;
17831   vl_api_classify_table_by_interface_t *mp;
17832
17833   u32 sw_if_index = ~0;
17834   int ret;
17835   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17836     {
17837       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17838         ;
17839       else if (unformat (input, "sw_if_index %d", &sw_if_index))
17840         ;
17841       else
17842         break;
17843     }
17844   if (sw_if_index == ~0)
17845     {
17846       errmsg ("missing interface name or sw_if_index");
17847       return -99;
17848     }
17849
17850   /* Construct the API message */
17851   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
17852   mp->context = 0;
17853   mp->sw_if_index = ntohl (sw_if_index);
17854
17855   S (mp);
17856   W (ret);
17857   return ret;
17858 }
17859
17860 int
17861 api_classify_table_info (vat_main_t * vam)
17862 {
17863   unformat_input_t *input = vam->input;
17864   vl_api_classify_table_info_t *mp;
17865
17866   u32 table_id = ~0;
17867   int ret;
17868   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17869     {
17870       if (unformat (input, "table_id %d", &table_id))
17871         ;
17872       else
17873         break;
17874     }
17875   if (table_id == ~0)
17876     {
17877       errmsg ("missing table id");
17878       return -99;
17879     }
17880
17881   /* Construct the API message */
17882   M (CLASSIFY_TABLE_INFO, mp);
17883   mp->context = 0;
17884   mp->table_id = ntohl (table_id);
17885
17886   S (mp);
17887   W (ret);
17888   return ret;
17889 }
17890
17891 int
17892 api_classify_session_dump (vat_main_t * vam)
17893 {
17894   unformat_input_t *input = vam->input;
17895   vl_api_classify_session_dump_t *mp;
17896   vl_api_control_ping_t *mp_ping;
17897
17898   u32 table_id = ~0;
17899   int ret;
17900   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17901     {
17902       if (unformat (input, "table_id %d", &table_id))
17903         ;
17904       else
17905         break;
17906     }
17907   if (table_id == ~0)
17908     {
17909       errmsg ("missing table id");
17910       return -99;
17911     }
17912
17913   /* Construct the API message */
17914   M (CLASSIFY_SESSION_DUMP, mp);
17915   mp->context = 0;
17916   mp->table_id = ntohl (table_id);
17917   S (mp);
17918
17919   /* Use a control ping for synchronization */
17920   MPING (CONTROL_PING, mp_ping);
17921   S (mp_ping);
17922
17923   W (ret);
17924   return ret;
17925 }
17926
17927 static void
17928 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
17929 {
17930   vat_main_t *vam = &vat_main;
17931
17932   print (vam->ofp, "collector_address %U, collector_port %d, "
17933          "src_address %U, vrf_id %d, path_mtu %u, "
17934          "template_interval %u, udp_checksum %d",
17935          format_ip4_address, mp->collector_address,
17936          ntohs (mp->collector_port),
17937          format_ip4_address, mp->src_address,
17938          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
17939          ntohl (mp->template_interval), mp->udp_checksum);
17940
17941   vam->retval = 0;
17942   vam->result_ready = 1;
17943 }
17944
17945 static void
17946   vl_api_ipfix_exporter_details_t_handler_json
17947   (vl_api_ipfix_exporter_details_t * mp)
17948 {
17949   vat_main_t *vam = &vat_main;
17950   vat_json_node_t node;
17951   struct in_addr collector_address;
17952   struct in_addr src_address;
17953
17954   vat_json_init_object (&node);
17955   clib_memcpy (&collector_address, &mp->collector_address,
17956                sizeof (collector_address));
17957   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
17958   vat_json_object_add_uint (&node, "collector_port",
17959                             ntohs (mp->collector_port));
17960   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
17961   vat_json_object_add_ip4 (&node, "src_address", src_address);
17962   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
17963   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
17964   vat_json_object_add_uint (&node, "template_interval",
17965                             ntohl (mp->template_interval));
17966   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
17967
17968   vat_json_print (vam->ofp, &node);
17969   vat_json_free (&node);
17970   vam->retval = 0;
17971   vam->result_ready = 1;
17972 }
17973
17974 int
17975 api_ipfix_exporter_dump (vat_main_t * vam)
17976 {
17977   vl_api_ipfix_exporter_dump_t *mp;
17978   int ret;
17979
17980   /* Construct the API message */
17981   M (IPFIX_EXPORTER_DUMP, mp);
17982   mp->context = 0;
17983
17984   S (mp);
17985   W (ret);
17986   return ret;
17987 }
17988
17989 static int
17990 api_ipfix_classify_stream_dump (vat_main_t * vam)
17991 {
17992   vl_api_ipfix_classify_stream_dump_t *mp;
17993   int ret;
17994
17995   /* Construct the API message */
17996   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
17997   mp->context = 0;
17998
17999   S (mp);
18000   W (ret);
18001   return ret;
18002   /* NOTREACHED */
18003   return 0;
18004 }
18005
18006 static void
18007   vl_api_ipfix_classify_stream_details_t_handler
18008   (vl_api_ipfix_classify_stream_details_t * mp)
18009 {
18010   vat_main_t *vam = &vat_main;
18011   print (vam->ofp, "domain_id %d, src_port %d",
18012          ntohl (mp->domain_id), ntohs (mp->src_port));
18013   vam->retval = 0;
18014   vam->result_ready = 1;
18015 }
18016
18017 static void
18018   vl_api_ipfix_classify_stream_details_t_handler_json
18019   (vl_api_ipfix_classify_stream_details_t * mp)
18020 {
18021   vat_main_t *vam = &vat_main;
18022   vat_json_node_t node;
18023
18024   vat_json_init_object (&node);
18025   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
18026   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
18027
18028   vat_json_print (vam->ofp, &node);
18029   vat_json_free (&node);
18030   vam->retval = 0;
18031   vam->result_ready = 1;
18032 }
18033
18034 static int
18035 api_ipfix_classify_table_dump (vat_main_t * vam)
18036 {
18037   vl_api_ipfix_classify_table_dump_t *mp;
18038   vl_api_control_ping_t *mp_ping;
18039   int ret;
18040
18041   if (!vam->json_output)
18042     {
18043       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
18044              "transport_protocol");
18045     }
18046
18047   /* Construct the API message */
18048   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
18049
18050   /* send it... */
18051   S (mp);
18052
18053   /* Use a control ping for synchronization */
18054   MPING (CONTROL_PING, mp_ping);
18055   S (mp_ping);
18056
18057   W (ret);
18058   return ret;
18059 }
18060
18061 static void
18062   vl_api_ipfix_classify_table_details_t_handler
18063   (vl_api_ipfix_classify_table_details_t * mp)
18064 {
18065   vat_main_t *vam = &vat_main;
18066   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
18067          mp->transport_protocol);
18068 }
18069
18070 static void
18071   vl_api_ipfix_classify_table_details_t_handler_json
18072   (vl_api_ipfix_classify_table_details_t * mp)
18073 {
18074   vat_json_node_t *node = NULL;
18075   vat_main_t *vam = &vat_main;
18076
18077   if (VAT_JSON_ARRAY != vam->json_tree.type)
18078     {
18079       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18080       vat_json_init_array (&vam->json_tree);
18081     }
18082
18083   node = vat_json_array_add (&vam->json_tree);
18084   vat_json_init_object (node);
18085
18086   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
18087   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
18088   vat_json_object_add_uint (node, "transport_protocol",
18089                             mp->transport_protocol);
18090 }
18091
18092 static int
18093 api_sw_interface_span_enable_disable (vat_main_t * vam)
18094 {
18095   unformat_input_t *i = vam->input;
18096   vl_api_sw_interface_span_enable_disable_t *mp;
18097   u32 src_sw_if_index = ~0;
18098   u32 dst_sw_if_index = ~0;
18099   u8 state = 3;
18100   int ret;
18101   u8 is_l2 = 0;
18102
18103   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18104     {
18105       if (unformat
18106           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
18107         ;
18108       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
18109         ;
18110       else
18111         if (unformat
18112             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
18113         ;
18114       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
18115         ;
18116       else if (unformat (i, "disable"))
18117         state = 0;
18118       else if (unformat (i, "rx"))
18119         state = 1;
18120       else if (unformat (i, "tx"))
18121         state = 2;
18122       else if (unformat (i, "both"))
18123         state = 3;
18124       else if (unformat (i, "l2"))
18125         is_l2 = 1;
18126       else
18127         break;
18128     }
18129
18130   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
18131
18132   mp->sw_if_index_from = htonl (src_sw_if_index);
18133   mp->sw_if_index_to = htonl (dst_sw_if_index);
18134   mp->state = state;
18135   mp->is_l2 = is_l2;
18136
18137   S (mp);
18138   W (ret);
18139   return ret;
18140 }
18141
18142 static void
18143 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
18144                                             * mp)
18145 {
18146   vat_main_t *vam = &vat_main;
18147   u8 *sw_if_from_name = 0;
18148   u8 *sw_if_to_name = 0;
18149   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18150   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18151   char *states[] = { "none", "rx", "tx", "both" };
18152   hash_pair_t *p;
18153
18154   /* *INDENT-OFF* */
18155   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18156   ({
18157     if ((u32) p->value[0] == sw_if_index_from)
18158       {
18159         sw_if_from_name = (u8 *)(p->key);
18160         if (sw_if_to_name)
18161           break;
18162       }
18163     if ((u32) p->value[0] == sw_if_index_to)
18164       {
18165         sw_if_to_name = (u8 *)(p->key);
18166         if (sw_if_from_name)
18167           break;
18168       }
18169   }));
18170   /* *INDENT-ON* */
18171   print (vam->ofp, "%20s => %20s (%s) %s",
18172          sw_if_from_name, sw_if_to_name, states[mp->state],
18173          mp->is_l2 ? "l2" : "device");
18174 }
18175
18176 static void
18177   vl_api_sw_interface_span_details_t_handler_json
18178   (vl_api_sw_interface_span_details_t * mp)
18179 {
18180   vat_main_t *vam = &vat_main;
18181   vat_json_node_t *node = NULL;
18182   u8 *sw_if_from_name = 0;
18183   u8 *sw_if_to_name = 0;
18184   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18185   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18186   hash_pair_t *p;
18187
18188   /* *INDENT-OFF* */
18189   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18190   ({
18191     if ((u32) p->value[0] == sw_if_index_from)
18192       {
18193         sw_if_from_name = (u8 *)(p->key);
18194         if (sw_if_to_name)
18195           break;
18196       }
18197     if ((u32) p->value[0] == sw_if_index_to)
18198       {
18199         sw_if_to_name = (u8 *)(p->key);
18200         if (sw_if_from_name)
18201           break;
18202       }
18203   }));
18204   /* *INDENT-ON* */
18205
18206   if (VAT_JSON_ARRAY != vam->json_tree.type)
18207     {
18208       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18209       vat_json_init_array (&vam->json_tree);
18210     }
18211   node = vat_json_array_add (&vam->json_tree);
18212
18213   vat_json_init_object (node);
18214   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
18215   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
18216   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
18217   if (0 != sw_if_to_name)
18218     {
18219       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
18220     }
18221   vat_json_object_add_uint (node, "state", mp->state);
18222   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
18223 }
18224
18225 static int
18226 api_sw_interface_span_dump (vat_main_t * vam)
18227 {
18228   unformat_input_t *input = vam->input;
18229   vl_api_sw_interface_span_dump_t *mp;
18230   vl_api_control_ping_t *mp_ping;
18231   u8 is_l2 = 0;
18232   int ret;
18233
18234   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18235     {
18236       if (unformat (input, "l2"))
18237         is_l2 = 1;
18238       else
18239         break;
18240     }
18241
18242   M (SW_INTERFACE_SPAN_DUMP, mp);
18243   mp->is_l2 = is_l2;
18244   S (mp);
18245
18246   /* Use a control ping for synchronization */
18247   MPING (CONTROL_PING, mp_ping);
18248   S (mp_ping);
18249
18250   W (ret);
18251   return ret;
18252 }
18253
18254 int
18255 api_pg_create_interface (vat_main_t * vam)
18256 {
18257   unformat_input_t *input = vam->input;
18258   vl_api_pg_create_interface_t *mp;
18259
18260   u32 if_id = ~0, gso_size = 0;
18261   u8 gso_enabled = 0;
18262   int ret;
18263   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18264     {
18265       if (unformat (input, "if_id %d", &if_id))
18266         ;
18267       else if (unformat (input, "gso-enabled"))
18268         {
18269           gso_enabled = 1;
18270           if (unformat (input, "gso-size %u", &gso_size))
18271             ;
18272           else
18273             {
18274               errmsg ("missing gso-size");
18275               return -99;
18276             }
18277         }
18278       else
18279         break;
18280     }
18281   if (if_id == ~0)
18282     {
18283       errmsg ("missing pg interface index");
18284       return -99;
18285     }
18286
18287   /* Construct the API message */
18288   M (PG_CREATE_INTERFACE, mp);
18289   mp->context = 0;
18290   mp->interface_id = ntohl (if_id);
18291   mp->gso_enabled = gso_enabled;
18292
18293   S (mp);
18294   W (ret);
18295   return ret;
18296 }
18297
18298 int
18299 api_pg_capture (vat_main_t * vam)
18300 {
18301   unformat_input_t *input = vam->input;
18302   vl_api_pg_capture_t *mp;
18303
18304   u32 if_id = ~0;
18305   u8 enable = 1;
18306   u32 count = 1;
18307   u8 pcap_file_set = 0;
18308   u8 *pcap_file = 0;
18309   int ret;
18310   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18311     {
18312       if (unformat (input, "if_id %d", &if_id))
18313         ;
18314       else if (unformat (input, "pcap %s", &pcap_file))
18315         pcap_file_set = 1;
18316       else if (unformat (input, "count %d", &count))
18317         ;
18318       else if (unformat (input, "disable"))
18319         enable = 0;
18320       else
18321         break;
18322     }
18323   if (if_id == ~0)
18324     {
18325       errmsg ("missing pg interface index");
18326       return -99;
18327     }
18328   if (pcap_file_set > 0)
18329     {
18330       if (vec_len (pcap_file) > 255)
18331         {
18332           errmsg ("pcap file name is too long");
18333           return -99;
18334         }
18335     }
18336
18337   /* Construct the API message */
18338   M (PG_CAPTURE, mp);
18339   mp->context = 0;
18340   mp->interface_id = ntohl (if_id);
18341   mp->is_enabled = enable;
18342   mp->count = ntohl (count);
18343   if (pcap_file_set != 0)
18344     {
18345       vl_api_vec_to_api_string (pcap_file, &mp->pcap_file_name);
18346     }
18347   vec_free (pcap_file);
18348
18349   S (mp);
18350   W (ret);
18351   return ret;
18352 }
18353
18354 int
18355 api_pg_enable_disable (vat_main_t * vam)
18356 {
18357   unformat_input_t *input = vam->input;
18358   vl_api_pg_enable_disable_t *mp;
18359
18360   u8 enable = 1;
18361   u8 stream_name_set = 0;
18362   u8 *stream_name = 0;
18363   int ret;
18364   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18365     {
18366       if (unformat (input, "stream %s", &stream_name))
18367         stream_name_set = 1;
18368       else if (unformat (input, "disable"))
18369         enable = 0;
18370       else
18371         break;
18372     }
18373
18374   if (stream_name_set > 0)
18375     {
18376       if (vec_len (stream_name) > 255)
18377         {
18378           errmsg ("stream name too long");
18379           return -99;
18380         }
18381     }
18382
18383   /* Construct the API message */
18384   M (PG_ENABLE_DISABLE, mp);
18385   mp->context = 0;
18386   mp->is_enabled = enable;
18387   if (stream_name_set != 0)
18388     {
18389       vl_api_vec_to_api_string (stream_name, &mp->stream_name);
18390     }
18391   vec_free (stream_name);
18392
18393   S (mp);
18394   W (ret);
18395   return ret;
18396 }
18397
18398 int
18399 api_pg_interface_enable_disable_coalesce (vat_main_t * vam)
18400 {
18401   unformat_input_t *input = vam->input;
18402   vl_api_pg_interface_enable_disable_coalesce_t *mp;
18403
18404   u32 sw_if_index = ~0;
18405   u8 enable = 1;
18406   int ret;
18407   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18408     {
18409       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18410         ;
18411       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18412         ;
18413       else if (unformat (input, "disable"))
18414         enable = 0;
18415       else
18416         break;
18417     }
18418
18419   if (sw_if_index == ~0)
18420     {
18421       errmsg ("Interface required but not specified");
18422       return -99;
18423     }
18424
18425   /* Construct the API message */
18426   M (PG_INTERFACE_ENABLE_DISABLE_COALESCE, mp);
18427   mp->context = 0;
18428   mp->coalesce_enabled = enable;
18429   mp->sw_if_index = htonl (sw_if_index);
18430
18431   S (mp);
18432   W (ret);
18433   return ret;
18434 }
18435
18436 int
18437 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
18438 {
18439   unformat_input_t *input = vam->input;
18440   vl_api_ip_source_and_port_range_check_add_del_t *mp;
18441
18442   u16 *low_ports = 0;
18443   u16 *high_ports = 0;
18444   u16 this_low;
18445   u16 this_hi;
18446   vl_api_prefix_t prefix;
18447   u32 tmp, tmp2;
18448   u8 prefix_set = 0;
18449   u32 vrf_id = ~0;
18450   u8 is_add = 1;
18451   int ret;
18452
18453   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18454     {
18455       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
18456         prefix_set = 1;
18457       else if (unformat (input, "vrf %d", &vrf_id))
18458         ;
18459       else if (unformat (input, "del"))
18460         is_add = 0;
18461       else if (unformat (input, "port %d", &tmp))
18462         {
18463           if (tmp == 0 || tmp > 65535)
18464             {
18465               errmsg ("port %d out of range", tmp);
18466               return -99;
18467             }
18468           this_low = tmp;
18469           this_hi = this_low + 1;
18470           vec_add1 (low_ports, this_low);
18471           vec_add1 (high_ports, this_hi);
18472         }
18473       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
18474         {
18475           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
18476             {
18477               errmsg ("incorrect range parameters");
18478               return -99;
18479             }
18480           this_low = tmp;
18481           /* Note: in debug CLI +1 is added to high before
18482              passing to real fn that does "the work"
18483              (ip_source_and_port_range_check_add_del).
18484              This fn is a wrapper around the binary API fn a
18485              control plane will call, which expects this increment
18486              to have occurred. Hence letting the binary API control
18487              plane fn do the increment for consistency between VAT
18488              and other control planes.
18489            */
18490           this_hi = tmp2;
18491           vec_add1 (low_ports, this_low);
18492           vec_add1 (high_ports, this_hi);
18493         }
18494       else
18495         break;
18496     }
18497
18498   if (prefix_set == 0)
18499     {
18500       errmsg ("<address>/<mask> not specified");
18501       return -99;
18502     }
18503
18504   if (vrf_id == ~0)
18505     {
18506       errmsg ("VRF ID required, not specified");
18507       return -99;
18508     }
18509
18510   if (vrf_id == 0)
18511     {
18512       errmsg
18513         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18514       return -99;
18515     }
18516
18517   if (vec_len (low_ports) == 0)
18518     {
18519       errmsg ("At least one port or port range required");
18520       return -99;
18521     }
18522
18523   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
18524
18525   mp->is_add = is_add;
18526
18527   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
18528
18529   mp->number_of_ranges = vec_len (low_ports);
18530
18531   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
18532   vec_free (low_ports);
18533
18534   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
18535   vec_free (high_ports);
18536
18537   mp->vrf_id = ntohl (vrf_id);
18538
18539   S (mp);
18540   W (ret);
18541   return ret;
18542 }
18543
18544 int
18545 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
18546 {
18547   unformat_input_t *input = vam->input;
18548   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
18549   u32 sw_if_index = ~0;
18550   int vrf_set = 0;
18551   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
18552   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
18553   u8 is_add = 1;
18554   int ret;
18555
18556   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18557     {
18558       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18559         ;
18560       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18561         ;
18562       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
18563         vrf_set = 1;
18564       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
18565         vrf_set = 1;
18566       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
18567         vrf_set = 1;
18568       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
18569         vrf_set = 1;
18570       else if (unformat (input, "del"))
18571         is_add = 0;
18572       else
18573         break;
18574     }
18575
18576   if (sw_if_index == ~0)
18577     {
18578       errmsg ("Interface required but not specified");
18579       return -99;
18580     }
18581
18582   if (vrf_set == 0)
18583     {
18584       errmsg ("VRF ID required but not specified");
18585       return -99;
18586     }
18587
18588   if (tcp_out_vrf_id == 0
18589       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
18590     {
18591       errmsg
18592         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18593       return -99;
18594     }
18595
18596   /* Construct the API message */
18597   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
18598
18599   mp->sw_if_index = ntohl (sw_if_index);
18600   mp->is_add = is_add;
18601   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
18602   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
18603   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
18604   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
18605
18606   /* send it... */
18607   S (mp);
18608
18609   /* Wait for a reply... */
18610   W (ret);
18611   return ret;
18612 }
18613
18614 static int
18615 api_set_punt (vat_main_t * vam)
18616 {
18617   unformat_input_t *i = vam->input;
18618   vl_api_address_family_t af;
18619   vl_api_set_punt_t *mp;
18620   u32 protocol = ~0;
18621   u32 port = ~0;
18622   int is_add = 1;
18623   int ret;
18624
18625   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18626     {
18627       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
18628         ;
18629       else if (unformat (i, "protocol %d", &protocol))
18630         ;
18631       else if (unformat (i, "port %d", &port))
18632         ;
18633       else if (unformat (i, "del"))
18634         is_add = 0;
18635       else
18636         {
18637           clib_warning ("parse error '%U'", format_unformat_error, i);
18638           return -99;
18639         }
18640     }
18641
18642   M (SET_PUNT, mp);
18643
18644   mp->is_add = (u8) is_add;
18645   mp->punt.type = PUNT_API_TYPE_L4;
18646   mp->punt.punt.l4.af = af;
18647   mp->punt.punt.l4.protocol = (u8) protocol;
18648   mp->punt.punt.l4.port = htons ((u16) port);
18649
18650   S (mp);
18651   W (ret);
18652   return ret;
18653 }
18654
18655 static int
18656 api_delete_subif (vat_main_t * vam)
18657 {
18658   unformat_input_t *i = vam->input;
18659   vl_api_delete_subif_t *mp;
18660   u32 sw_if_index = ~0;
18661   int ret;
18662
18663   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18664     {
18665       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18666         ;
18667       if (unformat (i, "sw_if_index %d", &sw_if_index))
18668         ;
18669       else
18670         break;
18671     }
18672
18673   if (sw_if_index == ~0)
18674     {
18675       errmsg ("missing sw_if_index");
18676       return -99;
18677     }
18678
18679   /* Construct the API message */
18680   M (DELETE_SUBIF, mp);
18681   mp->sw_if_index = ntohl (sw_if_index);
18682
18683   S (mp);
18684   W (ret);
18685   return ret;
18686 }
18687
18688 #define foreach_pbb_vtr_op      \
18689 _("disable",  L2_VTR_DISABLED)  \
18690 _("pop",  L2_VTR_POP_2)         \
18691 _("push",  L2_VTR_PUSH_2)
18692
18693 static int
18694 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
18695 {
18696   unformat_input_t *i = vam->input;
18697   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
18698   u32 sw_if_index = ~0, vtr_op = ~0;
18699   u16 outer_tag = ~0;
18700   u8 dmac[6], smac[6];
18701   u8 dmac_set = 0, smac_set = 0;
18702   u16 vlanid = 0;
18703   u32 sid = ~0;
18704   u32 tmp;
18705   int ret;
18706
18707   /* Shut up coverity */
18708   clib_memset (dmac, 0, sizeof (dmac));
18709   clib_memset (smac, 0, sizeof (smac));
18710
18711   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18712     {
18713       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18714         ;
18715       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18716         ;
18717       else if (unformat (i, "vtr_op %d", &vtr_op))
18718         ;
18719 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
18720       foreach_pbb_vtr_op
18721 #undef _
18722         else if (unformat (i, "translate_pbb_stag"))
18723         {
18724           if (unformat (i, "%d", &tmp))
18725             {
18726               vtr_op = L2_VTR_TRANSLATE_2_1;
18727               outer_tag = tmp;
18728             }
18729           else
18730             {
18731               errmsg
18732                 ("translate_pbb_stag operation requires outer tag definition");
18733               return -99;
18734             }
18735         }
18736       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
18737         dmac_set++;
18738       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
18739         smac_set++;
18740       else if (unformat (i, "sid %d", &sid))
18741         ;
18742       else if (unformat (i, "vlanid %d", &tmp))
18743         vlanid = tmp;
18744       else
18745         {
18746           clib_warning ("parse error '%U'", format_unformat_error, i);
18747           return -99;
18748         }
18749     }
18750
18751   if ((sw_if_index == ~0) || (vtr_op == ~0))
18752     {
18753       errmsg ("missing sw_if_index or vtr operation");
18754       return -99;
18755     }
18756   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
18757       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
18758     {
18759       errmsg
18760         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
18761       return -99;
18762     }
18763
18764   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
18765   mp->sw_if_index = ntohl (sw_if_index);
18766   mp->vtr_op = ntohl (vtr_op);
18767   mp->outer_tag = ntohs (outer_tag);
18768   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
18769   clib_memcpy (mp->b_smac, smac, sizeof (smac));
18770   mp->b_vlanid = ntohs (vlanid);
18771   mp->i_sid = ntohl (sid);
18772
18773   S (mp);
18774   W (ret);
18775   return ret;
18776 }
18777
18778 static int
18779 api_flow_classify_set_interface (vat_main_t * vam)
18780 {
18781   unformat_input_t *i = vam->input;
18782   vl_api_flow_classify_set_interface_t *mp;
18783   u32 sw_if_index;
18784   int sw_if_index_set;
18785   u32 ip4_table_index = ~0;
18786   u32 ip6_table_index = ~0;
18787   u8 is_add = 1;
18788   int ret;
18789
18790   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18791     {
18792       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18793         sw_if_index_set = 1;
18794       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18795         sw_if_index_set = 1;
18796       else if (unformat (i, "del"))
18797         is_add = 0;
18798       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18799         ;
18800       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18801         ;
18802       else
18803         {
18804           clib_warning ("parse error '%U'", format_unformat_error, i);
18805           return -99;
18806         }
18807     }
18808
18809   if (sw_if_index_set == 0)
18810     {
18811       errmsg ("missing interface name or sw_if_index");
18812       return -99;
18813     }
18814
18815   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
18816
18817   mp->sw_if_index = ntohl (sw_if_index);
18818   mp->ip4_table_index = ntohl (ip4_table_index);
18819   mp->ip6_table_index = ntohl (ip6_table_index);
18820   mp->is_add = is_add;
18821
18822   S (mp);
18823   W (ret);
18824   return ret;
18825 }
18826
18827 static int
18828 api_flow_classify_dump (vat_main_t * vam)
18829 {
18830   unformat_input_t *i = vam->input;
18831   vl_api_flow_classify_dump_t *mp;
18832   vl_api_control_ping_t *mp_ping;
18833   u8 type = FLOW_CLASSIFY_N_TABLES;
18834   int ret;
18835
18836   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
18837     ;
18838   else
18839     {
18840       errmsg ("classify table type must be specified");
18841       return -99;
18842     }
18843
18844   if (!vam->json_output)
18845     {
18846       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18847     }
18848
18849   M (FLOW_CLASSIFY_DUMP, mp);
18850   mp->type = type;
18851   /* send it... */
18852   S (mp);
18853
18854   /* Use a control ping for synchronization */
18855   MPING (CONTROL_PING, mp_ping);
18856   S (mp_ping);
18857
18858   /* Wait for a reply... */
18859   W (ret);
18860   return ret;
18861 }
18862
18863 static int
18864 api_feature_enable_disable (vat_main_t * vam)
18865 {
18866   unformat_input_t *i = vam->input;
18867   vl_api_feature_enable_disable_t *mp;
18868   u8 *arc_name = 0;
18869   u8 *feature_name = 0;
18870   u32 sw_if_index = ~0;
18871   u8 enable = 1;
18872   int ret;
18873
18874   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18875     {
18876       if (unformat (i, "arc_name %s", &arc_name))
18877         ;
18878       else if (unformat (i, "feature_name %s", &feature_name))
18879         ;
18880       else
18881         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18882         ;
18883       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18884         ;
18885       else if (unformat (i, "disable"))
18886         enable = 0;
18887       else
18888         break;
18889     }
18890
18891   if (arc_name == 0)
18892     {
18893       errmsg ("missing arc name");
18894       return -99;
18895     }
18896   if (vec_len (arc_name) > 63)
18897     {
18898       errmsg ("arc name too long");
18899     }
18900
18901   if (feature_name == 0)
18902     {
18903       errmsg ("missing feature name");
18904       return -99;
18905     }
18906   if (vec_len (feature_name) > 63)
18907     {
18908       errmsg ("feature name too long");
18909     }
18910
18911   if (sw_if_index == ~0)
18912     {
18913       errmsg ("missing interface name or sw_if_index");
18914       return -99;
18915     }
18916
18917   /* Construct the API message */
18918   M (FEATURE_ENABLE_DISABLE, mp);
18919   mp->sw_if_index = ntohl (sw_if_index);
18920   mp->enable = enable;
18921   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
18922   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
18923   vec_free (arc_name);
18924   vec_free (feature_name);
18925
18926   S (mp);
18927   W (ret);
18928   return ret;
18929 }
18930
18931 static int
18932 api_feature_gso_enable_disable (vat_main_t * vam)
18933 {
18934   unformat_input_t *i = vam->input;
18935   vl_api_feature_gso_enable_disable_t *mp;
18936   u32 sw_if_index = ~0;
18937   u8 enable = 1;
18938   int ret;
18939
18940   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18941     {
18942       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18943         ;
18944       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18945         ;
18946       else if (unformat (i, "enable"))
18947         enable = 1;
18948       else if (unformat (i, "disable"))
18949         enable = 0;
18950       else
18951         break;
18952     }
18953
18954   if (sw_if_index == ~0)
18955     {
18956       errmsg ("missing interface name or sw_if_index");
18957       return -99;
18958     }
18959
18960   /* Construct the API message */
18961   M (FEATURE_GSO_ENABLE_DISABLE, mp);
18962   mp->sw_if_index = ntohl (sw_if_index);
18963   mp->enable_disable = enable;
18964
18965   S (mp);
18966   W (ret);
18967   return ret;
18968 }
18969
18970 static int
18971 api_sw_interface_tag_add_del (vat_main_t * vam)
18972 {
18973   unformat_input_t *i = vam->input;
18974   vl_api_sw_interface_tag_add_del_t *mp;
18975   u32 sw_if_index = ~0;
18976   u8 *tag = 0;
18977   u8 enable = 1;
18978   int ret;
18979
18980   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18981     {
18982       if (unformat (i, "tag %s", &tag))
18983         ;
18984       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18985         ;
18986       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18987         ;
18988       else if (unformat (i, "del"))
18989         enable = 0;
18990       else
18991         break;
18992     }
18993
18994   if (sw_if_index == ~0)
18995     {
18996       errmsg ("missing interface name or sw_if_index");
18997       return -99;
18998     }
18999
19000   if (enable && (tag == 0))
19001     {
19002       errmsg ("no tag specified");
19003       return -99;
19004     }
19005
19006   /* Construct the API message */
19007   M (SW_INTERFACE_TAG_ADD_DEL, mp);
19008   mp->sw_if_index = ntohl (sw_if_index);
19009   mp->is_add = enable;
19010   if (enable)
19011     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
19012   vec_free (tag);
19013
19014   S (mp);
19015   W (ret);
19016   return ret;
19017 }
19018
19019 static int
19020 api_sw_interface_add_del_mac_address (vat_main_t * vam)
19021 {
19022   unformat_input_t *i = vam->input;
19023   vl_api_mac_address_t mac = { 0 };
19024   vl_api_sw_interface_add_del_mac_address_t *mp;
19025   u32 sw_if_index = ~0;
19026   u8 is_add = 1;
19027   u8 mac_set = 0;
19028   int ret;
19029
19030   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19031     {
19032       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19033         ;
19034       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19035         ;
19036       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
19037         mac_set++;
19038       else if (unformat (i, "del"))
19039         is_add = 0;
19040       else
19041         break;
19042     }
19043
19044   if (sw_if_index == ~0)
19045     {
19046       errmsg ("missing interface name or sw_if_index");
19047       return -99;
19048     }
19049
19050   if (!mac_set)
19051     {
19052       errmsg ("missing MAC address");
19053       return -99;
19054     }
19055
19056   /* Construct the API message */
19057   M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
19058   mp->sw_if_index = ntohl (sw_if_index);
19059   mp->is_add = is_add;
19060   clib_memcpy (&mp->addr, &mac, sizeof (mac));
19061
19062   S (mp);
19063   W (ret);
19064   return ret;
19065 }
19066
19067 static void vl_api_l2_xconnect_details_t_handler
19068   (vl_api_l2_xconnect_details_t * mp)
19069 {
19070   vat_main_t *vam = &vat_main;
19071
19072   print (vam->ofp, "%15d%15d",
19073          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
19074 }
19075
19076 static void vl_api_l2_xconnect_details_t_handler_json
19077   (vl_api_l2_xconnect_details_t * mp)
19078 {
19079   vat_main_t *vam = &vat_main;
19080   vat_json_node_t *node = NULL;
19081
19082   if (VAT_JSON_ARRAY != vam->json_tree.type)
19083     {
19084       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19085       vat_json_init_array (&vam->json_tree);
19086     }
19087   node = vat_json_array_add (&vam->json_tree);
19088
19089   vat_json_init_object (node);
19090   vat_json_object_add_uint (node, "rx_sw_if_index",
19091                             ntohl (mp->rx_sw_if_index));
19092   vat_json_object_add_uint (node, "tx_sw_if_index",
19093                             ntohl (mp->tx_sw_if_index));
19094 }
19095
19096 static int
19097 api_l2_xconnect_dump (vat_main_t * vam)
19098 {
19099   vl_api_l2_xconnect_dump_t *mp;
19100   vl_api_control_ping_t *mp_ping;
19101   int ret;
19102
19103   if (!vam->json_output)
19104     {
19105       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
19106     }
19107
19108   M (L2_XCONNECT_DUMP, mp);
19109
19110   S (mp);
19111
19112   /* Use a control ping for synchronization */
19113   MPING (CONTROL_PING, mp_ping);
19114   S (mp_ping);
19115
19116   W (ret);
19117   return ret;
19118 }
19119
19120 static int
19121 api_hw_interface_set_mtu (vat_main_t * vam)
19122 {
19123   unformat_input_t *i = vam->input;
19124   vl_api_hw_interface_set_mtu_t *mp;
19125   u32 sw_if_index = ~0;
19126   u32 mtu = 0;
19127   int ret;
19128
19129   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19130     {
19131       if (unformat (i, "mtu %d", &mtu))
19132         ;
19133       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19134         ;
19135       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19136         ;
19137       else
19138         break;
19139     }
19140
19141   if (sw_if_index == ~0)
19142     {
19143       errmsg ("missing interface name or sw_if_index");
19144       return -99;
19145     }
19146
19147   if (mtu == 0)
19148     {
19149       errmsg ("no mtu specified");
19150       return -99;
19151     }
19152
19153   /* Construct the API message */
19154   M (HW_INTERFACE_SET_MTU, mp);
19155   mp->sw_if_index = ntohl (sw_if_index);
19156   mp->mtu = ntohs ((u16) mtu);
19157
19158   S (mp);
19159   W (ret);
19160   return ret;
19161 }
19162
19163 static int
19164 api_p2p_ethernet_add (vat_main_t * vam)
19165 {
19166   unformat_input_t *i = vam->input;
19167   vl_api_p2p_ethernet_add_t *mp;
19168   u32 parent_if_index = ~0;
19169   u32 sub_id = ~0;
19170   u8 remote_mac[6];
19171   u8 mac_set = 0;
19172   int ret;
19173
19174   clib_memset (remote_mac, 0, sizeof (remote_mac));
19175   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19176     {
19177       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19178         ;
19179       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19180         ;
19181       else
19182         if (unformat
19183             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19184         mac_set++;
19185       else if (unformat (i, "sub_id %d", &sub_id))
19186         ;
19187       else
19188         {
19189           clib_warning ("parse error '%U'", format_unformat_error, i);
19190           return -99;
19191         }
19192     }
19193
19194   if (parent_if_index == ~0)
19195     {
19196       errmsg ("missing interface name or sw_if_index");
19197       return -99;
19198     }
19199   if (mac_set == 0)
19200     {
19201       errmsg ("missing remote mac address");
19202       return -99;
19203     }
19204   if (sub_id == ~0)
19205     {
19206       errmsg ("missing sub-interface id");
19207       return -99;
19208     }
19209
19210   M (P2P_ETHERNET_ADD, mp);
19211   mp->parent_if_index = ntohl (parent_if_index);
19212   mp->subif_id = ntohl (sub_id);
19213   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19214
19215   S (mp);
19216   W (ret);
19217   return ret;
19218 }
19219
19220 static int
19221 api_p2p_ethernet_del (vat_main_t * vam)
19222 {
19223   unformat_input_t *i = vam->input;
19224   vl_api_p2p_ethernet_del_t *mp;
19225   u32 parent_if_index = ~0;
19226   u8 remote_mac[6];
19227   u8 mac_set = 0;
19228   int ret;
19229
19230   clib_memset (remote_mac, 0, sizeof (remote_mac));
19231   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19232     {
19233       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19234         ;
19235       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19236         ;
19237       else
19238         if (unformat
19239             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19240         mac_set++;
19241       else
19242         {
19243           clib_warning ("parse error '%U'", format_unformat_error, i);
19244           return -99;
19245         }
19246     }
19247
19248   if (parent_if_index == ~0)
19249     {
19250       errmsg ("missing interface name or sw_if_index");
19251       return -99;
19252     }
19253   if (mac_set == 0)
19254     {
19255       errmsg ("missing remote mac address");
19256       return -99;
19257     }
19258
19259   M (P2P_ETHERNET_DEL, mp);
19260   mp->parent_if_index = ntohl (parent_if_index);
19261   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19262
19263   S (mp);
19264   W (ret);
19265   return ret;
19266 }
19267
19268 static int
19269 api_lldp_config (vat_main_t * vam)
19270 {
19271   unformat_input_t *i = vam->input;
19272   vl_api_lldp_config_t *mp;
19273   int tx_hold = 0;
19274   int tx_interval = 0;
19275   u8 *sys_name = NULL;
19276   int ret;
19277
19278   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19279     {
19280       if (unformat (i, "system-name %s", &sys_name))
19281         ;
19282       else if (unformat (i, "tx-hold %d", &tx_hold))
19283         ;
19284       else if (unformat (i, "tx-interval %d", &tx_interval))
19285         ;
19286       else
19287         {
19288           clib_warning ("parse error '%U'", format_unformat_error, i);
19289           return -99;
19290         }
19291     }
19292
19293   vec_add1 (sys_name, 0);
19294
19295   M (LLDP_CONFIG, mp);
19296   mp->tx_hold = htonl (tx_hold);
19297   mp->tx_interval = htonl (tx_interval);
19298   vl_api_vec_to_api_string (sys_name, &mp->system_name);
19299   vec_free (sys_name);
19300
19301   S (mp);
19302   W (ret);
19303   return ret;
19304 }
19305
19306 static int
19307 api_sw_interface_set_lldp (vat_main_t * vam)
19308 {
19309   unformat_input_t *i = vam->input;
19310   vl_api_sw_interface_set_lldp_t *mp;
19311   u32 sw_if_index = ~0;
19312   u32 enable = 1;
19313   u8 *port_desc = NULL, *mgmt_oid = NULL;
19314   ip4_address_t ip4_addr;
19315   ip6_address_t ip6_addr;
19316   int ret;
19317
19318   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
19319   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
19320
19321   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19322     {
19323       if (unformat (i, "disable"))
19324         enable = 0;
19325       else
19326         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19327         ;
19328       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19329         ;
19330       else if (unformat (i, "port-desc %s", &port_desc))
19331         ;
19332       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
19333         ;
19334       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
19335         ;
19336       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
19337         ;
19338       else
19339         break;
19340     }
19341
19342   if (sw_if_index == ~0)
19343     {
19344       errmsg ("missing interface name or sw_if_index");
19345       return -99;
19346     }
19347
19348   /* Construct the API message */
19349   vec_add1 (port_desc, 0);
19350   vec_add1 (mgmt_oid, 0);
19351   M (SW_INTERFACE_SET_LLDP, mp);
19352   mp->sw_if_index = ntohl (sw_if_index);
19353   mp->enable = enable;
19354   vl_api_vec_to_api_string (port_desc, &mp->port_desc);
19355   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
19356   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
19357   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
19358   vec_free (port_desc);
19359   vec_free (mgmt_oid);
19360
19361   S (mp);
19362   W (ret);
19363   return ret;
19364 }
19365
19366 static int
19367 api_tcp_configure_src_addresses (vat_main_t * vam)
19368 {
19369   vl_api_tcp_configure_src_addresses_t *mp;
19370   unformat_input_t *i = vam->input;
19371   vl_api_address_t first, last;
19372   u8 range_set = 0;
19373   u32 vrf_id = 0;
19374   int ret;
19375
19376   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19377     {
19378       if (unformat (i, "%U - %U",
19379                     unformat_vl_api_address, &first,
19380                     unformat_vl_api_address, &last))
19381         {
19382           if (range_set)
19383             {
19384               errmsg ("one range per message (range already set)");
19385               return -99;
19386             }
19387           range_set = 1;
19388         }
19389       else if (unformat (i, "vrf %d", &vrf_id))
19390         ;
19391       else
19392         break;
19393     }
19394
19395   if (range_set == 0)
19396     {
19397       errmsg ("address range not set");
19398       return -99;
19399     }
19400
19401   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
19402
19403   mp->vrf_id = ntohl (vrf_id);
19404   clib_memcpy (&mp->first_address, &first, sizeof (first));
19405   clib_memcpy (&mp->last_address, &last, sizeof (last));
19406
19407   S (mp);
19408   W (ret);
19409   return ret;
19410 }
19411
19412 static void vl_api_app_namespace_add_del_reply_t_handler
19413   (vl_api_app_namespace_add_del_reply_t * mp)
19414 {
19415   vat_main_t *vam = &vat_main;
19416   i32 retval = ntohl (mp->retval);
19417   if (vam->async_mode)
19418     {
19419       vam->async_errors += (retval < 0);
19420     }
19421   else
19422     {
19423       vam->retval = retval;
19424       if (retval == 0)
19425         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
19426       vam->result_ready = 1;
19427     }
19428 }
19429
19430 static void vl_api_app_namespace_add_del_reply_t_handler_json
19431   (vl_api_app_namespace_add_del_reply_t * mp)
19432 {
19433   vat_main_t *vam = &vat_main;
19434   vat_json_node_t node;
19435
19436   vat_json_init_object (&node);
19437   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
19438   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
19439
19440   vat_json_print (vam->ofp, &node);
19441   vat_json_free (&node);
19442
19443   vam->retval = ntohl (mp->retval);
19444   vam->result_ready = 1;
19445 }
19446
19447 static int
19448 api_app_namespace_add_del (vat_main_t * vam)
19449 {
19450   vl_api_app_namespace_add_del_t *mp;
19451   unformat_input_t *i = vam->input;
19452   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
19453   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
19454   u64 secret;
19455   int ret;
19456
19457   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19458     {
19459       if (unformat (i, "id %_%v%_", &ns_id))
19460         ;
19461       else if (unformat (i, "secret %lu", &secret))
19462         secret_set = 1;
19463       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19464         sw_if_index_set = 1;
19465       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
19466         ;
19467       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
19468         ;
19469       else
19470         break;
19471     }
19472   if (!ns_id || !secret_set || !sw_if_index_set)
19473     {
19474       errmsg ("namespace id, secret and sw_if_index must be set");
19475       return -99;
19476     }
19477   if (vec_len (ns_id) > 64)
19478     {
19479       errmsg ("namespace id too long");
19480       return -99;
19481     }
19482   M (APP_NAMESPACE_ADD_DEL, mp);
19483
19484   vl_api_vec_to_api_string (ns_id, &mp->namespace_id);
19485   mp->secret = clib_host_to_net_u64 (secret);
19486   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
19487   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
19488   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
19489   vec_free (ns_id);
19490   S (mp);
19491   W (ret);
19492   return ret;
19493 }
19494
19495 static int
19496 api_sock_init_shm (vat_main_t * vam)
19497 {
19498 #if VPP_API_TEST_BUILTIN == 0
19499   unformat_input_t *i = vam->input;
19500   vl_api_shm_elem_config_t *config = 0;
19501   u64 size = 64 << 20;
19502   int rv;
19503
19504   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19505     {
19506       if (unformat (i, "size %U", unformat_memory_size, &size))
19507         ;
19508       else
19509         break;
19510     }
19511
19512   /*
19513    * Canned custom ring allocator config.
19514    * Should probably parse all of this
19515    */
19516   vec_validate (config, 6);
19517   config[0].type = VL_API_VLIB_RING;
19518   config[0].size = 256;
19519   config[0].count = 32;
19520
19521   config[1].type = VL_API_VLIB_RING;
19522   config[1].size = 1024;
19523   config[1].count = 16;
19524
19525   config[2].type = VL_API_VLIB_RING;
19526   config[2].size = 4096;
19527   config[2].count = 2;
19528
19529   config[3].type = VL_API_CLIENT_RING;
19530   config[3].size = 256;
19531   config[3].count = 32;
19532
19533   config[4].type = VL_API_CLIENT_RING;
19534   config[4].size = 1024;
19535   config[4].count = 16;
19536
19537   config[5].type = VL_API_CLIENT_RING;
19538   config[5].size = 4096;
19539   config[5].count = 2;
19540
19541   config[6].type = VL_API_QUEUE;
19542   config[6].count = 128;
19543   config[6].size = sizeof (uword);
19544
19545   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
19546   if (!rv)
19547     vam->client_index_invalid = 1;
19548   return rv;
19549 #else
19550   return -99;
19551 #endif
19552 }
19553
19554 static void
19555 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
19556 {
19557   vat_main_t *vam = &vat_main;
19558   fib_prefix_t lcl, rmt;
19559
19560   ip_prefix_decode (&mp->lcl, &lcl);
19561   ip_prefix_decode (&mp->rmt, &rmt);
19562
19563   if (lcl.fp_proto == FIB_PROTOCOL_IP4)
19564     {
19565       print (vam->ofp,
19566              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19567              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19568              mp->scope, format_ip4_address, &lcl.fp_addr.ip4, lcl.fp_len,
19569              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
19570              &rmt.fp_addr.ip4, rmt.fp_len,
19571              clib_net_to_host_u16 (mp->rmt_port),
19572              clib_net_to_host_u32 (mp->action_index), mp->tag);
19573     }
19574   else
19575     {
19576       print (vam->ofp,
19577              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19578              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19579              mp->scope, format_ip6_address, &lcl.fp_addr.ip6, lcl.fp_len,
19580              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
19581              &rmt.fp_addr.ip6, rmt.fp_len,
19582              clib_net_to_host_u16 (mp->rmt_port),
19583              clib_net_to_host_u32 (mp->action_index), mp->tag);
19584     }
19585 }
19586
19587 static void
19588 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
19589                                              mp)
19590 {
19591   vat_main_t *vam = &vat_main;
19592   vat_json_node_t *node = NULL;
19593   struct in6_addr ip6;
19594   struct in_addr ip4;
19595
19596   fib_prefix_t lcl, rmt;
19597
19598   ip_prefix_decode (&mp->lcl, &lcl);
19599   ip_prefix_decode (&mp->rmt, &rmt);
19600
19601   if (VAT_JSON_ARRAY != vam->json_tree.type)
19602     {
19603       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19604       vat_json_init_array (&vam->json_tree);
19605     }
19606   node = vat_json_array_add (&vam->json_tree);
19607   vat_json_init_object (node);
19608
19609   vat_json_object_add_uint (node, "appns_index",
19610                             clib_net_to_host_u32 (mp->appns_index));
19611   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
19612   vat_json_object_add_uint (node, "scope", mp->scope);
19613   vat_json_object_add_uint (node, "action_index",
19614                             clib_net_to_host_u32 (mp->action_index));
19615   vat_json_object_add_uint (node, "lcl_port",
19616                             clib_net_to_host_u16 (mp->lcl_port));
19617   vat_json_object_add_uint (node, "rmt_port",
19618                             clib_net_to_host_u16 (mp->rmt_port));
19619   vat_json_object_add_uint (node, "lcl_plen", lcl.fp_len);
19620   vat_json_object_add_uint (node, "rmt_plen", rmt.fp_len);
19621   vat_json_object_add_string_copy (node, "tag", mp->tag);
19622   if (lcl.fp_proto == FIB_PROTOCOL_IP4)
19623     {
19624       clib_memcpy (&ip4, &lcl.fp_addr.ip4, sizeof (ip4));
19625       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
19626       clib_memcpy (&ip4, &rmt.fp_addr.ip4, sizeof (ip4));
19627       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
19628     }
19629   else
19630     {
19631       clib_memcpy (&ip6, &lcl.fp_addr.ip6, sizeof (ip6));
19632       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
19633       clib_memcpy (&ip6, &rmt.fp_addr.ip6, sizeof (ip6));
19634       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
19635     }
19636 }
19637
19638 static int
19639 api_session_rule_add_del (vat_main_t * vam)
19640 {
19641   vl_api_session_rule_add_del_t *mp;
19642   unformat_input_t *i = vam->input;
19643   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
19644   u32 appns_index = 0, scope = 0;
19645   ip4_address_t lcl_ip4, rmt_ip4;
19646   ip6_address_t lcl_ip6, rmt_ip6;
19647   u8 is_ip4 = 1, conn_set = 0;
19648   u8 is_add = 1, *tag = 0;
19649   int ret;
19650   fib_prefix_t lcl, rmt;
19651
19652   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19653     {
19654       if (unformat (i, "del"))
19655         is_add = 0;
19656       else if (unformat (i, "add"))
19657         ;
19658       else if (unformat (i, "proto tcp"))
19659         proto = 0;
19660       else if (unformat (i, "proto udp"))
19661         proto = 1;
19662       else if (unformat (i, "appns %d", &appns_index))
19663         ;
19664       else if (unformat (i, "scope %d", &scope))
19665         ;
19666       else if (unformat (i, "tag %_%v%_", &tag))
19667         ;
19668       else
19669         if (unformat
19670             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
19671              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
19672              &rmt_port))
19673         {
19674           is_ip4 = 1;
19675           conn_set = 1;
19676         }
19677       else
19678         if (unformat
19679             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
19680              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
19681              &rmt_port))
19682         {
19683           is_ip4 = 0;
19684           conn_set = 1;
19685         }
19686       else if (unformat (i, "action %d", &action))
19687         ;
19688       else
19689         break;
19690     }
19691   if (proto == ~0 || !conn_set || action == ~0)
19692     {
19693       errmsg ("transport proto, connection and action must be set");
19694       return -99;
19695     }
19696
19697   if (scope > 3)
19698     {
19699       errmsg ("scope should be 0-3");
19700       return -99;
19701     }
19702
19703   M (SESSION_RULE_ADD_DEL, mp);
19704
19705   clib_memset (&lcl, 0, sizeof (lcl));
19706   clib_memset (&rmt, 0, sizeof (rmt));
19707   if (is_ip4)
19708     {
19709       ip_set (&lcl.fp_addr, &lcl_ip4, 1);
19710       ip_set (&rmt.fp_addr, &rmt_ip4, 1);
19711       lcl.fp_len = lcl_plen;
19712       rmt.fp_len = rmt_plen;
19713     }
19714   else
19715     {
19716       ip_set (&lcl.fp_addr, &lcl_ip6, 0);
19717       ip_set (&rmt.fp_addr, &rmt_ip6, 0);
19718       lcl.fp_len = lcl_plen;
19719       rmt.fp_len = rmt_plen;
19720     }
19721
19722
19723   ip_prefix_encode (&lcl, &mp->lcl);
19724   ip_prefix_encode (&rmt, &mp->rmt);
19725   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
19726   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
19727   mp->transport_proto =
19728     proto ? TRANSPORT_PROTO_API_UDP : TRANSPORT_PROTO_API_TCP;
19729   mp->action_index = clib_host_to_net_u32 (action);
19730   mp->appns_index = clib_host_to_net_u32 (appns_index);
19731   mp->scope = scope;
19732   mp->is_add = is_add;
19733   if (tag)
19734     {
19735       clib_memcpy (mp->tag, tag, vec_len (tag));
19736       vec_free (tag);
19737     }
19738
19739   S (mp);
19740   W (ret);
19741   return ret;
19742 }
19743
19744 static int
19745 api_session_rules_dump (vat_main_t * vam)
19746 {
19747   vl_api_session_rules_dump_t *mp;
19748   vl_api_control_ping_t *mp_ping;
19749   int ret;
19750
19751   if (!vam->json_output)
19752     {
19753       print (vam->ofp, "%=20s", "Session Rules");
19754     }
19755
19756   M (SESSION_RULES_DUMP, mp);
19757   /* send it... */
19758   S (mp);
19759
19760   /* Use a control ping for synchronization */
19761   MPING (CONTROL_PING, mp_ping);
19762   S (mp_ping);
19763
19764   /* Wait for a reply... */
19765   W (ret);
19766   return ret;
19767 }
19768
19769 static int
19770 api_ip_container_proxy_add_del (vat_main_t * vam)
19771 {
19772   vl_api_ip_container_proxy_add_del_t *mp;
19773   unformat_input_t *i = vam->input;
19774   u32 sw_if_index = ~0;
19775   vl_api_prefix_t pfx = { };
19776   u8 is_add = 1;
19777   int ret;
19778
19779   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19780     {
19781       if (unformat (i, "del"))
19782         is_add = 0;
19783       else if (unformat (i, "add"))
19784         ;
19785       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
19786         ;
19787       else if (unformat (i, "sw_if_index %u", &sw_if_index))
19788         ;
19789       else
19790         break;
19791     }
19792   if (sw_if_index == ~0 || pfx.len == 0)
19793     {
19794       errmsg ("address and sw_if_index must be set");
19795       return -99;
19796     }
19797
19798   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
19799
19800   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
19801   mp->is_add = is_add;
19802   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
19803
19804   S (mp);
19805   W (ret);
19806   return ret;
19807 }
19808
19809 static int
19810 api_qos_record_enable_disable (vat_main_t * vam)
19811 {
19812   unformat_input_t *i = vam->input;
19813   vl_api_qos_record_enable_disable_t *mp;
19814   u32 sw_if_index, qs = 0xff;
19815   u8 sw_if_index_set = 0;
19816   u8 enable = 1;
19817   int ret;
19818
19819   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19820     {
19821       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19822         sw_if_index_set = 1;
19823       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19824         sw_if_index_set = 1;
19825       else if (unformat (i, "%U", unformat_qos_source, &qs))
19826         ;
19827       else if (unformat (i, "disable"))
19828         enable = 0;
19829       else
19830         {
19831           clib_warning ("parse error '%U'", format_unformat_error, i);
19832           return -99;
19833         }
19834     }
19835
19836   if (sw_if_index_set == 0)
19837     {
19838       errmsg ("missing interface name or sw_if_index");
19839       return -99;
19840     }
19841   if (qs == 0xff)
19842     {
19843       errmsg ("input location must be specified");
19844       return -99;
19845     }
19846
19847   M (QOS_RECORD_ENABLE_DISABLE, mp);
19848
19849   mp->record.sw_if_index = ntohl (sw_if_index);
19850   mp->record.input_source = qs;
19851   mp->enable = enable;
19852
19853   S (mp);
19854   W (ret);
19855   return ret;
19856 }
19857
19858
19859 static int
19860 q_or_quit (vat_main_t * vam)
19861 {
19862 #if VPP_API_TEST_BUILTIN == 0
19863   longjmp (vam->jump_buf, 1);
19864 #endif
19865   return 0;                     /* not so much */
19866 }
19867
19868 static int
19869 q (vat_main_t * vam)
19870 {
19871   return q_or_quit (vam);
19872 }
19873
19874 static int
19875 quit (vat_main_t * vam)
19876 {
19877   return q_or_quit (vam);
19878 }
19879
19880 static int
19881 comment (vat_main_t * vam)
19882 {
19883   return 0;
19884 }
19885
19886 static int
19887 elog_save (vat_main_t * vam)
19888 {
19889 #if VPP_API_TEST_BUILTIN == 0
19890   elog_main_t *em = &vam->elog_main;
19891   unformat_input_t *i = vam->input;
19892   char *file, *chroot_file;
19893   clib_error_t *error;
19894
19895   if (!unformat (i, "%s", &file))
19896     {
19897       errmsg ("expected file name, got `%U'", format_unformat_error, i);
19898       return 0;
19899     }
19900
19901   /* It's fairly hard to get "../oopsie" through unformat; just in case */
19902   if (strstr (file, "..") || index (file, '/'))
19903     {
19904       errmsg ("illegal characters in filename '%s'", file);
19905       return 0;
19906     }
19907
19908   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
19909
19910   vec_free (file);
19911
19912   errmsg ("Saving %wd of %wd events to %s",
19913           elog_n_events_in_buffer (em),
19914           elog_buffer_capacity (em), chroot_file);
19915
19916   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
19917   vec_free (chroot_file);
19918
19919   if (error)
19920     clib_error_report (error);
19921 #else
19922   errmsg ("Use the vpp event loger...");
19923 #endif
19924
19925   return 0;
19926 }
19927
19928 static int
19929 elog_setup (vat_main_t * vam)
19930 {
19931 #if VPP_API_TEST_BUILTIN == 0
19932   elog_main_t *em = &vam->elog_main;
19933   unformat_input_t *i = vam->input;
19934   u32 nevents = 128 << 10;
19935
19936   (void) unformat (i, "nevents %d", &nevents);
19937
19938   elog_init (em, nevents);
19939   vl_api_set_elog_main (em);
19940   vl_api_set_elog_trace_api_messages (1);
19941   errmsg ("Event logger initialized with %u events", nevents);
19942 #else
19943   errmsg ("Use the vpp event loger...");
19944 #endif
19945   return 0;
19946 }
19947
19948 static int
19949 elog_enable (vat_main_t * vam)
19950 {
19951 #if VPP_API_TEST_BUILTIN == 0
19952   elog_main_t *em = &vam->elog_main;
19953
19954   elog_enable_disable (em, 1 /* enable */ );
19955   vl_api_set_elog_trace_api_messages (1);
19956   errmsg ("Event logger enabled...");
19957 #else
19958   errmsg ("Use the vpp event loger...");
19959 #endif
19960   return 0;
19961 }
19962
19963 static int
19964 elog_disable (vat_main_t * vam)
19965 {
19966 #if VPP_API_TEST_BUILTIN == 0
19967   elog_main_t *em = &vam->elog_main;
19968
19969   elog_enable_disable (em, 0 /* enable */ );
19970   vl_api_set_elog_trace_api_messages (1);
19971   errmsg ("Event logger disabled...");
19972 #else
19973   errmsg ("Use the vpp event loger...");
19974 #endif
19975   return 0;
19976 }
19977
19978 static int
19979 statseg (vat_main_t * vam)
19980 {
19981   ssvm_private_t *ssvmp = &vam->stat_segment;
19982   ssvm_shared_header_t *shared_header = ssvmp->sh;
19983   vlib_counter_t **counters;
19984   u64 thread0_index1_packets;
19985   u64 thread0_index1_bytes;
19986   f64 vector_rate, input_rate;
19987   uword *p;
19988
19989   uword *counter_vector_by_name;
19990   if (vam->stat_segment_lockp == 0)
19991     {
19992       errmsg ("Stat segment not mapped...");
19993       return -99;
19994     }
19995
19996   /* look up "/if/rx for sw_if_index 1 as a test */
19997
19998   clib_spinlock_lock (vam->stat_segment_lockp);
19999
20000   counter_vector_by_name = (uword *) shared_header->opaque[1];
20001
20002   p = hash_get_mem (counter_vector_by_name, "/if/rx");
20003   if (p == 0)
20004     {
20005       clib_spinlock_unlock (vam->stat_segment_lockp);
20006       errmsg ("/if/tx not found?");
20007       return -99;
20008     }
20009
20010   /* Fish per-thread vector of combined counters from shared memory */
20011   counters = (vlib_counter_t **) p[0];
20012
20013   if (vec_len (counters[0]) < 2)
20014     {
20015       clib_spinlock_unlock (vam->stat_segment_lockp);
20016       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
20017       return -99;
20018     }
20019
20020   /* Read thread 0 sw_if_index 1 counter */
20021   thread0_index1_packets = counters[0][1].packets;
20022   thread0_index1_bytes = counters[0][1].bytes;
20023
20024   p = hash_get_mem (counter_vector_by_name, "vector_rate");
20025   if (p == 0)
20026     {
20027       clib_spinlock_unlock (vam->stat_segment_lockp);
20028       errmsg ("vector_rate not found?");
20029       return -99;
20030     }
20031
20032   vector_rate = *(f64 *) (p[0]);
20033   p = hash_get_mem (counter_vector_by_name, "input_rate");
20034   if (p == 0)
20035     {
20036       clib_spinlock_unlock (vam->stat_segment_lockp);
20037       errmsg ("input_rate not found?");
20038       return -99;
20039     }
20040   input_rate = *(f64 *) (p[0]);
20041
20042   clib_spinlock_unlock (vam->stat_segment_lockp);
20043
20044   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
20045          vector_rate, input_rate);
20046   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
20047          thread0_index1_packets, thread0_index1_bytes);
20048
20049   return 0;
20050 }
20051
20052 static int
20053 cmd_cmp (void *a1, void *a2)
20054 {
20055   u8 **c1 = a1;
20056   u8 **c2 = a2;
20057
20058   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
20059 }
20060
20061 static int
20062 help (vat_main_t * vam)
20063 {
20064   u8 **cmds = 0;
20065   u8 *name = 0;
20066   hash_pair_t *p;
20067   unformat_input_t *i = vam->input;
20068   int j;
20069
20070   if (unformat (i, "%s", &name))
20071     {
20072       uword *hs;
20073
20074       vec_add1 (name, 0);
20075
20076       hs = hash_get_mem (vam->help_by_name, name);
20077       if (hs)
20078         print (vam->ofp, "usage: %s %s", name, hs[0]);
20079       else
20080         print (vam->ofp, "No such msg / command '%s'", name);
20081       vec_free (name);
20082       return 0;
20083     }
20084
20085   print (vam->ofp, "Help is available for the following:");
20086
20087     /* *INDENT-OFF* */
20088     hash_foreach_pair (p, vam->function_by_name,
20089     ({
20090       vec_add1 (cmds, (u8 *)(p->key));
20091     }));
20092     /* *INDENT-ON* */
20093
20094   vec_sort_with_function (cmds, cmd_cmp);
20095
20096   for (j = 0; j < vec_len (cmds); j++)
20097     print (vam->ofp, "%s", cmds[j]);
20098
20099   vec_free (cmds);
20100   return 0;
20101 }
20102
20103 static int
20104 set (vat_main_t * vam)
20105 {
20106   u8 *name = 0, *value = 0;
20107   unformat_input_t *i = vam->input;
20108
20109   if (unformat (i, "%s", &name))
20110     {
20111       /* The input buffer is a vector, not a string. */
20112       value = vec_dup (i->buffer);
20113       vec_delete (value, i->index, 0);
20114       /* Almost certainly has a trailing newline */
20115       if (value[vec_len (value) - 1] == '\n')
20116         value[vec_len (value) - 1] = 0;
20117       /* Make sure it's a proper string, one way or the other */
20118       vec_add1 (value, 0);
20119       (void) clib_macro_set_value (&vam->macro_main,
20120                                    (char *) name, (char *) value);
20121     }
20122   else
20123     errmsg ("usage: set <name> <value>");
20124
20125   vec_free (name);
20126   vec_free (value);
20127   return 0;
20128 }
20129
20130 static int
20131 unset (vat_main_t * vam)
20132 {
20133   u8 *name = 0;
20134
20135   if (unformat (vam->input, "%s", &name))
20136     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
20137       errmsg ("unset: %s wasn't set", name);
20138   vec_free (name);
20139   return 0;
20140 }
20141
20142 typedef struct
20143 {
20144   u8 *name;
20145   u8 *value;
20146 } macro_sort_t;
20147
20148
20149 static int
20150 macro_sort_cmp (void *a1, void *a2)
20151 {
20152   macro_sort_t *s1 = a1;
20153   macro_sort_t *s2 = a2;
20154
20155   return strcmp ((char *) (s1->name), (char *) (s2->name));
20156 }
20157
20158 static int
20159 dump_macro_table (vat_main_t * vam)
20160 {
20161   macro_sort_t *sort_me = 0, *sm;
20162   int i;
20163   hash_pair_t *p;
20164
20165     /* *INDENT-OFF* */
20166     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
20167     ({
20168       vec_add2 (sort_me, sm, 1);
20169       sm->name = (u8 *)(p->key);
20170       sm->value = (u8 *) (p->value[0]);
20171     }));
20172     /* *INDENT-ON* */
20173
20174   vec_sort_with_function (sort_me, macro_sort_cmp);
20175
20176   if (vec_len (sort_me))
20177     print (vam->ofp, "%-15s%s", "Name", "Value");
20178   else
20179     print (vam->ofp, "The macro table is empty...");
20180
20181   for (i = 0; i < vec_len (sort_me); i++)
20182     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
20183   return 0;
20184 }
20185
20186 static int
20187 dump_node_table (vat_main_t * vam)
20188 {
20189   int i, j;
20190   vlib_node_t *node, *next_node;
20191
20192   if (vec_len (vam->graph_nodes) == 0)
20193     {
20194       print (vam->ofp, "Node table empty, issue get_node_graph...");
20195       return 0;
20196     }
20197
20198   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
20199     {
20200       node = vam->graph_nodes[0][i];
20201       print (vam->ofp, "[%d] %s", i, node->name);
20202       for (j = 0; j < vec_len (node->next_nodes); j++)
20203         {
20204           if (node->next_nodes[j] != ~0)
20205             {
20206               next_node = vam->graph_nodes[0][node->next_nodes[j]];
20207               print (vam->ofp, "  [%d] %s", j, next_node->name);
20208             }
20209         }
20210     }
20211   return 0;
20212 }
20213
20214 static int
20215 value_sort_cmp (void *a1, void *a2)
20216 {
20217   name_sort_t *n1 = a1;
20218   name_sort_t *n2 = a2;
20219
20220   if (n1->value < n2->value)
20221     return -1;
20222   if (n1->value > n2->value)
20223     return 1;
20224   return 0;
20225 }
20226
20227
20228 static int
20229 dump_msg_api_table (vat_main_t * vam)
20230 {
20231   api_main_t *am = vlibapi_get_main ();
20232   name_sort_t *nses = 0, *ns;
20233   hash_pair_t *hp;
20234   int i;
20235
20236   /* *INDENT-OFF* */
20237   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
20238   ({
20239     vec_add2 (nses, ns, 1);
20240     ns->name = (u8 *)(hp->key);
20241     ns->value = (u32) hp->value[0];
20242   }));
20243   /* *INDENT-ON* */
20244
20245   vec_sort_with_function (nses, value_sort_cmp);
20246
20247   for (i = 0; i < vec_len (nses); i++)
20248     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
20249   vec_free (nses);
20250   return 0;
20251 }
20252
20253 static int
20254 get_msg_id (vat_main_t * vam)
20255 {
20256   u8 *name_and_crc;
20257   u32 message_index;
20258
20259   if (unformat (vam->input, "%s", &name_and_crc))
20260     {
20261       message_index = vl_msg_api_get_msg_index (name_and_crc);
20262       if (message_index == ~0)
20263         {
20264           print (vam->ofp, " '%s' not found", name_and_crc);
20265           return 0;
20266         }
20267       print (vam->ofp, " '%s' has message index %d",
20268              name_and_crc, message_index);
20269       return 0;
20270     }
20271   errmsg ("name_and_crc required...");
20272   return 0;
20273 }
20274
20275 static int
20276 search_node_table (vat_main_t * vam)
20277 {
20278   unformat_input_t *line_input = vam->input;
20279   u8 *node_to_find;
20280   int j;
20281   vlib_node_t *node, *next_node;
20282   uword *p;
20283
20284   if (vam->graph_node_index_by_name == 0)
20285     {
20286       print (vam->ofp, "Node table empty, issue get_node_graph...");
20287       return 0;
20288     }
20289
20290   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20291     {
20292       if (unformat (line_input, "%s", &node_to_find))
20293         {
20294           vec_add1 (node_to_find, 0);
20295           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
20296           if (p == 0)
20297             {
20298               print (vam->ofp, "%s not found...", node_to_find);
20299               goto out;
20300             }
20301           node = vam->graph_nodes[0][p[0]];
20302           print (vam->ofp, "[%d] %s", p[0], node->name);
20303           for (j = 0; j < vec_len (node->next_nodes); j++)
20304             {
20305               if (node->next_nodes[j] != ~0)
20306                 {
20307                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
20308                   print (vam->ofp, "  [%d] %s", j, next_node->name);
20309                 }
20310             }
20311         }
20312
20313       else
20314         {
20315           clib_warning ("parse error '%U'", format_unformat_error,
20316                         line_input);
20317           return -99;
20318         }
20319
20320     out:
20321       vec_free (node_to_find);
20322
20323     }
20324
20325   return 0;
20326 }
20327
20328
20329 static int
20330 script (vat_main_t * vam)
20331 {
20332 #if (VPP_API_TEST_BUILTIN==0)
20333   u8 *s = 0;
20334   char *save_current_file;
20335   unformat_input_t save_input;
20336   jmp_buf save_jump_buf;
20337   u32 save_line_number;
20338
20339   FILE *new_fp, *save_ifp;
20340
20341   if (unformat (vam->input, "%s", &s))
20342     {
20343       new_fp = fopen ((char *) s, "r");
20344       if (new_fp == 0)
20345         {
20346           errmsg ("Couldn't open script file %s", s);
20347           vec_free (s);
20348           return -99;
20349         }
20350     }
20351   else
20352     {
20353       errmsg ("Missing script name");
20354       return -99;
20355     }
20356
20357   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
20358   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
20359   save_ifp = vam->ifp;
20360   save_line_number = vam->input_line_number;
20361   save_current_file = (char *) vam->current_file;
20362
20363   vam->input_line_number = 0;
20364   vam->ifp = new_fp;
20365   vam->current_file = s;
20366   do_one_file (vam);
20367
20368   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
20369   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
20370   vam->ifp = save_ifp;
20371   vam->input_line_number = save_line_number;
20372   vam->current_file = (u8 *) save_current_file;
20373   vec_free (s);
20374
20375   return 0;
20376 #else
20377   clib_warning ("use the exec command...");
20378   return -99;
20379 #endif
20380 }
20381
20382 static int
20383 echo (vat_main_t * vam)
20384 {
20385   print (vam->ofp, "%v", vam->input->buffer);
20386   return 0;
20387 }
20388
20389 /* List of API message constructors, CLI names map to api_xxx */
20390 #define foreach_vpe_api_msg                                             \
20391 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
20392 _(sw_interface_dump,"")                                                 \
20393 _(sw_interface_set_flags,                                               \
20394   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
20395 _(sw_interface_add_del_address,                                         \
20396   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
20397 _(sw_interface_set_rx_mode,                                             \
20398   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
20399 _(sw_interface_set_rx_placement,                                        \
20400   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
20401 _(sw_interface_rx_placement_dump,                                       \
20402   "[<intfc> | sw_if_index <id>]")                                         \
20403 _(sw_interface_set_table,                                               \
20404   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
20405 _(sw_interface_set_mpls_enable,                                         \
20406   "<intfc> | sw_if_index [disable | dis]")                              \
20407 _(sw_interface_set_vpath,                                               \
20408   "<intfc> | sw_if_index <id> enable | disable")                        \
20409 _(sw_interface_set_vxlan_bypass,                                        \
20410   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20411 _(sw_interface_set_l2_xconnect,                                         \
20412   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20413   "enable | disable")                                                   \
20414 _(sw_interface_set_l2_bridge,                                           \
20415   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
20416   "[shg <split-horizon-group>] [bvi]\n"                                 \
20417   "enable | disable")                                                   \
20418 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
20419 _(bridge_domain_add_del,                                                \
20420   "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") \
20421 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
20422 _(l2fib_add_del,                                                        \
20423   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
20424 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
20425 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
20426 _(l2_flags,                                                             \
20427   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20428 _(bridge_flags,                                                         \
20429   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20430 _(tap_create_v2,                                                        \
20431   "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]") \
20432 _(tap_delete_v2,                                                        \
20433   "<vpp-if-name> | sw_if_index <id>")                                   \
20434 _(sw_interface_tap_v2_dump, "")                                         \
20435 _(virtio_pci_create_v2,                                                    \
20436   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled [gro-coalesce] | csum-offload-enabled] [packed] [in-order]") \
20437 _(virtio_pci_delete,                                                    \
20438   "<vpp-if-name> | sw_if_index <id>")                                   \
20439 _(sw_interface_virtio_pci_dump, "")                                     \
20440 _(bond_create,                                                          \
20441   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
20442   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
20443   "[id <if-id>]")                                                       \
20444 _(bond_create2,                                                         \
20445   "[hw-addr <mac-addr>] {mode round-robin | active-backup | "           \
20446   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
20447   "[id <if-id>] [gso]")                                                 \
20448 _(bond_delete,                                                          \
20449   "<vpp-if-name> | sw_if_index <id>")                                   \
20450 _(bond_add_member,                                                      \
20451   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
20452 _(bond_detach_member,                                                   \
20453   "sw_if_index <n>")                                                    \
20454  _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
20455  _(sw_bond_interface_dump, "<intfc> | sw_if_index <nn>")                \
20456  _(sw_member_interface_dump,                                            \
20457   "<vpp-if-name> | sw_if_index <id>")                                   \
20458 _(ip_table_add_del,                                                     \
20459   "table <n> [ipv6] [add | del]\n")                                     \
20460 _(ip_route_add_del,                                                     \
20461   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
20462   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
20463   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
20464   "[multipath] [count <n>] [del]")                                      \
20465 _(ip_mroute_add_del,                                                    \
20466   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
20467   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
20468 _(mpls_table_add_del,                                                   \
20469   "table <n> [add | del]\n")                                            \
20470 _(mpls_route_add_del,                                                   \
20471   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
20472   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
20473   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
20474   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
20475   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
20476   "[count <n>] [del]")                                                  \
20477 _(mpls_ip_bind_unbind,                                                  \
20478   "<label> <addr/len>")                                                 \
20479 _(mpls_tunnel_add_del,                                                  \
20480   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
20481   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
20482   "[l2-only]  [out-label <n>]")                                         \
20483 _(sr_mpls_policy_add,                                                   \
20484   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
20485 _(sr_mpls_policy_del,                                                   \
20486   "bsid <id>")                                                          \
20487 _(bier_table_add_del,                                                   \
20488   "<label> <sub-domain> <set> <bsl> [del]")                             \
20489 _(bier_route_add_del,                                                   \
20490   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
20491   "[<intfc> | sw_if_index <id>]"                                        \
20492   "[weight <n>] [del] [multipath]")                                     \
20493 _(sw_interface_set_unnumbered,                                          \
20494   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
20495 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
20496 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
20497   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
20498   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
20499   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
20500 _(ip_table_replace_begin, "table <n> [ipv6]")                           \
20501 _(ip_table_flush, "table <n> [ipv6]")                                   \
20502 _(ip_table_replace_end, "table <n> [ipv6]")                             \
20503 _(set_ip_flow_hash,                                                     \
20504   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
20505 _(sw_interface_ip6_enable_disable,                                      \
20506   "<intfc> | sw_if_index <id> enable | disable")                        \
20507 _(l2_patch_add_del,                                                     \
20508   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20509   "enable | disable")                                                   \
20510 _(sr_localsid_add_del,                                                  \
20511   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
20512   "fib-table <num> (end.psp) sw_if_index <num>")                        \
20513 _(classify_add_del_table,                                               \
20514   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
20515   " [del] [del-chain] mask <mask-value>\n"                              \
20516   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
20517   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
20518 _(classify_add_del_session,                                             \
20519   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
20520   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
20521   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
20522   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
20523 _(classify_set_interface_ip_table,                                      \
20524   "<intfc> | sw_if_index <nn> table <nn>")                              \
20525 _(classify_set_interface_l2_tables,                                     \
20526   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20527   "  [other-table <nn>]")                                               \
20528 _(get_node_index, "node <node-name")                                    \
20529 _(add_node_next, "node <node-name> next <next-node-name>")              \
20530 _(l2tpv3_create_tunnel,                                                 \
20531   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
20532   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
20533   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
20534 _(l2tpv3_set_tunnel_cookies,                                            \
20535   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
20536   "[new_remote_cookie <nn>]\n")                                         \
20537 _(l2tpv3_interface_enable_disable,                                      \
20538   "<intfc> | sw_if_index <nn> enable | disable")                        \
20539 _(l2tpv3_set_lookup_key,                                                \
20540   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
20541 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
20542 _(vxlan_offload_rx,                                                     \
20543   "hw { <interface name> | hw_if_index <nn>} "                          \
20544   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
20545 _(vxlan_add_del_tunnel,                                                 \
20546   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20547   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
20548   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20549 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
20550 _(gre_tunnel_add_del,                                                   \
20551   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
20552   "[teb | erspan <session-id>] [del]")                                  \
20553 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
20554 _(l2_fib_clear_table, "")                                               \
20555 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
20556 _(l2_interface_vlan_tag_rewrite,                                        \
20557   "<intfc> | sw_if_index <nn> \n"                                       \
20558   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
20559   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
20560 _(create_vhost_user_if,                                                 \
20561         "socket <filename> [server] [renumber <dev_instance>] "         \
20562         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
20563         "[mac <mac_address>] [packed]")                                 \
20564 _(modify_vhost_user_if,                                                 \
20565         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
20566         "[server] [renumber <dev_instance>] [gso] [packed]")            \
20567 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
20568 _(sw_interface_vhost_user_dump, "<intfc> | sw_if_index <nn>")           \
20569 _(show_version, "")                                                     \
20570 _(show_threads, "")                                                     \
20571 _(vxlan_gpe_add_del_tunnel,                                             \
20572   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
20573   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20574   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
20575   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
20576 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
20577 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
20578 _(interface_name_renumber,                                              \
20579   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
20580 _(input_acl_set_interface,                                              \
20581   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20582   "  [l2-table <nn>] [del]")                                            \
20583 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
20584 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
20585 _(ip_dump, "ipv4 | ipv6")                                               \
20586 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
20587 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
20588   "  spid_id <n> ")                                                     \
20589 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
20590   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
20591   "  integ_alg <alg> integ_key <hex>")                                  \
20592 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
20593   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
20594   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
20595   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
20596 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
20597   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
20598   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
20599   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
20600   "  [instance <n>]")     \
20601 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
20602 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
20603 _(delete_loopback,"sw_if_index <nn>")                                   \
20604 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
20605 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
20606 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
20607 _(want_interface_events,  "enable|disable")                             \
20608 _(get_first_msg_id, "client <name>")                                    \
20609 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
20610 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
20611   "fib-id <nn> [ip4][ip6][default]")                                    \
20612 _(get_node_graph, " ")                                                  \
20613 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
20614 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
20615 _(ioam_disable, "")                                                     \
20616 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
20617                             " sw_if_index <sw_if_index> p <priority> "  \
20618                             "w <weight>] [del]")                        \
20619 _(one_add_del_locator, "locator-set <locator_name> "                    \
20620                         "iface <intf> | sw_if_index <sw_if_index> "     \
20621                         "p <priority> w <weight> [del]")                \
20622 _(one_add_del_local_eid,"vni <vni> eid "                                \
20623                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20624                          "locator-set <locator_name> [del]"             \
20625                          "[key-id sha1|sha256 secret-key <secret-key>]")\
20626 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
20627 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
20628 _(one_enable_disable, "enable|disable")                                 \
20629 _(one_map_register_enable_disable, "enable|disable")                    \
20630 _(one_map_register_fallback_threshold, "<value>")                       \
20631 _(one_rloc_probe_enable_disable, "enable|disable")                      \
20632 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
20633                                "[seid <seid>] "                         \
20634                                "rloc <locator> p <prio> "               \
20635                                "w <weight> [rloc <loc> ... ] "          \
20636                                "action <action> [del-all]")             \
20637 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
20638                           "<local-eid>")                                \
20639 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
20640 _(one_use_petr, "ip-address> | disable")                                \
20641 _(one_map_request_mode, "src-dst|dst-only")                             \
20642 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
20643 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
20644 _(one_locator_set_dump, "[local | remote]")                             \
20645 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
20646 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
20647                        "[local] | [remote]")                            \
20648 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
20649 _(one_ndp_bd_get, "")                                                   \
20650 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
20651 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip <ip4>")        \
20652 _(one_l2_arp_bd_get, "")                                                \
20653 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
20654 _(one_stats_enable_disable, "enable|disable")                           \
20655 _(show_one_stats_enable_disable, "")                                    \
20656 _(one_eid_table_vni_dump, "")                                           \
20657 _(one_eid_table_map_dump, "l2|l3")                                      \
20658 _(one_map_resolver_dump, "")                                            \
20659 _(one_map_server_dump, "")                                              \
20660 _(one_adjacencies_get, "vni <vni>")                                     \
20661 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
20662 _(show_one_rloc_probe_state, "")                                        \
20663 _(show_one_map_register_state, "")                                      \
20664 _(show_one_status, "")                                                  \
20665 _(one_stats_dump, "")                                                   \
20666 _(one_stats_flush, "")                                                  \
20667 _(one_get_map_request_itr_rlocs, "")                                    \
20668 _(one_map_register_set_ttl, "<ttl>")                                    \
20669 _(one_set_transport_protocol, "udp|api")                                \
20670 _(one_get_transport_protocol, "")                                       \
20671 _(one_enable_disable_xtr_mode, "enable|disable")                        \
20672 _(one_show_xtr_mode, "")                                                \
20673 _(one_enable_disable_pitr_mode, "enable|disable")                       \
20674 _(one_show_pitr_mode, "")                                               \
20675 _(one_enable_disable_petr_mode, "enable|disable")                       \
20676 _(one_show_petr_mode, "")                                               \
20677 _(show_one_nsh_mapping, "")                                             \
20678 _(show_one_pitr, "")                                                    \
20679 _(show_one_use_petr, "")                                                \
20680 _(show_one_map_request_mode, "")                                        \
20681 _(show_one_map_register_ttl, "")                                        \
20682 _(show_one_map_register_fallback_threshold, "")                         \
20683 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
20684                             " sw_if_index <sw_if_index> p <priority> "  \
20685                             "w <weight>] [del]")                        \
20686 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
20687                         "iface <intf> | sw_if_index <sw_if_index> "     \
20688                         "p <priority> w <weight> [del]")                \
20689 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
20690                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20691                          "locator-set <locator_name> [del]"             \
20692                          "[key-id sha1|sha256 secret-key <secret-key>]") \
20693 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
20694 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
20695 _(lisp_enable_disable, "enable|disable")                                \
20696 _(lisp_map_register_enable_disable, "enable|disable")                   \
20697 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
20698 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
20699                                "[seid <seid>] "                         \
20700                                "rloc <locator> p <prio> "               \
20701                                "w <weight> [rloc <loc> ... ] "          \
20702                                "action <action> [del-all]")             \
20703 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
20704                           "<local-eid>")                                \
20705 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
20706 _(lisp_use_petr, "<ip-address> | disable")                              \
20707 _(lisp_map_request_mode, "src-dst|dst-only")                            \
20708 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
20709 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
20710 _(lisp_locator_set_dump, "[local | remote]")                            \
20711 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
20712 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
20713                        "[local] | [remote]")                            \
20714 _(lisp_eid_table_vni_dump, "")                                          \
20715 _(lisp_eid_table_map_dump, "l2|l3")                                     \
20716 _(lisp_map_resolver_dump, "")                                           \
20717 _(lisp_map_server_dump, "")                                             \
20718 _(lisp_adjacencies_get, "vni <vni>")                                    \
20719 _(gpe_fwd_entry_vnis_get, "")                                           \
20720 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
20721 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
20722                                 "[table <table-id>]")                   \
20723 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
20724 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
20725 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
20726 _(gpe_get_encap_mode, "")                                               \
20727 _(lisp_gpe_add_del_iface, "up|down")                                    \
20728 _(lisp_gpe_enable_disable, "enable|disable")                            \
20729 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
20730   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
20731 _(show_lisp_rloc_probe_state, "")                                       \
20732 _(show_lisp_map_register_state, "")                                     \
20733 _(show_lisp_status, "")                                                 \
20734 _(lisp_get_map_request_itr_rlocs, "")                                   \
20735 _(show_lisp_pitr, "")                                                   \
20736 _(show_lisp_use_petr, "")                                               \
20737 _(show_lisp_map_request_mode, "")                                       \
20738 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
20739 _(af_packet_delete, "name <host interface name>")                       \
20740 _(af_packet_dump, "")                                                   \
20741 _(policer_add_del, "name <policer name> <params> [del]")                \
20742 _(policer_dump, "[name <policer name>]")                                \
20743 _(policer_classify_set_interface,                                       \
20744   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20745   "  [l2-table <nn>] [del]")                                            \
20746 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
20747 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
20748 _(mpls_table_dump, "")                                                  \
20749 _(mpls_route_dump, "table-id <ID>")                                     \
20750 _(classify_table_ids, "")                                               \
20751 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
20752 _(classify_table_info, "table_id <nn>")                                 \
20753 _(classify_session_dump, "table_id <nn>")                               \
20754 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
20755     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
20756     "[template_interval <nn>] [udp_checksum]")                          \
20757 _(ipfix_exporter_dump, "")                                              \
20758 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
20759 _(ipfix_classify_stream_dump, "")                                       \
20760 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
20761 _(ipfix_classify_table_dump, "")                                        \
20762 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
20763 _(sw_interface_span_dump, "[l2]")                                           \
20764 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
20765 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
20766 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
20767 _(pg_enable_disable, "[stream <id>] disable")                           \
20768 _(pg_interface_enable_disable_coalesce, "<intf> | sw_if_index <nn> enable | disable")  \
20769 _(ip_source_and_port_range_check_add_del,                               \
20770   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
20771 _(ip_source_and_port_range_check_interface_add_del,                     \
20772   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
20773   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
20774 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
20775 _(l2_interface_pbb_tag_rewrite,                                         \
20776   "<intfc> | sw_if_index <nn> \n"                                       \
20777   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
20778   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
20779 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
20780 _(flow_classify_set_interface,                                          \
20781   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
20782 _(flow_classify_dump, "type [ip4|ip6]")                                 \
20783 _(ip_table_dump, "")                                                    \
20784 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
20785 _(ip_mtable_dump, "")                                                   \
20786 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
20787 _(feature_enable_disable, "arc_name <arc_name> "                        \
20788   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
20789 _(feature_gso_enable_disable, "<intfc> | sw_if_index <nn> "             \
20790   "[enable | disable] ")                                                \
20791 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
20792 "[disable]")                                                            \
20793 _(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> "       \
20794   "mac <mac-address> [del]")                                            \
20795 _(l2_xconnect_dump, "")                                                 \
20796 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
20797 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
20798 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
20799 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
20800 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
20801 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
20802   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
20803 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
20804 _(sock_init_shm, "size <nnn>")                                          \
20805 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
20806 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
20807   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
20808 _(session_rules_dump, "")                                               \
20809 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
20810 _(output_acl_set_interface,                                             \
20811   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20812   "  [l2-table <nn>] [del]")                                            \
20813 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
20814
20815 /* List of command functions, CLI names map directly to functions */
20816 #define foreach_cli_function                                    \
20817 _(comment, "usage: comment <ignore-rest-of-line>")              \
20818 _(dump_interface_table, "usage: dump_interface_table")          \
20819 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
20820 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
20821 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
20822 _(dump_macro_table, "usage: dump_macro_table ")                 \
20823 _(dump_node_table, "usage: dump_node_table")                    \
20824 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
20825 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
20826 _(elog_disable, "usage: elog_disable")                          \
20827 _(elog_enable, "usage: elog_enable")                            \
20828 _(elog_save, "usage: elog_save <filename>")                     \
20829 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
20830 _(echo, "usage: echo <message>")                                \
20831 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
20832 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
20833 _(help, "usage: help")                                          \
20834 _(q, "usage: quit")                                             \
20835 _(quit, "usage: quit")                                          \
20836 _(search_node_table, "usage: search_node_table <name>...")      \
20837 _(set, "usage: set <variable-name> <value>")                    \
20838 _(script, "usage: script <file-name>")                          \
20839 _(statseg, "usage: statseg")                                    \
20840 _(unset, "usage: unset <variable-name>")
20841
20842 #define _(N,n)                                  \
20843     static void vl_api_##n##_t_handler_uni      \
20844     (vl_api_##n##_t * mp)                       \
20845     {                                           \
20846         vat_main_t * vam = &vat_main;           \
20847         if (vam->json_output) {                 \
20848             vl_api_##n##_t_handler_json(mp);    \
20849         } else {                                \
20850             vl_api_##n##_t_handler(mp);         \
20851         }                                       \
20852     }
20853 foreach_vpe_api_reply_msg;
20854 #if VPP_API_TEST_BUILTIN == 0
20855 foreach_standalone_reply_msg;
20856 #endif
20857 #undef _
20858
20859 void
20860 vat_api_hookup (vat_main_t * vam)
20861 {
20862 #define _(N,n)                                                  \
20863     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
20864                            vl_api_##n##_t_handler_uni,          \
20865                            vl_noop_handler,                     \
20866                            vl_api_##n##_t_endian,               \
20867                            vl_api_##n##_t_print,                \
20868                            sizeof(vl_api_##n##_t), 1);
20869   foreach_vpe_api_reply_msg;
20870 #if VPP_API_TEST_BUILTIN == 0
20871   foreach_standalone_reply_msg;
20872 #endif
20873 #undef _
20874
20875 #if (VPP_API_TEST_BUILTIN==0)
20876   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
20877
20878   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
20879
20880   vam->function_by_name = hash_create_string (0, sizeof (uword));
20881
20882   vam->help_by_name = hash_create_string (0, sizeof (uword));
20883 #endif
20884
20885   /* API messages we can send */
20886 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
20887   foreach_vpe_api_msg;
20888 #undef _
20889
20890   /* Help strings */
20891 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
20892   foreach_vpe_api_msg;
20893 #undef _
20894
20895   /* CLI functions */
20896 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
20897   foreach_cli_function;
20898 #undef _
20899
20900   /* Help strings */
20901 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
20902   foreach_cli_function;
20903 #undef _
20904 }
20905
20906 #if VPP_API_TEST_BUILTIN
20907 static clib_error_t *
20908 vat_api_hookup_shim (vlib_main_t * vm)
20909 {
20910   vat_api_hookup (&vat_main);
20911   return 0;
20912 }
20913
20914 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
20915 #endif
20916
20917 /*
20918  * fd.io coding-style-patch-verification: ON
20919  *
20920  * Local Variables:
20921  * eval: (c-set-style "gnu")
20922  * End:
20923  */